I am trying to load annotation the dynamic chart that I create after receiving data from the database and I have tried all possible options but somehow the chart loads but no the annotations.
chart.js version = v2.9.4
chart-plugin-annotation.min.js version = 0.5.7
Function in JS that runs when data is receiving from db:
function DrawChart(timeLabelList, unitsProducedList, goalList){
if(draw_the_chart != null) draw_the_chart.destroy();
Chart.defaults.global.defaultFontColor = 'white';
var ctx = document.getElementById('draw_the_chart').getContext("2d");
draw_the_chart = new Chart(ctx, {
type: 'line',
//plugins: [ChartAnnotation],
data: {
labels: timeLabelList,
datasets: [
{
label: 'Goal',
yAxisID: 'A',
data: goalList,
//backgroundColor: chartColumnColorBlueSolid,
borderColor: chartColumnColorGreenSolid,
borderWidth: 2,
pointStyle: 'star'
}]
},
options: {
annotation: {
annotations: [
{
id: "a-line-1",
type: "line",
mode: "vertical",
scaleID: "y-axis-0",
value: "1",
borderColor: "red",
borderWidth: 2
}
]
},
legend: {
position: 'bottom',
display: true,
},
elements: {
line: {
tension: 0
}
},
scales: {
xAxes: [{
stacked: true,
type: 'time',
time: {
unit: 'hour'
},
}],
yAxes: [{
stacked: false,
id: 'A',
type: 'linear',
position: 'right',
}]
},
}
});
}
I tried all possible ways to register and also different ways to used the plugin but had no luck plotting it. I even used latest CDN versions but had no luck.
Can anyone help with it.
Thanks!
Related
Just a warning: I am new to chart.js!
I have a couple of horizontal bar charts and it works fine except one issue that I cannot shake off. I have 5 labels in y-axis but the legend on top of the graph only shows one small rectangle in the color of the first (topmost) bar and even that does not display the label itself, followed by list of labels. I thought it would display each label next to small bar same color as in chart.
Unfortunately, this is an intranet app and I cannot provide a link but here is what I have (data is passed to this function from an ajax call):
function drawRespChart(chartLabels, chartData) {
var ctx = $("#rtChart");
console.log("Labels Array: " + chartLabels);
console.log("Data Array: " + chartData);
if (chartRespTime)
chartRespTime.destroy();
var chart = {
labels: chartLabels,
datasets: [
{
label: chartLabels,
backgroundColor: ["#c45850", "#e8c3b9", "#3cba9f", "#8e5ea2", "#3e95cd"],
data: chartData
}
]
};
chartRespTime = new Chart(ctx, {
type: 'horizontalBar',
data: chart,
datalabels: {
anchor: 'end',
align: 'start',
},
options: {
title: {
display: true,
text: 'IDC Database Response Time (mili-seconds)'
},
legend: {
display: true,
labels: {
fontColor: 'rgb(255, 99, 132)'
}
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Count'
},
ticks: {
major: {
fontStyle: 'bold',
fontColor: '#FF0000'
}
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Response Time (ms)'
}
}]
},
plugins: {
datalabels: {
color: 'white',
display: function (context) {
return context.dataset.data[context.dataIndex] > 15;
},
font: {
weight: 'bold'
},
formatter: Math.round
}
},
maintainAspectRatio: true,
responsive: true,
showInlineValues: true,
centeredInllineValues: true,
tooltipCaretSize: 0
}
});
}
This is what I see in console window:
Labels Array: 0-350,350-700,700-1000,1000-1500
Data Array: 5065,32,27,3
What I see as legend is one rectangle, same color as first bar, followed by list of labels.
It seems that charts.js labels only works when you split the datasets.
Leaving an example.
https://jsfiddle.net/code4mk/1j62ey38/
datasets: [ {
label: 'Result',
fill:false,
data: aDatasets1,
backgroundColor: '#E91E63',
},
{
label: 'Result2',
fill:false,
data: aDatasets2,
backgroundColor: '#E91E93',
}];
As seen on image below, how can i stop the gridlines from crossing the y-axis? I think it looks cleaner that way.
Set options.scales.yAxes[0].gridLines.drawTicks to false and and some padding in gridLines.ticks.padding:
{
type: 'bar',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [{
label: 'Users',
data: [50, 60, 70, 180]
}]
},
options: {
scales: {
yAxes: [{
gridLines: {
drawTicks: false,
},
ticks: {
padding: 8,
}
}]
}
}
}
How do I create legends like the following:
So far I have the following:
I can't figure out how to specify labels for the legend. They don't provide examples either.
https://www.chartjs.org/docs/latest/configuration/legend.html
So far I have the following code:
var topClickSourcesChart = new Chart('dashboard-click-source-chart', {
type: 'bar',
data: {
labels: ["Facebook","Google","NONE",],
datasets: [{
data: [10,5,3,],
backgroundColor: ['#4D90C3', '#866DB2', '#EA6F98', '#61BDF6', '#768BB7'],
}],
},
options: {
scales: {
xAxes: [{
display: false,
}]
},
legend: {
position: 'right',
labels: {
boxWidth: 10,
}
}
}
});
To show a legend you need to set the label property of a dataset, so the type of output you are expecting can be built by creating a chart from the code as shown below. Fiddle -> https://jsfiddle.net/6nkcx8sq/
var topClickSourcesChart = new Chart('dashboard-click-source-chart', {
type: 'bar',
data: {
labels: ["Number of users"],
datasets: [{
label: 'Facebook',
data: [10],
backgroundColor: '#4D90C3',
},
{
label: 'Instagram',
data: [15],
backgroundColor: '#866DB2',
},
{
label: 'Twitter',
data: [7],
backgroundColor: '#EA6F98',
}],
},
options: {
scales: {
xAxes: [{
display: false,
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
legend: {
position: 'right',
labels: {
boxWidth: 10,
}
}
}
});
I was able to get it with the following, but it was a pain in the ass for loops due to the backgroundColor having to be inside the dataset.
var topClickSourceChart = new Chart('dashboard-click-source-chart', {
type: 'bar',
data: {
labels: ["Facebook","Google","NONE",],
datasets: [
{label: "Facebook", data: [10]},{label: "Google", data: [5]},{label: "NONE", data: [3]},
]
},
options: {
scales: {
xAxes: [{
display: false,
}],
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
legend: {
position: 'right',
labels: {
boxWidth: 10,
}
}
}
});
if (topClickSourceChart.data.datasets.length > 0) topClickSourceChart.data.datasets[0].backgroundColor = '#4D90C3';
if (topClickSourceChart.data.datasets.length > 1) topClickSourceChart.data.datasets[1].backgroundColor = '#866DB2';
if (topClickSourceChart.data.datasets.length > 2) topClickSourceChart.data.datasets[2].backgroundColor = '#EA6F98';
if (topClickSourceChart.data.datasets.length > 3) topClickSourceChart.data.datasets[3].backgroundColor = '#61BDF6';
if (topClickSourceChart.data.datasets.length > 4) topClickSourceChart.data.datasets[4].backgroundColor = '#768BB7';
Here is the JSP/JSTL loop:
data: {
labels: [<c:forEach items="${clickSources}" var="cs">"${cs.key}",</c:forEach>],
datasets: [
<c:forEach items="${clickSources}" var="cs">{label: "${cs.key}", data: [${cs.value}]},</c:forEach>
]
},
I still could not find a way to make the top of the bars rounded.
I'm currently working with ChartJS.
It works fine on Firefox and Chrome.
On Safari there is horizontal lines which appear. (here there is one good on orange and two others unwanted )
I have a lot of datapoint (2 lines of 1600 data point). I don't know if it could be a cause.
My code is here.
In some other part, I update time uni and time min.
_displayChart: function(label1, label2){
var timeFormat = 'DD/MM/YYYY HH:mm';
var ctx = document.getElementById(this.heading).getContext('2d');
const data = {
// Labels should be Date objects
//labels:this._stats[1],
datasets: [{
fill: false,
label: label1,
data: this._stats[2],
borderColor: '#fe8b36',
pointRadius: 0,
backgroundColor: [
'#fe8b36'
]
},{
label: label2,
fill: false,
data: this._stats[3],
borderWidth: 1,
pointRadius: 0,
borderColor: 'rgba(99, 100, 200, 1)',
backgroundColor: [
'rgba(99, 100, 200, 0.2)'
]
}]
}
const options = {
type: 'line',
data: data,
options: {
responsive: false,
fill: false,
responsive: true,
maintainAspectRatio:!this._isMobile(),
max: this.max,
hover: {
// Overrides the global setting
mode: 'index'
},
annotation: {
drawTime: 'beforeDatasetsDraw',
events: ['click'],
annotations: []
},
legend: {
labels: {
filter: function(legendItem, chartData) {
if(legendItem.datasetIndex == 2 || legendItem.datasetIndex == 3 ){
return false;
}
return true;
}
}
},
tooltips: {
mode:'index',
intersect : false,
callbacks: {
title: function(tooltipItems, data) {
return tooltipItems[0].xLabel.format(timeFormat);
},
label: function(tooltipItems, data) {
return tooltipItems.yLabel+'%';
}
}
},
scales: {
xAxes: [{
type: 'time',
display: true,
time:{
unit:'day',
min:moment(Date.now()-this.monthTs),
max:this._stats[1][this._stats[1].length]
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
},
display: true
}]
}
}
}
this._chart = new Chart(ctx, options);
},
When I'm applying this, I have no problem:
this._chart.options.scales.xAxes[0].time.unit = 'month';
this._chart.options.scales.xAxes[0].time.stepSize = 1;
this._chart.options.scales.xAxes[0].time.min = this._stats[1][0];
this._chart.options.scales.xAxes[0].time.max = this._stats[1][this._stats[1].length-1];
Thanks
When running the below code without the scales and yAxisID values, it renders a 2 line chart with both lines on the same axis.
UPDATE: When only removing the yAxisID values from the code it runs as before without errors - although still with only a single y axis.
When adding these elements in order to get a split axis, it returns the js error cannot read property 'min' of undefined and the canvas is blank.
Not sure if his should make a difference, but data is a json object returned through an ajax request by way of a vue.js method.
Here is an example of how the data.sales variable looks in the browser console:
sales: (187) [0, 0, 43.2874, 10.276, ..., 23.834]
var ctx = document.getElementById("chart_canvas").getContext('2d')
var basic_line = new Chart(ctx, {
type: 'line',
data: {
labels: data.labels,
datasets: [{
label: 'Price',
yAxisID: 'B',
fill: false,
borderColor: ["#668cff"],
data: data.price
}, {
label: 'Sales',
yAxisID: 'A',
fill: false,
borderColor: ["grey"],
data: data.sales
}],
options: {
scales: {
yAxes: [{
id: 'A',
position: 'left',
type: 'linear'
}, {
id: 'B',
position: 'right',
type: 'linear'
}]
},
responsive: true,
maintainAspectRatio: false
}
}
})
The issue is merely occurring due to the fact that, you have placed the options object/property, inside the data property, while it should be outside.
Here is the revised version of your code :
var ctx = document.getElementById("chart_canvas").getContext('2d')
var basic_line = new Chart(ctx, {
type: 'line',
data: {
labels: data.labels,
datasets: [{
label: 'Price',
yAxisID: 'B',
fill: false,
borderColor: ["#668cff"],
data: data.price
}, {
label: 'Sales',
yAxisID: 'A',
fill: false,
borderColor: ["grey"],
data: data.sales
}]
},
options: {
scales: {
yAxes: [{
id: 'A',
position: 'left',
type: 'linear'
}, {
id: 'B',
position: 'right',
type: 'linear'
}]
},
responsive: true,
maintainAspectRatio: false
}
});