Graph 向D3线性图添加工具提示

Graph 向D3线性图添加工具提示,graph,d3.js,tooltip,Graph,D3.js,Tooltip,我对如何在我的线性d3图表中添加工具提示越来越着迷,这样用户就可以看到这些年来性能的具体价值。 这是小提琴: 这就是代码 // define dimensions of graph var m = [20, 80, 80, 80]; // margins var w = 650 - m[1] - m[3]; // width var h = 500 - m[0] - m[2]; // height var data = [30, 28, 33] ;

我对如何在我的线性d3图表中添加工具提示越来越着迷,这样用户就可以看到这些年来性能的具体价值。 这是小提琴: 这就是代码

    // define dimensions of graph
    var m = [20, 80, 80, 80]; // margins
    var w = 650 - m[1] - m[3]; // width
    var h = 500 - m[0] - m[2]; // height


    var data = [30, 28, 33] ;
    var years = [2010, 2011, 2012] ;

    var data2 = [100, 200, 200] ;
    var years2 = [2009, 2010, 2011] ;
    var alldata = data.concat(data2);
    var allyears = years.concat(years2);

    var data3 = [200, 220, 300] ;
    var years3 = [2011, 2012, 2013] ;
    var alldata = data.concat(data2, data3);
    var allyears = years.concat(years2, years3);


    //unique vals functin
    var unique = function(origArr) {
        var newArr = [],
            origLen = origArr.length,
            found,
            x, y;
        for ( x = 0; x < origLen; x++ ) {
            found = undefined;
            for ( y = 0; y < newArr.length; y++ ) {
                if ( origArr[x] === newArr[y] ) {
                  found = true;
                  break;
                }
            }
            if ( !found) newArr.push( origArr[x] );   
        }
       return newArr;
    };


    allyears = unique(allyears);


    var x = d3.scale.linear().domain([d3.min(allyears), d3.max(allyears)]).range([0,w]);


    var y = d3.scale.linear().domain([0, (d3.max(alldata))*1.3]).range([h, 0]);


    var line = d3.svg.line()

        .x(function(d,i) { 

            return x(years[i]); 
        })

        .y(function(d) { 

            return y(d); 
        })


    var line2 = d3.svg.line()

        .x(function(d,i) { 
            return x(years2[i]); 
        })

        .y(function(d) { 

            return y(d); 
        })          

    var line3 = d3.svg.line()
        .x(function(d,i) { 
            return x(years3[i]); 
        })

        .y(function(d) { 

            return y(d); 
        })          

    // Add an SVG element with the desired dimensions and margin.
    var graph = d3.select("#graph").append("svg:svg")
        .attr("width", w + m[1] + m[3])
        .attr("height", h + m[0] + m[2])
        .append("svg:g")
        .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

    // create xAxis
    var xAxis = d3.svg.axis().scale(x).ticks(allyears.length).tickSize(-h).tickSubdivide(true);
    // Add the x-axis.
    graph.append("svg:g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + h + ")")
          .call(xAxis);


    // create left yAxis
    var yAxisLeft = d3.svg.axis().scale(y).ticks(8).orient("left");
    // Add the y-axis to the left
    graph.append("svg:g")
          .attr("class", "y axis")
          .attr("transform", "translate(-25,0)")
          .call(yAxisLeft);


    graph.append("svg:text")
        .attr("class", "title1")
        .attr("x", (w/2))
        .attr("y", 0)
        .text("Performance")
        .style({ "stroke": "Black", "fill": "Black", "stroke-width": "1px"})
        .attr("text-anchor", "middle")  
        .style("font-size", "16px") ;   



    graph.append("svg:path").attr("d", line(data)).style("stroke", "steelblue");
    graph.append("svg:text")
        .attr("class", "title1")
        .attr("x", 0)
        .attr("y", 30)
        .text("TEAM A")
        .style({ "stroke": "steelblue", "fill": "steelblue", "stroke-width": "0px"});       
    graph.append("svg:path")
    .attr("d", line2(data2)).style("stroke", "green")
    ;




        graph.append("svg:text")
                        .attr("class", "title2")
                        .attr("x", 0)
                        .attr("y", 50)
                        .text("TEAM B")
                        .style({ "stroke": "Green", "fill": "Green", "stroke-width": "0px"});         
            graph.append("svg:path").attr("d", line3(data3)).style("stroke", "red");
                graph.append("svg:text")
                        .attr("class", "title3")
                        .attr("x", 0)
                        .attr("y", 70)
                        .text("team C")
                        .style({ "stroke": "Red", "fill": "Red", "stroke-width": "0px"});
//定义图形的维度
var m=[20,80,80,80];//边距
var w=650-m[1]-m[3];//宽度
var h=500-m[0]-m[2];//高度
var数据=[30,28,33];
风险值年数=[2010、2011、2012];
VarData2=[100200200];
风险值年份2=[2009、2010、2011];
var alldata=data.concat(data2);
var allyears=年。concat(年2);
VarData3=[200220300];
风险值年份3=[2011、2012、2013];
var alldata=data.concat(数据2,数据3);
var allyears=年。concat(年2,年3);
//唯一VAL函数
var unique=函数(ORIGAR){
var newArr=[],
origLen=Origar.长度,
建立
x、 y;
对于(x=0;x
实际上,我是D3新手,我已经看到了很多其他示例,但我无法在我的js代码中重现它们。有人能帮我吗?
关于

我在评论中提到“行的数据是完整的数组,要计算出用户鼠标在行的位置需要额外的计算”。这就是使用“隐形圆圈”在数据点上抓取鼠标事件的原因之一。另一个是,您可以使圆的半径比笔划宽度大得多,以便为鼠标事件创建更大的区域。第三个是,你可以在鼠标上装饰圆圈,就像在

但是如果你不想让更多的圆圈挤满你的DOM呢。或者,如果您希望鼠标悬停事件在线路上的任何位置触发,而不仅仅是在点上,该怎么办?您仍然可以找出鼠标相对于该线的位置,并可以使用该位置在该线的数据数组中找到正确的点

d3.selectAll("path")
    .on("mouseover", findValue);

function findValue(d, i) {
    var mouseX = d3.mouse(this.parentNode)[0];
    //find the mouse's horizontal coordinate relative to the drawing container

    var dataX = x.invert(mouseX); 
       //invert the scale to find the x value at the mouse point

    //scan through the data array to find the value closest to the mouse
    var j = d.length;
    while ((j--) && (d[j].x > dataX)); //repeat until false

    var datapoint;
    if (j >= 0) {
        //d[j] will now be the first datapoint *less than* the mousepoint
        //compare it with d[j+1] to see which is closer to the mouse:
        if ( isNaN(d[j+1]) || (dataX - d[j].x < d[j+1].x - dataX) )
            datapoint = d[j];
        else
            datapoint = d[j+1];
    } else {
        //all the values in the array were greater than the mouse point, 
        //so return the first point
        datapoint = d[0];
    }

    //Do something with your datapoint value:
    alert("Crossed line " + i + " near " + [datapoint.x, datapoint.y]);
}
d3.选择全部(“路径”)
.on(“鼠标悬停”,findValue);
函数findValue(d,i){
var mouseX=d3.mouse(this.parentNode)[0];
//查找鼠标相对于图形容器的水平坐标
var dataX=x.invert(mouseX);
//反转比例以查找鼠标点处的x值
//扫描数据数组以查找最接近鼠标的值
var j=d.长度;
while((j--)&&(d[j].x>dataX));//重复,直到false
var数据点;
如果(j>=0){
//d[j]现在将是第一个小于鼠标点*的数据点
//将其与d[j+1]进行比较,以查看哪个更靠近鼠标:
if(isNaN(d[j+1])| |(dataX-d[j].x