[Chartjs]-How to change line color based on data – chartist or chart.js

2👍

You could create a scatter chart and draw the lines directly on the canvas using the Plugin Core API. The API offers a range of hooks that may be used for performing custom code.

In below code snippet, I use the afterDraw hook to draw connection lines between data points. Their color depends on the direction property of the start data point.

const rawData = [
    {time: '3:00:00', speed: 20, direction: 345},
    {time: '3:01:00', speed: 0, direction: 0},
    {time: '3:02:00', speed: 25, direction: 290},
    {time: '3:03:00', speed: 10, direction: 180},
    {time: '3:04:00', speed: 5, direction: 0}
];
const data = rawData.map(o => ({ x: moment(o.time, 'H:mm:ss').toDate().getTime(), y: o.speed}));
const colorsPer100 = ['green', 'orange', 'blue', 'red']; 

new Chart(document.getElementById("myChart"), {
  type: "scatter",
  plugins: [{
    afterDraw: chart => {      
      var ctx = chart.chart.ctx; 
      var xAxis = chart.scales['x-axis-1'];
      var yAxis = chart.scales['y-axis-1'];      
      chart.config.data.datasets[0].data.forEach((value, index) => {
        if (index > 0) {        
           var valueFrom = data[index - 1];
           var xFrom = xAxis.getPixelForValue(valueFrom.x);     
           var yFrom = yAxis.getPixelForValue(valueFrom.y);     
           var direction = rawData[index -1].direction;
           var xTo = xAxis.getPixelForValue(value.x);         
           var yTo = yAxis.getPixelForValue(value.y); 
           ctx.save();           
           ctx.strokeStyle = colorsPer100[Math.floor(direction / 100)];           
           ctx.lineWidth = 2;
           ctx.beginPath();
           ctx.moveTo(xFrom, yFrom);             
           ctx.lineTo(xTo, yTo);
           ctx.stroke();
           ctx.restore();
        }
      });      
    }
  }],
  data: {
    datasets: [{
      label: "My Dataset",
      data: data,
      borderColor: "rgb(75, 192, 192)"
    }]
  },
  options: {
    legend: {
      display: false
    },
    scales: {
      xAxes: [{
        type: 'time',
        time: {
          unit: 'minute',
          displayFormats: {
            minute: 'H:mm:ss'
          }
        },
      }]
    }
  }  
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="90"></canvas>

0👍

uminder has an interesting solution. In another thread, someone posted a solution which I went with – they just created an array of colors that’s the same size as the dataset (and just feed that in with the data). That worked great and was much simpler than I think I was trying to make it.

Leave a comment