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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 00:46:19  来源:igfitidea点击:

Draw a Chart.js with ajax data and responsive. A few problems and questions

javascriptjquerychart.js

提问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

问题

  1. The chart is not being resized on window resize.
  2. Is there better code to do this? I think I am repeating to much code.
  3. In Google the drawing is fast. In firefox sometimes it hangs for a while. Is anything wrong with my code?
  4. Should the request be async or not?
  1. 图表未在窗口调整大小时调整大小。
  2. 有没有更好的代码来做到这一点?我想我重复了很多代码。
  3. 在 Google 中,绘图速度很快。在 Firefox 中,它有时会挂起一段时间。我的代码有什么问题吗?
  4. 请求是否应该是异步的?

回答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

  1. Indeed
  2. Yes, I'll give you an example.
  3. 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.
  4. No. (I don't really know why, this is more coincidence.)
  1. 的确
  2. 是的,我给你举个例子。
  3. 我没有看到任何可能导致问题的东西。除了 window.resize 可能比您想要的更频繁地触发渲染新图表。
  4. 没有。(我真的不知道为什么,这更巧合。)

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
 )