Javascript 为什么D3.js条形图上的数据更新不正确?

Javascript 为什么D3.js条形图上的数据更新不正确?,javascript,json,d3.js,transition,bar-chart,Javascript,Json,D3.js,Transition,Bar Chart,我构建了一个D3.js条形图,比较了几年的数据 根据Mike Bostock的教程,条形图的结构如下所示,一个矩形和一个文本元素(分别表示条形图及其标签)嵌套在一个g.bar元素中,所有g.bars都保存在g.chart中 <g class="chart" transform="translate(45,10)"> <g class="bar" transform="translate(0,0)"> <rect style="fill: rgb(

我构建了一个D3.js条形图,比较了几年的数据

根据Mike Bostock的教程,条形图的结构如下所示,一个矩形和一个文本元素(分别表示条形图及其标签)嵌套在一个g.bar元素中,所有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>

60
60
...
每个g.bar中应该只嵌套一个rect和一个text元素。在测试我的图表时,我注意到一些退出似乎没有正确发生。您必须通过使用Firebug或Chrome开发工具检查来重现这一点,但是在更改年份之后,或者实际上在加载图表时不更改年份,每个g.bar包含多个rect和text元素。
我是否没有正确实现enter()exit()remove()模式?我怎样才能解决这个问题?谢谢

一旦你读到这篇文章,你就不会相信这只虫子是多么愚蠢和肮脏


观察 为了方便起见,这里是原始代码的版本

如果你玩得够久,你会注意到有问题的情况是,不同年份(可能是不同的国家)的酒吧价值(高度)相同。例如,值44在2012年和2009年都提到过,当我们从2012年切换到2009年,或者从2009年切换到2012年,我们就遇到了您描述的问题

此外,如果一个值在同一年内被提及两次,则两个对应的条中的一条将丢失

这使我们得出结论,绑定到数据并不完全正确

实际上,问题是在enter()之后调用data()

关于的文档说明第二个参数应该是关键!不是你传递的值!这从上面解释了行为。只要值重复,d3就会将其解释为新数据或现有数据的同一个键,并且会将您的条带弄得一团糟

解决方案 而不是

.data(json[year], function(d){return d;});
使用

你的问题就会消失

下面是正确的代码-像魅力一样工作



您只想在
中添加rect和文本。请输入所选内容。因此,您必须捕获enter选择,然后在附加矩形和文本时使用它。像这样:

var barsEnter = bars.enter()
    .append("g")
    .classed("bar",true);
…然后应用它:

barsEnter.append("rect")
...
barsEnter.append("text")
...

这是一个例子。

是的,没问题,很高兴见到你@Fern@VividD这里也一样!谢谢你在这方面的帮助。嘿,@Fern,我不想听起来像是我在劈开头发,但是:2007年-你的解决方案没有解决这个问题-克罗地亚和斯洛伐克的值相同12,但是斯洛伐克酒吧不见了!(如果两个国家都将12改为120,你会看得更清楚)也许我们两种解决方案的结合才是最好的选择!我们能分几点吗?:);)@事实上,关于数据键控部分,您是绝对正确的。很好。这两个答案都很好地为OP服务。我们是梦之队!:)
barsEnter.append("rect")
...
barsEnter.append("text")
...