jQuery 使用 ajax 数据和响应式绘制 Chart.js。几个问题和疑问
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19894952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Draw a Chart.js with ajax data and responsive. A few problems and questions
提问by Miguel Moura
I am using Chart.js (http://www.chartjs.org/docs/) for charting.
我正在使用 Chart.js ( http://www.chartjs.org/docs/) 来绘制图表。
I need to get the data from an Ajax request and the chart to be responsive.
我需要从 Ajax 请求和图表中获取数据才能做出响应。
In my HTML code I added a canvas as follows:
在我的 HTML 代码中,我添加了一个画布,如下所示:
<div>
<canvas id="userscreated" class="plot" data-url="/stats/userscreated"></canvas>
</div>
And in my javascript (JQuery) code I have:
在我的 javascript (JQuery) 代码中,我有:
var data2;
$.ajax({
url: $('#userscreated').data('url'),
async: true,
dataType: 'json',
type: "get",
}).done(function (data) {
data2 = data;
// Draw chart
var context = $('#userscreated').get(0).getContext("2d");
var wrapper = $('#userscreated').parent();
var width = $('#userscreated').attr('width', $(wrapper).width());
new Chart(context).Line(
{
labels: data.Dates,
datasets: [
{ fillColor: #404040, data: data.Users }
]
},
{ animation: false }
);
});
// Redraw the chart with the same data
$(window).resize(function () {
var context = $('#userscreated').get(0).getContext("2d");
var wrapper = $('#userscreated').parent();
var width = $('#userscreated').attr('width', $(wrapper).width());
new Chart(context).Line(
{
labels: data2.Dates,
datasets: [
{ fillColor: #404040, data: data2.Users }
]
},
{ animation: false }
);
});
PROBLEMS
问题
- The chart is not being resized on window resize.
- Is there better code to do this? I think I am repeating to much code.
- In Google the drawing is fast. In firefox sometimes it hangs for a while. Is anything wrong with my code?
- Should the request be async or not?
- 图表未在窗口调整大小时调整大小。
- 有没有更好的代码来做到这一点?我想我重复了很多代码。
- 在 Google 中,绘图速度很快。在 Firefox 中,它有时会挂起一段时间。我的代码有什么问题吗?
- 请求是否应该是异步的?
回答by Cameron Tinker
You can make async AJAX calls no problem. It's just important that you setup the chart only after the success callback fires. Otherwise, you'll get issues with your canvas context not being defined. The first call to respondCanvas does the initial setup while the subsequent calls do the resizing.
您可以毫无问题地进行异步 AJAX 调用。只有在成功回调触发后才设置图表很重要。否则,您会遇到未定义画布上下文的问题。对 respondCanvas 的第一次调用进行初始设置,而随后的调用进行调整大小。
Here is what works for me:
以下是对我有用的方法:
var max = 0;
var steps = 10;
var chartData = {};
function respondCanvas() {
var c = $('#summary');
var ctx = c.get(0).getContext("2d");
var container = c.parent();
var $container = $(container);
c.attr('width', $container.width()); //max width
c.attr('height', $container.height()); //max height
//Call a function to redraw other content (texts, images etc)
var chart = new Chart(ctx).Line(chartData, {
scaleOverride: true,
scaleSteps: steps,
scaleStepWidth: Math.ceil(max / steps),
scaleStartValue: 0
});
}
var GetChartData = function () {
$.ajax({
url: serviceUri,
method: 'GET',
dataType: 'json',
success: function (d) {
chartData = {
labels: d.AxisLabels,
datasets: [
{
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
data: d.DataSets[0]
}
]
};
max = Math.max.apply(Math, d.DataSets[0]);
steps = 10;
respondCanvas();
}
});
};
$(document).ready(function() {
$(window).resize(respondCanvas);
GetChartData();
});
If you want to insert a small delay between calls, you can use a timeout:
如果你想在调用之间插入一个小的延迟,你可以使用超时:
$(document).ready(function() {
$(window).resize(setTimeout(respondCanvas, 500));
GetChartData();
});
The delay will make your resizing more responsive in case you have a large dataset on your graph.
如果您的图表上有大型数据集,延迟将使您的调整大小更具响应性。
回答by melon24
you can set that in chart.js
你可以在chart.js中设置
new Chart(context, {
type:"line",
labels: data.Dates,
datasets: [
{ fillColor: #404040, data: data.Users }
]
options: { responsive: false }
});
回答by Senjai
- Indeed
- Yes, I'll give you an example.
- I dont see anything that might cause an issue. Except that window.resize might be firing rendering a new chart far more often then you want.
- No. (I don't really know why, this is more coincidence.)
- 的确
- 是的,我给你举个例子。
- 我没有看到任何可能导致问题的东西。除了 window.resize 可能比您想要的更频繁地触发渲染新图表。
- 没有。(我真的不知道为什么,这更巧合。)
The code:
编码:
window.getVisitCounts = ($canvas) ->
url = Routes.visits_between_project_path($canvas.data('project-id'), {
format: "json",
start: $canvas.data('start'),
end: $canvas.data('end')
})
visits = []
days = []
$.ajax
url: url,
async: false,
dataType: "json",
type: "GET",
success: (data) - >
for point in data.chart.data
visits.push(point.visits)
days.push(point.date)
{
days: days,
visits: visits
}
window.createChartData = (raw) - > {
labels: raw.days,
datasets: [{
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
data: raw.visits,
}]
}
window.setupCanvas = ($canvas, data) - >
newWidth = $canvas.parent().width()
$canvas.prop
width: newWidth
height: 400
options = {
scaleOverride: true,
scaleSteps: 10,
scaleStepWidth: Math.ceil(Math.max.apply(Math, data.datasets[0].data) / 10),
scaleStartValue: 0
}
ctx = $canvas.get(0).getContext("2d")
new Chart(ctx).Line(data, options)
$ - > @canvas = $("#analytics-canvas")
if@ canvas.length != 0@ visits = window.createChartData(window.getVisitCounts(@canvas))
window.setupCanvas(@canvas, @visits)
$(window).on('resizeEnd', - >
setupCanvas(document.canvas, document.visits)
)
$(window).resize - >
if (@resizeTO)
clearTimeout(@resizeTO)
@resizeTO = setTimeout(- >
$(this).trigger "resizeEnd"
500
)