d3.js获取图表之外的图例

时间:2016-02-26 20:50:08

标签: javascript d3.js svg

我试图将图表的图例放在图表区域之外。

以下是边距:

var margin = {top: 50, right: 200, bottom: 50, left: 40};
        var width = 960 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;

首先我创建svg:

var svg = d3.select("body").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

所以,根据我的理解,我现在有了svg canvas元素和一个用于保存图表的g。我试图在右边距添加更多,所以我可以在svg画布和附加到它的g之间获得一些空间,它保存图表。然后我想把我的传说放在那个空旷的空间里。

这是我添加传奇的地方:

//add legend
            var legend = svg.append("g")
                .attr("class", "legend")
                .attr("height", 300)
                .attr("width", 200)
                .attr("transform", "translate(-1000,50");

即使我附加到SVG元素,它也会附加到svg元素中的g。因此,无论我翻译多少或尝试让它在屏幕上更加正确,它永远不会超过内部g的宽度。

进行故障排除时,我看到外部SVG元素的高度为960,宽度为500.附加的g的变换/转换为40,50。宽度最终为839px乘433.223px(不确定我理解这一点)。由于内置了边距,外部svg现在有一堆空间。

所以我试图增加附加到svg的g的宽度,这样我就可以将我的图例作为g的子项并将其移动到边距创建的空白区域。或者,我试图创建另一个g,它是第一个g的兄弟,然后我可以使用边距创建的空白空间。

我无法上班,也不知道哪种方式最好。

2 个答案:

答案 0 :(得分:4)

请注意,var svg被分配给嵌套在<g>

内的<svg>
svg = d3.select("body").append("svg")
        .attr("width",  width  + margin.left + margin.right)
        .attr("height", height + margin.top  + margin.bottom)
        .append("g") // <-- This is what svg is currently being assigned to
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

因此,当您稍后执行var legend = svg.append("g")时,您实际上将该图例作为上述<g>的子项附加。这就是你在开发工具中所描述的内容。

一个含义是,您应用于外部translate()的{​​{1}}转换会影响内部<g>(即<g>的{​​{1}}的翻译<g>被添加到外部legend)。

可能,你想分开这样的东西:

<g>

然后更改您的代码,将现有图表绘制到var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom); var inner = svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 而不是inner

因此,svg会将图例附加为var legend = svg.append("g")的兄弟,并且您应用于inner的任何翻译都将相对于svg的左上角(而不是legend 1}}左上角,由inner翻译

您可能希望翻译margin,如此:

legend

将图例移动到图表的右端,MINUS var legend = svg.append("g") .attr("transform", "translate(" + width - margin.right + "," + margin.top + ")"); 。这样,您可以调整margin.rightmargin.right创建足够的空间。

最后,请注意调用

legend

没有做任何事情,因为对于svg legend .attr("height", 300) .attr("width", 200) ,没有办法明确设置宽度和高度。无论如何,这些并不意味着什么,因为svg没有html布局的“流”行为。 dev工具中显示的宽度和高度是由<g>的子项的边界产生的隐式边界。 (如果需要,可以使用<g>函数在javascript中获取这些计算边界。

答案 1 :(得分:-1)

通过查看您提供的代码,您实际上是将图例var附加到您的论坛&#34; g&#34;而不是&#34; svg&#34;,var legend = svg.append("g")

在这一行中,你告诉d3将你的图例变量变为&#34; g&#34;这是附加到svg,如果我理解正确你应该尝试这样的事情:

var legend = svg.selectAll(".legend")
.enter().append("g")

创建另一个小组&#34; g&#34;为你的传说。 我为我糟糕的英语道歉。