Thanks, Thaddeus. That's a good suggestion. It turns out my case can be simplified considerably by using explicit id's for the sparklines, e.g.
$(function() { $(this).everyTime(1000,function(i) { $.getJSON('/peertool/sparkline/call/json/sparkdata/ 13/0/20', function(data) { $("#dynbar0").sparkline(data.dynbar0, {type: 'bar', barColor: 'green'}); $("#dynbar1").sparkline(data.dynbar1, {type: 'bar', barColor: 'green'}); // etc ... }); }); }); This works because I know how many plots will be needed when the page is rendered by the view, so it's fairly trivial to generate the necessary id's server side. If I were doing something that required consulting a different server to get the data for each plot, then I'd certainly look seriously at writing a plugin. In case it's useful to anyone else, here's a complete working example that's kind of fun to see in action. When you browse to the index page, it puts up between 5 and 25 bar graphs with random values reverse sorted to emulate Pareto charts. The charts update once per second with new data from the server. (WARNING - a few minutes of this drives my MacBook's cpu usage up because I don't have indexing turned off for wherever the json data is going.) 1. web2py_ajax.html - add the sparkline and timer plugins response.files.insert(4,URL(r=request,c='static',f='jquery.sparkline.js')) response.files.insert(5,URL(r=request,c='static',f='jquery.timers-1.2.js')) 2. The controller # coding: utf8 import sys import random def index(): ngraphs = random.choice(range(5,25)) return dict(message="hello from sparkline.py", ngraphs=ngraphs, chartmin=0, chartmax=20) def call(): session.forget() return service() @service.json def sparkdata(ngraphs,chartmin,chartmax): ngraphs = int(ngraphs) chartmin = int(chartmin) chartmax = int(chartmax) sys.stderr.write("\nsparkdata() called with ngraphs=%d\n"%ngraphs) d = dict() for n in xrange(ngraphs): id = "dynbar" + str(n) ## data for bar graph. 9 random ints between chartmax and chartmin data = [random.choice(range(chartmin,chartmax)) for i in xrange(9)] ## simulate a Pareto plot data.sort() data.reverse() d[id] = data sys.stderr.write("\n%s : %s"%(id, str(d[id]))) return d 3. The view (index.html) {{extend 'layout.html'}} {{ chartoptions = "{type: 'bar', barColor: 'green', 'chartRangeMin': '%d', 'chartRangeMax': '%d'}"%(chartmin,chartmax) jsonurl = URL(r=request,f='call/json/sparkdata/%(ngraphs)d/% (chartmin)d/%(chartmax)d'%locals()) }} <script type="text/javascript"> /* <![CDATA[ */ $(function() { $(this).everyTime(1000,function(i) { $.getJSON('{{=jsonurl}}', function(data) { {{for n in xrange(ngraphs):}} $("#dynbar{{=n}}").sparkline(data.dynbar{{=n}}, {{=chartoptions}}); {{pass}} }); }); }); /* ]]> */ </script> <h1>This is the sparkline.html template</h1> {{for n in xrange(ngraphs):}} <p> Bar chart with dynamic data: <span id="dynbar{{=n}}" class="dynamicbar">Loading..</span> </p> {{pass}} {{=BEAUTIFY(response._vars)}} That's it. BTW, sparkline charts are really useful in applications where you need to visually compare lots of similar data series. Here's a link to a chapter in Edward Tufte's "Beautiful Evidence" with more info http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR The JQuery Sparklines plug-in page is also useful. http://omnipotent.net/jquery.sparkline/ Cheers, Mike On May 15, 3:27 pm, Thadeus Burgess <thade...@thadeusb.com> wrote: > For multiple elements you might want to try and put it into a jQuery > plugin, allowing you to re-use the code for each sparkline. > > $(".spark").makeSparkline({url:/path/to/call/sparkdata, args:etc}); > > -- > Thadeus > > On Sat, May 15, 2010 at 1:34 PM, MikeEllis <michael.f.el...@gmail.com> wrote: > > > After spending some time with Firebug to find and fix a couple of > > typos, I've got it working now. There seems to be no way around > > explicitly referring to the SPAN element (see below), but I can live > > with that. > > > Now I need to tackle the next level, which is to expand the server- > > side JSON function to return data for multiple sparklines on a page > > and arrange to call sparkline() with the right data for each of the > > corresponding elements. > > > Thanks again for the help! > > > Here's what's working correctly: > > > In the view ... > > > <script type="text/javascript"> > > /* <![CDATA[ */ > > $(function() { > > $('.dynamicsparkline').everyTime(1000,function(i) { > > var j = 2+i%5; > > $.getJSON('{{=URL(r=request,f='call/json/ > > sparkdata')}}/'+j, function(data) { > > var sparkdata = [10,9,8,7,6,5,4]; > > for(var k=0; k<sparkdata.length; k++) { sparkdata[k] = > > data.a[k];} > > console.log("sparkdata = " + sparkdata); > > $('.dynamicsparkline').sparkline(sparkdata); // WORKS > > // $(this).sparkline(sparkdata) // DOES NOT WORK! > > }); > > }); > > }); > > /* ]]> */ > > </script> > > > <h1>This is the sparkline.html template</h1> > > <p> > > Sparkline with dynamic data: <span class="dynamicsparkline">Loading..</ > > span> > > </ > > p> > > > and in the controller ... > > > @service.json > > def sparkdata(j): > > sys.stderr.write("\nsparkdata() called with j=%d\n"%int(j)) > > j = int(j) > > return dict(a=[n%j for n in [10,9,8,7,6,5,4]]) > > > Cheers, > > Mike > > > On May 14, 9:51 pm, mdipierro <mdipie...@cs.depaul.edu> wrote: > >> aha try replace > > >> $(function() { > >> $('.dynamicsparkline').everyTime(1000,function(i) { > >> $.getJSON('{{=URL(r=request,f='call/json/ > >> datapoints')}}/'+i, function(data) { > >> var b = [0,0,0,0,0,0,0] > >> var j = 2+i%5; > >> for(var k=0; k<b.length; k++) { b[k] = data.a[k] > >> %j;} > >> $(this).sparkline(b); > >> }); > >> }); > >> }); > > >> with > > >> $(function() { > >> $('.dynamicsparkline').each(function(index){ > >> var obj=$(this); > >> obj.everyTime(1000,function(i) { > >> $.getJSON('{{=URL(r=request,f='call/json/ > >> datapoints')}}/'+i, function(data) { > >> var b = [0,0,0,0,0,0,0] > >> var j = 2+i%5; > >> for(var k=0; k<b.length; k++) { b[k] = data.a[k] %j;} > >> obj.sparkline(b); > >> }); > >> }); > >> }); > >> }); > >