Highcharts - labels inside and outside a pie chart - highcharts

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);
}
}
}

Related

Highcharts draw grid lines into yAxis area

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/

Highcharts: closest point on chart gets highlights and shows tooltip instead of the point where mouse in pointing

I am running into an issue of incorrect point's tooltip on synchronised charts. On the synchronised charts the crosshair is shown and using ordinal:false I am plotting equidistance ticks.
The issue occurs when the crosshair moves along with mouse-move and shows the nearest point's data on the tooltip.
The expected behaviour is: when there is no data, crosshair should be shown but not the tooltip.
here is an existing SO fiddle I found https://jsfiddle.net/jknipp/g3vr5v44/13/
To achieve the effect you need, just return false if window.isOutOfSync, instead of No data string here:
formatter: function(tooltip) {
var header,
s = [];
console.log(window.isOutOfSync);
if (window.isOutOfSync) {
console.log("don't show tooltip");
//return false;
console.log(this)
return false;
}
$.each(this.points, function(i, point) {
// check to see if the point is in the overall graph
//var overallChart = $("#total_success_rates").highcharts();
//console.log(overallChart);
var isSuccessRate = (point.series.name == 'Success');
if (header == null) {
var config = point.point.getLabelConfig();
header = tooltip.tooltipFooterHeaderFormatter(config);
}
s.push(formatSuccessRateToolTip(point.y, isSuccessRate));
// $("#" + point.series.name.toLowerCase() + "-rate").html(point.y + "%");
});
return header + s.reverse().join('<br>');
}
[EDIT]
Additionally, please call reflow() inside of the chart.events.load function on both charts, just like below:
chart: {
renderTo: container,
type: 'areaspline',
events: {
load() {
this.reflow()
}
},
height: '220',
spacingBottom: 20,
spacingTop: 20,
spacingLeft: 20,
spacingRight: 20
},
Live example: https://jsfiddle.net/27veyw1d/

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/

Datalabel placement - Opposite of of chart data (positive and negative values)

I'm creating a bar chart with positive and negative values and display the xAxis (category name) of each data point (See Fiddle: https://jsfiddle.net/bej8j/75/).
Here's what I have for plot options but I'm not sure what else I need (Really only putting this code in here because I need to include some code to link to a jsfiddle)
plotOptions : {
series : {
dataLabels: {
formatter: function() {
return this.x
},
enabled: true
}
}
},
I'm trying to place the label so that it's aligned with the start of each bar on the chart. I photoshoped my desired result: http://i.imgur.com/0I1jSHW.png
Any help would be greatly appreciated.
You can iterate on each datalabel and use translate() function to move SVG element.
http://jsfiddle.net/eMjGg/7/
$.each(chart.series[0].data,function(i,data){
position = chart.yAxis[0].toPixels(0);
console.log(data);
if(data.y < 0)
position-=10;
else
position-=70;
data.dataLabel.attr({
x:position
});
});
I think this would help you: http://jsfiddle.net/42dRt/5/
Here's more info: high-charts datalabel position needs to change when value is too small
You must play with the X value:
plotOptions : {
series : {
dataLabels: {
formatter: function() {
return this.x
},
x: ?,
enabled: true
}
}
}

Resources