Диаграмма Js, как я могу получить разные цветовые заливки между моими двумя наборами данных на линейном графике? - PullRequest
0 голосов
/ 09 мая 2020

graph[1]

Выше график, который я построил с помощью Chart JS. У меня есть два набора данных. У меня также есть пространство между двумя наборами данных, заполненное так, как я хочу. Но мне нужно получить заливку двух разных цветов. Когда набор данных Hours больше, чем набор данных Goal, я хочу, чтобы заливка была зеленой, а когда набор данных Hours меньше, чем Goal, я хочу, чтобы он был красным. Я очень надеюсь, что есть способ сделать это с помощью Chart JS, чтобы мне не пришлось воссоздавать это на Canvas.

Если это важно, это Vue. Js.

Вот код для двух наборов данных:

    const dataSets = [{

        label: this.dataSetLabel,
        data: this.dataArray,
        backgroundColor: new Array(this.dataArray.length).fill('rgba(255, 0, 0, 0.8)'), // red
        borderColor: new Array(this.dataArray.length).fill('rgba(255, 0, 0, 0.8)'),
        borderWidth: 1,
        fill: '+1'
      }]
      if (this.fi !== 3) {

        dataSets.push({
          label: 'Goal',
          data: new Array(this.dataArray.length).fill(this.user.braceHours),
          type: 'line',
          backgroundColor: new Array(this.dataArray.length).fill('rgba(84, 232, 198, 0.8)'), // green
          borderColor: new Array(this.dataArray.length).fill('rgba(84, 232, 198, 0.8)'),
          borderWidth: 1,
          fill: '-1'
        })
      }

Любая помощь в этом будет принята с благодарностью.

1 Ответ

1 голос
/ 09 мая 2020

Вы можете расширить существующую линейную диаграмму , как показано в приведенном ниже фрагменте исполняемого кода.

Это решение основано на ответе { ссылка } который нужно было немного адаптировать для работы с последней стабильной версией Chart. js (2.9.3).

const goal = 2;
Chart.defaults.areaConditionalColors = Chart.defaults.line;
Chart.controllers.areaConditionalColors = Chart.controllers.line.extend({
  update: function(reset) {
    var yAxis = this.chart.scales['y-axis-0'];  
    var max = Math.max.apply(null, this.chart.data.datasets[0].data);
    var yTop = yAxis.getPixelForValue(max);
    var yGoal = yAxis.getPixelForValue(goal);
    var min = Math.min.apply(null, this.chart.data.datasets[0].data);
    var yBottom = yAxis.getPixelForValue(min);

    // build a gradient that changes the color at the goal
    var ctx = this.chart.chart.ctx;
    var gradient = ctx.createLinearGradient(0, yTop, 0, yBottom);
    var ratio = Math.min((yGoal - yTop) / (yBottom - yTop), 1);
    gradient.addColorStop(0, 'green');
    gradient.addColorStop(ratio, 'green');
    gradient.addColorStop(ratio, 'red');
    gradient.addColorStop(1, 'red');
    this.chart.data.datasets[0].backgroundColor = gradient;

    return Chart.controllers.line.prototype.update.apply(this, arguments);
  }
});

new Chart('myChart', {
  type: 'areaConditionalColors',
  data: {
    labels: ['FRI', 'SAT', 'SUN', 'MON', 'TUE', 'WED', 'THU'],
    datasets: [{
      label: 'Hours',
      backgroundColor: 'green',
      data: [0, 3, 0, 9, 4, 0, 0],
      fill: '+1'
    },
    {
      label: 'Goal',
      backgroundColor: 'rgba(84, 232, 198, 0.8)',
      data: [goal, goal, goal, goal, goal, goal, goal],
      fill: '-1'
    }]
  },
  options: {
    legend: {
      onClick: e => e.stopPropagation()
    },
    tooltips: {
      mode: 'x'
    }
  }  
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="80"></canvas>
...