javascript - 如何使用 ChartJS 创建从新的 ajax 请求更新的条形图?
问题描述
我正在使用 Flask 和 MongoDB 构建我的应用程序。
现在我很难弄清楚如何让我的条形图根据我基于下拉菜单的不同 ajax 请求动态更改..
在弄清楚如何使图表响应我在下拉菜单中的选择之前,我决定致力于使图表能够对不同的 ajax 数据做出反应并相应地更新。
首先,我学习了如何创建一个基本的条形图,如下所示:
var getValues = $.get('/data/locations-vs-counts/');
getValues.done(function(bar_data){
counts = bar_data.counts;
label = bar_data.locations;
maxValue = Math.max.apply(Math, counts);
var barchart = new Chart(ctx, {
type: 'bar',
data: {
labels: label,
datasets: [{
label: '# of counts',
backgroundColor: 'rgb(17, 146, 232)',
borderColor: 'rgb(17, 146, 232)',
data: counts
}]
},
options: {
responsive: false,
scales: {
yAxes: [{
id: 'y-axis-1', type: 'linear', position: 'left', ticks:{beginAtZero:true,max:(maxValue+1)}
}]
}
}
});
});
但为了实现我想要的,我想我需要为图表创建一个函数,以便能够接受一些输入(URL、chart_title、标签等)。我决定在第一次尝试时只尝试 URL 输入。
我已阅读以下帖子以供参考:
Refresh the Bar Char in ChartJS (v2.6.0) Using Ajax Correct Way
How to return multiple arrays from a function in Javascript?
https://github.com/chartjs/Chart.js/issues/6176
使用动态数据更新chartJS
如何从AJAX 帖子获取Flask 中的数据 (尚未使用,但我认为在需要使用下拉列表更新chartjs 时会很有用)
到目前为止,我最终得到了以下代码:
// Bar chart (# of Counts vs Locations)
var ctx = document.getElementById('barChart').getContext('2d');
var barChart = new Chart(ctx,{
type: 'bar',
data:[],
option:{responsive: false}
});
function barData(url){
let data_labels = [];
let data_values = [];
$.ajax({
url: url,
type: 'GET',
async: false,
success: function(bar_data){
data_labels= bar_data.labels;
data_values= bar_data.values;
}
})
return {data_labels,data_values};
}
function updateBarChart(url_link){
let results = barData(url_link);
counts = results.data_values;
xlabels = results.data_labels;
maxValue = Math.max.apply(Math, counts);
console.log("counts:",counts);
console.log("xlabels:", xlabels);
barChart.data.labels = xlabels;
barChart.data.datasets.data = counts;
barChart.data.datasets.label = "# of counts";
barChart.data.datasets.backgroundColor = 'rgb(17, 146, 232)';
barChart.options.scales.yAxes[0].ticks.beginAtZero= true;
barChart.options.scales.yAxes[0].ticks.max = (maxValue+1);
barChart.update();
}
updateBarChart('/data/locations-vs-counts/')
但是..以上没有按预期工作。
画布以正确的 xlabels 和 y 比例显示,但未绘制条形。但我可以看到 counts 变量在控制台中具有正确值的数组。
我也尝试过barChart.data.datasets[0].data = counts;
一些建议的帖子,但显示错误:
未捕获的类型错误:无法在 updateBarChart 处设置未定义的属性“数据”
作为参考,我从 URL 获得的数据是我从 pandas 数据框生成的两个列表,如下所示:data_parse.py:
@data_parser.route('/locations-vs-counts/', methods=['GET'])
def locations_vs_counts():
locations = location_list() #from another function
df = all_counts()
df = df['location'].value_counts()
for location in locations:
if(location not in df.index):
df.loc[location] = 0
labels = df.index.tolist()
counts = df.tolist()
return jsonify({'labels':labels, 'values': counts})
有人可以告诉我我在updateBarChart()
功能上做错了什么吗?
如果这种方法是可行的,我想最终实现:将所有位置与计数作为默认图表的条形图,然后用户可以从位置下拉列表中选择以查看该位置的详细信息(来自另一条路线的 2 个新数组)
任何帮助表示赞赏!先感谢您!
对adelriosantiago建议的回应:
我可以看到我的条形图用以下内容正确绘制
var results = barData('/data/locations-vs-counts/'); //same barData() function from above
var myValues = results.data_values;
var myLabels = results.data_labels;
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: myLabels,
datasets: [{
label: '# of counts',
data: myValues
}]
},
options:{
responsive: false
}
});
所以我认为这证明 barData() 正在按预期获取值myLabels
并myValues
正确存储,尽管这async:false
似乎并不理想。我不猜测这与我如何更新内部的图形数据有关updateBarChart()
?
解决方案
这是一个异步与同步错误。本教程可能会有所帮助。
看一下这部分代码:
function barData(url){
let data_labels = [];
let data_values = [];
$.ajax({
url: url,
type: 'GET',
async: false,
success: function(bar_data){
data_labels= bar_data.labels;
data_values= bar_data.values;
}
})
return {data_labels,data_values};
}
这return {data_labels,data_values};
实际上是在$.ajax
通话之前发生的。如果你想从服务器返回结果,这一行应该在success
ajax 调用的函数内。看看这个问题,其中 OP 有同样的问题。
关于更新图表,这里有一个模拟服务器响应的演示,每秒更新其值:https ://codepen.io/adelriosantiago/pen/YzpNLbd
推荐阅读
- javascript - Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException- laravel 5.7.28
- ios - 取消 WhatsApp Swift 之类的语音注释
- python - 根据列中的行值对每个组执行扣除
- node.js - 我想使用节点 js 将 mongodb 查询结果保存到 postgresql
- java - 我已经创建了 chrome 驱动程序对象,然后我得到了 java.lang.NullPointerException
- java - 在 Sceneform 中拍照时隐藏 PlaneRenderer
- scala - 在@FXML 变量绑定之前调用'initialize'
- python-3.x - 运行 OpenCV 和 imutils 的属性错误
- javascript - 在 javaScript 中使用 == 运算符时,如何证明布尔数据类型转换为数字
- angular - Angular 5 ngForm:无法验证表单提交时的选择框选项