【问题标题】:How set color family to pie chart in chart.js如何在chart.js中将颜色系列设置为饼图
【发布时间】:2021-12-01 03:29:02
【问题描述】:

我正在尝试使用 Chart.js 绘制饼图。我的值来自数据库,因此我不知道数据库中有多少值。在这里,我想为每个值设置一个唯一的颜色。下面是我的例子。

var pieData = [
    {
        value: 20,
        color:"#878BB6"
    },
    {
        value : 40,
        color : "#4ACAB4"
    },
    {
        value : 10,
        color : "#FF8153"
    },
    {
        value : 30,
        color : "#FFEA88"
    }
];

var pieOptions = {
    segmentShowStroke : false,
    animateScale : true
}

var countries= document.getElementById("countries").getContext("2d");
        new Chart(countries).Pie(pieData, pieOptions);

目前在上面的示例中,我设置了硬编码值,但在我的示例中,数据 (Json) 来自 DB。

【问题讨论】:

    标签: charts chart.js


    【解决方案1】:

    我创建了一个包含 15 种不同颜色的简单颜色系列。
    它们不是随机选择的。取而代之的是,已选择颜色以最大化附近颜色之间的差异。

    您仍然可以创建少于 15 个数据点的图表,并且不会生成警告。

    代码如下:

    ctx = document.getElementById('myChart').getContext('2d');
    chart = new Chart(ctx, {
        type: 'pie',
        data: {
            datasets: [{
                label: 'Colors',
                data: [9, 8, 7, 6, 5, 4, 3, 2, 1],
                backgroundColor: ["#0074D9", "#FF4136", "#2ECC40", "#FF851B", "#7FDBFF", "#B10DC9", "#FFDC00", "#001f3f", "#39CCCC", "#01FF70", "#85144b", "#F012BE", "#3D9970", "#111111", "#AAAAAA"]
            }],
            labels: ['a','b','c','d','e','f','g','h','i']
        },
        options: {
            responsive: true,
            title:{
                display: true,
                text: "Color test"
            }
        }
    });
    

    这是html:

    <canvas id="myChart" width="600" height="400"></canvas>
    

    如果你想玩,这里是jsfiddle上的代码。

    我希望这会有所帮助:)

    【讨论】:

    • 我试图从一个空的 backgroundColor 数组开始,并在 data 上使用 for 循环来用随机颜色值填充 backgroundColor。这不起作用。任何线索为什么?此外,当我将鼠标悬停在饼图上时,会出现颜色,但这仅发生在带有 Script Error 的 JSFiddle 上
    【解决方案2】:

    首先,那里有很多色盲的人。这是一篇关于图表和色盲的好文章: Finding the Right Color Palettes for Data Visualizations

    这使用 Chart.js 2.4.0

    我正在从这样的渐变中计算不同的颜色:

    这给出了一个很好的凝聚力的外观。我从上面的链接中借用了调色板。我只测试了甜甜圈、条形图和折线图,但添加其他类型应该很容易。您还可以轻松制作自己的渐变。

    您可以找到jsfiddle here

    HTML:

    <div>
        <button onclick="doughnut();">Doughnut</button>
        <button onclick="lineBar('bar')">Bar</button>
        <button onclick="lineBar('line')">Line</button>
    </div>
    <div>
        <button onclick="chartColors('cool');">Cool</button>
        <button onclick="chartColors('warm')">Warm</button>
        <button onclick="chartColors('neon')">Neon</button>
    </div>
    <hr />
    <canvas id="canvas"></canvas>
    <hr />
    Palettes borrowed from:<br />
    <a href="https://blog.graphiq.com/finding-the-right-color-palettes-for-data-visualizations-fcd4e707a283">
        Finding the Right Color Palettes for Data Visualizations
    </a>
    

    Javascript:

    var ctx = document.getElementById('canvas').getContext('2d');
    var chart;
    var currentPalette = "cool";
    
    function doughnut() {
        if (chart) chart.destroy();
        chart = new Chart(ctx, {
            type: 'doughnut',
            data: {
                labels: ["Bananas", "Street lights", "Emotions", "Colors", "Children", "Nodes"],
                datasets: [{
                    data: [1, 2, 6, 9, 1, 2],
                }]
            },
        });
        chartColors();
    }
    
    function lineBar(type) {
        if (chart) chart.destroy();
        chart = new Chart(ctx, {
            type: type,
            data: {
                labels: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
                datasets: [{
                    label: "Bananas",
                    data: [1, 2, 6, 9, 1, 2]
                }, {
                    label: "Street lights",
                    data: [2, 6, 9, 1, 2, 7]
                }, {
                    label: "Emotions",
                    data: [2, 4, 6, 8, 6, 4]
                }, {
                    label: "Colors",
                    data: [3, 6, 3, 1, 3, 1]
                }, {
                    label: "Children",
                    data: [4, 4, 4, 5, 5, 5]
                }, {
                    label: "Nodes",
                    data: [5, 1, 2, 3, 4, 5]
                }, ]
            },
        });
        chartColors();
    }
    
    function chartColors(palette) {
        if (!palette) palette = currentPalette;
        currentPalette = palette;
    
        /*Gradients
          The keys are percentage and the values are the color in a rgba format.
          You can have as many "color stops" (%) as you like.
          0% and 100% is not optional.*/
        var gradient;
        switch (palette) {
            case 'cool':
                gradient = {
                    0: [255, 255, 255, 1],
                    20: [220, 237, 200, 1],
                    45: [66, 179, 213, 1],
                    65: [26, 39, 62, 1],
                    100: [0, 0, 0, 1]
                };
                break;
            case 'warm':
                gradient = {
                    0: [255, 255, 255, 1],
                    20: [254, 235, 101, 1],
                    45: [228, 82, 27, 1],
                    65: [77, 52, 47, 1],
                    100: [0, 0, 0, 1]
                };
                break;
            case 'neon':
                gradient = {
                    0: [255, 255, 255, 1],
                    20: [255, 236, 179, 1],
                    45: [232, 82, 133, 1],
                    65: [106, 27, 154, 1],
                    100: [0, 0, 0, 1]
                };
                break;
        }
    
        //Get a sorted array of the gradient keys
        var gradientKeys = Object.keys(gradient);
        gradientKeys.sort(function(a, b) {
            return +a - +b;
        });
    
        //Find datasets and length
        var chartType = chart.config.type;
        switch (chartType) {
            case "pie":
            case "doughnut":
                var datasets = chart.config.data.datasets[0];
                var setsCount = datasets.data.length;
                break;
            case "bar":
            case "line":
                var datasets = chart.config.data.datasets;
                var setsCount = datasets.length;
                break;
        }
    
        //Calculate colors
        var chartColors = [];
        for (i = 0; i < setsCount; i++) {
            var gradientIndex = (i + 1) * (100 / (setsCount + 1)); //Find where to get a color from the gradient
            for (j = 0; j < gradientKeys.length; j++) {
                var gradientKey = gradientKeys[j];
                if (gradientIndex === +gradientKey) { //Exact match with a gradient key - just get that color
                    chartColors[i] = 'rgba(' + gradient[gradientKey].toString() + ')';
                    break;
                } else if (gradientIndex < +gradientKey) { //It's somewhere between this gradient key and the previous
                    var prevKey = gradientKeys[j - 1];
                    var gradientPartIndex = (gradientIndex - prevKey) / (gradientKey - prevKey); //Calculate where
                    var color = [];
                    for (k = 0; k < 4; k++) { //Loop through Red, Green, Blue and Alpha and calculate the correct color and opacity
                        color[k] = gradient[prevKey][k] - ((gradient[prevKey][k] - gradient[gradientKey][k]) * gradientPartIndex);
                        if (k < 3) color[k] = Math.round(color[k]);
                    }
                    chartColors[i] = 'rgba(' + color.toString() + ')';
                    break;
                }
            }
        }
    
        //Copy colors to the chart
        for (i = 0; i < setsCount; i++) {
            switch (chartType) {
                case "pie":
                case "doughnut":
                    if (!datasets.backgroundColor) datasets.backgroundColor = [];
                    datasets.backgroundColor[i] = chartColors[i];
                    if (!datasets.borderColor) datasets.borderColor = [];
                    datasets.borderColor[i] = "rgba(255,255,255,1)";
                    break;
                case "bar":
                    datasets[i].backgroundColor = chartColors[i];
                    datasets[i].borderColor = "rgba(255,255,255,0)";
                    break;
                case "line":
                    datasets[i].borderColor = chartColors[i];
                    datasets[i].backgroundColor = "rgba(255,255,255,0)";
                    break;
            }
        }
    
        //Update the chart to show the new colors
        chart.update();
    }
    
    doughnut();
    

    这会给出这样的结果:

    【讨论】:

      【解决方案3】:

      您可以循环考虑您的 pieData 数组并为颜色值设置随机值。

      您可以将其设置为“rgb(230,0,0)”之类的值,并随机生成红绿蓝整数值。

      类似这样的:

      r = Math.floor(Math.random() * 200);
      g = Math.floor(Math.random() * 200);
      b = Math.floor(Math.random() * 200);
      color = 'rgb(' + r + ', ' + g + ', ' + b + ')';
      

      查看example jsfiddle here,带有随机值和随机颜色。 (运行它几次以了解它在不同数据集下的显示方式。)

      否则,您可以定义一组预定义颜色并使用它。考虑到超过 50 个项目的饼图的可读性不是很好。因此,默认列表 50 可能就可以了。

      【讨论】:

      • 嘿抱歉,我按照你的 jsfiddle 代码进行操作,但它不起作用。该图表没有显示任何内容,也没有错误消息。你知道为什么会这样吗?
      • 嗨,丹妮丝。我从一个不再存在的 CDN 调用 chart.js。现在已经修好了。试试看,我已经更新了链接。
      • 你也可以乘以255而不是200,因为每个RGB值的范围是0到255。
      【解决方案4】:

      不要浪费时间创建随机生成器。相反,选择一些明亮漂亮的颜色来循环播放。

      此函数采用任意大小并使用pallet 数组构建背景颜色数组。

      function getColors(length){
          let pallet = ["#0074D9", "#FF4136", "#2ECC40", "#FF851B", "#7FDBFF", "#B10DC9", "#FFDC00", "#001f3f", "#39CCCC", "#01FF70", "#85144b", "#F012BE", "#3D9970", "#111111", "#AAAAAA"];
          let colors = [];
      
          for(let i = 0; i < length; i++) {
            colors.push(pallet[i % (pallet.length - 1)]);
          }
      
          return colors;
        }
      

      然后您可以通过调用此函数来设置背景颜色,将数据的大小作为参数传递。

      datasets:
      [
        {
          data: data,
          backgroundColor: getColors(data.length)
        }
      ]
      

      这样你的颜色总是很漂亮,每个数据元素都有一个值。

      【讨论】:

      • 如果饼图的元素多于这里指定的颜色怎么办?
      • @KaranBhalla 颜色会回到开头。这是因为我使用模数符号。 23 % 24 == 2324 % 24 == 0,创建一个重复的配色方案。就个人而言,我发现这种显示颜色的方法看起来更漂亮,因为您可以选择要显示的颜色。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多