Data is not displayed in Highcharts

I am trying to combine several different chart demographics from Highcharts.

My examples: Data Classes and Popups and Little US with Label Data

I want the card to be the first one with a popup function of the second. I need to connect the map to my own google spreadsheet, but for now I'm just trying to get the data from the first example to work.

This is what I have so far, but cannot get any data on the map. I thought I had a problem with joinBy

, and I still can, but when I set joinBy

to null, I thought, "Map elements are connected by their position in the array," but nothing happened.

https://jsfiddle.net/9eq6mydv/

$(function () {
// Load the data from a Google Spreadsheet
// https://docs.google.com/a/highsoft.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0AoIaUO7wH1HwdFJHaFI4eUJDYlVna3k5TlpuXzZubHc&output=html
Highcharts.data({

    googleSpreadsheetKey: '0AoIaUO7wH1HwdDFXSlpjN2J4aGg5MkVHWVhsYmtyVWc',
    googleSpreadsheetWorksheet: 1,

    // custom handler for columns
    parsed: function (columns) {

        // Make the columns easier to read
        var keys = columns[0],
            names = columns[1],
            percent = columns[10],
        // Initiate the chart
        options = {
            chart : {
                renderTo: 'container',
                type: 'map',
                borderWidth : 1
            },

            title : {
                text : 'US presidential election 2008 result'
            },

            subtitle: {
                text: 'Source: <a href="http://en.wikipedia.org/wiki/United_States_presidential_election,' +
                    '_2008#Election_results">Wikipedia</a>'
            },

            mapNavigation: {
                enabled: true,
                enableButtons: false
            },

            legend: {
                align: 'right',
                verticalAlign: 'top',
                x: -100,
                y: 70,
                floating: true,
                layout: 'vertical',
                valueDecimals: 0,
                backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || 'rgba(255, 255, 255, 0.85)'
            },

            colorAxis: {
                dataClasses: [{
                    from: -100,
                    to: 0,
                    color: '#C40401',
                    name: 'McCain'
                }, {
                    from: 0,
                    to: 100,
                    color: '#0200D0',
                    name: 'Obama'
                }]
            },

            series : [{
                data : data,
                dataLabels: {
                    enabled: true,
                    color: '#FFFFFF',
                    format: '{point.code}',
                    style: {
                        textTransform: 'uppercase'
                    }
                },
                mapData: Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small']),
                joinBy: keys,
                name: 'Democrats margin',
                point: {
                    events: {
                        click: pointClick
                    }
                },
                tooltip: {
                    ySuffix: ' %'
                },
                cursor: 'pointer'
            }, {
                type: 'mapline',
                data: Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small'], 'mapline'),
                color: 'silver'
            }]
        };

        /**
         * Event handler for clicking points. Use jQuery UI to pop up
         * a pie chart showing the details for each state.
         */
        function pointClick() {
            var row = this.options.row,
                $div = $('<div></div>')
                    .dialog({
                        title: this.name,
                        width: 400,
                        height: 300
                    });

            window.chart = new Highcharts.Chart({
                chart: {
                    renderTo: $div[0],
                    type: 'pie',
                    width: 370,
                    height: 240
                },
                title: {
                    text: null
                },
                series: [{
                    name: 'Votes',
                    data: [{
                        name: 'Obama',
                        color: '#0200D0',
                        y: parseInt(columns[3][row], 10)
                    }, {
                        name: 'McCain',
                        color: '#C40401',
                        y: parseInt(columns[4][row], 10)
                    }],
                    dataLabels: {
                        format: '<b>{point.name}</b> {point.percentage:.1f}%'
                    }
                }]
            });
        }

        // Read the columns into the data array
        var data = [];
        $.each(keys, function (i, key) {
            data.push({
                key: key,//.toUpperCase(),
                value: parseFloat(percent[i]),
                name: names,
                row: i
            });
        });

        // Initiate the chart
        window.chart = new Highcharts.Map(options);
    },

    error: function () {
        $('#container').html('<div class="loading">' +
            '<i class="icon-frown icon-large"></i> ' +
            'Error loading data from Google Spreadsheets' +
            '</div>');
    }
});
});

      

UPDATE:

I wanted to share my final solution with everyone. Although Ondkloss did a great job in answering my question, the popup function still doesn't work and that's because I forgot to include jQuery to call .dialog

. As soon as I included that I had a blank popup with highchart error 17 , this is because the highmaps.js code does not include the pie chart class, so I had to add the code highcharts.js

and enable the module map.js

after that. You can see the final jsfiddle here .

Thanks again to Ondkloss for the great answer!

+3


source to share


1 answer


The problem here mostly comes down to usage joinBy

. Also, to fix this, there are some necessary changes for your data

and mapData

.

Currently yours joinBy

is an array of strings, eg ["al", "ak", ...]

. This is quite simply not an accepted parameter format joinBy

. You can read the details in the API documentation , but the simplest way is to have a common attribute in data

and mapData

then put a string in joinBy

, which then concatenates the two arrays to that attribute. For example:

series : [{
    data : data,
    mapData: mapData,
    joinBy: "hc-key",
]

      

Here, the attribute "hc-key"

must exist in data

, and in mapData

.

Here's how I would create a variable data

in your code:

var data = [];
$.each(keys, function (i, key) {
    if(i != 0)
        data.push({
            "hc-key": "us-"+key,
            code: key.toUpperCase(),
            value: parseFloat(percent[i]),
            name: names[i],
            row: i
        });
});

      



This is missing the first key, which is just "Key"

(column header). Here we make the "hc-key"

appropriate format "hc-key"

in our map data. An example would be "us-al"

. The rest are just metadata to be combined. Please note that you specified your data in the parameters before filling them with data, so this needs to be transferred before that.

This is how I create the variable mapData

in your code:

var mapData = Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small']);

// Process mapdata
$.each(mapData, function () {
    var path = this.path,
        copy = { path: path };

    // This point has a square legend to the right
    if (path[1] === 9727) {

        // Identify the box
        Highcharts.seriesTypes.map.prototype.getBox.call(0, [copy]);

        // Place the center of the data label in the center of the point legend box
        this.middleX = ((path[1] + path[4]) / 2 - copy._minX) / (copy._maxX - copy._minX);
        this.middleY = ((path[2] + path[7]) / 2 - copy._minY) / (copy._maxY - copy._minY);

    }
    // Tag it for joining
    this.ucName = this.name.toUpperCase();
});

      

The first part is your "standard card data". The rest is to correctly center the labels for the popout states and get directly from the example.

And voila, see this JSFiddle demo to witness your card in action.

I suggest doing a few console.log

-ing to see how data

u mapData

have hc-key

shared, which results in the merging of the data in a series.

+2


source







All Articles