Reputation: 4125
The data which I have is formatted like this:
[{"name":"project1","data":[50291,7410,2013,2013,524,201]},{"name":"project2","data":[1776995,758630,25633,4120054,24521,2045]}]
The cateogries on the xAxis of my highchart are:
['%50', '%60', '%70', '%80', '%90', '%95']
My code right now shows a bar chart with the categories on the xAxis and the different projects's values in each catergory. What I would like to have are relative percentages. What is mean, is there a way that per category I detemine the highest value, set that value to 100% and place the other values in that category relative to this 100%?
I have tried a couple of this, but no luck yet. And I also can't find a good example of this.
The code I have now, accepts the absoulte values and stacks the values, but this isn't what I would like.
I will include my code
$(function () {
var options = {
chart: {
renderTo: 'container_2',
type: 'column',
options3d: {
enabled: true,
alpha: 0,
beta: 0,
depth: 0,
viewDistance: 25
}
},
title: {
text: 'Data'
},
subtitle: {
text: 'Dataset'
},
plotOptions: {
column: {
stacking: 'percent'
}
},
series: [{name: '', data: []}],
xAxis: {
categories: ['%50', '%60', '%70', '%80', '%90', '%95']
},
yAxis: {
/* Other things */
labels: {
formatter: function(){
return 100 * this.value / $(this.axis.tickPositions).last()[0] + '%';
}
}
},
credits: {
enabled: false
}
};
$.getJSON('/uploads/test.json', function (list) {
options.series = list;
var chart = new Highcharts.Chart(options);
function showValues() {
$('#alpha-value').html(chart.options.chart.options3d.alpha);
$('#beta-value').html(chart.options.chart.options3d.beta);
$('#depth-value').html(chart.options.chart.options3d.depth);
}
// Activate the sliders
$('#sliders input').on('input change', function () {
chart.options.chart.options3d[this.id] = this.value;
showValues();
chart.redraw(false);
});
showValues();
});
});
Example of how I would like the graph to look
The four bars are all different projects and 412.628 is the highest value!
Upvotes: 0
Views: 6907
Reputation: 12472
You should treat Highcharts as a library for visualising data, not analysing it, thus the data should be prepared before rendering a chart. So you need to calculate percentage on your own.
First, you should find max values for each category
var listLen = list.length,
dataLen = list[0].data.length,
dataMaxes = list[0].data.slice(),
point,
dataIndex,
listIndex;
for (dataIndex = 0; dataIndex < dataLen; dataIndex++) {
for (listIndex = 1; listIndex < listLen; listIndex++) {
point = list[listIndex].data[dataIndex]
if (point > dataMaxes[dataIndex]) {
dataMaxes[dataIndex] = point;
}
}
}
Second, you should prepare series object, you need to calculate percentage and store absolute value to have access to it (e.g. in a tooltip).
options.series = list.map(function (project) {
return {
name: project.name,
data: project.data.map(function (point, dataIndex) {
return {
y: (point / dataMaxes[dataIndex]) * 100,
absoluteY: point
};
})
}
});
Third, format the labels, tooltip, etc., in this case add percentage symbol to value, and set point's absoluteY value in a tooltip.
yAxis: {
/* Other things */
labels: {
format: '{value}%'
}
},
tooltip: {
pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.absoluteY}</b><br/>'
},
Example: https://jsfiddle.net/bm3hpdc6/3/
Upvotes: 2
Reputation: 1459
For setting the highest value from amongst the data for all the projects as the reference (a level of 100 %), change the data in the series object like so -
series: [{
name: 'Project1',
data: [highestValueForThisProject/HighestValueForAllProjects * 100]
}, {
name: 'Project2',
data: [highestValueForThisProject/HighestValueForAllProjects * 100]
}, {
name: 'Project3',
data: [highestValueForThisProject/HighestValueForAllProjects * 100]
}, {
name: 'Project4',
data: [highestValueForThisProject/HighestValueForAllProjects * 100]
}]
for example -
series: [{
name: 'Project1',
data: [353.832 / 412.628 * 100]
}, {
name: 'Project2',
data: [31.812 / 412.628 * 100]
}, {
name: 'Project3',
data: [83.966 / 412.628 * 100]
}, {
name: 'Project4',
data: [412.628 / 412.628 * 100]
}]
Also, I don't see the need of a formatter function for labels.
Hope this helps.
Upvotes: 0