d3.js 多线图上的点(符号)颜色

dot (symbol) color on d3.js multiline chart

我正在尝试复制 this 带点的多线图表示例。我的数据基本相同,我在第一层有一个对象 namevalues,然后在第二层 values 中有几个值。在大多数情况下,我的代码有效,但由于某种原因,匿名函数中的 j 索引用于填充 returns 重复的数组 circle 而不是返回当前的父级元素。我相信这可能与我创建 svg 和选择元素的方式有关,但我无法弄清楚。下面是我的代码摘录,展示了我是如何创建 svg、直线路径和圆圈的。

var svgb = d3.select("body")
       .append("svg")
       .attr("id","svg-b")
       .attr("width", width)
       .attr("height", height)

var gameb = svgb.selectAll(".gameb")
                .data(games)
                .enter()
                .append("g")
                .attr("class", "gameb");

gameb.append("path")
     .attr("class", "line")
     .attr("d", function(d) {return line_count(d.values); })
     .style("stroke", function(d) { return color(d.name); })
     .style("fill", "none");

gameb.selectAll("circle")
     .data(function(d) {return d.values;})
     .enter()
     .append("circle")
     .attr("cx", function(d) {return x(d.date);})
     .attr("cy", function(d) {return y_count(d.count);})
     .attr("r", 3)
     .style("fill", function(d,i,j) {console.log(j)
                                return color(games[j].name);});

j(或更准确地说,第三个参数)将始终是选择中的节点(此处为圆圈数组),而不是父节点。如果你想要父数据,你可以使用:

 .attr("fill", function() { 
   let parent = this.parentNode;
   let datum = d3.select(parent).datum();
   return color(datum.name);
  })

请注意,使用 ()=> 而不是 function() 将更改 this 上下文,上述内容将不起作用。

但是,您可以使用 a 或父项 g 也为圆圈着色,而不是单独为每个圆圈着色:

gameb.append("g")
     .style("fill", function(d) { return color(d.name); })
     .selectAll("circle")
     .data(function(d) {return d.values;})
     .enter()
     .append("circle")
     .attr("cx", function(d) {return x(d.date);})
     .attr("cy", function(d) {return y_count(d.count);})
     .attr("r", 3);

这里我们添加一个中间体 g(尽管我们可以使用原始父级并进行一些额外的修改),为其应用填充颜色,然后父级 g 将为子级着色圈子给我们。数据在幕后传递给这个新 g