source: Dev/branches/rest-dojo-ui/client/dojox/charting/plot2d/Stacked.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 6.4 KB
Line 
1define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "./Default", "./common",
2        "dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/functional/sequence"],
3        function(lang, declare, arr, Default, dc, df, dfr, dfs){
4/*=====
5var Default = dojox.charting.plot2d.Default;
6=====*/
7        var purgeGroup = dfr.lambda("item.purgeGroup()");
8
9        return declare("dojox.charting.plot2d.Stacked", Default, {
10                //      summary:
11                //              Like the default plot, Stacked sets up lines, areas and markers
12                //              in a stacked fashion (values on the y axis added to each other)
13                //              as opposed to a direct one.
14                getSeriesStats: function(){
15                        //      summary:
16                        //              Calculate the min/max on all attached series in both directions.
17                        //      returns: Object
18                        //              {hmin, hmax, vmin, vmax} min/max in both directions.
19                        var stats = dc.collectStackedStats(this.series);
20                        this._maxRunLength = stats.hmax;
21                        return stats;
22                },
23                render: function(dim, offsets){
24                        //      summary:
25                        //              Run the calculations for any axes for this plot.
26                        //      dim: Object
27                        //              An object in the form of { width, height }
28                        //      offsets: Object
29                        //              An object of the form { l, r, t, b}.
30                        //      returns: dojox.charting.plot2d.Stacked
31                        //              A reference to this plot for functional chaining.
32                        if(this._maxRunLength <= 0){
33                                return this;
34                        }
35
36                        // stack all values
37                        var acc = df.repeat(this._maxRunLength, "-> 0", 0);
38                        for(var i = 0; i < this.series.length; ++i){
39                                var run = this.series[i];
40                                for(var j = 0; j < run.data.length; ++j){
41                                        var v = run.data[j];
42                                        if(v !== null){
43                                                if(isNaN(v)){ v = 0; }
44                                                acc[j] += v;
45                                        }
46                                }
47                        }
48                        // draw runs in backwards
49                        if(this.zoom && !this.isDataDirty()){
50                                return this.performZoom(dim, offsets);
51                        }
52                        this.resetEvents();
53                        this.dirty = this.isDirty();
54                        if(this.dirty){
55                                arr.forEach(this.series, purgeGroup);
56                                this._eventSeries = {};
57                                this.cleanGroup();
58                                var s = this.group;
59                                df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
60                        }
61
62                        var t = this.chart.theme, events = this.events(),
63                                ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
64                                vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler);
65
66                        for(var i = this.series.length - 1; i >= 0; --i){
67                                var run = this.series[i];
68                                if(!this.dirty && !run.dirty){
69                                        t.skip();
70                                        this._reconnectEvents(run.name);
71                                        continue;
72                                }
73                                run.cleanGroup();
74                                var theme = t.next(this.opt.areas ? "area" : "line", [this.opt, run], true),
75                                        s = run.group, outline,
76                                        lpoly = arr.map(acc, function(v, i){
77                                                return {
78                                                        x: ht(i + 1) + offsets.l,
79                                                        y: dim.height - offsets.b - vt(v)
80                                                };
81                                        }, this);
82
83                                var lpath = this.opt.tension ? dc.curve(lpoly, this.opt.tension) : "";
84
85                                if(this.opt.areas){
86                                        var apoly = lang.clone(lpoly);
87                                        if(this.opt.tension){
88                                                var p=dc.curve(apoly, this.opt.tension);
89                                                p += " L" + lpoly[lpoly.length - 1].x + "," + (dim.height - offsets.b) +
90                                                        " L" + lpoly[0].x + "," + (dim.height - offsets.b) +
91                                                        " L" + lpoly[0].x + "," + lpoly[0].y;
92                                                run.dyn.fill = s.createPath(p).setFill(theme.series.fill).getFill();
93                                        } else {
94                                                apoly.push({x: lpoly[lpoly.length - 1].x, y: dim.height - offsets.b});
95                                                apoly.push({x: lpoly[0].x, y: dim.height - offsets.b});
96                                                apoly.push(lpoly[0]);
97                                                run.dyn.fill = s.createPolyline(apoly).setFill(theme.series.fill).getFill();
98                                        }
99                                }
100                                if(this.opt.lines || this.opt.markers){
101                                        if(theme.series.outline){
102                                                outline = dc.makeStroke(theme.series.outline);
103                                                outline.width = 2 * outline.width + theme.series.stroke.width;
104                                        }
105                                }
106                                if(this.opt.markers){
107                                        run.dyn.marker = theme.symbol;
108                                }
109                                var frontMarkers, outlineMarkers, shadowMarkers;
110                                if(theme.series.shadow && theme.series.stroke){
111                                        var shadow = theme.series.shadow,
112                                                spoly = arr.map(lpoly, function(c){
113                                                        return {x: c.x + shadow.dx, y: c.y + shadow.dy};
114                                                });
115                                        if(this.opt.lines){
116                                                if(this.opt.tension){
117                                                        run.dyn.shadow = s.createPath(dc.curve(spoly, this.opt.tension)).setStroke(shadow).getStroke();
118                                                } else {
119                                                        run.dyn.shadow = s.createPolyline(spoly).setStroke(shadow).getStroke();
120                                                }
121                                        }
122                                        if(this.opt.markers){
123                                                shadow = theme.marker.shadow;
124                                                shadowMarkers = arr.map(spoly, function(c){
125                                                        return s.createPath("M" + c.x + " " + c.y + " " + theme.symbol).
126                                                                setStroke(shadow).setFill(shadow.color);
127                                                }, this);
128                                        }
129                                }
130                                if(this.opt.lines){
131                                        if(outline){
132                                                if(this.opt.tension){
133                                                        run.dyn.outline = s.createPath(lpath).setStroke(outline).getStroke();
134                                                } else {
135                                                        run.dyn.outline = s.createPolyline(lpoly).setStroke(outline).getStroke();
136                                                }
137                                        }
138                                        if(this.opt.tension){
139                                                run.dyn.stroke = s.createPath(lpath).setStroke(theme.series.stroke).getStroke();
140                                        } else {
141                                                run.dyn.stroke = s.createPolyline(lpoly).setStroke(theme.series.stroke).getStroke();
142                                        }
143                                }
144                                if(this.opt.markers){
145                                        frontMarkers = new Array(lpoly.length);
146                                        outlineMarkers = new Array(lpoly.length);
147                                        outline = null;
148                                        if(theme.marker.outline){
149                                                outline = dc.makeStroke(theme.marker.outline);
150                                                outline.width = 2 * outline.width + (theme.marker.stroke ? theme.marker.stroke.width : 0);
151                                        }
152                                        arr.forEach(lpoly, function(c, i){
153                                                var path = "M" + c.x + " " + c.y + " " + theme.symbol;
154                                                if(outline){
155                                                        outlineMarkers[i] = s.createPath(path).setStroke(outline);
156                                                }
157                                                frontMarkers[i] = s.createPath(path).setStroke(theme.marker.stroke).setFill(theme.marker.fill);
158                                        }, this);
159                                        if(events){
160                                                var eventSeries = new Array(frontMarkers.length);
161                                                arr.forEach(frontMarkers, function(s, i){
162                                                        var o = {
163                                                                element: "marker",
164                                                                index:   i,
165                                                                run:     run,
166                                                                shape:   s,
167                                                                outline: outlineMarkers[i] || null,
168                                                                shadow:  shadowMarkers && shadowMarkers[i] || null,
169                                                                cx:      lpoly[i].x,
170                                                                cy:      lpoly[i].y,
171                                                                x:       i + 1,
172                                                                y:       run.data[i]
173                                                        };
174                                                        this._connectEvents(o);
175                                                        eventSeries[i] = o;
176                                                }, this);
177                                                this._eventSeries[run.name] = eventSeries;
178                                        }else{
179                                                delete this._eventSeries[run.name];
180                                        }
181                                }
182                                run.dirty = false;
183                                // update the accumulator
184                                for(var j = 0; j < run.data.length; ++j){
185                                        var v = run.data[j];
186                                        if(v !== null){
187                                                if(isNaN(v)){ v = 0; }
188                                                acc[j] -= v;
189                                        }
190                                }
191                        }
192                        this.dirty = false;
193                        return this;    //      dojox.charting.plot2d.Stacked
194                }
195        });
196});
Note: See TracBrowser for help on using the repository browser.