使用 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
这个函数更好。
这是函数update
http://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的答案,有点不明白,想请教下。可以加好友么?