42

I am using Chart.js and everything is ok, but I want to replace current color background (fillColor: "rgba(250,174,50,0.5)") with a gradient.

I have a solution for replacing gradient but it's too dificult for me to implement this with my poor JS knowledge. I guess pretty easy for someone who knows JS.

So my Chart.js code:

<script>
  var data = {
    labels: [
      "02:00", "04:00", "06:00", "08:00", "10:00", "12:00",
      "14:00", "16:00", "18:00", "20:00", "22:00", "00:00"
    ],
    datasets: [
      {
        fillColor: "rgba(250,174,50,0.5)",
        strokeColor: "#ff6c23",
        pointColor: "#fff",
        pointStrokeColor: "#ff6c23",
        pointHighlightFill: "#fff",
        pointHighlightStroke: "#ff6c23",
        data: [
          25.0, 32.4, 22.2, 39.4, 34.2, 22.0,
          23.2, 24.1, 20.0, 18.4, 19.1, 17.4
        ]
      }
    ]
  };

  var options = {
    responsive: true,
    datasetStrokeWidth: 3,
    pointDotStrokeWidth: 4,
    tooltipFillColor: "rgba(0,0,0,0.8)",
    tooltipFontStyle: "bold",
    tooltipTemplate: "<%if (label){%><%=label + ' hod' %>: <%}%><%= value + '°C' %>",
    scaleLabel: "<%= Number(value).toFixed(0).replace('.', ',') + '°C'%>"
  };

  var ctx = document.getElementById("temp-chart").getContext("2d");
  var myLineChart = new Chart(ctx).Line(data, options);
</script>

And here is solution with gradient. Can someone try implement this gradient background instead of my current solid background? Thanks for the help!

I tried to implement it, but then other functions don't work (like scaleLabels etc.).

4
  • 2
    Do you still need help ? Commented Apr 8, 2015 at 14:20
  • @bviale This is actually brilliant and quite stupid from me, that I didn't think of that :D Ofc it is simple 2D graphics so it has to accept the gradient. Thank you a lot!! Commented May 9, 2015 at 20:39
  • 1
    fillColor changed with backgroundColor in ChartJS 3+. Commented Nov 14, 2021 at 6:06
  • The solution link bin is not functional Commented Apr 19, 2024 at 15:06

8 Answers 8

78

The link you provided was pretty clear, you have to put in the field fillColor in datasets as linearGradient object instead of a plain color. You can do complex gradients, but here is the code of a simple one (changing the opacity of the same orange):

var gradient = ctx.createLinearGradient(0, 0, 0, 400);
gradient.addColorStop(0, 'rgba(250,174,50,1)');   
gradient.addColorStop(1, 'rgba(250,174,50,0)');

And your complete datasets :

datasets: [
  {
    fillColor: gradient, // Put the gradient here as a fill color
    strokeColor: "#ff6c23",
    pointColor: "#fff",
    pointStrokeColor: "#ff6c23",
    pointHighlightFill: "#fff",
    pointHighlightStroke: "#ff6c23",
    data: [
      25.0, 32.4, 22.2, 39.4, 34.2, 22.0,
      23.2, 24.1, 20.0, 18.4, 19.1, 17.4
    ]
  }
]

See it in action in this JSFiddle

Sign up to request clarification or add additional context in comments.

6 Comments

@bviale I get "ctx is not defined"
@mesqueeb I had the same error, fixed it by defining ctx and canvas as variables. // var canvas = document.getElementById("name"); var ctx = canvas.getContext("2d");
I had to use backgroundColor instead of fillColor
All these answers give a gradient on the canvas level, did anyone achieve a consistent gradient in each bar of the bar chart?
@mesqueeb ctx is canvas context canvas = document.getElementById('canvas') ctx = canvas.getContext('2d')
|
39

Note: For those people who is using newer version (v2.7.0) of Chart.js, find out that is not working while you're copy-paste @bviale's answer back to your code base; Some property names has changed:

fillColor -> backgroundColor
strokeColor -> borderColor
pointColor -> pointBackgroundColor
pointStrokeColor -> pointBorderColor

You will need to update those property names to make it work.

Reference: https://github.com/chartjs/Chart.js/blob/master/docs/charts/line.md#dataset-properties

Comments

15

For using it in react, I did the following way.

You need to pass an id to your component and then fetch the element using that id.

import React, { Component } from 'react'
import { Line } from 'react-chartjs-2'

export default class GraphComponent extends Component {
  constructor(props) {
    super(props)
    this.state = {
      chartData: {}
    }
  }

  componentDidMount() {
    // your code
    var ctx = document.getElementById('canvas').getContext("2d")
    var gradient = ctx.createLinearGradient(0, 0, 0, 400)
    gradient.addColorStop(0, 'rgba(229, 239, 255, 1)')
    gradient.addColorStop(1, '#FFFFFF')
    const newData = {
      labels: [1, 1],
      datasets: [
        {
          label: 'usd',
          data: [1,1],
          backgroundColor: gradient,
          borderColor: this.props.border_color,
          pointRadius: 0
        }
      ]
    }
    this.setState({chartData: newData})
  }

  // more of your code

  render() {
    return(
      <Line
        id='canvas' // you need to give any id you want
        data={this.state.chartData}
        width={100}
        height={30}
        options={{
          legend: {
            display: false
          }
        }}
      />
    )
  }
}

This is only my second answer so please forgive me if I have made any mistakes in writing.

1 Comment

Works great 3 years later :D
12

for latest version do not forget to set fill: true

  function getGradient(ctx, chartArea) {
    let gradient = ctx.createLinearGradient(
      0,
      chartArea.bottom,
      0,
      chartArea.top
    );
    gradient.addColorStop(0.9, "rgba(102, 235, 169, .4)");
    gradient.addColorStop(0, "transparent");
    return gradient;
  }

set dataset options as below

fill: true,
backgroundColor: function (context) {
    const chart = context.chart;
    const { ctx, chartArea } = chart;

   // This case happens on initial chart load
   if (!chartArea) return;
   return getGradient(ctx, chartArea);
},

Comments

6

Updated version 2022

var ctx = document.getElementById("temp-chart").getContext("2d");

declare gradient after getting context element i.e ctx

var gradient = ctx.createLinearGradient(0, 0, 0, 400);
            gradient.addColorStop(0.2, 'rgb(255, 10, 86,0.5)');
            gradient.addColorStop(1, 'rgb(255, 10, 86,0.1)');

and your dataset will be

datasets: [{
                 label: 'Transactions',
                 data: [1,3,4,5]
                 backgroundColor: gradient,
                 borderColor: 'rgb(255, 10, 86,1)',
                 borderWidth: 2,
           }],

Comments

4

The React solutions posted here may work with some effort but will most likely produce additional errors such as "createLinearGradient is not a function" or "document.getElementById() returning null" because it is looking for the chart id before the DOM has loaded. It doesn't help that ChartJS documentation for React is lacking.

I find a cleaner solution is to create the charts as a functional component and make sure all needed ChartJS assets are properly initialized.

1. Making sure ChartJS is properly initialized and registered

import { Line } from 'react-chartjs-2' import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, Filler, ScriptableContext } from "chart.js";

ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,Filler);

2. Using the ScriptableContext to add the gradient

backgroundColor: (context: ScriptableContext<"line">) => { const ctx = context.chart.ctx; const gradient = ctx.createLinearGradient(0, 0, 0, 200); gradient.addColorStop(0, "rgba(238,174,202,1)"); gradient.addColorStop(1, "rgba(238,174,202,0)"); return gradient; },

Live Codepen w/ Line Chart Gradient enter link description here

1 Comment

Great, It worked for me. For regular react, I don't need ScriptableContext<"line">, Just context is fine.
1

You could use this npm package.

https://www.npmjs.com/package/chartjs-plugin-gradient

This makes it very easy to create a gradient backgroundColor or borderColor.

Example:

const chart = new Chart(ctx, {
  data: {
    datasets: [{
      // data
      gradient: {
        backgroundColor: {
          axis: 'y',
          colors: {
            0: 'red',
            50: 'yellow',
            100: 'green'
          }
        },
        borderColor: {
          axis: 'x',
          colors: {
            0: 'black',
            1: 'white',
            2: 'black',
            3: 'white'
          }
        }
      }
    }]
  }
});

Comments

0

For anyone using Angular and ng2-charts, here is my solution. Chart setup was left out for brevity.

import { Component, OnInit, ViewChild, ChangeDetectorRef, AfterViewInit } from '@angular/core';
import { BaseChartDirective } from 'ng2-charts';
import { GenericLineChart } from './generic-line-chart';


@Component({
    selector: 'app-stats-chart',
    templateUrl: './stats-chart.component.html',
    styleUrls: ['./stats-chart.component.scss']
})
export class StatsChartComponent implements OnInit, AfterViewInit {
    @ViewChild(BaseChartDirective, { static: true }) chartDirective: BaseChartDirective;

    constructor(private changeDetectorRef: ChangeDetectorRef) { }

    ngOnInit() {
        // ...setup chart
    }

    ngAfterViewInit() {
        // set gradient
        const gradient = this.chartDirective.chart.ctx.createLinearGradient(0, 0, 0, 400);
        gradient.addColorStop(0, 'rgba(30, 214, 254, .3)');
        gradient.addColorStop(1, 'rgba(0,0,0,0)');
        this.chart.lineChartData[0].backgroundColor = gradient;

        this.changeDetectorRef.detectChanges();
    }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.