且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

用g容器重绘功能

更新时间:2023-02-05 23:12:30

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

The first thing you should do is step through your code with a debugger, or by running it incrementally in the JavaScript console (with copy-and-paste, or by typing it out by hand). This way you can inspect the selections along the way and see where things start to go wrong.

关于您的第一个问题,当仅将一个元素添加到数据时,为什么会绘制两个元素:您是否知道实际上是在向数据添加两个元素? Array.push 采用可变数量的参数,因此,就像您在单击时所做的那样,将两个值添加到数组的末尾.如果要在特定索引处添加单个值,请使用 Array.剪接.

As to your first question, why are two elements drawn when only one element is added to data: are you aware you are actually adding two elements to data? Array.push takes a variable number of arguments, so data.push(50, i * 110), as you are doing on click, adds two values to the end of the array. If you want to add a single value at a specific index, then use Array.splice instead.

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

A second danger I see, but likely not a problem, is that your selector on redraw doesn't match your selector on creation; on creation, you say gChild.selectAll("g.baby"), but on redraw you say gChild.selectAll("g"). I would use selectAll(".baby") in both cases. I would also avoid camelCased class names, since CSS classes are case-insensitive and it is misleading to use capitalization.

下一个问题是您执行两次数据联接,这比您仅拥有一个数据集所需的时间多一倍.加入gChild后,也不需要加入gChild.selectAll("rect").问题在于您是将rect直接添加到gChild而不是您创建的gBaby.您需要遵循创建时使用的模式,并将其追加到输入的gBaby:

The next problem is that you are doing the data-join twice, which is one more time than necessary given you only have one dataset. After you've joined to gChild, you don't also need to join to gChild.selectAll("rect"). The problem is that you are adding the rects to the gChild directly rather than the gBaby you created. You need to follow the pattern that you used on creation, and append to the entering 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();

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

I also changed your code to use a shared transform rather than duplicating x and y attributes.