2014-02-10 86 views
1

我越來越瘋狂如何將工具提示添加到我的線性d3圖表,以便用戶可以看到多年來表現的具體價值。 這是小提琴:http://jsfiddle.net/d9Lya/ 這個代碼將工具提示添加到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"}); 

其實我是新來的D3和我周圍看到seveal其他樣本,我不能夠重現他們在我的js代碼。誰能幫我? Regards

+1

你見過[這個例子](http://bl.ocks.org/Matthew-Weber/5645518)? –

+0

是的,但仍然很難做到。我實際上可以添加使用工具提示:d。對( 「鼠標懸停」,功能(,I){ \t \t div.transition() \t \t .duration(200) \t \t .style( 「不透明度」, 0.9); \t \t div.html( 「在這裏我們是」) \t \t .style( 「左」,(d3.event.pageX)+ 「PX」) \t \t .style( 「頂部」,( d3.event.pageY - 28)+「px」); \t \t}) – picus

+0

但我真的不知道如何獲得Y數據以顯示真實值 – picus

回答

2

我在評論中提到「線條的數據是完整的數組,並且確定用戶的鼠標在哪一行會需要額外的計算」。這是使用「不可見圓圈」來抓取數據點上的鼠標事件的原因之一。另一個原因是可以使圓的半徑比筆畫寬度大得多,以便爲鼠標事件製作更大的區域。第三個是你可以在鼠標懸停上裝飾圓圈,就像NVD3 line charts

但是,如果你不想額外的圓形擁擠你的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]); 
} 

住在這裏例如:http://fiddle.jshell.net/c2mru/8/

d值傳遞給事件處理程序的功能是連接到<path>元素的數據對象。這通常是線上的點數組,雖然有時它是一個包含點數組作爲屬性的對象,在這種情況下,您必須修改該點以適合該點。使用d3.mouse(container),您可以計算出相關SVG座標系中的鼠標位置,並使用比例尺的反轉方法可以計算出鼠標相對於水平軸的位置。然後,假設您的數據是不重複x值的法線圖,只需滾動點陣列即可找到最接近鼠標的點。

請注意,此方法不會與@picus的原始代碼一起工作,因爲該代碼實際上並未使用d3方法將數據鏈接到元素。 (@picus,請查看Tutorials page以瞭解如何使d3更容易工作!)

+0

感謝您的意見和建議! – picus