web-dev-qa-db-ja.com

AjaxデータとレスポンシブでChart.jsを描画します。いくつかの問題と質問

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 }
  );

});

[〜#〜]問題[〜#〜]

  1. ウィンドウのサイズ変更時にチャートのサイズが変更されていません。
  2. これを行うためのより良いコードはありますか?私は多くのコードを繰り返していると思います。
  3. Googleでは、描画は高速です。 Firefoxでは、しばらくハングすることがあります。私のコードに何か問題はありますか?
  4. 要求は非同期である必要がありますか?
16
Miguel Moura

Async AJAXは問題ありません。成功コールバックが起動した後にのみチャートを設定することが重要です。そうしないと、キャンバスコンテキストが定義されていないという問題が発生します。 respondCanvasの呼び出しは初期セットアップを行い、後続の呼び出しはサイズ変更を行います。

ここに私のために働くものがあります:

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();
});

グラフ上に大きなデータセットがある場合、遅延によりサイズ変更の応答性が向上します。

19
Cameron Tinker

chart.jsで設定できます

new Chart(context, {
  type:"line",
  labels: data.Dates,
  datasets: [
    { fillColor: #404040, data: data.Users }
  ]
  options: { responsive: false }
});
5
melon24
  1. 確かに
  2. はい、例を挙げます。
  3. 問題を引き起こす可能性のあるものは見当たりません。ただし、window.resizeが発動して、新しいチャートが必要以上に頻繁にレンダリングされる場合があります。
  4. いいえ(理由はわかりませんが、これは偶然の一致です)。

コード:

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
 )
0
Senjai