From e44a7e37b6c7b5961adaffc62b9042b8d442938e Mon Sep 17 00:00:00 2001 From: mensonge Date: Thu, 13 Nov 2008 09:49:11 +0000 Subject: New feature: basic Ajax suggestion for tags and implementation of Dojo toolkit git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@151 b3834d28-1941-0410-a4f8-b48e95affb8f --- includes/js/dojox/charting/plot2d/Areas.js | 14 ++ includes/js/dojox/charting/plot2d/Bars.js | 89 +++++++++ includes/js/dojox/charting/plot2d/Base.js | 60 +++++++ includes/js/dojox/charting/plot2d/ClusteredBars.js | 63 +++++++ .../js/dojox/charting/plot2d/ClusteredColumns.js | 63 +++++++ includes/js/dojox/charting/plot2d/Columns.js | 88 +++++++++ includes/js/dojox/charting/plot2d/Default.js | 173 ++++++++++++++++++ includes/js/dojox/charting/plot2d/Grid.js | 116 ++++++++++++ includes/js/dojox/charting/plot2d/Lines.js | 13 ++ includes/js/dojox/charting/plot2d/Markers.js | 13 ++ includes/js/dojox/charting/plot2d/MarkersOnly.js | 14 ++ includes/js/dojox/charting/plot2d/Pie.js | 199 +++++++++++++++++++++ includes/js/dojox/charting/plot2d/Scatter.js | 14 ++ includes/js/dojox/charting/plot2d/Stacked.js | 160 +++++++++++++++++ includes/js/dojox/charting/plot2d/StackedAreas.js | 14 ++ includes/js/dojox/charting/plot2d/StackedBars.js | 85 +++++++++ .../js/dojox/charting/plot2d/StackedColumns.js | 83 +++++++++ includes/js/dojox/charting/plot2d/StackedLines.js | 13 ++ includes/js/dojox/charting/plot2d/common.js | 113 ++++++++++++ 19 files changed, 1387 insertions(+) create mode 100644 includes/js/dojox/charting/plot2d/Areas.js create mode 100644 includes/js/dojox/charting/plot2d/Bars.js create mode 100644 includes/js/dojox/charting/plot2d/Base.js create mode 100644 includes/js/dojox/charting/plot2d/ClusteredBars.js create mode 100644 includes/js/dojox/charting/plot2d/ClusteredColumns.js create mode 100644 includes/js/dojox/charting/plot2d/Columns.js create mode 100644 includes/js/dojox/charting/plot2d/Default.js create mode 100644 includes/js/dojox/charting/plot2d/Grid.js create mode 100644 includes/js/dojox/charting/plot2d/Lines.js create mode 100644 includes/js/dojox/charting/plot2d/Markers.js create mode 100644 includes/js/dojox/charting/plot2d/MarkersOnly.js create mode 100644 includes/js/dojox/charting/plot2d/Pie.js create mode 100644 includes/js/dojox/charting/plot2d/Scatter.js create mode 100644 includes/js/dojox/charting/plot2d/Stacked.js create mode 100644 includes/js/dojox/charting/plot2d/StackedAreas.js create mode 100644 includes/js/dojox/charting/plot2d/StackedBars.js create mode 100644 includes/js/dojox/charting/plot2d/StackedColumns.js create mode 100644 includes/js/dojox/charting/plot2d/StackedLines.js create mode 100644 includes/js/dojox/charting/plot2d/common.js (limited to 'includes/js/dojox/charting/plot2d') 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; + } + }); +})(); + +} -- cgit v1.2.3-54-g00ecf