Comment puis-je définir différentes couleurs pour chaque barre dans angular-chart.js?

J'ai regardé comment changer les couleurs pour Angular-Chart.js , mais il se rapporte aux couleurs pour un entier (jeu de données), pas une barre spécifique.

Ce que je cherche, c'est une façon d'appliquer différentes couleurs pour chaque barre dans un graphique à barres; ChartJS à Angular.

Donc, j'ai un graphique à barres:

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

Avec le code angulaire suivant (dans un contrôleur bien sûr)

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

getRandomColour() renverrait une couleur aléatoire.

En ce moment, le champ de colours applique cette couleur à toutes les barres:

Même couleur :(couleurs différentes

Quand je veux vraiment une couleur différente pour chaque barre:

Plunker

Plunker Demo

La chose la plus simple à faire était de modifier le fichier source chart.js pour accepter un tableau de couleurs pour fillColor plutôt qu'une seule chaîne de couleurs.

Si vous pouviez obtenir l'une des autres solutions proposées, je pense que cela finirait par se faire de manière très anodine.

Certaines personnes risquent de ne pas vouloir peaufiner la source, mais pour savoir si simple et facile à faire, et il réalise le résultat souhaité, et ce n'est pas moins «angulaire» dans sa solution … Appelons-le simplement une amélioration Chart.js.

Notez que j'ai seulement modifié le tableau "bar" pour accepter un tableau de couleurs, car il semble que chart.js fait référence à fillColor séparément dans chaque type de graphique. Donc, vous devriez pouvoir effectuer cette modification pour tous les types de graphiques.

L'endroit que vous devez modifier:

  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 : dataset.fillColor[index], // <- added [index] here highlightFill : dataset.highlightFill || dataset.fillColor, highlightStroke : dataset.highlightStroke || dataset.strokeColor })); },this); 

Ce bloc de code peut être trouvé dans la fonction Chart.type.extend pour le diagramme à barres. Il suffit de chercher ceci:

 Chart.Type.extend({ name: "Bar", 

Et regardez plus loin dans cette fonction pour l'endroit où il pousse le fillColor vers le datasetObject.bars.

Maintenant, configurez votre graphique comme avant, sauf s'il vous plaît un tableau pour fillColor:

 function($scope){ $scope.chartParams = { listOfLocations: ['Trenzalore','Earth','Caprica','Sol','Tau Ceti'], votes: [[5,10,6,7,2]], series: ["Nice Places"], colours: [{fillColor:["#FF0000", "#00FF00", "#0000FF", "#00FFFF", "#FFFF00"]}], options: {barShowStroke : false} }; } 

En utilisant la dernière version de angular-chart.js , voici un exemple qui modifie les couleurs en fonction d'une condition, sans modifier la bibliothèque elle-même. Au lieu de cela, il utilise la fonction chart-dataset-override .

L'astuce consiste à utiliser une série avec un seul ensemble de données.

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

Ajoutez le code suivant au contrôleur:

  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 } }] } }; 

Sortie

Produit:

Sortie graphique

Liens connexes

L'un des problèmes majeurs avec les bibliothèques de graphiques est que tôt ou tard vous frappez un mur, ce qui ne peut être violé qu'en piratant ou en étendant la bibliothèque. Vous savez que vous avez frappé ce mur et ce qui pourrait être la réponse à cette question.

Bien que vous puissiez créer un graphique personnalisé de chart.js, vous pouvez également le résoudre avec d3.js. J'ai pris l'un des exemples angulaires basiques de d3.js barchart et j'ai ajouté le comportement que vous voulez:

 var colors = d3.scale.category10(); // ... bars.enter().append('rect') .classed('bar', true) .attr({x: chartW, width: barW, y: function(d, i) { return y1(d); }, height: function(d, i) { return chartH - y1(d); }, fill: function(d,i) { return colors(i) } }) // ... 

http://plnkr.co/edit/9RCYAPCEj9iRsxkkYPaV?p=preview

Personnaliser un graphique de quelque façon que ce soit, comme changer le remplissage, le coup ou tout autre chose est à portée de main. Il en résulte encore beaucoup plus de code, mais si vous souhaitez personnaliser au-delà du support de la bibliothèque, c'est toujours beaucoup plus de code.