用g容器重绘功能 [英] redraw function with g containers

查看:101
本文介绍了用g容器重绘功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果有人可以阐明一些观点,我有几个问题.

I've got a couple questions if someone could shed some light.

我写了一个d3重绘函数.代码是此处.它基于示例条形图pt 2

I've written a d3 redraw function. The code is here. Its based off the example a bar chart pt 2

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

I've made it so clicking on a square adds to the data and then calls the redraw. The redraw() function adds the 'gBaby' container to the correct 'gChild' container, but it adds two instead of one - which is my first mystery. As well as this two 'rect' and 'text' elements are added to the same container although I realize why they are added to the same container.

  1. 为什么仅将一个元素添加到数据中时每次绘制两个元素?
  2. 添加和更新数据时,如何修改redraw()以在新的gBaby容器中附加新的rect和text元素(如果对数据进行拼接和更新,它将删除g容器吗?)
  3. 如果数据最初是空的,通过另一种方式更新并运行redraw(),将可以正常工作吗?

为所有帮助加油 r34ch

Cheers for any help at all r34ch

推荐答案

您应该做的第一件事是使用调试器逐步执行代码,或者在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.

这篇关于用g容器重绘功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆