4

I'm using a great visualization library called d3 and I'm finding myself with code that looks very much like the following all over the place:

<span id="sparkline"></span>
<script type="text/javascript">
  drawSparkline('#target', [10, 20, 30, 40]);
  // or
  drawSparkline('#target', 'http://data.com/location'));
</script>

Is there a way to make this more expressive by embedding the code that acts on the dom element directly as an attribute? Perhaps something like this:

<span onload="drawSparkline(this, [10, 20, 30, 40])"></span>
<span onload="drawSparkline(this, 'http://data.com/location')"></span>

Perhaps something like:

<span data-onload="drawSparkline(this, [10, 20, 30, 40])"></span> 

With something at the beginning in jQuery like:

$(document).ready(function() {
  $('*[data-onload]').each( eval the onload? );
});

What would be the appropriate way?

Ricardo Marimon
  • 10,339
  • 9
  • 52
  • 59

2 Answers2

1

I would be more explicit about the different types of data that you're encoding:

<span class="sparkline" data-values="10,20,30,40"></span>
<span class="sparkline" data-url="http://data.com/location"></span>

Then, when you're iterating over them, check for specific types of data:

$(".sparkline").each(function() {
    var $source = $(this),
        values = $source.data("values"),
        url = $source.data("url");
    if (values) {
        // JSON.parse() is okay too, but if you're just
        // encoding lists of numbers this will be faster
        var data = values.split(", ").map(parseFloat);
        drawSparkline(this, data);
    } else if (url) {
        var that = this;
        $.ajax(url)
            .then(function(data) {
                drawSparkline(that, data);
            });
    }
});

I'd also suggest that you check out Sparky (it's on github) if you want to save yourself some time and have them work in IE. :)

Shawn Allen
  • 4,994
  • 2
  • 17
  • 10
0

Instead of using eval you could identify the spans with a class like this:

<span class="sparkLine" data-sparkdata="[10, 20, 30, 40]"></span>
<span class="sparkLine" data-sparkdata="http://data.com/location"></span>

and then, with jQuery:

$(document).ready(function() {
   $('.sparkLine').each( function(){
      drawSparkline(this, $(this).data("sparkdata"));
   });
});
nicosantangelo
  • 13,216
  • 3
  • 33
  • 47
  • Sometimes are sparklines, some other times are mini pie charts. Having classes for all of them seem odd. – Ricardo Marimon Nov 18 '11 at 03:32
  • Oh, well, you can do $('[data-sparkdata]') instead of $('.sparkLine') and the same code will work (or, if you can, $("something").find('[data-sparkdata]') ) – nicosantangelo Nov 18 '11 at 03:40
  • I think this is a pretty good approach, but note that you're getting a string from the attribute, so in the array case you'll need to do something like `JSON.parse($(this).data(sparkdata))`. – nrabinowitz Nov 19 '11 at 16:20
  • I'm testing this approach, but I would really like to have something that would work for any javascript snippet. I might have to go with the eval version unless I can find something more secure. – Ricardo Marimon Nov 19 '11 at 17:56
  • 1
    @nrabinowitz jQuery does that by himself, check this http://goo.gl/5Z7mV . I don't know if it can help you, but you can add an attribute that can be the method itself and then use that, quick example: window[jQuert("#something").data("method")]() – nicosantangelo Nov 19 '11 at 19:18