首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何仅当Highcharts中存在值时才启用绘图?

如何仅当Highcharts中存在值时才启用绘图?
EN

Stack Overflow用户
提问于 2018-08-16 18:02:38
回答 2查看 221关注 0票数 0

我是highcharts的新手。我最近一直在绘制highcharts。我正在使用绘图带来绘制背景色。如果值存在,则必须对其进行着色;如果值不存在,则不应对其进行着色。

例如,在此图表中,对于橙色,阴影效果很好,因为正侧和负侧都有值。但是对于香蕉,阴影是不正确的。它只有正值,所以只有正边应该着色,而不是负边,即0到-2.5不应该用灰色着色。

任何帮助都是非常感谢的。

带图带的Highchart列:

代码如下:

Highcharts.chart('container', {  
  chart: {  
    type: 'column'  
  },  
  title: {  
    text: 'Column chart with negative values'  
  },  
  xAxis: {  
    categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],  
    plotBands: [{   
      color: 'gray',  
      from: 0.5,  
      to: 1.5  
    },  
    {   
      color: 'gray',  
      from: 3.5,  
      to: 4.5  
    }],  
  },  
  credits: {  
    enabled: false  
  },  
  series: [{  
    name: 'John',  
    data: [5, 3, 4, 7, 2]  
  }, {  
    name: 'Jane',  
    data: [2, -2, -2, 2, 1]  
  }, {  
    name: 'Joe',  
    data: [3, 4, 4, -2, 5]  
  }]  
});  
EN

回答 2

Stack Overflow用户

发布于 2018-08-16 22:31:50

您不能将绘图带用于您所描述的内容,因为它们将从-∞转换为∞。但是,您可以使用自定义形状并使它们看起来像打印标注栏。

首先,您需要在加载图表时触发一个函数:

chart: {
  events: {
    load: function() {
      this.customRect = [] //We use this to keep track off all the shapes we create
      addPlotbands(this); //Function to find what area should be colored in what way
    }
  }
}

然后,您需要一个函数来检测何时所有值都是正值、负值或混合值。这可以通过以下方式完成(请注意,这假设所有系列都具有完全相同的点数):

function addPlotbands(chart) {
  let series = chart.series
  let yMin = chart.yAxis[0].getExtremes().min;
  let yMax = chart.yAxis[0].getExtremes().max;

  for (let i = 0; i < series[0].data.length; i++) {
    let allAboveZero = true;
    let allBelowZero = true;
    for (let j = 0; j < chart.series.length; j++) {
      if (series[j].data[i].y >= 0) {
        allBelowZero = false;
      } else {
        allAboveZero = false;
      }
    }
    if (allAboveZero) {
      addCustomElement(chart, i, 0, yMax)
    } else if (allBelowZero) {
      addCustomElement(chart, i, yMin, 0)
    } else {
      addCustomElement(chart, i, yMin, yMax)
    }
  }
}

最后,您需要一个函数来创建自定义矩形形状,它可以像这样完成:

function addCustomElement(chart, x, yMin, yMax) { //yMin and yMax refers to the window, not the data
  let yAxis = chart.yAxis[0]
  let xAxis = chart.xAxis[0]
  chart.customRect.push(chart.renderer.rect(
    xAxis.toPixels(x - 0.5, false),                                  //Leftmost pixel
    yAxis.toPixels(yMax, false),                                     //Top pixel
    xAxis.toPixels(x + 0.5, false) - xAxis.toPixels(x - 0.5, false), //Width
    yAxis.toPixels(yMin, false) - yAxis.toPixels(yMax, false)        //Height
  )
  .attr({
    'stroke-width': 2,
    fill: 'gray',
    zIndex: -1
  })
  .add());
}

这很有效,但是当您调整窗口大小时,形状不会调整大小。这可以通过向重绘事件添加一些额外的代码来解决:

redraw: function() {
  if (this.customRect) {
    for (let i = 0; i < this.customRect.length; i++) {
      this.customRect[i].destroy(); // Remove all the old rectangles before adding any new ones
    }
    this.customRect = [] //Empty the array of shapes
    let chart = this;
    setTimeout(function() { //We use a small timeout here to make sure the user is done resizing
      addPlotbands(chart)
    }, 100);
  }
}

function addPlotbands(chart) {
  let series = chart.series
  let yMin = chart.yAxis[0].getExtremes().min;
  let yMax = chart.yAxis[0].getExtremes().max;

  for (let i = 0; i < series[0].data.length; i++) {
    let allAboveZero = true;
    let allBelowZero = true;
    for (let j = 0; j < chart.series.length; j++) {
      if (series[j].data[i].y >= 0) {
        allBelowZero = false;
      } else {
        allAboveZero = false;
      }
    }
    if (allAboveZero) {
      addCustomElement(chart, i, 0, yMax)
    } else if (allBelowZero) {
      addCustomElement(chart, i, yMin, 0)
    } else {
      addCustomElement(chart, i, yMin, yMax)
    }
  }
}

function addCustomElement(chart, x, yMin, yMax) {
  let yAxis = chart.yAxis[0]
  let xAxis = chart.xAxis[0]
  chart.customRect.push(chart.renderer.rect(
      xAxis.toPixels(x - 0.5, false), //Leftmost pixel
      yAxis.toPixels(yMax, false), //Topmost pixel
      xAxis.toPixels(x + 0.5, false) - xAxis.toPixels(x - 0.5, false), //Width
      yAxis.toPixels(yMin, false) - yAxis.toPixels(yMax, false) //Height
    )
    .attr({
      'stroke-width': 2,
      fill: 'gray',
      zIndex: -1
    })
    .add());
}

Highcharts.chart('container', {
  chart: {
    type: 'column',
    events: {
      load: function() {
        this.customRect = []
        addPlotbands(this);
      },
      redraw: function() {
        if (this.customRect) {
          for (let i = 0; i < this.customRect.length; i++) {
            this.customRect[i].destroy();
          }
          this.customRect = []
          let chart = this;
          setTimeout(function() {
            addPlotbands(chart)
          }, 100);
        }
      }
    }
  },
  title: {
    text: 'Column chart with negative values'
  },
  xAxis: {
    categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],

  },
  credits: {
    enabled: false
  },
  series: [{
    name: 'John',
    data: [5, 3, 4, 7, 2, -3],
  }, {
    name: 'Jane',
    data: [2, -2, -2, 2, 1, -1]
  }, {
    name: 'Joe',
    data: [3, 4, 4, -2, 5, -2]
  }]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>

<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>

Working JSFiddle示例: https://jsfiddle.net/ewolden/gbrjd2uk/

API REFs:

票数 0
EN

Stack Overflow用户

发布于 2018-08-17 04:04:16

除了使用plotBands之外,您还可以(由Highcharts创建)覆盖plotBands不需要的部分的白色矩形。您可以在下面找到此解决方案的响应示例:

    events: {
        render: function() {
            var chart = this,
                yAxis = chart.yAxis[0],
                xAxis = chart.xAxis[0],
                minPxY = yAxis.toPixels(yAxis.min),
                zeroPxY = yAxis.toPixels(0),
                series = chart.series,
                i,
                j,
                xValue,
                startCategory,
                endCategory,
                hasNegative;

            if (chart.correctedPlotBand) {
                Highcharts.each(chart.correctedPlotBand, function(el) {

                    el.destroy();
                });
                chart.correctedPlotBand = [];
            } else {
                chart.correctedPlotBand = [];
            }

            for (i = 0; i < series[0].points.length; i++) {
                hasNegative = false;

                for (j = 0; j < series.length; j++) {

                    if (series[j].points[i].y < 0) {
                        hasNegative = true;
                    }
                }
                if (!hasNegative) {
                    xValue = series[0].points[i].x;
                    startCategory = xAxis.toPixels(xValue - 0.5) - 1;
                    endCategory = Math.ceil(xAxis.toPixels(xValue + 0.5));

                    chart.correctedPlotBand.push(chart.renderer.rect(startCategory, zeroPxY, endCategory - startCategory, minPxY - zeroPxY)
                        .attr({
                            fill: '#fff',
                            zIndex: 0
                        })
                        .add())
                }
            }

        }
    }

现场演示:https://jsfiddle.net/BlackLabel/sm1kev4t/

接口参考:https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#rect

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51874422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档