How to open multiple level drilldown in highcharts programatically? - highcharts

I have this code for my chart
angular.module('myModule', []).service("CompOffLeaveService", function ($http) {
this.getdata = function () {
return $http({
method: "post",
url: "/Dashboard/GetCompOffLeaveReport",
params: [{ YearID: $("#YearIn option:selected").text() }],
dataType: "json"
});
};
}).controller('myController', function (CompOffLeaveService) {
GetAlldata();
function GetAlldata() {
var getCompOffLeaveData = CompOffLeaveService.getdata();
getCompOffLeaveData.then(function (NoOfLeaves) {
var myData = new Array();
for (var j = 0; j < NoOfLeaves.data.TeamNames.length; j++) {
debugger;
if (NoOfLeaves.data.TeamNames[j] != null) {
myData[j] = [
NoOfLeaves.data.TeamNames[j],
NoOfLeaves.data.TeamWiseCompOffLeaves[j]
];
}
else { break; }
}
var mySeries = [];
for (var i = 0; i < myData.length; i++) {
mySeries.push({ name: myData[i][0], y: myData[i][1], drilldown: true });
}
Highcharts.chart('container', {
chart: {
type: 'column'
},
credits: {
enabled: false
},
title: {
text: 'Comp Off Leave Report' + ' ' + $("#YearIn option:selected").text()
},
xAxis: {
type: 'category'
},
yAxis: {
title: {
text: 'Total CompOffLeave Recorded'
}
},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
format: '{point.y}COL'
}
}
},
tooltip: {
headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y} COL</b> in total<br/>',
},
series: [{
name: 'Team',
colorByPoint: true,
data: mySeries
}],
drilldown: {
series: []
}
});
}, function () {
alert('Error in getting records');
});
} $("#btnLoad").click(function (event) {
GetAlldata();
});
$("#btnBack").click(function (event) {
window.location.href = "home";
});
$(function () {
$("#draggable").draggable({ axis: "y", containment: "#parent", scroll: false, revert: true });
$("#resizable").resizable();
});
});
it is working perfectly well and gives me this output
what I want is to open a drilldown on any column click which will be having all months of the year e.g:
and on further drilldown I want this.e.g:
I can pass the data then..but drilldown is not getting open.

Related

How to sort order highchart pie jasperstudio by slice value min to max

I am working on jasper but i don't want to sort the data in the query as many other element of the report using the same query.
So i would like to sort it on the pie chart itself as example on this fiddle http://jsfiddle.net/highcharts/3bDMe/1/. How can it be done without button click? I meant as the chart load it automatically sort by slice value ascending.
$(function () {
$(document).ready(function () {
// Build the chart
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: 'Browser market shares at a specific website, 2010'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage}%</b>',
percentageDecimals: 1
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
},
series: [{
type: 'pie',
name: 'Browser share',
data: [
['Firefox', 45.0],
['IE', 6.8],
{
name: 'Chrome',
y: 12.8,
sliced: true,
selected: true
},
['Safari', 88.5],
['Opera', 26.2],
['Others', 30.7]
]
}]
});
$('#sort').click(function() {
chart.series[0].data.sort(function(a, b) {
return b.y - a.y;
});
var newData = {};
for (var i = 0; i < chart.series[0].data.length; i++) {
newData.x = i;
newData.y = chart.series[0].data[i].y;
newData.color = Highcharts.getOptions().colors[i];
chart.series[0].data[i].update(newData, false);
// Workaround:
chart.legend.colorizeItem(chart.series[0].data[i], chart.series[0].data[i].visible);
}
chart.redraw({ duration: 2000 });
});
});
});
In the load event you can create a new data array with sorted values and use setData method to apply changes:
chart: {
...,
events: {
load: function() {
var data = this.series[0].data,
newData = [];
data.forEach(function(point) {
newData.push({
y: point.y,
name: point.name
})
});
newData.sort(function(a, b) {
return a.y - b.y;
});
this.series[0].setData(newData);
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/6vzd8ak7/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Series#setData

Highchart hide a category and rescale is messing

I'm trying to draw a chart where categories can be filtered, and it's working pretty nicely, I used this to do it.
Problem is : my last category is the total of the others, and so is taller. I want that when the "total" checkbox is unchecheck the chart resize, but it doesn't and resize only if I also uncheck the "class7" checkbox.
you can try it here : https://jsfiddle.net/4rfdgvum/
var chart=null;
$(function() {
var chart = new Highcharts.Chart('container', {
chart: {
type: 'column',
shadow: true
},
title: {
text: 'My Title'
},
xAxis: {
categories: [{"class":"class1","name":"cat1"},{"class":"class2","name":"cat2"},{"class":"class3","name":"cat3"},{"class":"class4","name":"cat4"},{"class":"class5","name":"cat5"},{"class":"class6","name":"cat6"},{"class":"class7","name":"cat7"},{'class': 'total','name':'total'}],
labels: {
formatter: function() {
return this.value.name;
},
useHTML: true
}
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Numbers'
}
},
legend: {
enabled: true
},
tooltip: {
formatter: function () {
return '<b>' + this.x.name + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
formatter: function(){
return Highcharts.numberFormat(this.percentage,0) + '%';
}
}
}
},
series: [{
name: 'Ok',
color: 'green',
stack: 'a',
data: [
223,174,139,27,17,6,3,589 ]
},
{
name: 'Not Ok',
color: 'red',
stack: 'a',
data: [
21,29,26,14,15,11,11,127 ]
},
{
name: 'Partialy Ok',
color:'orange',
stack: 'a',
data: [
5,11,25,1,1,3,0,46 ]
},
{
name: 'Not usable',
color:'grey',
stack: 'a',
data: [
20,70,67,160,163,170,168,818 ]
},
{
name: 'Not done',
color:'brown',
stack: 'a',
data: [
173,158,185,240,246,252,260,1514 ]
}
]
}, function() {
$('input[type=checkbox]').bind('click', function() {
togglePointsByClass(this.value, $(this).is(':checked'), chart)
});
});
var visibleArr = [0,1,2,3,4,5,6,7];
function togglePointsByClass(className, shouldShow, chart) {
var isChartDirty = false;
if (shouldShow) {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className) {
visibleArr.push(i);
}
});
} else {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className && visibleArr.indexOf(i) > -1) {
visibleArr.splice(visibleArr.indexOf(i), 1);
}
});
}
if (visibleArr.length) {
chart.xAxis[0].update({
min: Math.min.apply(null, visibleArr),
max: Math.max.apply(null, visibleArr)
})
}
}
$('#container').highcharts().redraw();
});
Thanks
You can use axis.setExtremes() for setting max of the yAxis.
if (visibleArr.length) {
chart.xAxis[0].update({
min: Math.min.apply(null, visibleArr),
max: Math.max.apply(null, visibleArr)
}, false, false);
const max = visibleArr.reduce((a, b) => Math.max(chart.yAxis[0].stacks.columna[b].total, a), -Infinity)
chart.yAxis[0].setExtremes(0, max);
}
example: https://jsfiddle.net/mw7euo1a/

Can we set bar labels with dynamic custom array in Highcharts?

I think this is bug in the library.
I want a custom labels on each bar, but it is not working!
var options = {
chart: {
type: 'column'
},
plotOptions: {
series: {
stacking: 'normal',
dataLabels: {
enabled: true,
formatter: function() {
if (this.series.options.myLabels) {
return "XXX: " + this.series.options.myLabels[this.point.x];
}
}
}
}
},
exporting: {
url: 'http://export.highcharts.com/',
chartOptions: {
yAxis: {
labels: {
style: {
color: 'green'
}
}
}
}
},
yAxis: {
labels: {
style: {
color: 'red'
},
format: '{value:,.0f}'
}
},
series: [{
type: 'column',
data: [10000, 20000, 8000],
myLabels: ["A", "B", "C"]
}, {
type: 'column',
data: [10000, 2000, 10000]
}, {
type: 'spline',
data: [5000, 15000, 5000]
}
]
};
var globals = {
lang: {
thousandsSep: ','
}
}
$('#export').click(function() {
var obj = {},
exportUrl = options.exporting.url;
obj.options = JSON.stringify(options);
obj.globaloptions = JSON.stringify(globals);
obj.type = 'image/png';
obj.async = true;
$.ajax({
type: 'post',
url: exportUrl,
data: obj,
success: function(data) {
var imgContainer = $("#imgContainer");
$('<img>').attr('src', exportUrl + data).attr('width', '450px').appendTo(imgContainer);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="export">get image</button>
<div id="imgContainer"></div>
JSON is not a bug, because you cannot place the function inside the json. Functions are not executable and are skipped. So you need to use the callback and there place your function in series.update();
Fixed demo:
- http://jsfiddle.net/ayyunrb4/

Highcharts donut hover all area

I created a Pie Donut chart with highcharts, it works well. Now what I want to do is when I hover an area, I want to highlight its parents and children and also to have all their data in the tooltip.
Here is my chart :
https://jsfiddle.net/whoknows/q9srL6o7/2/
And here is what I'd like to do :
http://i.imgur.com/AMr42dO.png
Thanks.
It is possible to use setState in mouseOver and mouseOut events of points to set hover state for multiple points. Tooltip formatter can also display multiple points that will match criteria. I have added hoverGroup variable to each point to find those points for setting states and for tooltip.
Example: http://jsfiddle.net/q9srL6o7/4/
$(function () {
var chart;
$(document).ready(function () {
var colors = ["#00bcd4", "#00838f", "#69f0ae", "#f4511e", "#d81b60", "#1e88e5"],
categories = ['Site #1', 'Site #2', 'Site #3', 'Site #4', 'Site #5'],
data = [{
y: 55.11,
color: colors[0],
drilldown: {
name: 'Site #1',
categories: ['Leisure', 'Business'],
data: [45.01, 10.1],
drilldown: {
name: 'In/Out',
categories: ['In', 'In', 'Out', 'Out'],
data: [32.97, 12.04, 6.1, 4]
}
}
}, {
y: 21.63,
color: colors[1],
drilldown: {
name: 'Site #2',
categories: ['Leisure', 'Business'],
data: [13.12, 8.51],
drilldown: {
name: 'In/Out',
categories: ['In', 'In', 'Out', 'Out'],
data: [8.53, 4.59, 3.12, 5.39]
}
}
}, {
y: 11.94,
color: colors[2],
drilldown: {
name: 'Site #3',
categories: ['Leisure', 'Business'],
data: [9.91, 2.03],
drilldown: {
name: 'In/Out',
categories: ['In', 'In', 'Out', 'Out'],
data: [5.91, 4, 1, 1.03]
}
}
}, {
y: 7.15,
color: colors[3],
drilldown: {
name: 'Site #4',
categories: ['Leisure', 'Business'],
data: [4.55, 2.6],
drilldown: {
name: 'In/Out',
categories: ['In', 'In', 'Out', 'Out'],
data: [4, 0.55, 0.75, 1.85]
}
}
}, {
y: 4.17,
color: colors[4],
drilldown: {
name: 'Site #5',
categories: ['Leisure', 'Business'],
data: [2.49, 1.68],
drilldown: {
name: 'In/Out',
categories: ['In', 'In', 'Out', 'Out'],
data: [1.46, 1.03, 0.45, 1.23]
}
}
}],
siteData = [],
trafficData = [],
inoutData = [],
inoutColors = ['#faba59', '#f79f45', '#8cd260', '#5cc064'];
for (var i = 0; i < data.length; i++) {
siteData.push({
name: categories[i],
y: data[i].y,
color: data[i].color,
hoverGroup: i
});
for (var j = 0; j < data[i].drilldown.data.length; j++) {
trafficData.push({
name: data[i].drilldown.categories[j],
y: data[i].drilldown.data[j],
color: j === 0 ? '#f06e4a' : '#36a061',
hoverGroup: i
});
}
for (var k = 0; k < data[i].drilldown.drilldown.data.length; k++) {
inoutData.push({
name: data[i].drilldown.drilldown.categories[k],
y: data[i].drilldown.drilldown.data[k],
color: inoutColors[k],
hoverGroup: i
});
}
}
// Create the chart
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'pie'
},
showInLegend: false,
legend: {
enabled: false
},
credits: {
enabled: false
},
title: {
enabled: false,
text: ''
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
pie: {
shadow: false,
point: {
events: {
mouseOver: function () {
var hoverGroup = this.hoverGroup,
series = this.series.chart.series;
$.each(series, function (i, s) {
$.each(s.points, function (j, p) {
if (p.hoverGroup == hoverGroup) p.setState('hover');
});
});
},
mouseOut: function () {
var series = this.series.chart.series;
$.each(series, function (i, s) {
$.each(s.points, function (j, p) {
p.setState('');
});
});
}
}
}
}
},
tooltip: {
valueSuffix: '',
formatter: function () {
var ret = '',
once = true,
hoverGroup = this.point.hoverGroup,
series = this.series.chart.series;
$.each(series, function (i, s) {
$.each(s.points, function (j, p) {
if (p.hoverGroup == hoverGroup) {
ret = '<span style="color:' + p.color + ';">●</span> ' + p.name + ' :' + p.y + '<br/>' + ret;
}
});
});
return ret;
}
},
series: [{
name: 'In/Out',
data: inoutData,
size: '85%',
innerSize: '20%',
dataLabels: {
formatter: function () {
return null;
}
}
}, {
name: 'Type de trafic',
data: trafficData,
size: '90%',
innerSize: '85%',
dataLabels: {
formatter: function () {
return null;
}
}
}, {
name: 'Site',
data: siteData,
size: '100%',
innerSize: '90%',
dataLabels: {
formatter: function () {
return null;
}
}
}]
});
});
});

Highcharts Combo graphs with common legend click

I have a combo graphs, with Pie and Bar Graph, now my problem is that I want pie chart and bar graph both controlled from the same legend, as status are the same... source example created a JS fiddle any help would be much appreciated.
http://jsfiddle.net/TV8f4/
$(document).ready(function () {
var Loveralldata = [0,1,1,0,0,5];
var LDNOKdata = [['1032',11],['1040',0]];
var LDOKONOKdata = [['1032',1],['1040',0]];
var LDOKOOKdata = [['1032',1],['1040',0]];
var LTBDdata = [['1032',1],['1040',0]];
var LNAdata = [['1032',1],['1040',0]];
var LNUAdata = [['1032',4],['1040',8]];
var LCatData = ['Delhi HO','Regional Offices'];
$('#location').highcharts({
chart: {
//events: {
// click: function (event) {
// alert('hide');
// }
//}
},
credits: {
enabled: false
},
title: {
text: 'Location chart'
},
xAxis: {
categories: LCatData
},
yAxis: {
maxPadding: 1.5
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
alert(this.options.name);
}
}
}
}
},
tooltip: {
formatter: function () {
var s;
if (this.point.name) { // the pie chart
s = '' +
this.series.name + ': ' + this.y ;
} else {
s = '' +
this.category + ' ' + this.x + ': ' + this.y;
}
return s;
}
},
colors: ['#367A01', '#00D700', '#FFD700', '#D9D9D9', '#F4FA58', '#757873'],
labels: {
items: [{
style: {
left: '40px',
top: '8px',
color: 'black'
}
}]
},
series: [{
type: 'column',
name: 'Adequate and Effective',
data: LDOKOOKdata
}
, {
type: 'column',
name: 'New Remediation Plans',
data: LDOKONOKdata
}, {
type: 'column',
name: 'New Controls',
data: LDNOKdata
},
{
type: 'column',
name: 'Not Updated/Approved ',
data: LNUAdata
},
{
type: 'column',
name: 'NA',
data: LNAdata
}
, {
type: 'column',
name: 'To Be Deleted',
data: LTBDdata
}
, {
type: 'pie',
name: 'Overall Status',
data: [['Adequate and Effective', Loveralldata[2]], ['New Remediation Plans', Loveralldata[1]], ['New Controls', Loveralldata[0]], ['Not Updated/Approved', Loveralldata[5]], ['NA', Loveralldata[3]], ['To Be Deleted', Loveralldata[4]]],
center: [100, 50],
size: 150,
showInLegend: false,
dataLabels: {
enabled: false
}
}]
});
});
You can use legendItemClick event and then hide element with series index in pie chart like here http://jsfiddle.net/TV8f4/3/
legendItemClick:function(){
var index = this.index,
chart = this.chart,
series = chart.series,
len = series.length,
pieSerie = series[len-1];
pieSerie.data[index].setVisible();
}

Resources