【问题标题】:How can I fix the offset of the gradient to be aligned with the chart points(chart.js)?如何修复渐变的偏移量以与图表点(chart.js)对齐?
【发布时间】:2021-02-07 23:28:22
【问题描述】:

我尝试使用线性渐变将背景颜色放在折线图上,按趋势着色,如您在图像上看到的那样。 但不幸的是,gradient.addColorStop 的偏移量并没有与图表对齐。 我还尝试了值为 (0, 0.25, 0.5, 0.75, 1) 的硬编码偏移量,它也显示了这个问题。

const chartConfiguration = {
  type: 'line',
  data: {
    labels: ['21/12', '22/12', '23/12', '24/12', '25/12', '26/12', '27/12']
    datasets: [{
      data: [20.2, 31.2, 18.4, 20.1, 15.2, 23.6, 20.1],
      label: 'example',
      fill: true
    }]
  },
  options: {
    legend: {
      display: false
    },
    elements: {
      point: {
        radius: 0
      }
    },
    scales: {
      xAxes: [{
        gridLines: {
          color: 'rgba(0, 0, 0, 0)',
          display: false
        },
        ticks: {
          display: false
        }
      }],
      yAxes: [{
        gridLines: {
          color: 'rgba(0, 0, 0, 0)',
          display: false
        },
        ticks: {
          beginAtZero: true,
          display: false
        }
      }]
    }
  },
  plugins: [{
    beforeInit: (chartInstance, options) => {
      let trend: 'positive' | 'negative' = data[0] < data[1] ? 'positive' : 'negative';
      let startPosition = 0;
      let numOfItems = 0;
      const dim = 1 / (data.length - 1);
      const gradient = chartInstance.ctx.createLinearGradient(0, 0, 270, 0);

      for (let i = 0; i < data.length - 1; i++) {
        const newTrend = data[i] < data[i + 1] ? 'positive' : 'negative';
        if (newTrend !== trend) {
          const endPosition = startPosition + dim * numOfItems;
          addFillColor(startPosition, endPosition, trend, gradient);
          trend = newTrend;
          startPosition += dim * numOfItems;
          numOfItems = 1;
        } else {
          numOfItems++;
        }
      }

      addFillColor(startPosition, 1, trend, gradient);
      chartInstance.data.datasets[0].backgroundColor = gradient;
    }
  }]
}

const addFillColor = (startPosition: number, endPosition: number, trend: 'positive' | 'negative', gradient: CanvasGradient) => {
  const color = trend === 'positive' ? 'green' : 'red';
  gradient.addColorStop(startPosition, color);
  gradient.addColorStop(endPosition, color);
};

【问题讨论】:

  • 您使用的是哪个库? chart.jsechart?
  • 我使用chart.js

标签: javascript charts frontend chart.js


【解决方案1】:

您需要包含创建gradient 所需属性(leftright)的xAxis 以及getPixelForTick 方法来计算色标的offset

请在下面查看您修改后的代码,看看它是如何工作的。

new Chart('myChart', {
  type: 'line',
  plugins: [{
    afterLayout: chart => {
      let ctx = chart.chart.ctx;
      ctx.save();
      let xAxis = chart.scales['x-axis-0'];
      let gradient = ctx.createLinearGradient(xAxis.left, 0, xAxis.right, 0);
      let data = chart.data.datasets[0].data;
      let color;
      data.forEach((v, i) => {
        let x = xAxis.getPixelForTick(i) - xAxis.left;
        let offset = 1 / (xAxis.right - xAxis.left) * x;
        if (color) {
          gradient.addColorStop(offset, color);
        }
        if (i < data.length) {
          color = data[i + 1] > v ? 'green' : 'red'; 
          gradient.addColorStop(offset, color);
        }
      });
      chart.data.datasets[0].backgroundColor = gradient;
      ctx.restore();
    }
  }],
  data: {
    labels: ['21/12', '22/12', '23/12', '24/12', '25/12', '26/12', '27/12'],
    datasets: [{
      data: [20.2, 31.2, 18.4, 20.1, 15.2, 23.6, 20.1],
      label: 'example',
      fill: true
    }]
  },
  options: {
    legend: {
      display: false
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="90"></canvas>

【讨论】:

    猜你喜欢
    • 2017-04-23
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多