如何在 D3 中静态定位元素

How to statically position elements in D3

我目前有一个折线图,如下所示:

在 jsfiddle 上 http://jsfiddle.net/vertaire/kttndjgc/1/

我一直在尝试手动定位图表上的值,以便将它们打印在图例旁边,如下所示:

我尝试手动设置位置,但是当我尝试调整定位时,该定位似乎是相对于直线上的圆的位置,如下所示:

如何设置坐标以使值显示在图例旁边?

这是打印值的代码片段:

    var mouseCircle = causation.append("g") // for each line, add group to hold text and circle
      .attr("class","mouseCircle"); 

mouseCircle.append("circle") // add a circle to follow along path
  .attr("r", 7)
  .style("stroke", function(d) { console.log(d); return color(d.key); })
  .style("fill", function(d) { console.log(d); return color(d.key); })
  .style("stroke-width", "1px"); 

mouseCircle.append("text")
  .attr("transform", "translate(10,3)"); // text to hold coordinates

.on('mousemove', function() { // mouse moving over canvas
      if(!frozen) {
      d3.select(".mouseLine")
      .attr("d", function(){
          yRange = y.range(); // range of y axis
          var xCoor = d3.mouse(this)[0]; // mouse position in x
          var xDate = x.invert(xCoor); // date corresponding to mouse x 
          d3.selectAll('.mouseCircle') // for each circle group
              .each(function(d,i){
                 var rightIdx = bisect(data[1].values, xDate); // find date in data that right off mouse
                 yVal = data[i].values[rightIdx-1].VALUE;
                 yCoor = y(yVal); 
                 var interSect = get_line_intersection(xCoor,  // get the intersection of our vertical line and the data line
                      yRange[0], 
                      xCoor, 
                      yRange[1],
                      x(data[i].values[rightIdx-1].YEAR),
                      y(data[i].values[rightIdx-1].VALUE),
                      x(data[i].values[rightIdx].YEAR),
                      y(data[i].values[rightIdx].VALUE));

              d3.select(this) // move the circle to intersection
                  .attr('transform', 'translate(' + interSect.x + ',' + interSect.y + ')');

              d3.select(this.children[1]) // write coordinates out
                  .text(xDate.getFullYear() + "," + yVal);
                  yearCurrent = xDate.getFullYear();
                  console.log(yearCurrent)
                  return yearCurrent;

              });

          return "M"+ xCoor +"," + yRange[0] + "L" + xCoor + "," + yRange[1]; // position vertical line
      });
      }
  });

我要做的第一件事是动态创建图例,而不是对每个项目进行硬编码:

var legEnter = chart1.append("g")
      .attr("class","legend")
      .selectAll('.legendItem')
      .data(data)
      .enter();

  legEnter.append("text")
      .attr("class","legendItem")
      .attr("x",750)
      .attr("y", function(d,i){
        return 6 + (20 * i);  
      })
      .text(function(d){
          return d.key;
      }); 

  legEnter.append("circle")
      .attr("cx",740)
      .attr("cy", function(d,i){
        return 4 + (20 * i);  
      })
      .attr("r", 7)
      .attr("fill", function(d,i){
        return color(d.key); 
      });

即使保留原样,这里的关键是给每个 text 分配一个 legendItem 的 class。然后在鼠标悬停时,找到它并更新它的值:

d3.select(d3.selectAll(".legendItem")[0][i])   // find it by index               
  .text(function(d,i){
    return d.key + ": " + xDate.getFullYear() + "," + yVal;
  });

已更新 fiddle