如何动态设置chart.js背景颜色渐变?

时间:2019-05-23 21:14:23

标签: javascript chart.js chart.js2

我正在创建一个React应用,并使用chart.js显示来自https://www.coindesk.com/api的历史比特币价格数据

我希望根据所显示的数据对图表的背景进行颜色编码。如果数据中的特定点较低,则背景应为红色。如果高,则应为绿色。在中间的某个地方,应该是黄色的。

我可以使屏幕显示各种颜色,但它们并没有按预期与图形上的点对齐。

example chart

谷底应该是红色,峰顶应该是绿色,但是它们并不完全匹配。

我已经看过这两个堆栈溢出帖子,但是它们并没有我所需要的。 Chart.js and gradient background color Chart.js line chart set background color

我还对HTML画布进行了更多研究,以查看我是否弄错了宽度。我不这么认为,但这仍然是可能的。

class PriceIndexChart extends Component {
  state = {
    labels: [],
    data: [],
  }

  async getPriceIndexData() {
    const response = await fetch('https://api.coindesk.com/v1/bpi/historical/close.json?start=2019-05-11&end=2019-05-23');
    let data = await response.json();
    return data;
  }

  componentDidMount() {
    this.getPriceIndexData()
      .then(d => this.setState({
        labels: Object.keys(d.bpi),
        data: Object.values(d.bpi)     
      }))
      .catch(err => console.log(err))
  }


  getColorStopColors = () => {
    const colors = ['rgba(231, 76, 60, 1)', 'rgba(241, 196, 15, 1)', 'rgba(46, 204, 113, 1)'];
    const numArr = [...this.state.data];
    const sortArr = [...numArr].sort((a,b) => a - b);
    const breakPoint = Math.floor(numArr.length / 3);
    const firstThird = sortArr[breakPoint];
    const secondThird = sortArr[breakPoint * 2];
    const max = Math.max(...numArr);

    let output = [];

    for (let n of numArr) {
      switch (true) {
        case n <= firstThird:
          output.push(this.getRGBA(n, firstThird, colors[0]));
          break;
        case n <= secondThird:
          output.push(this.getRGBA(n, secondThird, colors[1]));
          break;
        case n > secondThird:
          output.push(this.getRGBA(n, max, colors[2]));
          break;
        default:
          console.log('something went wrong');
          break;
      }
    }
    return output;
  }

  getRGBA = (num, max, clr) => {
    return `rgba(${chroma(clr).alpha(num / max)._rgb.join(', ')})`;
  }

  getColorStopStops = () => {
    const length = this.state.data.length;
    let output = [];
    for (let i in this.state.data) {
      output.push(i / length);
    };
    return output;
  }

  setColorGradient = (canvas) => {
    const width = canvas.clientWidth;
    const ctx = canvas.getContext('2d');
    console.log(ctx);
    const gradient = ctx.createLinearGradient(0, 0, width, 0);
    const grdntStops = this.getColorStopStops();
    const grdntColors = this.getColorStopColors();
    for (let i = 0; i < this.state.data.length; i++) {
      gradient.addColorStop(grdntStops[i], grdntColors[i]);
    }
    // console.log(grdntStops, grdntColors);
    return gradient;
  }

  makeChart = canvas => {
    const chartData = {
      labels: this.state.labels,
      datasets: [
        {
          label: 'bitcoin price',
          data: this.state.data,
          backgroundColor: this.setColorGradient(canvas),
          pointHoverBackgroundColor: 'rgba(254, 202, 87, 1)',
          borderColor: 'rgba(10, 189, 227, .8)',
          borderWidth: 5,
          borderJoinStyle: 'round',
          lineTension: .2,
        },
      ]
    }
    return chart;
  }

0 个答案:

没有答案