How do I implement the 'autoskip' feature in chartjs? - javascript

Example
I am trying to use the autoSkip feature found here in the chart.js documentation:
https://www.chartjs.org/docs/latest/axes/cartesian/?h=autoskip
The issue I am having is my x-axes labels are overlapping (see above example).
Everything I have read says this autoSkip feature should automatically skip overlapping labels. However, when setting this to both true or false, nothing seems to change in my chart.
<Line
data={this.state.chartData}
options={{
elements: {
point: {
radius: 2
}
},
tooltips: {
mode: 'nearest',
intersect: false
},
scales: {
yAxes: [{
ticks: {
stepSize: 1, //sets the interval that our y axis counts by
beginAtZero: false, //starts our graph at 0 if true
},
gridLines: {
drawOnChartArea: false
}
}],
xAxes: [{
ticks: {
minRotation: 88,
autoskip: true,
autoSkipPadding: 50
},
gridLines: {
drawOnChartArea: false
},
type: 'time',
distribution: 'series',
time: {
unit: 'day',
displayFormats: {
day: 'MMM D',
},
tooltipFormat: 'MMM D h:mm a',
},
},
]
},
responsive: true, //lets us resize our chart
maintainAspectRatio: true, //lets us resize our chart
}
}
/>

In case anyone is wondering, please update to 2.9. Confirmed that the issue is resolved there.
https://github.com/chartjs/Chart.js/issues/6591

I noticed your autoskip is in lower case where in the documentation its in camlcase (ie. autoSkip) - from my experience with Chartjs, I've found that it might make a difference to try and fix that and see if that does the trick

You could try changing
distribution: series
to
distribution: linear
It looks to me like its trying to space the data evenly, despite the fact that you're missing data for 3 days (the weekend maybe?). It really shouldn't break your labels... but I bet the labels know there's enough space for n labels on the graph, but they don't realize that three of the labels are being squished together.
The default distribution is linear, so you could also just remove it. (https://www.chartjs.org/docs/latest/axes/cartesian/time.html#scale-distribution)

For anyone wondering, a chartjs dev has replied to my post here: https://github.com/chartjs/Chart.js/issues/6591
Looks like there are some issues in the current Chart.js version. Should be fixed in 2.9.

Related

Chart.js - mixed chart types (line/bar) on time scale causing offset problems after migration to v3

I'm using chart.js in my project where I'm having a daily-ticked time scale on the X axis and two linear scales on the Y axis. On one linear scale I'm rendering an usual line chart representing a chronological trend while rendering multiple stacked bar charts on the other linear scale, representing average stats for each day. Pre-v3 versions of chart.js were dictating to use a general chart type bar for this to work, and in my case it did even on a time scale. Only workaround I had to use to was to set the bar chart data to 12:00pm to have it centered on the day while also setting the barThickness manually, as it will default to 0 (?) on a time scale otherwise.
Now I've recently updated to v3.2.0 and adjusted my options and datasets according to the migration documentation. Rendering the charts I noticed that the scale ticks were offset by half a day, thus both charts being off. After some research I found out that it was due to the offset option for the scale being enabled as I was using a bar chart.
Manually turning off the offset option is to no avail either though. Besides the time scale not using up another day anymore, the ticks are still off by half a day.
Cutting out the bar chart dataset resets the ticks back to normal. Unfortunately there doesn't seem to be a way to apply the offset only to the bar charts. Does anyone have an idea how to deal with this?
I have now created a Codepen example for this.
scales: {
x: { // time scale
type: 'time',
offset: false,
time: {
unit: 'day',
displayFormats: {
day: 'iii, dd.MM'
}
},
bounds: 'ticks',
grid: {
color: "#444",
zeroLineColor: "#888",
zeroLineWidth: 2
},
title: {
display: true,
text: 'Date'
}
},
yT: { // line chart scale
position: 'right',
beginAtZero: false,
grid: {
color: "#444",
zeroLineColor: "#888",
zeroLineWidth: 2
},
ticks: {
maxTicksLimit: 24,
stepSize: 9000,
callback: (duration) => String(duration / 3600) + 'h'
}
},
yR: { // bar chart scale
position: 'right',
beginAtZero: false,
grid: {
color: "#444",
zeroLineColor: "#888",
zeroLineWidth: 2
},
ticks: {
maxTicksLimit: 48,
stepSize: 10800,
callback: (duration) => String(duration / 3600) + 'h'
},
title: {
display: true,
text: 'Duration'
},
stacked: true
}
}
I opened an issue on GitHub where I was told that I also had to explicitly set the grid.offset option to false, and this fixed it for me.

Chartjs-plugin-zoom plugin does not change x axis labels

I am working with the chart.js module in order to plot some data and am using the chartjs-plugin-zoom in order to enable zooming and panning however although the zooming works the labels on the x axis will not change for whatever reason.
I have seen similar questions but they all dealt with time series data and therefore the advice was unhelpful.
Here is the plot zoomed out:
and here is it zoomed in:
The key thing to notice is how the labels on the y axis have changed but the x axis labels have not changed. Here is the relevant config variable of the chart:
const config3 = {
type: 'line',
data: {
labels: [I ran out of chars but this is just a very long list of numbers in this format: 1,2,3,4,5],
datasets: [
{
label: "",
backgroundColor: '#'+Math.floor(Math.random()*16777215).toString(16),
borderColor: '#0071BC',
data: [I ran out of chars but this is just a very long list of numbers in this format: 1,2,3,4,5],
fill: false,
borderWidth: 1,
},
],
},
options: {
responsive: true,
title: {
display: true,
text: 'Peak: -1.2188'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Frequency (Hz)'
},
ticks:{
autoSkip: true,
maxTicksLimit: 20
},
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Amplitude'
}
}],
},
plugins:{
zoom: {
pan: {
enabled: true,
mode: 'xy',
speed: 20,
threshold: 10,
},
zoom: {
enabled: true,
drag: false,
mode: "xy",
speed: 0.1,
// sensitivity: 0.1,
}
}
},
elements: {
point:{
radius: 0
}
}
}
};
If needed I can provide more code but I imagine the mistake is probably contained in the config. I tried changing zoom.mode to be 'x' but that did not work.
In case someone else comes along this I figured out a solution that is pretty unintuitive.
The first problem is the way that labels are dealt with in chart.js and because they are treated as categories not x data the way that I thought they were. Therfore first you must pass your data in as coordinates in this format:
(as shown in this documentation: https://www.chartjs.org/docs/latest/charts/line.html)
data: [{
x: 10,
y: 20
}, {
x: 15,
y: 10
}]
And delete the labels variable.
However this will not work with line charts despite what the documentation says. To get around this you can set: type: 'scatter' and inside the dataset write showLine: true
This will generate a line plot where the x labels are auto generated and zooming will work perfectly.
I also think there was a performance boost which is a nice bonus.

ChartJS - How to increase the maximum degree of label rotation on x-axis?

I have a line chart, and at first, all the labels on x-axis are fully horizontal. Something like this:
Now if add more data, the labels start to rotate:
Until comes a point where it seems to have reached the maximum degree to which it can rotate:
By the looks of it, I think the maximum degree is 45. So now, if I add a little more data, instead of rotating the labels more, it removes every one in two labels, and becomes like this:
How can I increase this degree to 90, so that the labels rotate as much as becoming fully vertical?
Here's the code I used for the chart:
new Chart(chart, {
type: 'line',
data: chart_data,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
},
legend: {
position: 'top',
labels: {
boxWidth: 5,
usePointStyle: true
}
},
events: ['click', 'mousemove'],
onClick: clicked,
pan: {
enabled: true,
mode: 'x',
onPanComplete: function(event) {
console.log(event)
}
},
zoom: {
enabled: true,
mode: 'x'
}
}
});
You can configure this using the maxRotation property of the common tick configuration object.
Your code needs to be modified like so:
options: {
scales: {
xAxes: [{
ticks: {
maxRotation: 90
}
}],
yAxes: [{
...
The keyword of the issue is not rotation i think, it is Tick on xAxes.
I think this link can help you :
https://www.chartjs.org/docs/latest/axes/styling.html#tick-configuration
also
Chart.js: evenly distribute ticks when using maxTicksLimit
xAxes: [{
ticks: {
autoSkip: false, // Skip or not?
maxTicksLimit: 30 // How much?
}
}]
and rotation just can help as #timclutton said here : https://stackoverflow.com/a/58275468/7514010

Flot Chart Bar spacing

I am using flotchart JS for showing bar graphs. However, I can't seemed to fix the spacing between bars.
I have enabled panning already. However, sets the width of the bar according to the placeholder. How can set each bar's spacing according to its label?
this is my code:
$.plot("#graph", [ data ], {
series: {
bars: {
show: true,
barWidth: 0.6,
align: "center"
}
},
xaxis: {
mode: "categories",
showTicks: false,
gridLines: false,
panRange: [0,null],
},
yaxis: {
panRange: [0, null],
plotPan: false //pan axis is allowed for plot pan
},
pan: {
interactive: true,
mode: "smart",
active: true
}
});
An alternative solution to your problem could be to rotate the tick labels for example by using the tickrotor plugin:
xaxis: {
mode: "categories",
showTicks: false,
gridLines: false,
panRange: [0,null],
rotateTicks: 90
},
You may need to increase the height of the chart since the labels now take up more space. See this fiddle for a full example.
You can achieve this by limiting the number of bars shown at once by giving a max property for the xaxis:
xaxis: {
mode: "categories",
showTicks: false,
gridLines: false,
panRange: [0,null],
max: 7, // set according to your needs, maybe dynamic depending on chart width
min: 0
},
You then have to use panning to see the other bars. See this fiddle for an example.

Chart.js automatic scaling

I've been testing out chart.js for maybe including it in a project. I just have one smallish issue with it. It doesn't scale some datasets properly. I found somewhat similar questions here in SO, but nothing really that would solve my issue.
So this is what my chart looks like with some datasets:
For some reason, the max values (2.2) look ugly as hell. The reason is, that the dataset has a set of three duplicate values in this case (2.2, 2.2, 2.2). I would like there to be some room on top of this series, so that it would look a bit more reasonable.
How do you properly add "padding" on top the the series line? I would like a solution where I could rely on chart.js to find out the max value, and then maybe update that with some padding on the scale(like x + 10). Issue is, that I cant just hard code the min max values, because I can have over 200 different values that can be selected, and they can vary A LOT in scale.
Here is how I render the chart for now:
return new Chart(context, {
type: 'line',
data: {
labels: labels.data,
datasets: dataSets
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
ticks: {
beginAtZero: false
},
yAxes: [{
ticks: {
beginAtZero: false
},
id: 'A',
type: 'linear',
position: 'left',
}, {
ticks: {
beginAtZero: false
},
display: displayBAxis,
id: 'B',
type: 'linear',
position: 'right',
}]
}
}
});
This may not be the cleanest way but you can play with it as you see fit.
In short, you need to create a function that finds the max value out of all your dataSets arrays and in yAxes.ticks set max to that functions return value.
More details below
Referencing here first:
data:{
labels: labels.data,
datasets: dataSets //talking about this first
}
Create a function that will go through these arrays and get the max of all arrays. I did it using this but you can do it better I'm sure:
function getMax(){
var max = 0;
dataSets.forEach(function(x, i){
max = Math.max(max, Math.max.apply(null, x.data));
});
return max + 2;
}
Then in your return in yAxes you should be able to have:
ticks: {
beginAtZero: false,
max: getMax()
},
You can find the min and max of your dataset, then add/subtract a percentage of the difference (range).
For example, say you use 1% of the range.
[0.1, 0.2, 0.5] gives (1%)x(0.5-0.1)=0.004, so [min,max]=[0.096,0.504].
[1500, 1800, 3500, 3600] gives (1%)x(3600-1500)=21, so [min,max]=[1479,3621].

Categories

Resources