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