用g容器重绘功能

myo*_*yol 0 d3.js

如果有人能说清楚,我有几个问题.

我写了一个d3重绘功能.代码在这里.它基于示例条形图pt 2

我做了它所以点击一个正方形添加数据然后调用重绘.redraw()函数将'gBaby'容器添加到正确的'gChild'容器中,但它增加了两个而不是一个 - 这是我的第一个谜.除了这两个'rect'和'text'元素添加到同一个容器中,我知道为什么它们被添加到同一个容器中.

  1. 为什么每次只有一个元素添加到数据时会绘制两个元素?
  2. 如何添加和更新数据时,如何修改我的redraw()以在新的gBaby容器中追加新的rect和text元素(如果数据被拼接和更新,它会删除g容器吗?)
  3. 如果数据最初为空,通过其他方式更新并重新运行(),这是否可行?

欢呼任何帮助r34ch

mbo*_*ock 5

您应该做的第一件事是使用调试器逐步执行代码,或者在JavaScript控制台中逐步运行它(使用复制粘贴或手动输入).通过这种方式,您可以检查沿途的选择并查看出现问题的地方.

至于你的第一个问题,为什么只有一个元素被添加到数据时绘制了两个元素:你知道你实际上是在向数据中添加两个元素吗?Array.push采用可变数量的参数,因此data.push(50, i * 110),正如您在单击时所做的那样,将两个值添加到数组的末尾.如果要在特定索引处添加单个值,请改用Array.splice.

我看到的第二个危险,但可能不是问题,是重绘时的选择器与创建时的选择器不匹配; 你说gChild.selectAll("g.baby"),在创作时,你会说gChild.selectAll("g").我会selectAll(".baby")在两种情况下使用.我也会避免使用camelCased类名,因为CSS类不区分大小写,并且使用大小写会产生误导.

下一个问题是你正在进行两次数据连接,这比你只有一个数据集需要多一次.加入后gChild,您也不需要加入gChild.selectAll("rect").问题是您是gChild直接添加rects 而不是gBaby您创建的rects .您需要遵循在创建时使用的模式,并附加到输入gBaby:

var gBaby = gChild.selectAll(".baby")
    .data(data);

var gBabyEnter = gBaby.enter().append("g")
    .attr("class", "baby")
    .attr("transform", function(d) { return "translate(" + d + ")"; });

gBabyEnter.append("rect")
    …

gBabyEnter.append("text")
    …

gBaby.exit().remove();
Run Code Online (Sandbox Code Playgroud)

我还更改了代码以使用共享转换,而不是复制x和y属性.