make every labels different in doughnut chart (react js) - reactjs

i have double doughnut chart in my react js project code. in that double chart dougnut i want to have 3 different labels in 3 different colour, what should i write to make that?
this my code now
var dataDoughnut1 = {
labels: ["Blue", "Green", "Red"],
datasets: [{
data: [1000],
backgroundColor: [
"#36A2EB"
],
labels: [
'Blue',
]
}, {
data: [400,600],
backgroundColor: [
"#C4D34C",
"#F7464A"
],
labels: [
'Green',
'Red'
],
}],
};
until now with that code the output labels is "blue","green" and "green" again
i want to make 3 different labels in 3 different colour too, anyone can help me?
result :

Ok, so i have read the docs of react-chartjs-2 and their Doughnut Chart does not support rendering two datasets like you want, i came up with this workaround that will help you to achieve what you want.
import React from "react";
import { Doughnut } from "react-chartjs-2";
import { MDBContainer } from "mdbreact";
const App = () => {
var dataDoughnut1 = {
labels: ["Blue", "Green", "Red"],
datasets: [
{
data: [1000, 0, 0],
//You should set here all the other colors desired from the other datasets so it can be interpreted by the component
backgroundColor: ["#36A2EB"],
labels: ["Blue"],
},
{
data: [400, 600],
backgroundColor: ["#C4D34C", "#F7464A"],
labels: ["Green", "Red"],
},
],
};
const options = {
responsive: true,
legend: {
display: false,
},
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
console.log(tooltipItem.datasetIndex);
var dataset = data.datasets[tooltipItem.datasetIndex];
var index = tooltipItem.index;
return dataset.labels[index] + ": " + dataset.data[index];
},
},
},
};
return (
<MDBContainer>
<h3 className="mt-5">Doughnut chart</h3>
<Doughnut data={dataDoughnut1} options={options} />
</MDBContainer>
);
};
export default App;
Here is the result

Related

How to use a static color for Chart.js bar chart's legend, when using an array of background colors [duplicate]

I have a bar chart that always shows 4 bars. The bars are coloured dynamically. It looks like the coloured box takes its colour from the first data. I would like to use the colour from the 4th (last) data value. Maybe the options:plugins:legend:label:sort function helps but I don't understand what it does.
options
const options = {
scales: {
x: {
grid: {
display: false,
color: 'rgba(0,0,0)'
}
},
y: {
display: false,
min: 0,
max: 4
},
},
plugins: {
legend: {
position: 'bottom'
}
}
}
So I don't know if I can change the data that the box color comes from, or if there is a config option somewhere where I can change it manually.
You can use the generateLabels function as described here.
Please take a look at below runnable sample code and see how it works.
new Chart('myChart', {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow'],
datasets: [{
label: 'My Dataset',
data: [300, 50, 100],
backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56']
}]
},
options: {
responsive: false,
plugins: {
legend: {
labels: {
generateLabels: chart => {
let ds = chart.data.datasets[0];
let color = ds.backgroundColor[ds.backgroundColor.length - 1];
return [{
datasetIndex: 0,
text: ds.label,
fillStyle: color,
strokeStyle: color
}];
}
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart" height="180"></canvas>
Following up with #uminder's answer, if you want to keep the hide/show chart and the line-through style after clicking on the legend, you can add the following line:
options: {
responsive: false,
plugins: {
legend: {
labels: {
generateLabels: chart => {
let ds = chart.data.datasets[0];
let color = ds.backgroundColor[ds.backgroundColor.length - 1];
return [{
datasetIndex: 0,
text: ds.label,
fillStyle: color,
strokeStyle: color,
+ hidden: !chart.isDatasetVisible(0)
}];
}
}
}
}
}

React + ChartJS V3: Annoations don't work

I'm using react-chartjs-2 v4.1 with ChartJS v3.8 in typescript.
I'd like to draw a horizontal line through my bar graph as shown below:
I find many half-written examples of which I cannot create a functional one. I couldn't find any complete, working example on how to use annotations.
My Code
I've added the chartjs-plugin-annotation package to my project.
Below is the code for a react component showing the graph of the screenshot. The annotation, however, does not work.
Can anyone tell me what's wrong with the code?
import React from 'react';
import { Bar } from 'react-chartjs-2';
export const MyChart: React.FC = () => {
const options2 = {
plugins: {
legend: {
display: false,
},
annotation: {
annotations: [
{
id: 'a-line-1',
type: 'line',
mode: 'horizontal',
scaleID: 'y',
value: 1.0,
borderColor: 'red',
borderWidth: 4,
label: {
enabled: false,
content: 'Test label',
},
},
],
},
},
};
const data2 = {
labels: [ 'a', 'b'],
datasets: [ { data: [1, 2] } ],
};
return (<Bar options={options2} data={data2} height={150} />
);
};
You dont import and register the annotation plugin:
import { Chart } from 'chart.js';
import annotationPlugin from 'chartjs-plugin-annotation';
Chart.register(annotationPlugin);
Based on LeeLenalee's answer here's a fully working example.
Changes to code in question:
import and register annotationPlugin
set annotation type to type: 'line' as const (not just type: 'line'). Otherwise typescript complains.
import React from 'react';
import { Bar } from 'react-chartjs-2';
import { Chart } from 'chart.js';
import annotationPlugin from 'chartjs-plugin-annotation';
Chart.register(annotationPlugin);
export const MyChart: React.FC = () => {
const options2 = {
plugins: {
legend: {
display: false,
},
annotation: {
annotations: [
{
id: 'a-line-1',
type: 'line' as const, // important, otherwise typescript complains
mode: 'horizontal',
scaleID: 'y',
value: 1.0,
borderColor: 'red',
borderWidth: 4,
label: {
enabled: false,
content: 'Test label',
},
},
],
},
},
};
const data2 = {
labels: [ 'a', 'b'],
datasets: [ { data: [1, 2] } ],
};
return (<Bar options={options2} data={data2} height={150} />
);
};

Labels for Nested Doughtnut Chart React ChartJS

I am trying to implement nested Doughnut using React-ChartJS-2 but the label seem not to appear correctly in the Outer Doughnut.
Here is what I tried after checking out many examples online.
The version I use for chart.js is ^3.7.1 and ^4.1.0 for react-chartjs-2
import React from "react";
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
import { Doughnut } from "react-chartjs-2";
ChartJS.register(ArcElement, Tooltip, Legend);
const DoughnutChart = ({ xLabels, yData, titleText }) => {
console.log(xLabels);
console.log(yData);
const options = {
responsive: true,
rotation: 270,
circumference: 180,
maintainAspectRatio: true,
animation: false,
legend: {
display: false,
},
plugins: {
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
console.log(tooltipItem.datasetIndex);
var dataset = data.datasets[tooltipItem.datasetIndex];
var index = tooltipItem.index;
return dataset.labels[index] + ": " + dataset.data[index];
},
},
},
},
};
const data = {
labels: ["Time elapsed", "Time remaining"],
datasets: [
{
labels: ["Total Time"],
label: "D1",
data: [5],
backgroundColor: ["rgb(80, 170, 80)", "#ccc"],
},
{
label: "D2",
labels: ["Time elapsed", "Time remaining"],
data: [3.2, 1.3],
backgroundColor: ["goldenrod", "#cccff"],
},
],
};
return (
<div style={{ position: "relative", margin: "auto", width: "80%" }}>
<Doughnut data={data} options={options} />
</div>
);
};
export default DoughnutChart;
The outer doughnut "1" label should be Time elapsed: 5 (does not show correct label)
The inner doughnut "2" label should be Time elapsed: 3.2 and "3" should be Time remaining: 1.3 (correct label is shown)
I expect the outer doughnut label to show Total Time: 5 but I see Time elapsed: 5. How do I fix it or what am I doing wrong ?
By the way, I try to use the call back to update the label but it seems not to work.
For those facing similar issue, to name individual doughnut chart based on separate data within the dataset, I updated the callbacks for the tooltip like so:
plugins: {
tooltip: {
enabled: true,
callbacks: {
label: (tooltipItem) => {
var dataIndex = tooltipItem.dataIndex;
return (tooltipItem.dataset.labels[dataIndex] + ": " + tooltipItem.dataset.data[dataIndex]
);
}
}
}
}
Note: For Chart.js 3, "context" parameter can also be used instead of tooltipItem.

Chartjs React Typescript moving x axis labels above chart

I'm using chartjs to generate a bar chart, and one of the requirements is to have the x-axis labels appear at the top of the chart rather than the bottom. (Even though I disagree with this, apparently there is no leeway from the client) and I'm having trouble following the documentation and any examples I find are for older versions.
The relative packages I'm using are:
"chart.js": "^3.7.1",
"react-chartjs-2": "^4.0.0",
Secondly they want the labels to wrap rather being a single line based on bar width, since it's responsive. I was experimenting with using arrays to break up the words as an example, but wondering if this can be done within chartjs. Here is the code I have setup so far (I had to use some lorem ipsum cause of sensitive data):
import * as React from 'react';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
ChartOptions
} from 'chart.js';
import { Bar } from 'react-chartjs-2';
import { Chart } from 'react-chartjs-2';
ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
);
// added as an example. if there is a negative value, the bar color changes.
const generateBgColors = (data : number[]) => {
const bgColors = [];
for(let i = 0; i < data.length; i++) {
const value = data[i];
if(value > 0) {
bgColors.push('rgba(53, 162, 235, 0.5)');
} else {
bgColors.push('rgba(255, 99, 132, 0.5)');
}
}
return bgColors;
}
const options = {
responsive: true,
maintainAspectRatio: true,
plugins: {
legend: {
display: false
}
},
scales: {
}
}
var data = [2.0, -2.0, 0.5, 1.5];
const labels = [
['Lorem ipsum dolor sit amet,', ' consectetur adipiscing elit.', ' Integer eget auctor felis.'],
['label2'],
['label3'],
['label4'],
];
const chartData = {
labels: labels,
datasets: [
{
data: [2.0, -2.0, 0.5, 1.5],
backgroundColor: generateBgColors(data)
}
]
}
const BeliefsChart : React.FunctionComponent = (props) => {
const chartRef = React.useRef<ChartJS>(null);
return (
<React.Fragment>
<Chart type="bar" ref={chartRef} options={options} data={chartData} height={50} />
</React.Fragment>
);
}
To make the labels appear on top in V3 of chart.js you need to specify the position to top in options.scales.x like so:
options: {
scales: {
x: {
position: 'top'
}
}
}
To achieve multi line labels you will need to define your labels array as arrays for the the labels that have to be multi lined. Each entry in the nested arrray will be a new line
labels = ['singel line', ['line 1', 'line 2'], ['line 1', 'line 2', 'line3']]
Live Example:
const options = {
type: 'bar',
data: {
labels: ['singel line', ['line 1', 'line 2'], ['line 1', 'line 2', 'line3']],
datasets: [{
label: '# of Votes',
data: [12, 19, 3],
backgroundColor: 'orange'
},
{
label: '# of Points',
data: [7, 11, 5],
backgroundColor: 'pink'
}
]
},
options: {
scales: {
x: {
position: 'top'
}
}
}
}
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>
Apologies in advance since I'm not familiar with Typescript, but hopefully the following answers will be of help to you regardless.
To position the x-axis labels, try adding the following scales details to your options:
const options = {
responsive: true,
maintainAspectRatio: true,
plugins: {
legend: {
display: false
}
},
scales: {
xAxes: [{
position: "top"
}]
}
}
I don't know if it's possible to make the labels wrap, but an alternative responsive solution might be to use a variable for the fontSize of the ticks (labels) and vary the fontSize value based on the size of the screen using a media query. For example:
import { useMediaQuery } from "react-responsive";
const isMobile = useMediaQuery({ query: '(max-width: 480px)' });
const responsiveFontSize = isMobile ? 12 : 16;
const options = {
responsive: true,
maintainAspectRatio: true,
plugins: {
legend: {
display: false
}
},
scales: {
xAxes: [{
position: "top"
}]
ticks: {
fontSize: responsiveFontSize,
}
}
}

React JS Chart JS 2 is not hiding the grid lines in the background

I am building a web application using React JS. My application needs to display some chart widgets on the dashboard. I am using React JS Chart 2 Package, https://www.npmjs.com/package/react-chartjs-2. I can display the chart but there is a problem with styling. I am trying to hide the grid lines in the background. It looks something like this now.
This is my code.
const data = {
labels: ['1', '2', '3', '4', '5', '6'],
datasets: [
{
label: '# of Red Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: '#6886b4',
},
{
label: '# of Blue Votes',
data: [2, 3, 20, 5, 1, 4],
backgroundColor: '#9db8d7',
},
{
label: '# of Green Votes',
data: [3, 10, 13, 15, 22, 30],
backgroundColor: '#112c61',
},
],
};
const options = {
scales: {
yAxes: [
{
gridLines: {
display:false
}
}
],
xAxes: [
{
gridLines: {
display:false
}
}
],
},
};
const GroupedBarChartWidget = (props) => {
return (
<>
<div className={"box"}>
<div className={"box-content"}>
<Bar data={data} options={options} />
</div>
</div>
</>
)
}
As you can see I am trying to hide the gridlines in the background using this.
gridLines: {
display:false
}
But they are still there. What is wrong with my code and how can I fix it?
you are using V2 syntax with V3,
your config needs to be like this:
options: {
scales: {
x: {
grid: {
display: false
}
},
y: {
grid: {
display: false
}
}
}
}
For all differences please read the migration guide

Resources