[thelist] Sparklines implementation

Courtenay court3nay at gmail.com
Wed Oct 27 23:54:02 CDT 2004


OK, this is where i'm at with this.  The graph displays better with
pixels rather than EMs .

Also, its a long time since I got thrown out of CS, so if someone
wants to send me some nicer graph-drawing algorithm (I think I got it
right, but there's probably better ways) feel free!

Basically we draw a 1-em high graph (you can adjust it) out of SPANs
that are 0.1em high. (numbers subject to change).  The graph is drawn
by moving the spans up (position:relative; bottom: 0.5em).  Also, the
rise is calculated, and the height of the spans are modified.

the graph can be widened (you can adjust that in the code, too) and it
automagically creates the intermediate values to smooth out the graph.

(this code is released under the same creative commons/share alike
attribution license)

oh, and this function handles sparklines as before, and sparkgraphs,
in the same thing. at the moment its in kludge mode, and will be
probably straightened out as I integrate it into something else i'm
working on

also, there's room in there to put words and a current-data-point at
the end, like Mr Tufte has suggested, but I haven't implemented that
yet.

works in: ie6, firefox 1.0pr
-------------------

the styles

.sparkline { 
  display:none; 
  color: #ccc;
  } 
.sparkline span { 
  background-color:#ccc;
  font-size:0.5em;
  position:relative;
  } 
.sparkgraph span {
 position:relative;
 font-size: 0.1em;
 color:white; 
 }   
span.up {
 top:-0.5em;
}
span.dn {
 top:0.5em;
}



the javascript
you can mess with the constants to change the appearance of the graph.

function init()
{
/* constants *'/
  var NORMALIZE_MAX = 10; // number of y-steps. increase for more height
  var GRAPH_SCALE = 4; // number of intermediary x-elements. increase
to make wider.
  var GRAPH_COLOR = '#aaa';
  
  var sparks = document.getElementsByTagName('span');
  for (i=0; i<sparks.length; i++)
  {
	if (sparks[i].className == 'sparkgraph')
	{
	  sparks[i].style.display = 'inline';
	  var values = sparks[i].innerHTML.split(",");
	  var getmax = values[0];
	  /* find the maximum value for the values so we can normalize them */
	  for (j=0; j<values.length; j++)
	  {
	    if (!isNaN(values[j]))
	    getmax = Math.max(values[j], getmax);
	  }	  
	 /* clear out the span, ready for graph */
	  sparks[i].innerHTML = '';
	  /* normalize the values */
	  var graph = new Array();
	  for (j=0; j<values.length; j++) {	    
		if (isNaN(values[j])) break;
	        values[j] = (values[j] / getmax) * NORMALIZE_MAX;
		values[j] -= NORMALIZE_MAX / 3; // center the graph on the line--- ish
		}
	  /* create intermediate values for smoothing */	  
	  /* todo: allow words to be put in here */
	  for (j=0; j<values.length; j++) {
	    if (isNaN(values[j])) {
		  graph[j*GRAPH_SCALE] = values[j];
		  break;
		  }
	    graph[(j*GRAPH_SCALE)] = Math.round(values[j]);
		if (values[j+1])
		  for (k=0; k < GRAPH_SCALE; k++) {
		    graph[(j*GRAPH_SCALE)+k] = Math.round(values[j] + ((values[j+1]
- values[j]) / GRAPH_SCALE) * k) ;
		  }		
	  }
	  for (j=0; j<graph.length; j++) {	 
		if (!isNaN(graph[j])) {
			var newspan = document.createElement('span');
			newspan.className = 'line';
			newspan.style.bottom = (graph[j]) + 'em';
						
			if (graph[j+1]) {
			 var diff = Math.round((graph[j+1] - graph[j]));
			 if (diff > 0)
			 {
			  newspan.style.borderTop = (diff) + 'em solid ' + GRAPH_COLOR;
			  }
			 else if (diff == 0) {
			  newspan.style.borderTop = '1em solid ' + GRAPH_COLOR;
			 }
			 else if (diff < 0) {
			  window.status += diff;
			   newspan.style.bottom = (graph[j] + diff) + 'em';			  
			   newspan.style.borderTop = (-diff) + 'em solid ' + GRAPH_COLOR;			  			  
			  }
			 }
			newspan.innerHTML = '_';
			sparks[i].appendChild(newspan);
		}
		else
		{
/*		  if (graph[j].toString().match(/=[0-9]+$/)) 
		  sparks[i].innerHTML += '<strong>' +
graph[j].toString().match(/[0-9]+$/) + '</strong>';*/

		}
	  }	  
	}

    if (sparks[i].className == 'sparkline')
	{
	  sparks[i].style.display = "inline";
	  var values = sparks[i].innerHTML.split(",");
	  sparks[i].innerHTML = '';
	  for (j=0; j<values.length; j++)
	  {
	    if (values[j] == 1)		
		  sparks[i].innerHTML += '<span class="up">.</span>';
		else if (values[j] == 0)
		  sparks[i].innerHTML += '<span class="dn">.</span>';
		else 
		  sparks[i].innerHTML += values[j];
		
	  }
	}
  }
}


--------

and the implementation





This is an example of <span
class='sparkline'>1,0,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,1,128</span>
sparklines.


This is an example of a <span
class='sparkgraph'>50,128,15,2,2,40,20,60,50,54,92,88,15</span> spark
graph.




On Thu, 28 Oct 2004 16:59:26 +1300, Paul Bennett
<paul at web-business-pack.com> wrote:
> please post!! :)
> 
> 
> 
> Courtenay wrote:
> 
> >I have a (almost) working graph implementation of this, if anyone
> >wants me to post it.
> >
> >interface is:
> >  <span class='sparkgraph'>52,129,62,3,0,100,64</span>
> >
> >output is a nice graph with the pixels created from EM sized divs.
> >
> >On Wed, 27 Oct 2004 17:34:02 -0400, Joshua Olson <joshua at waetech.com> wrote:
> >
> >
> >>>-----Original Message-----
> >>>From: Luther, Ron
> >>>Sent: Wednesday, October 27, 2004 1:56 PM
> >>>
> >>>
> >>>I think it would almost be easier to define and embed a
> >>>'sparkline' font  into your page.
> >>>
> >>>
> >>Ron,
> >>
> >>This sounds like an excellent idea.  Do you mean like a font where each
> >>character is one "pixel" wide and has one "pixel" on the line
> >>highlighted?... Then to generate a graph you'd do something like this:
> >>
> >><span style="font-family: spark;">abcdedefghgfefghijhihgfedefgh</span>
> >>
> >>???
> >>
> >>Sounds like a decent idea to me.  Symantecly, I have my doubts about it's
> >>relevance
> >>
> >>
> 
> --
> 
> * * Please support the community that supports you.  * *
> http://evolt.org/help_support_evolt/
> 
> For unsubscribe and other options, including the Tip Harvester
> and archives of thelist go to: http://lists.evolt.org
> Workers of the Web, evolt !
>


More information about the thelist mailing list