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){ if(this._maxRunLength <= 0){ return this; } // 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 this.dirty = this.isDirty(); 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, events = this.events(), ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler), vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler); this.resetEvents(); 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: ht(i + 1) + offsets.l, y: dim.height - offsets.b - vt(v) }; }, this); if(!run.fill || !run.stroke){ // need autogenerated color color = new dojo.Color(t.next("color")); } var lpath = this.opt.tension ? dc.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=dc.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; run.dyn.fill = s.createPath(p).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"); } var frontMarkers, outlineMarkers, shadowMarkers; 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){ run.dyn.shadow = s.createPath(dc.curve(spoly, this.opt.tension)).setStroke(shadowStroke).getStroke(); } else { run.dyn.shadow = s.createPolyline(spoly).setStroke(shadowStroke).getStroke(); } } if(this.opt.markers){ shadowMarkers = dojo.map(spoly, function(c){ return 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){ frontMarkers = new Array(lpoly.length); outlineMarkers = new Array(lpoly.length); dojo.forEach(lpoly, function(c, i){ var path = "M" + c.x + " " + c.y + " " + marker; if(outline){ outlineMarkers[i] = s.createPath(path).setStroke(outline); } frontMarkers[i] = s.createPath(path).setStroke(stroke).setFill(stroke.color); }, this); if(events){ dojo.forEach(frontMarkers, function(s, i){ var o = { element: "marker", index: i, run: run, plot: this, hAxis: this.hAxis || null, vAxis: this.vAxis || null, shape: s, outline: outlineMarkers[i] || null, shadow: shadowMarkers && shadowMarkers[i] || null, cx: lpoly[i].x, cy: lpoly[i].y, x: i + 1, y: run.data[i] }; this._connectEvents(s, o); }, 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; } }); })();