【问题标题】:Different color for each bar in a bar chart; ChartJS条形图中每个条的颜色不同; ChartJS
【发布时间】:2014-10-25 00:17:26
【问题描述】:

我在我正在处理的项目中使用 ChartJS,我需要为条形图中的每个条形图使用不同的颜色。

这是条形图数据集的示例:

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

有什么方法可以不同地绘制每个条吗?

【问题讨论】:

  • 为了节省一些滚动,this answer 提到您可以将数据集的fillColor 设置为数组,chart.js 将遍历数组,为每个条形选择下一种颜色绘制。

标签: javascript chart.js


【解决方案1】:

从 v2 开始,您可以通过 backgroundColor 属性简单地指定一个值数组以对应每个条的颜色:

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

borderColorhoverBackgroundColorhoverBorderColor 也可以这样做。

来自Bar Chart Dataset Properties上的文档:

某些属性可以指定为数组。如果这些设置为数组值,则第一个值适用于第一个条,第二个值适用于第二个条,依此类推。

【讨论】:

    【解决方案2】:

    解决方法:调用update方法设置新值:

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

    【讨论】:

    • 这段代码不能以当前形式工作,因为 myObjBar 是在 window.onload 中定义的,但它在主脚本流程中使用,所以当我们尝试更改 myObjBar 时,不会定义 myObjBar颜色。但是,我将底部的颜色更改代码移动到与生成条形图的范围相同的范围内,并且效果很好!我真的不想修改 chart.js 来获得如此简单的工作,所以我对这种方法非常满意。编辑:我已经提交了对答案的编辑以应用我的修复,只需要等待它被批准。
    • 不幸的是,这似乎在 Firefox 或 IE 10 或 11 中不起作用。这是一个 JSFiddle:jsfiddle.net/3fefqLko/1。关于如何使其跨浏览器工作的任何想法?
    • 更正:它确实可以跨浏览器工作。只是你可以在Chrome中做fillColor = "#FFFFFF;",但是最后的分号不应该有,FF和IE都不接受。
    • 更新:您需要指定“._saved.fillColor”以及“.fillColor” - 它使用 _saved 值在鼠标悬停(突出显示)后恢复 - 例如如果您不为其分配新颜色,它会恢复原始颜色
    • 更新:这不适用于最新版本(2.0 +),但适用于 1.0.2
    【解决方案3】:

    查看 Chart.Bar.js 文件后,我设法找到了解决方案。 我用这个函数来生成随机颜色:

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

    我已将它添加到文件的末尾,并在“fillColor:”下调用了这个函数

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

    所以现在看起来像这样:

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

    它的工作原理是我为每个条得到不同的颜色。

    【讨论】:

    • 您能否发布您的完整解决方案(例如,使用数据和数据集变量等)?我想做类似的事情,我似乎无法复制你的解决方案。谢谢
    • 嘿@casey,这是完整的 Chart.Bar.js 文件(您需要替换的那个)。 pastebin.com/G2Rf0BBn,我突出显示了造成差异的那条线。请注意,在底部有一个函数,它根据索引“i”从数组中返回不同的颜色。数据集保持不变(就像问题中的那个)。希望对你有所帮助。
    • 这绝对有帮助,谢谢!我没有意识到您正在修改实际的 Chart.js 文件,而不是您自己的代码。
    • 这是一个很棒的解决方案,并不是 ChartJS 独有的。
    【解决方案4】:

    如果您查看基于 Chart.js 构建的库“ChartNew”,您可以通过将值作为数组传递来做到这一点:

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

    【讨论】:

    • 你的简单解决方案对我有用,谢谢,chartNew.js 对我来说非常好
    • 我们如何改变chartnew js中的ingraphdatashow颜色??
    • 非常感谢!不知道 fillColor 接受了一个数组。
    【解决方案5】:

    你可以调用这个函数来为每个条生成随机颜色

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

    【讨论】:

    • 嘿@Sudharshan 感谢您的回答,这将导致每个图表的颜色不同,但不会导致条形图中的每个条形,这是我想要的结果。有什么想法吗?
    • 感谢此代码。我能够使用它来更改条形本身的颜色。 backgroundColor 选项允许这样做。
    • 在 2.8 版中,您可以使用函数 backgroundColor: randomColorGenerator, 设置背景颜色,而不是函数 backgroundColor: randomColorGenerator(), 的结果。该函数是为每个项目调用的,而不是为所有项目调用一次。
    【解决方案6】:

    在这里,我通过制作两个函数解决了这个问题。

    1. dynamicColors() 生成随机颜色

    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() 创建颜色数组

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

    那么,就通过吧

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

    【讨论】:

      【解决方案7】:

      截至 2019 年 8 月,Chart.js 现在已内置此功能。

      您只需向 backgroundColor 提供一个数组。

      示例取自https://www.chartjs.org/docs/latest/getting-started/

      之前:

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

      之后:

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

      我刚刚测试了这个方法并且它有效。每个条形都有不同的颜色。

      【讨论】:

        【解决方案8】:

        生成随机颜色;

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

        并为每条记录调用它;

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

        最后设置颜色;

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

        【讨论】:

          【解决方案9】:

          这是一种使用color-hash生成一致随机颜色的方法

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

          【讨论】:

            【解决方案10】:

            我是这样处理的: 我推送了一个数组“颜色”,其条目数与数据数相同。为此,我在脚本末尾添加了一个函数“getRandomColor”。 希望对你有帮助...

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

            【讨论】:

              【解决方案11】:

              如果您无法使用 NewChart.js,您只需更改使用数组设置颜色的方式。 在 Chart.js 中找到辅助迭代:

              替换这一行:

              fillColor : dataset.fillColor,
              

              对于这个:

              fillColor : dataset.fillColor[index],
              

              生成的代码:

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

              在你的 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]
                              }
                            ]
              

              【讨论】:

              • 我创建了条形图代码的自定义子类,并在初始化程序中添加了类似的代码来执行此操作。
              【解决方案12】:

              试试这个:

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

              【讨论】:

                【解决方案13】:

                这适用于当前版本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(); 
                

                }

                【讨论】:

                  【解决方案14】:

                  采取其他答案,如果您想获得每个条的随机颜色列表,这里有一个快速解决方法:

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

                  现在你可以在数据的 backgroundColor 字段中使用这个函数了:

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

                  【讨论】:

                  • 这个答案需要工作。它给我带来了问题。我不得不将其重写为function getRandomColor(n) { var letters = '0123456789ABCDEF'.split(''); var color = '#'; for (var i = 0; i &lt; 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color; }
                  【解决方案15】:

                  如果你知道你想要什么颜色,你可以在一个数组中指定颜色属性,像这样:

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

                  【讨论】:

                    【解决方案16】:

                    我最近才遇到这个问题,这是我的解决方案

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

                    【讨论】:

                      【解决方案17】:

                      代码基于以下pull request

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

                      【讨论】:

                      • 非常有用的想法 - 不仅仅是选择随机颜色。为了进一步改善这一点,当有大量的条时,您也可以调整饱和度值,这样您就不会只是在色轮上绕圈,而是在它上面盘旋。
                      【解决方案18】:

                      我所做的是创建一个随机颜色生成器,这里有很多人建议

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

                      然后编码

                      var chartContext = document.getElementById('line-chart');
                          let lineChart = new Chart(chartContext, {
                              type: 'bar',
                              data : {
                                  labels: <?php echo json_encode($names); ?>,
                                  datasets: [{
                                      data : <?php echo json_encode($salaries); ?>,
                                      borderWidth: 1,
                                      backgroundColor: dynamicColors,
                                  }]
                              }
                              ,
                              options: {
                                  scales: {
                                      yAxes: [{
                                          ticks: {
                                              beginAtZero: true
                                          }
                                      }]
                                  },
                                  responsive: true,
                                  maintainAspectRatio: false,
                              }
                          });
                      

                      注意函数调用时没有括号 这使得代码每次都调用函数,而不是创建一个数组 这也可以防止代码对所有条使用相同的颜色

                      【讨论】:

                      • 假设反对意见来自在回答中使用动态颜色,而原始问题已硬编码颜色,这意味着我们希望手动控制显示的颜色
                      【解决方案19】:

                      在 dataPoints 中为每个条形传递一个颜色参数,如下所示:

                      {y: your value, label: your value, color: your color code}
                      

                      【讨论】:

                        【解决方案20】:

                        function getRandomColor() {
                        
                                const colors = [];
                                var obj = @json($year);
                                const length = Object.keys(obj).length;
                                for(let j=0; j<length; j++ )
                                {
                                    const letters = '0123456789ABCDEF'.split('');
                                    let color = '#';
                                    for (let i = 0; i < 6; i++ ) {
                                        color += letters[Math.floor(Math.random() * 16)];
                                    }
                                    colors.push(color);
                                }
                                return colors;
                            }
                        

                        对不同的颜色使用此功能

                        【讨论】:

                        • 它用于条形图和饼图JS中的不同colo
                        • 你可以edit你的答案而不是添加cmets。该链接就在您的帖子下方以供分享。
                        • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
                        猜你喜欢
                        • 2015-08-09
                        • 1970-01-01
                        • 2014-05-11
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2013-03-15
                        • 1970-01-01
                        相关资源
                        最近更新 更多