How can I set different colours for each bar in angular-chart.js?

Huey picture Huey · May 2, 2015 · Viewed 17.1k times · Source

I've looked at How to change colours for Angular-Chart.js, but it relates to colours for an entire (dataset), not a specific bar.

What I'm looking for is a way to apply Different color for each bar in a bar chart; ChartJS to Angular.

So, I've got a bar chart:

<canvas id="locationBar" class="chart chart-bar" data="chartParams.votes" labels="chartParams.listOfLocations" series="chartParams.series" colours="chartParams.colours" options="chartParams.options"></canvas> 

With the following angular code (in a controller of course)

$scope.chartParams = {
    listOfLocations: ['Trenzalore','Earth','Caprica','Sol','Tau Ceti'],
    votes: [[5,10,6,7,2]],
    series: ["Nice Places"],
    colours: [{fillColor:getRandomColour()}],
    options: {barShowStroke : false}
};

where getRandomColour() would return a random colour.

Right now, the colours field applies this colour to all the bars:

same colour :( different colours

when I actually want a different colour for each bar:

Plunker

Answer

Dave Jarvis picture Dave Jarvis · Nov 27, 2016

Using the latest version of angular-chart.js, here's an example that changes the colours based on a condition, without modifying the library itself. Instead, it uses the chart-dataset-override feature.

The trick is to use a series with only one data set.

HTML

<div ng-controller="chartControl">
  <canvas id="bar" class="chart chart-bar" 
    chart-data="goal.data" 
    chart-labels="goal.labels" 
    chart-options="goal.options" 
    chart-series="goal.series" 
    chart-dataset-override="goal.datasetOverride"></canvas>
</div>

JavaScript

Add the following code to the controller:

  var exceeded = '#27ae60';
  var achieved = '#bdc3c7';
  var defeated = '#e74c3c';

  $scope.goal = [];
  $scope.goal.goal = 3;

  $scope.goal.series = [ 'Visits' ];
  $scope.goal.labels = [
    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'
  ];
  $scope.goal.data = [
    [5, 2, 3, 3, 3, 4, 2, 3, 4],
  ];

  var backgroundColours = [];

  // Assign the background colour based on whether the goal was achieved.
  for( var i = 0; i < $scope.goal.data[0].length; i++ ) {
    var v = $scope.goal.data[0][i];

    if( v > $scope.goal.goal ) {
      backgroundColours[i] = exceeded;
    }
    else if( v < $scope.goal.goal ) {
      backgroundColours[i] = defeated;
    }
    else {
      backgroundColours[i] = achieved;
    }
  } 

  // Create a place to hold the background colours.
  $scope.goal.datasetOverride = [{ backgroundColor: [] }];

  // Assign the colours to the pre-populated array.
  $scope.goal.datasetOverride[0].backgroundColor = backgroundColours;

  $scope.goal.options = {
    barShowStroke: false,
    scales: {
      yAxes: [{
        ticks: {
          min: 0,
          max: 7,
          stepSize: 1
        }
      }]
    }
  };

Output

Produces:

Chart Output

Related Links