Как я могу установить разные цвета для каждого бара в angular-chart.js?

Я посмотрел на Как изменить цвета для Angular-Chart.js, но это относится к цветам для всего (набора данных), а не для конкретной полосы.

То, что я ищу, - это способ применения разных цветов для каждой гистограммы; ChartJS в угловой.

Итак, у меня есть гистограмма:

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

Со следующим угловым кодом (в контроллере, конечно)

$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() вернул бы случайный цвет.

Прямо сейчас colours Поле применяет этот цвет ко всем столбцам:

того же цветаразные цвета

когда я на самом деле хочу другой цвет для каждой полосы:

Plunker

3 ответа

Решение

Plunker Demo

Проще всего было изменить исходный файл chart.js так, чтобы он принимал массив цветов для fillColor, а не одну цветовую строку.

Если бы вы могли заставить работать одно из других предложенных решений, я думаю, что в конечном итоге это должно быть сделано очень неординарным способом.

Некоторым людям может не нравиться настраивать источник, но как просто и легко это сделать, и он достигает желаемого результата, и он не менее "угловат" в своем решении... давайте просто назовем это улучшением chart.js.

Обратите внимание, что я только изменил диаграмму "bar", чтобы она принимала массив цветов, потому что кажется, что chart.js ссылается на fillColor отдельно в каждом типе диаграммы. Таким образом, вы должны иметь возможность сделать эту модификацию работать для любого из типов диаграмм.

Место, которое нужно изменить:

            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);

Этот блок кода можно найти в функции Chart.type.extend для гистограммы. Просто посмотрите на это:

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

и загляните дальше внутрь этой функции, чтобы найти место, где она помещает fillColor в datasetObject.bars.

Теперь просто настройте диаграмму, как раньше, за исключением того, что передайте ей массив для 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}
      };
        }

Используя последнюю версию angular-chart.js, вот пример, который изменяет цвета в зависимости от условия, без изменения самой библиотеки. Вместо этого он использует chart-dataset-override особенность.

Хитрость заключается в использовании серии только с одним набором данных.

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

Добавьте следующий код в контроллер:

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

Выход

Производит:

Выход диаграммы

Ссылки по теме

Одна из самых больших проблем с библиотеками Chart заключается в том, что рано или поздно вы попадаете в стену, которая может быть взломана только путем взлома или расширения библиотеки. Знание, что вы врезались в эту стену, и что может быть ответом на этот вопрос.

Даже если вы можете создать собственный график chart.js, вы также можете решить его с помощью d3.js. Я взял один из базовых примеров угловых диаграмм d3.js и добавил желаемое поведение:

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

Любая настройка диаграммы, например, изменение заливки, обводки или чего-либо еще, находится в пределах досягаемости. Конечно, он все же содержит гораздо больше кода, но если вы хотите выполнить настройку, выходящую за рамки поддержки библиотеки, это всегда намного больше кода.

Другие вопросы по тегам