Dev.Opera - Follow the standards, break the rulesDev.Opera - Follow the standards, break the rules

Login

Lost password?


graphRenderer.js

Summary

No overview generated for 'graphRenderer.js'


/* 
 * Copyright (c) 2006, Opera Software ASA 
 * All rights reserved. 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met: 
 * 
 *     * Redistributions of source code must retain the above copyright 
 *       notice, this list of conditions and the following disclaimer. 
 *     * Redistributions in binary form must reproduce the above copyright 
 *       notice, this list of conditions and the following disclaimer in the 
 *       documentation and/or other materials provided with the distribution. 
 *     * Neither the name of Opera Software ASA nor the 
 *       names of its contributors may be used to endorse or promote products 
 *       derived from this software without specific prior written permission. 
 * 
 * THIS SOFTWARE IS PROVIDED BY OPERA SOFTWARE ASA AND CONTRIBUTORS ``AS IS'' AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL OPERA SOFTWARE ASA AND CONTRIBUTORS BE LIABLE FOR ANY 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */ 
 
/** 
 *	'lines' graph renderer 
 *	@addon 
 *	@version	0.9 
 *	@param	svg	{SVGElement}	the SVG render target 
 *	@return	{Boolean} 
 */ 
Graph.prototype.renderer_lines = function( svg ) 
{ 
	var	dataRangeObject	= this.getDataRange(), 
		dataRangeNull	= (dataRangeObject.minimum-dataRangeObject.maximum==0), 
		dataMinimum		= dataRangeNull?dataRangeObject.minimum-1:dataRangeObject.minimum, 
		dataMaximum		= dataRangeNull?dataRangeObject.maximum+1:dataRangeObject.maximum, 
		dataRange		= dataMaximum-dataMinimum, 
		labels			= this.getLabels(), 
		dataSets		= this.getDataSets(), 
		labelsLength	= labels.length, 
		svgWidth		= parseFloat(svg.getAttribute('width')), 
		svgHeight		= parseFloat(svg.getAttribute('height')), 
		svgGraphLeft	= 64, 
		svgGraphTop		= 32, 
		svgGraphRight	= 64, 
		svgGraphBottom	= 32, 
		svgGraphWidth	= svgWidth-svgGraphLeft-svgGraphRight, 
		svgGraphHeight	= svgHeight-svgGraphTop-svgGraphBottom, 
		xScale			= svgWidth/labelsLength, 
		yScale			= svgHeight/Math.max(1,dataRange) 
 
	svg.setAttribute( 'style', 'font-weight:normal;font-size:7pt;font-family:arial, sans-serif;' ); 
 
	//	frame 
	svg.appendChild( createSVGElement( 
		'rect', 
		{ 
			x:svgGraphLeft, 
			y:svgGraphTop, 
			width:svgGraphWidth, 
			height:svgGraphHeight, 
			fill:this.bgColor, 
			opacity:.25 
		} 
	) ); 
 
	//	rules, Y 
	var	graduations = Math.max( 2, Math.round( svgGraphHeight/48 ) ); 
	for( var i=0; i<=graduations; i++ ) 
	{ 
		var yi = svgGraphTop+svgGraphHeight*(graduations-i)/graduations; 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:svgGraphLeft-8, 
				y:yi, 
				'text-anchor':'end', 
				opacity:.5 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( parseFloat( (dataMinimum+i*dataRange/graduations).toFixed(2) ) ) ) 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:svgGraphLeft, 
				y1:yi, 
				x2:svgGraphLeft+svgGraphWidth, 
				y2:yi, 
				stroke:'#443', 
				opacity:.125 
			} 
		) ); 
	} 
	if( dataMinimum<0 && dataMaximum>0 ) 
	{ 
		var yi = svgGraphTop+svgGraphHeight*(dataRange+dataMinimum)/dataRange; 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:svgGraphLeft-8, 
				y:yi, 
				'text-anchor':'end', 
				opacity:.25 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( '0' ) ); 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:svgGraphLeft, 
				y1:yi, 
				x2:svgGraphLeft+svgGraphWidth, 
				y2:yi, 
				stroke:'#443', 
				opacity:.125 
			} 
		) ); 
	} 
 
	//	rule, labels 
	for( var i=0; i<labelsLength; i++ ) 
	{ 
		var xi = svgGraphLeft+svgGraphWidth*(labelsLength==1?.5:i)/Math.max(1,labelsLength-1); 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:xi, 
				y:svgGraphTop+svgGraphHeight+16, 
				'text-anchor':'middle', 
				opacity:.5 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( labels[i] ) ) 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:xi, 
				y1:svgGraphTop, 
				x2:xi, 
				y2:svgGraphTop+svgGraphHeight, 
				stroke:'#443', 
				opacity:.125 
			} 
		) ); 
	} 
 
 
 
	//	dataSets 
	for( var j=0,dataSet; dataSet=dataSets[j]; j++ ) 
	{ 
		var randomColor = this.getDataSetColor(j), 
			pointsArray	= [] 
		if( labelsLength==1 ) 
				pointsArray.push( svgGraphLeft+','+(svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[0]-dataMinimum)/dataRange ) ), (svgGraphLeft+svgGraphWidth)+','+(svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[0]-dataMinimum)/dataRange ) ) ) 
		else 
			for( var i=0; i<labelsLength; i++ ) 
				pointsArray.push( (svgGraphLeft+svgGraphWidth*(i/Math.max(1,labelsLength-1))) +','+ (svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[i]-dataMinimum)/dataRange ) ) ) 
 
 
		// dataSet polyline 
		svg.appendChild( createSVGElement( 
			'polyline', 
			{ 
				points:pointsArray.join(' '), 
				fill:'none''stroke-width':2, 
				stroke:randomColor 
			} 
		) ); 
 
		//	dots 
		for( var i=0; i<labelsLength; i++ ) 
		{ 
			var X = (labelsLength==1?svgGraphLeft+svgGraphWidth/2:svgGraphLeft+svgGraphWidth*(i/Math.max(1,labelsLength-1))), 
				Y = (svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[i]-dataMinimum)/dataRange ) ); 
			svg.appendChild( createSVGElement( 
				'circle', 
				{ 
					r:3, 
					cx:X, 
					cy:Y, 
					fill:randomColor, 
					'stroke-width':1, 
					stroke:'#fff', 
					onmouseover:'this.nextSibling.setAttribute("visibility","visible")', 
					onmouseout:'this.nextSibling.setAttribute("visibility","hidden")' 
				} 
			) ); 
 
			svg.appendChild( createSVGElement( 
				'text', 
				{ 
					x:X, 
					y:Y-4, 
					'text-anchor':'end', 
					fill:'#000', 
					visibility:'hidden' 
				} 
			) ); 
			svg.lastChild.appendChild( document.createTextNode( dataSet.data[i] ) ); 
 
		} 
 
		//	dataSet id 
		if( dataSet.id && dataSet.id!='' ) 
		{ 
			svg.appendChild( createSVGElement( 
				'text', 
				{ 
					x:svgGraphLeft+svgGraphWidth+4, 
					y:(svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[labelsLength-1]-dataMinimum)/dataRange ) ), 
					style:'font-weight:bold;', 
					fill:randomColor 
				} 
			) ); 
			svg.lastChild.appendChild( document.createTextNode( dataSet.id ) ) 
		} 
 
	} 
 
	//	title 
	svg.appendChild( createSVGElement( 
		'text', 
		{ 
			x:svgWidth/2, 
			y:svgGraphTop*.75, 
			'text-anchor':'middle', 
			style:'font-size:1.5em;font-weight:bold;font-style:italic;', 
			fill:'#000' 
 
		} 
	) ); 
	svg.lastChild.appendChild( document.createTextNode( this.title ) ) 
 
	return true; 
} 
 
/** 
 *	'lines' graph renderer 
 *	@addon 
 *	@version	0.9 
 *	@param	svg	{SVGElement}	the SVG render target 
 *	@return	{Boolean} 
 */ 
Graph.prototype.renderer_lines_with_dataSet_ID = function( svg ) 
{ 
	var	dataRangeObject	= this.getDataRange(), 
		dataRangeNull	= (dataRangeObject.minimum-dataRangeObject.maximum==0), 
		dataMinimum		= dataRangeNull?dataRangeObject.minimum-1:dataRangeObject.minimum, 
		dataMaximum		= dataRangeNull?dataRangeObject.maximum+1:dataRangeObject.maximum, 
		dataRange		= dataMaximum-dataMinimum, 
		labels			= this.getLabels(), 
		dataSets		= this.getDataSets(), 
		labelsLength	= labels.length, 
		svgWidth		= parseFloat(svg.getAttribute('width')), 
		svgHeight		= parseFloat(svg.getAttribute('height')), 
		svgGraphLeft	= 32, 
		svgGraphTop		= 48, 
		svgGraphRight	= 4, 
		svgGraphBottom	= 16, 
		svgGraphWidth	= svgWidth-svgGraphLeft-svgGraphRight, 
		svgGraphHeight	= svgHeight-svgGraphTop-svgGraphBottom, 
		xScale			= svgWidth/labelsLength, 
		yScale			= svgHeight/Math.max(1,dataRange) 
 
	svg.setAttribute( 'style', 'font-weight:normal;font-size:7pt;font-family:arial, sans-serif;' ); 
 
	//	title 
	svg.appendChild( createSVGElement( 
		'text', 
		{ 
			x:svgWidth/2, 
			y:svgGraphTop*.75, 
			'text-anchor':'middle', 
			style:'font-size:1.5em;font-weight:bold;font-style:italic;', 
			fill:'#000' 
 
		} 
	) ); 
	svg.lastChild.appendChild( document.createTextNode( this.title ) ) 
 
	//	frame 
	svg.appendChild( createSVGElement( 
		'rect', 
		{ 
			x:svgGraphLeft, 
			y:svgGraphTop, 
			width:svgGraphWidth, 
			height:svgGraphHeight, 
			fill:this.bgColor, 
			opacity:.25 
		} 
	) ); 
	//	rules, Y 
	var	precision, 
		tmpPrecision	= 1; 
	while( Math.round(dataRange/tmpPrecision)>20 )		tmpPrecision *= 10; 
	precision		= tmpPrecision; 
	tmpPrecision	= .5; 
	while( Math.round(dataRange/tmpPrecision)>20 )		tmpPrecision *= 10; 
	precision		= Math.min( tmpPrecision, precision ); 
 
	yValue = dataMinimum; 
	while( yValue!= dataMaximum+precision ) 
	{ 
		if( yValue>dataMaximum ) 
			yValue = dataMaximum; 
		else if( yValue!=dataMinimum ) 
			yValue	= Math.floor( yValue/precision )*precision, 
 
		var yi		= svgGraphTop+svgGraphHeight*(dataMaximum-yValue)/dataRange; 
 
		if( yValue>dataMinimum && yValue<dataMaximum ) 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:svgGraphLeft-4, 
				y:yi, 
				'text-anchor':'end', 
				opacity:.5 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( yValue ) ) 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:svgGraphLeft, 
				y1:yi, 
				x2:svgGraphLeft+svgGraphWidth, 
				y2:yi, 
				stroke:'#443', 
				opacity:.125 
			} 
		) ); 
		yValue += precision 
	} 
 
 
	//	rule, labels 
	for( var i=0; i<labelsLength; i++ ) 
	{ 
		var xi = svgGraphLeft+svgGraphWidth*(labelsLength==1?.5:i)/Math.max(1,labelsLength-1); 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:xi, 
				y:svgGraphTop+svgGraphHeight+16, 
				'text-anchor':'middle', 
				opacity:.5 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( labels[i] ) ) 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:xi, 
				y1:svgGraphTop, 
				x2:xi, 
				y2:svgGraphTop+svgGraphHeight, 
				stroke:'#443', 
				opacity:.125 
			} 
		) ); 
	} 
 
 
 
	//	dataSets 
	for( var j=0,dataSet; dataSet=dataSets[j]; j++ ) 
	{ 
		var randomColor = this.getDataSetColor(j), 
			pointsArray	= [] 
		if( labelsLength==1 ) 
				pointsArray.push( svgGraphLeft+','+(svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[0]-dataMinimum)/dataRange ) ), (svgGraphLeft+svgGraphWidth)+','+(svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[0]-dataMinimum)/dataRange ) ) ) 
		else 
			for( var i=0; i<labelsLength; i++ ) 
				pointsArray.push( (svgGraphLeft+svgGraphWidth*(i/Math.max(1,labelsLength-1))) +','+ (svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[i]-dataMinimum)/dataRange ) ) ) 
 
 
		// dataSet polyline 
		svg.appendChild( createSVGElement( 
			'polyline', 
			{ 
				points:pointsArray.join(' '), 
				fill:'none''stroke-width':2, 
				stroke:randomColor 
			} 
		) ); 
 
		//	dots 
		for( var i=0; i<labelsLength; i++ ) 
		{ 
			var X = (labelsLength==1?svgGraphLeft+svgGraphWidth/2:svgGraphLeft+svgGraphWidth*(i/Math.max(1,labelsLength-1))), 
				Y = (svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[i]-dataMinimum)/dataRange ) ); 
			svg.appendChild( createSVGElement( 
				'circle', 
				{ 
					r:3, 
					cx:X, 
					cy:Y, 
					fill:randomColor, 
					'stroke-width':1, 
					stroke:'#fff', 
					onmouseover:'this.nextSibling.setAttribute("visibility","visible")', 
					onmouseout:'this.nextSibling.setAttribute("visibility","hidden")' 
				} 
			) ); 
 
			svg.appendChild( createSVGElement( 
				'g', 
				{ 
					visibility:'hidden' 
				} ) ); 
 
 
			for( var jj=0; jj<dataSets.length; jj++ ) 
			{ 
				var txt = dataSets[jj].data[i] +'  '+ dataSets[jj].id; 
				svg.lastChild.appendChild( createSVGElement( 
					'text', 
					{ 
						x:X, 
						y:Y-6-jj*12, 
						fill:'#fff', 
						stroke:'#fff''stroke-width':4, 
						'text-anchor':(i>=labelsLength/2?'end':'start') 
					} 
				) ); 
				svg.lastChild.lastChild.appendChild( document.createTextNode( txt ) ); 
				svg.lastChild.appendChild( createSVGElement( 
					'text', 
					{ 
						x:X, 
						y:Y-6-jj*12, 
						fill:jj==j?'#000':'#999''text-anchor':(i>=labelsLength/2?'end':'start') 
					} 
				) ); 
				svg.lastChild.lastChild.appendChild( document.createTextNode( txt ) ); 
			} 
		} 
 
	} 
 
	return true; 
} 
 
/** 
 *	'pie' graph renderer 
 *	@addon 
 *	@version	1.0 
 *	@param	svg	{SVGElement}	the SVG render target 
 *	@return	{Boolean} 
 */ 
Graph.prototype.renderer_pie = function( svg ) 
{ 
	var dataRangeObject	= this.getDataRange(), 
		dataRangeNull	= (dataRangeObject.minimum-dataRangeObject.maximum==0), 
		dataMinimum		= dataRangeNull?dataRangeObject.minimum-1:dataRangeObject.minimum, 
		dataMaximum		= dataRangeNull?dataRangeObject.maximum+1:dataRangeObject.maximum, 
		dataRange		= dataMaximum-dataMinimum, 
		labels			= this.getLabels(), 
		dataSets		= this.getDataSets(), 
		labelsLength	= labels.length, 
		svgWidth		= parseFloat(svg.getAttribute('width')), 
		svgHeight		= parseFloat(svg.getAttribute('height')), 
		svgGraphLeft	= 64, 
		svgGraphTop		= 32, 
		svgGraphRight	= 64, 
		svgGraphBottom	= 32, 
		svgGraphWidth	= svgWidth-svgGraphLeft-svgGraphRight, 
		svgGraphHeight	= svgHeight-svgGraphTop-svgGraphBottom, 
		xScale			= svgWidth/labelsLength, 
		yScale			= svgHeight/Math.max(1,dataRange), 
		svgGraphCenterX = svgGraphLeft+svgGraphWidth/2, 
		svgGraphCenterY = svgGraphTop+svgGraphHeight/2 
 
	svg.setAttribute( 'style', 'font-weight:normal;font-size:8pt;font-family:arial, sans-serif;' ); 
 
	var G 			= createSVGElement( 'g', { 'transform':'translate('+ svgGraphCenterX +','+ svgGraphCenterY +')' } ); 
	svg.appendChild( G ); 
 
	G.alignSlices = function( sliceIndex ) 
	{ 
		for( var i=0,g; g=this.childNodes[i]; i++ ) 
			g.setAttribute( 'transform', 'rotate('+ g.angleArray[ sliceIndex ] +')' ); 
	} 
	G.setValueLabels = function( depth ) 
	{ 
		for( var i=0; i<this.childNodes[ depth ].valueArray.length; i++ ) 
			this.firstChild.childNodes[ 1+i*3 ].lastChild.nodeValue =  this.childNodes[ depth ].valueArray[ i ]; 
	} 
 
	//	dataSets 
	var maxR = Math.min( svgGraphWidth, svgGraphHeight )/2; 
	for( var i=0; i<labelsLength; i++ ) 
	{ 
		var	R	= maxR*(labelsLength-i)/labelsLength; 
		var	R2	= maxR*(labelsLength-1-i)/labelsLength; 
 
		var g 			= createSVGElement( 'g' ); 
 
		var	an			= 0, 
			sum			= 0, 
			angleArray	= [], 
			valueArray	= [] 
		for( var j=0,dataSet; dataSet=dataSets[j]; j++ ) 
			sum += dataSet.data[i]; 
 
		sum = sum.toFixed( 3 ).replace( /\.?0+$/g, '' ); 
		for( var j=0,dataSet; dataSet=dataSets[j]; j++ ) 
		{ 
			var anOld		= an; 
			angleArray.push( -an*180/Math.PI ); 
			valueArray.push( dataSet.data[i]+' / '+ sum ); 
			an += dataSet.data[i]*Math.PI*2/sum; 
 
 
 
			if( !i && dataSet.id && dataSet.id!='' ) 
			{ 
				//	dataSet id 
				g.appendChild( createSVGElement( 
					'text', 
					{ 
						x:maxR, 
						y:0, 
						style:'font-weight:bold;', 
						transform:'rotate('+Math.round((an+anOld)/2*180/Math.PI)+')', 
						fill:'#000', 
						opacity:.75 
					} 
				) ); 
				g.lastChild.appendChild( document.createTextNode( dataSet.id ) ) 
				g.appendChild( createSVGElement( 
					'text', 
					{ 
						x:maxR, 
						y:12, 
						transform:'rotate('+Math.round((an+anOld)/2*180/Math.PI)+')', 
						fill:'#000', 
						opacity:.5 
					} 
				) ); 
				g.lastChild.appendChild( document.createTextNode( valueArray[ j ] ) ) 
			} 
 
 
			var bla = 'M '+ (svgGraphCenterX*0+R*Math.cos(anOld)) +','+ (svgGraphCenterY*0+R*Math.sin(anOld)); 
				subdivision = Math.max( 1, Math.round( (an-anOld)*32/Math.PI ) ); 
			for( var k=1; k<=subdivision; k++ ) 
				bla += ' L '+ (svgGraphCenterX*0+R*Math.cos(anOld+(an-anOld)*k/subdivision)) +','+ (svgGraphCenterY*0+R*Math.sin(anOld+(an-anOld)*k/subdivision)); 
			for( k=subdivision ;k>=0; k-- ) 
				bla += ' L '+ (svgGraphCenterX*0+R2*Math.cos(anOld+(an-anOld)*k/subdivision)) +','+ (svgGraphCenterY*0+R2*Math.sin(anOld+(an-anOld)*k/subdivision)); 
			bla += ' z'; 
 
 
			// dataSet 
			g.appendChild( createSVGElement( 'path', 
				{ 
					d: bla, 
					fill:this.getDataSetColor(j), 
					'stroke-width':1, 
					style:'cursor:pointer', 
					stroke:'#ffe', 
					onclick:'this.parentNode.parentNode.alignSlices('+ j +')', 
					onmouseover:'this.parentNode.parentNode.setValueLabels('+ i +')' 
 
				} 
			) ); 
			g.lastChild.title = dataSet.data[i] +' / '+ sum; 
		} 
		g.angleArray = angleArray; 
		g.valueArray = valueArray 
		G.appendChild( g ); 
	} 
 
	//	title 
	svg.appendChild( createSVGElement( 
		'text', 
		{ 
			x:svgWidth/2, 
			y:svgGraphTop*.75, 
			'text-anchor':'middle', 
			style:'font-size:1.5em;font-weight:bold;font-style:italic;', 
			fill:'#000' 
 
		} 
	) ); 
	svg.lastChild.appendChild( document.createTextNode( this.title ) ) 
 
	return true; 
} 
 
 
/** 
 *	'bars' graph renderer 
 *	@addon 
 *	@version	1.0 
 *	@param	svg	{SVGElement}	the SVG render target 
 *	@return	{Boolean} 
 */ 
Graph.prototype.renderer_bars = function( svg ) 
{ 
	var	dataRangeObject	= this.getDataRange(), 
		dataRangeNull	= (dataRangeObject.minimum-dataRangeObject.maximum==0), 
		dataMinimum		= dataRangeNull?dataRangeObject.minimum-1:dataRangeObject.minimum, 
		dataMaximum		= dataRangeNull?dataRangeObject.maximum+1:dataRangeObject.maximum, 
		dataRange		= dataMaximum-dataMinimum, 
		labels			= this.getLabels(), 
		dataSets		= this.getDataSets(), 
		labelsLength	= labels.length, 
		svgWidth		= parseFloat(svg.getAttribute('width')), 
		svgHeight		= parseFloat(svg.getAttribute('height')), 
		svgGraphLeft	= 64, 
		svgGraphTop		= 32, 
		svgGraphRight	= 64, 
		svgGraphBottom	= 32, 
		svgGraphWidth	= svgWidth-svgGraphLeft-svgGraphRight, 
		svgGraphHeight	= svgHeight-svgGraphTop-svgGraphBottom, 
		xScale			= svgWidth/labelsLength, 
		yScale			= svgHeight/Math.max(1,dataRange), 
		y0; 
 
	svg.setAttribute( 'style', 'font-weight:normal;font-size:7pt;font-family:arial, sans-serif;' ); 
 
 
	// dataSet gradients 
	var defs = createSVGElement( 'defs' ); 
	for( var i=0; i<dataSets.length; i++ ) 
	{ 
		var c = this.getDataSetColor(i); 
		defs.appendChild( createSVGElement( 
			'linearGradient', 
			{ 
				id:'gradientForLabel'+ i, 
				x1:0, 
				y1:0, 
				x2:0, 
				y2:'75%' 
			} 
		) ); 
		defs.lastChild.appendChild( createSVGElement( 
			'stop', 
			{ 
				offset:'0%''stop-color':c, 
				'stop-opacity':1 
			} 
		) ); 
		defs.lastChild.appendChild( createSVGElement( 
			'stop', 
			{ 
				offset:'25%''stop-color':c, 
				'stop-opacity':.25 
			} 
		) ); 
		defs.lastChild.appendChild( createSVGElement( 
			'stop', 
			{ 
				offset:'100%''stop-color':c, 
				'stop-opacity':0 
			} 
		) ); 
		//	flipped 
		defs.appendChild( createSVGElement( 
			'linearGradient', 
			{ 
				id:'gradientForLabel'+ i +'flipped', 
				x1:0, 
				y1:'100%', 
				x2:0, 
				y2:'25%' 
			} 
		) ); 
		defs.lastChild.appendChild( createSVGElement( 
			'stop', 
			{ 
				offset:'0%''stop-color':c, 
				'stop-opacity':1 
			} 
		) ); 
		defs.lastChild.appendChild( createSVGElement( 
			'stop', 
			{ 
				offset:'25%''stop-color':c, 
				'stop-opacity':.25 
			} 
		) ); 
		defs.lastChild.appendChild( createSVGElement( 
			'stop', 
			{ 
				offset:'100%''stop-color':c, 
				'stop-opacity':0 
			} 
		) ); 
	} 
	svg.appendChild( defs ); 
 
 
	//	frame 
	svg.appendChild( createSVGElement( 
		'rect', 
		{ 
			x:svgGraphLeft, 
			y:svgGraphTop, 
			width:svgGraphWidth, 
			height:svgGraphHeight, 
			fill:this.bgColor, 
			opacity:.25 
		} 
	) ); 
	//	rules, Y 
	var	graduations = Math.max( 2, Math.round( svgGraphHeight/48 ) ); 
	for( var i=0; i<=graduations; i++ ) 
	{ 
		var yi = svgGraphTop+svgGraphHeight*(graduations-i)/graduations; 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:svgGraphLeft-8, 
				y:yi, 
				'text-anchor':'end', 
				opacity:.5 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( parseFloat( (dataMinimum+i*dataRange/graduations).toFixed(2) ) ) ); 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:svgGraphLeft, 
				y1:yi, 
				x2:svgGraphLeft+svgGraphWidth, 
				y2:yi, 
				stroke:'#443', 
				opacity:.125 
			} 
		) ); 
	} 
	//	ruler Y = 0 
	if( dataMinimum<0 && dataMaximum>0 ) 
	{ 
		y0 = svgGraphTop+svgGraphHeight*(dataRange+dataMinimum)/dataRange; 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:svgGraphLeft-8, 
				y:y0, 
				'text-anchor':'end', 
				opacity:.75 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( '0' ) ); 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:svgGraphLeft, 
				y1:y0, 
				x2:svgGraphLeft+svgGraphWidth, 
				y2:y0, 
				stroke:'#443', 
				opacity:.625 
			} 
		) ); 
	} 
 
 
	//	rule, labels 
	for( var i=0; i<labelsLength; i++ ) 
	{ 
		var xi = svgGraphLeft+svgGraphWidth*(labelsLength==1?.5:i+.5)/Math.max(1,labelsLength); 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:xi, 
				y:svgGraphTop+svgGraphHeight+16, 
				'text-anchor':'middle', 
				opacity:.5 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( labels[i] ) ) 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:xi, 
				y1:svgGraphTop, 
				x2:xi, 
				y2:svgGraphTop+svgGraphHeight, 
				stroke:'#443', 
				opacity:.125 
			} 
		) ); 
	} 
 
 
 
	// dataSet rect 
	for( var i=0; i<labelsLength; i++ ) 
	{ 
		//	dataSets 
		var	dataSetsBars = [] 
		for( var j=0,dataSet; dataSet=dataSets[j]; j++ ) 
		{ 
			x1 = (svgGraphLeft+svgGraphWidth*((i+.125)/Math.max(1,labelsLength))) 
			x2 = (svgGraphLeft+svgGraphWidth*((i+.875)/Math.max(1,labelsLength))) 
 
			if( dataSet.data[i]<0 ) 
			{ 
				y1 = typeof(y0)!='undefined'?y0:svgGraphTop; 
				y2 = (svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[i]-dataMinimum)/dataRange ) ); 
			} 
			else 
			{ 
				y1 = (svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[i]-dataMinimum)/dataRange ) ); 
				y2 = typeof(y0)!='undefined'?y0:svgGraphTop+svgGraphHeight; 
			} 
 
 
			var g = createSVGElement( 'g' ), 
				randomColor = this.getDataSetColor(j); 
 
			g.appendChild( createSVGElement( 
				'rect', 
				{ 
					x:x1, 
					y:y1, 
					width:x2-x1, 
					height:y2-y1, 
					fill:'url(#gradientForLabel'+j+(dataSet.data[i]<0?'flipped':'') +')', 
					stroke:'none', 
					onmouseover:'this.parentNode.lastChild.setAttribute("visibility","visible")', 
					onmouseout:'this.parentNode.lastChild.setAttribute("visibility","hidden")' 
				} 
			) ); 
			g.appendChild( createSVGElement( 
				'line', 
				{ 
					'x1':x1, 
					'y1':dataSet.data[i]<0?y2:y1, 
					'x2':x2, 
					'y2':dataSet.data[i]<0?y2:y1, 
					fill:'none''stroke-width':2, 
					stroke:randomColor, 
					onmouseover:'this.parentNode.lastChild.setAttribute("visibility","visible")', 
					onmouseout:'this.parentNode.lastChild.setAttribute("visibility","hidden")' 
				} 
			) ); 
			g.appendChild( createSVGElement( 
				'text', 
				{ 
					x:(x1+x2)/2, 
					y:(dataSet.data[i]<0?y1-1:y2+9), 
					'text-anchor':'middle', 
					style:'font-weight:bold;', 
					fill:'#0000', 
					visibility:'hidden' 
				} 
			) ); 
			g.lastChild.appendChild( document.createTextNode( dataSet.data[i] ) ) 
 
 
			dataSetsBars.push( { order:y1,element:g } ); 
 
			//	dataSet id 
			if( i==labelsLength-1 && dataSet.id && dataSet.id!='' ) 
			{ 
				svg.appendChild( createSVGElement( 
					'text', 
					{ 
						x:svgGraphLeft+svgGraphWidth+4, 
						y:(svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[labelsLength-1]-dataMinimum)/dataRange ) ), 
						style:'font-weight:bold;', 
						fill:randomColor, 
						opacity:1 
 
					} 
				) ); 
				svg.lastChild.appendChild( document.createTextNode( dataSet.id ) ) 
			} 
		} 
 
		dataSetsBars.sort( function( a, b ){ return a.order-b.order; }); 
		while( dataSetsBars.length ) 
			svg.appendChild( dataSetsBars.shift().element ); 
 
	} 
 
	//	title 
	svg.appendChild( createSVGElement( 
		'text', 
		{ 
			x:svgWidth/2, 
			y:svgGraphTop*.75, 
			'text-anchor':'middle', 
			style:'font-size:1.5em;font-weight:bold;font-style:italic;', 
			fill:'#000' 
 
		} 
	) ); 
	svg.lastChild.appendChild( document.createTextNode( this.title ) ) 
 
	return true; 
} 
 
 
/** 
 *	'accumulatedLines' graph renderer 
 *	@addon 
 *	@version	0.1 
 *	@param	svg	{SVGElement}	the SVG render target 
 *	@return	{Boolean} 
 */ 
Graph.prototype.renderer_accumulatedLines = function( svg ) 
{ 
	var	dataRangeObject	= this.getDataRange(), 
		dataRangeNull	= (dataRangeObject.minimum-dataRangeObject.maximum==0), 
		dataMinimum		= dataRangeNull?dataRangeObject.minimum-1:dataRangeObject.minimum, 
		dataMaximum		= dataRangeNull?dataRangeObject.maximum+1:dataRangeObject.maximum, 
		dataRange		= dataMaximum-dataMinimum, 
		labels			= this.getLabels(), 
		dataSets		= this.getDataSets(), 
		labelsLength	= labels.length, 
		svgWidth		= parseFloat(svg.getAttribute('width')), 
		svgHeight		= parseFloat(svg.getAttribute('height')), 
		svgGraphLeft	= 64, 
		svgGraphTop		= 32, 
		svgGraphRight	= 64, 
		svgGraphBottom	= 32, 
		svgGraphWidth	= svgWidth-svgGraphLeft-svgGraphRight, 
		svgGraphHeight	= svgHeight-svgGraphTop-svgGraphBottom, 
		xScale			= svgWidth/labelsLength, 
		yScale			= svgHeight/Math.max(1,dataRange) 
 
	svg.setAttribute( 'style', 'font-weight:normal;font-size:7pt;font-family:arial, sans-serif;' ); 
 
 
	//	frame 
	svg.appendChild( createSVGElement( 
		'rect', 
		{ 
			x:svgGraphLeft, 
			y:svgGraphTop, 
			width:svgGraphWidth, 
			height:svgGraphHeight, 
			fill:this.bgColor, 
			opacity:.25 
		} 
	) ); 
 
	//	dataSets 
	for( var j=0,dataSet; dataSet=dataSets[j]; j++ ) 
	{ 
		var pointsArray = [] 
 
 
		if( labelsLength==1 ) 
				pointsArray.push( svgGraphLeft+','+(svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[0]-dataMinimum)/dataRange ) ), (svgGraphLeft+svgGraphWidth)+','+(svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[0]-dataMinimum)/dataRange ) ) ); 
		else 
			for( var i=0; i<labelsLength; i++ ) 
				pointsArray.push( (svgGraphLeft+svgGraphWidth*(i/Math.max(1,labelsLength-1))) +','+ (svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[i]-dataMinimum)/dataRange ) ) ); 
 
 
 
		svg.appendChild( createSVGElement( 'g' ) ) 
 
		// dataSet polyline 
		var c = this.getDataSetColor(j); 
 
		svg.lastChild.appendChild( createSVGElement( 
			'polyline', 
			{ 
				points:pointsArray.join(' '), 
				fill:'none''stroke-width':2, 
				stroke:c 
			} 
		) ); 
 
		pointsArray.unshift( svgGraphLeft+','+(svgGraphTop+svgGraphHeight) ); 
		pointsArray.push( (svgGraphLeft+svgGraphWidth)+','+(svgGraphTop+svgGraphHeight) ); 
		svg.lastChild.appendChild( createSVGElement( 
			'polyline', 
			{ 
				points:pointsArray.join(' '), 
				fill:c, 
				stroke:'none', 
				opacity:.125 
			} 
		) ); 
 
		//	dataSet id 
		if( dataSet.id && dataSet.id!='' ) 
		{ 
			svg.lastChild.appendChild( createSVGElement( 
				'text', 
				{ 
					x:svgGraphLeft+svgGraphWidth+4, 
					y:(svgGraphTop+svgGraphHeight-svgGraphHeight*( (dataSet.data[labelsLength-1]-dataMinimum)/dataRange ) ), 
					style:'font-weight:bold;', 
					fill:'#000', 
					opacity:.5 
 
				} 
			) ); 
			svg.lastChild.lastChild.appendChild( document.createTextNode( dataSet.id ) ) 
		} 
 
	} 
 
	//	title 
	svg.appendChild( createSVGElement( 
		'text', 
		{ 
			x:svgWidth/2, 
			y:svgGraphTop*.75, 
			'text-anchor':'middle', 
			style:'font-size:1.5em;font-weight:bold;font-style:italic;', 
			fill:'#000' 
 
		} 
	) ); 
	svg.lastChild.appendChild( document.createTextNode( this.title ) ) 
	//	rules, Y 
	var	graduations = Math.max( 2, Math.round( svgGraphHeight/48 ) ); 
	for( var i=0; i<=graduations; i++ ) 
	{ 
		var yi = svgGraphTop+svgGraphHeight*(graduations-i)/graduations; 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:svgGraphLeft-8, 
				y:yi, 
				'text-anchor':'end', 
				opacity:.5 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( parseFloat( (dataMinimum+i*dataRange/graduations).toFixed(2) ) ) ) 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:svgGraphLeft, 
				y1:yi, 
				x2:svgGraphLeft+svgGraphWidth, 
				y2:yi, 
				stroke:'#443', 
				opacity:.125 
			} 
		) ); 
	} 
 
	//	rule, labels 
	for( var i=0; i<labelsLength; i++ ) 
	{ 
		var xi = svgGraphLeft+svgGraphWidth*(labelsLength==1?.5:i)/Math.max(1,labelsLength-1); 
		svg.appendChild( createSVGElement( 
			'text', 
			{ 
				x:xi, 
				y:svgGraphTop+svgGraphHeight+16, 
				'text-anchor':'middle', 
				opacity:.5 
			} 
		) ); 
		svg.lastChild.appendChild( document.createTextNode( labels[i] ) ) 
		svg.appendChild( createSVGElement( 
			'line', 
			{ 
				x1:xi, 
				y1:svgGraphTop, 
				x2:xi, 
				y2:svgGraphTop+svgGraphHeight, 
				stroke:'#443', 
				opacity:.125 
			} 
		) ); 
	} 
	//	<text x='35' y='210' style='text-anchor:end;fill:'>200</text> 
	//	<polyline fill="none" stroke="blue" stroke-width="10"  points="50,375 150,375 150,325 250,325 250,375 1150,375" /> 
 
 
 
	//	WIP!!!!!!! 
	svg.appendChild(	createSVGElement('line',{x1:0+Math.random()*32,y1:0+Math.random()*32,x2:svgWidth-Math.random()*32,y2:svgHeight-Math.random()*32,stroke:'#000','stroke-width':32,opacity:.67}) ); 
	svg.appendChild(	createSVGElement('line',{x1:0+Math.random()*32,y2:0+Math.random()*32,x2:svgWidth-Math.random()*32,y1:svgHeight-Math.random()*32,stroke:'#000','stroke-width':32,opacity:.67}) ); 
 
	return true; 
}


Documentation generated by JSDoc on Tue Oct 24 12:57:37 2006

Libraries