条形图中每个条的颜色不同; ChartJS

Posted

技术标签:

【中文标题】条形图中每个条的颜色不同; ChartJS【英文标题】:Different color for each bar in a bar chart; 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 将遍历数组,为每个条形选择下一种颜色绘制。 【参考方案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颜色?? 希望对您有所帮助! github.com/FVANCOP/ChartNew.js/wiki/100_080_In_Graph_Data 非常感谢!不知道 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。

以上是关于条形图中每个条的颜色不同; ChartJS的主要内容,如果未能解决你的问题,请参考以下文章

更改条形图中的条形颜色

Python:带颜色条的条形图

在条形图中的条形顶部显示值

在 MPAndroidChart 条形图中为条形设置不同的颜色

在悬停时在堆积条形图上绘制水平线(图表 js)

如何更改条形图中条形的颜色?