if ( !parent )
{
parent = top;
};
var SVGDocument = null;
var SVGRoot = null;
var svgns = 'http://www.w3.org/2000/svg';
var xlinkns = 'http://www.w3.org/1999/xlink';
var ChartRoot = null;
var ChartCanvas = null;
var TextWrapBuffer = null;
var DataBuffer = null;
var Stats = null;
var Defs = null;
//tooltip globals
var lastElement = null;
var titleText = '';
var titleDesc = '';
var toolTip = null;
var TrueCoords = null;
var tipBox = null;
var tipText = null;
var tipTitle = null;
var tipDesc = null;
var monthNamesArray = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];
var dayNamesArray = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ];
var AnnotationArea = null;
var Backdrop = null;
var ToolPanel = null;
var controlsArea = null;
function Init(evt)
{
SVGDebug( 'entering Init', 1 );
//buh()
SVGDocument = evt.target.ownerDocument;
SVGRoot = SVGDocument.documentElement;
InitCharts();
SVGDebug( 'exiting Init', 1 );
};
function InitCharts()
{
SVGDebug( 'entering InitCharts', 1 );
ChartRoot = SVGDocument.getElementById('ChartRoot');
TextWrapBuffer = SVGDocument.getElementById('TextWrapBuffer');
DataBuffer = SVGDocument.getElementById('DataBuffer');
Defs = SVGDocument.getElementById('Defs');
//tooltip globals
TrueCoords = SVGRoot.createSVGPoint();
toolTip = SVGDocument.getElementById('ToolTip');
tipBox = SVGDocument.getElementById('tipbox');
tipText = SVGDocument.getElementById('tipText');
tipTitle = SVGDocument.getElementById('tipTitle');
tipDesc = SVGDocument.getElementById('tipDesc');
controlsArea = SVGDocument.getElementById('controlsArea');
// instantiate chart canvas object, to serve as a container for all chart types
ChartCanvas = new ChartCanvasObj( 550, 410 );
var chartId = CreateUniqueId( 'ChartCanvas' );
ChartCanvas.id = ChartCanvas;
// instantiate statistics object to do analysis
Stats = new StatisticsObj();
InitAnnotation();
try
{
}
catch(er)
{
alert('Error in fn InitCharts:\n' + er.message);
}
SVGDebug( 'exiting InitCharts', 1 );
};
function SendValue( evt )
{
SVGDebug( 'entering SendValue', 1 );
var targetObject = evt.target;
top.GetOutput( self, targetObject.parentNode.id );
SVGDebug( 'exiting SendValue', 1 );
};
parent.ExportChart = ExportChart;
function ExportChart()
{
SVGDebug( 'entering ExportChart', 1 );
var chartBBox = ChartRoot.getBBox();
var viewbox = chartBBox.x + ' ' + chartBBox.y + ' ' + chartBBox.width + ' ' + chartBBox.height;
var watermark = 'created by 6th Sense Chartmaker';
var chart = '';
SVGDebug( 'exiting ExportChart', 1 );
return chart;
};
parent.SetChartType = SetChartType;
function SetChartType( id, type )
{
SVGDebug( 'entering SetChartType', 1 );
if ( ChartCanvas )
{
var chart = ChartCanvas.getChartById( id );
chart.type = type;
}
SVGDebug( 'exiting SetChartType', 1 );
};
parent.SetLegendPosition = SetLegendPosition;
function SetLegendPosition(id, posStr)
{
SVGDebug( 'entering SetLegendPosition', 1 );
// assert posStr equals {'left', 'right', 'top', 'bottom', 'none'}
// appears as though legends are at the ChartCanvas level
// so I don't need id, I'll just leave it here for now
if ( ChartCanvas )
{
ChartCanvas.reset( false );
ChartCanvas.legend.position = posStr;
}
SVGDebug( 'exiting SetLegendPosition', 1 );
};
parent.Toggle3D = Toggle3D;
function Toggle3D( id, isOn )
{
SVGDebug( 'entering Toggle', 1 );
if ( ChartCanvas )
{
var chart = ChartCanvas.getChartById( id );
chart.is3d = isOn;
}
SVGDebug( 'exiting Toggle', 1 );
};
parent.SetChartDimensions = SetChartDimensions;
function SetChartDimensions( width, height )
{
SVGDebug( 'entering SetChartDimensions', 1 );
if ( ChartCanvas )
{
ChartCanvas.setDimensions( width, height, false );
}
SVGDebug( 'exiting SetChartDimensions', 1 );
};
parent.SetColorIndex = SetColorIndex;
function SetColorIndex( index )
{
SVGDebug( 'entering SetColorIndex', 1 );
if ( ChartCanvas )
{
ChartCanvas.setColorIndex( index );
}
SVGDebug( 'exiting SetColorIndex', 1 );
};
parent.ResetChart = ResetChart;
function ResetChart()
{
SVGDebug( 'entering ResetChart', 1 );
if ( ChartCanvas )
{
ChartCanvas.reset( true );
}
SVGDebug( 'exiting ResetChart', 1 );
};
parent.DrawChart = DrawChart;
function DrawChart( callback )
{
SVGDebug( 'entering DrawChart', 1 );
ChartCanvas.callback = callback;
ChartCanvas.reset( false );
ChartCanvas.populate();
SVGDebug( 'exiting DrawChart', 1 );
};
function ClearParent( element )
{
SVGDebug( 'entering ClearParent', 1 );
if ( element )
{
while( element.firstChild )
{
element.removeChild(element.firstChild);
}
}
SVGDebug( 'exiting ClearParent', 1 );
};
function DatapointObj( value, title, desc, type, id, color, element, xLabel, yLabel, angle )
{
SVGDebug( 'entering DatapointObj', 1 );
this.value = value; // the value by which this datapoint is evaluated
this.title = title; // the title of this datapoint
this.desc = desc; // the description of this datapoint
this.type = type; // the type of this datapoint, such as numeric or a match-category
this.id = id; // the unique id of this datapoint
this.color = color; // the color assigned/associated with this datapoint (may link to legend)
this.fill = color; // the paint (gradient) assigned/associated with this datapoint
this.element = element; // the element that represents this datapoint
this.xLabel = xLabel; // the x-axis label element associated with this datapoint
this.yLabel = yLabel; // the y-axis label element associated with this datapoint
this.angle = angle; // the angle of the centerline for a pie slice for this datapoint
this.element = null; // the element that represents this datapoint
this.x = 0;
this.y = 0;
SVGDebug( 'exiting DatapointObj', 1 );
};
function SequenceObj( title, desc, id, element, xLabel, yLabel )
{
SVGDebug( 'entering SequenceObj', 1 );
this.title = title; // the title of this sequence
this.desc = desc; // the description of this sequence
this.id = id; // the unique id of this sequence
this.element = element; // the element that represents this sequence (a group that may include a background rect)
this.xLabel = xLabel; // the x-axis label element associated with this sequence
this.yLabel = yLabel; // the y-axis label element associated with this sequence
this.data = []; // the set of datapoints contained by this sequence
this.total = 0; // the sum total of all the datapoints in this sequence
this.maxValue = 0; // the single highest value of the datapoints in this sequence
SVGDebug( 'exiting SequenceObj', 1 );
};
function SeriesObj( title, desc, id, element, xLabel, yLabel )
{
SVGDebug( 'entering SeriesObj', 1 );
this.title = title; // the title of this series
this.desc = desc; // the description of this series
this.id = id; // the unique id of this series
this.element = element; // the element that represents this series (a group that may include a background rect)
this.xLabel = xLabel; // the x-axis label element associated with this series
this.yLabel = yLabel; // the y-axis label element associated with this series
this.sequences = []; // the set of sequences contained by this series
this.total = 0; // the sum total of all the sequences in this series
this.maxValue = 0; // the single highest value of the sequences in this series
SVGDebug( 'exiting SeriesObj', 1 );
};
function ChartObj( type, is3d, id, element, axisX, axisY, maxX, maxY, xMin, yMin, xtickStep, ytickStep, xLabelStep, yLabelStep, showTrend )
{
SVGDebug( 'entering ChartObj', 1 );
this.type = type; // the type of chart, such as bar, line, area, point, or pie
this.is3d = is3d; // bool indicating whether the graphics are to be rendered in pseudo-3D
this.showTrend = showTrend;
this.max = new PointObj( maxX, maxY ); //
this.min = new PointObj( xMin, yMin); //
this.scaleMax = new PointObj( Math.ceil( maxX ), Math.ceil( maxY ) ); //
this.scaleMin = new PointObj( Math.floor( xMin ), Math.floor( yMin ) ); //
this.axis = new PointObj( new AxisObj( null, 'x', axisX, null), new AxisObj( null, 'y', axisY, null) ); //
this.id = id; // the unique id of this chart
this.element = element; // the element that represents this chart (a group that may include a background rect)
this.series = []; // the set of series that this chart represents
this.totalValue = 0;
this.valueCount = 0;
this.callback = null;
SVGDebug( 'exiting ChartObj', 1 );
};
function PointObj( x, y )
{
SVGDebug( 'entering PointObj', 1 );
this.x = x; // the x value in this x/y pair
this.y = y; // the y value in this x/y pair
SVGDebug( 'exiting PointObj', 1 );
};
function BBox( x, y, width, height )
{
SVGDebug( 'entering BBox', 1 );
this.x = x; // the x position of this bounding box
this.y = y; // the y position of this bounding box
this.width = width; // the width of this bounding box
this.height = height; // the height of this bounding box
SVGDebug( 'exiting BBox', 1 );
};
function AxisObj( id, axisType, dataType, element )
{
SVGDebug( 'entering AxisObj', 1 );
this.id = id;
this.axisType = axisType;
this.dataType = dataType;
this.element = element;
this.items = [];
this.length = 0; //
this.tickStep = 0; //
this.labelStep = 0; //
SVGDebug( 'exiting AxisObj', 1 );
};
function LegendObj( id, position )
{
SVGDebug( 'entering LegendObj', 1 );
this.id = id;
this.position = position;
this.element = SVGDocument.getElementById('legendArea');
this.items = [];
this.itemCount = 0;
this.width = 0;
this.height = 0;
this.element.addEventListener('mousemove', ShowTooltip, false);
this.element.addEventListener('mouseout', HideTooltip, false);
SVGDebug( 'exiting LegendObj', 1 );
};
function LegendItemObj( id, title, desc, color, element )
{
SVGDebug( 'entering LegendItemObj', 1 );
this.id = id;
this.element = element;
this.title = title;
this.desc = desc;
this.color = color;
this.matches = [];
SVGDebug( 'exiting LegendItemObj', 1 );
};
function LabelObj( id, title, desc )
{
SVGDebug( 'entering LabelObj', 1 );
this.id = id;
this.title = title;
this.desc = desc;
this.element = null;
this.tickMark = null; //
this.labelEl = null; //
this.dataElArray = [];
SVGDebug( 'exiting LabelObj', 1 );
};
function ChartCanvasObj( width, height )
{
SVGDebug( 'entering ChartCanvasObj', 1 );
this.element = SVGDocument.getElementById('ChartArea');
this.axis = new PointObj( SVGDocument.getElementById('xAxis'), SVGDocument.getElementById('yAxis') ); //
this.legend = new LegendObj( null, 'bottom' );
this.controls = null;
this.chartArray = [];
this.id = null;
this.base = new PointObj( 0, 0 ); //
this.width = width;
this.height = height;
this.plotWidth = width - 10;
this.plotHeight = height - 10;
this.margin = new PointObj( 5, 5 ); //
this.max = new PointObj( 0, 0 ); //
this.scale = new PointObj( SVGDocument.getElementById('xScale'), SVGDocument.getElementById('yScale') ); //
this.totalValue = 0;
this.valueCount = 0;
this.titleMax = '';
this.colorMatchArray = [];
this.idArray = [];
this.element.addEventListener('mousemove', ShowTooltip, false);
this.element.addEventListener('mouseout', HideTooltip, false);
this.scale.x.addEventListener('mousemove', ShowTooltip, false);
this.scale.x.addEventListener('mouseout', HideTooltip, false);
this.scale.y.addEventListener('mousemove', ShowTooltip, false);
this.scale.y.addEventListener('mouseout', HideTooltip, false);
SVGDebug( 'exiting ChartCanvasObj', 1 );
};
ChartCanvasObj.prototype.reset = function( deleteAllData )
{
SVGDebug( 'entering reset', 1 );
//this causes problems when set to true
this.setDimensions( this.width, this.height, false );
if ( true == deleteAllData )
{
this.chartArray = [];
this.totalValue = 0;
}
ClearParent( this.scale.x );
ClearParent( this.scale.y );
ClearParent( this.element );
ClearParent( this.legend.element );
//clears out the stored predrawn legends; they won't re-render otherwise
this.legend.items = [];
SVGDebug( 'exiting reset', 1 );
};
ChartCanvasObj.prototype.getChartById = function( id )
{
SVGDebug( 'entering getChartById', 1 );
for ( var i = 0, iLen = this.chartArray.length; iLen > i; i++ )
{
var eachChart = this.chartArray[ i ];
if ( id == eachChart.id )
{
return eachChart;
}
}
SVGDebug( 'exiting getChartById', 1 );
return this.chartArray[ 0 ];
};
ChartCanvasObj.prototype.setDimensions = function( width, height, pauseRedraw )
{
SVGDebug( 'entering setDimensions', 1 );
if ( width )
{
this.width = Number(width);
}
if ( height )
{
this.height = Number(height);
}
if ( true != pauseRedraw )
{
this.drawChartDimensions();
}
SVGDebug( 'exiting setDimensions', 1 );
};
ChartCanvasObj.prototype.drawChartDimensions = function()
{
SVGDebug( 'entering drawChartDimensions', 1 );
//determine margins based on label sizes
this.base.x = 35;
if ( 0 < this.margin.x )
{
this.base.x += this.margin.x;
}
this.base.y = this.height;
if ( 0 < this.margin.y )
{
this.base.y = this.height - (( this.margin.y * 2 ) + 30);
}
this.plotWidth = this.width - (this.base.x + 40);
this.plotHeight = (this.base.y - 35);
var showYLabel = true;
if ( true == showYLabel )
{
this.plotWidth -= 25;
this.base.x += 25;
}
this.drawAxes();
controlsArea.setAttributeNS(null, 'transform', 'translate(' + this.width + ')' );
SVGDebug( 'exiting drawChartDimensions', 1 );
};
ChartCanvasObj.prototype.drawAxes = function()
{
SVGDebug( 'entering drawAxes', 1 );
//set x-axis line size and position
this.axis.x.setAttributeNS(null, 'x1', this.base.x - 5 );
this.axis.x.setAttributeNS(null, 'y1', this.base.y );
this.axis.x.setAttributeNS(null, 'x2', (this.base.x + this.plotWidth) );
this.axis.x.setAttributeNS(null, 'y2', this.base.y );
//set y-axis line size and position
this.axis.y.setAttributeNS(null, 'x1', this.base.x );
this.axis.y.setAttributeNS(null, 'y1', (this.base.y - this.plotHeight) );
this.axis.y.setAttributeNS(null, 'x2', this.base.x );
this.axis.y.setAttributeNS(null, 'y2', this.base.y + 5 );
SVGDebug( 'exiting drawAxes', 1 );
};
ChartCanvasObj.prototype.populate = function()
{
SVGDebug( 'entering populate', 1 );
//preserves window size that has been set via the API
this.setDimensions( this.width, this.height, true );
this.redraw();
SVGDebug( 'exiting populate', 1 );
};
ChartCanvasObj.prototype.redraw = function()
{
SVGDebug( 'entering redraw', 1 );
var hideAxes = false;
var barX = this.base.x;
var barY = 0;
var barGap = 0;
var seriesGap = 0;
//var lineStartX = this.base.x;
//var lineStartY = this.base.y;
//var lineX = this.base.x;
var centerX = (this.width / 2);
var centerY = (this.height / 2);
//var areaStartX = this.base.x;
//var areaStartY = this.base.y;
var pieStart = 0;
var sequenceCount = 0;
var eachWidth = 0;//(Number(width) / sequenceCount) - 10;
var sequenceWidth = 0;
// allocate space and calculate positions for legends
// test to see if there is a pie chart
var isPie = false;
for ( var i = 0, iLen = this.chartArray.length; iLen > i; i++ )
{
var eachChart = this.chartArray[ i ];
if ( 'pie' == eachChart.type )
{
isPie = true;
}
}
if ( !isPie )
{
var legendXStart = 10;
var legendX = legendXStart;
var legendY = 20;
var legendItemWidth = 143;
var legendItemHeight = 15;
var legendColumns = Math.floor( ( this.width - (legendX)) /legendItemWidth );
var legendColumnCount = legendColumns;
var legendRows = Math.ceil( this.legend.itemCount/legendColumns );
this.legend.height = legendRows * legendItemHeight;
this.legend.width = 150 * legendColumns;
var legendPosition = this.legend.position;
switch ( legendPosition )
{
case 'left':
this.base.x += legendItemWidth + 20;
this.plotWidth -= legendItemWidth;
legendXStart = 10;
centerX += (legendItemWidth/2) + 20;
break;
case 'right':
this.base.x -= legendItemWidth - 20;
this.plotWidth -= legendItemWidth;
legendXStart = this.width - (legendItemWidth + 10);
centerX -= (legendItemWidth/2) + 20;
break;
case 'bottom':
this.base.y -= this.legend.height;
this.plotHeight -= this.legend.height;
legendY = this.base.y + 30;
centerY -= (this.legend.height/2);
break;
case 'top':
this.base.y += this.legend.height;
this.plotHeight -= this.legend.height;
centerY += this.legend.height;
break;
}
this.drawAxes();
legendX = legendXStart;
}
var pieArray = [];
var pieRadius = Math.min( this.plotWidth, this.plotHeight )/2;
pieRadius *= 0.90;
var isOtherPieSlice = false;
var otherPieSliceColor = null;
var otherPieSliceValue = 0;
var otherPieSliceTitle = '';
var otherPieSliceDesc = '';
var otherPieData = null;
var otherSliceArray = [];
var legendArray = [];
var graphicArray = [];
for ( var i = 0, iLen = this.chartArray.length; iLen > i; i++ )
{
var eachChart = this.chartArray[ i ];
//reset scales to actual values
eachChart.scaleMax.x = Math.ceil( eachChart.max.x );
eachChart.scaleMax.y = Math.ceil( eachChart.max.y );
eachChart.scaleMin.x = Math.floor( eachChart.min.x );
eachChart.scaleMin.y = Math.floor( eachChart.min.y );
var seriesArray = eachChart.series;
var seriesCount = seriesArray.length;
var dataCount = 0;
var segmentArray = [];
var sequenceCount = 0;
for ( var s = 0; seriesCount > s; s++ )
{
var eachSeries = seriesArray[s];
sequenceCount += eachSeries.sequences.length;
}
seriesWidth = this.plotWidth / seriesCount;
eachWidth = this.plotWidth / sequenceCount;
sequenceWidth = eachWidth;
var seriesSize = sequenceCount/seriesCount; //number of sequences per series
//test for multi-series
if ( sequenceCount > seriesCount )
{
seriesGap = eachWidth/3;
sequenceWidth -= seriesGap / seriesSize;
}
barGap = sequenceWidth/3;
barX += (barGap/2) + (seriesGap/2);
barWidth = sequenceWidth/1.5;
var firstSeries = seriesArray[ 0 ];
if ( 'pie' != eachChart.type )
{
var drawRisers = false;
if ( 'line' == eachChart.type )
{
drawRisers = true;
}
var seriesWidth = eachWidth * seriesSize;
this.drawScaleX( eachChart, seriesWidth, drawRisers );
this.drawScaleY( eachChart );
}
for ( var j = 0; seriesCount > j; j++ )
{
var eachSeries = seriesArray[ j ];
var sequenceArray = eachSeries.sequences;
var seqCount = sequenceArray.length;
for ( var k = 0; seqCount > k; k++ )
{
var eachSequence = sequenceArray[ k ];
var barYbase = this.base.y;
var chartGroup = SVGDocument.createElementNS(svgns, 'g');
chartGroup.setAttributeNS(null, 'id', eachChart.id );
var areaGroup = SVGDocument.createElementNS(svgns, 'g');
var dataArray = eachSequence.data;
dataCount = dataArray.length
for ( var l = 0, lLen = dataCount; lLen > l; l++ )
{
var eachData = dataArray[ l ];
var id = eachData.id;
var color = eachData.color;
var value = Number(eachData.value);
var title = eachData.title;
var desc = eachData.desc;
var metadataTitle = title;
if ( desc )
{
metadataTitle += ': ' + desc;
}
//var metadataDesc = Math.ceil( value );
var metadataDesc = RoundToDecimal( value, 1 );
// calculate individual bar height
var height = 5;
var barHeight = 0;
if ( 0 == value )
{
height = 0;
}
else
{
height = Number(this.plotHeight) * ( value / Number(eachChart.scaleMax.y) );
}
barHeight = height;
barYbase -= barHeight;
barY = barYbase;
if ( 0 > value )
{
barHeight = Math.abs( barHeight );
barYbase = this.base.y;
barY = barYbase;
barYbase += barHeight;
}
eachData.x = barX;
eachData.y = barY;
//Stats.addDataPoint( barX, barY );
var graphic = null;
switch ( eachChart.type )
{
case 'bar':
if ( true == eachChart.is3d )
{
graphic = this.createBar3dGraphic( eachData, id, barX, barY, barWidth, barHeight, color );
}
else
{
var isRounded = false;
if ( lLen == l + 1 )
{
isRounded = true;
}
graphic = this.createBarGraphic( eachData, id, barX, barY, barWidth, barHeight, color, isRounded );
}
break;
case 'area':
var pos = 'mid';
if ( 0 == j )
{
pos = 'start';
}
else if ( seriesCount - 1 == j )
{
pos = 'end';
}
var x1 = this.base.x + (seriesWidth * (j - 1)) + seriesWidth/2;
var y1 = this.base.y;
var lastSegment = segmentArray[ title + '_' + desc ];
if ( lastSegment )
{
x1 = lastSegment.x;
y1 = lastSegment.y;
}
else
{
segmentArray[ title + '_' + desc ] = new PointObj();
lastSegment = segmentArray[ title + '_' + desc ];
}
var x2 = this.base.x + (seriesWidth * j) + (seriesWidth/2);
var y2 = this.base.y - height;
if ( 0 == j )
{
x1 = x2;
y1 = y2;
}
lastSegment.x = x2;
lastSegment.y = y2;
var areaColor = color;
if ( true == eachChart.is3d )
{
graphic = this.createArea3dGraphic( eachData, id, x1, y1, x2, y2, areaColor, pos );
}
else
{
graphic = this.createAreaGraphic( eachData, id, x1, y1, x2, y2, areaColor, pos );
}
break;
case 'line':
var dashArray = '';
var x1 = this.base.x + (seriesWidth * (j - 1)) + seriesWidth/2;
var y1 = this.base.y;
var lastSegment = segmentArray[ title + '_' + desc ];
if ( lastSegment )
{
x1 = lastSegment.x;
y1 = lastSegment.y;
}
else
{
segmentArray[ title + '_' + desc ] = new PointObj();
lastSegment = segmentArray[ title + '_' + desc ];
}
var x2 = this.base.x + (seriesWidth * j) + (seriesWidth/2);
var y2 = this.base.y - height;
if ( 0 == j )
{
x1 = x2;
y1 = y2;
}
lastSegment.x = x2;
lastSegment.y = y2;
//metadataDesc = Math.ceil( lastSegment.value ) + ' to ' + Math.ceil( value );
metadataDesc = RoundToDecimal( lastSegment.value, 1 ) + ' to ' + RoundToDecimal( value, 1 );
lastSegment.value = value;
if ( true == eachChart.is3d )
{
graphic = this.createLine3dGraphic( eachData, id, x1, y1, x2, y2, color, dashArray );
}
else
{
graphic = this.createLineGraphic( eachData, id, x1, y1, x2, y2, color, dashArray );
}
break;
case 'point':
var cx = this.base.x + (seriesWidth * j) + (seriesWidth/2);
var cy = this.base.y - height;
var r = 5;
graphic = this.createPointGraphic( eachData, id, cx, cy, r, color );
break;
case 'pie':
var value = Number(eachData.value);
var percentage = value / eachChart.totalValue;
if ( 0.05 > percentage )
{
otherSliceArray.push( eachData );
}
else
{
pieArray.push( eachData );
}
hideAxes = true;
break;
}
if ( graphic )
{
eachData.element = graphic;
chartGroup.appendChild( graphic );
this.addMetadata( graphic, metadataTitle, metadataDesc );
graphic.addEventListener('mouseover', Highlight, false);
graphic.addEventListener('mouseout', Lowlight, false);
}
legendArray.push( eachData );
}
// find x position for next bar
barX += sequenceWidth;
this.element.appendChild(chartGroup);
}
barX += seriesGap;
}
if ( 'pie' == eachChart.type )
{
if ( 1 == otherSliceArray.length )
{
pieArray.push( otherSliceArray[0] );
}
else if ( 1 < otherSliceArray.length )
{
var otherPieData = null;
for ( var o = 0, oLen = otherSliceArray.length; oLen > o; o++ )
{
var eachSlice = otherSliceArray[ o ];
//pieArray.push( eachData );
var id = eachSlice.id;
var color = eachSlice.color;
var value = Number(eachSlice.value);
var title = eachSlice.title;
var desc = eachSlice.desc;
///metadataTitle = title + ': ' + desc;
metadataTitle = title;
if ( desc )
{
metadataTitle += ': ' + desc;
}
var percentage = value / eachChart.totalValue;
//metadataDesc = Math.ceil( percentage * 100 ) + '%';
metadataDesc = RoundToDecimal(percentage * 100, 1) + '%';
otherPieSliceValue += value;
//otherPieSliceTitle = metadataTitle;
otherPieSliceDesc += metadataTitle + ' (' + metadataDesc + ')';
createSlice = false;
if ( !otherPieSliceColor )
{
otherPieSliceColor = color;
}
if ( oLen - 1 == o )
{
color = otherPieSliceColor;
value = otherPieSliceValue;
//metadataTitle = otherPieSliceTitle;
metadataTitle = 'Other ( < 5% each)';
metadataDesc = otherPieSliceDesc;
percentage = value / eachChart.totalValue;
var datapointId = CreateUniqueId( 'datapoint' );
valueType = eachSlice.valueType;
otherPieData = new DatapointObj( value, metadataTitle, metadataDesc, valueType, datapointId, color );
}
else
{
otherPieSliceTitle += '; ';
otherPieSliceDesc += '; ';
}
}
}
pieArray.sort( this.sortByDecreasingValue );
if ( otherPieData )
{
pieArray.push( otherPieData );
}
this.legend.itemCount = pieArray.length;
// allocate space and calculate positions for legends
var legendXStart = 10;
var legendX = legendXStart;
var legendY = 20;
var legendItemWidth = 143;
var legendItemHeight = 15;
var legendColumns = Math.floor( ( this.width - (legendX)) /legendItemWidth );
var legendColumnCount = legendColumns;
var legendRows = Math.ceil( this.legend.itemCount/legendColumns );
this.legend.height = legendRows * legendItemHeight;
this.legend.width = 150 * legendColumns;
var legendPosition = this.legend.position;
switch ( legendPosition )
{
case 'left':
this.base.x += legendItemWidth + 20;
this.plotWidth -= legendItemWidth;
legendXStart = 10;
centerX += (legendItemWidth/2) + 20;
break;
case 'right':
this.base.x -= legendItemWidth - 20;
this.plotWidth -= legendItemWidth;
legendXStart = this.width - (legendItemWidth + 10);
centerX -= (legendItemWidth/2) + 20;
break;
case 'bottom':
this.base.y -= this.legend.height;
this.plotHeight -= this.legend.height;
legendY = this.base.y + 30;
centerY -= (this.legend.height/2);
break;
case 'top':
this.base.y += this.legend.height;
this.plotHeight -= this.legend.height;
centerY += this.legend.height;
break;
}
this.drawAxes();
legendX = legendXStart;
legendArray = [];
for ( var p = 0, pLen = pieArray.length; pLen > p; p++ )
{
var eachData = pieArray[p];
var id = eachData.id;
var color = eachData.color;
var value = Number(eachData.value);
var title = eachData.title;
var desc = eachData.desc;
var percentage = value / eachChart.totalValue;
//metadataTitle = title + ': ' + Math.ceil( percentage * 100 ) + '%';
metadataTitle = title + ': ' + RoundToDecimal( percentage * 100, 1 ) + '%';
metadataDesc = desc;
graphic = this.createPieGraphic( eachData, id, centerX, centerY, pieStart, percentage, pieRadius, color, value );
pieStart += percentage;
eachData.element = graphic;
chartGroup.appendChild( graphic );
this.addMetadata( graphic, metadataTitle, metadataDesc );
graphic.addEventListener('mouseover', Highlight, false);
graphic.addEventListener('mouseout', Lowlight, false);
legendArray.push( eachData );
}
}
if ( otherPieData )
{
otherPieData = legendArray.pop();
legendArray.sort( this.sortByLabel );
legendArray.push( otherPieData );
}
else
{
legendArray.sort( this.sortByLabel );
}
for ( var l = 0, lLen = legendArray.length; lLen > l; l++ )
{
var eachData = legendArray[l];
var id = eachData.id;
var color = eachData.color;
var value = Number(eachData.value);
var title = eachData.title;
var desc = eachData.desc;
if ( 'none' != legendPosition )
{
if ( !this.legend.items[color] )
{
var legendTruncation = 135;
if ( 1 == lLen )
{
legendTruncation = null;
}
var legendLabel = title;
if ( desc )
{
legendLabel += ': ' + desc;
}
var legend = this.createLegend( '', legendX, legendY, color, legendLabel, legendTruncation );
this.addMetadata( legend, title, desc );
if ( 'top' == legendPosition || 'bottom' == legendPosition )
{
if ( 1 == legendColumnCount )
{
legendY += legendItemHeight;
legendX = legendXStart;
legendColumnCount = legendColumns;
}
else
{
legendX += legendItemWidth;
legendColumnCount--;
}
}
else
{
legendY += legendItemHeight;
}
this.legend.items[color] = [];
//Stats = new StatisticsObj()
}
//this.legend.items[color].push( eachData.element );
this.legend.items[color].push( eachData );
}
}
}
this.toggleAxes( hideAxes );
if ( this.callback )
{
this.callback( true );
}
try
{
}
catch(er)
{
SVGDebug('Error in fn ChartCanvasObj.prototype.redraw:\n' + er.message);
if ( this.callback )
{
this.callback( false, er.message );
}
}
SVGDebug( 'exiting redraw', 1 );
};
ChartCanvasObj.prototype.sortByDecreasingValue = function( a, b )
{
return Number(b.value) - Number(a.value);
};
ChartCanvasObj.prototype.sortByLabel = function( a, b )
{
var aLabel = a.title + ': ' + a.desc;
var bLabel = b.title + ': ' + b.desc;
aLabel = aLabel.toUpperCase();
bLabel = bLabel.toUpperCase();
return aLabel > bLabel ? 1 : aLabel < bLabel ? -1 : 0;
};
ChartCanvasObj.prototype.drawTrendLine = function( chart, trendX1, trendX2, color, trendTitle )
{
SVGDebug( 'entering drawTrendLine', 1 );
var trendPoints = Stats.findTrendLine( trendX1, trendX2, color );
var start = trendPoints[0];
var end = trendPoints[1];
var trendGroup = SVGDocument.createElementNS(svgns, 'g');
var trendline = ChartCanvas.createLineGraphic( 'trendline', start.x, start.y, end.x, end.y, color, '10' );
trendGroup.appendChild( trendline );
this.element.appendChild( trendGroup );
var startValue = Math.round( (this.base.y - start.y) / (Number(this.plotHeight) / Number(chart.scaleMaxY)) );
var endValue = Math.round( (this.base.y - end.y) / (Number(this.plotHeight) / Number(chart.scaleMax.y)) );
var yUnits = chart.axis.y.dataType;
var xUnits = chart.axis.x.dataType;
if ( startValue < endValue )
{
trendTitle = 'Upward Trend for ' + trendTitle;
}
else if ( startValue == endValue )
{
trendTitle = 'Steady Trend for ' + trendTitle;
}
else
{
trendTitle = 'Downward Trend for ' + trendTitle;
}
var trendDesc = 'From ' + startValue + ' ' + yUnits + ' to ' + endValue + ' ' + yUnits + ' per ' + xUnits;
this.addMetadata( trendGroup, trendTitle, trendDesc );
SVGDebug( 'exiting drawTrendLine', 1 );
};
ChartCanvasObj.prototype.toggleAxes = function( isHidden )
{
SVGDebug( 'entering toggleAxes', 1 );
var displayValue = 'inline';
if ( true == isHidden )
{
displayValue = 'none';
}
this.axis.x.setAttributeNS(null, 'display', displayValue );
this.axis.y.setAttributeNS(null, 'display', displayValue );
this.scale.y.setAttributeNS(null, 'display', displayValue );
this.scale.x.setAttributeNS(null, 'display', displayValue );
SVGDebug( 'exiting toggleAxes', 1 );
};
ChartCanvasObj.prototype.drawScale = function()
{
SVGDebug( 'entering drawScale', 1 );
try
{
}
catch(er)
{
alert('Error in fn ChartCanvasObj.prototype.drawScale:\n' + er.message);
}
SVGDebug( 'exiting drawScale', 1 );
};
ChartCanvasObj.prototype.drawScaleX = function( chart, width, hasRisers )
{
SVGDebug( 'entering drawScaleX', 1 );
// create X tickmarks and labels
var axisDataType = chart.axis.x.dataType;
var intervalArray = [];
var rotate = false;
var fontSize = 11;
var rotatedLabelHeight = 65;
var isDate = false;
if ( 'date' == axisDataType || 'day' == axisDataType || 'week' == axisDataType || 'month' == axisDataType || 'quarter' == axisDataType || 'year' == axisDataType )
{
//isDate = true;
var titleMax = this.titleMax;
this.titleMax = '';
//buh()
var dateRangeArray = this.createDateRange( chart.series );
if ( !dateRangeArray )
{
isDate = false;
intervalArray = chart.series;
this.titleMax = titleMax;
}
else
{
isDate = true;
var days = dateRangeArray[ 0 ];
var months = dateRangeArray[ 1 ];
var years = dateRangeArray[ 2 ];
intervalArray = days;
}
}
else
{
intervalArray = chart.series;
}
width = this.plotWidth / intervalArray.length;
// find font size and spacing, according to available area
fontSize = width / ( this.titleMax.length / 1.4 );
if ( 10 > fontSize )
{
fontSize = 10;
if ( !isDate )
{
rotate = true;
this.base.y -= rotatedLabelHeight;
this.plotHeight -= rotatedLabelHeight;
this.drawAxes();
}
}
else if ( 14 < fontSize )
{
fontSize = 14;
}
if ( isDate )
{
var verticalSpacing = fontSize + 3;
if ( 1 < months.length || 1 < years.length )
{
verticalSpacing += fontSize;
}
this.base.y -= verticalSpacing;
this.plotHeight -= verticalSpacing;
this.drawAxes();
}
// draw each interval label and tickmark
for ( var i = 0, iLen = intervalArray.length; iLen > i; i++ )
{
var eachInterval = intervalArray[ i ];
var title = eachInterval.title;
var desc = eachInterval.desc;
var labelText = title;
if ( isDate )
{
labelText = eachInterval[ 0 ];
title = eachInterval[ 1 ];
desc = eachInterval[ 2 ];
}
var xPos = this.base.x + (width * (i + 1));
var labelX = xPos - (width/2);
var labelGroup = SVGDocument.createElementNS(svgns, 'g');
var xMark = SVGDocument.createElementNS(svgns, 'line');
xMark.setAttributeNS(null, 'x1', xPos );
xMark.setAttributeNS(null, 'y1', this.base.y );
xMark.setAttributeNS(null, 'x2', xPos );
xMark.setAttributeNS(null, 'y2', this.base.y + 5 );
xMark.setAttributeNS(null, 'stroke', 'black' );
xMark.setAttributeNS(null, 'stroke-width', 2 );
xMark.setAttributeNS(null, 'stroke-linecap', 'round');
labelGroup.appendChild(xMark);
newMarkLabel = SVGDocument.createElementNS(svgns, 'text');
newMarkLabel.setAttribute('x', labelX );
newMarkLabel.setAttribute('y', this.base.y + fontSize + 4 );
newMarkLabel.setAttributeNS(null, 'font-size', fontSize );
if ( 15 < fontSize )
{
//newMarkLabel.setAttributeNS(null, 'font-weight', 'bold');
}
if ( true == rotate )
{
newMarkLabel.setAttributeNS(null, 'transform', 'rotate(' + -50 + ',' + labelX + ',' + (this.base.y + 10) + ')' );
newMarkLabel.setAttribute('text-anchor', 'end' );
labelText = TruncateText( labelText, 100, fontSize );
}
else
{
newMarkLabel.setAttributeNS(null, 'text-anchor', 'middle');
}
if ( hasRisers )
{
if ( chart.is3d )
{
linePoints = (labelX) + ',' + (this.base.y) + ' ' + (labelX + 10) + ',' + (this.base.y - 10) + ' ' + (labelX + 10) + ',' + ((this.base.y - this.plotHeight) - 10);
}
else
{
linePoints = (labelX) + ',' + (this.base.y) + ' ' + (labelX) + ',' + (this.base.y - this.plotHeight);
}
var riser = SVGDocument.createElementNS(svgns, 'polyline');
riser.setAttributeNS(null, 'points', linePoints);
riser.setAttributeNS(null, 'fill', 'none');
riser.setAttributeNS(null, 'stroke', '#ccc');
riser.setAttributeNS(null, 'stroke-width', '0.75');
labelGroup.appendChild(riser);
}
newMarkLabel.appendChild(SVGDocument.createTextNode( labelText ));
labelGroup.appendChild(newMarkLabel);
this.addMetadata( newMarkLabel, title, null );
this.scale.x.appendChild(labelGroup);
}
if ( isDate )
{
// add label for axis units
var boxWidth = axisDataType.length * 12;
var boxX = this.base.x - (boxWidth + 2);
var labelGroup = SVGDocument.createElementNS(svgns, 'g');
var labelBox = SVGDocument.createElementNS(svgns, 'rect');
labelBox.setAttributeNS(null, 'x', boxX );
labelBox.setAttributeNS(null, 'y', this.base.y + 3);
labelBox.setAttributeNS(null, 'width', boxWidth );
labelBox.setAttributeNS(null, 'height', fontSize + 4 );
labelBox.setAttributeNS(null, 'fill', '#ececec' );
labelGroup.appendChild(labelBox);
var unitsLabel = SVGDocument.createElementNS(svgns, 'text');
unitsLabel.setAttribute('x', this.base.x - 5 );
unitsLabel.setAttribute('y', this.base.y + fontSize + 4 );
unitsLabel.setAttributeNS(null, 'font-size', fontSize + 1 );
//unitsLabel.setAttributeNS(null, 'font-weight', 'bold');
unitsLabel.setAttributeNS(null, 'text-anchor', 'end');
//unitsLabel.appendChild( SVGDocument.createTextNode( axisDataType + ':' ) );
unitsLabel.appendChild( SVGDocument.createTextNode( axisDataType + ':' ) );
labelGroup.appendChild( unitsLabel );
this.scale.x.appendChild( labelGroup );
var yPos = 5;
var fontSize = 12;
var timePeriodArray = [ months, years ];
//alert(years)
//buh()
for ( var t = 0, tLen = timePeriodArray.length; tLen > t; t++ )
{
var timePeriods = timePeriodArray[ t ];
yPos += fontSize + 4;
for ( var i = 0, iLen = timePeriods.length; iLen > i; i++ )
{
var eachPeriod = timePeriods[ i ];
var labelText = eachPeriod[ 0 ];
if ( 0 == t )
{
labelText = monthNamesArray[ eachPeriod[0] - 1 ];
}
if ( 1 == months.length && 1 == years.length )
{
labelText += ' ' + years[ 0 ][ 0 ];
t++;
}
var boxId = 'id-' + labelText.toString().replace(' ', '_');
var xBegin = (width * eachPeriod[2] );
var xEnd = (width * eachPeriod[3] );
var boxX = this.base.x + xBegin + 1;
var boxY = this.base.y + yPos;
var boxWidth = (xEnd - xBegin) - 2;
var labelX = boxX + ( (xEnd - xBegin)/2 ) - 1;
var labelY = boxY + fontSize - 1;
var backlightX = boxX - 1.5;
var backlightY = this.base.y - this.plotHeight;
if ( chart.is3d )
{
backlightX += 10;
backlightY -= 10;
}
var labelGroup = SVGDocument.createElementNS(svgns, 'g');
var labelBox = SVGDocument.createElementNS(svgns, 'rect');
labelBox.setAttributeNS(null, 'id', boxId );
labelBox.setAttributeNS(null, 'x', boxX + 1 );
labelBox.setAttributeNS(null, 'y', this.base.y + yPos );
labelBox.setAttributeNS(null, 'width', boxWidth - 2 );
labelBox.setAttributeNS(null, 'height', fontSize + 2 );
labelBox.setAttributeNS(null, 'fill', '#ececec' );
labelGroup.appendChild(labelBox);
/*
var highlight = SVGDocument.createElementNS(svgns, 'set');
highlight.setAttribute('attributeName', 'fill');
highlight.setAttribute('to', 'lightgray');
highlight.setAttribute('begin', boxId + '.mouseover');
highlight.setAttribute('end', boxId + '.mouseout');
labelBox.appendChild(highlight);
*/
var backlightBox = SVGDocument.createElementNS(svgns, 'rect');
backlightBox.setAttributeNS(null, 'id', boxId + '_backlight');
backlightBox.setAttributeNS(null, 'x', backlightX );
backlightBox.setAttributeNS(null, 'y', backlightY );
backlightBox.setAttributeNS(null, 'width', boxWidth + 3 );
backlightBox.setAttributeNS(null, 'height', this.plotHeight );
backlightBox.setAttributeNS(null, 'fill', 'lightgray' );
backlightBox.setAttributeNS(null, 'stroke', 'lightgray' );
backlightBox.setAttributeNS(null, 'fill-opacity', '0.8' );
backlightBox.setAttributeNS(null, 'display', 'none' );
labelGroup.appendChild(backlightBox);
/*
var highlight = SVGDocument.createElementNS(svgns, 'set');
highlight.setAttribute('attributeName', 'display');
highlight.setAttribute('to', 'inline');
highlight.setAttribute('begin', boxId + '.mouseover');
highlight.setAttribute('end', boxId + '.mouseout');
backlightBox.appendChild(highlight);
*/
var newAxisLabel = SVGDocument.createElementNS(svgns, 'text');
newAxisLabel.setAttribute('x', labelX );
newAxisLabel.setAttribute('y', this.base.y + yPos + fontSize - 1 );
newAxisLabel.setAttributeNS(null, 'font-size', fontSize);
//newAxisLabel.setAttributeNS(null, 'font-weight', 'bold');
newAxisLabel.setAttributeNS(null, 'text-anchor', 'middle');
newAxisLabel.appendChild(SVGDocument.createTextNode( labelText ));
newAxisLabel.setAttributeNS(null, 'pointer-events', 'none');
labelGroup.appendChild( newAxisLabel );
this.addMetadata( labelGroup, eachPeriod[ 1 ], null );
labelGroup.addEventListener('mouseover', LabelHighlight, false);
labelGroup.addEventListener('mouseout', LabelLowlight, false);
this.scale.x.appendChild( labelGroup );
}
}
}
try
{
}
catch(er)
{
alert('Error in fn ChartCanvasObj.prototype.drawScaleX:\n' + er.message);
}
SVGDebug( 'exiting drawScaleX', 1 );
};
ChartCanvasObj.prototype.createDateRange = function( sourceArray )
{
SVGDebug( 'entering createDateRange', 1 );
var dateRangeArray = [];
var days = [];
var months = [];
var years = [];
for ( var d = 0, dLen = sourceArray.length; dLen > d; d++ )
{
var eachSeries = sourceArray[ d ];
var title = eachSeries.title;
var desc = eachSeries.desc;
if ( !title )
{
title = eachSeries;
}
var year = '';
var month = '';
var day = '';
//begin temporary code
if ( 0 == title.indexOf('Agg') )
{
return null;
}
//end temporary code
var appendedArray = title.split('+');
if ( 1 < appendedArray.length )
{
var subRangeArray = this.createDateRange( appendedArray );
if ( 3 == subRangeArray.length )
{
days = days.concat( subRangeArray[0] );
months = months.concat( subRangeArray[1] );
years = years.concat( subRangeArray[2] );
}
}
else
{
var eachDate = new Date();
var dateArray = title.split('-');
if ( 1 < dateArray.length )
{
year = dateArray[0];
month = dateArray[1];
day = Number(dateArray[2]);
//make sure that date is in a format that we can parse, else default to text string
if ( isNaN(day) )
{
return null;
}
if ( 10 > day )
{
day = '0' + day;
}
eachDate.setYear( year );
eachDate.setMonth( month );
eachDate.setDate( day );
}
else
{
eachDate.setTime( title );
year = eachDate.getYear();
month = eachDate.getMonth();
day = eachDate.getDate();
}
///var dayTitle = dayNamesArray[ eachDate.getDay() ];
///dayTitle += ', ' + monthNamesArray[ month - 1 ] + ' ' + Number( day ) + ', ' + year;
var dayTitle = monthNamesArray[ month - 1 ] + ' ' + Number( day ) + ', ' + year;
var monthTitle = monthNamesArray[ month - 1 ] + ' ' + year;
//days[ d ] = [ Number(day), dayTitle, desc ];
days[ d ] = [ day, dayTitle, desc ];
var monthTitle = monthNamesArray[ month - 1 ] + ' ' + year;
var monthCount = months.length;
if ( 0 == monthCount )
{
months.push( [ month, monthTitle, d, dLen ] );
}
else if ( months[ monthCount - 1 ][0] != month )
{
var lastEntry = months.pop();
//lastEntry.push( d );
lastEntry[ 3 ] = d;
months.push( lastEntry );
months.push( [ month, monthTitle, d, dLen ] );
}
var yearTitle = year;
var yearCount = years.length;
if ( 0 == yearCount )
{
years.push( [ year, yearTitle, d, dLen ] );
}
else if ( years[ yearCount - 1 ][0] != year )
{
var lastEntry = years.pop();
lastEntry[ 3 ] = d;
years.push( lastEntry );
years.push( [ year, yearTitle, d, dLen ] );
}
if ( this.titleMax.length < day.length )
{
this.titleMax = day;
}
}
}
dateRangeArray.push( days );
dateRangeArray.push( months );
dateRangeArray.push( years );
return dateRangeArray;
SVGDebug( 'exiting createDateRange', 1 );
};
ChartCanvasObj.prototype.drawScaleY = function( chart )
{
SVGDebug( 'entering drawScaleY', 1 );
var fontSize = 13;
// determine the normalized range of the axis, the tick interval, and the label interval,
// based on the font-size, the base values, and the height of the chart
var maxLabelCount = this.plotHeight / fontSize;
var labelInfo = this.normalizeRange( chart.scaleMax.y, fontSize );
chart.scaleMax.y = labelInfo.max;
var maxY = labelInfo.labelMax;
var labelInterval = labelInfo.interval;
var tickInterval = this.plotHeight/maxY;
var tickDisplayInterval = tickInterval;
while ( 5 > tickDisplayInterval )
{
tickDisplayInterval *= 2;
}
var topValue = this.plotHeight + 1;
SVGDebug( 'maxY: ' + maxY + '\nlabelInterval: ' + labelInterval + '\ntickInterval: ' + tickInterval + '\ntickDisplayInterval: ' + tickDisplayInterval + '\ntopValue: ' + topValue + '\nthis.plotHeight: ' + this.plotHeight + '\nmaxLabelCount: ' + maxLabelCount, 4 );
// create Y tickmark template and label template
var titleY = this.base.y - (this.plotHeight/2);
var titleX = this.base.x - 50;
var yLabel = chart.axis.y.dataType;
var yTitle = SVGDocument.createElementNS(svgns, 'text');
yTitle.setAttribute('x', titleX);
yTitle.setAttribute('y', titleY );
yTitle.setAttributeNS(null, 'font-size', 14);
//yTitle.setAttributeNS(null, 'font-weight', 'bold');
yTitle.setAttributeNS(null, 'pointer-events', 'none');
yTitle.setAttributeNS(null, 'text-anchor', 'middle');
yTitle.setAttribute('transform', 'rotate(' + -90 + ',' + titleX + ',' + titleY + ')' );
yTitle.appendChild(SVGDocument.createTextNode( yLabel ));
if ( labelInfo.units )
{
var yUnits = SVGDocument.createElementNS(svgns, 'tspan');
yUnits.setAttributeNS(null, 'font-size', 11);
yUnits.setAttributeNS(null, 'font-weight', 'normal');
yUnits.appendChild(SVGDocument.createTextNode( ' (in ' + labelInfo.units + ')' ));
yTitle.appendChild( yUnits );
}
this.scale.y.appendChild(yTitle);
var yMark = SVGDocument.createElementNS(svgns, 'g');
yMark.setAttributeNS(null, 'stroke-width', 1.5);
yMark.setAttributeNS(null, 'stroke-linejoin', 'round');
yMark.setAttributeNS(null, 'stroke-linecap', 'round');
var linePoints = '';
if ( chart.is3d )
{
linePoints = (this.base.x - 5) + ',' + (this.base.y) + ' ' + (this.base.x) + ',' + (this.base.y) + ' ' + (this.base.x + 10) + ',' + (this.base.y - 10) + ' ' + (this.base.x + this.plotWidth + 10) + ',' + (this.base.y - 10);
}
else
{
linePoints = (this.base.x - 5) + ',' + (this.base.y) + ' ' + (this.base.x + this.plotWidth) + ',' + (this.base.y);
}
var yBG = SVGDocument.createElementNS(svgns, 'polyline');
yBG.setAttributeNS(null, 'points', linePoints);
yBG.setAttributeNS(null, 'fill', 'none');
yBG.setAttributeNS(null, 'stroke', '#ccc');
yBG.setAttributeNS(null, 'stroke-width', '0.75');
yMark.appendChild(yBG);
var yTick = SVGDocument.createElementNS(svgns, 'line');
yTick.setAttributeNS(null, 'x1', this.base.x - 5);
yTick.setAttributeNS(null, 'y1', this.base.y);
yTick.setAttributeNS(null, 'x2', this.base.x);
yTick.setAttributeNS(null, 'y2', this.base.y);
yTick.setAttributeNS(null, 'stroke', 'black');
yTick.setAttributeNS(null, 'stroke-width', 2);
yMark.appendChild(yTick);
this.scale.y.appendChild(yMark);
//draw sidewall
if ( chart.is3d )
{
var yWall = SVGDocument.createElementNS(svgns, 'g');
var linePoints = (this.base.x) + ',' + (this.base.y) + ' ' + (this.base.x + 10) + ',' + (this.base.y - 10) + ' ' + (this.base.x + 10) + ',' + ((this.base.y - this.plotHeight) - 10) + ' ' + (this.base.x) + ',' + (this.base.y - this.plotHeight) + ' ' + (this.base.x) + ',' + (this.base.y);
var gradient = ColorObj.createGradient( '#cccccc', 'linear', true );
yWall.appendChild( gradient );
var gradientId = gradient.getAttributeNS(null, 'id' );
var riser = SVGDocument.createElementNS(svgns, 'polyline');
riser.setAttributeNS(null, 'points', linePoints);
riser.setAttributeNS(null, 'fill', 'url(#' + gradientId + ')' );
riser.setAttributeNS(null, 'stroke', '#ccc');
riser.setAttributeNS(null, 'stroke-width', '0.75');
riser.setAttributeNS(null, 'stroke-opacity', '0.2');
yWall.appendChild( riser );
this.scale.y.appendChild( yWall );
}
for (var i = tickInterval, j = 1; i <= topValue; i += tickInterval, j++)
{
if ( 1 == labelInterval || (0 == j%labelInterval) )
{
var newScaleMark = yMark.cloneNode(true);
newScaleMark.setAttribute('transform', 'translate(0,' + -i + ')' );
this.scale.y.appendChild(newScaleMark);
var labelY = this.base.y - (i - (fontSize * 0.33));
newMarkLabel = SVGDocument.createElementNS(svgns, 'text');
newMarkLabel.setAttribute('x', this.base.x - 10);
newMarkLabel.setAttribute('y', labelY);
newMarkLabel.setAttributeNS(null, 'font-size', fontSize);
//newMarkLabel.setAttributeNS(null, 'font-weight', 'bold');
newMarkLabel.setAttributeNS(null, 'text-anchor', 'end');
newMarkLabel.appendChild( SVGDocument.createTextNode(j) );
this.scale.y.appendChild( newMarkLabel );
}
}
try
{
}
catch(er)
{
alert('Error in fn ChartCanvasObj.prototype.drawScaleY:\n' + er.message);
}
SVGDebug( 'exiting drawScaleY', 1 );
};
ChartCanvasObj.prototype.normalizeRange = function( baseNumber, fontSize )
{
SVGDebug( 'entering NormalizeRange', 1 );
var longInt = Math.ceil( baseNumber );
var newMax = longInt;
var labelNumber = longInt;
var units = null;
var numberString = longInt.toString();
var multiplier = 1;
var labelMultiplier = 1;
var labelInterval = 1;
var maxLabelCount = this.plotHeight / fontSize;
if ( maxLabelCount < longInt )
{
if ( 1000 <= longInt )
{
var delimiter = 2;
switch ( numberString.length )
{
case 4:
delimiter = 1;
multiplier = 1000;
units = 'thousands';
break;
case 5:
delimiter = 2;
multiplier = 1000;
units = 'thousands';
break;
case 6:
delimiter = 2;
multiplier = 10000;
units = 'ten thousands';
break;
case 7:
delimiter = 1;
multiplier = 1000000;
units = 'millions';
break;
case 8:
delimiter = 2;
multiplier = 1000000;
units = 'millions';
break;
case 9:
delimiter = 2;
multiplier = 10000000;
units = 'ten millions';
break;
}
numberString = numberString.substr(0, delimiter);
labelNumber = Number( numberString );
while ( longInt > labelNumber * multiplier )
{
labelNumber++;
}
}
else
{
if ( 0 != longInt%5 || numberString != longInt.toString() || maxLabelCount < Number(numberString))
{
labelInterval = this.findLabelInterval( labelNumber, maxLabelCount );
if ( maxLabelCount < labelInterval )
{
var numberArray = numberString.split('');
var lastDigit = Number(numberArray.pop());
if ( 5 > lastDigit )
{
numberArray.push('5');
labelNumber = Number(numberArray.join(''));
}
else
{
numberArray.push(0);
labelNumber = Number(numberArray.join('')) + 10;
}
}
}
}
newMax = labelNumber * multiplier;
labelNumber = labelNumber * labelMultiplier;
}
if ( maxLabelCount < labelNumber )
{
labelInterval = this.findLabelInterval( labelNumber, maxLabelCount );
if ( labelInterval == labelNumber )
{
if ( 100 < labelNumber )
{
var numberArray = labelNumber.toString().split('');
var lastDigit = Number(numberArray.pop());
if ( 5 == lastDigit )
{
numberArray.push(0);
labelNumber = Number(numberArray.join('')) + 10;
}
labelInterval = this.findLabelInterval( labelNumber, maxLabelCount );
var trialCap = 10;
while ( ( labelNumber == labelInterval) || ( maxLabelCount < (labelNumber / labelInterval)) && 0 < trialCap )
{
labelNumber += 10;
labelInterval = this.findLabelInterval( labelNumber, maxLabelCount );
trialCap--;
}
}
else
{
var trialCap = 5;
while ( maxLabelCount < labelInterval && 0 < trialCap )
{
labelNumber += 1;
labelInterval = this.findLabelInterval( labelNumber, maxLabelCount );
trialCap--;
}
trialCap = 10;
while ( maxLabelCount < (labelNumber / labelInterval) && 0 < trialCap )
{
labelNumber += 5;
labelInterval = this.findLabelInterval( labelNumber, maxLabelCount );
trialCap--;
}
}
newMax = labelNumber * multiplier;
}
}
var range = new LabelRangeObj( newMax, 0, labelNumber, 0, units, labelInterval );
SVGDebug( 'exiting NormalizeRange', 1 );
return range;
};
function LabelRangeObj( max, min, labelMax, labelMin, units, interval )
{
SVGDebug( 'entering LabelRangeObj', 1 );
this.max = max;
this.min = min;
this.labelMax = labelMax;
this.labelMin = labelMin;
this.units = units;
this.interval = interval;
SVGDebug( 'exiting LabelRangeObj', 1 );
};
ChartCanvasObj.prototype.findLabelInterval = function( maxValue, maxLabelCount )
{
SVGDebug( 'entering findLabelInterval', 1 );
var labelInterval = maxValue;
if ( maxLabelCount < maxValue )
{
var intervalArray = [ 1, 5, 10, 25, 50, 100 ];
for ( var m = 0, mLen = intervalArray.length; mLen > m; m++ )
{
var interval = intervalArray[ m ];
if ( 0 == (maxValue % interval) && maxLabelCount >= ( maxValue / interval ) )
{
labelInterval = interval;
if ( 5 < maxLabelCount && 5 >= ( maxValue / interval ) )
{
break;
}
}
}
}
SVGDebug( 'exiting findLabelInterval', 1 );
return labelInterval;
};
ChartCanvasObj.prototype.createLegend = function( id, x, y, color, value, truncateWidth )
{
SVGDebug( 'entering createLegend', 1 );
var labelText = value;
if ( truncateWidth )
{
labelText = TruncateText( value, truncateWidth, 12 );
}
var lineColor = ColorObj.shiftColor( color, -6 );
var graphic = SVGDocument.createElementNS(svgns, 'g');
graphic.setAttributeNS(null, 'id', id);
graphic.addEventListener('mouseover', LegendHighlight, false);
graphic.addEventListener('mouseout', LegendLowlight, false);
var legendBox = SVGDocument.createElementNS(svgns, 'rect');
legendBox.setAttributeNS(null, 'x', x);
legendBox.setAttributeNS(null, 'y', y);
legendBox.setAttributeNS(null, 'width', '20');
legendBox.setAttributeNS(null, 'height', '10');
legendBox.setAttributeNS(null, 'rx', 5);
legendBox.setAttributeNS(null, 'ry', 5);
legendBox.setAttributeNS(null, 'fill', color);
legendBox.setAttributeNS(null, 'stroke', lineColor);
legendBox.setAttributeNS(null, 'stroke-width', '2');
legendLabel = SVGDocument.createElementNS(svgns, 'text');
legendLabel.setAttribute('x', (x + 25) );
legendLabel.setAttribute('y', (y + 9) );
legendLabel.setAttributeNS(null, 'font-size', 12);
legendLabel.setAttributeNS(null, 'fill', 'black');
legendLabel.setAttributeNS(null, 'stroke', 'none');
legendLabel.appendChild(SVGDocument.createTextNode( labelText ));
graphic.appendChild(legendBox);
graphic.appendChild(legendLabel);
this.legend.element.appendChild( graphic );
SVGDebug( 'exiting createLegend', 1 );
return graphic;
};
ChartCanvasObj.prototype.createBarGraphic = function( datapoint, id, x, y, width, height, color, isRounded )
{
SVGDebug( 'entering createBarGraphic', 1 );
var lineColor = ColorObj.shiftColor( color, -6 );
var graphic = SVGDocument.createElementNS(svgns, 'g');
graphic.setAttributeNS(null, 'id', id);
graphic.setAttributeNS(null, 'fill', color);
graphic.setAttributeNS(null, 'stroke', lineColor);
graphic.setAttributeNS(null, 'stroke-width', '2');
graphic.setAttributeNS(null, 'stroke-linejoin', 'round');
graphic.setAttributeNS(null, 'stroke-linecap', 'round');
graphic.setAttributeNS(null, 'fill-rule', 'nonzero');
graphic.setAttributeNS(null, 'fill-opacity', '1');
var isReversed = false;
var barData = '';
if ( true == isRounded )
{
var barRx = width/5;
if ( 5 < barRx )
{
barRx = 5;
}
var barRy = barRx;
if ( 5 >= height )
{
var barRy = height/5;
if ( 5 < barRx )
{
barRy = 5;
}
}
if ( this.base.y >= y )
{
// create positive bar
barData = 'M' + x + ',' + (y + height) + ' V' + (y + barRy)
+ ' Q' + x + ',' + y + ' ' + (x + barRx) + ',' + y
+ ' H' + ((x + width) - barRx)
+ ' Q' + (x + width) + ',' + y + ' ' + (x + width) + ',' + (y + barRy)
+ ' V' + (y + height)
+ ' H' + x;
}
else if ( 0 != height )
{
// create negative bar
barData = 'M' + x + ',' + y + ' V' + ((y + height) - barRy)
+ ' Q' + x + ',' + (y + height) + ' ' + (x + barRx) + ',' + (y + height)
+ ' H' + ((x + width) - barRx)
+ ' Q' + (x + width) + ',' + (y + height) + ' ' + (x + width) + ',' + ((y + height) - barRy)
+ ' V' + y
+ ' H' + x;
isReversed = true;
}
}
else
{
barData = 'M' + x + ',' + (y + height) + ' V' + y
+ ' H' + (x + width)
+ ' V' + (y + height)
+ ' H' + x;
if ( this.base.y < y )
{
isReversed = true;
}
}
var bar = SVGDocument.createElementNS(svgns, 'path');
bar.setAttributeNS(null, 'd', barData);
var gradient = ColorObj.createGradient( color, 'linear', isReversed );
var gradientId = gradient.getAttributeNS(null, 'id' );
var fill = 'url(#' + gradientId + ')';
graphic.setAttributeNS(null, 'fill', fill );
if ( datapoint )
{
datapoint.fill = fill;
}
graphic.appendChild( gradient );
graphic.appendChild( bar );
SVGDebug( 'exiting createBarGraphic', 1 );
return graphic;
};
ChartCanvasObj.prototype.createBar3dGraphic = function( datapoint, id, x, y, width, height, color )
{
SVGDebug( 'entering createBar', 1 );
var lineColor = ColorObj.shiftColor( color, -6 );
var graphic = SVGDocument.createElementNS(svgns, 'g');
graphic.setAttributeNS(null, 'id', id);
graphic.setAttributeNS(null, 'fill', color);
graphic.setAttributeNS(null, 'stroke', lineColor);
graphic.setAttributeNS(null, 'stroke-width', '2');
graphic.setAttributeNS(null, 'stroke-linejoin', 'round');
graphic.setAttributeNS(null, 'stroke-linecap', 'round');
graphic.setAttributeNS(null, 'fill-rule', 'nonzero');
graphic.setAttributeNS(null, 'fill-opacity', '1');
// var bar = SVGDocument.createElementNS(svgns, 'g');
// create back, left side, and bottom
var barBackData = 'M' + (x + 10) + ',' + (y - 10) + ' H' + (x + 10 + width) + ' V' + ((y - 10) + height) + ' H' + (x + 10) + ' V' + (y - 10)
+ ' M' + x + ',' + y + ' L' + (x + 10) + ',' + (y - 10) + ' V' + ((y - 10) + height) + ' L' + x + ',' + (y + height) + ' V' + y
+ ' M' + x + ',' + (y + height) + ' L' + (x + 10) + ',' + ((y - 10) + height) + ' H' + (x + 10 + width) + ' L' + (x + width) + ',' + (y + height) + ' H' + x;
var barBack = SVGDocument.createElementNS(svgns, 'path');
barBack.setAttributeNS(null, 'd', barBackData);
barBack.setAttributeNS(null, 'fill-opacity', 1);
// create right side, and top
var darkColor = ColorObj.shiftColor( color, -4 );
var barMidData = 'M' + (x + width) + ',' + y + ' L' + ((x + width) + 10) + ',' + (y - 10) + ' V' + ((y - 10) + height) + ' L' + (x + width) + ',' + (y + height) + ' V' + y
+ ' M' + x + ',' + y + ' L' + (x + 10) + ',' + (y - 10) + ' H' + (x + 10 + width) + ' L' + (x + width) + ',' + y + ' H' + x;
var barMid = SVGDocument.createElementNS(svgns, 'path');
barMid.setAttributeNS(null, 'd', barMidData);
barMid.setAttributeNS(null, 'fill', darkColor);
// create front
var barFrontData = 'M' + x + ',' + y + ' H' + (x + width) + ' V' + (y + height) + ' H' + x + ' V' + y;
var barFront = SVGDocument.createElementNS(svgns, 'path');
barFront.setAttributeNS(null, 'd', barFrontData);
/*
bar.appendChild( barBack );
bar.appendChild( barMid );
bar.appendChild( barFront );
graphic.appendChild( bar );
*/
graphic.appendChild( barBack );
graphic.appendChild( barMid );
graphic.appendChild( barFront );
SVGDebug( 'exiting createBar', 1 );
return graphic;
};
ChartCanvasObj.prototype.createPointGraphic = function( datapoint, id, cx, cy, r, color )
{
SVGDebug( 'entering createPointGraphic', 1 );
var lineColor = ColorObj.shiftColor( color, -6 );
var graphic = SVGDocument.createElementNS(svgns, 'g');
graphic.setAttributeNS(null, 'stroke', lineColor);
graphic.setAttributeNS(null, 'id', id);
var point = SVGDocument.createElementNS(svgns, 'circle');
point.setAttributeNS(null, 'cx', cx);
point.setAttributeNS(null, 'cy', cy);
point.setAttributeNS(null, 'r', r);
var gradient = ColorObj.createGradient( color, 'radial', false );
var gradientId = gradient.getAttributeNS(null, 'id' );
var fill = 'url(#' + gradientId + ')';
graphic.setAttributeNS(null, 'fill', fill );
if ( datapoint )
{
datapoint.fill = fill;
}
graphic.appendChild( point );
graphic.appendChild( gradient );
SVGDebug( 'exiting createPointGraphic', 1 );
return graphic;
};
ChartCanvasObj.prototype.createLineGraphic = function( datapoint, id, x1, y1, x2, y2, color, dasharray )
{
SVGDebug( 'entering createLineGraphic', 1 );
var graphic = SVGDocument.createElementNS(svgns, 'line');
graphic.setAttributeNS(null, 'id', id);
graphic.setAttributeNS(null, 'x1', x1);
graphic.setAttributeNS(null, 'y1', y1);
graphic.setAttributeNS(null, 'x2', x2);
graphic.setAttributeNS(null, 'y2', y2);
graphic.setAttributeNS(null, 'fill', 'none');
graphic.setAttributeNS(null, 'stroke', color);
graphic.setAttributeNS(null, 'stroke-width', '3');
graphic.setAttributeNS(null, 'stroke-linecap', 'round');
if ( dasharray )
{
graphic.setAttributeNS(null, 'stroke-dasharray', dasharray);
}
SVGDebug( 'exiting createLineGraphic', 1 );
return graphic;
};
ChartCanvasObj.prototype.createLine3dGraphic = function( datapoint, id, x1, y1, x2, y2, color, dasharray )
{
SVGDebug( 'entering createLine', 1 );
var faceColor = color;
if ( y1 >= y2 )
{
faceColor = ColorObj.shiftColor( color, -4 );
}
var segmentData = 'M' + x1 + ',' + y1 + ' L' + (x1 + 10) + ',' + (y1 - 10) + ' L' + (x2 + 10) + ',' + (y2 - 10) + ' L' + x2 + ',' + y2 + ' Z';
var line = SVGDocument.createElementNS(svgns, 'path');
line.setAttributeNS(null, 'd', segmentData);
line.setAttributeNS(null, 'fill', faceColor);
line.setAttributeNS(null, 'stroke', color);
line.setAttributeNS(null, 'stroke-dasharray', dasharray);
line.setAttributeNS(null, 'stroke-width', '2');
line.setAttributeNS(null, 'stroke-linejoin', 'round');
line.setAttributeNS(null, 'stroke-linecap', 'round');
var graphic = SVGDocument.createElementNS(svgns, 'g');
graphic.setAttributeNS(null, 'id', id);
graphic.appendChild( line );
SVGDebug( 'exiting createLine', 1 );
return graphic;
};
ChartCanvasObj.prototype.createAreaGraphic = function( datapoint, id, x1, y1, x2, y2, color, position )
{
SVGDebug( 'entering createAreaGraphic', 1 );
var lineColor = ColorObj.shiftColor( color, -4 );
var areaData = 'M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2 + ' V' + this.base.y + ' H' + x1 + ' V' + y1;
var lineData = 'M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2 + ' M' + x2 + ',' + this.base.y + ' H' + x1 + ' M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2;
if ( 'start' == position )
{
lineData = 'M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2 + ' M' + x2 + ',' + this.base.y + ' H' + x1 + ' V' + y1;
}
else if ( 'end' == position )
{
lineData = 'M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2 + ' V' + this.base.y + ' H' + x1;
}
var area = SVGDocument.createElementNS(svgns, 'path');
area.setAttributeNS(null, 'd', areaData);
area.setAttributeNS(null, 'fill', color);
area.setAttributeNS(null, 'shape-rendering', 'crispEdges');
var line = SVGDocument.createElementNS(svgns, 'path');
line.setAttributeNS(null, 'd', lineData);
line.setAttributeNS(null, 'fill', 'none');
line.setAttributeNS(null, 'stroke', lineColor);
line.setAttributeNS(null, 'stroke-width', '2');
line.setAttributeNS(null, 'stroke-linejoin', 'round');
line.setAttributeNS(null, 'stroke-linecap', 'round');
var graphic = SVGDocument.createElementNS(svgns, 'g');
graphic.setAttributeNS(null, 'id', id);
graphic.appendChild(area);
graphic.appendChild(line);
SVGDebug( 'exiting createAreaGraphic', 1 );
return graphic;
};
ChartCanvasObj.prototype.createArea3dGraphic = function( datapoint, id, x1, y1, x2, y2, color, position )
{
SVGDebug( 'entering createArea', 1 );
var lineColor = ColorObj.shiftColor( color, -4 );
var faceColor = color;
if ( y1 >= y2 )
{
faceColor = ColorObj.shiftColor( color, -4 );
}
var topData = 'M' + x1 + ',' + y1 + ' L' + (x1 + 10) + ',' + (y1 - 10) + ' L' + (x2 + 10) + ',' + (y2 - 10) + ' L' + x2 + ',' + y2 + ' Z';
var top = SVGDocument.createElementNS(svgns, 'path');
top.setAttributeNS(null, 'd', topData);
top.setAttributeNS(null, 'fill', faceColor);
top.setAttributeNS(null, 'stroke', lineColor);
top.setAttributeNS(null, 'stroke-width', '2');
top.setAttributeNS(null, 'stroke-linejoin', 'round');
top.setAttributeNS(null, 'stroke-linecap', 'round');
var side = null;
if ( 'end' == position )
{
var sideData = 'M' + x2 + ',' + y2 + ' L' + (x2 + 10) + ',' + (y2 - 10) + ' V' + (this.base.y - 10) + ' L' + x2 + ',' + this.base.y + ' Z';
var side = SVGDocument.createElementNS(svgns, 'path');
side.setAttributeNS(null, 'd', sideData);
side.setAttributeNS(null, 'fill', lineColor);
side.setAttributeNS(null, 'stroke', lineColor);
side.setAttributeNS(null, 'stroke-width', '2');
side.setAttributeNS(null, 'stroke-linejoin', 'round');
side.setAttributeNS(null, 'stroke-linecap', 'round');
}
var areaData = 'M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2 + ' V' + this.base.y + ' H' + x1 + ' V' + y1;
var lineData = 'M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2 + ' M' + x2 + ',' + this.base.y + ' H' + x1 + ' M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2;
if ( 'start' == position )
{
lineData = 'M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2 + ' M' + x2 + ',' + this.base.y + ' H' + x1 + ' V' + y1;
}
else if ( 'end' == position )
{
lineData = 'M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2 + ' V' + this.base.y + ' H' + x1;
}
var area = SVGDocument.createElementNS(svgns, 'path');
area.setAttributeNS(null, 'd', areaData);
area.setAttributeNS(null, 'fill', color);
area.setAttributeNS(null, 'shape-rendering', 'crispEdges');
var line = SVGDocument.createElementNS(svgns, 'path');
line.setAttributeNS(null, 'd', lineData);
line.setAttributeNS(null, 'fill', 'none');
line.setAttributeNS(null, 'stroke', lineColor);
line.setAttributeNS(null, 'stroke-width', '2');
line.setAttributeNS(null, 'stroke-linejoin', 'round');
line.setAttributeNS(null, 'stroke-linecap', 'round');
var graphic = SVGDocument.createElementNS(svgns, 'g');
graphic.setAttributeNS(null, 'id', id);
graphic.appendChild(top);
if ( side )
{
graphic.appendChild(side);
}
graphic.appendChild(area);
graphic.appendChild(line);
SVGDebug( 'exiting createArea', 1 );
return graphic;
};
ChartCanvasObj.prototype.createPieGraphic = function( datapoint, id, x, y, originPos, percentage, r, color, value )
{
SVGDebug( 'entering createPieGraphic', 1 );
var fontSize = 14;
var centerX = x;
var centerY = y;
var pi = Math.PI * 2;
var graphic = SVGDocument.createElementNS(svgns, 'g');
graphic.setAttributeNS(null, 'id', id);
var arcStartX = centerX - (-r * Math.sin(originPos * pi));
var arcStartY = centerY + (-r * Math.cos(originPos * pi));
var arcEndX = centerX - (-r * Math.sin((originPos + percentage) * pi));
var arcEndY = centerY + (-r * Math.cos((originPos + percentage) * pi));
var labelX = centerX - ((-r - (fontSize + 1) ) * Math.sin((originPos + ( percentage/2 )) * pi));
var labelY = centerY + ((-r - (fontSize + 1) ) * Math.cos((originPos + ( percentage/2 )) * pi));
var orientation = '0 0 1';
if ( 0.5 <= percentage )
{
orientation = '1 1 1';
}
if ( 1 == percentage )
{
arcEndX = arcStartX - 1;
arcEndY += ' L' + arcStartX + ',' + arcStartY;
}
var pathData = 'M' + centerX + ',' + centerY + ' L'
+ arcStartX
+ ','
+ arcStartY
+ ' A'
+ r
+ ','
+ r
+ ' '
+ orientation
+ ' '
+ arcEndX
+ ','
+ arcEndY
+ ' Z';
var shadow = SVGDocument.createElementNS(svgns, 'path' );
shadow.setAttributeNS(null, 'id', id + '-shadow' );
shadow.setAttributeNS(null, 'd', pathData );
var slice = shadow.cloneNode( false );
slice.setAttributeNS(null, 'id', id + '-slice' );
slice.setAttributeNS(null, 'd', pathData );
slice.setAttributeNS(null, 'stroke', 'black' );
shadow.setAttributeNS(null, 'fill', 'none' );
graphic.appendChild(slice);
graphic.appendChild(shadow);
// Angles[RefID] = originPos + percentage / 2;
//var labelText = Math.ceil( value );
var labelText = RoundToDecimal( value, 1 );
var sliceLabel = SVGDocument.createElementNS(svgns, 'text');
sliceLabel.setAttribute('x', labelX );
sliceLabel.setAttribute('y', labelY + (fontSize * 0.33) );
sliceLabel.setAttributeNS(null, 'font-size', fontSize );
sliceLabel.setAttributeNS(null, 'fill', 'black' );
//sliceLabel.setAttributeNS(null, 'font-weight', 'bold');
sliceLabel.setAttributeNS(null, 'pointer-events', 'none');
sliceLabel.setAttributeNS(null, 'text-anchor', 'middle');
sliceLabel.appendChild( SVGDocument.createTextNode( labelText ) );
graphic.appendChild(sliceLabel);
graphic.setAttributeNS(null, 'fill', color );
SVGDebug( 'exiting createPieGraphic', 1 );
return graphic;
};
ChartCanvasObj.prototype.addMetadata = function( element, title, desc )
{
SVGDebug( 'entering addMetadata', 1 );
var titleEl = this.createTextElement( 'title', title );
element.appendChild( titleEl );
var descEl = this.createTextElement( 'desc', desc );
element.appendChild( descEl );
SVGDebug( 'exiting addMetadata', 1 );
};
ChartCanvasObj.prototype.createTextElement = function( elementName, value )
{
SVGDebug( 'entering createTextElement', 1 );
var textEl = SVGDocument.createElementNS( svgns, elementName );
textEl.appendChild( SVGDocument.createTextNode( value ) );
SVGDebug( 'exiting createTextElement', 1 );
return textEl;
};
function CreateUniqueId( idSeed )
{
SVGDebug( 'entering CreateUniqueId', 1 );
try{
var instance = 0;
var newId = idSeed + '_' + instance;
while ( true == ChartCanvas.idArray[ newId ] || SVGDocument.getElementById( newId ) )
{
instance++;
newId = idSeed + '_' + instance;
}
ChartCanvas.idArray[ newId ] = true;
SVGDebug( 'exiting CreateUniqueId', 1 );
return newId;
} catch(er) { alert('Error in CreateUniqueId: ' + er.message); }
};
/**************************
*
* Text Helper Functions
*
***************************/
function FindTextWidth( string, fontSize, fontWeight )
{
SVGDebug( 'entering FindTextWidth', 1 );
try{
if ( 16 != fontSize )
{
TextWrapBuffer.setAttributeNS(null, 'font-size', fontSize);
}
if ( 'bold' != fontWeight )
{
TextWrapBuffer.setAttributeNS(null, 'font-weight', fontWeight);
}
TextWrapBuffer.firstChild.nodeValue = string;
//return rectangle around object as SVGRect object
var outline = TextWrapBuffer.getBBox();
SVGDebug( 'exiting FindTextWidth', 1 );
return Number(outline.width);
} catch(er) { alert('Error in FindTextWidth: ' + er.message); }
};
function TruncateText( textString, width, fontSize )
{
SVGDebug( 'entering TruncateText', 1 );
var charCount = textString.length;
if ( !fontSize )
{
fontSize = 15;
}
var newCharCount = Math.ceil( (width / fontSize) * 1.5 );
var newString = textString;
if ( charCount > newCharCount )
{
var textArray = textString.split('');
textArray.splice(newCharCount, charCount, '...' )
newString = textArray.join('');
}
SVGDebug( 'exiting TruncateText', 1 );
return newString;
try{
} catch(er) { alert('Error in TruncateText: ' + er.message); }
};
function WrapText( fullString, lineWidth, xVal, fontSize )
{
//buh()
try
{
var textNode = SVGDocument.createElementNS(svgns, 'tspan');
if( !fontSize )
{
fontSize = 16;
}
TextWrapBuffer.setAttributeNS(null, 'font-size', fontSize );
//fullString = fullString.replace(/> <');
var wordArray = fullString.split(' ');
var incrementLine = true;
var eachWord = '';
var tempLine = '';
var eachLine = '';
for ( var w = 0, wLen = wordArray.length; wLen > w; w++ )
{
eachWord = wordArray[w];
if ( '' != eachWord && ' ' != eachWord )
{
tempLine += eachWord + ' ';
TextWrapBuffer.firstChild.nodeValue = tempLine;
if ( lineWidth >= TextWrapBuffer.getComputedTextLength() )
{
eachLine = tempLine;
}
else
{
tempLine = eachWord + ' ';
var newLine = CreateTextItem( eachLine, xVal, incrementLine, fontSize );
textNode.appendChild( newLine );
incrementLine = true;
}
}
}
var newLine = CreateTextItem( tempLine, xVal, incrementLine, fontSize );
textNode.appendChild( newLine );
return textNode;
}
catch(er)
{
alert('Error in fn WrapText:\n' + er.message);
}
};
function SplitLongWord( word, maxLength )
{
try{
var splitWord = new Array();
if ( -1 != word.indexOf('-') )
{
splitWord = word.split('-');
//splitWord[0] += '-';
for ( var i = 0, iLen = splitWord.length; iLen >= i; i++ )
{
splitWord[i] += '-';
}
}
else if ( null != word )
{
}
else
{
}
return splitWord;
} catch(er) { alert('Error in Text: ' + er.message); }
};
String.prototype.trim = TrimString;
function TrimString( string )
{
try{
var newString = this.replace(/\s+$/g, ''); //.replace(/^\s+/g, '')
return newString;
} catch(er) { alert('Error in TrimString: ' + er.message); }
}
function CreateTextItem( lineString, xVal, incrementLine, fontSize )
{
try{
var newLine = SVGDocument.createElementNS(svgns, 'tspan');
if ( xVal )
{
newLine.setAttributeNS(null, 'x', xVal);
}
if ( incrementLine )
{
newLine.setAttributeNS(null, 'dy', fontSize + 2);
}
var lineText = SVGDocument.createTextNode(lineString);
newLine.appendChild(lineText);
return newLine;
} catch(er) { alert('Error in Text: ' + er.message); }
};
// BEGIN REMOVE
/**************************
*
* Number Helper Functions
*
***************************/
function RoundToDecimal_old( value, place )
{
SVGDebug( 'entering RoundToDecimal', 1 );
var digit = Math.pow( 10, place);
var tempValue = value * digit;
tempValue = Math.round( tempValue );
var newValue = tempValue / digit;
SVGDebug( 'exiting RoundToDecimal', 1 );
return newValue;
};
function RoundToDecimal( value, place )
{
SVGDebug( 'entering RoundToDecimal', 1 );
place = 1;
if ( 0 == value )
{
return value;
}
/*
else if ( 10 <= value )
{
return Math.round( value );
}
*/
else if ( 1 > value )
{
place = 2;
}
var digit = Math.pow( 10, place);
var tempValue = value * digit;
tempValue = Math.round( tempValue );
var newValue = tempValue / digit;
SVGDebug( 'exiting RoundToDecimal', 1 );
return newValue;
};
function showStatistics( total, count, max, min )
{
SVGDebug( 'entering showStatistics', 1 );
var statsArray = [];
var modeArray = [];
var total = 0;
var modeCount = 1;
var modeCandidates = [];
var sqrTotal = 0;
for ( var eachItem in MatchList )
{
if ( 'toJSON' != eachItem )
{
var eachValue = Number(MatchList[ eachItem ]);
statsArray.push(eachValue);
total += eachValue;
sqrTotal += ( eachValue * eachValue )
if ( modeArray[eachValue] )
{
modeArray[eachValue]++;
}
else
{
modeArray[eachValue] = 1;
}
if ( modeCount < modeArray[eachValue] )
{
modeCount = modeArray[ eachValue ];
modeCandidates = [eachValue];
}
else if ( modeCount == modeArray[eachValue] )
{
modeCandidates.push( eachValue );
}
}
}
statsArray = statsArray.sort();
var matches = statsArray.length;
var mean = total/matches;
var min = statsArray[ 0 ];
var max = statsArray[ statsArray.length - 1];
var range = max - min;
var median = 0;
var variance = ( sqrTotal - ((total * total)/matches) ) / matches;
var standardDeviation = Math.sqrt( variance );
if ( 0 == matches%2 )
{
var midpoint = matches/2;
var median1 = statsArray[ midpoint - 2];
var median2 = statsArray[ midpoint - 1 ];
median = (median1 + median2)/2;
}
else
{
var midpoint = (matches - 1) / 2;
median = statsArray[ midpoint ];
}
var modes = 'none';
if ( matches > modeCandidates.length )
{
modes = modeCandidates.join(' ');
}
TotalCount.firstChild.nodeValue = this.barList.length;
Matches.firstChild.nodeValue = matches;
TotalValue.firstChild.nodeValue = total;
Range.firstChild.nodeValue = range;
ModeValue.firstChild.nodeValue = modes;
MeanValue.firstChild.nodeValue = RoundToDecimal( mean, 3 );
MedianValue.firstChild.nodeValue = RoundToDecimal( median, 3 );
StandardDeviation.firstChild.nodeValue = RoundToDecimal( standardDeviation, 15 );
SVGDebug( 'exiting showStatistics', 1 );
};
// END REMOVE
function StatisticsObj()
{
SVGDebug( 'entering StatisticsObj', 1 );
this.dataCount = 0;
this.sumXY = 0;
this.sumX = 0;
this.sumY = 0;
this.sumXsq = 0;
this.m = 0;
this.b = 0;
SVGDebug( 'exiting StatisticsObj', 1 );
};
StatisticsObj.prototype.resetData = function()
{
SVGDebug( 'entering StatisticsObj.prototype.resetData', 1 );
this.dataCount = 0;
this.sumXY = 0;
this.sumX = 0;
this.sumY = 0;
this.sumXsq = 0;
this.m = 0;
this.b = 0;
SVGDebug( 'exiting StatisticsObj.prototype.resetData', 1 );
}
StatisticsObj.prototype.addDataPoint = function( x, y )
{
SVGDebug( 'entering StatisticsObj.prototype.addDataPoint', 1 );
this.sumXY += x * y;
this.sumX += x;
this.sumY += y;
this.sumXsq += x * x;
this.dataCount++;
SVGDebug( 'exiting StatisticsObj.prototype.addDataPoint', 1 );
};
StatisticsObj.prototype.findTrendLine = function( x1, x2 )
{
SVGDebug( 'entering StatisticsObj.prototype.findTrendLine', 1 );
this.m = ( this.dataCount * this.sumXY - ( this.sumX * this.sumY ) )/( this.dataCount * this.sumXsq - ( this.sumX * this.sumY ) );
this.b = ( this.sumY - this.m * this.sumX ) / this.dataCount;
var y1 = ( this.m * x1 + this.b );
var y2 = ( this.m * x2 + this.b );
var start = new PointObj( x1, y1 );
var end = new PointObj( x2, y2 );
this.resetData();
return [ start, end ];
SVGDebug( 'exiting StatisticsObj.prototype.findTrendLine', 1 );
};
/**************************
*
* Color Functionality
*
***************************/
var colorIndex = 0;
var ColorObj = {
nameArray : ['sas1', 'sas2', 'sas3', 'sas4', 'sas5', 'sas6', 'sas7', 'sas8', 'sas9', 'sas10', 'sas11', 'sas12', 'red', 'blue', 'lime', 'orange', 'purple', 'gold', 'deeppink', 'lightseagreen', 'crimson', 'slateblue', 'midnightblue', 'mediumaquamarine', 'tomato', 'violet', 'yellow', 'gray', 'darksalmon', 'darkgoldenrod', 'darkseagreen', 'greenyellow', 'magenta', 'darkslateblue', 'blueviolet', 'firebrick', 'lightgreen', 'navy', 'sandybrown', 'green', 'palevioletred', 'darkslategray', 'coral', 'deepskyblue', 'rosybrown', 'darkviolet', 'saddlebrown', 'olivedrab', 'black', 'orchid', 'brown', 'cadetblue', 'chartreuse', 'chocolate', 'cornflowerblue', 'darkblue', 'darkcyan', 'darkgreen', 'darkkhaki', 'darkmagenta', 'fuchsia', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'dimgray', 'darkturquoise', 'forestgreen', 'goldenrod', 'hotpink', 'indianred', 'dodgerblue', 'indigo', 'lawngreen', 'lightcoral', 'lightslategray', 'limegreen', 'maroon', 'mediumblue', 'mediumorchid', 'mediumseagreen', 'mediumslateblue', 'lightsalmon', 'mediumturquoise', 'mediumvioletred', 'olive', 'orangered', 'mediumpurple', 'peru', 'plum', 'mediumspringgreen', 'royalblue', 'salmon', 'seagreen', 'sienna', 'slategray', 'springgreen', 'steelblue', 'tan', 'teal', 'turquoise', 'yellowgreen'],
hexArray : ['#6173A9', '#8DA642', '#98341C', '#FDC861', '#8AA4C9', '#6F7500', '#B87F32', '#D6C66E', '#5E528B', '#679920', '#C8573C', '#7F5934', '#ff0000', '#0000ff', '#00ff00', '#ffa500', '#800080', '#ffd700', '#ff1493', '#20b2aa', '#dc143c', '#6a5acd', '#191970', '#66cdaa', '#ff6347', '#ee82ee', '#ffff00', '#808080', '#e9967a', '#b8860b', '#8fbc8f', '#adff2f', '#ff00ff', '#483d8b', '#8a2be2', '#b22222', '#90ee90', '#000080', '#f4a460', '#008000', '#db7093', '#2f4f4f', '#ff7f50', '#00bfff', '#bc8f8f', '#9400d3', '#8b4513', '#6b8e23', '#000000', '#da70d6', '#a52a2a', '#5f9ea0', '#7fff00', '#d2691e', '#6495ed', '#00008b', '#008b8b', '#006400', '#bdb76b', '#8b008b', '#ff00ff', '#556b2f', '#ff8c00', '#9932cc', '#8b0000', '#696969', '#00ced1', '#228b22', '#daa520', '#ff69b4', '#cd5c5c', '#1e90ff', '#4b0082', '#7cfc00', '#f08080', '#778899', '#32cd32', '#800000', '#0000cd', '#ba55d3', '#3cb371', '#7b68ee', '#ffa07a', '#48d1cc', '#c71585', '#808000', '#ff4500', '#9370db', '#cd853f', '#dda0dd', '#00fa9a', '#4169e1', '#fa8072', '#2e8b57', '#a0522d', '#708090', '#00ff7f', '#4682b4', '#d2b48c', '#008080', '#40e0d0', '#9acd32'],
rgbArray : ['rgb(97, 115, 169)', 'rgb(141, 166, 66)', 'rgb(152, 52, 28)', 'rgb(253, 200, 97)', 'rgb(138, 164, 201)', 'rgb(111, 117, 0)', 'rgb(184, 127, 50)', 'rgb(214, 198, 110)', 'rgb(94, 82, 139)', 'rgb(103, 153, 32)', 'rgb(200, 87, 60)', 'rgb(127, 89, 52)', 'rgb(255, 0, 0)', 'rgb(0, 0, 255)', 'rgb(0, 255, 0)', 'rgb(255, 165, 0)', 'rgb(128, 0, 128)', 'rgb(255, 215, 0)', 'rgb(255, 20, 147)', 'rgb( 32, 178, 170)', 'rgb(220, 20, 60)', 'rgb(106, 90, 205)', 'rgb( 25, 25, 112)', 'rgb(102, 205, 170)', 'rgb(255, 99, 71)', 'rgb(238, 130, 238)', 'rgb(255, 255, 0)', 'rgb(128, 128, 128)', 'rgb(233, 150, 122)', 'rgb(184, 134, 11)', 'rgb(143, 188, 143)', 'rgb(173, 255, 47)', 'rgb(255, 0, 255)', 'rgb( 72, 61, 139)', 'rgb(138, 43, 226)', 'rgb(178, 34, 34)', 'rgb(144, 238, 144)', 'rgb(0, 0, 128)', 'rgb(244, 164, 96)', 'rgb(0, 128, 0)', 'rgb(219, 112, 147)', 'rgb( 47, 79, 79)', 'rgb(255, 127, 80)', 'rgb(0, 191, 255)', 'rgb(188, 143, 143)', 'rgb(148, 0, 211)', 'rgb(139, 69, 19)', 'rgb(107, 142, 35)', 'rgb(0, 0, 0)', 'rgb(218, 112, 214)', 'rgb(165, 42, 42)', 'rgb( 95, 158, 160)', 'rgb(127, 255, 0)', 'rgb(210, 105, 30)', 'rgb(100, 149, 237)', 'rgb(0, 0, 139)', 'rgb(0, 139, 139)', 'rgb(0, 100, 0)', 'rgb(189, 183, 107)', 'rgb(139, 0, 139)', 'rgb(255, 0, 255)', 'rgb( 85, 107, 47)', 'rgb(255, 140, 0)', 'rgb(153, 50, 204)', 'rgb(139, 0, 0)', 'rgb(105, 105, 105)', 'rgb(0, 206, 209)', 'rgb( 34, 139, 34)', 'rgb(218, 165, 32)', 'rgb(255, 105, 180)', 'rgb(205, 92, 92)', 'rgb( 30, 144, 255)', 'rgb( 75, 0, 130)', 'rgb(124, 252, 0)', 'rgb(240, 128, 128)', 'rgb(119, 136, 153)', 'rgb( 50, 205, 50)', 'rgb(128, 0, 0)', 'rgb(0, 0, 205)', 'rgb(186, 85, 211)', 'rgb( 60, 179, 113)', 'rgb(123, 104, 238)', 'rgb(255, 160, 122)', 'rgb( 72, 209, 204)', 'rgb(199, 21, 133)', 'rgb(128, 128, 0)', 'rgb(255, 69, 0)', 'rgb(147, 112, 219)', 'rgb(205, 133, 63)', 'rgb(221, 160, 221)', 'rgb(0, 250, 154)', 'rgb( 65, 105, 225)', 'rgb(250, 128, 114)', 'rgb( 46, 139, 87)', 'rgb(160, 82, 45)', 'rgb(112, 128, 144)', 'rgb(0, 255, 127)', 'rgb( 70, 130, 180)', 'rgb(210, 180, 140)', 'rgb(0, 128, 128)'],
getHexByName : function( name )
{
for ( var i = 0, iLen = this.nameArray.length; iLen > i; i++ )
{
var eachItem = this.nameArray[i];
if ( name == eachItem )
{
return this.hexArray[i];
}
}
},
getRgbByName : function( name )
{
for ( var i = 0, iLen = this.nameArray.length; iLen > i; i++ )
{
var eachItem = this.nameArray[i];
if ( name == eachItem )
{
return this.rgbArray[i];
}
}
},
getNameByHex : function( hex )
{
for ( var i = 0, iLen = this.hexArray.length; iLen > i; i++ )
{
var eachItem = this.hexArray[i];
if ( hex == eachItem )
{
return this.nameArray[i];
}
}
},
getRgbByHex : function( hex )
{
for ( var i = 0, iLen = this.hexArray.length; iLen > i; i++ )
{
var eachItem = this.hexArray[i];
if ( hex == eachItem )
{
return this.rgbArray[i];
}
}
hex = hex.replace('#', '');
var rgbArray = [];
rgbArray[0] = parseInt( hex.substring(0,2), 16);
rgbArray[1] = parseInt( hex.substring(2,4), 16);
rgbArray[2] = parseInt( hex.substring(4,6), 16);
var rgb = 'rgb(' + rgbArray.join(', ') + ')';
return rgb;
},
getNameByRgb : function( rgb )
{
for ( var i = 0, iLen = this.rgbArray.length; iLen > i; i++ )
{
var eachItem = this.rgbArray[i];
if ( rgb == eachItem )
{
return this.nameArray[i];
}
}
},
getHexByRgb : function( rgb )
{
for ( var i = 0, iLen = this.rgbArray.length; iLen > i; i++ )
{
var eachItem = this.rgbArray[i];
if ( rgb == eachItem )
{
return this.hexArray[i];
}
}
var rgbArray = this.splitRgb( rgb );
var hexArray = [];
hexArray[0] = rgbArray[0].toString(16);
hexArray[1] = rgbArray[1].toString(16);
hexArray[2] = rgbArray[2].toString(16);
var hex = '#' + hexArray.join('');
return hex;
},
getHex : function( colorValue )
{
var hex = null;
if ( 0 == colorValue.indexOf('#') )
{
hex = this.normalizeHex( colorValue );
}
else if ( 0 == colorValue.indexOf('rgb') )
{
var rgb = this.normalizeRgb( colorValue );
hex = this.getHexByRgb( rgb );
}
else
{
hex = this.getHexByName( colorValue );
}
return hex;
},
normalizeHex : function( hex )
{
hex = hex.toLowerCase();
if ( 4 == hex.length )
{
var hexSplit = hex.split('');
hex = hexSplit[0] + hexSplit[1] + hexSplit[1] + hexSplit[2] + hexSplit[2] + hexSplit[3] + hexSplit[3];
}
return hex;
},
normalizeRgb : function( rgb )
{
var rgbSplit = this.splitRgb( rgb );
rgb = 'rgb(' + rgbSplit.join(', ') +')';
return rgb;
},
splitRgb : function( rgb )
{
rgb = rgb.replace(/ /g, '');
rgb = rgb.replace('rgb(', '');
rgb = rgb.replace(')', '');
var rgbSplit = rgb.split(',');
return rgbSplit;
},
shiftColor : function( colorValue, shadeMultiplier )
{
if ( !colorValue )
{
return;
}
var rgb = null;
if ( -1 != colorValue.indexOf('#') )
{
var hex = this.normalizeHex( colorValue );
rgb = this.getRgbByHex( hex );
}
else if ( -1 == colorValue.indexOf('rgb') )
{
rgb = this.getRgbByName( colorValue );
}
else
{
rgb = this.normalizeRgb( colorValue );
}
var rgbArray = this.splitRgb( rgb );
if ( !shadeMultiplier )
{
shadeMultiplier = 1;
}
var shiftValue = 20 * shadeMultiplier;
for ( var i = 0, iLen = rgbArray.length; iLen > i; i++ )
{
var eachComponent = Number(rgbArray[i]);
eachComponent += shiftValue;
if ( 255 < eachComponent )
{
eachComponent = 255;
}
else if ( 0 > eachComponent )
{
eachComponent = 0;
}
rgbArray[i] = eachComponent;
}
var newRgb = 'rgb(' + rgbArray.join(', ') +')';
return newRgb;
},
createGradient : function( baseColor, type, isReversed, isHorizontal )
{
var fadeColor = ColorObj.shiftColor( baseColor, 4 );
var hexVal = this.getHex( baseColor );
var gradientId = CreateUniqueId( type + 'Gradient_' + hexVal.replace('#', '') );
var gradient = null;
if ( 'linear' == type )
{
gradient = SVGDocument.createElementNS(svgns, 'linearGradient');
gradient.setAttributeNS(null, 'id', gradientId );
gradient.setAttributeNS(null, 'x1', '0%' );
gradient.setAttributeNS(null, 'y1', '0%' );
gradient.setAttributeNS(null, 'x2', '0%' );
gradient.setAttributeNS(null, 'y2', '100%' );
if ( false == isHorizontal )
{
gradient.setAttributeNS(null, 'x2', '100%' );
gradient.setAttributeNS(null, 'y2', '0%' );
}
}
else if ( 'radial' == type )
{
gradient = SVGDocument.createElementNS(svgns, 'radialGradient');
gradient.setAttributeNS(null, 'id', gradientId );
gradient.setAttributeNS(null, 'cx', '50%' );
gradient.setAttributeNS(null, 'cy', '50%' );
gradient.setAttributeNS(null, 'r', '100%' );
gradient.setAttributeNS(null, 'fx', '35%' );
gradient.setAttributeNS(null, 'fy', '35%' );
gradient.setAttributeNS(null, 'gradientUnits', 'userSpaceOnUse' );
}
var startColor = baseColor;
var endColor = fadeColor;
if ( true == isReversed )
{
startColor = fadeColor;
endColor = baseColor;
}
var stop1 = SVGDocument.createElementNS(svgns, 'stop');
stop1.setAttributeNS(null, 'offset', '0' );
stop1.setAttributeNS(null, 'stop-color', startColor );
gradient.appendChild( stop1 );
var stop2 = SVGDocument.createElementNS(svgns, 'stop');
stop2.setAttributeNS(null, 'offset', '1' );
stop2.setAttributeNS(null, 'stop-color', endColor );
gradient.appendChild( stop2 );
return gradient;
},
getNextRgbColor : function( newIndex )
{
if ( newIndex )
{
//colorIndex += newIndex;
colorIndex = newIndex;
}
if ( this.rgbArray.length <= colorIndex )
{
colorIndex = colorIndex - this.rgbArray.length;
}
var rgbColor = this.rgbArray[ colorIndex ];
colorIndex++;
return rgbColor;
}
};
/****************************
*
* XML/Data Input Processing
*
*****************************/
parent.ProcessData = ProcessData;
function ProcessData( dataString, isAppend, callback )
{
SVGDebug( 'entering ProcessData', 1 );
if ( dataString )
{
if ( isAppend )
{
ProcessData2( dataString, callback );
}
else
{
ResetData( dataString, callback );
}
}
else
{
alert('Could not load data. No data available.');
}
SVGDebug( 'exiting ProcessData', 1 );
};
function ResetData( dataString, callback )
{
SVGDebug( 'entering ResetData', 1 );
ChartCanvas.idArray = [];
ChartCanvas.colorMatchArray = [];
var removeArray = [ ChartCanvas.scale.x, ChartCanvas.scale.y, ChartCanvas.element, ChartCanvas.legend.element ];
for ( var i = 0, iLen = removeArray.length; iLen > i; i++ )
{
var eachItem = removeArray[i];
if ( eachItem && eachItem.parentNode)
{
var newItem = eachItem.cloneNode( false );
eachItem.parentNode.replaceChild( newItem, eachItem );
}
}
ChartCanvas = null;
InitCharts();
ProcessData2( dataString, callback );
SVGDebug( 'exiting ResetData', 1 );
};
function ProcessData2( dataString, callback )
{
SVGDebug( 'entering ProcessData', 1 );
var success = false;
if ( dataString )
{
//var tempColorIndex = 0;
var dataElement = parseXML( dataString, SVGDocument);
if ( dataElement )
{
var stuff = 'all data:';
if ( 9 == dataElement.nodeType )
{
dataElement = dataElement.documentElement;
}
DataBuffer.appendChild( dataElement );
dataElement = DataBuffer.firstChild;
var chartNS = dataElement.namespaceURI;
if ( 'chartInstance' == dataElement.localName )
{
var width = dataElement.getAttributeNS( null, 'width' );
var height = dataElement.getAttributeNS( null, 'height' );
var legendPosition = dataElement.getAttributeNS( null, 'legendPosition' );
if ( !legendPosition || '' == legendPosition )
{
legendPosition = 'none';
}
ChartCanvas.legend.position = legendPosition;
ChartCanvas.setDimensions( width, height, true );
//return list of target node's children of this element type as objects
var dataElNodes = dataElement.childNodes;
for ( var d = 0, dLen = dataElNodes.length; dLen > d; d++ )
{
var eachChart = dataElNodes.item( d );
if ( 'chart' == eachChart.localName )
{
var is3dValue = eachChart.getAttributeNS( null, 'is3d' );
var is3d = false;
if ( 'true' == is3dValue )
{
is3d = true;
}
var showTrendValue = eachChart.getAttributeNS( null, 'showTrend' );
var showTrend = false;
if ( 'true' == showTrendValue )
{
showTrend = true;
}
var chartType = eachChart.getAttributeNS( null, 'type' );
var axisX = eachChart.getAttributeNS( null, 'axis-x' );
var axisY = eachChart.getAttributeNS( null, 'axis-y' );
var xMin = eachChart.getAttributeNS( null, 'min-x' );
var yMin = eachChart.getAttributeNS( null, 'min-y' );
var maxX = eachChart.getAttributeNS( null, 'max-x' );
var maxY = eachChart.getAttributeNS( null, 'max-y' );
var xTickStep = eachChart.getAttributeNS( null, 'tick-step-x' );
var yTickStep = eachChart.getAttributeNS( null, 'tick-step-y' );
var xLabelStep = eachChart.getAttributeNS( null, 'label-step-x' );
var yLabelStep = eachChart.getAttributeNS( null, 'label-step-y' );
var series1 = eachChart.getAttributeNS( null, 'series1' );
var series2 = eachChart.getAttributeNS( null, 'series2' );
var chartId = CreateUniqueId( chartType + '_chart' );
var chart = new ChartObj( chartType, is3d, chartId, null, axisX, axisY, maxX, maxY, xMin, yMin, xTickStep, yTickStep, xLabelStep, yLabelStep, showTrend );
ChartCanvas.chartArray.push(chart);
var chartElNodes = eachChart.childNodes;
for ( var c = 0, cLen = chartElNodes.length; cLen > c; c++ )
{
var eachSeries = chartElNodes.item( c );
if ( 'series' == eachSeries.localName )
{
var seriesId = CreateUniqueId( 'series' );
var title = GetNodeValueByNameNS( chartNS, eachSeries, 'title' );
var desc = GetNodeValueByNameNS( chartNS, eachSeries, 'desc' );
var series = new SeriesObj( title, desc, seriesId );
chart.series.push( series );
var label = new LabelObj( seriesId + '_label', title, desc );
chart.axis.x.items.push( label );
if ( ChartCanvas.titleMax.length < title.length )
{
ChartCanvas.titleMax = title;
}
var seriesElNodes = eachSeries.childNodes;
for ( var s = 0, sLen = seriesElNodes.length; sLen > s; s++ )
{
var eachSequence = seriesElNodes.item( s );
if ( 'sequence' == eachSequence.localName )
{
var sequenceId = CreateUniqueId( 'sequence' );
var title = GetNodeValueByNameNS( chartNS, eachSequence, 'title' );
var desc = GetNodeValueByNameNS( chartNS, eachSequence, 'desc' );
var sequence = new SequenceObj( title, desc, sequenceId );
series.sequences.push( sequence );
var sequenceValue = 0;
var sequenceElNodes = eachSequence.childNodes;
for ( var q = 0, qLen = sequenceElNodes.length; qLen > q; q++ )
{
var eachData = sequenceElNodes.item( q );
if ( 'data' == eachData.localName )
{
var datapointId = CreateUniqueId( 'datapoint' );
var title = '';
var desc = '';
var value = 0;
var valueType = null;
var dataElNodes = eachData.childNodes;
for ( var d = 0, dLen = dataElNodes.length; dLen > d; d++ )
{
var eachNode = dataElNodes.item( d );
if ( eachNode && eachNode.firstChild)
{
switch ( eachNode.localName )
{
case 'title':
title = eachNode.firstChild.nodeValue;
break;
case 'desc':
desc = eachNode.firstChild.nodeValue;
break;
case 'value':
value = eachNode.firstChild.nodeValue;
value = value.replace(',','');
valueType = eachNode.getAttributeNS( null, 'type' );
break;
}
}
}
sequenceValue += Number(value);
var color = '';
var category = "";
if ( !series1 || series1 == "") {
category = axisX;
} else {
category = series1 + series2;
}
color = RegisterLegend( title, desc, category );
var datapoint = new DatapointObj( value, title, desc, valueType, datapointId, color );
sequence.data.push( datapoint );
chart.valueCount++;
}
if ( chart.max.y < sequenceValue )
{
chart.max.y = sequenceValue;
}
}
chart.totalValue += sequenceValue;
}
}
}
}
}
}
success = true;
}
else
{
alert('Could not load data. Error in data transmission.');
return;
}
DataBuffer.removeChild( dataElement );
if ( callback )
{
callback( success );
}
}
else
{
}
}
else
{
alert('Could not load data. Error in data transmission.');
}
try
{
}
catch(er)
{
alert('Error in ProcessData:\n' + er.message)
if ( callback )
{
callback( false, er.message );
}
}
SVGDebug( 'exiting ProcessData', 1 );
};
function RegisterLegend( title, desc, category )
{
SVGDebug( 'entering RegisterLegend', 1 );
var color = '';
if ( !ChartCanvas.colorMatchArray[title] )
{
ChartCanvas.colorMatchArray[title] = [];
color = SetLegendColor( title, desc, category );
}
else
{
if ( ChartCanvas.colorMatchArray[title][desc] )
{
color = ChartCanvas.colorMatchArray[title][desc];
}
else
{
color = SetLegendColor( title, desc, category );
}
}
return color;
SVGDebug( 'exiting RegisterLegend', 1 );
};
function SetLegendColor( title, desc, category )
{
SVGDebug( 'entering SetLegendColor', 1 );
var color = null;
if ( top.GetColor )
{
// coordinate color values with other charts
var legendStr = title + ' ' + desc;
color = top.GetColor( legendStr, category );
} else {
SVGDebug( ' not using top.getColor');
}
ChartCanvas.colorMatchArray[title][desc] = color;
ChartCanvas.legend.itemCount++;
return color;
SVGDebug( 'exiting SetLegendColor', 1 );
};
function ReportStatus()
{
SVGDebug( 'entering ReportStatus', 1 );
SVGDebug( 'exiting ReportStatus', 1 );
};
function GetNodeValueByNameNS( ns, parentEl, name )
{
SVGDebug( 'entering GetNodeValueByNameNS', 1 );
var value = '';
for ( var c = 0, cLen = parentEl.childNodes.length; cLen > c; c++ )
{
var eachNode = parentEl.childNodes.item( c );
if ( eachNode && name == eachNode.localName )
{
value = eachNode.firstChild.nodeValue;
}
}
if ( !value )
{
}
SVGDebug( 'exiting GetNodeValueByNameNS', 1 );
return value;
};
/**************************
*
* Annotation Functions
*
***************************/
function AnnotationObj( id, color, value, title, desc, type, element, xLabel, yLabel, angle )
{
SVGDebug( 'entering DatapointObj', 1 );
this.id = id; // the unique id of this datapoint
this.value = value; // the value by which this datapoint is evaluated
this.title = title; // the title of this datapoint
this.desc = desc; // the description of this datapoint
this.type = type; // the type of this datapoint, such as numeric or a match-category
this.color = color; // the color assigned/associated with this datapoint (may link to legend)
this.fill = color; // the paint (gradient) assigned/associated with this datapoint
this.element = element; // the element that represents this datapoint
this.xLabel = xLabel; // the x-axis label element associated with this datapoint
this.yLabel = yLabel; // the y-axis label element associated with this datapoint
this.angle = angle; // the angle of the centerline for a pie slice for this datapoint
this.element = null; // the element that represents this datapoint
this.x = 0;
this.y = 0;
SVGDebug( 'exiting DatapointObj', 1 );
};
var annoShape = null;
var annoType = null;
var annoStart = null;
var colorPicker = null;
var colorPickerType = null;
var annoColor = 'red';
function InitAnnotation()
{
SVGDebug( 'entering InitAnnotation', 1 );
AnnotationArea = SVGDocument.getElementById('annotationArea');
Backdrop = SVGDocument.getElementById('backdrop');
ToolPanel = SVGDocument.getElementById('ToolPanel');
colorPicker = SVGDocument.getElementById('colorPicker');
annoStart = new PointObj( 0, 0 );
SVGDebug( 'exiting InitAnnotation', 1 );
};
function ShowToolPanel()
{
SVGDebug( 'entering ShowToolPanel', 1 );
ToolPanel.setAttributeNS(null, 'display', 'inline' );
Backdrop.addEventListener('mouseover', HideToolPanel, false);
SVGDebug( 'exiting ShowToolPanel', 1 );
};
function HideToolPanel()
{
SVGDebug( 'entering HideToolPanel', 1 );
ToolPanel.setAttributeNS(null, 'display', 'none' );
Backdrop.removeEventListener('mouseover', HideToolPanel, false);
SVGDebug( 'exiting HideToolPanel', 1 );
};
function AdjustColorPicker( yPos, type )
{
SVGDebug( 'entering HideToolPanel', 1 );
colorPicker.setAttributeNS(null, 'transform', 'translate(0,' + yPos + ')');
colorPickerType = type;
SVGDebug( 'exiting HideToolPanel', 1 );
};
function PickAnnoColor( evt )
{
//SVGDebug( 'entering HideToolPanel', 1 );
//return object with focus, as object
var targetObject = evt.target;
if ( 'cpbg' != targetObject.getAttributeNS(null, 'id') )
{
annoColor = targetObject.getAttributeNS(null, 'fill');
ToolPanel.setAttributeNS(null, 'fill', annoColor );
ToolPanel.setAttributeNS(null, 'stroke', annoColor );
ToolPanel.setAttributeNS(null, 'marker-end', 'url(#arrow-' + annoColor + ')' );
SVGRoot.removeEventListener('mousedown', StartAnno, false);
setTimeout( 'ActivateAnnotations("' + colorPickerType + '")', 100);
}
//SVGDebug( 'exiting HideToolPanel', 1 );
};
function ActivateAnnotations( type )
{
//SVGDebug( 'entering StartAnno', 1 );
//alert("entering StartAnno\n" + type )
annoType = type;
ChartRoot.addEventListener('mousedown', StartAnno, false);
//SVGDebug( 'exiting StartAnno', 1 );
};
function StartAnno(evt)
{
//alert( 'entering StartAnno' );
//SVGDebug( 'entering StartAnno', 1 );
//return object with focus, as object
var targetElement = evt.target;
GetTrueCoords( evt );
switch ( annoType )
{
case 'line':
StartLine();
break;
case 'circle':
annoStart.x = TrueCoords.x;
annoStart.y = TrueCoords.y;
StartEllipse();
break;
case 'text':
StartText();
break;
case 'delete':
DeleteAnno( targetElement );
break;
}
ChartRoot.removeEventListener('mousedown', StartAnno, false);
ChartRoot.addEventListener('mousemove', DrawAnnoShape, false);
ChartRoot.addEventListener('mouseup', StopAnno, false);
//SVGDebug( 'exiting StartAnno', 1 );
};
function DeleteAnno( targetElement )
{
SVGDebug( 'entering DeleteAnno', 1 );
var targetParent = targetElement.parentNode;
while( targetParent )
{
if ( AnnotationArea == targetParent )
{
AnnotationArea.removeChild( targetElement );
return;
}
targetParent = targetParent.parentNode;
}
SVGDebug( 'exiting DeleteAnno', 1 );
};
function StartLine()
{
SVGDebug( 'entering StartAnno', 1 );
annoShape = SVGDocument.createElementNS(svgns, 'line');
annoShape.setAttributeNS(null, 'x1', TrueCoords.x );
annoShape.setAttributeNS(null, 'y1', TrueCoords.y );
annoShape.setAttributeNS(null, 'x2', TrueCoords.x );
annoShape.setAttributeNS(null, 'y2', TrueCoords.y );
annoShape.setAttributeNS(null, 'stroke', annoColor );
annoShape.setAttributeNS(null, 'stroke-width', 3 );
annoShape.setAttributeNS(null, 'stroke-linecap', 'round');
annoShape.setAttributeNS(null, 'marker-end', 'url(#arrow-' + annoColor + ')' );
//annoShape.setAttributeNS(null, 'pointer-events', 'none');
AnnotationArea.appendChild( annoShape );
SVGDebug( 'exiting StartAnno', 1 );
};
function StartEllipse()
{
SVGDebug( 'entering StartAnno', 1 );
annoShape = SVGDocument.createElementNS(svgns, 'ellipse');
annoShape.setAttributeNS(null, 'cx', TrueCoords.x );
annoShape.setAttributeNS(null, 'cy', TrueCoords.y );
annoShape.setAttributeNS(null, 'rx', 0 );
annoShape.setAttributeNS(null, 'rx', 0 );
annoShape.setAttributeNS(null, 'fill', 'none' );
annoShape.setAttributeNS(null, 'stroke', annoColor );
annoShape.setAttributeNS(null, 'stroke-width', 2 );
//annoShape.setAttributeNS(null, 'pointer-events', 'none');
AnnotationArea.appendChild( annoShape );
SVGDebug( 'exiting StartAnno', 1 );
};
function StartText()
{
SVGDebug( 'entering StartText', 1 );
var x = TrueCoords.x;
var y = TrueCoords.y;
var labelValue = top.GetTextInput( 'text label' );
if ( labelValue && '' != labelValue )
{
annoShape = SVGDocument.createElementNS(svgns, 'text');
annoShape.setAttributeNS(null, 'x', x );
annoShape.setAttributeNS(null, 'y', y );
annoShape.setAttributeNS(null, 'font-size', 17);
annoShape.setAttributeNS(null, 'font-weight', 'bold');
//annoShape.setAttributeNS(null, 'text-anchor', 'middle');
annoShape.setAttributeNS(null, 'fill', annoColor );
//annoShape.setAttributeNS(null, 'stroke', 'black' );
//annoShape.setAttributeNS(null, 'stroke-width', 0.5 );
//annoShape.setAttributeNS(null, 'pointer-events', 'none');
annoShape.appendChild( SVGDocument.createTextNode( labelValue ) );
AnnotationArea.appendChild( annoShape );
}
//StopAnno();
SVGDebug( 'exiting StartText', 1 );
};
function DrawAnnoShape(evt)
{
SVGDebug( 'entering StartAnno', 1 );
GetTrueCoords( evt );
switch ( annoType )
{
case 'line':
UpdateLine();
break;
case 'circle':
UpdateEllipse();
break;
case 'text':
//StartText();
break;
}
SVGDebug( 'exiting StartAnno', 1 );
};
function UpdateLine()
{
annoShape.setAttributeNS(null, 'x2', TrueCoords.x );
annoShape.setAttributeNS(null, 'y2', TrueCoords.y );
};
function UpdateEllipse()
{
var radiusX = (TrueCoords.x - annoStart.x) / 2;
var radiusY = (TrueCoords.y - annoStart.y) / 2;
var centerX = annoStart.x + radiusX
var centerY = annoStart.y + radiusY
annoShape.setAttributeNS(null, 'cx', centerX);
annoShape.setAttributeNS(null, 'cy', centerY);
annoShape.setAttributeNS(null, 'rx', Math.abs(radiusX));
annoShape.setAttributeNS(null, 'ry', Math.abs(radiusY));
window.status = 'centerX: ' + centerX + '\ncenterY: ' + centerY + '\nrx: ' + Math.abs(radiusX) + '\nry: ' + Math.abs(radiusY);
};
function StopAnno()
{
SVGDebug( 'entering StartAnno', 1 );
annoShape = null;
ChartRoot.removeEventListener('mousemove', DrawAnnoShape, false);
ChartRoot.removeEventListener('mouseout', StopAnno, false);
SVGDebug( 'exiting StartAnno', 1 );
};
/**************************
*
* Tooltip Functions
*
***************************/
function GetTrueCoords(evt)
{
SVGDebug( 'entering GetTrueCoords', 1 );
// find the current zoom level and pan setting, and adjust the reported
// mouse position accordingly
var newScale = SVGRoot.currentScale;
var translation = SVGRoot.currentTranslate;
TrueCoords.x = (evt.clientX - translation.x)/newScale;
TrueCoords.y = (evt.clientY - translation.y)/newScale;
SVGDebug( 'exiting GetTrueCoords', 1 );
};
function HideTooltip( evt )
{
SVGDebug( 'entering HideTooltip', 1 );
toolTip.setAttributeNS(null, 'visibility', 'hidden');
SVGDebug( 'exiting HideTooltip', 1 );
};
function ShowTooltip( evt )
{
SVGDebug( 'entering ShowTooltip', 1 );
//buh()
if ( ChartRoot.suspendRedraw )
{
}
GetTrueCoords( evt );
var tipScale = 1/SVGRoot.currentScale;
var textWidth = 0;
var charCount = 0;
var tspanWidth = 0;
var boxHeight = 20;
tipBox.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
tipText.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
var multiLine = false;
var titleValue = '';
var descValue = '';
var targetElement = evt.target.parentNode;
if ( lastElement != targetElement )
{
//alert(printNode(targetElement));
var targetTitle = targetElement.getElementsByTagName('title').item(0);
if ( targetTitle )
{
// if there is a 'title' element, use its contents for the tooltip title
titleValue = targetTitle.firstChild.nodeValue;
}
var targetDesc = targetElement.getElementsByTagName('desc').item(0);
if ( targetDesc )
{
// if there is a 'desc' element, use its contents for the tooltip desc
descValue = targetDesc.firstChild.nodeValue;
if ( '' == titleValue )
{
// if there is no 'title' element, use the contents of the 'desc' element for the tooltip title instead
titleValue = descValue;
descValue = '';
}
}
// selectively assign the tooltip title and desc the proper values,
// and hide those which don't have text values
//
var titleDisplay = 'none';
if ( '' != titleValue )
{
tipTitle.firstChild.nodeValue = titleValue;
titleDisplay = 'inline';
}
tipTitle.setAttributeNS(null, 'display', titleDisplay );
var descDisplay = 'none';
if ( '' != descValue )
{
var maxChars = 50;
if ( maxChars >= descValue.length )
{
//tipDesc.firstChild.nodeValue = descValue;
var descNode = SVGDocument.createTextNode( descValue );
tipDesc.replaceChild( descNode, tipDesc.firstChild );
}
else
{
//descValue = '';
//alert(titleValue + '\n' + descValue)
var descNode = WrapText( descValue, 350, 5, 12 );
//descNode.setAttributeNS(null, 'y', 35 );
tipDesc.replaceChild( descNode, tipDesc.firstChild );
descValue.length = maxChars;
var tempStr = descValue.split('');
tempStr.length = maxChars;
descValue = tempStr.join('');
multiLine = true;
}
descDisplay = 'inline';
}
tipDesc.setAttributeNS(null, 'display', descDisplay );
charCount = Math.max( titleValue.length, descValue.length )
}
// if there are tooltip contents to be displayed, adjust the size and position of the box
if ( '' != titleValue )
{
var xPos = TrueCoords.x + (10 * tipScale);
var yPos = TrueCoords.y + (10 * tipScale);
var fontSize = 12;
var textWidth = fontSize * (charCount/1.9);
var boxWidth = textWidth + 15;
var boxHeight = 20;
if ( multiLine )
{
var lineCount = tipDesc.getElementsByTagName( 'tspan' );
boxHeight += (lineCount.length - 1) * 14;
}
else if ( '' != descValue )
{
boxHeight = 35;
}
tipBox.setAttributeNS(null, 'width', boxWidth );
tipBox.setAttributeNS(null, 'height', boxHeight );
if ( ChartCanvas.width < (xPos + boxWidth) )
{
xPos = ChartCanvas.width - boxWidth - 2;
}
if ( ChartCanvas.height <= (yPos + (boxHeight + 5)) )
{
yPos = ChartCanvas.height - (boxHeight + 5) - 2;
}
// update position
toolTip.setAttributeNS(null, 'transform', 'translate(' + xPos + ',' + yPos + ')');
toolTip.setAttributeNS(null, 'visibility', 'visible');
//top.GetOutput( self, printNode(toolTip) );
//window.clipboardData.setData("text", printNode(toolTip));
}
if ( ChartRoot.unsuspendRedraw )
{
}
SVGDebug( 'exiting ShowTooltip', 1 );
};
/**************************
*
* UI Functions
*
***************************/
function Highlight( evt )
{
SVGDebug( 'entering Highlight', 1 );
try{
var targetObject = evt.currentTarget;
targetObject.setAttributeNS(null, 'fill-opacity', '0.6');
} catch(er) { alert('Error in Highlight: ' + er.message); }
SVGDebug( 'exiting Highlight', 1 );
};
function Lowlight( evt )
{
SVGDebug( 'entering Lowlight', 1 );
try{
var targetObject = evt.currentTarget;
targetObject.setAttributeNS(null, 'fill-opacity', '1');
} catch(er) { alert('Error in Lowlight: ' + er.message); }
SVGDebug( 'exiting Lowlight', 1 );
};
function LegendHighlight( evt )
{
SVGDebug( 'entering LegendHighlight', 1 );
var targetObject = evt.target;
if ( 'rect' != targetObject.localName )
{
targetObject = targetObject.previousSibling;
}
var color = targetObject.getAttributeNS(null, 'fill');
if ( ChartRoot.suspendRedraw )
{
}
for ( var eachColor in ChartCanvas.legend.items )
{
var eachSetArray = ChartCanvas.legend.items[ eachColor ];
//alert(' color: ' + color + ' = ' + ColorObj.getHex(color) + '\n eachColor: ' + eachColor + ' = ' + ColorObj.getHex(eachColor) );
if ( ColorObj.getHex(color) != ColorObj.getHex(eachColor) )
{
for ( var i = 0, iLen = eachSetArray.length; iLen > i; i++ )
{
var eachItem = eachSetArray[i];
if ( eachItem )
{
eachItem.element.setAttributeNS(null, 'opacity', '0.4');
eachItem.element.setAttributeNS(null, 'fill', 'lightgray');
///alert(printNode(eachItem.parentNode ) )
}
}
}
}
if ( ChartRoot.unsuspendRedraw )
{
}
try{
} catch(er) { alert('Error in Highlight: ' + er.message); }
SVGDebug( 'exiting LegendHighlight', 1 );
};
function LegendLowlight( evt )
{
SVGDebug( 'entering LegendLowlight', 1 );
try{
if ( ChartRoot.suspendRedraw )
{
}
for ( var eachColor in ChartCanvas.legend.items )
{
var eachSetArray = ChartCanvas.legend.items[ eachColor ];
for ( var i = 0, iLen = eachSetArray.length; iLen > i; i++ )
{
var eachItem = eachSetArray[i];
if ( eachItem )
{
eachItem.element.setAttributeNS(null, 'opacity', '1');
eachItem.element.setAttributeNS(null, 'fill', eachItem.fill );
}
}
}
if ( ChartRoot.unsuspendRedraw )
{
}
} catch(er) { alert('Error in Lowlight: ' + er.message); }
SVGDebug( 'exiting LegendLowlight', 1 );
};
function LabelHighlight( evt )
{
SVGDebug( 'entering LabelHighlight', 1 );
try{
var targetObject = evt.target;
var labelBoxId = targetObject.getAttributeNS(null, 'id' );
var labelBox = SVGDocument.getElementById( labelBoxId );
var backlight = SVGDocument.getElementById( labelBoxId + '_backlight' );
if ( labelBox && backlight ){
labelBox.setAttributeNS(null, 'fill', 'lightgray' );
backlight.setAttributeNS(null, 'display', 'inline' );
}
} catch(er) { alert('Error in LabelHighlight: ' + er.message); }
SVGDebug( 'exiting LabelHighlight', 1 );
};
function LabelLowlight( evt )
{
SVGDebug( 'entering LabelLowlight', 1 );
try{
var targetObject = evt.target;
var labelBoxId = targetObject.getAttributeNS(null, 'id' );
var labelBox = SVGDocument.getElementById( labelBoxId );
var backlight = SVGDocument.getElementById( labelBoxId + '_backlight' );
if ( labelBox && backlight ){
labelBox.setAttributeNS(null, 'fill', '#ececec' );
backlight.setAttributeNS(null, 'display', 'none' );
}
} catch(er) { alert('Error in LabelLowlight: ' + er.message); }
SVGDebug( 'exiting LabelLowlight', 1 );
};
/**************************
*
* Non-ASV Helper Functions
*
***************************/
var imp = top.document.implementation;
// check whether the DOM3 Load & Save module is supported
if ( !imp.hasFeature || !imp.hasFeature('LS','3.0') )
{
if ( window.Window )
{
if ( !window.printNode )
{
Window.prototype.printNode= function ( el )
{
return (new XMLSerializer()).serializeToString( el );
};
}
if ( !window.parseXML )
{
Window.prototype.parseXML = function ( str, doc )
{
var domParser = new DOMParser();
if ( domParser )
{
var fragment = null;
if ( null == doc )
{
fragment = domParser.parseFromString( str, 'text/xml' );
}
else
{
fragment = domParser.parseFromString( str, 'text/xml' );
//alert(fragment)
//doc.importNode( fragment, true );
}
return fragment;
}
return null;
};
}
}
}
else
{
window.parseXML = function( str, doc )
{
var lsParser = imp.createLSParser( DOMImplementationLS.MODE_SYNCHRONOUS, null );
var lsInput = imp.createLSInput();
lsInput.stringData = str;
// parse the string
var resultDoc = lsParser.parse( lsInput );
// import parsed XML into current document
var resultEl = resultDoc.documentElement;
var fragment = SVGDocument.importNode( resultEl, true);
return fragment;
};
};
var debugArray = [];
var debugPriority = 4;
function SVGDebug( msg, priority )
{
if ( debugPriority <= priority )
{
debugArray.push( msg );
}
//window.clipboardData.setData("text", debugArray.toString() );
};
parent.ShowSVGDebug = ShowSVGDebug;
function ShowSVGDebug()
{
var debugStr = debugArray.join('\n');
return debugStr;
};
parent.ReportChartReady = ReportChartReady;
function ReportChartReady()
{
SVGDebug( 'entering ReportChartReady', 1 );
return true;
SVGDebug( 'exiting ReportChartReady', 1 );
};