调整SVG foreignObject元素的大小以适合HTML元素

时间:2013-08-20 14:57:01

标签: html svg d3.js size

我正在使用D3 javascript库进行可视化。我想为可视化的一些元素创建工具提示,而我的客户希望它们看起来像'纸片/后贴'。最初我使用一些不错的CSS技巧为工具提示创建了简单的DIV来创建所需的外观。 (受this tutorial启发)

我想使用工具提示封装到SVG foreignObject-element中,因此它更适合可视化,我可以轻松地操作它们。 (例如缩放/平移)所以我的问题是:如何获得DIV的正确大小,它位于foreignObject-element中,所以我可以准确地设置foreignObject-element的大小?特别是当使用margin / padding / shadow ....

我通过使用 .getBoundingClientRect()来解决这个问题,但我不知道这是不是最好的方式。

这是一个代码示例:

var body = d3.select("body");

var svg = body.append("svg");

var tooltipContainer = svg.append("svg:g");

var html = tooltipContainer.append("foreignObject")
var div = html.append("xhtml:div")
    .attr('class', 'paper-tooltip')
    .html("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam.     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum     dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet,     consectetur adipiscing elit. Donec eu enim quam. ");

var bcr = div[0][0].getBoundingClientRect();

html.attr('x', 50)
    .attr('y', 50)
    .attr('width', bcr.width)
    .attr('height', bcr.height);

svg.call(d3.behavior.zoom().on('zoom', redrawOnZoom));

 function redrawOnZoom(){
    tooltipContainer.attr('transform', 'translate(' + d3.event.translate + ')' + ' scale(' +         d3.event.scale + ')');
};

这是一个有效的jsFiddle示例:http://jsfiddle.net/jhe8Y/1/

编辑:

我意识到,对于不同的阴影框设置, .getBoundingClientRect()将不起作用。我也意识到,使用我的第一个解决方案, .getBoundingClientRect()会返回太大的大小,特别是在正确的大小上。

所以我尝试了另一种方法,使用jQuerys .outerWidth(true)/ .externalHeight(true)并手动计算阴影大小。这似乎工作得很好,但做这样的事情感觉非常糟糕。

有没有其他方法可以获得所有组件的DIV的确切大小?

更新的jsFiddle在这里:http://jsfiddle.net/jhe8Y/3/

2 个答案:

答案 0 :(得分:0)

我之前一直在努力解决这个问题,而且我发现最简单的事情就是依靠Bootstrap's Tooltip

E.g。

// title: this is what gets shown as the title in the tooltip
d3.select('svg').attr('title','This is my tooltip title');

// content: this will show up as the content if you go for 
// popovers instead . 
d3.select('svg').attr('data-content','This is some content');

// set the options – read more on the Bootstrap page linked to above
$('svg').popover({
   'trigger':'hover'
   ,'container': 'body'
   ,'placement': 'top'
   ,'white-space': 'nowrap'
   ,'html':'true' // preserve html formatting
});

归结为,将titledata-content属性添加到您对添加tootltips感兴趣的任何svg元素中。然后,将内容设置为您想要的任何内容。因此,在您的情况下,html将是

<div class='paper-tooltip'>Lorem ipsum dolor sit amet, ... etc etc.</div>

相关:

How do I show a bootstrap tooltip with an SVG object; Question on Stack Overflow

Bootstrap Tooltips

My super-short blog post on it

答案 1 :(得分:0)

您不需要上下缩放。没有真正使用它,对吧?然后,您可以将foreignObject heightwidth设置为1,并通过CSS设置foreignObject { overflow: visible; }