dliv
dliv

Reputation: 685

Highcharts.js different structure of input data

I have a simple Highcharts pie chart that takes the following data as input:

data: [
        {"y":4, "name":"Russia", "txt": "Our hotel at the countryside was very nice and welcoming."},
        {"y":2, "name":"Australia", "txt": "The trip to Ayers Rock was one of the highlights of our trip. The Great Barrier Reef and its clear water were simply amazing!"},
        {"y":1, "name":"Argentina", "txt": "It has been a childhood dream to just go into the wild."},
        {"y":4, "name":"China", "txt": "in year 1930 it was this is just a silly simple text to check if everything here is working."},
        {"y":2, "name":"Neverland", "txt": "in year 1940 it was like this."},
        {"y":4, "name":"Mars", "txt": "in year 1900 it was like this."}
            ]

Example:

$(document).ready(function() {
//var colors = ['#8d62a0', '#ceb3d8', '#d5dddd'];


    Highcharts.getOptions().plotOptions.pie.colors = (function () {
        var colors = [],
            base = '#801a00',
            i;

        for (i = 0; i < 100; i += 1) {
            colors.push(Highcharts.Color(base).brighten((i - 3) / 15).get());
        }
        return colors;
    }());

    var chart = new Highcharts.Chart({
        chart: {
            renderTo: 'container',
            type: 'pie'
        },
        tooltip: {
              formatter: function() {
        				return '<b>'+this.point.name+'</b>';
        				}
         },
         legend: {
              enabled: false
         },

         plotOptions: {
            pie: {
                innerSize: '75%'
            },
            series: {
            	cursor: 'pointer',
            	point: {
            		events: {
            			 click: function(){
            				defineInnerData(this.y, this.txt, this);
        				},
       				}
        	     },
                 states: {
                  hover: {
                    enabled: false
                  }
                }
        	}
        },
        yAxis: {
            title: {
              text: null
            },
            labels: {
              enabled: false
            }
        },
        series: [{
            dataLabels: {
              enabled: false
            },

            data: [
        {"y":4, "name":"Russia", "txt": "Our hotel at the countryside was very nice and welcoming."},
        {"y":2, "name":"Australia", "txt": "The trip to Ayers Rock was one of the highlights of our trip. The Great Barrier Reef and its clear water were simply amazing!"},
        {"y":1, "name":"Argentina", "txt": "It has been a childhood dream to just go into the wild."},
        {"y":4, "name":"China", "txt": "in year 1930 it was this is just a silly simple text to check if everything here is working."},
        {"y":2, "name":"Neverland", "txt": "in year 1940 it was like this."},
        {"y":4, "name":"Mars", "txt": "in year 1900 it was like this."}
            ]
            }]
    });

    function defineInnerData(name, y, obj) { // on complete
        var chart=$("#container").highcharts();
        $( "#pieChartInfoText" ).remove();
        var textX = chart.plotLeft + (chart.plotWidth  * 0.5);
        var textY = chart.plotTop  + (chart.plotHeight * 0.5);
        var span = '<span id="pieChartInfoText" style="position:absolute; text-align:block;left: 235px;top:210px;width: 150px; height: 180px; overflow: scroll;">';
        span += '<span style="font-size: 11px">'+ y +'</span><br>';
        span += '</span>';

        $("#addText").append(span);
        span = $('#pieChartInfoText');
        span.css('left', textX + (span.width() * -0.5));
        span.css('top', textY + (span.height() * -0.5));
        span.css('overflow', 'auto');

    }
  
  defineInnerData("", "Click on the slices to see the text");

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <script src="http://code.highcharts.com/highcharts.js"></script>
</head>
<body>

<div>
    <div id="container" style="position:absolute; left:0px; top:0px;"></div>
    <div id="addText" style="position:absolute; left:0px; top:0px;"></div>
</div>
<script src="testfile_highcharts.js"></script>

</body>
</html>

My question now is: How would I read data as input that comes in a different structure like the json code below (its geoJSON), where I would like to get the following values as input for my chart:

Here is how the geoJSON data looks like:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": 4,
      "properties": {
        "id": 4,
        "name": "Thailand",
        "lat": "13.7538929",
        "lon": "100.8160803",
        "2005": 14
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          "100.8160803",
          "13.7538929"
        ]
      },
      "text": ["The official reason given was that he wanted to give the Thai people time to mourn his father before he became king.", "Thailand has rarely had what might be called routine royal successions. The last was 70 years ago, when the young King Ananda was found shot dead in his bedroom in still unexplained circumstances."],
      "sentences": "2"
    },
    {
      "type": "Feature",
      "id": 7,
      "properties": {
        "id": 7,
        "name": "the United States",
        "lat": "38.8949549",
        "lon": "-77.0366455",
        "2005": 14
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          "-77.0366455",
          "38.8949549"
        ]
      },
      "text": ["The presidential elections will be a hard fight this year", "The best travelling season is September until end of October", "New York City is a must-see when travelling on the East Coast."],
      "sentences": "3"
    },
    {
      "type": "Feature",
      "id": 8,
      "properties": {
        "id": 8,
        "name": "Greece",
        "lat": "37.9841493",
        "lon": "23.7279843",
        "2005": 14
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          "23.7279843",
          "37.9841493"
        ]
      },
      "text": ["The Aegean islands are little paradise spots not far away from the bustling capital Athens "],
      "sentences": "1"
    }
  ]
}

I've tried for hours now to get this working, but I cannot seem to be able to do it. I'm very new to JavaScript and would appreciate every help here. I'm also sorry if the explanation of my problems should not be entirely clear, but I hope that there is someone who can still help me...

Upvotes: 2

Views: 72

Answers (2)

wergeld
wergeld

Reputation: 14442

This can be done in by traversing the JSON object by its properties:

var featureSet = theJSON.features;
var theData = [];

for (var item in featureSet) {
        var set = featureSet[item];

        for (var theText in set.text) {
        var theSlice = {};
            theSlice.name = set.properties.name;
            theSlice.y = set.text.length;
            theSlice.txt = set.text[theText];

            theData.push(theSlice);
        }
}

Where theJSON is your returned JSON object. From here you modify the chart to use theData.

var chart = new Highcharts.Chart({
    chart: {
        renderTo: 'container',
        type: 'pie'
    },
    tooltip: {
          formatter: function() {
                    return '<b>'+this.point.name+'</b>';
                    }
     },
     legend: {
          enabled: false
     },

     plotOptions: {
        pie: {
            innerSize: '75%'
        },
        series: {
            cursor: 'pointer',
            point: {
                events: {
                     click: function(){
                        defineInnerData(this.y, this.txt, this);
                    },
                }
             },
             states: {
              hover: {
                enabled: false
              }
            }
        }
    },
    yAxis: {
        title: {
          text: null
        },
        labels: {
          enabled: false
        }
    },
    series: [{
        dataLabels: {
          enabled: false
        },
        data: theData
        }]
});

Sample jsFiddle. Note that your selector on which slice to pick is not happy due to multiple same name/value slices. I would add an index value to each slice and key off of that instead.

Upvotes: 1

Rodolfo Marcos
Rodolfo Marcos

Reputation: 159

The key point to accomplish this is to convert the json structured data to a javascript object in the strucuture you want.

For do this you should iterate over the json object, get the values you want and exports it to the list you're passing to chart.

// The empty list passed to chart
var dataToChart = [];

// Empty object of the list
var dataToChartObject = {"y":0, "name":"", "txt": ""}

// Iterate over jSon to populate dataToChartObject
$.each(jsonObject.features, function(index, value){
    
    dataToChartObject.name = value.properties.name;
    dataToChartObject.txt = value.text[0]
    
    // I didn't realize what the articles number is, but do the same logic to get it

    // Now let's insert the object to the list
    dataToChart.push(dataToChartObject);
});

Upvotes: 2

Related Questions