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
Related
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
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/
I'm displaying the x-axis of my Highstock chart at the top of the chart area with xAxis: { opposite: true}.
However the tooltip continues to show the x-axis value at the bottom of the chart, see for example here http://jsfiddle.net/ckj7kf2y/
Is there any way I can change the positioning of this be at the top, close to the x-axis?
Bonus points if someone knows why the tooltip.positioner callback isn't called when tooltip: { split: true }
It's possible to wrap core code to add this feature like in this demo: http://jsfiddle.net/ygmbwxtx/
(function(H){
H.wrap(H.Tooltip.prototype, 'renderSplit', function (proceed) {
proceed.apply(this, [].slice.call(arguments, 1));
var tooltip = this,
topAxis = tooltip.options.topAxis,
axisTT = tooltip.tt,
top = tooltip.chart.plotTop;
if (topAxis) {
axisTT.attr({
y: top - axisTT.height,
anchorY: top + 10
});
}
});
}(Highcharts))
and in chart's options:
...
tooltip: {
split: true,
topAxis: true
...
Bonus: positioner is not used for split tooltip - split uses own logic for positioning
Is there any way to completely hide scrollbar's buttons which contain arrow?
In addition to this, is there any way I can set the position of scrollbar such as setting y value so that the scrollbar hovers on the chart?
Setting its color to transparent doesn't help.
scrollbar: {
buttonBackgroundColor: 'transparent',
buttonBorderWidth: 0,
buttonArrowColor: 'transparent',
buttonBorderRadius: 0
}
EDIT:
Even if I hide the elements, I cannot use the space left as the picture below.
You can manipulate SVG elements.
chart: {
events: {
load: function () {
var chart = this;
chart.scroller.scrollbarButtons[0].hide();
chart.scroller.scrollbarButtons[1].hide();
}
}
},
Example:
http://jsfiddle.net/fexw25Lz/
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);
}
}
}