2013-04-04 104 views
2

我是D3的新手,我的要求是獲取多個線圖併爲他們提供工具提示。D3中多線圖的工具提示

我可以得到多線圖出現,但我得到多個工具提示點錯誤。

我是javascript新手。所以任何幫助將不勝感激。

這是我的代碼。

<script> 

function showData(obj, d) { 
var coord = d3.mouse(obj); 
var infobox = d3.select(".infobox"); 
// now we just position the infobox roughly where our mouse is 
infobox.style("left", (coord[0] + 200) + "px"); 
infobox.style("top", (coord[1] - 130) + "px"); 
$(".infobox").html(d); 
$(".infobox").show(); 
} 

function hideData() { 
$(".infobox").hide(); 
} 

    var xx,yy; 
    function xx(e) { 
    return x(e.date); }; 
    function yy(e) { 
    return y(e.returns); }; 

var draw = function() { 

     var margin = {top:100,left:200,right:200,bottom:100}, 
     width = 1150 - margin.left - margin.right, 
     height = 500 - margin.top - margin.bottom; 


     var parseDate = d3.time.format("%Y-%m-%d").parse; 

     x = d3.time.scale().range([0,width]); 

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

     //values of the axis is plotted here 
     var xAxis = d3.svg.axis().scale(x).orient("bottom"); 

     var yAxis = d3.svg.axis().scale(y).orient("left"); 

     var svg = d3.select("#chart").append("svg") 
        .attr("width" , width + margin.left + margin.right) 
        .attr("height" , height + margin.top + margin.bottom) 
        .attr("pointer-events" , "all") 
       .append("g") 
        //this is the line that positions the graph 
       .attr("transform" , "translate(" + margin.left + "," + margin.top +") ");  

     var activeReturns = new Array(); 
     var passiveReturns = new Array(); 
     var D3Obj = new Array(); 

     var line = d3.svg.line() 
       .interpolate("basis") 
       .x(function(d) { return x(d.date); }) 
       .y(function(d) { return y(d.returns);}); 

     d3.json("d3.v3/sample1.json",function(error,result) { 
     result.data.forEach(function(d){ 

      var arObj = new Object(); 
      arObj.date = parseDate(d.date); 
      arObj.returns = +d.returns; 

      var prObj = new Object(); 
      prObj.date = parseDate(d.date); 
      prObj.returns = +d.ticker_performance; 

      activeReturns.push(arObj); 
      passiveReturns.push(prObj); 

     }); 

     D3Obj.push(activeReturns); 
     D3Obj.push(passiveReturns); 


     // this is where i tell that the line graph to be done 


    x.domain(d3.extent(D3Obj[0], function(d) {return d.date ;})); 
    y.domain(d3.extent(D3Obj[0], function(d) {return d.returns ;})); 

    svg.append("g") 
     .attr("class" , "x axis") 
     .call(xAxis) 
     .attr("transform","translate(0 ,"+ height + ")") 


    svg.append("g") 
     .attr("class" , "y axis") 
     //this is where yaxis line is added 
     .call(yAxis) 
    .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 6) 
     .attr("dy", ".71em") 
     .style("text-anchor", "end") 
     .text("Price ($)"); 

    svg.selectAll(".line") 
    .data(D3Obj) 
    .enter().append("path") 
    .attr("class","line") 
    .attr("d",line) 

//this is where i am adding the tooltips 
//tooltip for 1st line 
svg.selectAll("circle") 
.data(D3Obj[0]) 
.enter().append("circle") 
.attr("fill", "red") 
.attr("r", 2) 
    .attr("cx", xx) 
.attr("cy", yy) 
.on("mouseover", function(d) { showData(this, d.returns);}) 
.on("mouseout", function(){ hideData();}); 

//tooltip for 2nd line - this is where i think i am going wrong. 
svg.selectAll("circle") 
.data(D3Obj[1]) 
.enter().append("circle") 
.attr("fill", "steelblue") 
.attr("r", 2) 
    .attr("cx", xx) 
.attr("cy", yy) 
.on("mouseover", function(d) { showData(this, d.returns);}) 
.on("mouseout", function(){ hideData();}); 


}); 

$("#chart").append("<div class='infobox' style='display:none;'>Test</div>"); 

}; 
</script> 

回答

4

當您創建第二個點時,實際上沒有發生任何事情。函數.data()將嘗試將您傳遞的數據元素與您選擇的數據元素(在本例中爲一個圓圈)進行匹配,並在此處取得成功。這意味着你的輸入選擇是空的,沒有任何反應。

D3的方法是所有傳遞你想使用一次創建元素和功能的相應的處理來設置屬性等等。這是數據,你的代碼應該看起來像

svg.selectAll("circle") 
    .data(D3Obj) 
    .enter().append("circle") 
    .attr("fill", function(d, i) { if(i == 0) { return "red"; } else { return "steelblue"; } }) 
    .attr("r", 2) 
    .attr("cx", xx) 
    .attr("cy", yy) 
    .on("mouseover", function(d) { showData(this, d.returns);}) 
    .on("mouseout", function(){ hideData();}); 

這將創建兩個圓圈並將相應的偵聽器附加到它們上。