使用 Highcharts 通过 JSON 重新加载图表数据

Posted

技术标签:

【中文标题】使用 Highcharts 通过 JSON 重新加载图表数据【英文标题】:Reload chart data via JSON with Highcharts 【发布时间】:2011-05-11 18:51:31 【问题描述】:

我正在尝试基于页面中其他位置的按钮单击通过 JSON 重新加载 Highcharts 图表的数据。最初我想显示一组默认数据(按类别支出),然后根据用户输入加载新数据(例如,按月支出)。我能想到的从服务器输出 JSON 的最简单方法是将 GET 请求传递到 php 页面,例如 $.get('/dough/includes/live-chart.php?mode=month' ,从按钮的 ID 属性中检索此值。

这是我到目前为止检索默认数据(按类别支出)的内容。需要找到如何根据用户输入,按需将完全不同的数据加载到饼图中:

$(document).ready(function() 
            //This is an example of how I would retrieve the value for the button
            $(".clickMe").click(function() 
                var clickID = $(this).attr("id");
            );
            var options = 
                chart: 
                    renderTo: 'graph-container',
                    margin: [10, 175, 40, 40]
                ,
                title: 
                    text: 'Spending by Category'
                ,
                plotArea: 
                    shadow: null,
                    borderWidth: null,
                    backgroundColor: null
                ,
                tooltip: 
                    formatter: function() 
                        return '<b>'+ this.point.name +'</b>: $'+ this.y;
                    
                ,
                credits: 
                    enabled: false
                ,
                plotOptions: 
                    pie: 
                        allowPointSelect: true,
                        cursor: 'pointer',
                        dataLabels: 
                            enabled: true,
                            formatter: function() 
                                if (this.y > 5) return '$' + this.y;
                            ,
                            color: 'white',
                            style: 
                                font: '13px Trebuchet MS, Verdana, sans-serif'
                            
                        
                    
                ,
                legend: 
                    layout: 'vertical',
                    style: 
                        left: 'auto',
                        bottom: 'auto',
                        right: '50px',
                        top: '100px'
                    
                ,
                series: [
                    type: 'pie',
                    name: 'Spending',
                    data: []
                ]
            ;
            $.get('/dough/includes/live-chart.php', function(data) 
            var lines = data.split('\n');
            $.each(lines, function(lineNo, line) 
                var items = line.split(',');
                var data = ;
                $.each(items, function(itemNo, item) 
                    if (itemNo === 0) 
                        data.name = item;
                     else 
                        data.y = parseFloat(item);
                    
                );
                options.series[0].data.push(data);
            );
            // Create the chart
            var chart = new Highcharts.Chart(options);
        );
        );

任何帮助将不胜感激

编辑

感谢 Robodude,这是更新后的 javascript。约翰,你让我在正确的轨道上 - 谢谢!我现在不知道如何从 AJAX 请求中替换图表上的数据。我必须承认 $.get() 后面的代码很可能来自示例代码,我不完全理解它运行时发生了什么——也许有更好的方法来格式化数据?

我能够在图表现在加载新数据方面取得一些进展,但它被添加到已经存在的数据之上。我怀疑罪魁祸首是这一行:

options.series[0].data.push(data);

我试过 options.series[0].setData(data);但什么也没发生。从好的方面来说,AJAX 请求可以根据选择菜单的值完美运行,并且没有 Javascript 错误。这是有问题的代码,没有图表选项:

$.get('/dough/includes/live-chart.php?mode=cat', function(data) 
            var lines = data.split('\n');
            $.each(lines, function(lineNo, line) 
                var items = line.split(',');
                var data = ;
                $.each(items, function(itemNo, item) 
                    if (itemNo === 0) 
                        data.name = item;
                     else 
                        data.y = parseFloat(item);
                    
                );
                options.series[0].data.push(data);
            );
            // Create the chart
            var chart = new Highcharts.Chart(options);
        );
        $("#loadChart").click(function() 
            var loadChartData = $("#chartCat").val();
                $.get('/dough/includes/live-chart.php?mode=' + loadChartData, function(data) 
                var lines = data.split('\n');
                $.each(lines, function(lineNo, line) 
                    var items = line.split(',');
                    var data = ;
                    $.each(items, function(itemNo, item) 
                        if (itemNo === 0) 
                            data.name = item;
                         else 
                            data.y = parseFloat(item);
                        
                    );
                    options.series[0].data.push(data);
                );
                // Create the chart
                var chart = new Highcharts.Chart(options);
            );
        );
    );

编辑 2 这是图表从中提取的格式 - 非常简单,类别名称和值后面都有 \n。

Coffee, 4.08
Dining Out, 5.05
Dining: ODU, 5.97
Dining: Work, 38.41
Entertainment, 4.14
Gas, 79.65
Groceries, 228.23
Household, 11.21
Misc, 12.20
Snacks, 20.27

【问题讨论】:

【参考方案1】:

data = [150,300]; // data from ajax or any other way chart.series[0].setData(data, true);

setData 会调用重绘方法。

参考:http://api.highcharts.com/highcharts/Series.setData

【讨论】:

【参考方案2】:

其实也许你应该选择update这个函数更好。 这是函数updatehttp://api.highcharts.com/highcharts#Series.update的文档

你可以像下面这样输入代码:

chart.series[0].update(data: [1,2,3,4,5])

这些代码将合并原始选项,并更新更改的数据。

【讨论】:

【参考方案3】:

编辑:下面的回答更正确!

https://***.com/a/8408466/387285

http://www.highcharts.com/ref/#series-object

html

<SELECT id="list">
<OPTION VALUE="A">Data Set A
<OPTION VALUE="B">Data Set B
</SELECT>
<button id="change">Refresh Table</button>

<div id="container" style="height: 400px"></div>

Javascript:

var options = 
    chart: 
        renderTo: 'container',
        defaultSeriesType: 'spline'
    ,
    series: []
;

$("#change").click(function() 
    if ($("#list").val() == "A") 
        options.series = [name: 'A', data: [1,2,3,2,1]]
        // $.get('/dough/includes/live-chart.php?mode=month'
     else 
        options.series = [name: 'B', data: [3,2,1,2,3]]
        // $.get('/dough/includes/live-chart.php?mode=newmode'
     

    var chart = new Highcharts.Chart(options);    
);

这是一个非常简单的示例,因为我这里没有我的文件,但基本思想是每次用户为他们想要查看的内容选择新选项时,您将需要替换 .系列数据对象与来自服务器的新信息,然后使用新的 Highcharts.Chart(); 重新创建图表。

希望这会有所帮助! 约翰

编辑:

看看这个,它来自我过去工作过的东西:

$("table#tblGeneralInfo2 > tbody > tr").each(function (index) 
    if (index != 0) 
        var chartnumbervalue = parseInt($(this).find("td:last").text());
        var charttextvalue = $(this).find("td:first").text();
        chartoptions.series[0].data.push([charttextvalue, chartnumbervalue]);
    
);

我有一个表格,其中包含我需要添加到饼图中的第一个和最后一个 tds 中的信息。我遍历每一行并推入值。注意:我使用 chartoptions.series[0].data 因为饼图只有 1 个系列。

【讨论】:

为了您的方便,我把我写的代码放到了 jsfiddle 上:jsfiddle.net/EmMxH 你好 NightMICU!抱歉,我没有太多时间解释发生了什么,但请查看:jsfiddle.net/w4DKf 返回的数据格式是什么?请记住,饼图的每个值都是数组的一部分,该数组是 highcharts 数据数组的一部分,该数组是系列数组的一部分! 约翰,我认为这里的问题可能是图表数据的格式。它不是 JSON,我猜它需要是?如果我将 PHP 文件的输出更改为 JSON,我将如何将其包含到 Javascript 中? 执行此操作的正确方法是使用 chart.series[0].setData(...) 函数,该函数将有效地更新数据并可选择为您重新绘制图表。一遍又一遍地重新创建图表对象会泄漏内存,最终您的网页将开始运行 -terrible-。 在创建一个新的之前至少调用 Chart.destroy()。否则你最终会耗尽内存。去过那里,做到了。【参考方案4】:

其他答案对我不起作用。我在他们的文档中找到了答案:

http://api.highcharts.com/highcharts#Series

使用这种方法(see JSFiddle example):

var chart = new Highcharts.Chart(
    chart: 
        renderTo: 'container'
    ,

    series: [
        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]        
    ]
);

// the button action
$('#button').click(function() 
    chart.series[0].setData([129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4] );
);

【讨论】:

这个解决方案甚至更糟糕,因为只会更改更新的值,仅此而已。此处示例:jsfiddle.net/ebuTs/16 +1 这是正确的方法......选择的答案涉及每次进行更改时重新创建 Chart 对象并且效率非常低。 就我的目的而言,这根本不起作用,实际上让客户对我感到不满。我要显示的数据是当地救援队的呼叫统计数据。每个月,他们在不同类别中拨打不同数量的电话 - 因此每个月并不总是相同(例如,他们可能不会在一个月内发生一次车祸,下个月可能会发生 10 次)。您的回答导致了奇怪的行为,包括缺少类别和 HighCharts 代码中的错误“a is undefined”。选择的答案在某些方面可能效率低下,但它有效并且客户很高兴。 如果我有多个系列的数据怎么办?这似乎是一个非常具体的答案,对许多场景都没有真正的用处 series[0], series[1], series[2] 代表您的所有 3 个系列。您可以将其概括为: series.forEach(function(s, index)s.setData(newData[index]))【参考方案5】:

你总是可以加载一个json数据

这里我将 Chart 定义为命名空间

 $.getJSON('data.json', function(data)
                Chart.options.series[0].data = data[0].data;
                Chart.options.series[1].data = data[1].data;
                Chart.options.series[2].data = data[2].data;

                var chart = new Highcharts.Chart(Chart.options);

            );

【讨论】:

【参考方案6】:

正确答案是:

$.each(lines, function(lineNo, line) 
                    var items = line.split(',');
                    var data = ;
                    $.each(items, function(itemNo, item) 
                        if (itemNo === 0) 
                            data.name = item;
                         else 
                            data.y = parseFloat(item);
                        
                    );
                    options.series[0].data.push(data);
                    data = ;
                );

您需要刷新“数据”数组。

data = ;

【讨论】:

【参考方案7】:

如果您正在使用 push 将数据动态推送到 option.series .. 只需使用

options.series = [];  

清除它。

options.series = [];
$("#change").click(function()

【讨论】:

【参考方案8】:

在将新数据推入之前,您需要清除旧数组。有很多方法可以做到这一点,但我使用了这个:

options.series[0].data.length = 0;

所以你的代码应该是这样的:

options.series[0].data.length = 0;
$.each(lines, function(lineNo, line) 
                    var items = line.split(',');
                    var data = ;
                    $.each(items, function(itemNo, item) 
                        if (itemNo === 0) 
                            data.name = item;
                         else 
                            data.y = parseFloat(item);
                        
                    );
                    options.series[0].data.push(data);
                );

现在,当单击按钮时,旧数据将被清除,并且只会显示新数据。希望对您有所帮助。

【讨论】:

经过 2 小时的尝试弄清楚,为什么我的散点图在每次调用时都会堆积系列。我终于找到了这个修复。你拯救了我剩下的时间。有效。谢谢。

以上是关于使用 Highcharts 通过 JSON 重新加载图表数据的主要内容,如果未能解决你的问题,请参考以下文章

如何构造 HighCharts 数据系列以匹配通过 ajax 调用返回的 Json

通过 JSON 将 Django 数据库查询集传递给 Highcharts

在baidu中看到你的关于Highcharts 中后台添加series的答案,有点不明白,想请教下。可以加好友么?

将 JSON 编码的 PHP 变量传递给 HighCharts

通过循环分配的 highcharts 的系列名称和数据

如何为highcharts创建Json格式的数据