Highcharts draw grid lines into yAxis area - highcharts

In Highcharts, there is a possibility to shift the y-Axis labels into the plot-area with
yAxis: {
labels: {
align: 'left',
x: 0,
y: -2
}
}
With this setting, the labels are covered by the lines, data-labels and so on.
Is it possible to draw the horizontal grid lines across the yAxis-Label-Area without making the xAxis and the series start there. The wished behavior is indicated with the black lines in the image below.

The simplest solution is to adjust the xAxis, for example:
xAxis: {
min: -0.5
}
Live demo: http://jsfiddle.net/BlackLabel/qnayxb04/
API: https://api.highcharts.com/highcharts/xAxis.min
If you want to have more control over the lines, you can use setAttribute to edit the path element:
chart: {
events: {
load: function() {
var gridLines = this.yAxis[0].gridGroup.element.children,
i,
path;
for (i = 0; i < gridLines.length; i++) {
path = gridLines[i].attributes.d.nodeValue;
path = 'M 40' + path.substr(4);
gridLines[i].setAttribute('d', path)
}
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/61h5qtn9/1/

Related

Highcharts Bar - Display DataLabel at the right end of the plot

I need the dataLabels to be always displayed at the right end of bar chart irrespective of the data value. According to the Highcharts API, the dataLabel position is adjustable only relative of its current position. Is there a way to change the datalabel position relative to the chart area?
You're looking for something like this?
If you make the labels HTML elements instead of SVG elements..
plotOptions: {
bar: {
dataLabels: {
enabled: true,
allowOverlap: true,
//Labels are easier to move around if we switch from SVG to HTML:
useHTML: true,
}
}
}
..it's quite easy to move them around using CSS:
.highcharts-data-labels.highcharts-bar-series {
/* Stretch the labels container across the whole chart area: */
right: 0;
}
.highcharts-label.highcharts-data-label,
.highcharts-label.highcharts-data-label span {
/* Disable the default label placement.. */
left: auto !important;
/* ..and put them along the right side of the container */
right: 8px;
}
https://jsfiddle.net/ncbedru8/
You can also position data labels in the render event:
events: {
render: function() {
var chart = this;
chart.series.forEach(function(s) {
s.points.forEach(function(p) {
if (p.dataLabel) {
p.dataLabel.attr({
x: chart.plotWidth - p.dataLabel.width
});
}
});
});
}
}
Live demo: http://jsfiddle.net/BlackLabel/yt1joqLr/1/
API Reference: https://api.highcharts.com/highcharts/chart.events

xAxis - point specific label positions

Is there a way to have a point specific positionning of the xAxis labels ?
I am using a waterfall chart and for some bars I would like the label to appear directly under the bar like below :
I have found the following code in the xAxis plotOptions but at this point I don't see how I can acces the info on the bottom of the chart.
xAxis: {
labels: {
y:-100 //label's y position
}
},
You can use point dataLabels to achieve such result:
dataLabels: {
crop: false,
overflow: 'none',
verticalAlign: 'bottom',
format: 'label1',
y: 20
}
Live demo: https://jsfiddle.net/BlackLabel/71jtp5mf/
API Reference: https://api.highcharts.com/highcharts/series.waterfall.dataLabels
Another way is to create your own custom function to position the xAxis labels, for example:
events: {
load: function() {
var chart = this,
point;
Highcharts.objectEach(chart.xAxis[0].ticks, function(tick) {
if (!tick.isNewLabel) {
point = chart.series[0].points[tick.pos];
tick.label.attr({
y: point.plotY + chart.plotTop + point.shapeArgs.height + 15
})
}
});
}
}
Live demo: https://jsfiddle.net/BlackLabel/oaj9bgt4/

Show plotlines in highcharts with hidden axis?

Is there a way to show plotlines even when the associated axis has visible: false? Is seems that hiding the axis also hides the plotlines.
More details...
I'm drawing a diagram of a day, like this:
I simply want to add a vertical line at certain times, line the "Now" time, etc.
If I do that using a plot line, then the axis shows up too:
I definitely do not want the axis to show.
My plan now is to draw my own line on the chart using render.rect or render.path. Is there another option?
I found a relatively trivial solution... just hide it with css:
.highcharts-xaxis {
display: none;
}
and in js:
xAxis: {
type: 'datetime',
labels:{
enabled: false
}
}
You can extend Highcharts by wrapping the method responsible for redrawing an axis.
Highcharts.wrap(Highcharts.Axis.prototype, 'redraw', function(p) {
p.call(this);
console.log(this);
var axis = this,
each = Highcharts.each,
options = this.options;
// move plot lines and bands
if (!axis._addedPlotLB) { // only first time
each((options.plotLines || []), function(plotLineOptions) {
axis.addPlotBandOrLine(plotLineOptions);
});
axis._addedPlotLB = true;
}
each(this.plotLinesAndBands, function(plotLine) {
plotLine.render();
});
});
example: http://jsfiddle.net/ncs81btt/
The solution above is not very elegant, though. Much better ways to do it is using Renderer or hide particular axis elements (labels, ticks, etc.).
Depending on what you need from plot lines functionality, using renderer requires to do some calculations.
var customPlotLines = [{
value: 5,
color: 'red',
width: 3
}, {
value: 10,
color: 'yellow',
width: 3
}]
function renderPlotLines() {
var axis = this.xAxis[0],
top = axis.chart.plotTop,
bottom = top + axis.chart.plotHeight,
path = [
'M', null, top,
'L', null, bottom
];
if (!this.customPlotLines) {
this.customPlotLines = customPlotLines.map(plotLine => {
return this.renderer.path([]).add();
});
}
this.customPlotLines.forEach((plotLine, i) => {
var opt = customPlotLines[i];
path[4] = path[1] = axis.toPixels(opt.value);
plotLine.attr({
d: path.join(' '),
'stroke-width': opt.width,
stroke: opt.color
});
});
}
Hook into load/redraw event, so the elements will resize.
chart: {
zoomType: 'xy',
events: {
load: renderPlotLines,
redraw: renderPlotLines
}
},
example: http://jsfiddle.net/ncs81btt/1/

How do I move the title-label of a polar (spider) graph with HighChart 4?

I created a polar graph. It has some complicated title-lables. It looks as expected on desktop:
But when it's on mobile, the title-lables don't have enough room to show up. And HighCharts neither did it for me. So it looks like this:
What I desire is to move the two title-labels under the triangle, without changing how it behaves in Desktop view.
What can I do to achieve this?
Thanks!
You can translate labels using tick.label.attr({ x: new_x }); method. For example, create some reposition method:
function reposition () {
var chart = this,
xAxis = chart.xAxis[0],
tick, bbox, xy;
$.each(xAxis.tickPositions, function(i, pos){
tick = xAxis.ticks[pos];
if (tick && tick.label) {
bbox = tick.label.getBBox(); // get label's bounding box
xy = tick.label.xy; // get label's xy position
if (xy.x - bbox.width < 0) {
tick.label.attr({
x: bbox.width
});
}
if (xy.x + bbox.width > chart.plotWidth + chart.plotLeft) {
tick.label.attr({
x: chart.plotWidth + chart.plotLeft - bbox.width
});
}
}
});
}
Which will be called on each chart redraw and starting load events:
$('#container').highcharts({
chart: {
polar: true,
type: 'line',
events: {
redraw: reposition,
load: reposition
}
},
...
});
Live demo: http://jsfiddle.net/wmgbbp9k/

Highcharts - labels inside and outside a pie chart

I know it's possible to put pie chart labels either inside or outside the pie by changing plotOptions.pie.dataLabels.distance. I am trying to figure out whether it's possible to change that on a point by point basis:
if slice is smaller than 15%, place labels inside the slice
else place the label outside the slice
Is this possible in Highcharts? Below is one of my attempts, which doesn't work; the plain jsfiddle is here: http://jsfiddle.net/supertrue/q6bQP/
plotOptions: {
pie: {
dataLabels: {
distance: -30,
color: 'white',
formatter: function() {
if (this.y < 15 ) {
this.point.dataLabels.color = 'red';
this.point.dataLabels.distance = 20;
return this.point.name;
} else {
return this.point.name;
}
}
},
This post can helps you to acomplish your work :
Is it possible to position Highcharts dataLabels depending on the value?
$.each(chart.series[0].data, function(i, point) {
// using the value or calculating the percent
if(point.percentage < 30) {
point.dataLabel.attr({y:20});
}
});
This can be achieve using events as well.
Working fiddle : Outside Fiddle
Here if data point is less than five the show labels outside the charts.
chart: {
type: 'pie',
events: {
load: function() {
var series = this.series[0];
setTimeout(function(){
(series.points).forEach(function(point, i){
if (point.y < 5) {
point.update({dataLabels:{distance: 2}});
}
});
}, 200);
}
}
}

Resources