Grouped bar chart having each group with different data using chart.js - chart.js

I am looking to build the same as shown in the image, I checked chart.js documentation(https://www.chartjs.org/docs/3.0.2/) but didn't find anything like this. Is it possible to create a chart like this using chart.js?

Yes you can use the datalabels plugin to achieve what you want:
Example:
Chart.register(ChartDataLabels);
var options = {
type: 'bar',
data: {
labels: ["Category 1", "Category 2", "Category 3"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3],
animals: ['cat', 'dog', 'bear'],
borderWidth: 1,
backgroundColor: ['orange', 'blue', 'gray']
},
{
label: '# of Points',
data: [7, 11, 5],
animals: ['monkey', 'bird', 'fish'],
borderWidth: 1,
backgroundColor: ['yellow', 'cyan', 'purple']
}
]
},
options: {
plugins: {
title: {
display: true,
text: 'title'
},
datalabels: {
anchor: 'end', // remove this line to get label in middle of the bar
align: 'end',
formatter: (val, x) => (x.dataset.animals[x.dataIndex]),
labels: {
value: {
color: 'purple'
}
}
}
}
}
}
var 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.3.2/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0-rc"></script>
</body>

you can use Plotly.js for grouped chart please check below code
Reference URL : https://plotly.com/javascript/bar-charts/
var trace1 = {
x: ['giraffes', 'orangutans', 'monkeys'],
y: [20, 14, 23],
name: 'SF Zoo',
type: 'bar'
};
var trace2 = {
x: ['giraffes', 'orangutans', 'monkeys'],
y: [12, 18, 29],
name: 'LA Zoo',
type: 'bar'
};
var data = [trace1, trace2];
var layout = {barmode: 'group'};
Plotly.newPlot('myDiv', data, layout);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-1.58.4.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>

Related

How to display small numbers in chart js tooltip?

I am working with chart.js and I have data than is very small like this (0.00000023120098, 0.00000887272934, 0.00000343234). The problem is that, the tooltip only display 0 when I hover on the chart. I tried finding solutions but couldn't find any.
You will need to override the default label callback so it doesnt do any formatting:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow"],
datasets: [{
label: '# of Votes',
data: [0.00000023120098, 0.00000887272934, 0.00000343234],
borderColor: 'pink'
}]
},
options: {
plugins: {
tooltip: {
callbacks: {
label: (ctx) => (`${ctx.dataset.label}: ${ctx.raw}`)
}
}
}
}
}
var 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>

chartjs datalabels not showing anything with django template

I tried so many time to ask this question but no one was able to help me so I decided to deleted the previous question and reask with taking into considerations the answers that I received.
I have this chart created with chartjs, as you can see you can hover over points to see their coordinated or data, I would like to have an option to show them without having to hover. The reason why I want to do this is because I am going to add export to pdf, and it exports whatever it can see on the HTML , and exporting a chart without its values would be unreadable to the end user.
Note (I don't know if this matters but I am using django and I did not do any npm installation of datalabels)
Another Note : I was told that I have to register the plugin before using it, with
Chart.register(ChartDataLabels); but adding it the chart script just causes the chart to disappear.
.cann {
border: 3px solid darkgrey;
padding: 10px;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
width: 650px;
height: 250px;
margin-left: 3em;
}
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- semantic UI -->
<link rel="stylesheet" type='text/css' href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.14/semantic.min.css">
<!--Chart js-->
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.0.0-alpha"> </script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0-rc"></script>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$(document).ready(function (){
Chart.register(ChartDataLabels);
var ctx = document.getElementById('myChart');
window.myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
data: [12, 19, 3, 5, 2, 3],
label: 'Advisor Closed MTD',
backgroundColor: 'rgb(192,111,94)',
barThickness: 25,
datalabels: {
color: '#FFCE56'
}
}],
},
options: {
responsive: false,
plugins: {
datalabels: {
anchor: 'end',
align: 'end',
labels: {
value: {
color: 'blue'
}
}
}
}
}
}
);
});
</script>
<canvas id="myChart" class="cann"></canvas>
How about instead of reposting and deleting you post each time so people dont know whats wrong you actually keep your post so people can actually help you because with what you provide its working fine, chart shows, with register the plugin shows so unless you point out where its going bad and people can see it you wont get any better answers
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.2.1">
</script>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0-rc"></script>
<canvas id="turn_over_line" class="cann"></canvas>
<script>
// Turn over line chart
$(document).ready(function() {
Chart.register(ChartDataLabels);
var ctx = document.getElementById('turn_over_line');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [0, 1, 2, 3, 2, 3, 0.5, 8, 4, 2],
datasets: [{
backgroundColor: '#ccddee',
borderColor: '#5566aa',
data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}]
},
options: {
legend: false,
tooltip: false,
plugins: {
datalabels: {
align: function(context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
var invert = Math.abs(value) <= 1;
return value < 1 ? 'end' : 'start'
},
anchor: 'end',
backgroundColor: null,
borderColor: null,
borderRadius: 4,
borderWidth: 1,
color: '#223388',
font: {
size: 11,
weight: 600
},
offset: 4,
padding: 0,
formatter: function(value) {
return Math.round(value * 10) / 10
}
}
}
}
});
})
</script>
Actually my code was perfectly fine, I appreciate the effort of the guy who kept posting the same answer that did not help, I finally figured out that the issue is in my chartjs version , so if you are facing the same issue with chartjs 3.0.0-alpha , 3.2.1 seemed to fix it for me.

Responsive legend font size in react-chartjs 2

I have tried to make a pie chart using react-chartjs 2, It is working fine in desktop view but in mobile view the legend is not responsive it is taking much space and due to this the size of pie chart become very small.
my code:
function Chart(props: any) {
const option = {
tooltips: {enter image description here
callbacks: {
label: function (tooltipItem: any, data: any) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var meta = dataset._meta[Object.keys(dataset._meta)[0]];
var total = meta.total;
var currentValue = dataset.data[tooltipItem.index];
var percentage = parseFloat(
((currentValue / total) * 100).toFixed(1)
);
return currentValue + " (" + percentage + "%)";
},
title: function (tooltipItem: any, data: any) {
return data.labels[tooltipItem[0].index];
},
},
},
legend: {
display: true,
labels: {
fontSize: 12,
},
position: "right",
},
};
return (
<div className="chart">
<Pie data={props.ChartData} options={option} />
</div>
);
You can set your fontSize object as a ternery operator that checks the widts (or something else) to see if you are on a mobile device and give back the right fontSize according to it
If you want to update it real time because screen sizes change you can do that by mutating the chart options itself in a resizeEvent listner
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
legend: {
labels: {
fontSize: window.innerWidth > 350 ? 20 : 10
}
},
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);
window.addEventListener('resize', () => {
if (window.innerWidth < 350) {
chart.options.legend.labels.fontSize = 10;
} else {
chart.options.legend.labels.fontSize = 20
}
});
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js" integrity="sha512-hZf9Qhp3rlDJBvAKvmiG+goaaKRZA6LKUO35oK6EsM0/kjPK32Yw7URqrq3Q+Nvbbt8Usss+IekL7CRn83dYmw==" crossorigin="anonymous"></script>
</body>
Here is the way to have a responsive legend font size (also explained here)
options: {
plugins: {
legend: {
labels: {
// This more specific font property overrides the global property
font: {
size: 14
}
}
}
}
}

ChartJS - would like to create a mixed chart with horizontal Bar and a dot to represent the answer from the current user

I am trying to create a mixed chart with horizontal bar chart and a dot to represent the answer from the current user. I have the horizontal bar chart created (please see attached screenshot) and I would like to show a green dot to represent what the current user answered. I am able to show the green dot using a mixed vertical bar chart with a line chart (keeping all points on the line null, except the one that needs to show the green dot), but I am not able to make this work using a horizontal char.
https://www.dropbox.com/s/i4xrwabq49ufzth/Untitled.png?dl=0
Next time when you ask a question please post the code you already have so people can help you more easily, made a quick example for you you can see underneath here.
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Jan", "Feb", "Mar", "Apr", "May"],
datasets: [{
label: 'values',
backgroundColor: "red",
borderColor: "red",
data: [120, 23, 24, 45, 51]
}, {
type: 'line',
label: 'point',
backgroundColor: "green",
borderColor: "green",
data: [{
y: 'Feb',
x: 27
}]
}]
},
options: {
responsive: true,
indexAxis: 'y',
elements: {
point: {
radius: 10,
hoverRadius: 10
}
}
}
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.0.0-beta.11/chart.js" integrity="sha512-1J1wxKm2JepFETRYyEEDHQAjc5ZgRvdYKWdfiP27m1pfDmLQ47joNkTPHVvmfkg7BLktY+Jd0TU1VAuIO81uQg==" crossorigin="anonymous"></script>
</body>
</html>

Google chart vAxis title being cut off and needs to move closer to axis

I'm trying to use Google charts to display the results of a survey. All seems fine, apart from the title of the vAxis is being cut off slightly and I can't work out how to move it closer to the axis.
This is the code:
google.load("visualization", "1.0", {packages:["bar"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Question title goes here', 'Percentage Score'],
['Always', 40],
['Usually', 30],
['Rarely', 10],
['Never', 20]
]);
var options = {
chart: {
title: 'Section Title',
subtitle: 'Section subtitle',
},
legend: { position: "none" },
vAxis: {
title: 'Percentage',
viewWindowMode:'explicit',
viewWindow: {
max:100,
min:0
}
},
bars: 'vertical', // Required for Material Bar Charts.
width: 600,
height: 500
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
I have a fiddle here:
https://jsfiddle.net/SBComms/pa4yLcb3/
With a Core Chart, you can adjust the size of the chartArea to allow room for the title.
However, this doesn't appear to work for a Material Chart.
Also, I would recommend loading with loader.js vs. the older library jsapi.
See following example...
google.charts.load('current', {
callback: drawChart,
packages: ['bar', 'corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Question title goes here', 'Percentage Score'],
['Always', 40],
['Usually', 30],
['Rarely', 10],
['Never', 20]
]);
var options = {
chart: {
title: 'Section Title',
subtitle: 'Section subtitle',
},
chartArea: {
backgroundColor: 'cyan',
height: 400,
left: 60,
top: 20,
width: 500
},
legend: {
position: "none"
},
vAxis: {
title: 'Percentage',
viewWindowMode:'explicit',
viewWindow: {
max:100,
min:0
}
},
bars: 'vertical',
width: 600,
height: 500
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
var chart2 = new google.visualization.ColumnChart(document.getElementById('barchart_core'));
chart2.draw(data, options);
};
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div>========MATERIAL========</div>
<div id="barchart_material"></div>
<div>==========CORE==========</div>
<div id="barchart_core"></div>
I managed to find a real fiddle to the problem. I have updated the chart script so that the vAxis fontSize is 18:
google.load("visualization", "1.0", {packages:["bar"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['', 'Percentage'],
['Always', 40],
['Usually', 30],
['Rarely', 10],
['Never', 20]
]);
var options = {
chart: {
title: 'Company Performance'
},
legend: { position: "none" },
vAxis: {
title: 'Percentage',
titleTextStyle: {
fontSize: '18',
},
viewWindowMode:'explicit',
viewWindow: {
max:100,
min:0
}
},
bars: 'vertical', // Required for Material Bar Charts.
width: 400,
height: 400
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
I have then added a CSS setting to force the font size back to normal:
#barchart_material g text {
font-size: 12px !important;
}
I have updated the fiddle here: https://jsfiddle.net/SBComms/pa4yLcb3/1/