使用d3.js在表中显示两个字符串

使用d3.js在表中显示两个字符串,d3.js,D3.js,我一直在尝试使用d3.js来显示一个使用两个输入字符串的表,我添加了下面的代码。显示第二个字符串时,仅显示索引大于字符串x长度的字符 我认为这与匿名函数有关,当遍历第二个字符串时,我从它在第一个字符串中结束的索引值开始,例如,第二个字符串中只显示fo,而不是fresihnfo。有人能给我一些关于如何解决这个问题的建议吗 谢谢 var x = ["a", "e", "d", "i", "r", "z"]; var y = ["f", "r", "s", "i", "

我一直在尝试使用d3.js来显示一个使用两个输入字符串的表,我添加了下面的代码。显示第二个字符串时,仅显示索引大于字符串x长度的字符

我认为这与匿名函数有关,当遍历第二个字符串时,我从它在第一个字符串中结束的索引值开始,例如,第二个字符串中只显示fo,而不是fresihnfo。有人能给我一些关于如何解决这个问题的建议吗

谢谢

        var x = ["a", "e", "d", "i", "r", "z"];
        var y = ["f", "r", "s", "i", "h", "n", "f", "o"];

        var w = (x.length + 1) * 50;
        var h = (y.length + 1) * 50;

        var svg = d3.select("body")
                    .append("svg")
                    .attr("width", w)
                    .attr("height", h);

        /*Displays the first string*/
        svg.selectAll("rect")
           .data(x)
           .enter()
           .append("rect")
           .attr("x", function(d, i) {
                return (i * 45) + 45;
           })
           .attr("y", "0px")
           .attr("width", "40px")
           .attr("height", "40px")
           .attr("fill", "rgb(0, 0, 102)");

        svg.selectAll("text")
           .data(x)
           .enter()
           .append("text")
           .text(function(d) {
                return d;
           })
           .attr("text-anchor", "middle")
           .attr("x", function(d, i) {
                return (i * 45) + 65;
           })
           .attr("y", "27px")
           .attr("font-family", "sans-serif")
           .attr("font-size", "20px")
           .attr("fill", "white");

        /*Displays the second string*/
        svg.selectAll("rect")
           .data(y)
           .enter()
           .append("rect")
           .attr("x", "0px")
           .attr("y", function(d, i) {
                return ((i - x.length) * 45) + 45;
           })
           .attr("width", "40px")
           .attr("height", "40px")
           .attr("fill", "rgb(0, 0, 102)");

        svg.selectAll("text")
           .data(y)
           .enter()
           .append("text")
           .text(function(d) {
                return d;
           })
           .attr("text-anchor", "middle")
           .attr("x", "20px")
           .attr("y", function(d, i) {
                return ((i - x.length) * 45) + 70;
           })
           .attr("font-family", "sans-serif")
           .attr("font-size", "20px")
           .attr("fill", "white");          
电流输出:


所需的输出是将字符串y的其余部分显示在左列。

正如Marc所说,问题在于每次的第二个选择都被解释为第一个选择的更新,而不是一组新的元素。由于您只处理更新的enter部分,所以您甚至看不到您已经更改了第一组矩形的数据这一事实

要确认第一组矩形已获得来自第二个数组的数据,请右键单击其中一个,选择Inspect Element,然后打开inspector中的properties选项卡—_data__;属性保存元素的D3数据对象

那么你如何修复它呢?在select语句中,需要一种区分两组矩形的方法。有两种选择:

选项1:在SVG组元素上使用子选择

您有两组矩形,因此使用svg分组元素将它们组织起来是有意义的。不要将矩形直接添加到svg,而是向svg添加一个组元素,然后向其中添加矩形/文本

svg.append("g").selectAll("rect") //etc.
对第二组矩形执行同样的操作,它们将在第二组中很好地排列,只要始终从组选择中调用select语句,它将只选择属于该组的元素

选项2:使用class属性来区分这两种元素类型

您有两种类型的值,x和y,因此您应该通过设置相应的class属性来区分svg元素属于哪种类型。然后,在select语句中,确保只选择正确类的元素。某个类的元素的格式为elementName.ClassName,因此您的代码如下所示:

.selectAll("rect.x")
  .data(x)
enter()
  .append("rect")
  .classed("x", true)
  // etc. 
或者,选项3:两者都使用

如果你想在将来更新矩形,仅仅把它们分为两组是不够的——你还需要一种区分这些组的方法。因此,在附加元素时添加一个x或y类,并在创建元素时使用g.x或g.y选择器

如果你想保持D3代码的简洁,我强烈建议你仔细阅读选择、选择器、嵌套选择和更新过程。有一个

另外,作为匿名函数的命名参数创建的i值在该函数的范围内总是有限的。如果需要,您可以给它们不同的名称,它们的值将始终是D3传递给它们的值—第一个参数的数据对象,第二个参数的当前选择中的索引。

selectAll的主要目标是在处理数据时选择容器中存在的元素

它将数据与元素连接起来,这样我们就可以

使用enter为新数据项添加新元素

使用“更新”更新与数据匹配的元素

使用exit删除没有要匹配的数据的元素

使用svg.selectAllrect.datax.enter追加rect时,selectAll将返回0元素

enter将为每个数据生成占位符,以便您可以将所有数据附加到x中

但是当使用svg.selectAllrect.datay.enter为y追加rect时。选择All将返回6

rects,因此datay.enter将为'f'和'o'提供产品占位符这就是为什么您只得到两个

元素

解决方案:对x和y使用不同的选择器,例如不同的类名

svg.selectAll(".x").data(x).enter().append("rect").attr("class", "x"); // other operation

svg.selectAll(".y").data(x).enter().append("rect").attr("class", "y"); // other operation
您可以通过以下文章深入了解d3选择和数据连接:


你能澄清一下你想要的结果和实际发生的情况吗?添加了当前输出的图像。你的问题不是匿名函数本身。这是D3中选择和附加的工作方式。它正在为尚未表示的矩形数输入一个新的矩形。当您切换数据时,您更改了rect元素的数量,因此它只需输入那些尚未出现的额外元素。阅读这里的选择。但我不知道如何解决这个问题。