Multiple charts in one page with chart.js - javascript

I use chart.js and its dependency, jQuery to draw chart. In my case, I need 2 doughnut charts in one of my page, here's my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.js"></script>
<title>Document</title>
<script>
$(function () {
var ctx = document.getElementById("layanan").getContext('2d');
var data = {
datasets: [{
data: [10, 20, 30],
backgroundColor: [
'#3c8dbc',
'#f56954',
'#f39c12',
],
}],
labels: [
'Request',
'Layanan',
'Problem'
]
};
var myDoughnutChart = new Chart(ctx, {
type: 'doughnut',
data: data,
options: {
maintainAspectRatio: false,
legend: {
position: 'bottom',
labels: {
boxWidth: 12
}
}
}
});
var ctx_2 = document.getElementById("layanan_subbagian").getContext('2d');
var data_2 = {
datasets: [{
data: [10, 20, 30],
backgroundColor: [
'#3c8dbc',
'#f56954',
'#f39c12',
],
}],
labels: [
'Request',
'Layanan',
'Problem'
]
};
var myDoughnutChart_2 = new Chart(ctx_2, {
type: 'doughnut',
data: data_2,
options: {
maintainAspectRatio: false,
legend: {
position: 'bottom',
labels: {
boxWidth: 12
}
}
}
});
});
</script>
</head>
<body>
<canvas id="layanan" width="240" height="240"></canvas>
<canvas id="layanan_subbagian" width="240" height="240"></canvas>
</body>
</html>
When I only have one chart, nothing's gone wrong, but when I try to add one more chart, my charts become so large and my page layout becomes so messy. Can you guys figure out what's wrong with my code? Thanks.

As per chartjs documentation:
Detecting when the canvas size changes can not be done directly from
the CANVAS element. Chart.js uses its parent container to update the
canvas render and display sizes. However, this method requires the
container to be relatively positioned and dedicated to the chart
canvas only. Responsiveness can then be achieved by setting relative
values for the container size
Source: https://www.chartjs.org/docs/latest/general/responsive.html
You should wrap your canvas into div and add width,height into it.
Here is the change I did
<div style="width:240px;height:240px">
<canvas id="layanan"></canvas>
</div>
<div style="width:240px;height:240px">
<canvas id="layanan_subbagian" ></canvas>
</div>
$(function () {
var ctx = document.getElementById("layanan").getContext('2d');
var data = {
datasets: [{
data: [10, 20, 30],
backgroundColor: [
'#3c8dbc',
'#f56954',
'#f39c12',
],
}],
labels: [
'Request',
'Layanan',
'Problem'
]
};
var myDoughnutChart = new Chart(ctx, {
type: 'doughnut',
data: data,
options: {
maintainAspectRatio: false,
legend: {
position: 'bottom',
labels: {
boxWidth: 12
}
}
}
});
var ctx_2 = document.getElementById("layanan_subbagian").getContext('2d');
var data_2 = {
datasets: [{
data: [10, 20, 30],
backgroundColor: [
'#3c8dbc',
'#f56954',
'#f39c12',
],
}],
labels: [
'Request',
'Layanan',
'Problem'
]
};
var myDoughnutChart_2 = new Chart(ctx_2, {
type: 'doughnut',
data: data_2,
options: {
maintainAspectRatio: false,
legend: {
position: 'bottom',
labels: {
boxWidth: 12
}
}
}
});
});
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.js"></script>
<title>Document</title>
<div style="width:240px;height:240px">
<canvas id="layanan"></canvas>
</div>
<div style="width:240px;height:240px">
<canvas id="layanan_subbagian" ></canvas>
</div>

Try to add
options: {
responsive: false
}

I found two solutions:
You have to put the charts in a container such as a div. <canvas> is an element semantically dedicated for drawing graphics dynamically via scripting. <div> is a general-purpose container. The important point is: width and height properties are not the size in px but the ratio between them. <canvas id="layanan" width="240px" height="240px"></canvas> would result into a 1:1 ratio, but you need a parent container to work with. In the example below, I put a div around each canvas.
You can disable this feature by setting maintainAspectRatio to false. Removing the divs from my code and setting this into yours gives the same result :)
Cheers!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.js"></script>
<title>Document</title>
<script>
$(function () {
var ctx = document.getElementById("layanan").getContext('2d');
var data = {
datasets: [{
data: [10, 20, 30],
backgroundColor: [
'#3c8dbc',
'#f56954',
'#f39c12',
],
}],
labels: [
'Request',
'Layanan',
'Problem'
]
};
var myDoughnutChart = new Chart(ctx, {
type: 'doughnut',
data: data,
options: {
responsive: false,
maintainAspectRatio: false,
legend: {
position: 'bottom',
labels: {
boxWidth: 12
}
}
}
});
var ctx_2 = document.getElementById("layanan_subbagian").getContext('2d');
var data_2 = {
datasets: [{
data: [10, 20, 30],
backgroundColor: [
'#3c8dbc',
'#f56954',
'#f39c12',
],
}],
labels: [
'Request',
'Layanan',
'Problem'
]
};
var myDoughnutChart_2 = new Chart(ctx_2, {
type: 'doughnut',
data: data_2,
options: {
responsive: false,
maintainAspectRatio: false,
legend: {
position: 'bottom',
labels: {
boxWidth: 12
}
}
}
});
});
</script>
</head>
<body>
<div>
<canvas id="layanan" width="240px" height="240px"></canvas>
</div>
<div>
<canvas id="layanan_subbagian" width="240px" height="240px"></canvas>
</div>
</body>
</html>

Related

Having trouble returning to the initial dataset with chartjs-plugin-crosshair on reset zoom

Did anyone have the chance to work with the chartjs plugin - chartjs-plugin-crosshair? I'm having trouble after having zoomed in the datasets several times and when clicking the 'reset zoom' button I can only zoom out the last zoom in action, but I would like to return to the initial dataset before having initialized the zoom in action. Does anyone know how to tackle this problem?
Below is the code in jsfiddle:
https://jsfiddle.net/u0594jed/
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<link rel="stylesheet" href="">
<script src=https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js></script>
<script src=https://cdn.jsdelivr.net/npm/chartjs-plugin-crosshair#1.2.0></script>
</head>
<body>
<canvas id="myChart" width="400" height="400"></canvas>
<script type="text/javascript">
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['a','b','c','d','e','f','g','h','i','a','b','c','d','a', 'c','d', 'a'],
datasets: [{
label: '# of Votes',
data: [100,200,400,321,345,1234,456,5675,345,456,678,79,456,345,234,34,345],
backgroundColor: [
'rgba(255, 99, 132, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
},
plugins: {
tooltip: {
mode: 'interpolate',
intersect: false
},
crosshair: {
line: {
color: '#F66', // crosshair line color
width: 1 // crosshair line width
},
sync: {
enabled: true, // enable trace line syncing with other charts
group: 1, // chart group
suppressTooltips: false // suppress tooltips when showing a synced tracer
},
zoom: {
enabled: true, // enable zooming
zoomboxBackgroundColor: 'rgba(66,133,244,0.2)', // background color of zoom box
zoomboxBorderColor: '#48F', // border color of zoom box
zoomButtonText: 'Reset Zoom', // reset zoom button text
zoomButtonClass: 'reset-zoom', // reset zoom button class
},
callbacks: {
beforeZoom: () => function(start, end) { // called before zoom, return false to prevent zoom
return true;
},
afterZoom: () => function(start, end) {
// called after zoom
}
}
}
}
}
});
</script>
</body>
</html>
colleague:). Had the same problem... Found the answer into crosshair plugin src file: chartjs-plugin-crosshair.esm.js (line 477)
var filterDataset = (chart.config.options.scales.x.type !== 'category');
It means that you need to use another type of scale. I used type "time" - and voila, zoom fixed. Sample of code here

Using Plotly JS UpdateMenu Animate Method Dropdown to Animate Between Traces

I am trying to animate a plotly chart using the UpdateMenu's animate method.
I can't get it to animate back to the original trace.
In the example below, I can change the chart to trace 2. But it does not go back to trace 1.
Here is a code example of my problem
//myPlot = document.getElementById('chart')
var trace1 = {
x: [1],
y: [1],
type: 'scatter',
mode: 'markers',
name: 'Trace 1',
}
var trace2 = {
x: [.5],
y: [.5],
type: 'scatter',
mode: 'markers',
name: 'Trace 2',
}
var frames = [{
name: 'trace 1',
data: [trace1]
},
{
name: 'trace 2',
data: [trace2]
}
]
console.log(frames)
var layout = {
yaxis: {
range: [0, 2]
},
xaxis: {
range: [0, 2]
},
updatemenus: [{
buttons: [{
method: 'animate',
args: [
['trace 1']
],
label: 'One'
},
{
method: 'animate',
args: [
['trace 2']
],
label: 'Two'
}
]
}]
}
Plotly.newPlot("chart", [trace1], layout).then(function() {
Plotly.addFrames('chart', frames);
});
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Media Bias</title>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- <link rel="stylesheet" type="text/css" href="static/css/Index_Style.css">
-->
</head>
<div Id='chart'>
</div>
and a modified code example of their working sample.
In the working sample, you can change between the three traces using the drop down.
For some reason you can't put the trace in the list for data (inside the frames variable). You need to set the data x and y values manually.
//myPlot = document.getElementById('chart')
var trace1 = {
x: [1],
y: [1],
type: 'scatter',
mode: 'markers',
name: 'Trace 1',
}
var trace2 = {
x: [.5],
y: [.5],
type: 'scatter',
mode: 'markers',
name: 'Trace 2',
}
var frames = [{
name: 'trace 1',
data: [{
x: trace1.x,
y: trace1.y
}]
},
{
name: 'trace 2',
data: [{
x: trace2.x,
y: trace2.y
}]
}
]
//console.log(frames)
var layout = {
yaxis: {
range: [0, 2]
},
xaxis: {
range: [0, 2]
},
updatemenus: [{
buttons: [{
method: 'animate',
args: [
['trace 1']
],
label: 'One'
},
{
method: 'animate',
args: [
['trace 2']
],
label: 'Two'
}
]
}]
}
Plotly.newPlot("chart", [trace1], layout).then(function() {
Plotly.addFrames('chart', frames);
});
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Media Bias</title>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- <link rel="stylesheet" type="text/css" href="static/css/Index_Style.css">
-->
</head>
<div Id='chart'>
</div>

How do I outline the bars of my barchart with a thick black outline?

I am new to coding and am trying to make a barchart with eCharts. I have made a simple bar chart example but now I want to make a thick outline for the bars on the chart. This is my code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.3.0/echarts-en.min.js"></script>
</head>
<body>
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// based on prepared DOM, initialize echarts instance
var myChart = echarts.init(document.getElementById('main'));
// specify chart configuration item and data
var option = {
title: {
text: 'ECharts entry example'
},
tooltip: {},
legend: {
data:['Sales']
},
xAxis: {
data: ["shirt","cardign","chiffon shirt","pants","heels","socks"]
},
yAxis: {},
series: [{
name: 'Sales',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
}]
};
// use configuration item and data specified to show chart
myChart.setOption(option);
</script>
</body>
</html>
How do I add a thick black outline on the bars?
You can use the option barBorderColor and barBorderWidth to set the color and width of the border respectively for each bar.
Below is an example based on your existing code.
var myChart = echarts.init(document.getElementById('main'));
// specify chart configuration item and data
var option = {
title: {
text: 'ECharts entry example'
},
tooltip: {},
legend: {
data: ['Sales']
},
xAxis: {
data: ["shirt", "cardign", "chiffon shirt", "pants", "heels", "socks"]
},
yAxis: {},
series: [{
name: 'Sales',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
//Added item style
itemStyle: {
normal: {
barBorderWidth: 5,
barBorderColor: "#000"
}
}
}]
};
// use configuration item and data specified to show chart
myChart.setOption(option);
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.3.0/echarts-en.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>

Chart.js tooltip not showing on line chart

I'm at a loss as to why my chart's tooltips aren't displaying... can anybody show me what I'm doing wrong?
The tooltips work fine if I set the chart type to "bar" but for some reason don't work with "line". I'm relatively new to chart.js and am probably making some basic newbie mistake?
Here's my current code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.min.js"></script>
</head>
<body onLoad="ready()">
<canvas id="myChart" width="250" height="150"></canvas>
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels:[],
datasets: [{
label: 'Applicants',
data: [],//start empty
backgroundColor: [
'rgba(10, 168, 196, 0.2)'
],
borderColor: [
'rgba(10, 168, 196, 1)'
],
}]
},
options: {
tooltips: {
enabled: true
},
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
// time: {
// unit: 'day'
// }
}],
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
onClick: handleClick
}
});
window.onmessage = function(event){
myChart.data.datasets[0].data = event.data.data;
myChart.data.labels = event.data.labels;
myChart.update();
};
function handleClick(e){
var activeBars = myChart.getElementAtEvent(e);
var value = myChart.config.data.datasets[activeBars[0]._datasetIndex].data[activeBars[0]._index];
var label = activeBars[0]._model.label;
window.parent.postMessage({
"type":"click",
"label":label,
"value":value
} , "*");
}
function ready(){
window.parent.postMessage({"type":"ready"}, "*");
}
</script>
</body>
</html>
For anyone having problems with this using Chartjs v3, you need to make sure you have registered the Tooltip plugin:
import { Chart, Tooltip } from 'chart.js'
Chart.register([Tooltip])

How can I express this element?

Hello I have this code using javascript and chart.js :
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id = "Global">
<div id = "gauche">
<canvas id="line-chart" width="800" height="450"></canvas>
<script>
var ctx = document.getElementById("line-chart").getContext('2d');
var config = {
type: 'line',
data: {
datasets: [{
data: [{'y': 426777.148122,'x': 18.123},
{'y': 258927.721326,'x': 46.8603108462},
{'y': 5419.37148146,'x': 1110.14081215},
{'y': 5136.33830766,'x': 1138.878123}],
label: "Model",
borderColor: "#3e95cd",
fill: false
}, {
label : 'Data',
fill:false,
showLine: false,
backgroundColor: "#FF0000",
data : [{x: 17.0, y: 454995.091169},
{x: 1137.0, y: 3369.7047454},
{x: 1138.0, y: 3539.605825},
{x: 1140.0, y: 4927.1313084}],
type: 'line'
}]
},
options: {
title:{
display: true,
text:"Graph"
},
scales: {
xAxes: [{
type: 'logarithmic',
position: 'bottom'
}],
yAxes: [{
type: 'logarithmic'
}]
}
}
};
var forecast_chart = new Chart(ctx, config);
alert(data.datasets[0].data);
</script>
But when I type this : alert(data.datasets[0].data); I get nothing... basically I just want to express this 426777.148122 which is part of the data but I don't know how to do it, I thought to write this data.datasets[0].data but it does not work...
Any ideas ?
Thank you very much !
Try:
alert(JSON.stringify(config.data.datasets[0].data[0]));
You will need JSON.stringify because config.data.datasets[0].data is also an array of objects
or
alert(config.data.datasets[0].data[0].x);
To get the X value of the first entry of config.data.datasets[0].data

Categories

Resources