【问题标题】:How to fill background colors on line-charts?如何在折线图上填充背景颜色?
【发布时间】:2021-05-17 19:18:07
【问题描述】:

我正在将一些绘图从 Plot.ly 迁移到 Chart.js v2.9,并且我正在尝试为我的新 Chart.js 绘图添加背景颜色以匹配其前身:

但是当我将适当的插件添加到我的 Chart.js 配置中时,我得到了这个:

这是我的插件代码:

 [{
  beforeDraw: function (chart, easing) {
    let config: DragenChartConfiguration = chart.config;
    if (chart.ctx) {
      if (config.dragen?.hBars) {
        var ctx = chart.ctx;
        var chartArea = chart.chartArea;

        for (const hBar of config.dragen.hBars) {
          ctx.save();
          ctx.fillStyle = hBar.color;
          ctx.fillRect(chartArea.left, hBar.from, chartArea.right - chartArea.left, hBar.to - hBar.from);
          ctx.restore();
        }
      }
    }
  }
}] 

每个“Hbar”对象只定义了一个颜色和一个我想要着色的 Y 轴范围:

hBars: Array(3)
0: {from: 28, to: 100, color: "rgb(195, 230, 195)"}
1: {from: 20, to: 28, color: "rgb(230, 220, 195)"}
2: {from: 0, to: 20, color: "rgb(230, 195, 195)"}
length: 3

我在这里错过了什么?

【问题讨论】:

    标签: plugins chart.js chart.js2


    【解决方案1】:

    您正在获取原始值而不是获取这些值的像素,如果您这样做,它将起作用:

    插件 V3:

    {
      id: 'backgrounds',
      beforeDraw: (chart, args, options) => {
        const { ctx, chartArea, scales: {y} } = chart;
        
        options.hbars.forEach((hBar) => {
          ctx.save();
          ctx.fillStyle = hBar.color;
          ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
          ctx.restore();
        })
      }
    }
    

    插件 V2:

    {
      id: 'backgrounds',
      beforeDraw: (chart, x, options) => {
        const { ctx, chartArea, scales } = chart;
        const y = scales['y-axis-0']
        
        options.hbars.forEach((hBar) => {
          ctx.save();
          ctx.fillStyle = hBar.color;
          ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
          ctx.restore();
        }) 
      }
    

    工作示例 V3:

    var options = {
      type: 'line',
      data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
        datasets: [{
            label: '# of Votes',
            data: [100, 19, 3, 5, 2, 3],
            borderWidth: 1
          },
          {
            label: '# of Points',
            data: [7, 11, 5, 8, 3, 7],
            borderWidth: 1
          }
        ]
      },
      options: {
        plugins: {
          backgrounds: {
            hbars: [{
                from: 28,
                to: 100,
                color: "rgb(195, 230, 195)"
              },
              {
                from: 20,
                to: 28,
                color: "rgb(230, 220, 195)"
              },
              {
                from: 0,
                to: 20,
                color: "rgb(230, 195, 195)"
              }
            ]
          }
        }
      },
      plugins: [{
        id: 'backgrounds',
        beforeDraw: (chart, args, options) => {
          const {
            ctx,
            chartArea,
            scales: {
              y
            }
          } = chart;
    
          options.hbars.forEach((hBar) => {
            ctx.save();
            ctx.fillStyle = hBar.color;
            ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
            ctx.restore();
          })
        }
      }]
    }
    
    var ctx = document.getElementById('chartJSContainer').getContext('2d');
    new Chart(ctx, options);
    <body>
      <canvas id="chartJSContainer" width="600" height="400"></canvas>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.0/chart.js"></script>
    </body>

    工作示例 V2:

    var options = {
      type: 'line',
      data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
        datasets: [{
            label: '# of Votes',
            data: [100, 19, 3, 5, 2, 3],
            borderWidth: 1
          },
          {
            label: '# of Points',
            data: [7, 11, 5, 8, 3, 7],
            borderWidth: 1
          }
        ]
      },
      options: {
        plugins: {
          backgrounds: {
            hbars: [{
                from: 28,
                to: 100,
                color: "rgb(195, 230, 195)"
              },
              {
                from: 20,
                to: 28,
                color: "rgb(230, 220, 195)"
              },
              {
                from: 0,
                to: 20,
                color: "rgb(230, 195, 195)"
              }
            ]
          }
        }
      },
      plugins: [{
        id: 'backgrounds',
        beforeDraw: (chart, x, options) => {
          const {
            ctx,
            chartArea,
            scales
          } = chart;
          const y = scales['y-axis-0']
    
          options.hbars.forEach((hBar) => {
            ctx.save();
            ctx.fillStyle = hBar.color;
            ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
            ctx.restore();
          })
        }
      }]
    }
    
    var ctx = document.getElementById('chartJSContainer').getContext('2d');
    new Chart(ctx, options);
    <body>
      <canvas id="chartJSContainer" width="600" height="400"></canvas>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
    </body>

    小提琴 V3:https://jsfiddle.net/Leelenaleee/6s8upz10/15/

    小提琴 V2:https://jsfiddle.net/Leelenaleee/tj71gLa2/10/

    【讨论】:

    • 谢谢,但这似乎是 v3 特定的解决方案。如何在 v2 上获取 Chart.js 上的刻度? (为了兼容一些插件,我坚持使用 v2.9.4)
    • 用 v2 语法更新了答案@BioInfoBrett
    • 非常感谢!我会在早上试一试
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    相关资源
    最近更新 更多