Chart.js Line, different fill color for negative point

chartjs fill color
chart.js bar background color
chart js color
chart js multiple lines
chart js line no fill
chart js options
chart js bar border color
chartjs stepped line

I need to change the fill color (internal area) in a Line Chart.js when the point is negative.

The code is simple and basic:

$(document).ready(function(){

  var ctx = $("#myChart").get(0).getContext("2d");

  var data = {
      labels: ["January", "February", "March", "April", "May", "June", "July"],
      datasets: [
          {
              label: "My First dataset",
              //fillColor : "rgba(60,91,87,1)",
              // String - the color to fill the area under the line with if fill is true
              backgroundColor: "rgba(75,192,192,0.4)",
              strokeColor : "rgba(60,91,87,1)",
              pointColor : "rgba(60,91,87,1)",
              pointStrokeColor : "#58606d",
              // The actual data
              data: [65, 59, 80, -81, 56, 55, -40],

              // String - If specified, binds the dataset to a certain y-axis. If not specified, the first y-axis is used. First id is y-axis-0
              yAxisID: "y-axis-0",
          }
      ]
  };

  var options = {
      scales: {
          yAxes: [{
              display: true,
              ticks: {
                  suggestedMin: 0,    // minimum will be 0, unless there is a lower value.
                  // OR //
                  beginAtZero: true   // minimum value will be 0.
              }
          }]
      }
  };

  var myLineChart = new Chart(ctx, {
      type: 'line',
      data: data,
      options: options
  });

//  myLineChart.data.datasets[0].metaDataset._points[3]._model.backgroundColor = "red";
//  if (myLineChart.datasets[0].points[4].value < 0) {
//    myLineChart.datasets[0].points[4].fillColor =  "red";
//    myLineChart.update();
// }
})

I'm trying to get this result:

You can extend the line chart to do this.


Preview


Script

Chart.defaults.NegativeTransparentLine = Chart.helpers.clone(Chart.defaults.line);
Chart.controllers.NegativeTransparentLine = Chart.controllers.line.extend({
    update: function () {
        // get the min and max values
        var min = Math.min.apply(null, this.chart.data.datasets[0].data);
        var max = Math.max.apply(null, this.chart.data.datasets[0].data);
        var yScale = this.getScaleForId(this.getDataset().yAxisID);

        // figure out the pixels for these and the value 0
        var top = yScale.getPixelForValue(max);
        var zero = yScale.getPixelForValue(0);
        var bottom = yScale.getPixelForValue(min);

        // build a gradient that switches color at the 0 point
        var ctx = this.chart.chart.ctx;
        var gradient = ctx.createLinearGradient(0, top, 0, bottom);
        var ratio = Math.min((zero - top) / (bottom - top), 1);
        gradient.addColorStop(0, 'rgba(75,192,192,0.4)');
        gradient.addColorStop(ratio, 'rgba(75,192,192,0.4)');
        gradient.addColorStop(ratio, 'rgba(0,0,0,0)');
        gradient.addColorStop(1, 'rgba(0,0,0,0)');
        this.chart.data.datasets[0].backgroundColor = gradient;

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

and then

 ...
 var myLineChart = new Chart(ctx, {
     type: 'NegativeTransparentLine',
     data: {
     ...

Fiddle - http://jsfiddle.net/g2r2q5Lu/

Dataset colors: option for different colors for negative values? · Issue , If I'm charting an account balance in a line/bar chart, it'd be nice to show positive .com/questions/36916867/chart-js-line-different-fill-color-for-negative-point The fill color for points. pointBorderColor: The border color for points. pointBorderWidth: The width of the point border in pixels. pointHitRadius: The pixel size of the non-displayed point that reacts to mouse events. pointRadius: The radius of the point shape. If set to 0, the point is not rendered. pointRotation: The rotation of the point

To get @potatopeelings code above to work with chart.js 2.5.x you need to add yAxisID : 'y-axis-0' into your datasets, as below.

var myLineChart = new Chart(ctx, {
  type: 'NegativeTransparentLine',
  data: {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [{
      yAxisID : 'y-axis-0',
      ....

Chart.js Line chart with different fill color for negative point, <html> <head> <title>chart.js 2.0</title> <meta name="viewport" content="width=​device-width, initial-scale=1"> <script type="text/javascript"  ok thank you, I use the Line Chart to make a balance, Positive must be green and negative red. To make it, I've separated my data and I've putted it into 2 different Chart. One for the positive values, and an another one for the negative values. That do the job.

@potatopeelings code will work if your dataset data format is in [1,2,3,...] form

If your data format is in [{x: 1 , y: 1},...] form, you need to change var min and var max to:

    var min = this.chart.data.datasets[0].data.reduce((min, p) => p.y < min ? p.y : min, this.chart.data.datasets[0].data[0].y);
    var max = this.chart.data.datasets[0].data.reduce((max, p) => p.y > max ? p.y : max, this.chart.data.datasets[0].data[0].y);

Tested on ChartJS 2.7.3

Line · Chart.js documentation, A line chart is a way of plotting data points on a line. Often, it is used to show trend data, pointBackgroundColor, The fill color for points. pointBorderColor, The  Hi there, I&#39;m wondering whether it is possible to have points on a line chart with each a different color (background/border). Not sure whether this would be something that could be done via a

i update the method to work with multiple datasets.

Chart.defaults.NegativeTransparentLine = Chart.helpers.clone(Chart.defaults.line);
    Chart.controllers.NegativeTransparentLine = Chart.controllers.line.extend({
        update: function () {
          for(let i=0; i< this.chart.data.datasets.length; i++) {
            // get the min and max values
            var min = Math.min.apply(null, this.chart.data.datasets[i].data);
            var max = Math.max.apply(null, this.chart.data.datasets[i].data);
            var yScale = this.getScaleForId(this.chart.data.datasets[i].yAxisID);

            // figure out the pixels for these and the value 0
            var top = yScale.getPixelForValue(max);
            var zero = yScale.getPixelForValue(0);
            var bottom = yScale.getPixelForValue(min);

            // build a gradient that switches color at the 0 point
            var ctx = this.chart.chart.ctx;
            var gradient = ctx.createLinearGradient(0, top, 0, bottom);
            var ratio = Math.min((zero - top) / (bottom - top), 1);
            gradient.addColorStop(0, 'rgba(55,210,99,0.4)');
            gradient.addColorStop(ratio, 'rgba(55,210,99,0.4)');
            gradient.addColorStop(ratio, 'rgba(247,100,120,0.4)');
            gradient.addColorStop(1, 'rgba(247,100,120,0.4)');
            this.chart.data.datasets[i].backgroundColor = gradient;
          }
          return Chart.controllers.line.prototype.update.apply(this, arguments);
        }
    });

Tested on chart.js 2.8.0 on Angular 8

import { Component, OnInit, ViewChild } from '@angular/core';
import { Chart, ChartDataSets, ChartOptions } from 'chart.js';
import { Color, Label } from 'ng2-charts';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  public lineChartData: ChartDataSets[] = [
    { data: [89, 0, -80, 81, 56, -55, 40], label: 'Series A', yAxisID: 'y-axis-0' },
    { data: [-890, 0, 800, -810, -560, 550, -400], label: 'Series B', yAxisID: 'y-axis-0' },
  ];
  public lineChartLabels: Label[] = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
  public lineChartOptions: (ChartOptions & { annotation: any }) = {
    responsive: true,
  };
  public lineChartColors: Color[] = [
    {
      backgroundColor: 'rgba(255,0,0,0.3)',
    },
    {
      backgroundColor: 'rgba(0,255,0,0.3)',
    },
  ];
  public lineChartLegend = true;
  public lineChartType = 'line';
  public lineChartPlugins = [];

  constructor() {
    Chart.defaults.NegativeTransparentLine = Chart.helpers.clone(Chart.defaults.line);
    Chart.controllers.NegativeTransparentLine = Chart.controllers.line.extend({
        update: function () {
          for(let i=0; i< this.chart.data.datasets.length; i++) {
            // get the min and max values
            var min = Math.min.apply(null, this.chart.data.datasets[i].data);
            var max = Math.max.apply(null, this.chart.data.datasets[i].data);
            var yScale = this.getScaleForId(this.chart.data.datasets[i].yAxisID);

            // figure out the pixels for these and the value 0
            var top = yScale.getPixelForValue(max);
            var zero = yScale.getPixelForValue(0);
            var bottom = yScale.getPixelForValue(min);

            // build a gradient that switches color at the 0 point
            var ctx = this.chart.chart.ctx;
            var gradient = ctx.createLinearGradient(0, top, 0, bottom);
            var ratio = Math.min((zero - top) / (bottom - top), 1);
            gradient.addColorStop(0, 'rgba(55,210,99,0.4)');
            gradient.addColorStop(ratio, 'rgba(55,210,99,0.4)');
            gradient.addColorStop(ratio, 'rgba(247,100,120,0.4)');
            gradient.addColorStop(1, 'rgba(247,100,120,0.4)');
            this.chart.data.datasets[i].backgroundColor = gradient;
          }
          return Chart.controllers.line.prototype.update.apply(this, arguments);
        }
    });
    this.lineChartType = 'NegativeTransparentLine';
  }

  ngOnInit() {
  }
}
<div style="display: block;">
  <canvas baseChart width="400" height="400"
    [datasets]="lineChartData"
    [labels]="lineChartLabels"
    [options]="lineChartOptions"
    [colors]="lineChartColors"
    [legend]="lineChartLegend"
    [chartType]="lineChartType"
    [plugins]="lineChartPlugins">
  </canvas>
</div>

Colors · Chart.js documentation, You can specify the color as a string in hexadecimal, RGB, or HSL notations. For example, if you wanted to fill a dataset with a pattern from an image you could​  It is possible to either remove the grid lines or have them display in a different color. In both options.scales.xAxes and options.scales.yAxes you can add gridLines: { display: false , color: "#FFFFFF" },

Chart.js Tutorial, Chart.js is a JavaScript library that allows you to create beautiful charts to represent different types of statistics. In this tutorial, you will learn how to create the line chart with gradient colors and animation. You can access to There is an option to fill in this chart area instead of showing only line stroke. First  Okay, so I have a ChartJS line chart working that populates directly from data coming for my db. What I need now is to get rid of the color underneath each of the lines.

Line with different negative color, This demo shows how we can color any segment of the line below the zero line with an <script src="https://www.amcharts.com/lib/4/charts.js"></script> <! Elements. While chart types provide settings to configure the styling of each dataset, you sometimes want to style all datasets the same way.A common example would be to stroke all of the bars in a bar chart with the same colour but change the fill per dataset.

Highcharts demos, Highcharts basic line chart JavaScript example displays graph plot of solar employment Line chart with 500k points Area with negative values Highcharts 3D Bubbles chart JavaScript example graph compares series values as radial gradient fill graph compares variables as three dimensional vertical color bar chart  Filling different backgrounds when over or below an arbitrary marker (I don't remember if Chart.js has arbitrary markers, but if so, this mode can be quite useful) Filling different backgrounds when over or below another curve (basically, you have to be able to create a inverted path for one of the curves, and append it to the path of the other

Comments
  • Chart does not support doing that, as far as I know. There's only one color (well, one set of colors, for different details) per line.
  • That's what i looking for! Thank you!
  • As a quick pointer if you don't notice at first, this is actually general, to not just transparent colors on the bottom. All you need to do is pick a different 2nd color. So you can do top green and bottom red, for example. This is very cool!
  • @potatopeelings that's perfect, is there a way to change also the border color?
  • I am now getting "TypeError: Chart.controllers is undefined" EDIT I was using an outdated Chart.js.