I'm trying to change the background color of labels in a Polar Chart. I want to change the background color to black.
I'm using the global variable to change the font color:
Chart.defaults.global.defaultFontColor = 'rgba(255, 255, 255, 0.7)';
This is the chart that is shown.
Chart Printscreen
new Chart(ctx, {
data: data = {
datasets: [{
data: [25, 10, 20],
backgroundColor: [
'yellow',
'blue',
'red',
],
borderColor: [
'yellow',
'blue',
'red',
],
}],
labels: [
'Yellow',
'Blue',
'Red',
]
},
type: 'polarArea',
});
Thanks for the attention!
I checked the official documentation, and they seemed to have the same issue, especially when changing the theme to 'Night' or 'Sepia' from 'White'.
However, under further inspection, I found this GitHub issue that explained it.
After type: 'polarArea', add the following code to change the background-color of the text elements:
options: {
scale: {
ticks: {
backdropColor: 'black'
}
}
}
There is also a JSFiddle I made, which is here. Also, in this GitHub issue, I found that docs for this is under Linear Radial Axis, not in Polar Area. Hope that helps!
Related
I have a chart with three datasets (Svelte REPL with code and result) and would like to change the background colors of the boxes corresponding to each set, for example:
let legendColors = ['#dddddd', '#aaaaaa', '#777777'];
After several attempts the closest I got was changing font color, but not even that as array, only a single one. :(
How do I get the boxes of the legend to be in the 3 colors I want?
Thank you in advance for your help!
Edit: I did find something here: What happened to generateLegend() in chartjs 3.0?, but that removes the functionality of the legend (i.e. removing parts of the data).
Edit: Another answer below has running snippet that is simpler to implement which also answers OP's request. My original answer below is more focused on building the legend completely by oneself.
Live Demo. I've found this is fun...
Some points to note:
You need to build the legend yourself, as your colors are not "relevant" to the data you use (that's why by default it is using the colors from dataset "a") (edited as another answer shows such possibility)
As you are using Svelte, in the Demo I used the <style> which binds with the <div> for the legend for styling of the legend.
For people who ain't using Svelte, or are seeking solutions within Chart.js, they should follow the advice from the StackOverflow answer OP linked -- they need to build the legend using the plugins field of 2nd argument when creating a new Chart()
No matter which route to take, to keep the functionality of the legend as OP mentioned, I added a tweaked version of default behaviour of OnClick.
P.S. For (3) we have to further override generateLabels() (here, but may cause meta.controllers._resolveAnimation having problems, which we may still need to override onClick).
P.P.S. When a legend item is clicked, the label is crossed out (strikethrough) as a default behaviour. That is left as a further exercise or another answer. (For Svelte, use Boolean flags to change styles. Alternatively, hack with CSS checked checkbox labels).
You can achieve this in 2 ways, using a custom generateLabels function or by specifying a backgroundcolor in the dataset.
Custom generateLabels:
let legendColors = ['#dddddd', '#aaaaaa'];
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange'
}
]
},
options: {
plugins: {
legend: {
labels: {
generateLabels: function(chart) {
const datasets = chart.data.datasets;
const {
labels: {
usePointStyle,
pointStyle,
textAlign,
color
}
} = chart.legend.options;
return chart._getSortedDatasetMetas().map((meta, i) => {
const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
const borderWidth = Chart.helpers.toPadding(style.borderWidth);
return {
text: datasets[meta.index].label,
fillStyle: legendColors[i],
fontColor: color,
hidden: !meta.visible,
lineCap: style.borderCapStyle,
lineDash: style.borderDash,
lineDashOffset: style.borderDashOffset,
lineJoin: style.borderJoinStyle,
lineWidth: (borderWidth.width + borderWidth.height) / 4,
strokeStyle: style.borderColor,
pointStyle: pointStyle || style.pointStyle,
rotation: style.rotation,
textAlign: textAlign || style.textAlign,
borderRadius: 0, // TODO: v4, default to style.borderRadius
// Below is extra data used for toggling the datasets
datasetIndex: meta.index
};
}, this);
}
}
}
}
},
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>
Adding background color prop in datasets:
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink',
pointBackgroundColor: 'pink',
backgroundColor: '#dddddd'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange',
pointBackgroundColor: 'orange',
backgroundColor: '#aaaaaa'
}
]
},
options: {},
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>
For some reason, the legend on this doughnut chart created with chart.js is not moving to the right. Even tried adding the rule to chart creation itself instead of putting it in the variable
EDIT
With further inspection, it appears any options that are set to the legend do not appear to be working.
const mobileData = {
labels: ["Desktop", "Tablet", "Phons"],
datasets: [{
label: '# of Users',
data: [2000, 550, 500],
borderWidth: 0,
backgroundColor: [
'#7477BF',
'#78CF82',
'#51B6C8'
]
}]
};
const mobileOptions = {
legend: {
position: 'right',
labels: {
boxwidth: 20,
fontStyle: 'bold'
}
}
}
let mobileChart = new Chart(mobileCanvas, {
type: 'doughnut',
data: mobileData,
options: mobileOptions
});
Here's a fiddle to the project minus images.
https://jsfiddle.net/5j2ucpv6/3/
You are using the new V3 version of the lib instead of V2
So please read the migration guide from chart.js (https://www.chartjs.org/docs/latest/getting-started/v3-migration.html)
The legend options have been moved to the plugin section like this
options: {
plugins: {
legend: {
position: 'right'
}
}
}
I am using JQuery Flot graph plugin to plot some bar charts in a page. when I plot a graph by datas and option below:
var chartData = [{
label: 'success',
data: [[0,1],[1,1]],
bars: {
order: 0,
fillColor: '#fff'
},
color: '#fff'
}, {
label: 'fail',
data: [[0,3],[2,1]],
bars: {
order: 1,
fillColor: 'rgba(255,255,255,0.5)'
},
color: 'rgba(255,255,255,0.5)'
}];
var barChartOptions = {
...
legend:{
container: '.flot-chart-legends--bar',
backgroundOpacity: 0.5,
noColumns: 0,
lineWidth: 0,
labelBoxBorderColor: 'rgba(255,255,255,0)'
}
};
$.plot($('.flot-bar'), chartData, barChartOptions);
It works for my bar chart, however, the other charts which hasn't label attached the same label. How can I do for it? Please help!
I sovled it! Check the source code in flot.js and found the incorrect code as follow:
$(options.legend.container).html(table);
which makes all the selectors of container contained the same html. I corrected it like this:
placeholder.parent().find(options.legend.container).html(table);
and the html is only attahced to the right chart I want.
In my chart I'm using Points to create rounded circles like
{
id: 7,
label: 'Sample 1',
borderColor: '#ff3f0c',
backgroundColor: '#ff3f0c',
pointBorderColor: '#ff3f0c',
pointBackgroundColor: '#fff',
pointBorderWidth: 1,
pointRadius: 5,
fill: false,
data: [0, 5, 2, 0, 3, 3, 5, 1, 0, 2, 2, 0]
},
The problem with this is that my bottom legend is inheriting the dot style, more specifically the pointBackgroundColor which is white.
The chart tooltip also suffers from the same problem. It doesn't need to be rounded, but it's filling the background color with white.
The inherits occurs with the code:
legend:
{
display: true,
position: 'bottom',
labels:
{
boxWidth: 10,
usePointStyle: true
}
},
My goal:
The chart dots be rounded and have white background
The chart legend be rounded and inherit the background in the backgroundColor property
The chart tooltip be square and inherit the background in the backgroundColor property
JSFiddle to see the issue: https://jsfiddle.net/0eLtkzmy/
Solved.
The solution is to maintain the code as it is
The solution is here https://stackoverflow.com/a/43173498/3355243
The solution is below
Applies the colors of the tooltips taking in consideration the dataset index.
options:
{
tooltips:
{
mode: 'index',
intersect: false,
callbacks:
{
labelColor: function(tooltipItem, chart)
{
var datasetIndex = tooltipItem.datasetIndex;
var borderColor = chart.legend.legendItems[datasetIndex].fillStyle;
var backgroundColor = chart.legend.legendItems[datasetIndex].fillStyle;
return {
borderColor: borderColor,
backgroundColor: backgroundColor
};
},
}
},
}
I have been racking my brain on this for days now, starting to think its a bug in the chartJS package? When I setup a stacked bar chart, even with a pretty simple options config, I tend to get very slim transparent gaps between the bar data itself. The more data you have in the bar, the more apparent it becomes. I've isolated it completely out of my code (we're using React and react-chartjs-2, but i=I've recreated it using vanilla ChartJS, latest version).
In my example here, I've turned all the bar data to black, and put it on a red background, with a hover border of white. If you look close you'll see vertical lines of red between the bars (ie: we're seeing through the bars themselves to the red background) and the white hover border never triggers on the left side.
Any ideas as to if this may be a data issue, or an options setting I haven't messed with yet, or possibly a bug in the package? The chart we are rendering this with is using thousands of data points and it starts to look like a broken gradient with all the subpixel transparent lines showing up. Any assistance would be greatly appreciated, thanks!
Here's some quick demo code i've put in a JSFiddle as an example:
var barOptions_stacked = {
scales: {
xAxes: [
{
ticks: {
fontColor: "#FFF"
},
stacked: true,
},
],
yAxes: [
{
ticks: {
fontColor: "#FFF"
},
stacked: true,
},
],
},
};
var myChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ['2014', '2013'],
datasets: [
{
label: "one",
data: [100,200],
backgroundColor: 'black',
hoverBorderColor: '#FFFFFF',
},
{
label: "two",
data: [300, 400],
backgroundColor: 'black',
hoverBorderColor: '#FFFFFF',
}
],
},
options: barOptions_stacked,
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<div style="background-color: red">
<canvas id="ctx"></canvas>
</div>
Here is a JSFiddle example, if you really expand the chart view up you'll see the lines in play.
JSFiddle Example
Bar Chart Example Img