RGraph = window.RGraph || {isRGraph:
true
};
RGraph.SVG = RGraph.SVG || {};
(
function
(win, doc, undefined)
{
var
RG = RGraph,
ua = navigator.userAgent,
ma = Math,
win = window,
doc = document;
RG.SVG.Bipolar =
function
(conf)
{
this
.set =
function
(name, value)
{
if
(arguments.length === 1 &&
typeof
name === 'object
') {
for (i in arguments[0]) {
if (typeof i === '
string
') {
var ret = RG.SVG.commonSetter({
object: this,
name: i,
value: arguments[0][i]
});
name = ret.name;
value = ret.value;
this.set(name, value);
}
}
} else {
var ret = RG.SVG.commonSetter({
object: this,
name: name,
value: value
});
name = ret.name;
value = ret.value;
this.properties[name] = value;
// If setting the colors, update the originalColors
// property too
if (name === '
colors
') {
this.originalColors = RG.SVG.arrayClone(value);
this.colorsParsed = false;
}
}
return this;
};
this.id = conf.id;
this.uid = RG.SVG.createUID();
this.container = document.getElementById(this.id);
this.layers = {}; // MUST be before the SVG tag is created!
this.svg = RG.SVG.createSVG({object: this,container: this.container});
this.isRGraph = true;
this.data = [conf.left, conf.right];
this.left = conf.left;
this.right = conf.right;
this.type = '
bipolar
';
this.coords = [];
this.coordsLeft = [];
this.coordsRight = [];
this.coords2 = [];
this.coords2Left = [];
this.coords2Right = [];
this.stackedBackfacesLeft = [];
this.stackedBackfacesRight = [];
this.originalColors = {};
this.gradientCounter = 1;
this.sequentialIndex = 0; // Used for tooltips
// Add this object to the ObjectRegistry
RG.SVG.OR.add(this);
this.container.style.display = '
inline-block
';
this.properties =
{
gutterLeft: 35,
gutterRight: 35,
gutterTop: 35,
gutterBottom: 35,
gutterCenter: null,
backgroundColor: null,
backgroundGrid: true,
backgroundGridColor: '
#ddd',
backgroundGridLinewidth: 1,
backgroundGridHlines:
true
,
backgroundGridHlinesCount:
null
,
backgroundGridVlines:
true
,
backgroundGridVlinesCount:
null
,
backgroundGridBorder:
true
,
backgroundGridDashed:
false
,
backgroundGridDotted:
false
,
backgroundGridDashArray:
null
,
xaxis:
true
,
xaxisLinewidth: 1,
xaxisTickmarks:
true
,
xaxisTickmarksLength: 5,
xaxisLabelsCount: 5,
xaxisLabelsPositionEdgeTickmarksCount: 5,
xaxisColor: 'black
',
xaxisLabelsOffsetx: 0,
xaxisLabelsOffsety: 0,
xaxisUnitsPre: '
',
xaxisUnitsPost: '
',
xaxisStrict: false,
xaxisDecimals: 0,
xaxisPoint: '
.
',
xaxisThousand: '
,
',
xaxisRound: false,
xaxisMax: null,
xaxisMin: 0,
xaxisFormatter: null,
xaxisTextFont: null,
xaxisTextSize: null,
xaxisTextBold: null,
xaxisTextItalic: null,
xaxisTextColor: null,
yaxis: true,
yaxisTickmarks: true,
yaxisTickmarksLength: 5,
yaxisColor: '
black
',
yaxisScale: false,
yaxisLabels: null,
yaxisLabelsOffsetx: 0,
yaxisLabelsOffsety: 0,
yaxisTextFont: null,
yaxisTextSize: null,
yaxisTextBold: null,
yaxisTextItalic: null,
yaxisTextColor: null,
// 20 colors. If you need more you need to set the colors property
colors: [
'
red
', '
#0f0', '#00f', '#ff0', '#0ff', '#0f0','pink','orange','gray','black',
'red
', '
#0f0', '#00f', '#ff0', '#0ff', '#0f0','pink','orange','gray','black'
],
colorsSequential:
false
,
strokestyle: 'rgba(0,0,0,0)
',
vmargin: 3,
vmarginGrouped: 2,
labelsAbove: false,
labelsAboveFont: null,
labelsAboveSize: null,
labelsAboveBold: null,
labelsAboveItalic: null,
labelsAboveColor: null,
labelsAboveBackground: null,
labelsAboveBackgroundPadding: 0,
labelsAboveUnitsPre: null,
labelsAboveUnitsPost: null,
labelsAbovePoint: null,
labelsAboveThousand: null,
labelsAboveFormatter: null,
labelsAboveDecimals: null,
labelsAboveOffsetx: 0,
labelsAboveOffsety: 0,
labelsAboveSpecific: null,
textColor: '
black
',
textFont: '
sans-serif
',
textSize: 12,
textBold: false,
textItalic: false,
linewidth: 1,
grouping: '
grouped
',
tooltips: null,
tooltipsOverride: null,
tooltipsEffect: '
fade
',
tooltipsCssClass: '
RGraph_tooltip
',
tooltipsEvent: '
click
',
highlightStroke: '
rgba(0,0,0,0)
',
highlightFill: '
rgba(255,255,255,0.7)
',
highlightLinewidth: 1,
title: '
',
titleSize: 16,
titleX: null,
titleY: null,
titleHalign: '
center
',
titleValign: null,
titleColor: '
black
',
titleFont: null,
titleBold: false,
titleItalic: false,
titleSubtitle: null,
titleSubtitleSize: 10,
titleSubtitleX: null,
titleSubtitleY: null,
titleSubtitleHalign: '
center
',
titleSubtitleValign: null,
titleSubtitleColor: '
#aaa',
titleSubtitleFont:
null
,
titleSubtitleBold:
false
,
titleSubtitleItalic:
false
,
shadow:
false
,
shadowOffsetx: 2,
shadowOffsety: 2,
shadowBlur: 2,
shadowOpacity: 0.25,
key:
null
,
keyColors:
null
,
keyOffsetx: 0,
keyOffsety: 0,
keyTextOffsetx: 0,
keyTextOffsety: -1,
keyTextSize:
null
,
keyTextBold:
null
,
keyTextItalic:
null
,
keyTextFont:
null
};
RG.SVG.getGlobals(
this
);
if
(RG.SVG.FX &&
typeof
RG.SVG.FX.decorate === '
function
') {
RG.SVG.FX.decorate(this);
}
var prop = this.properties;
//
// The draw method draws the Bar chart
//
this.draw = function ()
{
// Fire the beforedraw event
RG.SVG.fireCustomEvent(this, '
onbeforedraw
');
// Should the first thing that'
s done inthe.draw()
function
this
.width = Number(
this
.svg.getAttribute(
'width'
));
this
.height = Number(
this
.svg.getAttribute(
'height'
));
RG.SVG.createDefs(
this
);
if
(
typeof
prop.gutterCenter !==
'number'
) {
prop.gutterCenter =
this
.getGutterCenter();
}
this
.coords = [];
this
.coordsLeft = [];
this
.coordsRight = [];
this
.coords2 = [];
this
.coords2Left = [];
this
.coords2Right = [];
this
.graphWidth = (
this
.width - prop.gutterLeft - prop.gutterRight - prop.gutterCenter) / 2;
this
.graphHeight =
this
.height - prop.gutterTop - prop.gutterBottom;
RG.SVG.resetColorsToOriginalValues({object:
this
});
this
.parseColors();
var
values = [];
for
(
var
i=0; i<2; ++i) {
for
(
var
j=0,max=0; j<
this
.data[i].length; ++j) {
if
(
typeof
this
.data[i][j] ===
'number'
) {
values.push(
this
.data[i][j]);
}
else
if
(RG.SVG.isArray(
this
.data[i][j]) && prop.grouping ===
'grouped'
) {
values.push(RG.SVG.arrayMax(
this
.data[i][j]));
}
else
if
(RG.SVG.isArray(
this
.data[i][j]) && prop.grouping ===
'stacked'
) {
values.push(RG.SVG.arraySum(
this
.data[i][j]));
}
}
}
var
max = RG.SVG.arrayMax(values);
if
(
typeof
prop.xaxisMax ===
'number'
) {
max = prop.xaxisMax;
}
this
.scale = RG.SVG.getScale({
object:
this
,
numlabels: prop.xaxisLabelsCount,
unitsPre: prop.xaxisUnitsPre,
unitsPost: prop.xaxisUnitsPost,
max: max,
min: prop.xaxisMin,
point: prop.xaxisPoint,
round: prop.xaxisRound,
thousand: prop.xaxisThousand,
decimals: prop.xaxisDecimals,
strict:
typeof
prop.xaxisMax ===
'number'
,
formatter: prop.xaxisFormatter
});
this
.max =
this
.scale.max;
this
.min =
this
.scale.min;
prop.yaxisMax =
this
.scale.max;
prop.yaxisMin =
this
.scale.min;
this
.drawBackground(
this
);
this
.drawTitle();
this
.drawBars();
this
.drawAxes();
this
.drawLabels()
this
.drawLabelsAbove();
if
(
typeof
prop.key !==
null
&& RG.SVG.drawKey) {
RG.SVG.drawKey(
this
);
}
else
if
(!RG.SVG.isNull(prop.key)) {
alert(
'The drawKey() function does not exist - have you forgotten to include the key library?'
);
}
RG.SVG.fireCustomEvent(
this
,
'ondraw'
);
return
this
;
};
this
.drawBackground =
function
()
{
var
originalGutterRight = prop.gutterRight,
originalGutterLeft = prop.gutterLeft;
prop.gutterRight =
this
.width - (prop.gutterLeft +
this
.graphWidth);
if
(RG.SVG.isNull(prop.backgroundGridHlinesCount)) {
var
resetToNull =
true
;
prop.backgroundGridHlinesCount =
this
.left.length;
}
var
properties = [
''
,
'Aspect'
,
'Opacity'
,
'Stretch'
,
'X'
,
'Y'
,
'W'
,
'H'
,];
for
(i
in
properties ) {
if
(
typeof
properties[i] ===
'string'
) {
prop[
'backgroundImage'
+ properties[i]] = prop[
'backgroundImageLeft'
+ properties[i]];
}
}
RG.SVG.drawBackground(
this
);
if
(resetToNull) {
prop.backgroundGridHlinesCount =
null
;
}
prop.gutterRight = originalGutterRight;
prop.gutterLeft =
this
.width - (prop.gutterRight +
this
.graphWidth);
if
(RG.SVG.isNull(prop.backgroundGridHlinesCount)) {
prop.backgroundGridHlinesCount =
this
.right.length;
}
var
properties = [
''
,
'Aspect'
,
'Opacity'
,
'Stretch'
,
'X'
,
'Y'
,
'W'
,
'H'
,];
for
(i
in
properties ) {
if
(
typeof
properties[i] ===
'string'
) {
prop[
'backgroundImage'
+ properties[i]] = prop[
'backgroundImageRight'
+ properties[i]];
}
}
RG.SVG.drawBackground(
this
);
prop.gutterLeft = originalGutterLeft;
prop.gutterRight = originalGutterRight;
};
this
.drawAxes =
function
()
{
if
(prop.xaxis) {
RG.SVG.create({
svg:
this
.svg,
type:
'path'
,
parent:
this
.svg.all,
attr: {
d:
'M {1} {2} L {3} {4}'
.format(
prop.gutterLeft,
this
.height - prop.gutterBottom,
prop.gutterLeft +
this
.graphWidth,
this
.height - prop.gutterBottom
),
'stroke-width'
: prop.xaxisLinewidth,
stroke: prop.xaxisColor,
fill:
'rgba(0,0,0,0)'
,
'shape-rendering'
:
'crispEdges'
}
});
RG.SVG.create({
svg:
this
.svg,
type:
'path'
,
parent:
this
.svg.all,
attr: {
d:
'M {1} {2} L {3} {4}'
.format(
this
.width - prop.gutterRight,
this
.height - prop.gutterBottom,
this
.width - prop.gutterRight -
this
.graphWidth,
this
.height - prop.gutterBottom
),
'stroke-width'
: prop.xaxisLinewidth,
stroke: prop.xaxisColor,
fill:
'rgba(0,0,0,0)'
,
'shape-rendering'
:
'crispEdges'
}
});
if
(prop.xaxisTickmarks) {
var
startY =
this
.height - prop.gutterBottom,
endY =
this
.height - prop.gutterBottom + prop.xaxisTickmarksLength;
for
(
var
i=0; i<prop.xaxisLabelsPositionEdgeTickmarksCount; ++i) {
var
x = prop.gutterLeft + (i * (
this
.graphWidth / prop.xaxisLabelsPositionEdgeTickmarksCount));
RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'path'
,
attr: {
d:
'M{1} {2} L{3} {4}'
.format(
x + 0.001,
startY,
x,
endY
),
stroke: prop.xaxisColor,
'stroke-width'
: prop.xaxisLinewidth,
'shape-rendering'
:
"crispEdges"
}
});
}
if
(!prop.yaxis) {
var
x = prop.gutterLeft +
this
.graphWidth;
RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'path'
,
attr: {
d:
'M{1} {2} L{3} {4}'
.format(
x + 0.001,
startY,
x,
endY
),
stroke: prop.xaxisColor,
'stroke-width'
: prop.xaxisLinewidth,
'shape-rendering'
:
"crispEdges"
}
});
}
for
(
var
i=0; i<prop.xaxisLabelsPositionEdgeTickmarksCount; ++i) {
var
x = prop.gutterLeft + prop.gutterCenter +
this
.graphWidth + ((i+1) * (
this
.graphWidth / prop.xaxisLabelsPositionEdgeTickmarksCount));
RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'path'
,
attr: {
d:
'M{1} {2} L{3} {4}'
.format(
x + 0.001,
startY,
x,
endY
),
stroke: prop.xaxisColor,
'stroke-width'
: prop.xaxisLinewidth,
'shape-rendering'
:
"crispEdges"
}
});
}
if
(!prop.yaxis) {
var
x = prop.gutterLeft +
this
.graphWidth + prop.gutterCenter;
RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'path'
,
attr: {
d:
'M{1} {2} L{3} {4}'
.format(
x + 0.001,
startY,
x,
endY
),
stroke: prop.xaxisColor,
'stroke-width'
: prop.xaxisLinewidth,
'shape-rendering'
:
"crispEdges"
}
});
}
}
}
if
(prop.yaxis) {
RG.SVG.create({
svg:
this
.svg,
type:
'path'
,
parent:
this
.svg.all,
attr: {
d:
'M {1} {2} L {3} {4}'
.format(
prop.gutterLeft +
this
.graphWidth,
this
.height - prop.gutterBottom,
prop.gutterLeft +
this
.graphWidth,
prop.gutterTop
),
'stroke-width'
: prop.yaxisLinewidth,
stroke: prop.yaxisColor,
fill:
'rgba(0,0,0,0)'
,
'shape-rendering'
:
'crispEdges'
,
'stroke-linecap'
:
'square'
}
});
RG.SVG.create({
svg:
this
.svg,
type:
'path'
,
parent:
this
.svg.all,
attr: {
d:
'M {1} {2} L {3} {4}'
.format(
prop.gutterLeft +
this
.graphWidth + prop.gutterCenter,
this
.height - prop.gutterBottom,
prop.gutterLeft +
this
.graphWidth + prop.gutterCenter,
prop.gutterTop
),
'stroke-width'
: prop.yaxisLinewidth,
stroke: prop.yaxisColor,
fill:
'rgba(0,0,0,0)'
,
'shape-rendering'
:
'crispEdges'
,
'stroke-linecap'
:
'square'
}
});
if
(prop.yaxisTickmarks) {
var
startX = prop.gutterLeft +
this
.graphWidth,
endX = prop.gutterLeft +
this
.graphWidth + prop.yaxisTickmarksLength,
numticks =
this
.left.length;
for
(
var
i=0; i<numticks; ++i) {
var
y = prop.gutterTop + (i * (
this
.graphHeight / numticks));
RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'path'
,
attr: {
d:
'M{1} {2} L{3} {4}'
.format(
startX + 0.001,
y,
endX,
y
),
stroke: prop.yaxisColor,
'stroke-width'
: prop.yaxisLinewidth,
'shape-rendering'
:
"crispEdges"
}
});
}
if
(!prop.xaxis) {
var
y = prop.gutterTop +
this
.graphHeight;
RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'path'
,
attr: {
d:
'M{1} {2} L{3} {4}'
.format(
startX + 0.001,
y,
endX,
y
),
stroke: prop.yaxisColor,
'stroke-width'
: prop.yaxisLinewidth,
'shape-rendering'
:
"crispEdges"
}
});
}
var
startX = prop.gutterLeft +
this
.graphWidth + prop.gutterCenter,
endX = prop.gutterLeft +
this
.graphWidth + prop.gutterCenter - prop.yaxisTickmarksLength,
numticks =
this
.right.length;
for
(
var
i=0; i<numticks; ++i) {
var
y = prop.gutterTop + (i * (
this
.graphHeight / numticks));
RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'path'
,
attr: {
d:
'M{1} {2} L{3} {4}'
.format(
startX + 0.001,
y,
endX,
y
),
stroke: prop.yaxisColor,
'stroke-width'
: prop.yaxisLinewidth,
'shape-rendering'
:
"crispEdges"
}
});
}
if
(!prop.xaxis) {
var
y = prop.gutterTop +
this
.graphHeight;
RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'path'
,
attr: {
d:
'M{1} {2} L{3} {4}'
.format(
startX + 0.001,
y,
endX,
y
),
stroke: prop.yaxisColor,
'stroke-width'
: prop.yaxisLinewidth,
'shape-rendering'
:
"crispEdges"
}
});
}
}
}
};
this
.drawLabels =
function
()
{
var
numlabels = prop.yaxisLabels ? prop.yaxisLabels.length : 5
for
(
var
i=0; i<numlabels; ++i) {
var
segment =
this
.graphHeight / numlabels,
y = prop.gutterTop + (segment * i) + (segment / 2) + prop.yaxisLabelsOffsety,
x = prop.gutterLeft +
this
.graphWidth + (prop.gutterCenter / 2) + prop.yaxisLabelsOffsetx;
var
text = RG.SVG.text({
object:
this
,
parent:
this
.svg.all,
text: prop.yaxisLabels && prop.yaxisLabels[i] ? prop.yaxisLabels[i] :
''
,
x: x,
y: y,
halign:
'center'
,
valign:
'center'
,
tag:
'labels.yaxis'
,
font: prop.yaxisTextFont || prop.textFont,
size: prop.yaxisTextSize || (
typeof
prop.textSize ===
'number'
? prop.textSize +
'pt'
: prop.textSize),
bold: !RG.SVG.isNull(prop.yaxisTextBold) ? prop.yaxisTextBold : prop.textBold,
italic: !RG.SVG.isNull(prop.yaxisTextItalic) ? prop.yaxisTextItalic : prop.textItalic,
color: prop.yaxisTextColor || prop.textColor
});
}
var
segment =
this
.graphWidth / prop.xaxisLabelsCount;
for
(
var
i=0; i<
this
.scale.labels.length; ++i) {
RG.SVG.text({
object:
this
,
parent:
this
.svg.all,
text:
this
.scale.labels[i],
x: prop.gutterLeft +
this
.graphWidth - (segment * (i+1)) + prop.xaxisLabelsOffsetx,
y:
this
.height - prop.gutterBottom + 10 + prop.xaxisLabelsOffsety,
halign:
'center'
,
valign:
'top'
,
tag:
'labels.xaxis'
,
font: prop.xaxisTextFont || prop.textFont,
size: prop.xaxisTextSize || (
typeof
prop.textSize ===
'number'
? prop.textSize +
'pt'
: prop.textSize),
bold:
typeof
prop.xaxisTextBold ===
'boolean'
? prop.xaxisTextBold : prop.textBold,
italic:
typeof
prop.xaxisTextItalic ===
'boolean'
? prop.xaxisTextItalic : prop.textItalic,
color: prop.xaxisTextColor || prop.textColor
});
}
var
y =
this
.height - prop.gutterBottom + 10,
str = (prop.xaxisUnitsPre + prop.xaxisMin.toFixed(prop.xaxisDecimals).replace(/\./, prop.xaxisPoint) + prop.xaxisUnitsPost);
var
text = RG.SVG.text({
object:
this
,
parent:
this
.svg.all,
text: str,
x: prop.gutterLeft +
this
.graphWidth + prop.xaxisLabelsOffsetx,
y: y + prop.xaxisLabelsOffsety,
halign:
'center'
,
valign:
'top'
,
tag:
'labels.xaxis'
,
font: prop.xaxisTextFont || prop.textFont,
size: prop.xaxisTextSize || (
typeof
prop.textSize ===
'number'
? prop.textSize +
'pt'
: prop.textSize),
bold:
typeof
prop.xaxisTextBold ===
'boolean'
? prop.xaxisTextBold : prop.textBold,
italic:
typeof
prop.xaxisTextItalic ===
'boolean'
? prop.xaxisTextItalic : prop.textItalic,
color: prop.xaxisTextColor || prop.textColor
});
for
(
var
i=0; i<
this
.scale.labels.length; ++i) {
RG.SVG.text({
object:
this
,
parent:
this
.svg.all,
text:
this
.scale.labels[i],
x: prop.gutterLeft +
this
.graphWidth + prop.gutterCenter + (segment * (i + 1)) + prop.xaxisLabelsOffsetx,
y:
this
.height - prop.gutterBottom + 10 + prop.xaxisLabelsOffsety,
halign:
'center'
,
valign:
'top'
,
tag:
'labels.xaxis'
,
font: prop.xaxisTextFont || prop.textFont,
size: prop.xaxisTextSize || (
typeof
prop.textSize ===
'number'
? prop.textSize +
'pt'
: prop.textSize),
bold:
typeof
prop.xaxisTextBold ===
'boolean'
? prop.xaxisTextBold : prop.textBold,
italic:
typeof
prop.xaxisTextItalic ===
'boolean'
? prop.xaxisTextItalic : prop.textItalic,
color: prop.xaxisTextColor || prop.textColor
});
}
var
text = RG.SVG.text({
object:
this
,
parent:
this
.svg.all,
text: prop.xaxisUnitsPre + prop.xaxisMin.toFixed(prop.xaxisDecimals).replace(/\./, prop.xaxisPoint) + prop.xaxisUnitsPost,
x: prop.gutterLeft +
this
.graphWidth + prop.gutterCenter + prop.xaxisLabelsOffsetx,
y:
this
.height - prop.gutterBottom + 10 + prop.xaxisLabelsOffsety,
halign:
'center'
,
valign:
'top'
,
tag:
'labels.xaxis'
,
font: prop.xaxisTextFont || prop.textFont,
size: prop.xaxisTextSize || (
typeof
prop.textSize ===
'number'
? prop.textSize +
'pt'
: prop.textSize),
bold:
typeof
prop.xaxisTextBold ===
'boolean'
? prop.xaxisTextBold : prop.textBold,
italic:
typeof
prop.xaxisTextItalic ===
'boolean'
? prop.xaxisTextItalic : prop.textItalic,
color: prop.xaxisTextColor || prop.textColor
});
};
this
.drawBars =
function
()
{
if
(prop.shadow) {
RG.SVG.setShadow({
object:
this
,
offsetx: prop.shadowOffsetx,
offsety: prop.shadowOffsety,
blur: prop.shadowBlur,
opacity: prop.shadowOpacity,
id:
'dropShadow'
});
}
for
(
var
i=0; i<
this
.left.length; ++i) {
if
(
typeof
this
.left[i] ===
'number'
) {
var
color = prop.colors[
this
.sequentialIndex],
tooltip = RG.SVG.isNull(prop.tooltips) ?
null
: prop.tooltips[
this
.sequentialIndex],
y = prop.gutterTop + ((
this
.graphHeight /
this
.left.length) * i) + prop.vmargin,
width =
this
.getWidth(
this
.left[i]),
x = prop.gutterLeft +
this
.graphWidth - width,
height = (
this
.graphHeight /
this
.left.length) - prop.vmargin - prop.vmargin;
var
rect = RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'rect'
,
attr: {
x: x,
y: y,
width: width,
height: height,
fill: prop.colorsSequential ? prop.colors[
this
.sequentialIndex] : prop.colors[0],
stroke: prop.strokestyle,
'stroke-width'
: prop.linewidth,
'shape-rendering'
:
'crispEdges'
,
'data-original-x'
: x,
'data-original-y'
: y,
'data-original-width'
: width,
'data-original-height'
: height,
'data-tooltop'
: (tooltip ||
''
),
'data-index'
: i,
'data-sequential-index'
:
this
.sequentialIndex,
'data-value'
:
this
.left[i],
filter: prop.shadow ?
'url(#dropShadow)'
:
''
}
});
this
.coords.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coordsLeft.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.installTooltipsEventListeners({
rect: rect,
index: i,
sequentialIndex:
this
.sequentialIndex
});
this
.sequentialIndex++;
}
else
if
(RG.SVG.isArray(
this
.left[i]) && prop.grouping ===
'stacked'
) {
var
accWidth = 0;
for
(
var
j=0; j<
this
.left[i].length; ++j) {
var
color = prop.colors[
this
.sequentialIndex],
tooltip = RG.SVG.isNull(prop.tooltips) ?
null
: prop.tooltips[
this
.sequentialIndex],
y = prop.gutterTop + ((
this
.graphHeight /
this
.left.length) * i) + prop.vmargin,
width =
this
.getWidth(
this
.left[i][j]),
accWidth = accWidth + width,
x = prop.gutterLeft +
this
.graphWidth - accWidth,
height = (
this
.graphHeight /
this
.left.length) - prop.vmargin - prop.vmargin;
if
(j === 0 && prop.shadow) {
var
shadowBackfaceX = prop.gutterLeft +
this
.graphWidth -
this
.getWidth(RG.SVG.arraySum(
this
.left[i])),
shadowBackfaceWidth =
this
.getWidth(RG.SVG.arraySum(
this
.left[i]));
var
rect = RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'rect'
,
attr: {
fill:
'#eee'
,
x: shadowBackfaceX,
y: y,
width: shadowBackfaceWidth,
height: height,
'stroke-width'
: 0,
'data-index'
: i,
filter:
'url(#dropShadow)'
}
});
this
.stackedBackfacesLeft[i] = rect;
}
var
rect = RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'rect'
,
attr: {
x: x,
y: y,
width: width,
height: height,
fill: prop.colorsSequential ? prop.colors[
this
.sequentialIndex] : prop.colors[j],
stroke: prop.strokestyle,
'stroke-width'
: prop.linewidth,
'shape-rendering'
:
'crispEdges'
,
'data-original-x'
: x,
'data-original-y'
: y,
'data-original-width'
: width,
'data-original-height'
: height,
'data-tooltop'
: (tooltip ||
''
),
'data-index'
: i,
'data-subindex'
: j,
'data-sequential-index'
:
this
.sequentialIndex,
'data-value'
:
this
.left[i][j]
}
});
this
.coords.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coordsLeft.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
if
(!
this
.coords2[i]) {
this
.coords2[i] = [];
}
if
(!
this
.coords2Left[i]) {
this
.coords2Left[i] = [];
}
this
.coords2[i].push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coords2Left[i].push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.installTooltipsEventListeners({
rect: rect,
index: i,
sequentialIndex:
this
.sequentialIndex
});
this
.sequentialIndex++;
}
}
else
if
(RG.SVG.isArray(
this
.left[i]) && prop.grouping ===
'grouped'
) {
for
(
var
j=0; j<
this
.left[i].length; ++j) {
var
color = prop.colors[
this
.sequentialIndex],
tooltip = RG.SVG.isNull(prop.tooltips) ?
null
: prop.tooltips[
this
.sequentialIndex],
height = ((
this
.graphHeight /
this
.left.length) - prop.vmargin - prop.vmargin - (prop.vmarginGrouped * (
this
.left[i].length - 1))) /
this
.left[i].length,
y = prop.gutterTop + ((
this
.graphHeight /
this
.left.length) * i) + prop.vmargin + (height * j) + (j * prop.vmarginGrouped),
width =
this
.getWidth(
this
.left[i][j]),
x = prop.gutterLeft +
this
.graphWidth - width;
var
rect = RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'rect'
,
attr: {
x: x,
y: y,
width: width,
height: height,
fill: prop.colorsSequential ? prop.colors[
this
.sequentialIndex] : prop.colors[j],
stroke: prop.strokestyle,
'stroke-width'
: prop.linewidth,
'shape-rendering'
:
'crispEdges'
,
'data-original-x'
: x,
'data-original-y'
: y,
'data-original-width'
: width,
'data-original-height'
: height,
'data-tooltop'
: (tooltip ||
''
),
'data-index'
: i,
'data-subindex'
: j,
'data-sequential-index'
:
this
.sequentialIndex,
'data-value'
:
this
.left[i][j],
filter: prop.shadow ?
'url(#dropShadow)'
:
''
}
});
this
.coords.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coordsLeft.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
if
(!
this
.coords2[i]) {
this
.coords2[i] = [];
}
if
(!
this
.coords2Left[i]) {
this
.coords2Left[i] = [];
}
this
.coords2[i].push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coords2Left[i].push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.installTooltipsEventListeners({
rect: rect,
index: i,
sequentialIndex:
this
.sequentialIndex
});
this
.sequentialIndex++;
}
}
}
for
(
var
i=0; i<
this
.right.length; ++i) {
if
(
typeof
this
.right[i] ===
'number'
) {
var
color = prop.colors[
this
.sequentialIndex],
tooltip = RG.SVG.isNull(prop.tooltips) ?
null
: prop.tooltips[
this
.sequentialIndex],
y = prop.gutterTop + ((
this
.graphHeight /
this
.right.length) * i) + prop.vmargin,
width =
this
.getWidth(
this
.right[i]),
x = prop.gutterLeft +
this
.graphWidth + prop.gutterCenter,
height = (
this
.graphHeight /
this
.right.length) - prop.vmargin - prop.vmargin;
var
rect = RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'rect'
,
attr: {
x: x,
y: y,
width: width,
height: height,
fill: prop.colorsSequential ? prop.colors[
this
.sequentialIndex] : prop.colors[0],
stroke: prop.strokestyle,
'stroke-width'
: prop.linewidth,
'shape-rendering'
:
'crispEdges'
,
'data-original-x'
: x,
'data-original-y'
: y,
'data-original-width'
: width,
'data-original-height'
: height,
'data-tooltop'
: (tooltip ||
''
),
'data-index'
: i,
'data-sequential-index'
:
this
.sequentialIndex,
'data-value'
:
this
.right[i],
filter: prop.shadow ?
'url(#dropShadow)'
:
''
}
});
this
.coords.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coordsRight.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.installTooltipsEventListeners({
rect: rect,
index: i,
sequentialIndex:
this
.sequentialIndex
});
this
.sequentialIndex++;
}
else
if
(RG.SVG.isArray(
this
.right[i]) && prop.grouping ===
'stacked'
) {
var
accWidth = 0;
for
(
var
j=0; j<
this
.right[i].length; ++j) {
var
color = prop.colors[
this
.sequentialIndex],
tooltip = RG.SVG.isNull(prop.tooltips) ?
null
: prop.tooltips[
this
.sequentialIndex],
y = prop.gutterTop + ((
this
.graphHeight /
this
.right.length) * i) + prop.vmargin,
width =
this
.getWidth(
this
.right[i][j]),
x = prop.gutterLeft +
this
.graphWidth + prop.gutterCenter + accWidth,
accWidth = accWidth + width,
height = (
this
.graphHeight /
this
.left.length) - prop.vmargin - prop.vmargin;
if
(j === 0 && prop.shadow) {
var
shadowBackfaceX = prop.gutterLeft +
this
.graphWidth + prop.gutterCenter,
shadowBackfaceWidth =
this
.getWidth(RG.SVG.arraySum(
this
.right[i]));
var
rect = RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'rect'
,
attr: {
fill:
'#eee'
,
x: shadowBackfaceX,
y: y,
width: shadowBackfaceWidth,
height: height,
'stroke-width'
: 0,
'data-index'
: i,
filter:
'url(#dropShadow)'
}
});
this
.stackedBackfacesRight[i] = rect;
}
var
rect = RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'rect'
,
attr: {
x: x,
y: y,
width: width,
height: height,
fill: prop.colorsSequential ? prop.colors[
this
.sequentialIndex] : prop.colors[j],
stroke: prop.strokestyle,
'stroke-width'
: prop.linewidth,
'shape-rendering'
:
'crispEdges'
,
'data-original-x'
: x,
'data-original-y'
: y,
'data-original-width'
: width,
'data-original-height'
: height,
'data-tooltop'
: (tooltip ||
''
),
'data-index'
: i,
'data-subindex'
: j,
'data-sequential-index'
:
this
.sequentialIndex,
'data-value'
:
this
.right[i][j]
}
});
this
.coords.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coordsRight.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
if
(!
this
.coords2[i +
this
.left.length]) {
this
.coords2[i +
this
.left.length] = [];
}
if
(!
this
.coords2Right[i]) {
this
.coords2Right[i] = [];
}
this
.coords2[i +
this
.left.length].push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coords2Right[i].push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.installTooltipsEventListeners({
rect: rect,
index: i,
sequentialIndex:
this
.sequentialIndex
});
this
.sequentialIndex++;
}
}
else
if
(RG.SVG.isArray(
this
.right[i]) && prop.grouping ===
'grouped'
) {
for
(
var
j=0; j<
this
.right[i].length; ++j) {
var
color = prop.colors[
this
.sequentialIndex],
tooltip = RG.SVG.isNull(prop.tooltips) ?
null
: prop.tooltips[
this
.sequentialIndex],
height = ((
this
.graphHeight /
this
.right.length) - prop.vmargin - prop.vmargin - (prop.vmarginGrouped * (
this
.right[i].length - 1))) /
this
.right[i].length,
y = prop.gutterTop + ((
this
.graphHeight /
this
.right.length) * i) + prop.vmargin + (height * j) + (j * prop.vmarginGrouped),
width =
this
.getWidth(
this
.right[i][j]),
x = prop.gutterLeft +
this
.graphWidth + prop.gutterCenter;
var
rect = RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'rect'
,
attr: {
x: x,
y: y,
width: width,
height: height,
fill: prop.colorsSequential ? prop.colors[
this
.sequentialIndex] : prop.colors[j],
stroke: prop.strokestyle,
'stroke-width'
: prop.linewidth,
'shape-rendering'
:
'crispEdges'
,
'data-original-x'
: x,
'data-original-y'
: y,
'data-original-width'
: width,
'data-original-height'
: height,
'data-tooltop'
: (tooltip ||
''
),
'data-index'
: i,
'data-subindex'
: j,
'data-sequential-index'
:
this
.sequentialIndex,
'data-value'
:
this
.right[i][j],
filter: prop.shadow ?
'url(#dropShadow)'
:
''
}
});
this
.coords.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coordsRight.push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
if
(!
this
.coords2[i +
this
.left.length]) {
this
.coords2[i +
this
.left.length] = [];
}
if
(!
this
.coords2Right[i]) {
this
.coords2Right[i] = [];
}
this
.coords2[i +
this
.left.length].push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.coords2Right[i].push({
object:
this
,
element: rect,
x: parseFloat(rect.getAttribute(
'x'
)),
y: parseFloat(rect.getAttribute(
'y'
)),
width: parseFloat(rect.getAttribute(
'width'
)),
height: parseFloat(rect.getAttribute(
'height'
))
});
this
.installTooltipsEventListeners({
rect: rect,
index: i,
sequentialIndex:
this
.sequentialIndex
});
this
.sequentialIndex++;
}
}
}
};
this
.installTooltipsEventListeners =
function
(opt)
{
var
obj =
this
;
if
(!RG.SVG.isNull(prop.tooltips) && prop.tooltips[
this
.sequentialIndex]) {
(
function
(idx, seq)
{
opt.rect.addEventListener(prop.tooltipsEvent.replace(/^on/,
''
),
function
(e)
{
obj.removeHighlight();
RG.SVG.tooltip({
object: obj,
index: idx,
group:
null
,
sequentialIndex: seq,
text: prop.tooltips[seq],
event: e
});
obj.highlight(e.target);
},
false
);
opt.rect.addEventListener(
'mousemove'
,
function
(e)
{
e.target.style.cursor =
'pointer'
},
false
);
})(opt.index, opt.sequentialIndex);
}
};
this
.getWidth =
function
(value)
{
var
x1 =
this
.getLeftXCoord(0),
x2 =
this
.getLeftXCoord(value);
if
(RG.SVG.isNull(x1) || RG.SVG.isNull(x2)) {
return
null
;
}
return
x1 - x2;
};
this
.getLeftXCoord =
function
(value)
{
var
width;
if
(value >
this
.scale.max) {
return
null
;
}
if
(value <
this
.scale.min) {
return
null
;
}
width = ((value -
this
.scale.min) / (
this
.scale.max -
this
.scale.min));
width *=
this
.graphWidth;
var
x = prop.gutterLeft +
this
.graphWidth - width;
return
x;
};
this
.getRightXCoord =
function
(value)
{
var
width;
if
(value >
this
.scale.max) {
return
null
;
}
if
(value <
this
.scale.min) {
return
null
;
}
width = ((value -
this
.scale.min) / (
this
.scale.max -
this
.scale.min));
width *=
this
.graphWidth;
var
x = prop.gutterLeft +
this
.graphWidth + prop.gutterCenter + width;
return
x;
};
this
.highlight =
function
(rect)
{
var
x = parseInt(rect.getAttribute(
'x'
)),
y = parseInt(rect.getAttribute(
'y'
)),
width = parseInt(rect.getAttribute(
'width'
)),
height = parseInt(rect.getAttribute(
'height'
));
var
highlight = RG.SVG.create({
svg:
this
.svg,
parent:
this
.svg.all,
type:
'rect'
,
attr: {
stroke: prop.highlightStroke,
fill: prop.highlightFill,
x: x - 1,
y: y - 1,
width: width + 2,
height: height + 2
},
style: {
pointerEvents:
'none'
}
});
RG.SVG.REG.set(
'highlight'
, highlight);
};
this
.parseColors =
function
()
{
if
(!Object.keys(
this
.originalColors).length) {
this
.originalColors = {
colors: RG.SVG.arrayClone(prop.colors),
backgroundGridColor: RG.SVG.arrayClone(prop.backgroundGridColor),
highlightFill: RG.SVG.arrayClone(prop.highlightFill),
backgroundColor: RG.SVG.arrayClone(prop.backgroundColor)
}
}
var
colors = prop.colors;
if
(colors) {
for
(
var
i=0; i<colors.length; ++i) {
colors[i] = RG.SVG.parseColorLinear({
object:
this
,
color: colors[i],
direction:
'horizontal'
});
}
}
prop.backgroundGridColor = RG.SVG.parseColorLinear({object:
this
, color: prop.backgroundGridColor,direction:
'horizontal'
});
prop.highlightFill = RG.SVG.parseColorLinear({object:
this
, color: prop.highlightFill,direction:
'horizontal'
});
prop.backgroundColor = RG.SVG.parseColorLinear({object:
this
, color: prop.backgroundColor,direction:
'horizontal'
});
};
this
.drawLabelsAbove =
function
()
{
if
(prop.labelsAbove) {
for
(
var
dataset=0,seq=0; dataset<
this
.data.length; ++dataset,++seq) {
for
(
var
i=0; i<
this
.data[dataset].length; ++i,++seq) {
var
value =
this
.data[dataset][i],
halign = dataset === 0 ?
'right'
:
'left'
,
valign =
'center'
,
hoffset = dataset === 0 ? -10 : 10;
if
(
typeof
value ===
'number'
) {
var
x = parseInt(
this
.coords[seq].element.getAttribute(
'x'
)) + hoffset + prop.labelsAboveOffsetx,
height = parseInt(
this
.coords[seq].element.getAttribute(
'height'
)),
y = parseInt(
this
.coords[seq].element.getAttribute(
'y'
)) + (height / 2) + prop.labelsAboveOffsety,
width = parseInt(
this
.coords[seq].element.getAttribute(
'width'
));
if
(dataset === 1) {
x += width;
}
var
str = RG.SVG.numberFormat({
object:
this
,
num: value.toFixed(prop.labelsAboveDecimals),
prepend:
typeof
prop.labelsAboveUnitsPre ===
'string'
? prop.labelsAboveUnitsPre :
null
,
append:
typeof
prop.labelsAboveUnitsPost ===
'string'
? prop.labelsAboveUnitsPost :
null
,
point:
typeof
prop.labelsAbovePoint ===
'string'
? prop.labelsAbovePoint :
null
,
thousand:
typeof
prop.labelsAboveThousand ===
'string'
? prop.labelsAboveThousand :
null
,
formatter:
typeof
prop.labelsAboveFormatter ===
'function'
? prop.labelsAboveFormatter :
null
});
if
(prop.labelsAboveSpecific && prop.labelsAboveSpecific.length && (
typeof
prop.labelsAboveSpecific[seq] ===
'string'
||
typeof
prop.labelsAboveSpecific[seq] ===
'number'
) ) {
str = parseStr(prop.labelsAboveSpecific[seq]);
}
else
if
( prop.labelsAboveSpecific && prop.labelsAboveSpecific.length &&
typeof
prop.labelsAboveSpecific[seq] !==
'string'
&&
typeof
prop.labelsAboveSpecific[seq] !==
'number'
) {
continue
;
}
RG.SVG.text({
object:
this
,
parent:
this
.svg.all,
text: str,
x: x,
y: y,
halign: halign,
valign: valign,
tag:
'labels.above'
,
font: prop.labelsAboveFont || prop.textFont,
size: prop.labelsAboveSize || prop.textSize,
bold:
typeof
prop.labelsAboveBold ===
'boolean'
? prop.labelsAboveBold : prop.textBold,
italic:
typeof
prop.labelsAboveItalic ===
'boolean'
? prop.labelsAboveItalic : prop.textItalic,
color: prop.labelsAboveColor || prop.textColor,
background: prop.labelsAboveBackground,
padding: prop.labelsAboveBackgroundPadding
});
}
else
if
(
typeof
value ===
'object'
&& prop.grouping ===
'stacked'
) {
for
(
var
k=0,sum=0,width=0; k<
this
.coords2[i].length; ++k) {
sum += parseFloat(
this
.coords2[i][k].element.getAttribute(
'data-value'
));
}
var
len =
this
.coords2[i].length;
if
(dataset === 0) {
var
x = parseFloat(
this
.coords2[i][len - 1].x) + hoffset,
height = parseFloat(
this
.coords2[i][len - 1].height),
y = parseFloat(
this
.coords2[i][0].y) + (height / 2);
}
else
{
var
x = parseFloat(
this
.coords2[
this
.data[0].length + i][0].x) + hoffset + prop.labelsAboveOffsetx,
height = parseFloat(
this
.coords2[i][len - 1].height),
y = parseFloat(
this
.coords2[i][0].y) + (height / 2) + prop.labelsAboveOffsety;
for
(
var
j=0; j<
this
.coords2Right[i].length; ++j) {
x +=
this
.coords2Right[i][j].width;
}
}
var
str = RG.SVG.numberFormat({
object:
this
,
num: sum.toFixed(prop.labelsAboveDecimals),
prepend:
typeof
prop.labelsAboveUnitsPre ===
'string'
? prop.labelsAboveUnitsPre :
null
,
append:
typeof
prop.labelsAboveUnitsPost ===
'string'
? prop.labelsAboveUnitsPost :
null
,
point:
typeof
prop.labelsAbovePoint ===
'string'
? prop.labelsAbovePoint :
null
,
thousand:
typeof
prop.labelsAboveThousand ===
'string'
? prop.labelsAboveThousand :
null
,
formatter:
typeof
prop.labelsAboveFormatter ===
'function'
? prop.labelsAboveFormatter :
null
});
if
(prop.labelsAboveSpecific && prop.labelsAboveSpecific.length && (
typeof
prop.labelsAboveSpecific[seq] ===
'string'
||
typeof
prop.labelsAboveSpecific[seq] ===
'number'
) ) {
str = parseStr(prop.labelsAboveSpecific[seq]);
}
else
if
( prop.labelsAboveSpecific && prop.labelsAboveSpecific.length &&
typeof
prop.labelsAboveSpecific[seq] !==
'string'
&&
typeof
prop.labelsAboveSpecific[seq] !==
'number'
) {
continue
;
}
RG.SVG.text({
object:
this
,
parent:
this
.svg.all,
text: str,
x: x,
y: y,
halign: halign,
valign: valign,
tag:
'labels.above'
,
font: prop.labelsAboveFont || prop.textFont,
size: prop.labelsAboveSize || prop.textSize,
bold:
typeof
prop.labelsAboveBold ===
'boolean'
? prop.labelsAboveBold : prop.textBold,
italic:
typeof
prop.labelsAboveItalic ===
'boolean'
? prop.labelsAboveItalic : prop.textItalic,
color: prop.labelsAboveColor || prop.textColor,
background: prop.labelsAboveBackground,
padding: prop.labelsAboveBackgroundPadding
});
}
else
if
(
typeof
value ===
'object'
&& prop.grouping ===
'grouped'
) {
for
(
var
k=0; k<value.length; ++k) {
val = value[k];
var
x = parseInt(
this
.coords[seq].element.getAttribute(
'x'
)) + hoffset + prop.labelsAboveOffsetx,
height = parseInt(
this
.coords[seq].element.getAttribute(
'height'
)),
y = parseInt(
this
.coords[seq].element.getAttribute(
'y'
)) + (height / 2) + prop.labelsAboveOffsety,
width = parseInt(
this
.coords[seq].element.getAttribute(
'width'
));
if
(dataset === 1) {
x += width;
}
var
str = RG.SVG.numberFormat({
object:
this
,
num: parseFloat(val).toFixed(prop.labelsAboveDecimals),
prepend:
typeof
prop.labelsAboveUnitsPre ===
'string'
? prop.labelsAboveUnitsPre :
null
,
append:
typeof
prop.labelsAboveUnitsPost ===
'string'
? prop.labelsAboveUnitsPost :
null
,
point:
typeof
prop.labelsAbovePoint ===
'string'
? prop.labelsAbovePoint :
null
,
thousand:
typeof
prop.labelsAboveThousand ===
'string'
? prop.labelsAboveThousand :
null
,
formatter:
typeof
prop.labelsAboveFormatter ===
'function'
? prop.labelsAboveFormatter :
null
});
if
(prop.labelsAboveSpecific && prop.labelsAboveSpecific.length && (
typeof
prop.labelsAboveSpecific[seq] ===
'string'
||
typeof
prop.labelsAboveSpecific[seq] ===
'number'
) ) {
str = parseStr(prop.labelsAboveSpecific[seq]);
}
else
if
( prop.labelsAboveSpecific && prop.labelsAboveSpecific.length &&
typeof
prop.labelsAboveSpecific[seq] !==
'string'
&&
typeof
prop.labelsAboveSpecific[seq] !==
'number'
) {
continue
;
}
RG.SVG.text({
object:
this
,
parent:
this
.svg.all,
text: str,
x: x,
y: y,
halign: halign,
valign: valign,
tag:
'labels.above'
,
font: prop.labelsAboveFont || prop.textFont,
size: prop.labelsAboveSize || prop.textSize,
bold:
typeof
prop.labelsAboveBold ===
'boolean'
? prop.labelsAboveBold : prop.textBold,
italic:
typeof
prop.labelsAboveItalic ===
'boolean'
? prop.labelsAboveItalic : prop.textItalic,
color: prop.labelsAboveColor || prop.textColor,
background: prop.labelsAboveBackground,
padding: prop.labelsAboveBackgroundPadding
});
seq++;
}
seq--;
}
}
--seq;
}
}
};
this
.on =
function
(type, func)
{
if
(type.substr(0,2) !==
'on'
) {
type =
'on'
+ type;
}
RG.SVG.addCustomEventListener(
this
, type, func);
return
this
;
};
this
.exec =
function
(func)
{
func(
this
);
return
this
;
};
this
.removeHighlight =
function
()
{
var
highlight = RG.SVG.REG.get(
'highlight'
);
if
(highlight && highlight.parentNode) {
highlight.parentNode.removeChild(highlight);
}
RG.SVG.REG.set(
'highlight'
,
null
);
};
this
.getGutterCenter =
function
()
{
var
bold =
typeof
prop.yaxisTextBold ===
'boolean'
? prop.yaxisTextBold : prop.textBold,
font =
typeof
prop.yaxisTextFont ===
'string'
? prop.yaxisTextFont : prop.textFont,
size =
typeof
prop.yaxisTextSize ===
'number'
? prop.yaxisTextSize : prop.textSize,
width = 0;
if
(prop.yaxisLabels) {
for
(
var
i=0,len=prop.yaxisLabels.length; i<len; ++i) {
width = ma.max(width, RG.SVG.measureText({
text: prop.yaxisLabels[i],
bold: bold,
font: font,
size: size
})[0]);
}
}
else
{
var
width = 50;
}
return
width + 15;
};
this
.drawTitle =
function
()
{
if
(RG.SVG.isNull(prop.titleX)) {
prop.titleX = ((
this
.width - prop.gutterLeft - prop.gutterRight) / 2) + prop.gutterLeft;
}
RG.SVG.drawTitle(
this
);
};
this
.grow =
function
()
{
var
opt = arguments[0] || {},
frames = opt.frames || 30,
frame = 0,
obj =
this
,
left = RG.SVG.arrayClone(
this
.left),
right = RG.SVG.arrayClone(
this
.right),
seq = 0;
this
.draw();
var
iterate =
function
()
{
for
(
var
i=0,seq=0,len=obj.coordsLeft.length; i<len; ++i, ++seq) {
var
multiplier = (frame / frames)
* RG.SVG.FX.getEasingMultiplier(frames, frame)
* RG.SVG.FX.getEasingMultiplier(frames, frame);
if
(
typeof
left[i] ===
'number'
) {
width = ma.abs(obj.getLeftXCoord(left[i]) - obj.getLeftXCoord(0));
left[i] = obj.left[i] * multiplier;
obj.coordsLeft[i].element.setAttribute(
'width'
,
width
);
obj.coords[seq].element.setAttribute(
'x'
,
obj.getLeftXCoord(0) - width
);
}
else
if
(
typeof
left[i] ===
'object'
&& prop.grouping ===
'stacked'
) {
var
accumulativeWidth = 0;
for
(
var
j=0,len2=left[i].length; j<len2; ++j, ++seq) {
width = ma.abs(obj.getLeftXCoord(left[i][j]) - obj.getLeftXCoord(0));
left[i][j] = obj.left[i][j] * multiplier;
obj.coords[seq].element.setAttribute(
'width'
,
width
);
obj.coords[seq].element.setAttribute(
'x'
,
obj.getLeftXCoord(0) - width - accumulativeWidth
);
accumulativeWidth += (prop.grouping ===
'stacked'
? width : 0);
}
if
(obj.stackedBackfacesLeft[i]) {
obj.stackedBackfacesLeft[i].setAttribute(
'width'
,
accumulativeWidth
);
obj.stackedBackfacesLeft[i].setAttribute(
'x'
,
obj.getLeftXCoord(0) - accumulativeWidth
);
}
--seq;
}
else
if
(
typeof
left[i] === 'object
' && prop.grouping === '
grouped
') {
// Loop thru the group
for (var j=0,len2=left[i].length; j<len2; ++j, ++seq) {
width = ma.abs(obj.getLeftXCoord(left[i][j]) - obj.getLeftXCoord(0));
left[i][j] = obj.left[i][j] * multiplier;
obj.coords[seq].element.setAttribute(
'
width
',
width
);
obj.coords[seq].element.setAttribute(
'
x
',
obj.getLeftXCoord(0) - width
);
}
// Decrease seq by one so that it'
s not incremented twice
--seq;
}
}
for
(
var
i=0,seq=0,len=obj.coordsRight.length; i<len; ++i, ++seq) {
var
multiplier = (frame / frames)
* RG.SVG.FX.getEasingMultiplier(frames, frame)
* RG.SVG.FX.getEasingMultiplier(frames, frame);
if
(
typeof
right[i] ===
'number'
) {
width = ma.abs(obj.getRightXCoord(right[i]) - obj.getRightXCoord(0));
right[i] = obj.right[i] * multiplier;
obj.coordsRight[i].element.setAttribute(
'width'
,
width
);
obj.coordsRight[seq].element.setAttribute(
'x'
,
obj.getRightXCoord(0)
);
}
else
if
(
typeof
right[i] ===
'object'
&& prop.grouping ===
'stacked'
) {
var
accumulativeWidth = 0;
for
(
var
j=0,len2=right[i].length; j<len2; ++j, ++seq) {
width = ma.abs(obj.getRightXCoord(right[i][j]) - obj.getRightXCoord(0));
right[i][j] = obj.right[i][j] * multiplier;
obj.coordsRight[seq].element.setAttribute(
'width'
,
width
);
obj.coordsRight[seq].element.setAttribute(
'x'
,
obj.getRightXCoord(0) + accumulativeWidth
);
accumulativeWidth += width;
}
if
(obj.stackedBackfacesRight[i]) {
obj.stackedBackfacesRight[i].setAttribute(
'width'
,
accumulativeWidth
);
obj.stackedBackfacesRight[i].setAttribute(
'x'
,
obj.getRightXCoord(0)
);
}
--seq;
}
else
if
(
typeof
right[i] === 'object
' && prop.grouping === '
grouped
') {
// Loop thru the group
for (var j=0,len2=right[i].length; j<len2; ++j, ++seq) {
width = ma.abs(obj.getRightXCoord(right[i][j]) - obj.getRightXCoord(0));
right[i][j] = obj.right[i][j] * multiplier;
obj.coordsRight[seq].element.setAttribute(
'
width
',
width
);
obj.coordsRight[seq].element.setAttribute(
'
x
',
obj.getRightXCoord(0)
);
}
// Decrease seq by one so that it'
s not incremented twice
--seq;
}
}
if
(frame++ <= frames) {
RG.SVG.FX.update(iterate);
}
else
if
(opt.callback) {
(opt.callback)(obj);
}
};
iterate();
return
this
;
};
this
.wave =
function
()
{
var
obj =
this
,
opt = arguments[0] || {},
frames = opt.frames || 120,
startFrames_left = [],
startFrames_right = [],
counters_left = [],
counters_right = [];
var
framesperbar = frames / 3,
frame_left = -1,
frame_right = -1,
callback = arguments[1] ||
function
() {},
original_left = RG.SVG.arrayClone(
this
.left),
original_right = RG.SVG.arrayClone(
this
.right);
for
(
var
i=0,len=
this
.left.length,seq=0; i<len; i+=1,++seq) {
startFrames_left[seq] = ((frames / 3) / (RG.SVG.arrayLinearize(
this
.left).length - 1)) * i;
startFrames_right[seq] = ((frames / 3) / (RG.SVG.arrayLinearize(
this
.right).length - 1)) * i;
counters_left[seq] = 0;
counters_right[seq] = 0;
if
(RG.SVG.isArray(
this
.left[i])) {
for
(
var
j=0; j<
this
.left[i].length; ++j,seq++) {
startFrames_left[seq] = ((frames / 3) / (RG.SVG.arrayLinearize(
this
.left).length - 1)) * seq;
startFrames_right[seq] = ((frames / 3) / (RG.SVG.arrayLinearize(
this
.right).length - 1)) * seq;
counters_left[seq] = 0;
counters_right[seq] = 0;
}
--seq;
}
}
this
.draw();
for
(
var
i=0,len=
this
.left.length; i<len; i+=1) {
if
(
typeof
this
.left[i] ===
'number'
) {
this
.left[i] = 0;
this
.right[i] = 0;
this
.coordsLeft[i].element.setAttribute(
'width'
, 0);
this
.coordsRight[i].element.setAttribute(
'width'
, 0);
}
else
if
(
typeof
this
.left[i] ===
'object'
&& !RG.SVG.isNull(
this
.left[i])) {
for
(
var
j=0; j<
this
.left[i].length; ++j) {
this
.left[i][j] = 0;
this
.right[i][j] = 0;
this
.coords2Left[i][j].element.setAttribute(
'width'
, 0);
this
.coords2Right[i][j].element.setAttribute(
'width'
, 0);
}
}
}
function
iteratorLeft ()
{
++frame_left;
for
(
var
i=0,len=obj.left.length,seq=0; i<len; i+=1,seq+=1) {
if
(frame_left >= startFrames_left[seq]) {
var
isNull = RG.SVG.isNull(obj.left[i]);
if
(
typeof
obj.left[i] ===
'number'
) {
obj.left[i] = ma.min(
ma.abs(original_left[i]),
ma.abs(original_left[i] * ( (counters_left[i]++) / framesperbar))
);
var
rect_left = obj.coords[i].element;
rect_left.setAttribute(
'width'
,
parseFloat(rect_left.getAttribute(
'data-original-width'
)) * (obj.left[i] / rect_left.getAttribute(
'data-value'
))
);
rect_left.setAttribute(
'x'
,
obj.properties.gutterLeft + obj.graphWidth - (parseFloat(rect_left.getAttribute(
'data-original-width'
)) * (obj.left[i] / rect_left.getAttribute(
'data-value'
)))
);
}
else
if
(RG.SVG.isArray(obj.left[i])) {
for
(
var
j=0,accWidth=0; j<obj.left[i].length; ++j,++seq) {
obj.left[i][j] = ma.min(
ma.abs(original_left[i][j]),
ma.abs(original_left[i][j] * ( (counters_left[seq]++) / framesperbar))
);
var
rect_left = obj.coords[seq].element;
rect_left.setAttribute(
'width'
,
parseFloat(rect_left.getAttribute(
'data-original-width'
)) * (obj.left[i][j] / rect_left.getAttribute(
'data-value'
))
);
rect_left.setAttribute(
'x'
,
obj.properties.gutterLeft + obj.graphWidth - (parseFloat(rect_left.getAttribute(
'data-original-width'
)) * (obj.left[i][j] / rect_left.getAttribute(
'data-value'
))) - accWidth
);
if
(obj.properties.grouping ===
'stacked'
) {
accWidth += parseFloat(rect_left.getAttribute(
'width'
));
}
}
seq--;
}
if
(isNull) {
obj.left[i] =
null
;
}
}
else
{
obj.left[i] =
typeof
obj.left[i] ===
'object'
&& obj.left[i] ? RG.SVG.arrayPad([], obj.left[i].length, 0) : (RG.SVG.isNull(obj.left[i]) ?
null
: 0);
}
}
if
(frame_left <= frames) {
RG.SVG.FX.update(iteratorLeft);
}
}
function
iteratorRight ()
{
++frame_right;
for
(
var
i=0,len=obj.right.length,seq=0; i<len; i+=1,seq+=1) {
if
(frame_right >= startFrames_right[seq]) {
var
isNull = RG.SVG.isNull(obj.right[i]);
if
(
typeof
obj.right[i] ===
'number'
) {
obj.right[i] = ma.min(
ma.abs(original_right[i]),
ma.abs(original_right[i] * ( (counters_right[i]++) / framesperbar))
);
var
rect_right = obj.coords[i + obj.left.length].element;
rect_right.setAttribute(
'width'
,
parseFloat(rect_right.getAttribute(
'data-original-width'
)) * (obj.right[i] / rect_right.getAttribute(
'data-value'
))
);
rect_right.setAttribute(
'x'
,
obj.properties.gutterLeft + obj.graphWidth + prop.gutterCenter
);
}
else
if
(RG.SVG.isArray(obj.right[i])) {
for
(
var
j=0,accWidth=0; j<obj.right[i].length; ++j,++seq) {
obj.right[i][j] = ma.min(
ma.abs(original_right[i][j]),
ma.abs(original_right[i][j] * ( (counters_right[seq]++) / framesperbar))
);
var
rect_right = obj.coordsRight[seq].element;
rect_right.setAttribute(
'width'
,
parseFloat(rect_right.getAttribute(
'data-original-width'
)) * (obj.right[i][j] / rect_right.getAttribute(
'data-value'
))
);
rect_right.setAttribute(
'x'
,
obj.properties.gutterLeft + obj.graphWidth + prop.gutterCenter + accWidth
);
if
(obj.properties.grouping ===
'stacked'
) {
accWidth += parseFloat(rect_right.getAttribute(
'width'
));
}
}
seq--;
}
if
(isNull) {
obj.right[i] =
null
;
}
}
else
{
obj.right[i] =
typeof
obj.right[i] ===
'object'
&& obj.right[i] ? RG.SVG.arrayPad([], obj.right[i].length, 0) : (RG.SVG.isNull(obj.right[i]) ?
null
: 0);
}
}
if
(frame_right <= frames) {
RG.SVG.FX.update(iteratorRight);
}
else
{
}
}
iteratorLeft();
iteratorRight();
return
this
;
};
for
(i
in
conf.options) {
if
(
typeof
i ===
'string'
) {
this
.set(i, conf.options[i]);
}
}
};
return
this
;
})(window, document);