Anna Jeanine
Anna Jeanine

Reputation: 4125

Convert data to percentages HighCharts

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

enter image description here

The four bars are all different projects and 412.628 is the highest value!

Upvotes: 0

Views: 6907

Answers (2)

morganfree
morganfree

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

gkb
gkb

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

Related Questions