Chart.JS: Stop chart from rescaling when hiding/unhiding a dataset? - javascript

I have several stacked bar charts which show a bunch of datasets. Often the user needs to hide or un-hide individual datasets. I need several of the features provided by the responsive property -- namely, updating chart size when the window is resized, or re-rendering when the underlying data changes.
However, when an individual dataset is hidden or un-hiddden, it's a problem that the chart re-scales so whatever bar has the highest value becomes the top of the scale. It makes it very difficult to understand the effect of hiding/showing a dataset on the various bars' total sizes.
Is there a way to keep all the other "responsive" features, but set it up so hiding datasets doesn't trigger a rescaling?

That isn't difficult. There are min and max properties in your options that overwrite any rearrangements. Just loop over all your data and set the highest value to the max property.
let chart = new Chart(ctx, {
type: 'bar',
data: { ... },
options: {
scales: {
yAxes: [{
ticks: {
min: 0,
max: 100
}
}]
}
}
}

Related

Chart.js, adding footer to chart

Using Chart.js 2.0. I'm looking for a way to add a footer (line of text) at the bottom of the chart in order to display sources of data.
I tried to solve it via the option object, the same way as title and legend are included and modified. Like this:
`options: { ...
footer: {
display: true,
text: 'data from xy'
}
}`
I saw 'footer' several times mentioned in the documentation and ways to style it or use it in the context of 'tooltips', but haven't seen anything how to add it concretely.
EDIT/UPDATE:
I've found two workarounds (but no perfect solution) to add a footer to the chart while trying to solve this. In case someone is running into same problem like I did, here some suggestions how to solve this.
Nr. 1: adding a HTML element. This workaround has the disadvantage that the added HTML element is not shown if a user downloads the chart as a .png. Maybe this is the best solution, if the element doesn't have to be visible if a user downloads the chart as a .png.
`var myChart = new Chart(ctx, {
type: 'line',
data: { ... },
options: {
legend: { ... },
...
legendCallback: function(){
return '<p>bla bla</p>';
},
...
},
});
document.getElementById('legendID').innerHTML =
myChart.generateLegend();`
adding AFTER the canvas a div to append the new HTML element
<div id=legendID></div>
Nr. 2: adding another dataset which is empty but a label which contains the information that is supposed to be displayed. borderColor and backgroundColor set to transparent. Adding some empty labels (" ") gives some distance between labels and the footer which is added. The disadvantage of this workaround are the limited possibilities for styling.
Nr. 3: the solution of ana liza. This finally works best for my case since the added info is visible on the .png.
From the official docs:
Labeling Axes
When creating a chart, you want to tell the viewer what data they are viewing. To do this, you need to label the axis.
The scale label configuration is nested under the scale configuration in the scaleLabel key. It defines options for the scale title. Note that this only applies to cartesian axes.
You can add labels for both axes but in your case, since you only need it on the x-axis, your chart options should look similar to this.
var options = {
scales: {
xAxes: [
{
scaleLabel: {
display: true,
labelString: 'Party size',
fontColor: '#C7C7CC',
fontSize: 11
}
}
]
}
};

Custom gridLines and Axes Chartjs

I am trying to design a CDF Chart using chartjs to show probabilities in a graph. Basically, I will always have 100 points starting at 0 to some max number which I calculate beforehand and I want to generate the charts as I attached. Smooth and not many gridLines. I tried using chart type "line", yet it is far off.
Could you please help me out to configure the chart correctly.
Examples of what I am looking for:
This is a solution without autoSkip, using gridline colour options to hide unwanted x axis gridlines. (sorry about my British spelling of 'colour'!)
I can't use autoSkip since my time/x axis labels show new Year, Month, Date only once and I couldn't work out how to not skip the particular labels which indicate a new month, for instance. I finally found that you can define gridline colours in an array, so my solution is to create a gridline colour array, setting the chart background colour to the gridlines I want to hide. In my case, I already send a list of labels with empty values for when I don't want a label and gridline, just a datapoint.
var labels = data3json['labels'].split(',');
//set gridline colour to background when label is empty:
var xaxis_gridline_colours = [];
for (var i = 0; i < labels.length; i++) {
if (labels[i].length > 0) {
if (i == 0) {
xaxis_gridline_colours.push("#cccccc"); //x and y axis!
} else {
xaxis_gridline_colours.push("#dddddd"); //visible gridline
}
} else {
xaxis_gridline_colours.push("#ffffff"); //invisible gridline
//or call a chart background colour variable like:
//xaxis_gridline_colours.push(chart_bkg_colour);
}
}
Later in the code:
chart = new Chart(ctx24, {
options: {
scales: {
xAxes: [{
gridLines: {
display: true, //default true
color: xaxis_gridline_colours,
etc
First about the gridLines, you can in your chart options change the stepSize of your xAxes (put it to 10 for instance) so you will have 10 times less vertical grid Lines (since your xAxes stepSize seems to be 1 by default).
If the big points are bothering you, when you create your datasets you can change their pointRadius to 0; this way no points displayed just a smoothline.
Finally you can change the color of the line of each dataset by setting the property borderColor.
Take a look at this page for more customization : http://www.chartjs.org/docs/latest/charts/line.html
Hope this helps.
I have noticed that most of you add the line styles only via code. I just spend 1h looking for the settings, as I change it once, but then I couldn't change it again.
How to do it. Post on Stackoverflow pointed me in the right direction.
Charts grid lines style
Line: this.chart1.ChartAreas[0].AxisX.LineDashStyle.Dot
Go to Properties->Chart->Chart Areas and click on 3 dots (...) next collection.
Properties
In Collection, go to Axes and again click on 3 dots (...) next collection.
Axes Collection
You will have 2 Axis: X and Y. Select each Axis and go to the required section to change properties. Be careful. They are well hidden, but I tried to highlight all the options. Of course, to perform the custom modification, you will have to code it.
Axis Collection Editor

ECharts: how to show all axis labels?

Echarts seems to have a nice feature that automatically chooses which labels to display depending on the space provided. However, this algorithm seems to be bit too aggressive at times and does not take into account text rotate. I've gone through the chart options and there doesn't appear to be a way to disable this feature. I'm hoping it's just something I've overlooked. Help appreciated.
axisLabel (under yAxis or xAxis) has an option interval. Set this to 0 and labels will be displayed.
You can try this to force the label of the x-axis,
xAxis: {
type: "category",
data: data[0],
axisLabel: {
interval: 0,
rotate: 30 //If the label names are too long you can manage this by rotating the label.
}
//If your label is in the `y-axis` simply change the code `xAxis` to `yAxis`.
If your axis label is not showing in a chart frame (mean ECharts label's length is too long), Try this,
grid: { containLabel: true },
2 ways to solve long label text
Using rotate option xAxis : { axisLabel: {
rotate: 45
} }
Using formatter and introducing '/n' to break the text
just for the record:
If your categories have a fixed width, you can also set it up like this, in order to show all labels:
axisLabel: {
width: 100, //fixed number of pixels
overflow: 'truncate', // or 'break' to continue in a new line
interval: 0,
},

Chart.js V2 ticklines no grid

I'm using ChartJs V2. Trying to have no horizontal gridlines but still have a little tick-line at the ticks. How is this possible? I'm using angular-charts to set the global options currently:
scales: {
yAxes: [{
gridLines: {
display: false,
drawTicks: true,
}
}],
}
What I have:
What I want:
The gridlines display option must be set to true for the ticks part of the gridlines to be drawn.
To show only the ticks, use the drawOnChartArea option to turn off the gridlines on the chart.
scales: {
yAxes: [{
gridLines: {
display: true,
drawOnChartArea: false,
}
}],
}
EDIT:
JSFiddle
What you need for this are Chart.js plugins.
They let you handle what is happening when events like the rendering or the update are triggered.
For instance, in your case, we want to draw again the ticks which were erased via the display:false attribute of options.scales.yAxes.gridLines.
We will then need the afterDraw event. Plugins in Chart.js are created like this :
Chart.pluginService.register({
afterDraw: function(chart, easing) {
// Your code in here
}
});
Now that you know how to do, let's focus on what to do.
What we want is to redisplay the tick lines on the yAxes. But they were removed (as I said above).
We can't bring them back, but since Chart.js charts are using a <canvas> tag, we can try to draw them once again.
To do it dynamically (most I can at least), we will need to loop in the different ticks of your y axe and, by also getting the height of your axe, we will be able to draw our own ticks.
Here is a jsFiddle (improved by the OP) with some explanation about what we must do and of course a fully working example, and here is its preview :

Highcharts - Resizing Columns to Fix Data Label

I'm trying to get the columns of my Highcharts chart to resize in order to always leave room for the data labels.
Right now, I can only do one of the following:
Have the data labels appear inside the columns themselves: jsfiddle.net/gjslick/LrAuf/
Have the data labels cropped when they don't fit: jsfiddle.net/gjslick/L7LKA/1/
Have the data labels display, but overlap other lines in the chart: jsfiddle.net/gjslick/WbQb4/1/
Is there any way to get the columns to be resized in order to guarantee that the label fits above/below the column? Thanks!
My preference would be for #1. But, you could also try using xAxis.offset to add some padding between the xAxis labels and the actual chart area (see this one). But, as you can see I increased the negative value to be much larger than your original one. This shows how the yAxis is auto-scalling and it actually increases the padding a bit too much. To fix this you may need to go and get prefetch the maximum/minimum y-values and manually set the yAxis min/max.
xAxis: [{
offset: 14,
title: {
text: ''
},
type: 'category'
}],
yAxis: [{
min: -10,
max: 10,
title: {
text: ''
},
labels: {
enabled: false
},
gridLineWidth: 0
}],

Categories