Higcharts - marginBottom does not let rendering xAxis series ellipsis - highcharts

The space for xAxis generally is rendered dynamically by the Highcharts library and add the ellipsis in the correct place, making it display from the start and cutting it when it stop displaying it on the graph with some ellipsis.
When I try to change that space to not render dynamically, the property marginBottom does it,but it stops picking up when the text should start displaying and the start of the text is cutted from the down of the graph. Is there a way to render correctly the text at the bottom from the highcharts? I Do need it to be rotate 270 degrees, and not let the auto rotate work, and don't want to collapse more part of the graph just for displaying the text.
Here is a sample when that happes:
Highcharts.chart('container', {
chart: {
height: 350,
spacingBottom: 0,
marginBottom: 50,
type: "column"
},
series: [{
name: 'Total',
data: [1,2,3,4,5]
}],
xAxis: {
categories: ["very long name to test if the characters are rigth and cropped",
"Not so long but long enough", "I still am long and out of the screen",
"lets see how is cropped", "cropped", "crop"],
labels: {
rotation: 270
}
}
});
Sample fiddle with marginBottom : https://jsfiddle.net/ragmar/6ru4hze3/
If you remove the marginBottom, even the legend move down a bit.
It is possible to do this behavior? even including some css?
Thanks in advance

To make it work the way you want, you have to make some modifications in Highcharts core. For example you can do not use marginBottom option, but set fixed value as a commonWidth variable in renderUnsquish method:
if (attr.rotation) {
commonWidth = (
maxLabelLength > chart.chartHeight * 0.5 ?
40 : // changed from 'chart.chartHeight * 0.33'
maxLabelLength
);
if (!textOverflowOption) {
commonTextOverflow = 'ellipsis';
}
}
Live demo: https://jsfiddle.net/BlackLabel/moL1tw6c/

Related

Prevent Highchart.js from cutting xAxis label

I want to only show the first and last label for the xAxis. Then, I want to show it without rotation and in a single line. And when I do this, this happens and the last label gets cut when there are many columns or the width of the viewport is small.
Demo online:
https://jsfiddle.net/8esnf4dj/
This is my xAxis config:
xAxis: {
categories: [....],
labels: {
rotation: 0,
style: {
textOverflow: 'none',
whiteSpace: 'nowrap'
},
}
}
Is there any way to align the text in a way that this won't happen?
I've seen that this can be fixed by adding chart.marginRight but I would rather prefer not to "lose" that space not the right and just align the text in a way that will always be visible.
I am not sure if it is possible to achieve it by using only API options, because all the labels are rendered in the center of the tick, but you can move/set the position of each label 'manually'.
events: {
render() {
const chart = this;
const xAxis = chart.xAxis[0];
const lastTickPosition = xAxis.tickPositions.length - 1;
const lastLabel = chart.xAxis[0].ticks[lastTickPosition].label;
lastLabel.translate(-lastLabel.getBBox().width/ 4, 0)
}
}
Demo: https://jsfiddle.net/BlackLabel/kbn7zwfc/
API: https://api.highcharts.com/highcharts/chart.events.render
You can use "align: right"
Read the usage of align to understand why this works. Basically this would mean that the bar would align to the rightmost end of the label so the label always fits
xAxis: {
categories: [....],
labels: {
rotation: 0,
align: "right",
style: {
textOverflow: 'none',
whiteSpace: 'nowrap'
},
}
}

Center title of chart relative to the plot background

I would like to center the title of a pie chart relative to the plot background (not the element containing the chart), so that if there is a legend next to the char the title is still centered relative to the pie.
Using
title: {
text: 'Title',
align: 'center'
}
centers the title relative to the containing element.
See this fiddle for the full example.
Is it possible somehow?
You can position the title in the render event, for example:
chart: {
...,
events: {
render: function() {
var seriesGroupBBox = this.seriesGroup.getBBox();
this.title.attr({
x: seriesGroupBBox.x + seriesGroupBBox.width / 2 - this.title.getBBox().width / 2
});
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/6a9sroe7/
API Reference: https://api.highcharts.com/highcharts/chart.events.render

HighCharts xAxis show on 0 line with tick marks between all columns

I've developed a bunch of bar charts in HighCharts cloud with positive and negative values.
First question:
is it possible to have the xAxis appear at the 0 line (not at the bottom of the chart)?
What I've done so far is offset the xAxis so it's placed on the 0 line, which kinda works but I was hoping for a better solution. The other method I was think was to use plotLines code on the yAxis, but I don't get the ticks:
plotLines: [{
color: '#010101',
width: 2,
value: 0,
zIndex: 5
}],
Second question:
is it possible to have the tick marks to appear between each bar, and not just the bars that have an xAxis label?
This is what's rendering for me at the moment, and I'm trying to get a tick between all the bars while showing the same number of labels https://cloud.highcharts.com/show/cLtfEDClS
First question:
You can merge this configuration into chart options in Cloud’s custom code section:
chart: {
events: {
load: function() {
var yAxis = this.yAxis[0];
this.xAxis[0].update({
offset: -yAxis.toPixels(Math.abs(yAxis.min), true)
});
}
}
},
Demo: http://jsfiddle.net/BlackLabel/6712zrod/
It automatically positions x axis so that it works as y = 0 line.
Second question:
Try setting X Axis[0] > Labels > Step to 1.
API reference: https://api.highcharts.com/highcharts/xAxis.labels.step
Explanation from Docs:
To show only every n'th label on the axis, set the step to n. Setting the step to 2 shows every other label.
By default, the step is calculated automatically to avoid overlap. To prevent this, set it to 1. This usually only happens on a category axis, and is often a sign that you have chosen the wrong axis type.

Highstock/Highcharts - yAxis Label top

Using Highstock or Highcharts, I want my yAxis label on the top. What I don't want, is a varying margin between the left border of the chart and the beginning of the grid lines.
If you take a look at the following fiddle:
JSFiddle
Relevant part is:
yAxis: {
title: {
align: 'high',
offset: 0,
text: 'Rainfall (mm)',
rotation: 0,
y: -10
}
}
This is almost correct, but the offset margin is taken from the label width. If I set offset: -41 instead, it looks exactly right. The problem is, that the -41 is due to the rendered length of the text. If I change the text to something of a different length, the label is positioned wrongly again.
Is there any possibility to make sure, that the positions are always "correct" in my above definition of correct, regardless of the text length?
Screenshot, left part is wrong, right part is correct:
I think that you can use text-anchor property to style your title. Here you can find more information about text-anchor property: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-anchor
title: {
align: 'high',
text: 'Rainfall (mm)',
style: {
'text-anchor': 'start'
},
rotation: 0,
y: -10,
x: -25
},
I think that you need to use chart.marginLeft parameter as well. It will give you a chance to set specific left margin for your chart. Here you can find information about it.
http://api.highcharts.com/highcharts#chart.marginLeft
You may also use xAxis.labels.reserveSpace parameter to turn off reserving space for labels: http://api.highcharts.com/highcharts#xAxis.labels.reserveSpace
Here you can find live example how your chart can work with this options:
http://jsfiddle.net/Ljwp7694/
Kind regards,

Align Legend with x-Axis Title in HighCharts

The default behavior of the x-axis title alignment is within the bounds of the x-axis. However, the legend alignment is within the bounds of the entire chart. Thus, if you align both center, they have a slight offset. How can I get the legend to base its position off of the x-axis bounds instead? My graph options are dynamic, so I would need to do it dynamically.
Sample JS Fiddle
$('#container').highcharts({
legend: { margin:5, padding:0 },
xAxis:{
title:{
text:'THIS IS MY X-AXIS TITLE',
align:'middle',
},
categories:["A","B","C","D","E","F"]
}
});
Thanks in advance!
Example for you: http://jsfiddle.net/xqag5e72/2/
In short, you can change translation for legend to be similar to xAxis' title:
function moveLegend(e) {
var legend = this.legend,
x = this.plotLeft + (this.xAxis[0].width / 2) - legend.group.getBBox().width / 2,
y = legend.group.translateY;
legend.group.attr({
transform: 'translate(' + x + ',' + y +')'
});
}
Note: I'm using load and redraw events, to translate legend after first initialization and later to make this legend responsive.

Resources