修复鼠标悬停功能只显示一个值 D3

Fix mouseover feature only show one value D3

好吧,我一直在努力让我的堆积面积图显示鼠标悬停时的值,我让它工作(奇迹)但它只显示一个值,无论你把鼠标移到哪里.因此,当我进入 5 种不同颜色中的任何一种时,它只显示整个颜色的一个值,无论鼠标在哪里。我能得到一些帮助解决这个问题吗?

这是我的代码:

   var t = 0;
   var n = 40;
   var dnsData = getDNS();
   var connectData = getConnect();
   var SSLData = getSSL();
   var sendData = getSend();
   var serverBusyData = getServerBusy();
   var receiveData = getReceive();


function getDNS() {
    var time = 0;
    var arr = [];
    for(var i=0; i<bardata.length; i++){
        var obj = {
            time: i,
            value: bardata[i].aggs.dns.avg
        };
        arr.push(obj);
    }
    t=time;
    return arr;
}

function getConnect() {
   var time = 0;
   var arr = [];
   for (var i = 0; i < bardata.length; i++) {
       var obj = {
           time: i,
           value: bardata[i].aggs.con.avg + bardata[i].aggs.dns.avg
       };
       arr.push(obj);
   }
   t = time;
   return arr;
}

function getSSL() {
   var time = 0;
   var arr = [];
   for (var i = 0; i < bardata.length; i++) {
       var obj = {
           time: i,
           value: bardata[i].aggs.ssl.avg + bardata[i].aggs.con.avg + bardata[i].aggs.dns.avg
       };
       arr.push(obj);
   }
   t = time;
   return arr;
}

function getSend() {
   var time = 0;
   var arr = [];
   for (var i = 0; i < bardata.length; i++) {
       var obj = {
           time: i,
           value: bardata[i].aggs.snd.avg + bardata[i].aggs.ssl.avg + bardata[i].aggs.con.avg + bardata[i].aggs.dns.avg
       };
       arr.push(obj);
   }
   t = time;
   return arr;
}

function getServerBusy() {
   var time = 0;
   var arr = [];
   for (var i = 0; i < bardata.length; i++) {
       var obj = {
           time: i,
           value: bardata[i].aggs.srvbsy.avg + bardata[i].aggs.snd.avg + bardata[i].aggs.ssl.avg + bardata[i].aggs.con.avg + bardata[i].aggs.dns.avg
       };
       arr.push(obj);
   }
   t = time;
   return arr;
}

function getReceive() {
   var time = 0;
   var arr = [];
   for (var i = 0; i < bardata.length; i++) {
       var obj = {
           time: i,
           value: bardata[i].aggs.rcv.avg + bardata[i].aggs.srvbsy.avg + bardata[i].aggs.snd.avg + bardata[i].aggs.ssl.avg + bardata[i].aggs.con.avg + bardata[i].aggs.dns.avg
       };
       arr.push(obj);
   }
   t = time;
   return arr;
}

var margin = {
    top: 10,
    right: 10,
    bottom: 20,
    left: 40
},
   width = 760 - margin.left - margin.right,
   height = 425 - margin.top - margin.bottom;

var x = d3.scale.linear()
    .domain([t, n + 1])
    .range([0, width]);

var y = d3.scale.linear()
    .domain([0, 2500])
    .range([height, 0]);

var line = d3.svg.area()
    .interpolate("basis")
    .x(function (d, i) {
        return x(d.time);
     })
    .y0(function (d, i) {
        return y(d.value);
     })
    .y1(function(d, i){
        return height;
    });

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom);

var g = svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

 // extra svg to clip the graph and x axis as they transition in and out
var graph = g.append("svg")
    .attr("width", width)
    .attr("height", height + margin.top + margin.bottom);

var xAxis = d3.svg.axis().scale(x).orient("bottom");
var axis = graph.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(x.axis = xAxis);

/****************ADDED THESE TWO CHUNKS************************/
var focus = graph.append("svg")
    .style("display", "none");

focus.append("circle")
    .attr("class", "y")
    .style("fill", "none")
    .style("stroke", "black")
    .attr("r", 4);
/****************ADDED THESE TWO CHUNKS************************/

g.append("g")
    .attr("class", "y axis")
    .call(d3.svg.axis().scale(y).orient("left"));

var path5 = graph.append("g")
    .append("path")
    .data([receiveData])
    .attr("class", "receiveLine")
    .style({'fill':'#005266'})
    .append("title")
        .text(function(d, i){return d[i].value});

var path4 = graph.append("g")
    .append("path")
    .data([serverBusyData])
    .attr("class", "serverBusyLine")
    .style({'fill':'#008FB2'})
    .on("mouseover", function(){ focus.style("display", null); })
    .on("mouseout", function() { focus.style("display", "none"); })
    .on("mousemove", mousemove);

var path3 = graph.append("g")
    .append("path")
    .data([sendData])
    .attr("class", "sendLine")
    .style({'fill':'#00CCFF'})
    .on("mouseover", function(){ focus.style("display", null); })
    .on("mouseout", function() { focus.style("display", "none"); })
    .on("mousemove", mousemove);

var path2 = graph.append("g")
    .append("path")
    .data([SSLData])
    .attr("class", "SSLLine")
    .style({'fill':'#4DDBFF'})
    .on("mouseover", function(){ focus.style("display", null); })
    .on("mouseout", function() { focus.style("display", "none"); })
    .on("mousemove", mousemove);

var path1 = graph.append("g")
    .append("path")
    .data([connectData])
    .attr("class", "connectLine")
    .style({'fill':'#99EBFF'})
    .on("mouseover", function(){ focus.style("display", null); })
    .on("mouseout", function() { focus.style("display", "none"); })
    .on("mousemove", mousemove);

var path0 = graph.append("g")
    .append("path")
    .data([dnsData])
    .attr("class", "connectLine")
    .style({'fill':'#E6FAFF'})
    .on("mouseover", function(){ focus.style("display", null); })
    .on("mouseout", function() { focus.style("display", "none"); })
    .on("mousemove", mousemove);

   tick();

   function tick() {
      graph.select(".connectLine")
         .attr("d", line);

      graph.select(".SSLLine")
         .attr("d", line);

      graph.select(".sendLine")
         .attr("d", line);

      graph.select(".serverBusyLine")
         .attr("d", line);

      graph.select(".receiveLine")
         .attr("d", line);
   }

/****************ADDED THESE TWO CHUNKS************************/
var bisectDate = d3.bisector(function(d){return d.value;}).left;

function mousemove(){
    var x0 = x.invert(d3.mouse(this)[0]),
        i = bisectDate(line, x0, 1),
        d0 = line[i - 1],
        d1 = line[i];
}
/****************ADDED THESE TWO CHUNKS************************/

这是 fiddle:https://jsfiddle.net/5kkv0ct4/ 我感谢所有帮助!!

作为一种快速(但不是那么优雅)的解决方案,您可以监听 graph SVG 上的鼠标移动,然后使用鼠标坐标的倒数(域值)更新工具提示的文本相对于 y 尺度。

因此,在您的 graph 变量上调用以下代码:

graph
    .on("mousemove", function() {
        d3.selectAll("path").select("title").text(y.invert(d3.mouse(this)[1]));
    });