【问题标题】:Reload chart data via JSON with Highcharts使用 Highcharts 通过 JSON 重新加载图表数据
【发布时间】: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

【问题讨论】:

    标签: jquery json highcharts


    【解决方案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://stackoverflow.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 小时的尝试弄清楚,为什么我的散点图在每次调用时都会堆积系列。我终于找到了这个修复。你拯救了我剩下的时间。有效。谢谢。
              猜你喜欢
              • 1970-01-01
              • 2023-04-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-08-21
              • 1970-01-01
              • 2019-10-21
              相关资源
              最近更新 更多