Подсказки для нескольких линейных графиков в 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>
1 2

1 ответ:

Когда вы создаете вторую точку, на самом деле ничего не происходит. Функция .data() попытается сопоставить элементы данных, которые вы передаете, с тем, что вы выбрали (в данном случае один круг), и преуспеет в этом. Это означает, что ваш выбор enter пуст и ничего не происходит.

Способ 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();});
Это создаст два круга и присоединит к ним соответствующих слушателей.