Chart.js automatic scaling - javascript

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].

Related

I have 10 points inn x-axis, ranging [-25,-20,,-15,-10,0,10,20,30,40,50]. But I want my line chart to start from -15 of x-axis. How we can achieve?

I have 10 points inn x-axis, ranging [-25,-20,-10,0,10,20,30,40,50]. But I want my line chart to start from -15 of x-axis. How we can achieve?
Below is the code i tried with suggestedmin and suggestedmax but it didnt worked.
Please suggest some way to achieve this
export class CgChartComponent {
lineChartData: ChartDataSets[] = [
{ data: [3145000, 3430001, 1499998, 1700000, 3515340, 2480011], label: 'ABC', lineTension: 0, },
];
lineChartLabels: Label[] = ['-25','-20','-15', '-10', '0', '10', '20', '30','40','50' ];
lineChartOptions = {
responsive: true,
responsiveAnimationDuration: 30,
legend: {
position: 'bottom'
},
scales: {
xAxes: [{
ticks: {
suggestedMin: -15,
suggestedMax: 40
}
}]
}
};
lineChartColors: Color[] = [
{
borderColor: 'black',
},
];
lineChartLegend = true;
lineChartPlugins = [];
lineChartType = 'line';
}
Try to use min and max instead of suggestedMin and suggestedMax as follows:
xAxes: [{
ticks: {
min: -15,
max: 40
}
}]
From Chart.js documentation
Axis Range Settings
The suggestedMax and suggestedMin settings only change the data values that are used to scale the axis. These are useful for extending the range of the axis while maintaining the auto fit behaviour.
Tick Configuration
min: User defined minimum value for the scale, overrides minimum value from data.
max: User defined maximum value for the scale, overrides maximum value from data.
UPDATE
The problem is probably that the labels are strings but min and max are defined as numbers. This can be solved in two different ways.
Either you transform the labels into numbers or you define min and max as follows:
xAxes: [{
ticks: {
min: '-15',
max: '40'
}
}]

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

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.

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

Chart.js mixed chart : Lines not starting at zero

current situation
chart
what i want : chart
I build a mixed chart with lines and bars. I have problem with lines.
Lines not starting at zero.
Here is my codes;
https://jsfiddle.net/ameydan/vb4fsyqp/31/
` options: {
legend: {
display: false,
position: 'top',
},
elements: {
point: {
radius: 0
}
},
scales: {
yAxes: [{
stacked: true,
ticks: {
beginAtZero: true
}
}
],
xAxes: [{
stacked: true,
ticks: {
beginAtZero: true
}
}
]
}
}`
thanks in advance.
beginAtZero : true , not solved problem.
That is cause you setted stacked to true.
scales: {
yAxes: [{
stacked: **false**,
ticks: {
beginAtZero: true
}
}
],
xAxes: [{
stacked: true,
ticks: {
beginAtZero: true
}
}
]
}
EDIT:
Second thought coming from => https://www.chartjs.org/docs/latest/charts/mixed.html
At this point we have a chart rendering how we'd like. It's important to note that the default options for a line chart are not merged in this case. Only the options for the default type are merged in. In this case, that means that the default options for a bar chart are merged because that is the type specified by the type field.
I found a solution!
Just add this :
myChart.options.scales.xAxes[0].offset = false;
myChart.update();
The only counterpart is that if there's data # index 0 of a bar dataset, it will be only half drawn and the last one as well as shown here : https://jsfiddle.net/0qsh8znu/1/
I had the same issue. When I followed #rOulito 's solution, I found that the lack of offset for my line graph made it no longer line up with the data points of my bar graph, so that didn't work, sadly.
My solution was to follow the docs for a chartjs plugin for annotations
This is how I drew a line from the first data point of my line graph to the bottom left of the graph:
let options = {
plugins: {
annotation: {
annotations: {
line1: {
type: 'line',
yMax: 50000,
xMax: 0,
borderColor: 'black',
borderWidth: 3,
},
},
},
},
};

Chart.js timescale: set min and max on xAxes

How can I set a min and max on the xAxes? It works fine on the yAxes but on the xAxes it shows no behavior.
My xAxes is using the type: 'time'. My labels for the xAxis are using the moment object aswell. But it also does not work when I remove the type time and use normal digits. I am using the Chart.js version 2.2.2.
scales: {
yAxes: [{
ticks: {
beginAtZero:false,
}
}],
xAxes: [{
type: 'time',
ticks: {
min: moment(1471174953000),
max: moment(1473853353000)
}
}]
}
Here is the chart.js Time Scale documentation.
The properties you are looking for actually are in the time attribute :
options: {
scales: {
xAxes: [{
type: "time",
time: {
min: 1471174953000,
max: 1473853353000
}
}]
}
}
This was changed in 3.0
https://www.chartjs.org/docs/latest/getting-started/v3-migration.html#options
scales.[x/y]Axes.time.max was renamed to scales[id].max
scales.[x/y]Axes.time.min was renamed to scales[id].min

Categories

Resources