在散点上添加工具提示,为 D3.js 版本 4 生成错误

Add Tooltip on Scatter points, error is generated for D3.js Version 4

我的问题是 - 我使用 D3 版本 4 生成了散点图。现在,我需要在鼠标悬停时向点添加工具提示。但是,我收到一条错误消息 - "setAttribute is not a function" 有人可以为我提供相同的线索,并检查函数声明是否正确吗?

https://jsfiddle.net/kunal16/be37wmaj/

   var width = 700;
var height = 700;
var padding = 70;
var myData = [12, 15, 20, 9, 17, 25, 30];
var errData = [6, 7.5, 10, 4.5, 8.5, 12.5, 15];
 var svg = d3.select("body").
          append("svg")
          .attr("width", width)
          .attr("height", height);

var yScale = d3.scaleLinear().domain([0, d3.max(myData)]).range([height/2, 0]);
var xScale = d3.scaleLinear().domain([0, d3.max(myData)]).range([0, width - 200]);
var y_ErScale = d3.scaleLinear().domain([0, d3.max(errData)]).range([height/2, 0]);
var x_ErScale = d3.scaleLinear().domain([0, d3.max(errData)]).range([0, width - 200]);
// var div = d3.select("body").append("svg")    
//     .attr("class", "tooltip")                
//     .style("opacity", 0);


var eBar = d3.select("body").append("svg");
//var x_min = 
var x_axis = d3.axisBottom()
                   .scale(xScale);

    var y_axis = d3.axisLeft()
                   .scale(yScale);

    svg.append("g")
       .attr("transform", "translate(50, 10)")
       .call(y_axis);

    var xAxisTranslate = height/2 + 10;

    svg.append("g")
            .attr("transform", "translate(50, " + xAxisTranslate  +")")
            .call(x_axis);

svg.append("g")
.selectAll("scatter-dots")
  .data(myData)  
  .enter().append("svg:circle")
  .attr("cx", function (d,i) { return xScale(myData[i]); } ) 
      .attr("cy", function (d) { return yScale(d); } ) 
      .attr("r", 3)
      .style("opacity", 0.8);


  // var errorBar = eBar.append("path")
  //   .attr("d", yScale(errData))
  //   .attr("stroke", "red")
  //   .attr("stroke-width", 1.5);
//   svg.append("g")
// .selectAll("error-bars")
//   .data(errData)  
//   .enter().append("svg:path")
//   .attr("cx", function (d,i) { return x_ErScale(errData[i]); } ) 
//       .attr("cy", function (d) { return y_ErScale(d); } ) 
     //  .attr("stroke", "red")
      // .attr("stroke-width", 1.5);

svg.append("g")
.selectAll("line")
    .data(errData)
    .enter()
  .append("line")
  .attr("class", "error-line")
  .attr("x1", function(d) {
    return x_ErScale(d);
  })
  .attr("y1", function(d) {
    return y_ErScale(d) + 30;
  })
  .attr("x2", function(d) {
    return x_ErScale(d);
  })
  .attr("y2", function(d) {
    return y_ErScale(d) + 2;
  });


  svg.append("g").selectAll("line")
    .data(errData).enter()
  .append("line")
  .attr("class", "error-cap")
  .attr("x1", function(d) {
    return x_ErScale(d) - 20;
  })
  .attr("y1", function(d) {
    return y_ErScale(d) - 30;
  })
  .attr("x2", function(d) {
    return x_ErScale(d) + 20;
  })
  .attr("y2", function(d) {
    return y_ErScale(d) - 30;
  });

  svg.append("g")
.selectAll("line")
    .data(errData)
    .enter()
  .append("line")
  .attr("class", "error-line")
  .attr("x1", function(d) {
    return x_ErScale(d);
  })
  .attr("y1", function(d) {
    return y_ErScale(d) - 30;
  })
  .attr("x2", function(d) {
    return x_ErScale(d);
  })
  .attr("y2", function(d) {
    return y_ErScale(d) - 2;
  });

 // Add Error Bottom Cap
svg.append("g").selectAll("line")
    .data(errData).enter()
  .append("line")
  .attr("class", "error-cap")
  .attr("x1", function(d) {
    return x_ErScale(d) - 20;
  })
  .attr("y1", function(d) {
    return y_ErScale(d) + 30;
  })
  .attr("x2", function(d) {
    return x_ErScale(d) + 20;
  })
  .attr("y2", function(d) {
    return y_ErScale(d) + 30;
  });

// console.log(svg.append("g").selectAll("scatter-dots"));
  var div = svg.append("g").selectAll("scatter-dots")
  .data(myData)  
  .enter()
  // .append("circle")
  .attr("class", "tooltip")             
  .style("opacity", 0)
  .on("mouseover", function(d)
  {
    div
    .transition()   
    .duration(200)
    .html(myData)
    .style("opacity", 0.8);
  })
  .on("mouseout", function(d)
  {
    div
    .transition()   
    .duration(500)
    .style("opacity", 0);
  });

请参考以上fiddle.Thanks!

加入数据以创建圈子后,无需向每个圈子添加 divs。您可以使用 mouseovermouseout 函数将听众放在圆圈上。

https://jsfiddle.net/xqqfq9hf/

var tooltip = d3.select("body").append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);

svg.append("g")
.selectAll("scatter-dots")
  .data(myData)  
  .enter().append("svg:circle")
  .attr("cx", function (d,i) { return xScale(myData[i]); } ) 
      .attr("cy", function (d) { return yScale(d); } ) 
      .attr("r", 3)
      .style("opacity", 0.8)
      .on("mouseover", function(d) {
       tooltip.transition()
         .duration(200)
         .style("opacity", .9);
       tooltip.html(d) 
         .style("left", (d3.event.pageX) + "px")
         .style("top", (d3.event.pageY - 28) + "px");
       })
     .on("mouseout", function(d) {
       tooltip.transition()
         .duration(500)
         .style("opacity", 0);
       });