Different color for each bar in a bar chart; ChartJS

I'm using ChartJS in a project I'm working on and I need a different color for each bar in a Bar Chart.

Here's an example of the bar chart data set:

var barChartData = {
  labels: ["001", "002", "003", "004", "005", "006", "007"],
  datasets: [{
    label: "My First dataset",
    fillColor: "rgba(220,220,220,0.5)", 
    strokeColor: "rgba(220,220,220,0.8)", 
    highlightFill: "rgba(220,220,220,0.75)",
    highlightStroke: "rgba(220,220,220,1)",
    data: [20, 59, 80, 81, 56, 55, 40]
  }]
};

Is there any way to paint each bar differently?

Answers:

Answer

As of v2, you can simply specify an array of values to correspond to a color for each bar via the backgroundColor property:

datasets: [{
  label: "My First dataset",
  data: [20, 59, 80, 81, 56, 55, 40],
  backgroundColor: ["red", "blue", "green", "blue", "red", "blue"], 
}],

This is also possible for the borderColor, hoverBackgroundColor, hoverBorderColor.

From the documentation on the Bar Chart Dataset Properties:

Some properties can be specified as an array. If these are set to an array value, the first value applies to the first bar, the second value to the second bar, and so on.

Answer

After looking into the Chart.Bar.js file I've managed to find the solution. I've used this function to generate a random color:

function getRandomColor() {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    for (var i = 0; i < 6; i++ ) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

I've added it to the end of the file and i called this function right inside the "fillColor:" under

helpers.each(dataset.data,function(dataPoint,index){
                    //Add a new point for each piece of data, passing any required data to draw.

so now it looks like this:

helpers.each(dataset.data,function(dataPoint,index){
                    //Add a new point for each piece of data, passing any required data to draw.

                    datasetObject.bars.push(new this.BarClass({
                        value : dataPoint,
                        label : data.labels[index],
                        datasetLabel: dataset.label,
                        strokeColor : dataset.strokeColor,
                        fillColor : getRandomColor(),
                        highlightFill : dataset.highlightFill || dataset.fillColor,
                        highlightStroke : dataset.highlightStroke || dataset.strokeColor
                    }));
                },this);

and it works I get different color for each bar.

Answer

If you take a look at the library "ChartNew" which builds upon Chart.js you can do this by passing the values in as an array like so:

var data = {
    labels: ["Batman", "Iron Man", "Captain America", "Robin"],
    datasets: [
        {
            label: "My First dataset",
            fillColor: ["rgba(220,220,220,0.5)", "navy", "red", "orange"],
            strokeColor: "rgba(220,220,220,0.8)",
            highlightFill: "rgba(220,220,220,0.75)",
            highlightStroke: "rgba(220,220,220,1)",
            data: [2000, 1500, 1750, 50]
        }
    ]
};
Answer

You can call this function which generates random colors for each bars

var randomColorGenerator = function () { 
    return '#' + (Math.random().toString(16) + '0000000').slice(2, 8); 
};

var barChartData = {
        labels: ["001", "002", "003", "004", "005", "006", "007"],
        datasets: [
            {
                label: "My First dataset",
                fillColor: randomColorGenerator(), 
                strokeColor: randomColorGenerator(), 
                highlightFill: randomColorGenerator(),
                highlightStroke: randomColorGenerator(),
                data: [20, 59, 80, 81, 56, 55, 40]
            }
        ]
    };
Answer

Generate random colors;

function getRandomColor() {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

and call it for each record;

function getRandomColorEachEmployee(count) {
    var data =[];
    for (var i = 0; i < count; i++) {
        data.push(getRandomColor());
    }
    return data;
}

finally set colors;

var data = {
    labels: jsonData.employees, // your labels
    datasets: [{
        data: jsonData.approvedRatios, // your data
        backgroundColor: getRandomColorEachEmployee(jsonData.employees.length)
    }]
};
Answer

Here, I solved this issue by making two functions.

1. dynamicColors() to generate random color

function dynamicColors() {
    var r = Math.floor(Math.random() * 255);
    var g = Math.floor(Math.random() * 255);
    var b = Math.floor(Math.random() * 255);
    return "rgba(" + r + "," + g + "," + b + ", 0.5)";
}

2. poolColors() to create array of colors

function poolColors(a) {
    var pool = [];
    for(i = 0; i < a; i++) {
        pool.push(dynamicColors());
    }
    return pool;
}

Then, just pass it

datasets: [{
    data: arrData,
    backgroundColor: poolColors(arrData.length),
    borderColor: poolColors(arrData.length),
    borderWidth: 1
}]
Answer

As of August 2019, Chart.js now has this functionality built in.

Successful bar chart with different colored bars

You simply need to provide an array to backgroundColor.

Example taken from https://www.chartjs.org/docs/latest/getting-started/

Before:

  data: {
        labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
        datasets: [{
            label: 'My First dataset',
            backgroundColor: 'rgb(255, 99, 132)',
            borderColor: 'rgb(255, 99, 132)',
            data: [0, 10, 5, 2, 20, 30, 45]
        }]
    },

After:

  data: {
        labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
        datasets: [{
            label: 'My First dataset',
            backgroundColor: ['rgb(255, 99, 132)','rgb(0, 255, 0)','rgb(255, 99, 132)','rgb(128, 255, 0)','rgb(0, 255, 255)','rgb(255, 255, 0)','rgb(255, 255, 128)'],
            borderColor: 'rgb(255, 99, 132)',
            data: [0, 10, 5, 2, 20, 30, 45]
        }]
    },

I just tested this method and it works. Each bar has a different color.

Answer

here is how I dealed: I pushed an array "colors", with same number of entries than number of datas. For this I added a function "getRandomColor" at the end of the script. Hope it helps...

for (var i in arr) {
    customers.push(arr[i].customer);
    nb_cases.push(arr[i].nb_cases);
    colors.push(getRandomColor());
}

window.onload = function() {
    var config = {
        type: 'pie',
        data: {
            labels: customers,
            datasets: [{
                label: "Nomber of cases by customers",
                data: nb_cases,
                fill: true,
                backgroundColor: colors 
            }]
        },
        options: {
            responsive: true,
            title: {
                display: true,
                text: "Cases by customers"
            },
        }
    };

    var ctx = document.getElementById("canvas").getContext("2d");
    window.myLine = new Chart(ctx, config);
};

function getRandomColor() {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}
Answer

If you're not able to use NewChart.js you just need to change the way to set the color using array instead. Find the helper iteration inside Chart.js:

Replace this line:

fillColor : dataset.fillColor,

For this one:

fillColor : dataset.fillColor[index],

The resulting code:

//Iterate through each of the datasets, and build this into a property of the chart
  helpers.each(data.datasets,function(dataset,datasetIndex){

    var datasetObject = {
      label : dataset.label || null,
      fillColor : dataset.fillColor,
      strokeColor : dataset.strokeColor,
      bars : []
    };

    this.datasets.push(datasetObject);

    helpers.each(dataset.data,function(dataPoint,index){
      //Add a new point for each piece of data, passing any required data to draw.
      datasetObject.bars.push(new this.BarClass({
        value : dataPoint,
        label : data.labels[index],
        datasetLabel: dataset.label,
        strokeColor : dataset.strokeColor,
        //Replace this -> fillColor : dataset.fillColor,
        // Whith the following:
        fillColor : dataset.fillColor[index],
        highlightFill : dataset.highlightFill || dataset.fillColor,
        highlightStroke : dataset.highlightStroke || dataset.strokeColor
      }));
    },this);

  },this);

And in your js:

datasets: [
                {
                  label: "My First dataset",
                  fillColor: ["rgba(205,64,64,0.5)", "rgba(220,220,220,0.5)", "rgba(24,178,235,0.5)", "rgba(220,220,220,0.5)"],
                  strokeColor: "rgba(220,220,220,0.8)",
                  highlightFill: "rgba(220,220,220,0.75)",
                  highlightStroke: "rgba(220,220,220,1)",
                  data: [2000, 1500, 1750, 50]
                }
              ]
Answer

try this :

  function getChartJs() {
        **var dynamicColors = function () {
            var r = Math.floor(Math.random() * 255);
            var g = Math.floor(Math.random() * 255);
            var b = Math.floor(Math.random() * 255);
            return "rgb(" + r + "," + g + "," + b + ")";
        }**

        $.ajax({
            type: "POST",
            url: "ADMIN_DEFAULT.aspx/GetChartByJenisKerusakan",
            data: "{}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (r) {
                var labels = r.d[0];
                var series1 = r.d[1];
                var data = {
                    labels: r.d[0],
                    datasets: [
                        {
                            label: "My First dataset",
                            data: series1,
                            strokeColor: "#77a8a8",
                            pointColor: "#eca1a6"
                        }
                    ]
                };

                var ctx = $("#bar_chart").get(0).getContext('2d');
                ctx.canvas.height = 300;
                ctx.canvas.width = 500;
                var lineChart = new Chart(ctx).Bar(data, {
                    bezierCurve: false,
                    title:
                      {
                          display: true,
                          text: "ProductWise Sales Count"
                      },
                    responsive: true,
                    maintainAspectRatio: true
                });

                $.each(r.d, function (key, value) {
                    **lineChart.datasets[0].bars[key].fillColor = dynamicColors();
                    lineChart.datasets[0].bars[key].fillColor = dynamicColors();**
                    lineChart.update();
                });
            },
            failure: function (r) {
                alert(r.d);
            },
            error: function (r) {
                alert(r.d);
            }
        });
    }
Answer

Code based on the following pull request:

datapoint.color = 'hsl(' + (360 * index / data.length) + ', 100%, 50%)';
Answer

This works for me in the current version 2.7.1:

function colorizePercentageChart(myObjBar) {

var bars = myObjBar.data.datasets[0].data;
console.log(myObjBar.data.datasets[0]);
for (i = 0; i < bars.length; i++) {

    var color = "green";

    if(parseFloat(bars[i])  < 95){
        color = "yellow";
    }
    if(parseFloat(bars[i])  < 50){
         color = "red";
    }

    console.log(color);
    myObjBar.data.datasets[0].backgroundColor[i] = color;

}
myObjBar.update(); 

}

Answer

Taking the other answer, here is a quick fix if you want to get a list with random colors for each bar:

function getRandomColor(n) {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    var colors = [];
    for(var j = 0; j < n; j++){
        for (var i = 0; i < 6; i++ ) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        colors.push(color);
        color = '#';
    }
    return colors;
}

Now you could use this function in the backgroundColor field in data:

data: {
        labels: count[0],
        datasets: [{
            label: 'Registros en BDs',
            data: count[1],
            backgroundColor: getRandomColor(count[1].length)
        }]
}
Answer

Here's a way to generate consistent random colors using color-hash

const colorHash = new ColorHash()

const datasets = [{
  label: 'Balance',
  data: _.values(balances),
  backgroundColor: _.keys(balances).map(name => colorHash.hex(name))
}]

enter image description here

Answer

I have just got this issue recently, and here is my solution

var labels = ["001", "002", "003", "004", "005", "006", "007"];
var data = [20, 59, 80, 81, 56, 55, 40];
for (var i = 0, len = labels.length; i < len; i++) {
   background_colors.push(getRandomColor());// I use @Benjamin method here
}

var barChartData = {
  labels: labels,
  datasets: [{
    label: "My First dataset",
    fillColor: "rgba(220,220,220,0.5)", 
    strokeColor: "rgba(220,220,220,0.8)", 
    highlightFill: "rgba(220,220,220,0.75)",
    highlightStroke: "rgba(220,220,220,1)",
    backgroundColor: background_colors,
    data: data
  }]
};
Answer

If you know which colors you want, you can specify color properties in an array, like so:

    backgroundColor: [
    'rgba(75, 192, 192, 1)',
    ...
    ],
    borderColor: [
    'rgba(75, 192, 192, 1)',
    ...
    ],
Answer

You can generate easily with livegap charts
Select Mulicolors from Bar menu


(source: livegap.com)

** chart library used is chartnew.js modified version of chart.js library
with chartnew.js code will be something like this

var barChartData = {
        labels: ["001", "002", "003", "004", "005", "006", "007"],
        datasets: [
            {
                label: "My First dataset",
                fillColor: ["rgba(0,10,220,0.5)","rgba(220,0,10,0.5)","rgba(220,0,0,0.5)","rgba(120,250,120,0.5)" ],
                strokeColor: "rgba(220,220,220,0.8)", 
                highlightFill: "rgba(220,220,220,0.75)",
                highlightStroke: "rgba(220,220,220,1)",
                data: [20, 59, 80, 81, 56, 55, 40]
            }
        ]
    };
Answer

Solution: call the update method to set new values ??:

var barChartData = {
    labels: ["January", "February", "March"],
    datasets: [
        {
            label: "My First dataset",
            fillColor: "rgba(220,220,220,0.5)", 
            strokeColor: "rgba(220,220,220,0.8)", 
            highlightFill: "rgba(220,220,220,0.75)",
            highlightStroke: "rgba(220,220,220,1)",
            data: [20, 59, 80]
        }
    ]
};

window.onload = function(){
    var ctx = document.getElementById("mycanvas").getContext("2d");
    window.myObjBar = new Chart(ctx).Bar(barChartData, {
          responsive : true
    });

    //nuevos colores
    myObjBar.datasets[0].bars[0].fillColor = "green"; //bar 1
    myObjBar.datasets[0].bars[1].fillColor = "orange"; //bar 2
    myObjBar.datasets[0].bars[2].fillColor = "red"; //bar 3
    myObjBar.update();
}

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.