Chart.js xAxes Date Labels are altered based on screen width - javascript

I've been messing around with chart.js time options (displayFormat and tooltipFormat):
type: 'time',
unit: 'day',
unitStepSize: 1,
time: {
displayFormats: {
'day': 'dd',
},
tooltipFormat: 'll'
},
Which works as expected - on a 17inch laptop screen.
This shows dates as Mo, Tu, We, Th, Fr, Sa, Su.
However on a 24inch monitor chart.js automatically alters the dates and they become:
Aug 18 12AM - Aug 18 12PM, Aug 19 12AM - Aug 19 12PM, etc
How can I stop this from happening?

You need to set the hour property of displayFormats to dd as well, like so :
...
time: {
displayFormats: {
'day': 'dd',
'hour': 'dd' //<-- set this
},
tooltipFormat: 'll'
},
...

Related

Chart.js Thick label gets replaced by three dots

How can I display full thick label? It always gets cut off and replaced by 3 dots.
I've been trying various options from https://www.chartjs.org/docs/master/axes/index with padding and similar, but I can't find this. Full date data is there.
You are using a previous version of Charts.js. With Charts.js >2.0 axis label should grow as much as needed to display the full date unless you override the label function like done here.
Demo: https://codepen.io/adelriosantiago/pen/wvooQRR?editors=1010
Date format can be changed in options.scales:
xAxes: [{
type: "time",
time: {
unit: 'hour',
unitStepSize: 0.5,
round: 'hour',
tooltipFormat: "h:mm:ss a",
displayFormats: {
hour: 'Y MMMM D, H:M:S A'
}
}
}]

ChartJS - Highlight Weekends and Lowest and Highest Values

I'm using ChartJS and I'd like to highlight all Saturdays and Sundays as a different colour - I'd also light to highlight the highest and lowest values in the chart.
Is this possible?
Fiddle so far:
http://jsfiddle.net/3wku56Lq/
new Chart(document.getElementById("myChart"), {
type: 'bar',
data: {
labels: ['14 May 2019 (Tue)', '15 May 2019 (Wed)', '16 May 2019 (Thu)', '17 May 2019 (Fri)', '18 May 2019 (Sat)', '19 May 2019 (Sun)', '20 May 2019 (Mon)', '21 May 2019 (Tue)', '22 May 2019 (Wed)', '23 May 2019 (Thu)', '24 May 2019 (Fri)', '25 May 2019 (Sat)', '26 May 2019 (Sun)', '27 May 2019 (Mon)', '28 May 2019 (Tue)', '29 May 2019 (Wed)', '30 May 2019 (Thu)', '31 May 2019 (Fri)', '01 Jun 2019 (Sat)', '02 Jun 2019 (Sun)', '03 Jun 2019 (Mon)', '04 Jun 2019 (Tue)', '05 Jun 2019 (Wed)', '06 Jun 2019 (Thu)', '07 Jun 2019 (Fri)'],
datasets: [{
data: [25738, 25261, 25499, 24178, 12400, 13356, 26033, 26588, 25018, 22972, 21702, 11232, 11617, 14308, 24212, 23949, 23708, 21511, 11545, 13836, 25536, 26824, 0, 0, 0],
label: "Impressions",
backgroundColor: 'rgb(199, 199, 199, 0.7)',
borderColor: 'rgb(199, 199, 199)',
fill: true
}
]
},
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var value = data.datasets[0].data[tooltipItem.index];
value = value.toString();
value = value.split(/(?=(?:...)*$)/);
value = value.join(',');
return value;
}
} // end callbacks:
}, //end tooltips
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
userCallback: function(value, index, values) {
// Convert the number to a string and splite the string every 3 charaters from the end
value = value.toString();
value = value.split(/(?=(?:...)*$)/);
value = value.join(',');
return value;
}
}
}],
xAxes: [{
ticks: {
}
}]
}
}
});
You can highlight weekends using map functions:
http://jsfiddle.net/75apft3m/
Also, you can do the same with the lowest and highest value.
But for this you must store that arrays somewhere.
Like this:
http://jsfiddle.net/75apft3m/1/
Just use Math.max.apply(null, dataArray)
and Math.min.apply(null, dataArray) to find highest and lowest values :)

Vis.js / Moment.js - Timeline Labels

I'm having a problem with the label format of vis.js timeline. I want to display an excat time period of 1 hour and 30 minutes and the labels should only display the amount of minutes and seconds passed.
I configured the options like this:
let options = {
autoResize: true,
min: '2000-1-1 00:00:00',
max: '2000-1-1 01:30:00',
start: '2000-1-1 00:00:00',
end: '2000-1-1 01:30:00',
//zoomMax: 86399999,
zoomMin: 18000,
format: {
minorLabels: {
millisecond: '',
second: 'mm:ss',
minute: 'mm:ss',
hour: 'mm:ss',
weekday: '',
day: '',
week: '',
month: '',
year: ''
},
majorLabels: {
millisecond:'',
second: '',
minute: '',
hour: '',
weekday: '',
day: '',
week: '',
month: '',
year: ''
}
}
};
As far as I understood it, vis.js calls for the labels (second, minute, hour, etc.) the moment().format() function from moment.js. Is it somehow possible in moment.js formatting to add the amount of hours (H) times 60 to the minutes (mm) value in an easy way?
In my current configuration it restarts at 00 minutes after 60 minutes:
timeline
(And yes, I'm working on an application for soccer)
In the docs you can find option to customize date format via function:
You can also use a function format for each label. The function accepts as arguments the date, scale and step in that order, and expects to return a string for the label.
Below you can find converted time to minutes:
format: {
minorLabels: function (date, scale, step) {
var time = date.format("HH:mm");
return moment.duration(time).asMinutes();
},
majorLabels: function (date, scale, step) { return "" }
}
JSFiddle with example

Chart.js time object labels not updating correctly

I am using Chart.js to draw a line graph which is based on dates. When it first loads it shows data for the current month.
var dayByDayChart = new Chart(ctx, {
type: 'line',
data: {
labels: <?php echo json_encode($arr_dates); ?>,
//labels: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31],
datasets: [{
label: '<?php echo $thisYear; ?>',
data: [<?php echo $rev2017; ?>],
backgroundColor: "rgba(153,255,51,0.6)"
}, {
label: '<?php echo $lastYear;?>',
data: [<?php echo $rev2016; ?>],
backgroundColor: "rgba(255,153,0,0.6)"
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [{
type: 'time',
time: {
displayFormats: {
'millisecond': 'MMM DD',
'second': 'MMM DD',
'minute': 'MMM DD',
'hour': 'MMM DD',
'day': 'MMM DD',
'week': 'MMM DD',
'month': 'MMM DD',
'quarter': 'MMM DD',
'year': 'MMM DD'
}
}
}]
}
}
});
You can then update the chart by selecting a date range, where I build a new set of data and pass it through using the objects and running update().
dayByDayChart.data.datasets[0].data = json.this_year;
dayByDayChart.data.datasets[1].data = json.last_year;
dayByDayChart.data.labels = json.dates;
The only issue is, Chart.js updates the time period correctly but still has the same number of x-axis points for the dates. Which means they get duplicated over and over. Here's an example of the intial chart:
and then the Ajax updated one:
As you can see, the date range is meant to be 1st to the 9th but it spreads those dates over the previous 28 days that are in Feb.
How can I get it to update correctly?
After looking at the docs and a couple forums I have found a solution that works. Chartsjs with the time config will try and guess the right time unit and when updating the chart dynamically it looks like it keeps the previous "guess".
Passing through the actual time unit I wanted i.e by day now allows the chart to update just once per day rather than trying to push single days over multiple ticks. here's the config example.
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'day',
displayFormats: {
//'millisecond': 'MMM DD',
'second': 'MMM DD',
'minute': 'MMM DD',
'hour': 'MMM DD',
'day': 'MMM DD',
'week': 'MMM DD',
'month': 'MMM DD',
'quarter': 'MMM DD',
'year': 'MMM DD'
}
}
}]
}
}
The difference is the unit option under time.

Customize amCharts date aggregation level

I would like to customize the date aggregate(axis labels) for amCharts, but I couldn't find a provision to do this in amCharts docs. Googling the same just pointed me to the dateFormats documentation.
amCharts provides an option for aggregating date by setting parseDates to true and adding dateFormats as shown below. This option aggregates date by doing some calculation by amCharts itself, let's say 25 days for week aggregation(Jan 5), 65 days for month aggregation(Jan) and so on, but I would like to customize the default date aggregation level.
parseDates: true,
dateFormats: [{
fff: 'period',
format: 'JJ:NN:SS'
}, {
period: 'ss',
format: 'JJ:NN:SS'
}, {
period: 'mm',
format: 'JJ:NN'
}, {
period: 'hh',
format: 'JJ:NN'
}, {
period: 'DD', // day level
format: 'MM/DD/YYYY'
}, {
period: 'WW', // week level
format: 'MM/W/YYYY'
}, {
period: 'MM', // month level
format: 'MMM YYYY'
}, {
period: 'YYYY',
format: 'YYYY'
}]
I would like to change the default day, week, month levels in the following manner.
DAY LEVEL: <= 14 days
WEEK LEVEL: 14 < x <= 91
MONTH LEVEL: 91 < x <= 731
I would like to customize the date aggregation levels in amCharts. How could I do this? Any help would be appreciated. Thanks in advance.
You can't set this so precisely. The next period is chosen when there are too many items in the selected period. You can try adjusting minHorizontalGap value of CategoryAxis: http://docs.amcharts.com/3/javascriptcharts/CategoryAxis#minHorizontalGap (default is 75). If you make it smaller, more items will fit and you'll have more labels.

Categories

Resources