Highcharts 中的方差图

问题描述 投票:0回答:1

如何使用 Highcharts 创建方差图? Variance Chart example

我已经使用plotOptions.zones在Highcharts中成功创建了一个具有统一阈值的面积样条图。如果值超过阈值 (100),则阈值以上的区域将显示为绿色。如果该值低于阈值,则该值和阈值之间的下方区域将显示为红色。

const series = ...;
const categories = ...;
const plotOptions = {
  series: {
    threshold: 100,
    zones: [
      {
        value: 100,
        color: 'red'
      },{
        color: 'green'
      }
    ],
    marker: {
      lineWidth: 2,
      lineColor: 'blue'
    }
  }
};
Highcharts.chart('container', {
    chart: {
        type: 'areaspline'
    },
    xAxis: {
        categories: categories
    },
    plotOptions: plotOptions,
    series: series
});

单阈值小提琴 Single Threshold Image

但是,我需要创建一个“方差图”,其中阈值可以沿 x 轴逐点变化。我已尝试使用以下代码为plotOptions生成区域,但它没有生成我需要的内容。 (我相信区域应该按照阈值增加的顺序来定义。)我如何通过配置 Highcharts API 来实现这一点,或者我需要创建一个扩展?

const data = [
  { value: 29.9, threshold: 50 },
  { value: 71.5, threshold: 60 },
  { value: 106.4, threshold: 70 },
  { value: 129.2, threshold: 80 },
  { value: 144.0, threshold: 90 },
  { value: 176.0, threshold: 100 },
  { value: 135.6, threshold: 110 },
  { value: 148.5, threshold: 120 },
  { value: 216.4, threshold: 130 },
  { value: 194.1, threshold: 140 },
  { value: 95.6, threshold: 150 },
  { value: 54.4, threshold: 160 }
];
const series = [{
  data: data.map(obj => obj.value)
}];
const plotOptions = createPlotOptions(data);
// Update the thresholds dynamically
function createPlotOptions(data) {
  return {
    areaspline: {
      zones: data.map(function(d) {
        return {
          value: d.threshold,
          color: (d.value < d.threshold) ? 'red' : 'green'
        };
      })
    }
  };
}
Highcharts.chart('container', {
    chart: {
        type: 'areaspline'
    },
    xAxis: {
        categories: categories
    },
    plotOptions: plotOptions,
    series: series
});
highcharts threshold
1个回答
0
投票

我想出了一个使用堆叠样条图的解决方案,通过创建一个透明的“基础”系列来抵消目标(阈值)的值与系列中每个点的“实际”测量值。

let data = [
  { value: 70, threshold: 50 },
  { value: 71.5, threshold: 30 },
  { value: 50, threshold: 70 },
  { value: 129.2, threshold: 80 },
  { value: 95, threshold: 90 },
  { value: 120, threshold: 70 },
  { value: 115, threshold: 90 },
  { value: 80, threshold: 115 },
  { value: 180, threshold: 65 },
  { value: 150, threshold: 80 },
  { value: 95.6, threshold: 110 },
  { value: 54.4, threshold: 100 }
];

for (let i = 0; i < data.length; i++) {
    let obj = data[i];
  if (obj.value > obj.threshold) {
    obj.above = obj.value - obj.threshold;
    obj.below = 0;
    obj.base = obj.threshold;
  } else {
    obj.above = 0
    obj.below = obj.threshold - obj.value;
    // offset the base below the measured value
    obj.base = obj.value - (obj.threshold - obj.value);
  }
  data[i] = obj;
}

const series = [
{
  name: 'Above',
  type: 'areaspline',
  data: data.map(obj => obj.above),
  linkedTo: 'actual',
  color: 'rgba(0,128,0,1)'  
},
{
  name: 'Below',
  type: 'areaspline',
  data: data.map(obj => obj.below),
  linkedTo: 'actual',
  color: 'rgba(255,0,0,1)'  
},
{
  name: 'Base',
  type: 'areaspline',
  data: data.map(obj => obj.base),
  linkedTo: 'actual',
  fillOpacity: 0,
},
{
  name: 'Actual',
  id: 'actual',
  type: 'spline',
  lineWidth: 2,
  zIndex: 1,
  color: 'yellow',
  data: data.map(obj => obj.value)
},
{
  name: 'Goal',
  id: 'goal',
  type: 'spline',
  dashStyle: 'longdash',
  zIndex: 2,
  data: data.map(obj => obj.threshold)
}];

Highcharts.chart('container', {
    title: {
        text: 'Variance Chart'
    },
    tooltip: {
      shared: true,
      formatter: function() {
        // Only include Actual and Goal series in the shared tooltip.
        const points = this.points.filter(point => {
          return point.series.name === 'Actual' || point.series.name === 'Goal';
        });

        let tooltipHtml = `<b>${this.x}</b><br/>`;
        points.forEach(point => {
          tooltipHtml += `<span style="color:${point.color}">\u25CF</span> ${point.series.name}: <b>${point.y}</b><br/>`;
        });

        return tooltipHtml;
      },
    },
    xAxis: {
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },
    plotOptions: {
      spline: {
        marker: {
          enabled: true
        },
        showInLegend: true
      },
      areaspline: {
        stacking: 'normal',
        showInLegend: false
      }
    },
    series: series
});

小提琴的链接。

它看起来像这样: enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.