Нарисуйте Chart.js с данными ajax и реагируйте. Несколько проблем и вопросов
Я использую Chart.js(http://www.chartjs.org/docs/) для создания диаграмм.
Мне нужно получить данные из запроса Ajax, и диаграмма будет реагировать.
В моем HTML-коде я добавил холст следующим образом:
<div>
<canvas id="userscreated" class="plot" data-url="/stats/userscreated"></canvas>
</div>
И в моем 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 }
);
});
<сильные > ПРОБЛЕМЫ
-
Диаграмма не изменяется при изменении размера окна.
-
Есть ли лучший код для этого? Я думаю, что повторяю много кода.
-
В Google рисунок выполняется быстро. В firefox иногда он висит на некоторое время.
Что-то не так с моим кодом?
-
Если запрос будет асинхронным или нет?
Спасибо,
Miguel
Ответы
Ответ 1
Вы можете сделать асинхронные вызовы AJAX без проблем. Очень важно, чтобы вы настраивали диаграмму только после срабатывания обратного вызова. В противном случае вы не будете задавать проблемы со своим контекстом canvas. Первый вызов responseCanvas выполняет начальную настройку, а последующие вызовы - изменение размера.
Вот что работает для меня:
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();
});
Если вы хотите вставить небольшую задержку между вызовами, вы можете использовать таймаут:
$(document).ready(function() {
$(window).resize(setTimeout(respondCanvas, 500));
GetChartData();
});
Задержка сделает ваше изменение размера более отзывчивым, если у вас на вашем графике большой набор данных.
Ответ 2
вы можете установить это в chart.js
new Chart(context, {
type:"line",
labels: data.Dates,
datasets: [
{ fillColor: #404040, data: data.Users }
]
options: { responsive: false }
});
Ответ 3
- Действительно
- Да, я приведу вам пример.
- Я не вижу ничего, что могло бы вызвать проблему. За исключением того, что window.resize может запускать рендеринг новой диаграммы намного чаще, чем вы хотите.
- Нет. (Я не знаю, почему, это больше совпадение.)
Код:
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")
[email protected] canvas.length != [email protected] 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
)