D3.js:多线图的工具提示

时间:2017-06-27 06:30:38

标签: javascript d3.js

您好我使用以下帖子帮助Multiseries line chart with mouseover tooltip使用工具提示实现了多线图 但我面临以下问题, enter image description here 在所有点上都显示最高点(58),并且由于它是线性图形,因此不会显示直线上的值。

此代码如下所示:

 

    var margin = {   top : 20,
                      right : 100,
                      bottom : 100,
                      left : 60}, 
    margin2 = {       top : 430,
                      right : 10,
                      bottom : 20,
                      left : 40}, 
     width = 600 ,
     height = 500- margin.top - margin.bottom - 20,
     height2 = 500 - margin2.top - margin2.bottom - 5;
     var parseDate = d3.time.format("%Y%m%d%H").parse;
     var xScale = d3.time.scale().range([ 0, width ]),
     xScale2 = d3.time.scale().range([ 0, width ]);
     var yScale = d3.scale.linear().range([ height, 0 ]);
     var color = d3.scale.ordinal().range( [ "#48A36D", "#9788CD", "#E2AA59" ]);
     var xAxis = d3.svg.axis().scale(xScale).orient( "bottom"),
     xAxis2 = d3.svg.axis().scale(xScale2).orient("bottom");
     var yAxis = d3.svg.axis().scale(yScale).orient("left");
     var line = d3.svg.line().interpolate("linear").x( function ( d ) {
                                                return xScale(d.date);
                                            }).y(function ( d ) {
                                        return yScale(d.rating);
                                    })
     var maxY; 
        var svg = d3.select("#chart").append("svg").attr("width", width + margin.left + margin.right).attr("height",   height + margin.top + margin.bottom +100) .append("g").attr( "transform","translate(" + margin.left + ","+ margin.top + ")");
 svg.append("rect").attr("width", width).attr("height", height).attr("x", 0).attr("y", 0).attr("id", "mouse-tracker").style("fill", "transparent");
                  var context = svg.append("g")
                .attr("transform","translate(" + 0 + "," + 395 + ")")
.attr("class", "context");
       svg.append("defs").append("clipPath").attr("id","clip").append("rect")
.attr("width", width)
                  .attr("height", height);                       
    d3.json( "/a//aaaa/aaa",function ( data ) {
             var time_changed = function ( timeFormat ) {
                                                        var split = 0;
                                                        switch ( timeFormat ) {
                                                        case 'M':
                                                            split = 12;
                                                            break;
                                                        case 'H':
                                                            split = 10;
                                                            break;
                                                        case 'D':
                                                            split = 8;
                                                            break;
                                                        case 'm':
                                                            split = 6;
                                                            break;
                                                        case 'Y':
                                                            split = 4;
                                                            break;
                                                        }
 var temp = data.map(function ( d ) {dat = d.date.substring(0,10);
                                     return {data = temp;}
time_changed('d');  
 data.forEach(function ( d ) {                                                 d.date = parseDate(d.date);                                                    });
    var categories = color.domain().map(  function ( name ) {
return {
name : name,                                                                      values : data                                                                                    .map(function ( d ) {                                                                                        return {                                                                                            date : d.date,                                                                                            rating : +(d[name]),                                                                                        };                                                                                    }),                                                                            visible : (name === "A" ? true: false)
};});
                                                                     xScale.domain(d3.extent(data, function ( d ) {  return d.date; })); 
     maxY = findMaxY(categories);
      yScale.domain([ 0, maxY]);                                                  xScale2.domain(xScale.domain()); 
 var brush = d3.svg.brush().x(xScale2).on("brush", brushed);
context.append("g").attr("class", "x axis1").attr( "transform","translate(0,"+ height2 + ")").call(xAxis2);
var contextArea = d3.svg.area().interpolate("monotone").x( function ( d ) {
            return xScale2(d.date);     }) 
            .y0(height2) .y1(0); 
    context.append("path") .attr( "d",contextArea(categories[0].values))
                           .attr("fill","darkgray");
context.append("g").attr( "class", "x brush")                                                            .call(brush).selectAll("rect").attr(    "height",     height2)
                      .attr("fill", "coral");
                                                   
                svg.append("g").attr("class", "x axis").attr(  "transform",
           "translate(0," + height    + ")").attr(  "fill", "white").call(
                                                            xAxis);

      svg     .append("g") .attr("class", "y axis") .call(yAxis)
               .append("text").attr("transform",
                                                                    "rotate(-90)")    .attr("y", 6)    .attr("x", -10)   .attr("dy", ".71em")
             .attr("fill", "white") .style("text-anchor", "end")
        var issue = svg.selectAll(
                                                            ".issue").data(
                                                            categories)
                                                    .enter().append("g").attr(
                                                            "class", "issue");

                                                    issue
                                                            .append("path")
                                                            .attr("class", "line")
                                                            .style(
                                                                    "pointer-events",
                                                                    "none")
                                                            .attr(
                                                                    "id",
                                                                    function ( d ) {
                                                                        return "line-"
                                                                                + d.name
                                                                                        .replace(
                                                                                                " ",
                                                                                                "")
                                                                                        .replace(
                                                                                                "/",
                                                                                                ""); // Give
                                                                        // line id
                                                                        // of
                                                                        // line-(insert
                                                                        // issue
                                                                        // name,with
                                                                        // any
                                                                        // spaces
                                                                        // replaced
                                                                        // with no
                                                                        // spaces)   })    .attr( "d",  function ( d ) {      return d.visible ? line(d.values): null;                               })
               .attr("clip-path","url(#clip)")  .style(	"stroke", function ( d ) {  return color(d.name); });
 var legendSpace = 450 / categories.length;
 issue  .append("rect") .attr("width", 10) .attr("height", 10)
             .attr( "x",width + (margin.right / 3)  - 15)
             .attr( "y",function ( d, i ) { return (legendSpace)+ i * (legendSpace)- 8;  }) .attr( "fill", function ( d ) { return d.visible ? color(d.name): "#F1F1F2";   })
               .attr("class","legend-box") .on( "click", function ( d ) {d.visible = !d.visible;
   maxY = findMaxY(categories);
   yScale.domain([0,maxY ]);
   svg.select(".y.axis").transition().call(yAxis);
   issue.select("path")
         .transition()
         .attr("d",function (d ) {                                                                                            return d.visible ? line(d.values): null;})

issue.select("rect")
.transition()                                                                                .attr("fill",function (d ) {                                                                                         return d.visible ? color(d.name): "#F1F1F2";
});
      })
 .on(   "mouseover",  function ( d ) {
    d3
                                                                                .select(
                                                                                        this)
                                                                                .transition()
                                                                                .attr(
                                                                                        "fill",
                                                                                        function (d ) {return color(d.name);});
  d3
                                                                                .select(
                                                                                        "#line-"
                                                                                                + d.name
                                                                                                        .replace(
                                                                                                                " ",
                                                                                                                "")
                                                                                                        .replace(
                                                                                                                "/",
                                                                                                                ""))
                                                                                .transition()
                                                                                .style(
                                                                                        "stroke-width",
                                                                                        2.5);
                                                                    })

                                                            .on(
                                                                    "mouseout",
                                                                    function ( d ) {

                                                                        d3
                                                                                .select(
                                                                                        this)
                                                                                .transition()
                                                                                .attr(
                                                                                        "fill",
                                                                                        function (
                                                                                                d ) {
                                                                                            return d.visible ? color(d.name)
                                                                                                    : "#F1F1F2";
                                                                                        });

                                                                        d3
                                                                                .select(
                                                                                        "#line-"
                                                                                                + d.name
                                                                                                        .replace(
                                                                                                                " ",
                                                                                                                "")
                                                                                                        .replace(
                                                                                                                "/",
                                                                                                                ""))
                                                                                .transition()
                                                                                .style(
                                                                                        "stroke-width",
                                                                                        1.5);
                                                                    })

                                                    issue
                                                            .append("text")
                                                            .attr(
                                                                    "x",
                                                                    width
                                                                            + (margin.right / 3))
                                                            .attr(
                                                                    "y",
                                                                    function ( d, i ) {
                                                                        return (legendSpace)
                                                                                + i
                                                                                * (legendSpace);
                                                                    }) // (return
                                                            // (11.25/2
                                                            // =) 5.625)
                                                            // + i *
                                                            // (5.625)
                                                            .text(function ( d ) {
                                                                return d.name;
                                                            });

                                                    // Hover line
                                                    var hoverLineGroup = svg
                                                            .append("g").attr(
                                                                    "class",
                                                                    "hover-line");

                                                    var hoverLine = hoverLineGroup
                                                            // Create line with
                                                            // basic attributes
                                                            .append("line")
                                                            .attr("id",
                                                                    "hover-line")
                                                            .attr("x1", 10)
                                                            .attr("x2", height)
                                                            .attr("y1", 0)
                                                            .attr("y2", height + 10)
                                                            .style(
                                                                    "pointer-events",
                                                                    "none")
                                                            .style("opacity", 1e-6);
                   var hoverDate = hoverLineGroup .append('text')
                    .attr("class", "hover-text") .attr( "y",height
                                                                            - (height - 40))                                         .attr("x", width - 150)                                                        .style("fill",
                                                                    "#E6E7E8");

                                                    var columnNames = d3.keys(
                                                            data[0]) // grab the
                                                    // key values from your first
                                                    // data row these are the same
                                                    // as your column names
                                                    .slice(1); // remove the first
                                                    // column name (`date`);

                                                    var focus = issue.select("g") // create
                                                    // group elements to house
                                                    // tooltip text
                                                    .data(columnNames) // bind each
                                                    // column name date to each g
                                                    // element
                                                    .enter().append("g") // create
                                                    // one <g> for each columnName
                                                    .attr("class", "focus");

                                                    focus
                                                            .append("text")
                                                .attr("class",
                                                                    "tooltip")
                                                            .attr("fill", "white")
                                                            .attr("x", width + 20)
                                                            // position tooltips
                                                            .attr(
                                                                    "y",
                                                                    function ( d, i ) {
                                                                        return (legendSpace)
                                                                                + i
                                                                                * (legendSpace);
                                                                    }); // (return
                                                    // (11.25/2 =) 5.625) + i *
                                                    // (5.625) position tooltips

                                                    function mousemove () {
                                                        var mouse_x = d3
                                                                .mouse(this)[0]; // Finding
                                                        // mouse x position on rect
                                                        var graph_x = xScale
                                                                .invert(mouse_x);
                                                        // var mouse_y =
                                                        // d3.mouse(this)[1]; //
                                                        // Finding mouse y position
                                                        // on rect
                                                        // var graph_y =
                                                        // yScale.invert(mouse_y);
                                                        // console.log(graph_x);

                                                        var format = d3.time
                                                                .format('%b %Y');   hoverDate
                                                                .text(format(graph_x));  d3
                                                                .select(
                                                                        "#hover-line")
                                                              
                                                                .attr("x1", mouse_x)
                                                                .attr("x2", mouse_x)
                                                                .style("opacity", 1);
                           var x0 = xScale.invert(d3   .mouse(this)[0]),
                                   i = bisectDate(data, x0, 1), 
d0 = data[i - 1], d1 = data[i],
  d = x0 - d0.date > d1.date - x0 ? d1 : d0;     focus.select("text").text(function (columnName ) {                                           return (d[columnName]); });  };
 function brushed () {
   xScale .domain(brush .empty() ? xScale2.domain(): brush.extent()); 
   svg.select(".x.axis").transition().call(xAxis);
   maxY = findMaxY(categories);
   yScale.domain([ 0, maxY ]);
   svg.select(".y.axis").transition().call(yAxis);
   issue.select("path").transition().attr("d",function (d ) {
  return d.visible ? line(d.values): null; }); };
   function findMaxY ( data ) { 
     var maxYValues = data .map(function ( d ) {  if ( d.visible ) {
  return d3.max(d.values,function (value ) {return value.rating;
})   }  }); return d3.max(maxYValues);
                                                    }                                                         
var mouseG = svg.append("g")
                .attr("class", "mouse-over-effects");
mouseG.append("path")
       .attr("class", "mouse-line").style("stroke", "white") .style("stroke-width", "1px").style("opacity", "0");
var lines = document.getElementsByClassName('line');
 var mousePerLine = mouseG.selectAll('.mouse-per-line') .data(categories)
             .enter().append("g").attr("class", "mouse-per-line");
  mousePerLine.append("circle").attr("r", 7) .style("stroke", function(d) {
                                                        return color(d.name);
                                                      })
        .style("fill", function(d) {return color(d.name);})
        .style("stroke-width", "1px")  .style("opacity", "0");
        mousePerLine.append("text").attr("transform", "translate(10,3)").style("font-size", "12px").style("font-family", "cursive")
                                                     .attr("fill", "white");
 mouseG.append('svg:rect').attr('width', width).attr('height', height)
       .attr('fill', 'none').attr('pointer-events', 'all')
       .on('mouseout', function({ d3.select(".mouse-line").style("opacity","0");
 d3.selectAll(".mouse-per-line circle") .style("opacity", "0");
 d3.selectAll(".mouse-per-line text").style("opacity", "0");
                                }).on('mouseover', function() { 
                                       d3.select(".mouse-line")
                                         .style("opacity", "1");
                                      d3.selectAll(".mouse-per-line circle")
                                         .style("opacity", "1");
                                      d3.selectAll(".mouse-per-line text")
                                         .style("opacity", "1");
                                                      })
   .on('mousemove', function() {  var mouse = d3.mouse(this);
 d3.select(".mouse-line").attr("d", function() {
     var d = "M" + mouse[0] + "," + height;
      d += " " + mouse[0] + "," + 0;
      return d;  });
 d3.selectAll(".mouse-per-line").attr("transform", function(d, i) {
                          var xDate = xScale.invert(mouse[0]),
      bisect = d3.bisector(function(d) { return d.date; }).right;
     idx = bisect(d.values, xDate);
         var beginning = 0,
         end = lines[i].getTotalLength(),target = null;
while (true){target = Math.floor((beginning + end) / 2);
     pos = lines[i].getPointAtLength(target);
     if ((target === end || target === beginning) && pos.x !== mouse[0]) {
                                                                  break; }
     if (pos.x > mouse[0])      end = target;
     else if (pos.x < mouse[0]) beginning = target;
    else break;  }
    d3.select(this).select('text')
                 .text(yScale.invert(pos.y).toFixed(2));
return "translate(" + mouse[0] + "," + pos.y +")";  });
            }); }); });

有谁知道我哪里出错了 我的json格式如下: 日期:25012016 A:12 B:11 C:0.44, 日期:25012016 A:99 B:11 C:0.44,

0 个答案:

没有答案