如何突出显示lineChart

时间:2017-06-06 12:01:12

标签: dc.js

我使用dc.js lineChart和barChart。现在我需要用'renderArea(true)'标记lineChart上的最大值和最小值。

我想要下面的图片或其他内容,但我不知道如何添加此功能。

highlighted points in area chart

更新

戈登的回答是完美的。不幸的是,我的图表没有显示标记点上的“鼠标悬停”提示

highlighted points in area chart

还有一次更新

如何在缩放后重绘这些点?

highlighted points in area chart

1 个答案:

答案 0 :(得分:2)

这不是dc.js直接支持的内容,但您可以使用renderlet注释图表。很高兴,当你需要这样的自定义注释时,dc.js可以很容易地逃到d3。

我们将使用这样的事实:默认情况下,折线图在每个数据点绘制不可见的点(仅在它们悬停时出现)。我们将从中获取坐标并使用它们在另一层中绘制或更新我们自己的点。

通常我们想要使用pretransition事件处理程序,但这些点在转换之后似乎没有位置,因此我们必须处理renderlet事件:

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

这是相当复杂的,所以让我们一步一步地看一下:

  1. 我们正在侦听renderlet事件,该事件在所有事件都已转换后触发
  2. 我们将创建另一个图层。 .data([0]).enter().insert(stuff)技巧是d3 general update pattern的退化情况,只是确保项目只添加一次。我们将现有工具提示/点图层的选择器指定为.insert()的第二个参数,以便将此图层放在之前的DOM顺序,这意味着之后。此外,我们将保留update selection,因为它是插入的节点或现有节点。
  3. 我们遍历每个工具提示点
  4. 在每个堆栈中,我们将选择所有现有的点
  5. 并迭代所有数据,找到最小和最大索引minimaxi
  6. 现在我们将创建一个双元素数据数组,用于绑定最小/最大高光点,从现有点中提取数据
  7. 现在我们终于准备好了。我们将使用相同的退化更新模式,使用类minmax-highlight _1_2等绘制两个点。
  8. 并使用我们在步骤6中记住的颜色和位置
  9. 请注意,每个堆栈的最小值和最大值不一定与总的最小值和最大值相同,因此较高堆栈的突出显示点可能不是最高点或最低点。

    不是那么简单,但如果你愿意做一些d3黑客攻击,那么很难。

    示例小提琴:http://jsfiddle.net/gordonwoodhull/7vptdou5/31/

    min-max highlighted dots