如何创建条形图,从新的ajax请求与ChartJS更新?



我正在用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, label等)。我决定在第一次尝试中只使用URL输入。
我已经阅读了以下帖子供我参考:
刷新ChartJS中的Bar Char (v2.6.0)使用Ajax正确的方式
如何从Javascript中的函数返回多个数组?
https://github.com/chartjs/Chart.js/issues/6176
使用动态数据更新ChartJS
如何从Ajax post中获取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/')

然而. .以上并没有像预期的那样工作。
画布显示了正确的xlabel和y刻度,但是没有绘制条形图。但我可以看到计数变量在控制台中有正确值的数组。
我也尝试了barChart.data.datasets[0].data = counts;像一些帖子建议,但错误显示:

Uncaught TypeError: Cannot set property 'data' of undefined在updateBarChart

作为参考,我从URL中得到的数据是我从pandas dataframe中生成的两个列表,如下所示: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()功能?
如果这种方法是可行的,我想最终实现:柱状图与所有的位置vs计数作为默认图表,然后用户可以从下拉的位置选择查看该位置的详细信息(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()正在获得预期的值,并正确地存储在myLabelsmyValues中,尽管async:false似乎并不理想。我不猜这与我如何更新updateBarChart()内的图形数据有关?

这是一个异步vs同步错误。本教程可能会有所帮助。

看一下这部分代码:

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调用之前。如果希望从服务器返回结果,这一行应该位于ajax调用的success函数中。看看这个问题,OP有同样的问题。

关于更新图表,这里有一个模拟服务器响应的演示,该响应每秒更新其值:https://codepen.io/adelriosantiago/pen/YzpNLbd

最新更新