I want to display the datatable inside Pie chart using Highcharts.I can display the table outside but on exporting the image, datatable is not exported.
So my aim is to display datatable inside the Pie chart.
Refering to this.I was able to partly acheive it.demo
But how can i give the column headers and borders to it?
$(function () {
Highcharts.drawTable = function() {
// user options
var tableTop = 200,
colWidth = 60,
tableLeft = 50,
rowHeight = 20,
cellPadding = 2.5,
valueDecimals = 1,
valueSuffix = '';
// internal variables
var chart = this,
series = chart.series,
renderer = chart.renderer,
cellLeft = tableLeft;
// draw category labels
$.each(series, function(serie_index, serie) {
renderer.text(
serie.name,
cellLeft + cellPadding,
tableTop + (serie_index + 1) * rowHeight - cellPadding
)
.css({
fontWeight: 'bold'
})
.add();
});
$.each(series[0].data, function(i) {
renderer.text(
series[0].data[i].name,
cellLeft + colWidth - cellPadding,
tableTop + (i + 2) * rowHeight - cellPadding
)
.attr({
align: 'right'
})
.add();
});
$.each(series[0].data, function(i) {
renderer.text(
Highcharts.numberFormat(series[0].data[i].y, valueDecimals) + valueSuffix,
150,
tableTop + (i + 2) * rowHeight - cellPadding
)
.attr({
align: 'left'
})
.add();
});
}
$('#container').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
events: {
load: Highcharts.drawTable
},
height: 600,
width: 800,
marginBottom: 250
},
title: {
text: 'Browser market shares at a specific website, 2010'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
format: '<b>{point.name}</b>: {point.percentage:.1f} %'
}
}
},
series: [{
type: 'pie',
name: 'Browser share',
data: [
['Firefox', 45.0],
['IE', 26.8],
{
name: 'Chrome',
y: 12.8,
sliced: true,
selected: true
},
['Safari', 8.5],
['Opera', 6.2],
['Others', 0.7]
]
}]
});
});
For the column headers, I don't know. Depends on what you want to do.
As for the borders, since that's SVG, you could draw the borders using RECT and PATH. Take a look at this fork of your demo for some crude borders and maybe you can improve on it.
Related
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
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/
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/
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/
I am using Area chart with navigator, what I am trying to do is highlight high and Low point markers (only two points ) in the current visible chart, and on top of these markers I want to display fixed tooltips displaying the point information.
And as user navigates through navigator these point markers should be recalculated and tooltips should follow them.
[This is what I am trying to accomplish][1]
So far I have been able to calculate high and low points and highlight corrosponding markers in chart, and I have also been able to display two tooltips, but they are not ACURATELY positioned along with point markers.
![So far this has been accomplished][2]
Here is my Code:
function customTooltip(point) {
console.log(chart);
var text = chart.renderer.text(
'Max',
point.plotX + chart.plotLeft + 10,
point.plotY + chart.plotTop - 10
).attr({
zIndex: 5
}).add();
var box = text.getBBox();
chart.renderer.rect(box.x - 5, box.y - 5, box.width + 10, box.height + 10, 5)
.attr({
fill: '#FFFFEF',
stroke: 'gray',
'stroke-width': 1,
zIndex: 4
})
.add();
}
var labelArr = [], // keeps Tooltips for High and Low
chart = $('#container').highcharts('StockChart', {
chart: {
type: 'line',
width: 900
},
scrollbar: {
enabled: false
},
navigator: {
top: -1,
height: 25,
handles: {
backgroundColor: 'transparent',
borderColor: 'transparent'
}
},
rangeSelector: {
inputPosition: {
align: 'left',
x: 10,
y: 30
},
buttons: [{
type: 'year',
count: 1,
text: ''
}],
buttonTheme: { // styles for the buttons
fill: 'none',
stroke: 'none',
'stroke-width': 0,
states: {
hover: {
fill: 'none'
},
select: {
fill: 'none'
}
}
},
inputDateFormat: '%m-%d-%Y',
inputStyle: {
fontSize: '14px',
borderColor: '#FFF'
},
selected: 0
},
yAxis: {
labels: {
align: 'right',
x: -5,
formatter: function () {
return "$" + this.value;
}
}
},
xAxis: {
type: 'datetime',
tickWidth: 0,
labels: {
y: 20
},
dateTimeLabelFormats: {
month: '%B'
},
events: {
setExtremes: function () {
var pointMax, pointMin, labelLength = labelArr.length;
// Flush out Old Tooltips for High and Low
if (labelLength > 0) {
for (var i = 0; i < labelLength; i++) {
var popVal = labelArr.pop();
this.chart.container.firstChild.removeChild(popVal);
}
}
$.each(this.series[0].points, function (i, point) {
if (!pointMax && !pointMin) pointMax = pointMin = point;
// If marker is enabled for any point, disable it
if (typeof point.marker != 'undefined') point.marker.enabled = false;
// Calculate Highest point
if (pointMax.y < point.y) pointMax = point;
// Calculate Lowest point
if (pointMin.y > point.y) pointMin = point;
});
pointMax.update({
marker: {
enabled: true
}
}, false, false);
//customTooltip( pointMax );
pointMin.update({
marker: {
enabled: true
}
}, false, false);
//customTooltip( pointMin );
}
}
},
tooltip: {
crosshairs: false
/*useHTML: true,
borderRadius: 0,
backgroundColor: '#000',
shadow: false,
borderWidth: 0,
enabled: true,
formatter: function(){
/* Temp Disable Custom tool-Tip
var arr = [];
$.each(this.points, function(k, obj){
arr.push( "<span style='color:#FFF'>Low price w/o sales charge</span>" );
arr.push( "<br>" );
arr.push( "<span style='font-weight:bold;color:#FFF'>$" + obj.y + "</span>" );
arr.push( "<br>" );
});
return arr.join(' ');
} */
},
plotOptions: {
area: {
marker: {
fillColor: '#f7941e',
states: {
hover: {
enabled: false
}
}
}
},
series: {
point: {
events: {
update: function (event) {
event.target.series.chart.tooltip.refresh([event.target]);
var cloneToolTip = event.target.series.chart.tooltip.label.element.cloneNode(true);
event.target.series.chart.container.firstChild.appendChild(cloneToolTip);
labelArr.push(cloneToolTip);
}
}
}
}
},
series: [{
name: 'Quarterly Returns w/o sales charge',
data: [
[1149120000000, 62.17],
[1149206400000, 61.66],
[1369699200000, 441.44],
[1369785600000, 444.95]
]
// pointWidth: 14,
}]
}).highcharts();
});
Can you please guide me on how to proceed from here?