3

我正在尝试结合来自 Highcharts 的几个不同的图表演示。

我的例子是:Data classes and popupSmall US with data labels

我想要第一个的地图和第二个的弹出功能。我需要将地图连接到我自己的谷歌电子表格,但现在我只是试图从第一个示例中获取数据来工作。

这是我到目前为止所拥有的,但似乎无法在地图中获取任何数据。我以为我有joinBy问题,我可能仍然存在,但是当我设置joinBy为 null 时,我认为“地图项通过它们在数组中的位置连接”,但什么也没发生。

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>');
    }
});
});

更新:

我想与大家分享我的最终解决方案。尽管 Ondkloss 在回答我的问题方面做得非常出色,但弹出功能仍然不起作用,这是因为我忘记在.dialog调用中包含 jQuery。一旦我包含一个带有highchart 错误 17的空弹出窗口,这是因为 highmaps.js 代码不包含饼图类。所以我不得不在之后添加highcharts.js代码并包含map.js模块。你可以在这里看到我最后的 jsfiddle

再次感谢 Ondkloss 的出色回答!

4

1 回答 1

2

这里的问题主要归结为使用joinBy. 此外,为了更正它,您的datamapData.

目前你joinBy是一个字符串数组,比如["al", "ak", ...]. 这根本不是一个可接受的joinBy选项格式。您可以阅读API 文档中的详细信息,但最简单的方法是拥有一个共同的属性,data然后mapData提供一个字符串joinBy,然后通过该属性将这两个数组连接起来。例如:

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

这里该"hc-key"属性必须同时存在于datamapData中。

以下是我data在您的代码中创建变量的方法:

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
        });
});

这会跳过第一个键,它只是"Key"(列的标题)。在这里,我们使"hc-key"适合"hc-key"地图数据中的格式。一个例子是"us-al"。其余的只是将要加入的元数据。请注意,您在用数据填充数据之前在选项中引用了您的数据,因此必须在此之前移动它。

这就是我mapData在您的代码中创建变量的方式:

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();
});

第一部分是您的“标准地图数据”。剩下的就是正确地将弹出状态的标签居中,并直接从示例中获得。

瞧,看看这个 JSFiddle 演示来见证你的地图在行动。

我建议做一些console.log- 看看如何datamapDatahc-key共同点,这会导致系列中的数据加入。

于 2015-05-11T01:29:34.737 回答