我已经建立了一个比较几年数据的D3.js条形图。 This is a demo。
根据Mike Bostock的Let's Make a Bar Chart教程,条形结构如下所示,其中嵌套在g.bar元素中的rect和text元素(表示条形图及其标签为repsectively),所有g.bars都在g.chart中。
<g class="chart" transform="translate(45,10)">
<g class="bar" transform="translate(0,0)">
<rect style="fill: rgb(117, 220, 205); stroke-width: 0.5; stroke: rgb(255, 255, 255);" height="2.0673635307781666" width="56.9547619047619" y="116.5993031358885">
<text class="total" y="111.5993031358885" x="28.47738095238095" text-anchor="middle" alignment-baseline="middle" style="stroke: none; fill: rgb(51, 51, 51); font-size: 0.5em; font-weight: bold; display: none;">60</text>
</g>
<g class="bar" transform="translate(0,0)">
<rect style="fill: rgb(117, 220, 205); stroke-width: 0.5; stroke: rgb(255, 255, 255);" height="2.0673635307781666" width="56.9547619047619" y="116.5993031358885">
<text class="total" y="111.5993031358885" x="28.47738095238095" text-anchor="middle" alignment-baseline="middle" style="stroke: none; fill: rgb(51, 51, 51); font-size: 0.5em; font-weight: bold; display: none;">60</text>
</g>
...
</g>
每个g.bar应该只有一个rect和一个嵌入其中的文本元素。在测试我的图表时,我注意到有些出口似乎没有正常发生。您必须通过使用Firebug或Chrome开发工具检查demo来重现这一点,但在更改一年或确实加载图表而不更改年份后,每个g.bar包含多个rect和text元素。 我没有正确实现enter()exit()remove()模式吗?我怎样才能解决这个问题?谢谢!
答案 0 :(得分:2)
您只想在.enter
选项中添加rects和text。因此,您必须捕获输入选择,然后在附加rects和text时使用它。像这样:
var barsEnter = bars.enter()
.append("g")
.classed("bar",true);
...然后应用它:
barsEnter.append("rect")
...
barsEnter.append("text")
...
以下是PLUNK说明这一点。
答案 1 :(得分:1)
一旦你读完这篇文章,你就不会相信这个愚蠢有多愚蠢和多么讨厌。
为方便起见,这是原始代码的jsfiddle版本。
如果你玩的时间足够长,你会注意到有问题的案例是那些不同年份的酒吧价值(高度)相同的案例(它们可能针对不同的国家)。例如,在2012年和2009年都提到了44值,当我们从2012年切换到2009年时,反之亦然,我们遇到了您所描述的问题。
此外,如果在同一年提到两次值,两个相应的酒吧中的一个将会丢失!
这使我们得出结论,绑定数据并不完全正确。
而且,实际上,问题是在输入()之后调用data()!
关于data()的文档说第二个参数应该是关键!不是你传递的价值!这解释了上面的行为。每当值重复时,d3会将此解释为新数据或现有数据的相同键,并且会使您的酒吧变得混乱!
而不是
.data(json[year], function(d){return d;});
使用
.data(json[year], function(d, i){ return [year, d, i]; });
你的问题就会消失!
以下是jsfiddle,其中包含更正的代码 - 像魅力一样工作!