Related
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
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/
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/
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;
}
}
}]
});
});
});
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();
}