I am trying to add more chart on the div, I want to render more charts out at the same page using for loop or something. i can render charts using just paste another chart. but I want to render the more charts with using for loop or something in vanila javascript. i want to know if it's possible.
enter image description here
Yes this is possible, you can just call the new chart in a for loop, make sure to save the chart instances so you can work with them later
example:
const charts = {
options0: {
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: {}
},
options1: {
type: 'bar',
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: {}
},
options2: {
type: 'radar',
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: {}
}
}
let activeCharts = [];
for (let i = 0; i < Object.keys(charts).length; i++) {
activeCharts.push(new Chart(document.getElementById(`con${i}`).getContext('2d'), charts[`options${i}`]));
}
<body>
<canvas id="con0" width="600" height="400"></canvas>
<canvas id="con1" width="600" height="400"></canvas>
<canvas id="con2" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.0/chart.js" integrity="sha512-opXrgVcTHsEVdBUZqTPlW9S8+99hNbaHmXtAdXXc61OUU6gOII5ku/PzZFqexHXc3hnK8IrJKHo+T7O4GRIJcw==" crossorigin="anonymous"></script>
</body>
Related
When you hover over a specific data point on a chartjs linechart the point's value can be shown. But let's say you hover on the graph, not on a specific data point but over the "empty space". In that case there should be some function to show the values of the points vertically aligned with the pointer. Does any such solution exist?
Basically the reason I'm asking is to be able to make mobile-friendly graphs and it can be difficult/irritating for the user to try and hit the small data points with their fingers.
Yes, you can set intersect to false in the tooltip config:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'orange'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'pink'
}
]
},
options: {
plugins: {
tooltip: {
intersect: false
}
}
}
}
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.0/chart.js"></script>
</body>
I can't figure out why my console.log isn't triggered in the Chart.js tooltip itemSort function. Do I miss something ?
plugins: {
legend: {
display: false,
},
tooltip: {
backgroundColor: "transparent",
titleColor: "black",
titleAlign: "center",
bodyColor: "black",
bodyAlign: "center",
displayColors: false,
callbacks: {
label: (element) => element.raw,
},
itemSort: (elements) => {
console.log("elements", elements);
return elements;
},
},
},
This is because by default the interaction mode is 'point' so it only shows a single value and thus can not be sorted. So chart.js does not call the method. If you make it another interaction mode like 'index' where it shows the tooltip for all datapoints at that data index it is getting called:
const 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: {
plugins: {
tooltip: {
mode: 'index',
itemSort: (e, x) => {
console.log(e.raw, x.raw) // Dont log entire objects since stack does not like that
}
}
}
}
}
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.0/chart.js"></script>
</body>
Edit:
From your comment on deleted answer if you want to change the order of the label and the value you should use the label callback instead of using the sort function
const 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: {
plugins: {
tooltip: {
callbacks: {
label: (e) => (`${e.formattedValue}, ${e.label}`)
}
}
}
}
}
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.0/chart.js"></script>
</body>
I want to show all tooltip always (not only hover), so that when i download it as pdf i can see the tooltip data. I used chartjs 3.1. it is possile?
If you want all datapoints you cant use the tooltip for that, you will have to use the datalabels plugin for that: https://v2_0_0-beta_1--chartjs-plugin-datalabels.netlify.app/samples/charts/line.html
If you only want to show 1 datapoint with the tooltip on download you can programaticatlly trigger the tooltip like so:
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: {}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
var chart = new Chart(ctx, options);
document.getElementById("triggger").addEventListener("click", () => {
const tooltip = chart.tooltip;
if (tooltip.getActiveElements().length > 0) {
tooltip.setActiveElements([], {
x: 0,
y: 0
});
} else {
const chartArea = chart.chartArea;
tooltip.setActiveElements([{
datasetIndex: 0,
index: 2,
}, {
datasetIndex: 1,
index: 2,
}]);
}
chart.update();
});
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<br>
<button id="triggger">
trigger hover
</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.0/chart.js" integrity="sha512-opXrgVcTHsEVdBUZqTPlW9S8+99hNbaHmXtAdXXc61OUU6gOII5ku/PzZFqexHXc3hnK8IrJKHo+T7O4GRIJcw==" crossorigin="anonymous"></script>
</body>
How do I make the last element in the data active, specifically July, in a js diagram?
example https://codepen.io/pichugin/pen/eYgdvBx
[https://codepen.io/pichugin/pen/eYgdvBx][1]
With the new upcomming release of version 3 you can do this with the setActive elements.
Documentation: https://www.chartjs.org/docs/master/developers/api/#setactiveelementsactiveelements
var options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
hoverBackgroundColor: 'green',
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1,
hoverBackgroundColor: 'red',
}
]
},
options: {
scales: {}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);
chart.setActiveElements([{
datasetIndex: 0,
index: 1,
}, {
datasetIndex: 1,
index: 1,
}]);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.0.0-beta.10/chart.js" integrity="sha512-7igYTuENB1pHNsZ/SyzMYrcJAmRCk084yVOsxNNCQAdX1wSYvCeBOgSOMC6wUdKMO76kCJNOpW4jY3UW5CoBnA==" crossorigin="anonymous"></script>
</body>
Thanks in advance guys :)
I want to display 2 doughnut charts side by side to compare stats from 2 different years. I want to have the same key and keep the data in the same <canvas>.
I dont want: 2 canvas, 1 chart in the canvas
<canvas id="chart1"></chart>
<canvas id="chart2"></chart>
I do want: 1 canvas, 2 charts in the canvas
<canvas id="chart1"></chart>
Here's some JS to add context, this data adds 1 chart.
var ctx = document.getElementById('chart1').getContext('2d');
var chart1 = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['1', '2', '3'],
datasets: [{
label: 'Pie',
data: [12, 9, 3],
backgroundColor: [
'rgb(0,51,10)',
'rgb(02,11,191)',
'rgb(98,18,08)'
],
borderWidth: 1
}]
},
options: {
cutoutPercentage: 75,
responsive: false
}
});
You can use 2 canvas on 1 page - see here:
<body>
<table border="1">
<tr>
<th>Chart1</th>
<th>Chart2</th>
</tr>
<tr>
<td>
<div style="width: 50%">
<canvas id="canvas1" height="450" width="600"></canvas>
</div>
</td>
<td>
<div style="width: 50%">
<canvas id="canvas2" height="450" width="600"></canvas>
</div>
</td>
</tr>
</table>
</body>
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: {
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var options2 = {
type: 'bar',
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: {
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var ctx = document.getElementById('canvas1').getContext('2d');
new Chart(ctx, options);
var ctx2 = document.getElementById('canvas2').getContext('2d');
new Chart(ctx2, options2);
fiddle