views:

49

answers:

2

I've got a javascript 101 question.

I'm using a nice graphing library (flot), and plotting multiple graphs on a single page. Each graph is a div, with a attribute set that tells the graph where to grab it's data from. For example, the HTML might be:

<div class="line-chart" data-src='/revenue.js'></div>
<div class="scatter-chart" data-src='/users/byweek.js'></div>
<div class="scatter-chart2" data-src='/apps/byweek.js'></div>

Where I've got two types of charts here, a scatter and line. Ideally I'd be able to iterate over the classes, and simply grab the appropriate data. However, I'm confused by the context of the callback, and not knowing which div I'm actually in, so instead I'm doing this hack in my JS:

$(document).ready(function() {

    $('.line-chart').each(function() {
        $.getJSON($(this).attr('data-src'),
        function(data) {
            $.plot($('.line-chart'), [data], { xaxis: { mode: "time" }});
        });
    });

    $('.scatter-chart').each(function() {
        $.getJSON($(this).attr('data-src'),
        function(data) {
            $.plot($('.scatter-chart'), [data], { xaxis: { mode: "time" },
                             lines: { show: false },
                             points: { show: true }
            });
        });
    });

    $('.scatter-chart2').each(function() {
        $.getJSON($(this).attr('data-src'),
        function(data) {
            $.plot($('.scatter-chart2'), [data], { xaxis: { mode: "time" },
                             lines: { show: false },
                             points: { show: true }
            });
        });
    });
});

I'm sure I can clean this up, I'm just not clear on how to go about doing it. The main problem is that the $.plot needs to apply to the specific chart that the getJSON was called a against, not the first one it finds.

+3  A: 

If you are unsure about the context of the callback, it will probably be cleaner not to use that context anyway. You can use the context of your each() loop instead:

$('.line-chart').each(function() {
  var self = $(this);
  $.getJSON(self.attr('data-src'),
    function(data) {
        $.plot(self, [data], { xaxis: { mode: "time" }});
    });
});
Victor Nicollet
Nice, it was as simple as I feared. That's exactly what I was looking for. Thanks!
teich
A: 
$(function() {

    function plotChart (selector,options) {
        $(selector).each(function() {
            var $this = $(this);
            $.getJSON($this.attr('data-src'), function (data) {
                $.plot($this, [data], options);
            });
        });
    }

    plotChart('.line-chart', { xaxis: { mode: "time" });

    plotChart('.scatter-chart', { xaxis: { mode: "time" },
                                  lines: { show: false },
                                 points: { show: true });

    plotChart('.scatter-chart2', { xaxis: { mode: "time" },
                                   lines: { show: false },
                                  points: { show: true });

});

is quite a bit cleaner.

Rich