How to display specific time label in x-axis by Chart.js? - javascript

I am collecting the data of temperature and relative humidity everyday. I wanted to display these data with Chart.js and currently it is possible to show all my data. But I wonder how to display specific time label in x-axis by Chart.js?
As you can see, the x-axis is too "crowded" with the time label. I searched Chart.js documentation and tried to add autoskip and autoskippadding but it failed to show the targeted time label.
xAxes: [{
ticks: {
autoSkip: true,
autoSkipPadding: 60
}
}]
Hence, as these data were collected every minute and the size of data is so huge, how can I to display specific time label in x-axis only (00:00, 01:00, 02:00... and so on) so that to prevent too "crowded"? Any suggestions are highly appreciated, thank you!

You can define the x-axis as a time cartesian axis as follows:
scales: {
x: {
type: 'time',
time: {
parser: 'HH:mm:ss',
unit: 'hour',
displayFormats: {
hour: 'HH:mm'
},
tooltipFormat: 'D MMM YYYY - HH:mm:ss'
}
}
}
Please take a look at your amended code below and see how it works. This code now uses the chartjs-adapter-moment together with moment. Feel free to use a different adapter.
$(function() {
getXlsxData();
});
function getXlsxData() {
var xlsxUrl =
"https://script.google.com/macros/s/AKfycbw9PQRojIml3x5gnMMiKihnTh9aLODd86ankhoz0ETIu0a8tcVh1ZIc4R08hlw8nHF8pA/exec?id=1Bvzqyu_NvPdL-zsOShbKF5me2bjtVVWQCK9MDA2KW58&sheet=Today"
var xlsxData = $.getJSON(xlsxUrl, function(data) {
$.each(data.Today, function(i, el) {
labels.push(el.Time);
TodayTemperature.push(el.CurrentTemp);
TodayRH.push(el.CurrentRH);
});
load_chart();
});
}
var labels = [],
TodayTemperature = [],
TodayRH = []
function load_chart() {
var myChart = new Chart('alldata', {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Temperature(°C)',
fill: false,
data: TodayTemperature,
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132, 0.8)',
borderWidth: 1,
radius: 0,
}, {
label: 'Relative Humidity (%)',
fill: false,
data: TodayRH,
backgroundColor: 'rgb(255, 159, 64)',
borderColor: 'rgb(255, 159, 64, 0.8)',
hidden: true,
borderWidth: 1,
radius: 0,
}, ]
},
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
position: 'bottom',
},
layout: {
padding: {
top: 35,
right: 15,
}
},
scales: {
x: {
type: 'time',
time: {
parser: 'HH:mm:ss',
unit: 'hour',
displayFormats: {
hour: 'HH:mm'
},
tooltipFormat: 'D MMM YYYY - HH:mm:ss'
}
}
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#1.0.0"></script>
<canvas id="alldata" height="200"></canvas>

Related

How to set vertical lines for new day on x-axis in ChartJS v3.x

I have a graph that displays data of the last 2h, 8h, 24h, or 48h. This can be changed via buttons on the webpage. When the timespan includes midnight, I would like to display vertical lines with little labels (maybe at hover) at midnight displaying the date (or day of the week) of the upcoming day.
I have not found any resources on how to do that in Chartjs 3. How would I do such a task?
This is how I create the graph. "time" is an array of epoch times:
chart = new Chart(
document.getElementById('Chart'),
{
type: 'line',
data:
{
labels: time,
datasets: [
{
label: dataObjects[start].label,
backgroundColor: dataObjects[start].backgroundColor,
borderColor: dataObjects[start].borderColor,
fill: dataObjects[start].fill,
data: dataObjects[start].data,
yAxisID: 'A',
}]
},
options: {
elements: {point: {radius: 0.5, borderWidth: 1},
line: {borderWidth: 3}},
maintainAspectRatio: false,
scales: {
x:
{
//max: last_time,
type: "time",
grid: {borderColor: color.time},
ticks: {color: color.time},
time: {
unit: 'hour',
tooltipFormat: 'dd.MM. HH:mm',
displayFormats: {
second: "HH:mm",
minute: "HH:mm",
hour: "HH:mm",
day: "d.MM.",
week: "d.MM."
},
}
},
A:
{
type: 'linear',
grid: {borderColor: color.time},
position: 'left',
ticks: {color: color.time},
suggestedMin: dataObjects[start].suggestedMin,
suggestedMax: dataObjects[start].suggestedMax,
title: {text: dataObjects[start].text,
display: true,
color: color.time}
}
},
plugins: {
legend: {display: false}
}
}
});
You could use the annotation plugin. In your case you will need to change the string I used to determine the correct x axis placement to the timestamp of the midnight you want and then you have a line there:
const 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: {
line1: {
type: 'line',
xMin: 'Green',
xMax: 'Green',
label: {
enabled: true,
content: 'end value'
}
},
line2: {
type: 'line',
xMin: 'Blue',
xMax: 'Blue',
label: {
enabled: true,
content: 'begin value'
}
}
}
}
}
}
}
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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/1.3.1/chartjs-plugin-annotation.min.js"></script>
</body>
You can use a mixed chart to create this graph mixing a line chart and a bar chart.
Here you can view one example:
https://codepen.io/alyf-mendonca/pen/dyZZoeB
HTML:
<div>
<canvas id="myChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
JS:
const labels = [
'January',
'February',
'March',
'April',
'May',
'June',
];
const data = {
labels: [
'20:00',
'21:00',
'22:00',
'23:00',
'00:00',
'01:00',
'02:00'
],
datasets: [{
type: 'line',
label: 'Bar Dataset',
data: [20, 21, 23, 22, 21, 20, 23],
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgba(255, 99, 132, 0.2)'
}, {
type: 'bar',
label: 'Line Dataset',
data: [0, 0, 0, 0, 50, 0, 0],
fill: false,
borderColor: 'rgb(54, 162, 235)'
}]
};
const config = {
type: 'bar',
data: data,
options: {
scales: {
x: {
stacked: true
}
}
},
};
const myChart = new Chart(
document.getElementById('myChart'),
config
);

ChartJS not showing data for time series bar chart

This was working when it was a line chart, but I am trying to convert it to a bar chart. The X-axis displays properly with all of the separate date spans and it changes when I select a dataset. However, none of the data is being displayed on the Y-axis. What is the issue?
var ctx = document.getElementById('activityChart');
var timeFormat = 'YYYY-MM-DD';
var StMarySchool = [{x: 1583422868000,y:1.5},{x: 1583510166000,y:1.5},{x: 1583516698000,y:0.75},{x: 1583516698000,y:0.75},{x: 1583568876000,y:3.75},{x: 1583575074000,y:0.75},{x: 1583581331000,y:1.875},{x: 1583585883000,y:1.875},{x: 1583664583000,y:0.375},{x: 1583664583000,y:0.375},{x: 1583693978000,y:1.875},{x: 1583749868000,y:0.75},{x: 1583756595000,y:0.75},{x: 1583789510000,y:0.75},{x: 1583837107000,y:1.125},{x: 1583852507000,y:0.75},{x: 1583852988000,y:0.75},{x: 1583872458000,y:1.875},{x: 1584121049000,y:1.5},{x: 1584172626000,y:3.75},{x: 1584445225000,y:0.75},{x: 1584533992000,y:3.75},{x: 1584538374000,y:1.125},{x: 1584538374000,y:1.125},{x: 1584565055000,y:1.125},{x: 1584783939000,y:1.875},{x: 1585034842000,y:1.875},{x: 1585073536000,y:1.875},{x: 1587468291000,y:0.75},{x: 1588780685000,y:1.875},{x: 1589222744000,y:0.75},{x: 1589560042000,y:1.125},{x: 1592056137000,y:1.875},{x: 1592144769000,y:0.75},{x: 1592299139000,y:0.75},{x: 1592816935000,y:0.75},{x: 1592900043000,y:0.75},{x: 1592909141000,y:7.5},{x: 1593162077000,y:1.125},{x: 1593961268000,y:1.875},{x: 1593961312000,y:1.875},{x: 1594487280000,y:1.875},{x: 1595336470000,y:0.75},{x: 1596191887000,y:0.75},{x: 1596785796000,y:3.75},{x: 1596989721000,y:1.5},{x: 1596989721000,y:1.5},{x: 1596989721000,y:1.5},{x: 1597007626000,y:0.75},{x: 1597139159000,y:0.75},{x: 1597184422000,y:0.75},{x: 1597322300000,y:0.75},{x: 1597341478000,y:1.125},{x: 1597431163000,y:1.5},{x: 1597666257000,y:0.75},{x: 1597857382000,y:1.875},{x: 1598288284000,y:0.75},{x: 1598462641000,y:0.75}];var BagelUniversity = [{x: 1596095822000,y:0.75},{x: 1596966501000,y:0.75},{x: 1597564562000,y:0.75},{x: 1597564562000,y:0.75},{x: 1597765250000,y:0.75},{x: 1598288284000,y:0.75}];var MerighisSavoyInn = [{x: 1597406165000,y:1.875},{x: 1597428169000,y:1.875},{x: 1597681599000,y:1.875}];
var config = {
type: 'bar',
data: {
datasets: [
{label:'Bagel University', data: BagelUniversity, fill: true, backgroundColor: ['rgba(239, 248, 251, .70)'],borderColor: ['rgb(42, 159, 216)']},{label:'Merighis Savoy Inn', data: MerighisSavoyInn, fill: true, backgroundColor: ['rgba(239, 248, 251, .70)'],borderColor: ['rgb(42, 159, 216)']},{label:'St. Mary School', data: StMarySchool, fill: true, backgroundColor: ['rgba(239, 248, 251, .70)'],borderColor: ['rgb(42, 159, 216)']}
]
},
options: {
responsive: true,
title: {
display: false
},
scales: {
xAxes: [{
offset: true,
type: "time",
/*time: {
unit: 'month',
format: timeFormat,
tooltipFormat: 'll',
max:"05/03/2020" ,
min:"26/08/2020",
},*/
time: {
unit: 'day',
round: 'day',
displayFormats: {
day: 'MMM D'
}
},
scaleLabel: {
display: true,
labelString: 'Date'
},
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: '$'
},
ticks: {
beginAtZero: true
}
}]
},
}
};
var myChart = new Chart(ctx, config);
I found that every date has to be in the data, regardless if it contains a datapoint.

ChartJS - Labels getting cutoff using datalabels plugin

I have a simple bar chart and I'm using the datalabels plugin to place labels inside each bar and at the top.
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['One', "Two"],
datasets: [{
data: [40, .5],
backgroundColor: [
'rgba(255, 99, 132)',
'rgba(54, 162, 235)'
],
borderWidth: 1
}]
},
options: {
legend: {
display: false
},
tooltips: {
enabled: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
max: 40
},
}],
xAxes: [{
maxBarThickness: 50
}]
},
plugins: {
datalabels: {
display: true,
anchor: 'end',
align: 'top',
color: 'white',
offset: -30,
font: {
weight: 'bold',
size: 14
}
}
}
}
});
But sometimes, I'll have a value that doesn't allow enough room for the label. See second bar on https://jsfiddle.net/myckxLun/1/.
I want to make sure I have X amount of room for these labels. I've tried minBarLength for the Y-axis - but all this does is force the bar length to be a min pixel value and doesn't adjust the graph (i.e. the bar length is inaccurate).
Ideas on how I can fix this? Thanks!

Does the min value of the xAxes have to be within the dataset

I'm trying to add the ability to change a 'date' range for my chart, and I've added a button callback that changes the min value of the xAxes and then calls chart.update(), but the chart doesn't change.
I've tried manually entering a number, and unless it's a value in the data given for the table it won't update the graph.
this.analysisChart = new Chart(context, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: calculations.rollingTimestamps,
datasets: [
{
label: 'Cycle Times',
data: calculations.rollingCycleTimesXY,
borderColor: 'rgb(0,255,0,1)',
backgroundColor: 'rgb(0,255,0,0.5)',
type: 'scatter',
showLine: false,
labels: calculations.rollingAliases
},
{
label: 'Rolling μ',
borderColor: 'rgb(255, 99, 132, 1)',
backgroundColor: 'rgb(255, 99, 132, 0.5)',
data: calculations.rollingAverage,
fill: false,
pointRadius: 0
},
{
label: 'Overall μ',
data: calculations.overallAverageArr,
fill: false,
borderColor: 'rgb(0,0,0,1)',
backgroundColor: 'rgb(0,0,0,0.5)',
pointRadius: 0,
showLine: true
},
{
label: 'μ + σ',
data: calculations.rollingMaxStandardDeviation,
fill: 4,
backgroundColor: 'rgb(50,50,255,0.35)',
borderColor: 'rgb(50,50,255,0)',
pointRadius: 0,
showLine: true
},
{
label: 'μ - σ',
data: calculations.rollingMinStandardDeviation,
fill: 3,
backgroundColor: 'rgb(50,50,255,0.35)',
borderColor: 'rgb(50,50,255,0)',
pointRadius: 0,
showLine: true
},
{
label: 'μ + 2 * σ',
data: calculations.rollingMaxSecondStandardDeviation,
fill: 3,
backgroundColor: 'rgb(50,50,255,0.3)',
borderColor: 'rgb(50,50,255,0)',
pointRadius: 0,
showLine: true
},
{
label: 'μ - 2 * σ',
data: calculations.rollingMinSecondStandardDeviation,
fill: 4,
backgroundColor: 'rgb(50,50,255,0.3)',
borderColor: 'rgb(50,50,255,0)',
pointRadius: 0,
showLine: true
}
]
},
// Configuration options go here
options: {
layout: {
padding: {
left: 20,
right: 20,
top: 0,
bottom: 0
}
},
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
label += Math.round(tooltipItem.yLabel * 10) / 10;
return label + " days";
}
}
},
hover: {
mode: 'index',
intersect: false
},
scales: {
yAxes: [{
ticks: {
min: 0,
type: 'linear',
callback: function(label, index, labels) {
return label + " days";
}
}
}],
xAxes: [{
ticks: {
type: 'linear',
min: 0,
callback: function(label, index, labels) {
return new Date(label).toDateString();
}
}
}]
},
title: {
display: true,
text: 'Cycle Times'
}
}
});
What I'd like to do is give an arbitrary number and have it perform a greater than check across the data for determining what to cut off rather than doing a find and then cutting anything off that is after that index in the array.
How can I do this?
As a solution, I just wrote a function to iterate through the array and find the first value that is greater than or equal to the value I wanted and then set the min of the xAxes to that value. Not very ideal, but hey at least it works.
I couldn't find anything in the documentation about callbacks for the min value.

how to disable last/max value shown on x axis in chart js?

Hi I have a list of dataset of every hour in a day, like below:
{"x":"2017-10-14T00:00:00","y":95},{"x":"2017-10-14T01:00:00","y":62},...,{"x":"2017-10-14T23:00:00","y":23}
I would like to show them in a four-hour time unit on x-axis so settings are like this:
scales: {
xAxes: [{
type: 'time',
time: {
displayFormats: {
'hour': 'HH:mm'
},
unit: 'hour',
stepSize: 4
}
}]
}
However, chart js would display last/max value '23:00' at the end of x-axis which is quite annoying because every tick is 4-hour difference. May I ask how to disable last/max value on x axis?
You can use a callback function for x-axis' ticks to hide/disable the last value, like so :
scales: {
xAxes: [{
ticks: {
callback: function(tick) {
// if tick/value is not equals to '23:00'
// then return the tick/value
// else return an empty string
return tick !== '23:00' ? tick : '';
}
}
}]
}
ᴅᴇᴍᴏ ⧩
log = console.log;
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['19:00', '20:00', '21:00', '22:00', '23:00'],
datasets: [{
label: 'LINE',
data: [3, 1, 4, 2, 5],
backgroundColor: 'rgba(0, 119, 290, 0.2)',
borderColor: 'rgba(0, 119, 290, 0.6)'
}]
},
options: {
scales: {
xAxes: [{
ticks: {
callback: function(tick) {
// if tick/value is not equals to '23:00'
// then return the tick/value
// else return an empty string
return tick !== '23:00' ? tick : '';
}
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>

Categories

Resources