I am trying to draw a line chart with time x-axis. But chart is giving me this error. I want to print the time in a certain format 'hh:mm:ss' but looks like this format is causing some issue. When i send hardcoded labels the chart is drawn correctly.
Chart.min.js:14 Uncaught TypeError: Cannot read property 'call' of undefined
This is my call stack
This is my code
var timeFormat = 'h:mm:ss a';
function newDate(days) {
//return moment().add(days, 'd').toDate();
return moment().add(days, 'm').format(timeFormat);
}
function DrawTrendTempChart() {
var temp_data_trend = {
labels: [newDate(0), newDate(10), newDate(20), newDate(30), newDate(40), newDate(50), newDate(60)], // Date Objects,
datasets: [{
lineTension: 0,
label: 'Trend',
data: [1, 2, 3, 4, 5, 6, 7],
pointRadius: 2,
backgroundColor: ['transparent'],
borderColor: [OrangeRGB],
borderWidth: liveDataLineWidth,
//fill: false,
//borderDash: [5, 5],
}]
}
var temp_options_trend = {
scales: {
xAxes: [{
type: "time",
time: {
format: timeFormat,
tooltipFormat: timeFormat,
unit: 'minute',
unitStepSize: 20,
},
scaleLabel: {
display: true,
labelString: 'Date'
}
}, ],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'value'
},
ticks: {
autoSkip: false
}
}]
},
legend: { display: true },
tooltips: { enabled: true },
showTooltips: true,
responsive: true,
title: {
display: true,
text: "Trend Chart"
}
}
var ctx = document.getElementById("sensorDataTrend").getContext("2d");
myChart = new Chart(ctx, {
type: 'line',
data: temp_data_trend,
options: temp_options_trend
});
}
Related
I'm trying to get a stacked bar chart with two bars sharing a label next to each other on the x-axis but I'm having issues with getting the 2nd bar to display - currently it sits underneath the first bar (if you hide the 2021 value, you will see the 2022 bar will appear):
var barChartData = {
labels: ["January", "February"],
datasets: [{
data: [10, 20],
label: '2021',
backgroundColor: "#ffe100",
yAxisId: 'y-stacked',
}, {
data: [15, 30],
label: '2021 Total',
backgroundColor: "#ee0000",
yAxisId: 'y-stacked',
}, {
data: [6, 19],
label: '2022 YTD',
backgroundColor: "#555555",
}]
};
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title: {
display: true,
text: "Chart.js Bar Chart - Stacked"
},
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: false,
ticks: {
beginAtZero: true,
}
}, {
id: "y-stacked",
stacked: true,
display: false,
ticks: {
beginAtZero: true,
min: 0,
},
type: 'linear'
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.js"></script>
<div style="width: 100%">
<canvas id="canvas"></canvas>
</div>
Is there any way I can get the 2022 bar to show next to the 2021 bar?
I have tried adding another x-axis and changing the value of the x-axis stack to false but this just unstacks all three bars and sits them all next to each other
Turns out there is a stacked property you can use on the datasets and you don't need multiple axes
var barChartData = {
labels: ["January", "February"],
datasets: [{
data: [10, 20],
label: '2021',
backgroundColor: "#ffe100",
stack: 'stack 1',
}, {
data: [15, 30],
label: '2021 Total',
backgroundColor: "#ee0000",
stack: 'stack 1',
}, {
data: [6, 19],
label: '2022 YTD',
backgroundColor: "#555555",
stack: 'stack 2',
}]
};
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title: {
display: true,
text: "Chart.js Bar Chart - Stacked"
},
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true,
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.js"></script>
<div style="width: 100%">
<canvas id="canvas"></canvas>
</div>
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
I am using Chart.js to generate a horizontal stacked bar chart. The chart currently looks like this:
This chart shows the user after how many years they should restorate a specific component of a house. I am trying to change this to in which year the user should do the restoration. Adding the current year to the values results to the following:
This is pretty much what I need if I could set the starting value of the x-axis to the current year. I tried to do this setting the minimum value like this:
options: {
scales: {
xAxes: [{
ticks: {
min: 2017
},
...
Unfortunatly results in not displaying the datasets at all like this:
I tried all combinations with adding the current year and setting the minimum values but nothing results in a useful chart.
In the following you can see my current source code:
var mainChart_ctx = document.getElementById("main_chart").getContext("2d");
var mainChart_config = {
type: 'horizontalBar',
data: {
labels: ['Kellerdecke', 'Fenster', 'Außenwand', 'Erdberührter Boden', 'Dach'],
datasets: [{
label: 'Beginn ab heute',
backgroundColor: 'transparent',
data: [4, 21, 25, 25, 25],
borderColor: '#666',
borderWidth: 1
},
{
label: 'Sanierungsdauer',
backgroundColor: '#ffcc00',
data: [2, 5, 5, 5, 5],
borderColor: '#666',
borderWidth: 1
},
{
label: 'Mittlere Restlebensdauer',
backgroundColor: 'orange',
data: [39, 0, 38, 51, 37],
borderColor: '#666',
borderWidth: 1
},
{
label: 'Maximale Restlebensdauer',
backgroundColor: 'orangered',
data: [20, 0, 0, 0, 0],
borderColor: '#666',
borderWidth: 1
}
]
},
options: {
tooltips: {
enabled: true
},
legend: {
display: false
},
title: {
display: true,
text: 'Sanierungsfahrplan',
fontSize: 24
},
scales: {
xAxes: [{
ticks: {
min: 0 /* Todo: change to current year? */
},
stacked: true,
scaleLabel: {
display: true,
labelString: 'Jahre',
fontSize: 16
}
}],
yAxes: [{
ticks: {
stepSize: 10
},
stacked: false,
scaleLabel: {
display: true,
labelString: 'Bauteil',
fontSize: 16
},
}]
}
}
};
mainChart = new Chart(mainChart_ctx, mainChart_config)
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.bundle.min.js"></script>
<canvas id="main_chart"></canvas>
I was able to get a suitable result using a callback like this:
xAxes: [{
ticks: {
min: 0,
callback: function (value, index, values) {
return value + 2017;
}
},
...
]
I found that suggestedMin works well:
options: {
scales: {
xAxes: [{
display: true,
ticks: {
suggestedMin: 2017
}
}]
}
}
[UPDATE] The question seems to be solved (see comments). I will update the answer as soon as i am sure about it
I am trying to achieve a weather chart using chartjs library.
The chart will always have the weather date of the first day of the month and in addition to that one value in between (makes 24 values).
I want all "first day of the month" labels to be shown (with the corresponding gridline), the other data point in between should not be shown (or at least with no gridline).
The Problem now, somehow the last (12th) label is not gonna be shown and I have no idea why. The result looks like that:
My javascript code is that
var ctx = document.getElementById('canvas').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [
"01","","02","","03","","04", "","05","","06","","07","","08","","09","","10","","11", "","12",""
],
datasets: [{
label: 'Temperature [°C]',
data: [
1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6
],
borderColor: "rgb(0, 182, 206)",
pointRadius: 1,
backgroundColor: "rgba(0, 182, 206,0.4)"
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
legend:{
display:false // Suppress interactive legend
},
scales: {
xAxes: [{
scaleLabel: {
display: false,
labelString: 'Month'
} ,
afterTickToLabelConversion: function(data){
var xLabels = data.ticks;
xLabels.forEach(function (labels, i) {
if (xLabels[i].length == 0){
xLabels[i] = '';
}
});
},
ticks: {
//maxRotation: 0,
//minRotation: 0,
autoSkip: true,
maxTicksLimit: 12
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Temperature [°C]'
},
ticks: {
beginAtZero: true
}
}]
}
}
});
Do you have some ideas?
I am trying to align the generated time scale labels using Chart.js v2.2 with the centre of the bars of a bar chart. I have tried the offsetGridLines option but this seems to have no effect when using Xaxis scale type time.
Here is an example, maybe I have missed something:
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var barChartData = {
labels: ["2015-01-01", "2015-02-01", "2015-03-01", "2015-04-01", "2015-05-01", "2015-07-01"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [10, 4, 5, 7, 2, 3]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
}
,
scales: {
xAxes: [{
categoryPercentage: .5,
barPercentage: 1,
type: 'time',
scaleLabel: {
display: true,
labelString: 'Year-Month'
},
time: {
min: '2014-12-01' ,
max: '2015-12-01',
unit: 'month',
displayFormats: {
month: "MMM YY"
}
},
gridLines: {
offsetGridLines: false,
drawTicks: true,
display: true
},
stacked: true
}],
yAxes: [{
ticks: {
beginAtZero: true
},
stacked: true
}]
}
}
});
};
</script>
This fiddle may help to place the data label in the center of the bar
https://jsfiddle.net/tea8dhgy/
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
var barChartData = {
labels: ["2015-01-01", "2015-02-01", "2015-03-01", "2015-04-01", "2015-05-01", "2015-07-01"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [10, 4, 5, 7, 2, 3]
}]
};
var ctx = document.getElementById("canvas").getContext("2d");
new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
scales: {
xAxes: [{
categoryPercentage: .5,
barPercentage: 1,
type: 'time',
scaleLabel: {
display: true,
labelString: 'Year-Month'
},
time: {
// min: '2014-12-01' ,
// max: '2015-12-01',
unit: 'month',
displayFormats: {
month: "MMM YY"
}
},
gridLines: {
offsetGridLines: false,
drawTicks: true,
display: true
},
stacked: true
}],
yAxes: [{
ticks: {
beginAtZero: true
},
stacked: true
}]
},
animation: {
onComplete: function() {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(10, "bold", Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'center';
this.data.datasets.forEach(function(dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function(bar, index) {
//var data = dataset.data[index];
var data = dataset.data[index];
console.log(bar);
if (data > 0) {
ctx.fillText(data, bar._model.x, bar._model.base - (bar._model.base - bar._model.y) / 2 - 5);
}
});
});
}
}
}
});
I was able to get a working chart by removing the min and max values set.
Here is the JSFiddle
Was the following image the desired outcome?