2

我是 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

1 回答 1

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();});

这将创建两个圆圈并将相应的侦听器附加到它们。

于 2013-04-04T17:54:51.270 回答