Highcharts:areaplinerange,填充颜色,考虑范围的方向

时间:2016-12-22 22:14:29

标签: highcharts

我想填补两条线之间的空间,这两条线通常一前一后地上下移动,但有时一条线在另一条线之上,有时则是另一条线。而且我希望填充颜色能够反映哪条线位于顶部。

this为例。在7月6日到7月7日范围的下端和上端交叉的地方,我希望填充颜色发生变化。这可能吗?

$(function () {

    var ranges = [
            [1246406400000, 14.3, 27.7],
            [1246492800000, 14.5, 27.8],
            [1246579200000, 15.5, 28.6],
            [1246665600000, 16.7, 28.7],
            [1246752000000, 16.5, 25.0],
            [1246838400000, 17.8, 22.7],
            // low-high becomes high-low here
            [1246924800000, 20.8, 19.5],
            [1247011200000, 21.4, 17.5],
            [1247097600000, 23.8, 15.2],
            [1247184000000, 21.8, 14.6],
            [1247270400000, 23.7, 13.7],
            [1247356800000, 23.3, 13.0],
            [1247443200000, 23.7, 12.6],
            [1247529600000, 20.7, 12.8]
        ]


    Highcharts.chart('container', {

        title: {
            text: 'Cross-over'
        },

        xAxis: {
            type: 'datetime'
        },

        yAxis: {
            title: {
                text: null
            }
        },

        tooltip: {
            crosshairs: true,
            shared: true,
            valueSuffix: '°C'
        },

        legend: {
        },

        series: [{
            name: 'Range',
            data: ranges,
            type: 'areasplinerange',
            lineWidth: 0,
            linkedTo: ':previous',
            color: Highcharts.getOptions().colors[0],
            fillOpacity: 0.3,
            zIndex: 0
        }]
    });
});

1 个答案:

答案 0 :(得分:0)

我建议使用以下数学概念:https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection,但它仅适用于直线,因此,如果要使用它,则必须将图表的类型从areaplinerange更改为arearange。

检查相交坐标的JS函数:

function checkLineIntersection(a1, a2) {
  if (a1 && a2) {
    var saX = a2.x - a1.x,
      saY = a2.high - a1.high,
      sbY = a2.low - a1.low,
      sabX = a1.plotX - a2.plotX,
      sabY = a1.high - a1.low,
      u,
      t;


    u = (-saY * sabX + saX * sabY) / (-saX * saY + saX * sbY);
    t = (saX * sabY - sbY * sabX) / (-saX * saY + saX * sbY);

    if (u >= 0 && u <= 1 && t >= 0 && t <= 1) {
      return {
        plotX: a1.x + (t * saX),
        plotY: a1.high + (t * saY)
      };
    }
  }

  return false;
}

使用Highcharts方法计算区域并正确更新序列:

chart: {
  events: {
    load() {
      let chart = this,
        series = chart.series[0],
        data = series.data,
        cross,
        negative = true,
        howManyIntersections = 0,
        zones = [];

      data.forEach((point, i) => {
        if (point.low > point.high && negative) {
          howManyIntersections++;
          negative = !negative;
          cross = checkLineIntersection(data[i - 1], point)
          zones.push({
            value: cross.plotX,
            fillColor: 'red'
          })
        } else if (point.low < point.high && !negative) {
          howManyIntersections++;
          negative = !negative;
          cross = checkLineIntersection(data[i - 1], point)
          zones.push({
            value: cross.plotX,
            fillColor: 'green'
          })
        }
      })

      if (howManyIntersections % 2) {
        zones.push({
          fillColor: 'green'
        })
      } else {
        zones.push({
          fillColor: 'red'
        })
      }

      series.update({
        zones: zones
      })

    }
  }
},

jsFiddle:https://jsfiddle.net/BlackLabel/0qzsm83j

我有力量!