Home > Blockchain >  chart.js change colour of line chart graph based on previous values
chart.js change colour of line chart graph based on previous values

Time:07-16

I just want to change the graph color based on previous value. Like if previous value is greater than present value-- means graph declining, I've to show red if it's vice-versa then I've to show green like this.

###Expected output###

enter image description here

For now what I'm doing is I've setting some threshold & I'm doing it.

const threshold = 97.5;

    new Chart('myChart', {
      type: 'line',
      plugins: [{
        afterLayout: chart => {
          let ctx = chart.chart.ctx;
          ctx.save();
          let yAxis = chart.scales["y-axis-0"];
          let yThreshold = yAxis.getPixelForValue(threshold);          
          let gradient = ctx.createLinearGradient(0, yAxis.top, 0, yAxis.bottom);   
          gradient.addColorStop(0, 'green'); 
          let offset = 1 / yAxis.bottom * yThreshold; 
          gradient.addColorStop(offset, 'green'); 
          gradient.addColorStop(offset, 'red'); 
          gradient.addColorStop(1, 'red');           
          chart.data.datasets[0].borderColor = gradient;
          ctx.restore();
        }
      }],
      data: {
        labels: ['1', '2', '3', '4', '5', '6','7', '8', '9','10', '11', '12','13', '14', '15','16', '17', '18','19', '20', '21','22', '23'],
        datasets: [{
          label: 'My Dataset',
          data: [97.5, 98, 99.2, 98.2, 97, 98, 98.5,97.5, 98, 99.2, 98.2, 97, 98, 98.5,97.5, 98, 99.2, 98.2, 97, 98, 98.5,98, 98.1 ],
          fill: false
        }]
      },
      options: {
        legend: {
          display: false
        }
      }
    });

output I'm getting enter image description here

You guys can help me with any suggestions pls?. Have you guys worked on similar scenarios?

CodePudding user response:

it's not exactly the same as your requirement, but results in kinda similar output,

enter image description here logic: separated the points into two lines, and plotted both on the graph,

you can tune some graph settings to get the same view.

    let redLine = [];
    let greenLine = [];
    let points = [
      { x: 1, y: 1 },
      { x: 2, y: 2 },
      { x: 3, y: 1 },
      { x: 4, y: 5 },
      { x: 5, y: 2 },
      { x: 6, y: 5 },
      { x: 7, y: 8 },
      { x: 8, y: 9 },
      { x: 9, y: 2 },
      { x: 10, y: 1 },
      { x: 11, y: 9 },
      { x: 12, y: 6 },
      { x: 13, y: 7 },
      { x: 14, y: 3 },
      { x: 15, y: 6 },
    ];
    points.forEach((point, index) => {
      let isIncreasing = false;
      if (index > 0) {
        isIncreasing = point.y > points[index - 1].y;
        (isIncreasing ? redLine : greenLine).push(NaN);
        greenLine.push(point);
        redLine.push(point);
      } else {
        // index === 1 && (isIncreasing ? greenLine : redLine).push(points[0]);
        greenLine.push(point);
        redLine.push(point);
      }
    });

const data = {
  datasets: [
  {
    data: greenLine,
    backgroundColor: 'rgb(165, 95, 0,0.3)',
    borderColor: 'rgb(0, 255, 0)',
    borderWidth: 1,
    showLine: true,
    spanGaps: false,
    fill: "start",
    tension:0.2
  },
  {
    data: redLine,
    backgroundColor: 'rgb(165, 95, 0,0.3)',
    borderColor: 'rgb(255, 0, 0)',
    borderWidth: 1,
    showLine: true,
    spanGaps: false,
    fill: "start",
    tension:0.2
  }],
};
const config = {
  type: 'scatter',
  data: data,
  options: {
    scales: {
      x: {
        type: 'linear',
        position: 'bottom'
      }
    }
  }
};

CodePudding user response:

You can use segments for this:

const options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      segment: {
        borderColor: (ctx) => (ctx.p0.parsed.y < ctx.p1.parsed.y ? 'green' : 'red')
      }
    }]
  },
  options: {}
}

const 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.8.0/chart.js"></script>
</body>

  • Related