Centering labels in pie. Highcharts - highcharts

I have the following pie chart: http://jsfiddle.net/wjqrh/76/
new Highcharts.Chart({
chart: {
renderTo: 'f-chart-container',
type: 'pie',
backgroundColor: 'rgba(255, 255, 255, 0)'
},
title: {
text: ''
},
plotOptions: {
pie: {
shadow: true,
dataLabels: {
formatter: function () {
return '<span style="color: ' + this.point.color + '; font-weight: bold; font-size: 115%">'
+ this.point.percentage.toFixed(1)
+ '%</span>';
},
distance: 3,
connectorWidth: 0,
x: 0,
y: 0
}
}
},
tooltip: {
formatter: function () {
return '<b>' + this.point.name + '</b>: '
+ this.point.y
}
},
series: [
{
name: '',
data: data,
size: '73%',
innerSize: '50%',
showInLegend: false
}
],
colors: colors
});
The label of the violet sector is placed somewhere right but I would like to place it exactly in the center, like the third (green) sector's label is displayed.
The same label positioning thing is happening with orange and cyan sectors.
How can I force to place labels in the center of the sector?

Only what comes to my mind is using translate() function, which allows to move SVG elements.
http://jsfiddle.net/wjqrh/77/
chart.series[0].data[5].dataLabel.translate(275,520);

Related

How can I move the datalabel in top right in variable pie chart

How can I move the below datalabel football in the top right of the variable pie chart instead of showing in bottom. I tried these options
alignTo: 'connectors' or alignTo: 'toPlotEdges'
But nothing worked for me. Any help will be appreciated
var total = 80;
Highcharts.chart('container', {
chart: {
type: 'variablepie',
height: 370,
marginBottom: 50
},
credits: {
enabled: false
},
title: {
text: 'Football vs cricket',
align: 'center',
y: -5,
verticalAlign: 'bottom',
style: {
fontFamily: 'proxima_nova_bold',
fontSize: '20px',
fontWeight: 'normal',
color: '#8d99ab',
}
},
subtitle: {
text: ' ' + total + '<br/> Total',
useHTML: true,
verticalAlign: 'middle',
y: -20
},
xAxis: {
labels: {
rotation: 0
}
},
plotOptions: {
variablepie: {
size: 220,
dataLabels: {
enabled: true,
connectorColor: '#979797',
useHTML: true,
formatter: function () {
var key;
if(this.key == 'football'){
key = 'as football / Lionel Messi';
}else if(this.key == 'cricket'){
key = 'as cricket / Sachin Tendulkar';
}else{
key = this.key;
}
return '<span class=cls1>' + this.y + '</span>' + '<span class=cls2>' + key + '</span>';
}
},
showInLegend: true,
}
},
tooltip: {
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.y +' %';
}
},
legend: {
enabled: false
},
series: [{
minPointSize: 10,
innerSize: '70%',
zMin: 0,
data: [{name: "football", y: 71, z: 30}, {name: "cricket", y: 2, z: 18}]
}]
});
https://jsfiddle.net/anikettiwari/Lr3zy8qc/2/
You can try to implement one of the options showed here: https://www.highcharts.com/docs/advanced-chart-features/pie-datalabels-alignment
Or use the render callback and set the y position of this particular label manually.
Demo: https://jsfiddle.net/BlackLabel/2oskhmnd/
events: {
render() {
let chart = this;
chart.series[0].points[0].dataLabel.attr({y: 10});
chart.series[0].points[0].connector.hide();
}
}
Unfortunately, this solution requires to render the custom connector to moved dataLabel. You can do it by using some of the methods shown in the above link (pie-datalabels-alignment) or by using SVGRenderer tool to render a path: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#path
API: https://api.highcharts.com/highcharts/chart.events.render

Highcharts - Ignore Series in Pie Percentage

I have a series that I would like to be ignored in the percentage calculation of a pie chart but still be shown/hidden when the legend item is clicked. The series represents the total and should always be 100%. If I set visible to false for the series it is initially hidden in the chart and the legend item is greyed out. However, clicking the legend item shows the series with the calculated percentage. It seems like I need another series behind the values I would like to be calculated and displayed, that's always 100%, any ideas?
Thanks!
Chart Config
vm.installationResultsConfig = {
options: {
exporting: {
type: 'application/pdf',
filename: 'installation-results'
},
credits: {
enabled: false
},
navigation: {
buttonOptions: {
enabled: false
}
},
chart: {
backgroundColor: '#F9F9F9',
borderColor: '#eee',
plotBackgroundColor: null,
plotBorderWidth: 0,
plotShadow: false,
height: 440
},
title: {
text: 'Installation Results',
align: 'center',
verticalAlign: 'top'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
dataLabels: {
enabled: false
},
startAngle: 0,
endAngle: 360,
center: ['50%', '55%'],
showInLegend: true
}
},
legend: {
align: 'left',
verticalAlign: 'middle',
layout: 'vertical',
x: -8,
y: 30,
labelFormatter: function () {
if(this.name === 'All Vehicles') {
this.percentage = 100;
}
return '<span>' + this.name + '</span><br />' +
'<span>' + this.dataLabels.count + '</span><br />' +
'<span>' + $filter('number')(this.percentage) + '%</span>';
},
useHTML: true,
itemMarginTop: 5,
itemMarginBottom: 5
}
},
series: [{
type: 'pie',
name: 'Installation Results',
innerSize: '70%',
data: [
{
name: 'All Vehicles', // should be ignored and alway render as 100%
y: chartData.allVehicles,
color: '#999999',
dataLabels: {
count: $filter('number')(chartData.allVehicles)
}
},
{
name: 'Successful',
y: chartData.successful,
color: '#50CF63',
dataLabels: {
count: $filter('number')(chartData.successful)
}
},
{
name: 'Failed',
y: chartData.failed,
color: '#F22F1D',
dataLabels: {
count: $filter('number')(chartData.failed)
}
},
{
name: 'Not Attempted',
y: chartData.notAttempted,
color: '#296499',
dataLabels: {
count: $filter('number')(chartData.notAttempted)
}
}
]
}]
};
The percentage property will affect all pie slices in series. In that situation, you can create custom percentage property, which will be calculated based only on visible slices that are not 'All Vehicles' slice. Take a look at the example below. Also, I think that the labelFormatter function is not the right place to make calculations but I only wanted to show you the idea.
Example:
http://jsfiddle.net/g1hw761h/

Highcharts column graph custom legend formatting not showing legend symbols

I'm trying to create a simple column chart using Highcharts. I want to be able to show legends at the bottom with legend symbols having same color as bars followed by the value and category. For some reason, I only see the first legend symbol. Here is the source https://jsfiddle.net/DeanSharma/gjbfj0rg/
$(function() {
var categories = ["Open","Expire within 90 days","In Progress","Past"],
colors = ["#1097ae","#81cbd6","#b4d66c","#317fc2"],
data = [9,13,7,8];
var chartData = [{y: 9, color: '#1097ae', name: 'Open'}, {y: 13, color: '#81cbd6', name: 'Expire within 90 days'}, {y: 7, color: '#b4d66c', name: 'In Progress'}, {y: 8, color: '#317fc2', name: 'Past'}];
var customLegend = '<div class="legend" style="vertical-align: bottom; background-color: transparent">';
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
height: 400,
marginBottom: 100,
align: 'top'
},
title: {text:'My Custom Column Chart', align:'center', style:{"font-size":'14px',"color":'#0000ff'}},
colors: colors,
legend: {
align: 'center',
enabled: true,
floating: true,
symbolWidth: 0,
labelFormatter: function() {
for(index=0; index< categories.length; index++) {
customLegend += '<div style="background-color:' + colors[index] + ' ; width:12px; height:12px;"></div>';
customLegend += '<div class="legend__value">' + data[index] + ' </div>';
customLegend += '<div class="legend__name">' + categories[index] + ' </div>';
customLegend += '<br />';
};
customLegend += '</div>';
return customLegend;
},
layout: 'horizontal',
verticalAlign: 'bottom',
y: 10
},
credits: {enabled: true, text: 'Courtesy DeanS', href:'stackoverflow.com'},
xAxis: {
categories: categories,
labels: {autoRotation: false,
style: {color: '#777',fontFamily: 'Open Sans',fontSize: '10px'}
},
lineColor: '#f8f8f8',
tickColor: '#f8f8f8'
},
yAxis: {
title: {
text: '',
useHTML: true
}
},
series: [{
data: chartData
}]
});
});
To achieve that result you do not need a custom legend. You can split your points into seperate series, disable grouping and then in the label formatter - return the point's value and the category.
plotOptions: {
series: {
grouping: false
}
},
series: data.map((point, i) => {
return {
data: [
[i, point]
]
}
})
Legend config:
legend: {
labelFormatter: function() {
return data[this.index] + ' ' + categories[this.index];
},
layout: 'vertical',
},
example: https://jsfiddle.net/gjbfj0rg/1/

How do you add text to the bottom center of legend and bottom center of chart under legend?

I have a custom HighCharts that have totals in the legend. I need to add one line of custom text centered under the totals "in the legend". Also I need to add text center at the bottom of the chart "under the legend".
See fiddle:
http://jsfiddle.net/no1uknow/cvsTB/
[EDIT]
I did figure this much out but don't know how to get text centered under legend.
http://jsfiddle.net/no1uknow/cvsTB/1/
$(function () {
var chart;
$(document).ready(function() {
var container_chartFreqAtaTailNum = new Highcharts.Chart({
chart: {
renderTo: 'container_chartFreqAtaTailNum',
type: 'bar',
height: 795
},
title: {
text: 'Frequency by Tail Number'
},
subtitle: {
text: 'Fact ATA (25)'
},
xAxis: {
categories: ['235','245','402','411','432','442','493','703','714','720','730','745','756','767','772','792'],
title: {
text: 'Tail Number'
},
labels: {
style: {
width: '12000px'
}
}
},
yAxis: {
min: 0,
title: {
text: 'Count',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
tooltip: {
formatter: function() {
return ''+ this.series.name +': '+ this.y +' Count';
}
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
},
series: {
pointWidth:10,
groupPadding: .05,
shadow: true
}
},
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom',
floating: false,
borderWidth: 1,
backgroundColor: '#FFFFFF',
shadow: true,
labelFormatter: function() {
return '<div class="' + this.name + '-arrow"></div><span style="font-family: \'Advent Pro\', sans-serif; font-size:12px">' + this.name +'</span><br/><span style="font-size:10px; color:#ababaa"> Total: ' + this.options.total + '</span>';
}
},
credits: {
enabled: false
},
exporting: {
enabled: true
},
series: [{
name: 'Heavy',
total: '5421',
data: [117,102,698,640,251,115,269,279,260,309,328,427,316,754,239,317]
},{
name: 'Intermediate',
total: '4888',
data: [299,169,448,532,210,256,241,295,226,368,319,420,272,243,313,277]
},{
name: 'Line',
total: '659',
data: [29,38,50,47,33,27,22,67,57,44,36,53,41,37,35,43]
},{
name: 'Lite',
total: '2172',
data: [101,116,139,124,123,139,148,249,168,141,122,136,91,154,105,116]
}]
});
});
});
spacingBottom is what you need to add, and also you need to take care of the offset:
chart: {
events: {
load: function () {
var label = this.renderer.label("How do I move this center and under the legend.")
.css({
width: '450px',
color: '#222',
fontSize: '16px'
})
.attr({
'stroke': 'silver',
'stroke-width': 2,
'r': 5,
'padding': 10
})
.add();
label.align(Highcharts.extend(label.getBBox(), {
align: 'center',
x: 0, // offset
verticalAlign: 'bottom',
y: 50 // set the right offset
}), null, 'spacingBox');
}
},
renderTo: 'container_chartFreqAtaTailNum',
type: 'bar',
height: 895,
spacingBottom: 100 // The space between the bottom edge of the chart and the content (plot area, axis title and labels, title, subtitle or legend in top position).
}
Here is the fiddle: http://jsfiddle.net/uMBHf/1/

Highcharts Legend styles no longer rendering correctly

I have had these charts built for a couple months, and just today the styles of the legend seem to have shifted about 150px to the left. They were just right-aligned from the pie chart but now render directly over the top of the pie chart and I am unable to figure out why. I can add inline styles to the div's I am creating with margins and padding but that doesn't justify the colored boxes on the legend that correspond with each pie slice. My code/styles have not changed and I do believe this is a functionality issue. Here is my code;
Any help is appreciated.
var options = {
chart:{type:'pie',
renderTo: 'ctl00_ContentPlaceHolder1_Overview1_AssetCategoryChart',
events: {
load: function(event) {
$('#ctl00_ContentPlaceHolder1_Overview1_AssetCategoryChart .highcharts-legend-item').last().append('<br/><div style="width: 200px; margin-left: 170px; height: 2px;">_____</div><br/><div style="width:200px; height: 10px;"><span style="float:right"><b>100%</b></span> </div>');
}
},
spacingTop: 0,
marginTop: 0
},
credits:{enabled: false},
colors:[
'#5485BC', '#AA8C30', '#5C9384', '#981A37', '#FCB319', '#86A033', '#614931', '#00526F', '#594266', '#cb6828', '#aaaaab', '#a89375'
],
title:{text: null},
tooltip:{
enabled: true,
animation: true,
formatter: function(){
return this.point.name + '<br/>' + this.y.toFixed(2) + '%';
}
},
plotOptions: {
pie: {
allowPointSelect: true,
animation: true,
cursor: 'pointer',
showInLegend: true,
dataLabels: {
enabled: false,
formatter: function() {
return this.y.toFixed(2) + '%';
}
}
}
},
legend: {
enabled: true,
layout: 'vertical',
align: 'right',
width: 200,
verticalAlign: 'top',
borderWidth: 0,
useHTML: true,
itemMarginBottom: 4,
labelFormatter: function() {
return '<div style="width:180px; margin-left: 150px;"><span style="float:left">' + this.name + '</span><span style="float:right">' + this.y.toFixed(2) + '%</span></div>';
},
title: {
text: 'Category',
style: {
fontWeight: 'bold'
}
}
},
series: [{
type: 'pie',
dataLabels:{
},
data: [
['Real Estate', 12.55],
['Large-Cap Growth', 12.34],
['Foreign Large-Cap Blend', 12.19],
['Large-Cap Value', 7.51],
['Emerging Markets', 6.51],
['Health',5.59],
['Cash Equivalents',5.23],
['Foreign Large-Cap Value',4.02],
['Large-Cap Blend',3.95],
['World Allocation',3.55],
['Mid-Cap Growth',3.29],
['Remaining', 23.30]
]
}]
}

Resources