summaryrefslogtreecommitdiffstatshomepage
path: root/includes/js/dojox/charting/plot2d
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dojox/charting/plot2d')
-rw-r--r--includes/js/dojox/charting/plot2d/Areas.js14
-rw-r--r--includes/js/dojox/charting/plot2d/Bars.js89
-rw-r--r--includes/js/dojox/charting/plot2d/Base.js60
-rw-r--r--includes/js/dojox/charting/plot2d/ClusteredBars.js63
-rw-r--r--includes/js/dojox/charting/plot2d/ClusteredColumns.js63
-rw-r--r--includes/js/dojox/charting/plot2d/Columns.js88
-rw-r--r--includes/js/dojox/charting/plot2d/Default.js173
-rw-r--r--includes/js/dojox/charting/plot2d/Grid.js116
-rw-r--r--includes/js/dojox/charting/plot2d/Lines.js13
-rw-r--r--includes/js/dojox/charting/plot2d/Markers.js13
-rw-r--r--includes/js/dojox/charting/plot2d/MarkersOnly.js14
-rw-r--r--includes/js/dojox/charting/plot2d/Pie.js199
-rw-r--r--includes/js/dojox/charting/plot2d/Scatter.js14
-rw-r--r--includes/js/dojox/charting/plot2d/Stacked.js160
-rw-r--r--includes/js/dojox/charting/plot2d/StackedAreas.js14
-rw-r--r--includes/js/dojox/charting/plot2d/StackedBars.js85
-rw-r--r--includes/js/dojox/charting/plot2d/StackedColumns.js83
-rw-r--r--includes/js/dojox/charting/plot2d/StackedLines.js13
-rw-r--r--includes/js/dojox/charting/plot2d/common.js113
19 files changed, 1387 insertions, 0 deletions
diff --git a/includes/js/dojox/charting/plot2d/Areas.js b/includes/js/dojox/charting/plot2d/Areas.js
new file mode 100644
index 0000000..35d859f
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Areas.js
@@ -0,0 +1,14 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Areas"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Areas"] = true;
+dojo.provide("dojox.charting.plot2d.Areas");
+
+dojo.require("dojox.charting.plot2d.Default");
+
+dojo.declare("dojox.charting.plot2d.Areas", dojox.charting.plot2d.Default, {
+ constructor: function(){
+ this.opt.lines = true;
+ this.opt.areas = true;
+ }
+});
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Bars.js b/includes/js/dojox/charting/plot2d/Bars.js
new file mode 100644
index 0000000..dd82b64
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Bars.js
@@ -0,0 +1,89 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Bars"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Bars"] = true;
+dojo.provide("dojox.charting.plot2d.Bars");
+
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Base");
+
+dojo.require("dojox.lang.utils");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+
+(function(){
+ var df = dojox.lang.functional, du = dojox.lang.utils,
+ dc = dojox.charting.plot2d.common,
+ purgeGroup = df.lambda("item.purgeGroup()");
+
+ dojo.declare("dojox.charting.plot2d.Bars", dojox.charting.plot2d.Base, {
+ defaultParams: {
+ hAxis: "x", // use a horizontal axis named "x"
+ vAxis: "y", // use a vertical axis named "y"
+ gap: 0, // gap between columns in pixels
+ shadows: null // draw shadows
+ },
+ optionalParams: {}, // no optional parameters
+
+ constructor: function(chart, kwArgs){
+ this.opt = dojo.clone(this.defaultParams);
+ du.updateWithObject(this.opt, kwArgs);
+ this.series = [];
+ this.hAxis = this.opt.hAxis;
+ this.vAxis = this.opt.vAxis;
+ },
+
+ calculateAxes: function(dim){
+ var stats = dc.collectSimpleStats(this.series), t;
+ stats.hmin -= 0.5;
+ stats.hmax += 0.5;
+ t = stats.hmin, stats.hmin = stats.vmin, stats.vmin = t;
+ t = stats.hmax, stats.hmax = stats.vmax, stats.vmax = t;
+ this._calc(dim, stats);
+ return this;
+ },
+ render: function(dim, offsets){
+ if(this.dirty){
+ dojo.forEach(this.series, purgeGroup);
+ this.cleanGroup();
+ var s = this.group;
+ df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+ }
+ var t = this.chart.theme, color, stroke, fill, f,
+ gap = this.opt.gap < this._vScaler.scale / 3 ? this.opt.gap : 0;
+ for(var i = this.series.length - 1; i >= 0; --i){
+ var run = this.series[i];
+ if(!this.dirty && !run.dirty){ continue; }
+ run.cleanGroup();
+ var s = run.group;
+ if(!run.fill || !run.stroke){
+ // need autogenerated color
+ color = run.dyn.color = new dojo.Color(t.next("color"));
+ }
+ stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+ fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+ var baseline = Math.max(0, this._hScaler.bounds.lower),
+ xoff = offsets.l + this._hScaler.scale * (baseline - this._hScaler.bounds.lower),
+ yoff = dim.height - offsets.b - this._vScaler.scale * (1.5 - this._vScaler.bounds.lower) + gap;
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j],
+ width = this._hScaler.scale * (v - baseline),
+ height = this._vScaler.scale - 2 * gap,
+ w = Math.abs(width);
+ if(w >= 1 && height >= 1){
+ var shape = s.createRect({
+ x: xoff + (width < 0 ? width : 0),
+ y: yoff - this._vScaler.scale * j,
+ width: w, height: height
+ }).setFill(fill).setStroke(stroke);
+ run.dyn.fill = shape.getFill();
+ run.dyn.stroke = shape.getStroke();
+ }
+ }
+ run.dirty = false;
+ }
+ this.dirty = false;
+ return this;
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Base.js b/includes/js/dojox/charting/plot2d/Base.js
new file mode 100644
index 0000000..c894ce3
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Base.js
@@ -0,0 +1,60 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Base"] = true;
+dojo.provide("dojox.charting.plot2d.Base");
+
+dojo.require("dojox.charting.Element");
+dojo.require("dojox.charting.plot2d.common");
+
+dojo.declare("dojox.charting.plot2d.Base", dojox.charting.Element, {
+ clear: function(){
+ this.series = [];
+ this._hAxis = null;
+ this._vAxis = null;
+ this.dirty = true;
+ return this;
+ },
+ setAxis: function(axis){
+ if(axis){
+ this[axis.vertical ? "_vAxis" : "_hAxis"] = axis;
+ }
+ return this;
+ },
+ addSeries: function(run){
+ this.series.push(run);
+ return this;
+ },
+ calculateAxes: function(dim){
+ return this;
+ },
+ render: function(dim, offsets){
+ return this;
+ },
+ getRequiredColors: function(){
+ return this.series.length;
+ },
+
+ // utilities
+ _calc: function(dim, stats){
+ // calculate scaler
+ if(this._hAxis){
+ if(!this._hAxis.initialized()){
+ this._hAxis.calculate(stats.hmin, stats.hmax, dim.width);
+ }
+ this._hScaler = this._hAxis.getScaler();
+ }else{
+ this._hScaler = {bounds: {lower: stats.hmin, upper: stats.hmax},
+ scale: dim.width / (stats.hmax - stats.hmin)};
+ }
+ if(this._vAxis){
+ if(!this._vAxis.initialized()){
+ this._vAxis.calculate(stats.vmin, stats.vmax, dim.height);
+ }
+ this._vScaler = this._vAxis.getScaler();
+ }else{
+ this._vScaler = {bounds: {lower: stats.vmin, upper: stats.vmax},
+ scale: dim.height / (stats.vmax - stats.vmin)};
+ }
+ }
+});
+
+}
diff --git a/includes/js/dojox/charting/plot2d/ClusteredBars.js b/includes/js/dojox/charting/plot2d/ClusteredBars.js
new file mode 100644
index 0000000..9d64bb2
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/ClusteredBars.js
@@ -0,0 +1,63 @@
+if(!dojo._hasResource["dojox.charting.plot2d.ClusteredBars"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.ClusteredBars"] = true;
+dojo.provide("dojox.charting.plot2d.ClusteredBars");
+
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Bars");
+
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+
+(function(){
+ var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+ purgeGroup = df.lambda("item.purgeGroup()");
+
+ dojo.declare("dojox.charting.plot2d.ClusteredBars", dojox.charting.plot2d.Bars, {
+ render: function(dim, offsets){
+ if(this.dirty){
+ dojo.forEach(this.series, purgeGroup);
+ this.cleanGroup();
+ var s = this.group;
+ df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+ }
+ var t = this.chart.theme, color, stroke, fill, f,
+ gap = this.opt.gap < this._vScaler.scale / 3 ? this.opt.gap : 0,
+ thickness = (this._vScaler.scale - 2 * gap) / this.series.length;
+ for(var i = this.series.length - 1; i >= 0; --i){
+ var run = this.series[i];
+ if(!this.dirty && !run.dirty){ continue; }
+ run.cleanGroup();
+ var s = run.group;
+ if(!run.fill || !run.stroke){
+ // need autogenerated color
+ color = run.dyn.color = new dojo.Color(t.next("color"));
+ }
+ stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+ fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+ var baseline = Math.max(0, this._hScaler.bounds.lower),
+ xoff = offsets.l + this._hScaler.scale * (baseline - this._hScaler.bounds.lower),
+ yoff = dim.height - offsets.b - this._vScaler.scale * (1.5 - this._vScaler.bounds.lower) +
+ gap + thickness * (this.series.length - i - 1);
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j],
+ width = this._hScaler.scale * (v - baseline),
+ height = thickness, w = Math.abs(width);
+ if(w >= 1 && height >= 1){
+ var shape = s.createRect({
+ x: xoff + (width < 0 ? width : 0),
+ y: yoff - this._vScaler.scale * j,
+ width: w, height: height
+ }).setFill(fill).setStroke(stroke);
+ run.dyn.fill = shape.getFill();
+ run.dyn.stroke = shape.getStroke();
+ }
+ }
+ run.dirty = false;
+ }
+ this.dirty = false;
+ return this;
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/ClusteredColumns.js b/includes/js/dojox/charting/plot2d/ClusteredColumns.js
new file mode 100644
index 0000000..9a4170a
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/ClusteredColumns.js
@@ -0,0 +1,63 @@
+if(!dojo._hasResource["dojox.charting.plot2d.ClusteredColumns"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.ClusteredColumns"] = true;
+dojo.provide("dojox.charting.plot2d.ClusteredColumns");
+
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Columns");
+
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+
+(function(){
+ var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+ purgeGroup = df.lambda("item.purgeGroup()");
+
+ dojo.declare("dojox.charting.plot2d.ClusteredColumns", dojox.charting.plot2d.Columns, {
+ render: function(dim, offsets){
+ if(this.dirty){
+ dojo.forEach(this.series, purgeGroup);
+ this.cleanGroup();
+ var s = this.group;
+ df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+ }
+ var t = this.chart.theme, color, stroke, fill, f,
+ gap = this.opt.gap < this._hScaler.scale / 3 ? this.opt.gap : 0,
+ thickness = (this._hScaler.scale - 2 * gap) / this.series.length;
+ for(var i = 0; i < this.series.length; ++i){
+ var run = this.series[i];
+ if(!this.dirty && !run.dirty){ continue; }
+ run.cleanGroup();
+ var s = run.group;
+ if(!run.fill || !run.stroke){
+ // need autogenerated color
+ color = run.dyn.color = new dojo.Color(t.next("color"));
+ }
+ stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+ fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+ var baseline = Math.max(0, this._vScaler.bounds.lower),
+ xoff = offsets.l + this._hScaler.scale * (0.5 - this._hScaler.bounds.lower) + gap + thickness * i,
+ yoff = dim.height - offsets.b - this._vScaler.scale * (baseline - this._vScaler.bounds.lower);
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j],
+ width = thickness,
+ height = this._vScaler.scale * (v - baseline),
+ h = Math.abs(height);
+ if(width >= 1 && h >= 1){
+ var shape = s.createRect({
+ x: xoff + this._hScaler.scale * j,
+ y: yoff - (height < 0 ? 0 : height),
+ width: width, height: h
+ }).setFill(fill).setStroke(stroke);
+ run.dyn.fill = shape.getFill();
+ run.dyn.stroke = shape.getStroke();
+ }
+ }
+ run.dirty = false;
+ }
+ this.dirty = false;
+ return this;
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Columns.js b/includes/js/dojox/charting/plot2d/Columns.js
new file mode 100644
index 0000000..ff97393
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Columns.js
@@ -0,0 +1,88 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Columns"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Columns"] = true;
+dojo.provide("dojox.charting.plot2d.Columns");
+
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Base");
+
+dojo.require("dojox.lang.utils");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+
+(function(){
+ var df = dojox.lang.functional, du = dojox.lang.utils,
+ dc = dojox.charting.plot2d.common,
+ purgeGroup = df.lambda("item.purgeGroup()");
+
+ dojo.declare("dojox.charting.plot2d.Columns", dojox.charting.plot2d.Base, {
+ defaultParams: {
+ hAxis: "x", // use a horizontal axis named "x"
+ vAxis: "y", // use a vertical axis named "y"
+ gap: 0, // gap between columns in pixels
+ shadows: null // draw shadows
+ },
+ optionalParams: {}, // no optional parameters
+
+ constructor: function(chart, kwArgs){
+ this.opt = dojo.clone(this.defaultParams);
+ du.updateWithObject(this.opt, kwArgs);
+ this.series = [];
+ this.hAxis = this.opt.hAxis;
+ this.vAxis = this.opt.vAxis;
+ },
+
+ calculateAxes: function(dim){
+ var stats = dc.collectSimpleStats(this.series);
+ stats.hmin -= 0.5;
+ stats.hmax += 0.5;
+ this._calc(dim, stats);
+ return this;
+ },
+ render: function(dim, offsets){
+ if(this.dirty){
+ dojo.forEach(this.series, purgeGroup);
+ this.cleanGroup();
+ var s = this.group;
+ df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+ }
+ var t = this.chart.theme, color, stroke, fill, f,
+ gap = this.opt.gap < this._hScaler.scale / 3 ? this.opt.gap : 0;
+ for(var i = this.series.length - 1; i >= 0; --i){
+ var run = this.series[i];
+ if(!this.dirty && !run.dirty){ continue; }
+ run.cleanGroup();
+ var s = run.group;
+ if(!run.fill || !run.stroke){
+ // need autogenerated color
+ color = run.dyn.color = new dojo.Color(t.next("color"));
+ }
+ stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+ fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+ var baseline = Math.max(0, this._vScaler.bounds.lower),
+ xoff = offsets.l + this._hScaler.scale * (0.5 - this._hScaler.bounds.lower) + gap,
+ yoff = dim.height - offsets.b - this._vScaler.scale * (baseline - this._vScaler.bounds.lower);
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j],
+ width = this._hScaler.scale - 2 * gap,
+ height = this._vScaler.scale * (v - baseline),
+ h = Math.abs(height);
+ if(width >= 1 && h >= 1){
+ var rect = {
+ x: xoff + this._hScaler.scale * j,
+ y: yoff - (height < 0 ? 0 : height),
+ width: width, height: h
+ },
+ shape = s.createRect(rect).setFill(fill).setStroke(stroke);
+ run.dyn.fill = shape.getFill();
+ run.dyn.stroke = shape.getStroke();
+ }
+ }
+ run.dirty = false;
+ }
+ this.dirty = false;
+ return this;
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Default.js b/includes/js/dojox/charting/plot2d/Default.js
new file mode 100644
index 0000000..a8ca8a5
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Default.js
@@ -0,0 +1,173 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Default"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Default"] = true;
+dojo.provide("dojox.charting.plot2d.Default");
+
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Base");
+
+dojo.require("dojox.lang.utils");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+
+(function(){
+ var df = dojox.lang.functional, du = dojox.lang.utils,
+ dc = dojox.charting.plot2d.common,
+ purgeGroup = df.lambda("item.purgeGroup()");
+
+ dojo.declare("dojox.charting.plot2d.Default", dojox.charting.plot2d.Base, {
+ defaultParams: {
+ hAxis: "x", // use a horizontal axis named "x"
+ vAxis: "y", // use a vertical axis named "y"
+ lines: true, // draw lines
+ areas: false, // draw areas
+ markers: false, // draw markers
+ shadows: 0, // draw shadows
+ tension: 0 // draw curved lines (tension>0)
+ },
+ optionalParams: {}, // no optional parameters
+
+ constructor: function(chart, kwArgs){
+ this.opt = dojo.clone(this.defaultParams);
+ du.updateWithObject(this.opt, kwArgs);
+ this.series = [];
+ this.hAxis = this.opt.hAxis;
+ this.vAxis = this.opt.vAxis;
+ },
+
+ calculateAxes: function(dim){
+ this._calc(dim, dc.collectSimpleStats(this.series));
+ return this;
+ },
+ render: function(dim, offsets){
+ if(this.dirty){
+ dojo.forEach(this.series, purgeGroup);
+ this.cleanGroup();
+ var s = this.group;
+ df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+ }
+ var t = this.chart.theme, stroke, outline, color, marker;
+ for(var i = this.series.length - 1; i >= 0; --i){
+ var run = this.series[i];
+ if(!this.dirty && !run.dirty){ continue; }
+ run.cleanGroup();
+ if(!run.data.length){
+ run.dirty = false;
+ continue;
+ }
+
+ // inner function for translating polylines to curves with tension
+ function curve(arr, tension){
+ var p=dojo.map(arr, function(item, i){
+ if(i==0){ return "M" + item.x + "," + item.y; }
+ var dx=item.x-arr[i-1].x, dy=arr[i-1].y;
+ return "C"+(item.x-(tension-1)*(dx/tension))+","+dy+" "+(item.x-(dx/tension))+","+item.y+" "+item.x+","+item.y;
+ });
+ return p.join(" ");
+ }
+
+ var s = run.group, lpoly;
+ if(typeof run.data[0] == "number"){
+ lpoly = dojo.map(run.data, function(v, i){
+ return {
+ x: this._hScaler.scale * (i + 1 - this._hScaler.bounds.lower) + offsets.l,
+ y: dim.height - offsets.b - this._vScaler.scale * (v - this._vScaler.bounds.lower)
+ };
+ }, this);
+ }else{
+ lpoly = dojo.map(run.data, function(v, i){
+ return {
+ x: this._hScaler.scale * (v.x - this._hScaler.bounds.lower) + offsets.l,
+ y: dim.height - offsets.b - this._vScaler.scale * (v.y - this._vScaler.bounds.lower)
+ };
+ }, this);
+ }
+ if(!run.fill || !run.stroke){
+ // need autogenerated color
+ color = run.dyn.color = new dojo.Color(t.next("color"));
+ }
+
+ var lpath="";
+ if(this.opt.tension){
+ var lpath=curve(lpoly, this.opt.tension);
+ }
+
+ if(this.opt.areas){
+ var fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+ var apoly = dojo.clone(lpoly);
+ if(this.opt.tension){
+ var apath="L" + (apoly[apoly.length-1].x) + "," + (dim.height-offsets.b) + " "
+ + "L"+apoly[0].x+","+(dim.height-offsets.b)+" "
+ + "L"+apoly[0].x+","+apoly[0].y;
+ run.dyn.fill = s.createPath(lpath+" "+apath).setFill(fill).getFill();
+ } else {
+ apoly.push({x: lpoly[lpoly.length - 1].x, y: dim.height - offsets.b});
+ apoly.push({x: lpoly[0].x, y: dim.height - offsets.b});
+ apoly.push(lpoly[0]);
+ run.dyn.fill = s.createPolyline(apoly).setFill(fill).getFill();
+ }
+ }
+ if(this.opt.lines || this.opt.markers){
+ // need a stroke
+ stroke = run.stroke ? dc.makeStroke(run.stroke) : dc.augmentStroke(t.series.stroke, color);
+ if(run.outline || t.series.outline){
+ outline = dc.makeStroke(run.outline ? run.outline : t.series.outline);
+ outline.width = 2 * outline.width + stroke.width;
+ }
+ }
+ if(this.opt.markers){
+ // need a marker
+ marker = run.dyn.marker = run.marker ? run.marker : t.next("marker");
+ }
+ if(this.opt.shadows && stroke){
+ var sh = this.opt.shadows, shadowColor = new dojo.Color([0, 0, 0, 0.3]),
+ spoly = dojo.map(lpoly, function(c){
+ return {x: c.x + sh.dx, y: c.y + sh.dy};
+ }),
+ shadowStroke = dojo.clone(outline ? outline : stroke);
+ shadowStroke.color = shadowColor;
+ shadowStroke.width += sh.dw ? sh.dw : 0;
+ if(this.opt.lines){
+ if(this.opt.tension){
+ s.createPath(curve(spoly, this.opt.tension)).setStroke(shadowStroke);
+ } else {
+ s.createPolyline(spoly).setStroke(shadowStroke);
+ }
+ }
+ if(this.opt.markers){
+ dojo.forEach(spoly, function(c){
+ s.createPath("M" + c.x + " " + c.y + " " + marker).setStroke(shadowStroke).setFill(shadowColor);
+ }, this);
+ }
+ }
+ if(this.opt.lines){
+ if(outline){
+ if(this.opt.tension){
+ run.dyn.outline = s.createPath(lpath).setStroke(outline).getStroke();
+ } else {
+ run.dyn.outline = s.createPolyline(lpoly).setStroke(outline).getStroke();
+ }
+ }
+ if(this.opt.tension){
+ run.dyn.stroke = s.createPath(lpath).setStroke(stroke).getStroke();
+ } else {
+ run.dyn.stroke = s.createPolyline(lpoly).setStroke(stroke).getStroke();
+ }
+ }
+ if(this.opt.markers){
+ dojo.forEach(lpoly, function(c){
+ var path = "M" + c.x + " " + c.y + " " + marker;
+ if(outline){
+ s.createPath(path).setStroke(outline);
+ }
+ s.createPath(path).setStroke(stroke).setFill(stroke.color);
+ }, this);
+ }
+ run.dirty = false;
+ }
+ this.dirty = false;
+ return this;
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Grid.js b/includes/js/dojox/charting/plot2d/Grid.js
new file mode 100644
index 0000000..52cb348
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Grid.js
@@ -0,0 +1,116 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Grid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Grid"] = true;
+dojo.provide("dojox.charting.plot2d.Grid");
+
+dojo.require("dojox.charting.Element");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.lang.functional");
+
+(function(){
+ var du = dojox.lang.utils;
+
+ dojo.declare("dojox.charting.plot2d.Grid", dojox.charting.Element, {
+ defaultParams: {
+ hAxis: "x", // use a horizontal axis named "x"
+ vAxis: "y", // use a vertical axis named "y"
+ hMajorLines: true, // draw horizontal major lines
+ hMinorLines: false, // draw horizontal minor lines
+ vMajorLines: true, // draw vertical major lines
+ vMinorLines: false, // draw vertical minor lines
+ hStripes: "none", // TBD
+ vStripes: "none" // TBD
+ },
+ optionalParams: {}, // no optional parameters
+
+ constructor: function(chart, kwArgs){
+ this.opt = dojo.clone(this.defaultParams);
+ du.updateWithObject(this.opt, kwArgs);
+ this.hAxis = this.opt.hAxis;
+ this.vAxis = this.opt.vAxis;
+ },
+ clear: function(){
+ this._hAxis = null;
+ this._vAxis = null;
+ this.dirty = true;
+ return this;
+ },
+ setAxis: function(axis){
+ if(axis){
+ this[axis.vertical ? "_vAxis" : "_hAxis"] = axis;
+ }
+ return this;
+ },
+ addSeries: function(run){
+ // nothing
+ return this;
+ },
+ calculateAxes: function(dim){
+ // nothing
+ return this;
+ },
+ getRequiredColors: function(){
+ return 0;
+ },
+ render: function(dim, offsets){
+ // draw horizontal stripes and lines
+ if(!this.dirty){ return this; }
+ this.cleanGroup();
+ var s = this.group, ta = this.chart.theme.axis,
+ scaler = this._vAxis.getScaler();
+ if(this.opt.hMinorLines && scaler.minor.tick){
+ for(var i = 0; i < scaler.minor.count; ++i){
+ var y = dim.height - offsets.b - scaler.scale *
+ (scaler.minor.start - scaler.bounds.lower + i * scaler.minor.tick);
+ s.createLine({
+ x1: offsets.l,
+ y1: y,
+ x2: dim.width - offsets.r,
+ y2: y
+ }).setStroke(ta.minorTick);
+ }
+ }
+ if(this.opt.hMajorLines && scaler.major.tick){
+ for(var i = 0; i < scaler.major.count; ++i){
+ var y = dim.height - offsets.b - scaler.scale *
+ (scaler.major.start - scaler.bounds.lower + i * scaler.major.tick);
+ s.createLine({
+ x1: offsets.l,
+ y1: y,
+ x2: dim.width - offsets.r,
+ y2: y
+ }).setStroke(ta.majorTick);
+ }
+ }
+ // draw vertical stripes and lines
+ scaler = this._hAxis.getScaler();
+ if(this.opt.vMinorLines && scaler.minor.tick){
+ for(var i = 0; i < scaler.minor.count; ++i){
+ var x = offsets.l + scaler.scale *
+ (scaler.minor.start - scaler.bounds.lower + i * scaler.minor.tick);
+ s.createLine({
+ x1: x,
+ y1: offsets.t,
+ x2: x,
+ y2: dim.height - offsets.b
+ }).setStroke(ta.minorTick);
+ }
+ }
+ if(this.opt.vMajorLines && scaler.major.tick){
+ for(var i = 0; i < scaler.major.count; ++i){
+ var x = offsets.l + scaler.scale *
+ (scaler.major.start - scaler.bounds.lower + i * scaler.major.tick);
+ s.createLine({
+ x1: x,
+ y1: offsets.t,
+ x2: x,
+ y2: dim.height - offsets.b
+ }).setStroke(ta.majorTick);
+ }
+ }
+ this.dirty = false;
+ return this;
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Lines.js b/includes/js/dojox/charting/plot2d/Lines.js
new file mode 100644
index 0000000..34e6897
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Lines.js
@@ -0,0 +1,13 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Lines"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Lines"] = true;
+dojo.provide("dojox.charting.plot2d.Lines");
+
+dojo.require("dojox.charting.plot2d.Default");
+
+dojo.declare("dojox.charting.plot2d.Lines", dojox.charting.plot2d.Default, {
+ constructor: function(){
+ this.opt.lines = true;
+ }
+});
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Markers.js b/includes/js/dojox/charting/plot2d/Markers.js
new file mode 100644
index 0000000..177aafb
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Markers.js
@@ -0,0 +1,13 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Markers"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Markers"] = true;
+dojo.provide("dojox.charting.plot2d.Markers");
+
+dojo.require("dojox.charting.plot2d.Default");
+
+dojo.declare("dojox.charting.plot2d.Markers", dojox.charting.plot2d.Default, {
+ constructor: function(){
+ this.opt.markers = true;
+ }
+});
+
+}
diff --git a/includes/js/dojox/charting/plot2d/MarkersOnly.js b/includes/js/dojox/charting/plot2d/MarkersOnly.js
new file mode 100644
index 0000000..48cd663
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/MarkersOnly.js
@@ -0,0 +1,14 @@
+if(!dojo._hasResource["dojox.charting.plot2d.MarkersOnly"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.MarkersOnly"] = true;
+dojo.provide("dojox.charting.plot2d.MarkersOnly");
+
+dojo.require("dojox.charting.plot2d.Default");
+
+dojo.declare("dojox.charting.plot2d.MarkersOnly", dojox.charting.plot2d.Default, {
+ constructor: function(){
+ this.opt.lines = false;
+ this.opt.markers = true;
+ }
+});
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Pie.js b/includes/js/dojox/charting/plot2d/Pie.js
new file mode 100644
index 0000000..2d0f55e
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Pie.js
@@ -0,0 +1,199 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Pie"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Pie"] = true;
+dojo.provide("dojox.charting.plot2d.Pie");
+
+dojo.require("dojox.charting.Element");
+dojo.require("dojox.charting.axis2d.common");
+dojo.require("dojox.charting.plot2d.common");
+
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.gfx");
+
+(function(){
+ var df = dojox.lang.functional, du = dojox.lang.utils,
+ dc = dojox.charting.plot2d.common,
+ da = dojox.charting.axis2d.common,
+ g = dojox.gfx;
+
+ dojo.declare("dojox.charting.plot2d.Pie", dojox.charting.Element, {
+ defaultParams: {
+ labels: true,
+ ticks: false,
+ fixed: true,
+ precision: 1,
+ labelOffset: 20,
+ labelStyle: "default", // default/rows/auto
+ htmlLabels: true // use HTML to draw labels
+ },
+ optionalParams: {
+ font: "",
+ fontColor: "",
+ radius: 0
+ },
+
+ constructor: function(chart, kwArgs){
+ this.opt = dojo.clone(this.defaultParams);
+ du.updateWithObject(this.opt, kwArgs);
+ du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+ this.run = null;
+ this.dyn = [];
+ },
+ clear: function(){
+ this.dirty = true;
+ this.dyn = [];
+ return this;
+ },
+ setAxis: function(axis){
+ // nothing
+ return this;
+ },
+ addSeries: function(run){
+ this.run = run;
+ return this;
+ },
+ calculateAxes: function(dim){
+ // nothing
+ return this;
+ },
+ getRequiredColors: function(){
+ return this.run ? this.run.data.length : 0;
+ },
+ render: function(dim, offsets){
+ if(!this.dirty){ return this; }
+ this.dirty = false;
+ this.cleanGroup();
+ var s = this.group, color, t = this.chart.theme;
+
+ // calculate the geometry
+ var rx = (dim.width - offsets.l - offsets.r) / 2,
+ ry = (dim.height - offsets.t - offsets.b) / 2,
+ r = Math.min(rx, ry),
+ taFont = "font" in this.opt ? this.opt.font : t.axis.font,
+ size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
+ taFontColor = "fontColor" in this.opt ? this.opt.fontColor : t.axis.fontColor,
+ start = 0, step, sum, slices, labels, shift, labelR,
+ run = this.run.data;
+ if(typeof run[0] == "number"){
+ sum = df.foldl1(run, "+");
+ slices = dojo.map(run, function(x){ return x / sum; });
+ if(this.opt.labels){
+ labels = dojo.map(slices, function(x){
+ return this._getLabel(x * 100) + "%";
+ }, this);
+ }
+ }else{
+ sum = df.foldl1(run, function(a, b){ return {y: a.y + b.y}; }).y;
+ slices = df.map(run, function(x){ return x.y / sum; });
+ if(this.opt.labels){
+ labels = dojo.map(slices, function(x, i){
+ var v = run[i];
+ return "text" in v ? v.text : this._getLabel(x * 100) + "%";
+ }, this);
+ }
+ }
+ if(this.opt.labels){
+ shift = df.foldl1(df.map(labels, function(label){
+ return dojox.gfx._base._getTextBox(label, {font: taFont}).w;
+ }, this), "Math.max(a, b)") / 2;
+ if(this.opt.labelOffset < 0){
+ r = Math.min(rx - 2 * shift, ry - size) + this.opt.labelOffset;
+ }
+ labelR = r - this.opt.labelOffset;
+ }
+ if("radius" in this.opt){
+ r = this.opt.radius;
+ labelR = r - this.opt.labelOffset;
+ }
+ var circle = {
+ cx: offsets.l + rx,
+ cy: offsets.t + ry,
+ r: r
+ };
+
+ this.dyn = [];
+ if(!this.run || !run.length){
+ return this;
+ }
+ if(run.length == 1){
+ // need autogenerated color
+ color = new dojo.Color(t.next("color"));
+ var shape = s.createCircle(circle).
+ setFill(dc.augmentFill(t.run.fill, color)).
+ setStroke(dc.augmentStroke(t.series.stroke, color));
+ this.dyn.push({color: color, fill: shape.getFill(), stroke: shape.getStroke()});
+ if(this.opt.labels){
+ // draw the label
+ var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"]
+ (this.chart, s, circle.cx, circle.cy + size / 2, "middle",
+ "100%", taFont, taFontColor);
+ if(this.opt.htmlLabels){ this.htmlElements.push(elem); }
+ }
+ return this;
+ }
+ // draw slices
+ dojo.forEach(slices, function(x, i){
+ // calculate the geometry of the slice
+ var end = start + x * 2 * Math.PI, v = run[i];
+ if(i + 1 == slices.length){
+ end = 2 * Math.PI;
+ }
+ var step = end - start,
+ x1 = circle.cx + r * Math.cos(start),
+ y1 = circle.cy + r * Math.sin(start),
+ x2 = circle.cx + r * Math.cos(end),
+ y2 = circle.cy + r * Math.sin(end);
+ // draw the slice
+ var color, fill, stroke;
+ if(typeof v == "object"){
+ color = "color" in v ? v.color : new dojo.Color(t.next("color"));
+ fill = "fill" in v ? v.fill : dc.augmentFill(t.series.fill, color);
+ stroke = "stroke" in v ? v.stroke : dc.augmentStroke(t.series.stroke, color);
+ }else{
+ color = new dojo.Color(t.next("color"));
+ fill = dc.augmentFill(t.series.fill, color);
+ stroke = dc.augmentStroke(t.series.stroke, color);
+ }
+ var shape = s.createPath({}).
+ moveTo(circle.cx, circle.cy).
+ lineTo(x1, y1).
+ arcTo(r, r, 0, step > Math.PI, true, x2, y2).
+ lineTo(circle.cx, circle.cy).
+ closePath().
+ setFill(fill).
+ setStroke(stroke);
+ this.dyn.push({color: color, fill: fill, stroke: stroke});
+ start = end;
+ }, this);
+ // draw labels
+ if(this.opt.labels){
+ start = 0;
+ dojo.forEach(slices, function(slice, i){
+ // calculate the geometry of the slice
+ var end = start + slice * 2 * Math.PI, v = run[i];
+ if(i + 1 == slices.length){
+ end = 2 * Math.PI;
+ }
+ var labelAngle = (start + end) / 2,
+ x = circle.cx + labelR * Math.cos(labelAngle),
+ y = circle.cy + labelR * Math.sin(labelAngle) + size / 2;
+ // draw the label
+ var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"]
+ (this.chart, s, x, y, "middle",
+ labels[i], taFont,
+ (typeof v == "object" && "fontColor" in v)
+ ? v.fontColor : taFontColor);
+ if(this.opt.htmlLabels){ this.htmlElements.push(elem); }
+ start = end;
+ }, this);
+ }
+ return this;
+ },
+
+ // utilities
+ _getLabel: function(number){
+ return this.opt.fixed ? number.toFixed(this.opt.precision) : number.toString();
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Scatter.js b/includes/js/dojox/charting/plot2d/Scatter.js
new file mode 100644
index 0000000..d307cb1
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Scatter.js
@@ -0,0 +1,14 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Scatter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Scatter"] = true;
+dojo.provide("dojox.charting.plot2d.Scatter");
+
+dojo.require("dojox.charting.plot2d.Default");
+
+dojo.declare("dojox.charting.plot2d.Scatter", dojox.charting.plot2d.Default, {
+ constructor: function(){
+ this.opt.lines = false;
+ this.opt.markers = true;
+ }
+});
+
+}
diff --git a/includes/js/dojox/charting/plot2d/Stacked.js b/includes/js/dojox/charting/plot2d/Stacked.js
new file mode 100644
index 0000000..0e26a75
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/Stacked.js
@@ -0,0 +1,160 @@
+if(!dojo._hasResource["dojox.charting.plot2d.Stacked"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Stacked"] = true;
+dojo.provide("dojox.charting.plot2d.Stacked");
+
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Default");
+
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.sequence");
+dojo.require("dojox.lang.functional.reversed");
+
+(function(){
+ var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+ purgeGroup = df.lambda("item.purgeGroup()");
+
+ dojo.declare("dojox.charting.plot2d.Stacked", dojox.charting.plot2d.Default, {
+ calculateAxes: function(dim){
+ var stats = dc.collectStackedStats(this.series);
+ this._maxRunLength = stats.hmax;
+ this._calc(dim, stats);
+ return this;
+ },
+ render: function(dim, offsets){
+ // stack all values
+ var acc = df.repeat(this._maxRunLength, "-> 0", 0);
+ for(var i = 0; i < this.series.length; ++i){
+ var run = this.series[i];
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j];
+ if(isNaN(v)){ v = 0; }
+ acc[j] += v;
+ }
+ }
+ // draw runs in backwards
+ if(this.dirty){
+ dojo.forEach(this.series, purgeGroup);
+ this.cleanGroup();
+ var s = this.group;
+ df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+ }
+
+ // inner function for translating polylines to curves with tension
+ function curve(arr, tension){
+ var p=dojo.map(arr, function(item, i){
+ if(i==0){ return "M" + item.x + "," + item.y; }
+ var dx=item.x-arr[i-1].x, dy=arr[i-1].y;
+ return "C"+(item.x-(tension-1)*(dx/tension))+","+dy+" "+(item.x-(dx/tension))+","+item.y+" "+item.x+","+item.y;
+ });
+ return p.join(" ");
+ }
+
+ var t = this.chart.theme, stroke, outline, color, marker;
+ for(var i = this.series.length - 1; i >= 0; --i){
+ var run = this.series[i];
+ if(!this.dirty && !run.dirty){ continue; }
+ run.cleanGroup();
+ var s = run.group,
+ lpoly = dojo.map(acc, function(v, i){
+ return {
+ x: this._hScaler.scale * (i + 1 - this._hScaler.bounds.lower) + offsets.l,
+ y: dim.height - offsets.b - this._vScaler.scale * (v - this._vScaler.bounds.lower)
+ };
+ }, this);
+ if(!run.fill || !run.stroke){
+ // need autogenerated color
+ color = new dojo.Color(t.next("color"));
+ }
+
+ var lpath="";
+ if(this.opt.tension){
+ lpath=curve(lpoly, this.opt.tension);
+ }
+
+ if(this.opt.areas){
+ var apoly = dojo.clone(lpoly);
+ var fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+ if(this.opt.tension){
+ var p=curve(apoly, this.opt.tension);
+ p += " L" + lpoly[lpoly.length-1].x + "," + (dim.height - offsets.b) + " "
+ + "L" + lpoly[0].x + "," + (dim.height - offsets.b) + " "
+ + "L" + lpoly[0].x + "," + lpoly[0].y;
+ s.createPath(p).setFill(fill);
+ } else {
+ apoly.push({x: lpoly[lpoly.length - 1].x, y: dim.height - offsets.b});
+ apoly.push({x: lpoly[0].x, y: dim.height - offsets.b});
+ apoly.push(lpoly[0]);
+ s.createPolyline(apoly).setFill(fill);
+ }
+ }
+ if(this.opt.lines || this.opt.markers){
+ // need a stroke
+ stroke = run.stroke ? dc.makeStroke(run.stroke) : dc.augmentStroke(t.series.stroke, color);
+ if(run.outline || t.series.outline){
+ outline = dc.makeStroke(run.outline ? run.outline : t.series.outline);
+ outline.width = 2 * outline.width + stroke.width;
+ }
+ }
+ if(this.opt.markers){
+ // need a marker
+ marker = run.marker ? run.marker : t.next("marker");
+ }
+ if(this.opt.shadows && stroke){
+ var sh = this.opt.shadows, shadowColor = new dojo.Color([0, 0, 0, 0.3]),
+ spoly = dojo.map(lpoly, function(c){
+ return {x: c.x + sh.dx, y: c.y + sh.dy};
+ }),
+ shadowStroke = dojo.clone(outline ? outline : stroke);
+ shadowStroke.color = shadowColor;
+ shadowStroke.width += sh.dw ? sh.dw : 0;
+ if(this.opt.lines){
+ if(this.opt.tension){
+ s.createPath(curve(spoly, this.opt.tension)).setStroke(shadowStroke);
+ } else {
+ s.createPolyline(spoly).setStroke(shadowStroke);
+ }
+ }
+ if(this.opt.markers){
+ dojo.forEach(spoly, function(c){
+ s.createPath("M" + c.x + " " + c.y + " " + marker).setStroke(shadowStroke).setFill(shadowColor);
+ }, this);
+ }
+ }
+ if(this.opt.lines){
+ if(outline){
+ if(this.opt.tension){
+ s.createPath(lpath).setStroke(outline);
+ } else {
+ s.createPolyline(lpoly).setStroke(outline);
+ }
+ }
+ if(this.opt.tension){
+ s.createPath(lpath).setStroke(stroke);
+ } else {
+ s.createPolyline(lpoly).setStroke(stroke);
+ }
+ }
+ if(this.opt.markers){
+ dojo.forEach(lpoly, function(c){
+ var path = "M" + c.x + " " + c.y + " " + marker;
+ if(outline){
+ s.createPath(path).setStroke(outline);
+ }
+ s.createPath(path).setStroke(stroke).setFill(stroke.color);
+ }, this);
+ }
+ run.dirty = false;
+ // update the accumulator
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j];
+ if(isNaN(v)){ v = 0; }
+ acc[j] -= v;
+ }
+ }
+ this.dirty = false;
+ return this;
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/StackedAreas.js b/includes/js/dojox/charting/plot2d/StackedAreas.js
new file mode 100644
index 0000000..7bfd255
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/StackedAreas.js
@@ -0,0 +1,14 @@
+if(!dojo._hasResource["dojox.charting.plot2d.StackedAreas"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.StackedAreas"] = true;
+dojo.provide("dojox.charting.plot2d.StackedAreas");
+
+dojo.require("dojox.charting.plot2d.Stacked");
+
+dojo.declare("dojox.charting.plot2d.StackedAreas", dojox.charting.plot2d.Stacked, {
+ constructor: function(){
+ this.opt.lines = true;
+ this.opt.areas = true;
+ }
+});
+
+}
diff --git a/includes/js/dojox/charting/plot2d/StackedBars.js b/includes/js/dojox/charting/plot2d/StackedBars.js
new file mode 100644
index 0000000..e5c9c22
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/StackedBars.js
@@ -0,0 +1,85 @@
+if(!dojo._hasResource["dojox.charting.plot2d.StackedBars"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.StackedBars"] = true;
+dojo.provide("dojox.charting.plot2d.StackedBars");
+
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Bars");
+
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+
+(function(){
+ var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+ purgeGroup = df.lambda("item.purgeGroup()");
+
+ dojo.declare("dojox.charting.plot2d.StackedBars", dojox.charting.plot2d.Bars, {
+ calculateAxes: function(dim){
+ var stats = dc.collectStackedStats(this.series), t;
+ this._maxRunLength = stats.hmax;
+ stats.hmin -= 0.5;
+ stats.hmax += 0.5;
+ t = stats.hmin, stats.hmin = stats.vmin, stats.vmin = t;
+ t = stats.hmax, stats.hmax = stats.vmax, stats.vmax = t;
+ this._calc(dim, stats);
+ return this;
+ },
+ render: function(dim, offsets){
+ // stack all values
+ var acc = df.repeat(this._maxRunLength, "-> 0", 0);
+ for(var i = 0; i < this.series.length; ++i){
+ var run = this.series[i];
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j];
+ if(isNaN(v)){ v = 0; }
+ acc[j] += v;
+ }
+ }
+ // draw runs in backwards
+ if(this.dirty){
+ dojo.forEach(this.series, purgeGroup);
+ this.cleanGroup();
+ var s = this.group;
+ df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+ }
+ var t = this.chart.theme, color, stroke, fill, f,
+ gap = this.opt.gap < this._vScaler.scale / 3 ? this.opt.gap : 0;
+ for(var i = this.series.length - 1; i >= 0; --i){
+ var run = this.series[i];
+ if(!this.dirty && !run.dirty){ continue; }
+ run.cleanGroup();
+ var s = run.group;
+ if(!run.fill || !run.stroke){
+ // need autogenerated color
+ color = run.dyn.color = new dojo.Color(t.next("color"));
+ }
+ stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+ fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+ for(var j = 0; j < acc.length; ++j){
+ var v = acc[j],
+ width = this._hScaler.scale * (v - this._hScaler.bounds.lower),
+ height = this._vScaler.scale - 2 * gap;
+ if(width >= 1 && height >= 1){
+ var shape = s.createRect({
+ x: offsets.l,
+ y: dim.height - offsets.b - this._vScaler.scale * (j + 1.5 - this._vScaler.bounds.lower) + gap,
+ width: width, height: height
+ }).setFill(fill).setStroke(stroke);
+ run.dyn.fill = shape.getFill();
+ run.dyn.stroke = shape.getStroke();
+ }
+ }
+ run.dirty = false;
+ // update the accumulator
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j];
+ if(isNaN(v)){ v = 0; }
+ acc[j] -= v;
+ }
+ }
+ this.dirty = false;
+ return this;
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/StackedColumns.js b/includes/js/dojox/charting/plot2d/StackedColumns.js
new file mode 100644
index 0000000..15fd141
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/StackedColumns.js
@@ -0,0 +1,83 @@
+if(!dojo._hasResource["dojox.charting.plot2d.StackedColumns"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.StackedColumns"] = true;
+dojo.provide("dojox.charting.plot2d.StackedColumns");
+
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Columns");
+
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+
+(function(){
+ var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+ purgeGroup = df.lambda("item.purgeGroup()");
+
+ dojo.declare("dojox.charting.plot2d.StackedColumns", dojox.charting.plot2d.Columns, {
+ calculateAxes: function(dim){
+ var stats = dc.collectStackedStats(this.series);
+ this._maxRunLength = stats.hmax;
+ stats.hmin -= 0.5;
+ stats.hmax += 0.5;
+ this._calc(dim, stats);
+ return this;
+ },
+ render: function(dim, offsets){
+ // stack all values
+ var acc = df.repeat(this._maxRunLength, "-> 0", 0);
+ for(var i = 0; i < this.series.length; ++i){
+ var run = this.series[i];
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j];
+ if(isNaN(v)){ v = 0; }
+ acc[j] += v;
+ }
+ }
+ // draw runs in backwards
+ if(this.dirty){
+ dojo.forEach(this.series, purgeGroup);
+ this.cleanGroup();
+ var s = this.group;
+ df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+ }
+ var t = this.chart.theme, color, stroke, fill, f,
+ gap = this.opt.gap < this._hScaler.scale / 3 ? this.opt.gap : 0;
+ for(var i = this.series.length - 1; i >= 0; --i){
+ var run = this.series[i];
+ if(!this.dirty && !run.dirty){ continue; }
+ run.cleanGroup();
+ var s = run.group;
+ if(!run.fill || !run.stroke){
+ // need autogenerated color
+ color = run.dyn.color = new dojo.Color(t.next("color"));
+ }
+ stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+ fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+ for(var j = 0; j < acc.length; ++j){
+ var v = acc[j],
+ width = this._hScaler.scale - 2 * gap,
+ height = this._vScaler.scale * (v - this._vScaler.bounds.lower);
+ if(width >= 1 && height >= 1){
+ var shape = s.createRect({
+ x: offsets.l + this._hScaler.scale * (j + 0.5 - this._hScaler.bounds.lower) + gap,
+ y: dim.height - offsets.b - this._vScaler.scale * (v - this._vScaler.bounds.lower),
+ width: width, height: height
+ }).setFill(fill).setStroke(stroke);
+ run.dyn.fill = shape.getFill();
+ run.dyn.stroke = shape.getStroke();
+ }
+ }
+ run.dirty = false;
+ // update the accumulator
+ for(var j = 0; j < run.data.length; ++j){
+ var v = run.data[j];
+ if(isNaN(v)){ v = 0; }
+ acc[j] -= v;
+ }
+ }
+ this.dirty = false;
+ return this;
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/charting/plot2d/StackedLines.js b/includes/js/dojox/charting/plot2d/StackedLines.js
new file mode 100644
index 0000000..2581b85
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/StackedLines.js
@@ -0,0 +1,13 @@
+if(!dojo._hasResource["dojox.charting.plot2d.StackedLines"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.StackedLines"] = true;
+dojo.provide("dojox.charting.plot2d.StackedLines");
+
+dojo.require("dojox.charting.plot2d.Stacked");
+
+dojo.declare("dojox.charting.plot2d.StackedLines", dojox.charting.plot2d.Stacked, {
+ constructor: function(){
+ this.opt.lines = true;
+ }
+});
+
+}
diff --git a/includes/js/dojox/charting/plot2d/common.js b/includes/js/dojox/charting/plot2d/common.js
new file mode 100644
index 0000000..de60020
--- /dev/null
+++ b/includes/js/dojox/charting/plot2d/common.js
@@ -0,0 +1,113 @@
+if(!dojo._hasResource["dojox.charting.plot2d.common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.common"] = true;
+dojo.provide("dojox.charting.plot2d.common");
+
+dojo.require("dojo.colors");
+dojo.require("dojox.gfx");
+dojo.require("dojox.lang.functional");
+
+(function(){
+ var df = dojox.lang.functional, dc = dojox.charting.plot2d.common;
+
+ dojo.mixin(dojox.charting.plot2d.common, {
+ makeStroke: function(stroke){
+ if(!stroke){ return stroke; }
+ if(typeof stroke == "string" || stroke instanceof dojo.Color){
+ stroke = {color: stroke};
+ }
+ return dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
+ },
+ augmentColor: function(target, color){
+ var t = new dojo.Color(target),
+ c = new dojo.Color(color);
+ c.a = t.a;
+ return c;
+ },
+ augmentStroke: function(stroke, color){
+ var s = dc.makeStroke(stroke);
+ if(s){
+ s.color = dc.augmentColor(s.color, color);
+ }
+ return s;
+ },
+ augmentFill: function(fill, color){
+ var fc, c = new dojo.Color(color);
+ if(typeof fill == "string" || fill instanceof dojo.Color){
+ return dc.augmentColor(fill, color);
+ }
+ return fill;
+ },
+
+ defaultStats: {hmin: Number.POSITIVE_INFINITY, hmax: Number.NEGATIVE_INFINITY,
+ vmin: Number.POSITIVE_INFINITY, vmax: Number.NEGATIVE_INFINITY},
+
+ collectSimpleStats: function(series){
+ var stats = dojo.clone(dc.defaultStats);
+ for(var i = 0; i < series.length; ++i){
+ var run = series[i];
+ if(!run.data.length){ continue; }
+ if(typeof run.data[0] == "number"){
+ // 1D case
+ var old_vmin = stats.vmin, old_vmax = stats.vmax;
+ if(!("ymin" in run) || !("ymax" in run)){
+ dojo.forEach(run.data, function(val, i){
+ var x = i + 1, y = val;
+ if(isNaN(y)){ y = 0; }
+ stats.hmin = Math.min(stats.hmin, x);
+ stats.hmax = Math.max(stats.hmax, x);
+ stats.vmin = Math.min(stats.vmin, y);
+ stats.vmax = Math.max(stats.vmax, y);
+ });
+ }
+ if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
+ if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
+ }else{
+ // 2D case
+ var old_hmin = stats.hmin, old_hmax = stats.hmax,
+ old_vmin = stats.vmin, old_vmax = stats.vmax;
+ if(!("xmin" in run) || !("xmax" in run) || !("ymin" in run) || !("ymax" in run)){
+ dojo.forEach(run.data, function(val, i){
+ var x = val.x, y = val.y;
+ if(isNaN(x)){ x = 0; }
+ if(isNaN(y)){ y = 0; }
+ stats.hmin = Math.min(stats.hmin, x);
+ stats.hmax = Math.max(stats.hmax, x);
+ stats.vmin = Math.min(stats.vmin, y);
+ stats.vmax = Math.max(stats.vmax, y);
+ });
+ }
+ if("xmin" in run){ stats.hmin = Math.min(old_hmin, run.xmin); }
+ if("xmax" in run){ stats.hmax = Math.max(old_hmax, run.xmax); }
+ if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
+ if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
+ }
+ }
+ return stats;
+ },
+
+ collectStackedStats: function(series){
+ // collect statistics
+ var stats = dojo.clone(dc.defaultStats);
+ if(series.length){
+ // 1st pass: find the maximal length of runs
+ stats.hmin = Math.min(stats.hmin, 1);
+ stats.hmax = df.foldl(series, "seed, run -> Math.max(seed, run.data.length)", stats.hmax);
+ // 2nd pass: stack values
+ for(var i = 0; i < stats.hmax; ++i){
+ var v = series[0].data[i];
+ if(isNaN(v)){ v = 0; }
+ stats.vmin = Math.min(stats.vmin, v);
+ for(var j = 1; j < series.length; ++j){
+ var t = series[j].data[i];
+ if(isNaN(t)){ t = 0; }
+ v += t;
+ }
+ stats.vmax = Math.max(stats.vmax, v);
+ }
+ }
+ return stats;
+ }
+ });
+})();
+
+}