[Chartjs]-How to use segment property to color line / border color based on value in chart js?

3👍

You will get the both points on the start and end of the line segment the function is evaluating for as p0 and p1 in here you can access the y value like this: val = ctx.p0.parsed.y;

Live example:

var 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) => {
          val = ctx.p0.parsed.y;
          return val >= 15 ? 'green' : val >= 10 ? 'blue' : val >= 5 ? 'pink' : 'purple'
        }
      }
    }]
  },
  options: {}
}

var 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.5.0/chart.js"></script>
</body>

EDIT:

As per my comment you were pretty close with your pixelForValue, you just had to pass the context also to your gradiant function and dont use the v2 default ID’s for the scales:

borderColor: function(context, options) {
  const chart = context.chart;
  const {
    ctx,
    chartArea
  } = chart;
  if (!chartArea) {
    return null;
  }
  return getGradient(ctx, chartArea, chart);
}

function getGradient(ctx, chartArea, chart) {
  const chartWidth = chartArea.right - chartArea.left;
  const chartHeight = chartArea.bottom - chartArea.top;

  if (gradient === null || width !== chartWidth || height !== chartHeight) {
    width = chartWidth;
    height = chartHeight;
    let y2 = 27; // I want this to be the pixel for value I pass, instead of hard value
    
    const { scales: { x, y } } = chart;

    console.log(x.getPixelForValue(20), x.getPixelForValue(4))
    


    gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);
    gradient.addColorStop(y2 / chartHeight, 'black');
    gradient.addColorStop(0.6, 'yellow');

    gradient.addColorStop(0.9, 'red');

    gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);
    gradient.addColorStop(y2 / chartHeight, 'black');
    gradient.addColorStop(0.6, 'yellow');

    gradient.addColorStop(0.9, 'red');
  }
  return gradient;
}

But you can also choose to make an array of objects with the value and color and use that to make your gradiant:

var ctx = document.getElementById('LineChart').getContext("2d");
let width, height, gradient;

const getcolorStop = (val, max) => (val / max);
const colors = [{
    val: 2,
    color: 'pink',
  },
  {
    val: 12,
    color: 'purple',
  },
  {
    val: 20,
    color: 'green',
  }
]

function getGradient(ctx, chartArea, chart) {
  const chartWidth = chartArea.right - chartArea.left;
  const chartHeight = chartArea.bottom - chartArea.top;

  if (gradient === null || width !== chartWidth || height !== chartHeight) {
    width = chartWidth;
    height = chartHeight;

    const {
      scales: {
        y: {
          max
        }
      }
    } = chart;

    gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);

    colors.forEach((color) => {
      if (color.val > max) {
        color.val = max;
      }

      gradient.addColorStop(getcolorStop(color.val, max), color.color);
    });
  }
  return gradient;
}
var myChart = new Chart(ctx, {
  type: 'line',
  data: {
    labels: ['10', '20', '30', '40', '50'],
    datasets: [{
      label: 'Hello',
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: 'rgba(255, 255, 78, 1)',
      borderColor: function(context, options) {
        const chart = context.chart;
        const {
          ctx,
          chartArea
        } = chart;
        if (!chartArea) {
          return null;
        }
        return getGradient(ctx, chartArea, chart);
      },
    }]
  },
});
<h1>Chart One</h1>
<canvas id="LineChart" height="100"></canvas>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2"></script>

Leave a comment