Search code examples
javascriptnode.jsreactjshighchartssunburst-diagram

Convert row-data to sunburst chart data for Highcharts library


My Row-Data which I got from my MongoDB database. Now, I want to convert the below data to sunburst chart data. Can anyone help me?

These are my Input data array.

[
{
    "globalId": "Chart Global",
    "country": "India",
    "state": "Gujarat",
    "city": "Vadodara",
    "mode": "traffic",
    "value": 2.9
},
{
    "globalId": "Chart Global",
    "first": "India",
    "state": "Rajsthan",
    "city": "Jaipur",
    "mode": "traffic",
    "value": 2.9
},
{
    "globalId": "Chart Global",
    "first": "India",
    "state": "Delhi",
    "city": "Delhi",
    "mode": "traffic",
    "value": 100
},
{
    "globalId": "Chart Global",
    "first": "India",
    "state": "Delhi",
    "city": "Delhi",
    "mode": "population",
    "value": 2000
},
{
    "globalId": "Chart Global",
    "first": "India",
    "state": "Delhi",
    "city": "Delhi",
    "mode": "animals",
    "value": 5
},
{
    "globalId": "Chart Global",
    "first": "India",
    "state": "Delhi",
    "city": "Delhi",
    "mode": "birds",
    "value": 0
},
{
    "globalId": "Chart Global",
    "first": "India",
    "state": "Delhi",
    "city": "Delhi",
    "mode": "trees",
    "value": 0
}
]

I want data for the sunburst Chart for highcharts library

Does anyone have solutions?


Solution

  • As a start point you can use this function (I changed a little bit the data to see more effects):

    function seqToBurstData(originalData, circleKeys){
        const sunBurstData = [];
        const valuePath2pointId = {}; // auxiliary data used to identify the parent id of a point
    
        // get all the values for {dataPoint} from top key to {level} key, joined by '_'
        // used to index nameLevel2pointId data, to ensure each point has a unique index value
        const valuePath = (dataPoint, level) =>
            Array.from({length: level}, (_, i) => dataPoint[circleKeys[i]]).join('_');
    
        circleKeys.forEach(function(key, index){
            const level = index + 1;
            let currentValuePath = null, nValues = 0, sunBurstPoint;
            for(const o of originalData){
                const thisValuePath = valuePath(o, level);
                if(thisValuePath !== currentValuePath){
                    currentValuePath = thisValuePath;
                    sunBurstPoint = {
                        id: level + '.' + nValues, // scheme similar to Highcharts examples for sunburst
                        parent: level === 1 ? null : valuePath2pointId[valuePath(o, level - 1)],
                        name: o[key],
                        level, // level not required but useful
                        ...(level === circleKeys.length ? {value: o.value} : {}) // only for the final level
                    };
                    if(level < circleKeys.length){
                        valuePath2pointId[currentValuePath] = sunBurstPoint.id;
                    }
                    sunBurstData.push(sunBurstPoint);
                    nValues++;
                }
                else if(level === circleKeys.length){
                    sunBurstPoint.value += o.value;
                }
            }
        });
    
        return sunBurstData;
    }
    
    const originalData = [
        {
            "globalId": "Chart Global",
            "first": "India",
            "state": "Gujarat",
            "city": "Vadodara",
            "mode": "traffic",
            "value": 59
        },
        {
            "globalId": "Chart Global",
            "first": "India",
            "state": "Rajasthan",
            "city": "Jaipur",
            "mode": "traffic",
            "value": 59
        },
        {
            "globalId": "Chart Global",
            "first": "India",
            "state": "Rajasthan",
            "city": "Ranthambore",
            "mode": "tigers",
            "value": 40
        },
        {
            "globalId": "Chart Global",
            "first": "India",
            "state": "Delhi",
            "city": "Delhi",
            "mode": "traffic",
            "value": 100
        },
        {
            "globalId": "Chart Global",
            "first": "India",
            "state": "Delhi",
            "city": "Delhi",
            "mode": "population",
            "value": 200
        },
        {
            "globalId": "Chart Global",
            "first": "India",
            "state": "Delhi",
            "city": "Delhi",
            "mode": "animals",
            "value": 50
        },
        {
            "globalId": "Chart Global",
            "first": "India",
            "state": "Delhi",
            "city": "Delhi",
            "mode": "birds",
            "value": 5
        },
        {
            "globalId": "Chart Global",
            "first": "India",
            "state": "Delhi",
            "city": "Delhi",
            "mode": "trees",
            "value": 5
        }
    ];
    
    
    const sunBurstData = seqToBurstData(originalData, ['first', 'state', 'city', 'mode']).
        // add the "intro" key to change the point title according to the level
        map(o=>({...o, intro: o.level === 4 ? 'The value of' : 'Total for'}));
    
    Highcharts.chart('chart', {
    
        chart: {
            height: '100%'
        },
    
        title: {
            text: ''
        },
    
        series: [{
            type: 'sunburst',
            data: sunBurstData,
            name: sunBurstData[0].name,
            allowDrillToNode: true,
            cursor: 'pointer',
            dataLabels: {
                format: '{point.name}'
            },
            levels: [{
                level: 1,
                color: 'transparent'
            }, {
                level: 2,
                colorByPoint: true
            }, {
                level: 3,
                colorVariation: {
                    key: 'brightness',
                    to: 0.3
                }
            }, {
                level: 4,
                colorVariation: {
                    key: 'brightness',
                    to: -0.3
                }
            }]
        }],
    
        tooltip: {
            headerFormat: '',
            pointFormat: '{point.intro} <b>{point.name}</b> is <b>{point.value}</b>'
        }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/10.3.2/highcharts.js"></script>
    <script src="https://code.highcharts.com/modules/sunburst.js"></script>
    <script src="https://code.highcharts.com/modules/accessibility.js"></script>
    
    <div id="chart"></div>