【问题标题】:How can I set different colours for each bar in angular-chart.js?如何为 angular-chart.js 中的每个条设置不同的颜色?
【发布时间】:2015-07-12 01:23:39
【问题描述】:

我查看了How to change colours for Angular-Chart.js,但它与整个(数据集)的颜色有关,而不是特定条形。

我正在寻找一种将Different color for each bar in a bar chart; ChartJS 应用于 Angular 的方法。

所以,我有一个条形图:

<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

【问题讨论】:

标签: javascript angularjs charts bar-chart


【解决方案1】:

使用最新版本的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
        }
      }]
    }
  };

输出

生产:

相关链接

【讨论】:

    【解决方案2】:

    Plunker Demo

    最简单的做法是修改chart.js 源文件以接受用于fillColor 的颜色数组而不是单个颜色字符串。

    如果您可以让其他提议的解决方案之一发挥作用,我认为最终将不得不以一种非常不合时宜的方式完成。

    有些人可能不喜欢调整源代码,但是因为它是多么简单易行,它达到了预期的结果,而且它的解决方案一点也不“棱角分明”......让我们称之为对 chart.js 的改进。

    请注意,我只修改了“条形”图表以接受颜色数组,因为 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",
    

    并在该函数内部进一步查看它将填充颜色推送到 datasetObject.bars 的位置。

    现在像以前一样设置你的图表,除了为它提供一个填充颜色数组:

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

    【讨论】:

    • 如果您想避免总是必须提供颜色,我建议使用以下代码行更新库: Array.isArray(dataset.fillColor) ? dataset.fillColor[index] : dataset.fillColor
    【解决方案3】:

    图表库的一个更大的问题是,迟早你会碰壁,这只能通过黑客或扩展库来破坏。知道你撞到了那堵墙以及这个问题的答案可能是什么。

    即使您可以创建自定义 chart.js 图表,您也可以使用 d3.js 解决它。我采用了基本的 Angular 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

    以任何方式自定义图表,例如更改填充、描边或其他任何方式都触手可及。 虽然还有很多代码是有原因的,但是如果您想在库支持之外进行自定义,总是需要更多代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      相关资源
      最近更新 更多