how to highlight max and min points on lineChart

倾然丶 夕夏残阳落幕 提交于 2019-12-13 19:03:34

问题


I use dc.js lineChart and barChart. Now I need to mark the maximum and minimum values on my lineChart with 'renderArea(true)'.

I want something like in the picture below or maybe something else, but I don't know how to add this feature.

Update:

Gordon's answer is perfect. Unfortunately, my chart doesn't show the hint with 'mouseover' on marked points

One more update:

How can I redraw these points after zooming?


回答1:


This isn't something supported directly by dc.js, but you can annotate the chart with a renderlet. Gladly, dc.js makes it easy to escape out to d3 when you need custom annotations like this.

We'll use the fact that by default the line chart draws invisible dots at each data point (which only appear when they are hovered over). We'll grab the coordinates from those and use them to draw or update our own dots in another layer.

Usually we'd want to use a pretransition event handler, but those dots don't seem to have positions until after the transition, so we'll have to handle the renderlet event instead:

chart.on('renderlet', function(chart) { // 1
  // create a layer for the highlights, only once
  // insert it after the tooltip/dots layer
  var highlightLayer = chart.select('g.chart-body') // 2
    .selectAll('g.highlight-dots').data([0]);
  highlightLayer
    .enter().insert('g', 'g.dc-tooltip-list').attr('class', 'highlight-dots');
  chart.selectAll('g.dc-tooltip').each(function(_, stacki) { // 3
    var dots = d3.select(this).selectAll('circle.dot'); // 4
    var data = dots.data();
    var mini = 0, maxi = 0;
    data.forEach(function(d, i) { // 5
      if(i===0) return;
      if(d.y < data[mini].y)
        mini = i;
      if(d.y > data[maxi].y)
        maxi = i;
    });
    var highlightData = [mini, maxi].map(function(i) { // 6
      var dot = dots.filter(function(_, j) { return j === i; });
      return {
        x: dot.attr('cx'),
        y: dot.attr('cy'),
        color: dot.attr('fill')
      }
    });
    var highlights = highlightLayer.selectAll('circle.minmax-highlight._' + stacki).data(highlightData);
    highlights
      .enter().append('circle') // 7
      .attr({
      class: 'minmax-highlight _' + stacki,
      r: 10,
      'fill-opacity': 0.2,
      'stroke-opacity': 0.8
    });
    highlights.attr({ // 8
      cx: function(d) { return d.x; },
      cy: function(d) { return d.y; },
      stroke: function(d) { return d.color; },
      fill: function(d) { return d.color; }
    });
  });
});

This is fairly complicated, so let's look at it step-by-step:

  1. We're listening for the renderlet event, which fires after everything has transitioned
  2. We'll create another layer. The .data([0]).enter().insert(stuff) trick is a degenerate case of the d3 general update pattern that just makes sure an item is added exactly once. We specify the selector for the existing tooltip/dots layer as the second parameter to .insert(), in order to put this layer before in DOM order, which means behind. Also, we'll hold onto the update selection because that is either the inserted node or the existing node.
  3. We iterate through each of the stacks of tooltip-dots
  4. In each stack, we'll select all the existing dots,
  5. and iterate over all their data, finding the minimum and maximum indices mini and maxi.
  6. Now we'll create a two-element data array for binding to the min/max highlight dots, pulling data from the existing dots
  7. Now we're finally ready to draw stuff. We'll use the same degenerate update pattern to draw two dots with class minmax-highlight _1, _2, etc.
  8. And use the color and positions that we remembered in step 6

Note that the min and max for each stack is not necessarily the same as the total min and max, so the highlighted points for a higher stack might not be the highest or lowest points.

Not so simple, but not too hard if you're willing to do some d3 hacking.

Example fiddle: http://jsfiddle.net/gordonwoodhull/7vptdou5/31/



来源:https://stackoverflow.com/questions/44389484/how-to-highlight-max-and-min-points-on-linechart

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!