9π
You could loop thought your pieData array and set random values for the color value.
You can set this one with a value like βrgb(230,0,0)β and generate the red green blue integer values randomly.
Something like this :
r = Math.floor(Math.random() * 200);
g = Math.floor(Math.random() * 200);
b = Math.floor(Math.random() * 200);
color = 'rgb(' + r + ', ' + g + ', ' + b + ')';
See an example jsfiddle here, with random values and random colors. (Run it several times to get an idea of how it displays with different data sets.)
Or else you could define an array of predefined colors and just use that. Consider that a pie chart with more than 50 items is not very readeable. So a default list of 50 might just be ok.
28π
I have created a simple color family with 15 different colors.
They are not randomly chosen. Instead, the colors have been chosen to maximize the difference between near colors.
You can still create the chart with less than 15 data points and no warning will be generated.
Here is the code:
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"
}
}
});
This is the html:
<canvas id="myChart" width="600" height="400"></canvas>
If you want to play with it, here is the code on jsfiddle.
I hope this will help π
12π
First of all, there are a lot of color blind people out there. Here is a nice article about charts and color blindness:
Finding the Right Color Palettes for Data Visualizations
This uses Chart.js 2.4.0
Iβm calculating the different colors from a gradient like this:
This gives a nice cohesive look. I have borrowed the palettes from the link above. I have only tested with doughnut, bar and line charts, but it should be easy enough to add other types. You can also easily make your own gradients.
You can find a 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();
This would give something like this:
6π
Donβt waste your time creating a random generator. Instead, pick a few bright pretty colors to loop through.
This function takes any size and builds an array of background colors using the pallet
array.
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;
}
console.log(getColors(10));
You can then set your background colors by calling this function, passing the size of your data as a parameter.
datasets:
[
{
data: data,
backgroundColor: getColors(data.length)
}
]
This way your colors are always pretty and every data element is assigned a value.