ChartJS multichart graph not showing correctly legends - charts

Am trying to create bar graph with multiple plots using chartjs and the graph is generated successfully but one of the legend is not showing correctly.
Am using Chartjs 2.9.3 version.
One of the bar legendary is showing as circle instead of rectangle box. Kindly let me know if any workaround to get the correct legendary.
Bar graph show circle in the legendary
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [
{
label: 'Label1',
data: [3,4],
type: 'scatter',
backgroundColor: 'red',
pointStyle:'circle',
pointRadius:5
},
{
label: 'Label2',
data: [1,2],
type: 'scatter',
backgroundColor: 'blue',
pointStyle:'triangle',
pointRadius:5
},
{
backgroundColor: 'grey',
label: 'Label3',
data: [1,2],
borderWidth: 1,
type: 'bar'
}
]
},
options: {
responsive:false,
legend: {
labels : {
usePointStyle: true
}
},
title: {
display: true
},
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: '$/MWh'
}
}]
}
}
});

If the usePointstyle flag is set in the legend it defaults to the circle. In V2 this is not configurable for bar charts so you have 2 options
You can switch to a html legend and style that. Or you can update to chart.js version 3 where you can configure it for bar charts:
var options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'yellow'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
backgroundColor: 'pink',
pointStyle: 'rect'
}
]
},
options: {
plugins: {
legend: {
labels: {
usePointStyle: true
}
}
}
}
}
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.5.0/chart.js"></script>
</body>

Related

How can I draw a horizontal reference line in chart.js?

I want to draw a horizontal reference line at a particular value.
The data is of the format:
{
"Close": 15638.8,
"Date": "2022-06-21T10:00:00.000Z",
"High": 15707.25,
"Low": 15419.85,
"Open": 15455.95,
"Volume": 0,
"id": 36
}
This is what I have figured as of now. I am unsure how to use the refLines attribute.
var dataReqdFormat = {
labels: [],
datasets: [{
data: [],
label: "Nifty",
fill: true,
borderColor: (ctx) => {
const data = ctx.chart.data.datasets[ctx.datasetIndex].data;
return data[0] >= data[data.length - 1] ? 'red' : 'green'
}
}]
};
Any help is appreciated.
You can use the annotation plugin for this:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
}]
},
options: {
plugins: {
annotation: {
annotations: {
line: {
type: 'line',
yMin: 16,
yMax: 16,
borderWidth: 2,
borderColor: 'red'
}
}
}
}
}
}
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.8.0/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/1.4.0/chartjs-plugin-annotation.js"></script>
</body>

Chart.js specific label next to point

I'm trying to get chartjs to show a specific label next to each point, for example in this script it should display "TRALALA" in the label as well as mouse hover, but instead it shows the coordinates.
How to have the specific label instead ?
https://jsfiddle.net/z0eLygwx/
thanks
var valuedata = [{
x: 3,
y: 5
}];
var valuelabel = ['TRALALA'];
var chartData = {
labels: valuelabel,
datasets: [{
label: 'Distance',
borderColor: '#2196f3', // Add custom color border
backgroundColor: '#2196f3', // Add custom color background (Points and Fill)
data: valuedata,
pointRadius: 10,
pointHoverRadius: 12
}]
};
var myBarChart = new Chart(document.getElementById("myChart1"), {
type: 'scatter',
data: {
labels: valuelabel,
datasets: [{
label: 'Distance',
borderColor: '#2196f3', // Add custom color border
backgroundColor: '#2196f3', // Add custom color background (Points and Fill)
data: valuedata,
pointRadius: 10,
pointHoverRadius: 12
}]
},
options: {
legend: {
display: true
},
title: {
display: true,
text: 'Distance of JDPT kanji compared to the equivalent JLPT level'
},
scales: {
yAxes: [{
type: 'logarithmic',
display: true,
scaleLabel: {
display: true,
labelString: 'Count',
fontSize: 16
}
}],
xAxes: [{
type: 'linear',
position: 'bottom',
display: true,
scaleLabel: {
display: true,
labelString: 'Distance',
fontSize: 16
},
gridLines: {
display: true
}
}]
},
plugins: {
datalabels: {
color: '#d6621e',
align: 'right',
offset: 16,
font: {
weight: 'bold'
}
}
}
}
});
myBarChart.update();
Ok I got it with
formatter: function(value, context) {
context.chart.data.labels[context.dataIndex];
}
For example
var myBarChart = new Chart(document.getElementById("bar-chart"), {
type: 'line',
data: {
labels: ['a', 'b'],
datasets: [{
data: [10, 20]
}]
},
options: {
plugins: {
datalabels: {
formatter: function(value, context) {
return context.chart.data.labels[context.dataIndex];
}
}
}
}
});

Is there a way to specify the y-axis crossing point?

In the example below the y-axis crosses at 1, rather than 0. Is there a way to achieve this in echarts?
It seems to me, literally, you can't do this with basic bar chart because it will break the coordinate system and result will be anything but not a bar chart.
If you need only visual like on attached picture then you can hide xAxis and draw its surrogate with markLine but you will have the troubles with bar positioning (that will fix with stack and transparent bars, see below).
If you need real chart with responsive, zoomable and other opts then in the Echarts you can use custom series for build own chart type (see example).
Example how to make picture like attached:
var myChart = echarts.init(document.getElementById('main'));
var option = {
tooltip: {},
xAxis: {
data: ['Category-1', 'Category-2', 'Category-3', 'Category-4'],
show: true,
axisLine: {
show: true,
lineStyle: {
opacity: 0
}
},
axisTick: {
show: false,
}
},
yAxis: {
max: 4,
min: -1
},
series: [{
name: 'Series-1',
type: 'bar',
stack: 'group',
data: [1, 1, -3],
color: 'rgba(0,0,0, 0)',
}, {
name: 'Series-2',
type: 'bar',
stack: 'group',
data: [{
value: 1,
itemStyle: {
color: 'red'
}
}, {
value: 2,
itemStyle: {
color: 'green'
}
}, {
value: 1,
itemStyle: {
color: 'orange'
}
}],
markLine: {
symbol: "none",
data: [{
silent: false,
yAxis: 1,
lineStyle: {
color: "#000",
width: 1,
type: "solid"
}
}, ],
label: {
show: false,
}
},
}]
};
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.8.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>
P.S. If this not a secret, why you need it?

Vertical stacked bar chart with chart.js

Excellent and free library from chart.js. I'm transferring my charts from Google charts to chart.js, because I can use them offline and it seems more responsive to window's changes of size. Furthermore I realised that my viewers in China could not see my Google charts because Google services are blocked in China.
I've been reading the documentation regarding stacked vertical bar charts, but I can't figure out, how to make a chart like this. In all examples I saw for stacked bar charts, the number of items is the same for each bar.
Can I make only two vertical stacked datasets? It's because the right bar has more items than the left one. Or do I need n datasets, being n the number of items, of the bar which has more items?
Code
I want to group one dataset per (stacked) bar, but I can't.
var ctx = document.getElementById("barChart").getContext('2d');
var labels = ["standing costs", "running costs"];
var dataset = [
{
type: 'bar',
label: ["cost1", "cost2", "cost3", "cost4"],
data: [1, 2, 1, 3],
stack: "standing costs",
backgroundColor: [
'navy',
'blue',
'aqua',
'teal'
]
},
{
type: 'bar',
label: ["cost5", "cost6", "cost7", "cost8"],
data: [5, 1, 3, 0],
stack: "running costs",
backgroundColor: [
'green',
'lime',
'yellow',
'white'
]
}
];
var options = {
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
}
};
var content = {
type: 'bar',
data: {
labels: labels,
datasets: dataset
},
options
};
new Chart(ctx, content);
#import url("https://cdnjs.cloudflare.com/ajax/libs/colors/1.0/colors.min.css");
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.0/Chart.bundle.min.js"></script>
<canvas id="barChart"></canvas>
Quick Solution :
Vertical Stacked Bar Chart
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Standing costs', 'Running costs'], // responsible for how many bars are gonna show on the chart
// create 12 datasets, since we have 12 items
// data[0] = labels[0] (data for first bar - 'Standing costs') | data[1] = labels[1] (data for second bar - 'Running costs')
// put 0, if there is no data for the particular bar
datasets: [{
label: 'Washing and cleaning',
data: [0, 8],
backgroundColor: '#22aa99'
}, {
label: 'Traffic tickets',
data: [0, 2],
backgroundColor: '#994499'
}, {
label: 'Tolls',
data: [0, 1],
backgroundColor: '#316395'
}, {
label: 'Parking',
data: [5, 2],
backgroundColor: '#b82e2e'
}, {
label: 'Car tax',
data: [0, 1],
backgroundColor: '#66aa00'
}, {
label: 'Repairs and improvements',
data: [0, 2],
backgroundColor: '#dd4477'
}, {
label: 'Maintenance',
data: [6, 1],
backgroundColor: '#0099c6'
}, {
label: 'Inspection',
data: [0, 2],
backgroundColor: '#990099'
}, {
label: 'Loan interest',
data: [0, 3],
backgroundColor: '#109618'
}, {
label: 'Depreciation of the vehicle',
data: [0, 2],
backgroundColor: '#109618'
}, {
label: 'Fuel',
data: [0, 1],
backgroundColor: '#dc3912'
}, {
label: 'Insurance and Breakdown cover',
data: [4, 0],
backgroundColor: '#3366cc'
}]
},
options: {
responsive: false,
legend: {
position: 'right' // place legend on the right side of chart
},
scales: {
xAxes: [{
stacked: true // this should be set to make the bars stacked
}],
yAxes: [{
stacked: true // this also..
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx" width="700"></canvas>
apology for not giving explanation.
updated for v3
<div style="height: 500px">
<canvas id="chart_1" ></canvas>
</div>
<script>
chart = new Chart(document.getElementById('chart_1').getContext('2d'), {
type: 'bar',
data: {
labels: ["One", "Two", "Three"],
datasets: [{
label: 'Blue',
data: [100, 110, 120],
backgroundColor: 'blue',
},
{
label: 'Red',
data: [30, 20, 10],
backgroundColor: 'red',
},
]
},
options: {
plugins: {
title: {
display: true,
text: 'Example',
font: {
size: 14
}
},
},
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
});
</script>

Chart.js place both series on same scale

So I have a chart.js chart with two series. One is a bar chart and the other is a line graph.
S1 = 71,166,2,6,8
S2 = 6,2,4,8,5
When I plot them, they both appear on their own scales which makes the bar and line graphs kinda pointless.
I need a way to plot both charts on the same scale.
Is there a way to do this within chart.js? If not, how would you do it?
thanks.
var barChartData = {
labels: dataLabels,
datasets: [{
type: 'bar',
label: "Actual",
data: dataActual,
fill: false,
backgroundColor: '#71B37C',
borderColor: '#71B37C',
hoverBackgroundColor: '#71B37C',
hoverBorderColor: '#71B37C',
yAxisID: 'y-axis-2'
}, {
label: "Maximum",
type:'line',
data: dataMaximum,
fill: false,
borderColor: '#EC932F',
backgroundColor: '#EC932F',
pointBorderColor: '#EC932F',
pointBackgroundColor: '#EC932F',
pointHoverBackgroundColor: '#EC932F',
pointHoverBorderColor: '#EC932F',
yAxisID: 'y-axis-1'
} ]
};
$(function () {
if (theChart !== undefined) {
theChart.destroy();
}
var ctxActualVsMax = document.getElementById("myChart2").getContext("2d");
theChart = new Chart(ctxActualVsMax, {
type: 'bar',
data: barChartData,
options: {
responsive: true,
tooltips: {
mode: 'label'
},
elements: {
line: {
fill: false
}
},
scales: {
xAxes: [{
display: true,
gridLines: {
display: false
},
labels: {
show: true,
}
}],
yAxes: [{
type: "linear",
display: true,
position: "left",
id: "y-axis-1",
gridLines:{
display: false
},
labels: {
show:true,
}
}, {
type: "linear",
display: false,
position: "right",
id: "y-axis-2",
gridLines:{
display: false
},
labels: {
show:true,
}
}]
}
}
});
});
In your code you have specified your two datasets to use different yAxisId's. Just set them both to the same, you can also remove the unused yAxes object from the options
fiddle