【问题标题】:Chartjs gradient background color based on min and max valuesChartjs 基于最小值和最大值的渐变背景颜色
【发布时间】:2020-12-02 19:34:21
【问题描述】:

我正在使用带有 vue-chart 的 chartjs 在我的应用程序中显示一些数据,实际上我想要实现的是有一个背景颜色从红色到绿色的条形图。

图表具有动态最小值和最大值,但不能小于 0 和大于 5。类似于 5 星评级。

为了显示显示数据的差异,我没有将图表的最小值/最大值从 0 固定到 5。

目前这是显示我的图表的代码:

选项:

  • min比最小值-0.2但不小于0;

  • max 比最大值 +0.2 但不大于 5;

    return {
      legend: {
        display: false
      },
      scales: {
        yAxes: [
          {
            ticks: {
              beginAtZero: true,
              min,
              max,
              stepSize: 0.5
            }
          }
        ]
      }
    }
    

条形图数据:

  return {
    labels: this.labels,
    datasets: [
      {
        label: 'Evaluation',
        data: [
          this.photo.composition,
          this.photo.technique,
          this.photo.creativity,
          this.photo.content,
          this.photo.lighting
        ],
        borderWidth: 1
      }
    ]
  }

渲染图表:

  const gradient = this.$refs.canvas
    .getContext('2d')
    .createLinearGradient(0, 300, 0, 0)
  gradient.addColorStop(0, '#FF5722')
  gradient.addColorStop(0.5, '#FFC107')
  gradient.addColorStop(1, '#8BC34A')

  this.data.datasets[0].backgroundColor = gradient
  this.renderChart(this.data, this.options)

结果非常接近我正在寻找的结果:

不幸的是,我希望看到的是 0 上的红色和 5 上的绿色,因此如果最大值为 2.5(这里我希望为橙色)渐变不应该达到绿色,而对于较低的值也是如此......我希望它有意义。 有人可以指出我正确的方向吗?谢谢!

【问题讨论】:

    标签: javascript vue.js chart.js


    【解决方案1】:

    Plugin Core API 提供了一系列可用于执行自定义代码的挂钩。您可以使用 afterLayout 挂钩为 y 轴创建一个渐变,以扩展所需区域(值 0 到 5)。

    let yAxis = chart.scales["y-axis-0"];
    let yBottom = yAxis.getPixelForValue(0);
    let yTop = yAxis.getPixelForValue(5);          
    let gradient = ctx.createLinearGradient(0, yBottom, 0, yTop);  
    

    请看下面的示例,看看它是如何工作的。

    const data = [2, 2.25, 3.3];
    
    new Chart(document.getElementById("chart"), {
      type: "bar",
      plugins: [{
        afterLayout: chart => {
          let ctx = chart.chart.ctx;
          ctx.save();
          let yAxis = chart.scales["y-axis-0"];
          let yBottom = yAxis.getPixelForValue(0);
          let yTop = yAxis.getPixelForValue(5);          
          let gradient = ctx.createLinearGradient(0, yBottom, 0, yTop);   
          gradient.addColorStop(0, '#FF5722');           
          gradient.addColorStop(0.5, '#FFC107'); 
          gradient.addColorStop(1, '#8BC34A');           
          chart.data.datasets[0].backgroundColor = gradient;
          ctx.restore();
        }
      }],
      data: {
        labels: ["A", "B", "C"],
        datasets: [{
          label: "Evaluation",
          data: data
        }]
      },
      options: {
        scales: {
          yAxes: [{
            ticks: {
              min: Math.min(...data) - 0.2,
              max: Math.max(...data) + 0.2,
              stepSize: 0.5
            }
          }]
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
    <canvas id="chart" height="80"></canvas>

    【讨论】:

    • 嗨!感谢您的回答!我认为这会对我有所帮助。我只是不明白我应该如何以及在哪里将这个额外的代码放在 vue-chart 中。我不使用 元素,而是使用内部有画布的组件 。我很确定有办法做到这一点,但我在文档中找不到它。
    • 这太棒了@uminder,如果我也问你一个半径渐变是不是太过分了?我真的不明白在createRadiusGradient 中输入哪些数字...谢谢
    • 如果你能这么好意,我专门为它创建了一个问题,谢谢:stackoverflow.com/questions/65127233/…
    • @Ayeye Brazo:很抱歉,到目前为止我从未使用过createRadiusGradient
    猜你喜欢
    • 2021-03-09
    • 1970-01-01
    • 2014-08-12
    • 2018-09-13
    • 1970-01-01
    • 2012-03-15
    • 2022-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多