如何绘制chartJs的特定区域?

Posted

技术标签:

【中文标题】如何绘制chartJs的特定区域?【英文标题】:How to paint specific area of chartJs? 【发布时间】:2021-01-02 00:36:48 【问题描述】:

我有一个像下面这样的折线图(没有任何颜色)

在这个折线图中,我想给颜色直到特定的 y 轴值。当它大于 0 时,从那个值到顶部,应该像下面一样应用渐变

下面是我的解决方案

 plugins: [
        
          beforeRender: function (c, options) 
            var dataset = c.data.datasets[0];
            var yScale = c.scales['y-axis-0'];
            var yPos = yScale.getPixelForValue(0);
            let nonZeroPoint;
            for (var i = 0; i < dataset.data.length; i++) 
              if (dataset.data[i] != 0) 
                nonZeroPoint= dataset.data[i];
                break;
              
            
            const newHeight = (yPos * nonZeroPoint) / Math.max(...dataset.data);
            var gradientFill = c.ctx.createLinearGradient(0, yPos-newHeight, 0, 0);
            gradientFill.addColorStop(0.1, "#fff");
            gradientFill.addColorStop(1, "#7E0100");
            var model = c.data.datasets[0]._meta[Object.keys(dataset._meta)[0]].$filler.el._model;
            model.backgroundColor = gradientFill;
          
        
      ]

在这个解决方案中,yPos 是图表的高度。 nonZeroPoint是一个通过for循环计算出来的值,用来标识0之后的第一个数据值。

newHeight = (yPos * nonZeroPoint) / Math.max(...dataset.data);

这个公式根据顶点的高度和它的值来计算nonZeroHeight的高度。 但我无法得到预期的结果。它在下面。我该如何解决这个问题?

Codepen:https://codepen.io/Cicek96/pen/GRZBgpN

【问题讨论】:

【参考方案1】:

使用Plugin Core API 中的afterLayout 钩子,可以这样写:

plugins: [
  afterLayout: c => 
    let dataset = c.data.datasets[0];
    let yScale = c.scales['y-axis-0'];
    let yBottom = yScale.getPixelForValue(0);
    let yGradientStart = yScale.getPixelForValue(dataset.data.find(v => v > 0));
    let yTop = yScale.getPixelForValue(Math.max(...dataset.data));
    let gradientFill = c.ctx.createLinearGradient(0, yBottom, 0, yTop);
    gradientFill.addColorStop(0, "#fff");
    let offset = (yBottom - yGradientStart) / (yBottom - yTop);
    gradientFill.addColorStop(offset, "#fff");
    gradientFill.addColorStop(1, "#7E0100");
    dataset.backgroundColor = gradientFill;
  
], 

请看下面的可运行代码,看看它是如何工作的。

new Chart("chart", 
  type: 'line',
  plugins: [
    afterLayout: c => 
      let dataset = c.data.datasets[0];
      let yScale = c.scales['y-axis-0'];
      let yBottom = yScale.getPixelForValue(0);
      let yGradientStart = yScale.getPixelForValue(dataset.data.find(v => v > 0));
      let yTop = yScale.getPixelForValue(Math.max(...dataset.data));
      let gradientFill = c.ctx.createLinearGradient(0, yBottom, 0, yTop);
      gradientFill.addColorStop(0, "#fff");
      let offset = (yBottom - yGradientStart) / (yBottom - yTop); 
      gradientFill.addColorStop(offset, "#fff");
      gradientFill.addColorStop(1, "#7E0100");
      dataset.backgroundColor = gradientFill;
    
  ],
  data: 
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
      label: "My First dataset",
      borderColor: '#7E0100',
      data: [0, 120, 200, 350, 200, 120, 0]
    ]
  ,
  options: 
    scales: 
      yAxes: [
        ticks: 
          max: 500,
          stepSize: 100
        
      ]
    
  
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="chart" ></canvas>

【讨论】:

以上是关于如何绘制chartJs的特定区域?的主要内容,如果未能解决你的问题,请参考以下文章

图表区域背景颜色chartjs

如何获取使用chartjs创建的canvas图表的数据属性

使用Chartjs

chartjs 从 ajax 加载数据不能正常工作

Chartjs,气泡图,数据标签中重复值的定位问题

在 vue-chartjs 中循环遍历数组