source: Dev/trunk/src/client/dojox/charting/plot2d/Grid.js @ 531

Last change on this file since 531 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 12.1 KB
Line 
1define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/sniff",
2                "./CartesianBase", "./common", "dojox/lang/utils", "dojox/gfx/fx"],
3        function(lang, declare, arr, has, CartesianBase, dc, du, fx){
4
5        var sortTicks = function(a,b){return a.value - b.value};
6
7        /*=====
8        declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__CartesianCtorArgs, {
9                // summary:
10                //              A special keyword arguments object that is specific to a grid "plot".
11
12                // majorHLine: dojox.gfx.Stroke?
13                //              An optional dojox.gfx.Stroke for a major horizontal line. By default major lines use major tick stroke.
14                majorHLine:undefined,
15
16                // minorHLine: dojox.gfx.Stroke?
17                //              An optional dojox.gfx.Stroke for a minor horizontal line. By default minor lines use minor tick stroke.
18                minorHLine:undefined,
19
20                // majorVLine: dojox.gfx.Stroke?
21                //              An optional dojox.gfx.Stroke for a major vertical line. By default major lines use major tick stroke.
22                majorVLine:undefined,
23
24                // minorVLine: dojox.gfx.Stroke?
25                //              An optional dojox.gfx.Stroke for a minor vertical line. By default major lines use major tick stroke.
26                minorVLine:undefined,
27
28                // hFill: dojox.gfx.Fill?
29                //              An optional dojox.gfx.Fill used to fill every other horizontal stripe created by grid lines.
30                hFill: undefined,
31
32                // hAlternateFill: dojox.gfx.Fill?
33                //              An optional dojox.gfx.Fill used to fill alternating horizontal stripe created by grid lines not filled by `hFill`.
34                hAlternateFill: undefined,
35
36                // vFill: dojox.gfx.Fill?
37                //              An optional dojox.gfx.Fill used to fill every other vertical stripe created by grid lines.
38                vFill: undefined,
39
40                // vAlternateFill: dojox.gfx.Fill?
41                //              An optional dojox.gfx.Fill used to fill alternating vertical stripe created by grid lines not filled by `vFill`.
42                vAlternateFill: undefined,
43
44                // hMajorLines: Boolean?
45                //              Whether to show lines at the major ticks along the horizontal axis. Default is true.
46                hMajorLines: true,
47
48                // hMinorLines: Boolean?
49                //              Whether to show lines at the minor ticks along the horizontal axis. Default is false.
50                hMinorLines: false,
51
52                // vMajorLines: Boolean?
53                //              Whether to show lines at the major ticks along the vertical axis. Default is true.
54                vMajorLines: true,
55
56                // vMinorLines: Boolean?
57                //              Whether to show lines at the major ticks along the vertical axis. Default is false.
58                vMinorLines: false,
59
60                // hStripes: Boolean?
61                //              Whether to show horizontal stripes. Default is false.
62                hStripes: false,
63
64                // vStripes: Boolean?
65                //              Whether to show vertical stripes. Default is false.
66                vStripes: false,
67
68                // enableCache: Boolean?
69                //              Whether the grid lines are cached from one rendering to another. This improves the rendering performance of
70                //              successive rendering but penalize the first rendering.  Default false.
71                enableCache: false,
72
73                // renderOnAxis: Boolean?
74                //              Whether or not the grid is rendered when drawn at horizontal or vertical axis position. Default is true.
75                renderOnAxis: true
76        });
77        =====*/
78
79        return declare("dojox.charting.plot2d.Grid", CartesianBase, {
80                // summary:
81                //              A "faux" plot that can be placed behind other plots to represent
82                //              a grid against which other plots can be easily measured.
83                defaultParams: {
84                        hMajorLines: true,      // draw horizontal major lines
85                        hMinorLines: false,     // draw horizontal minor lines
86                        vMajorLines: true,      // draw vertical major lines
87                        vMinorLines: false,     // draw vertical minor lines
88                        hStripes: false,        // draw vertical stripes
89                        vStripes: false,        // draw vertical stripes
90                        animate: null,   // animate bars into place
91                        enableCache: false,
92                        renderOnAxis: true
93                },
94
95                optionalParams: {
96                        majorHLine: {},
97                        minorHLine: {},
98                        majorVLine: {},
99                        minorVLine: {},
100                        hFill: {},
101                        vFill: {},
102                        hAlternateFill: {},
103                        vAlternateFill: {}
104                },
105
106                constructor: function(chart, kwArgs){
107                        // summary:
108                        //              Create the faux Grid plot.
109                        // chart: dojox/charting/Chart
110                        //              The chart this plot belongs to.
111                        // kwArgs: dojox.charting.plot2d.__GridCtorArgs?
112                        //              An optional keyword arguments object to help define the parameters of the underlying grid.
113                        this.opt = lang.clone(this.defaultParams);
114                        du.updateWithObject(this.opt, kwArgs);
115                        du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
116                        this.animate = this.opt.animate;
117                        if(this.opt.enableCache){
118                                this._lineFreePool = [];
119                                this._lineUsePool = [];
120                                this._rectFreePool = [];
121                                this._rectUsePool = [];
122                        }
123                },
124                addSeries: function(run){
125                        // summary:
126                        //              Ignored but included as a dummy method.
127                        // returns: dojox/charting/plot2d/Grid
128                        //              The reference to this plot for functional chaining.
129                        return this;    //      dojox/charting/plot2d/Grid
130                },
131                getSeriesStats: function(){
132                        // summary:
133                        //              Returns default stats (irrelevant for this type of plot).
134                        // returns: Object
135                        //              {hmin, hmax, vmin, vmax} min/max in both directions.
136                        return lang.delegate(dc.defaultStats); // Object
137                },
138                cleanGroup: function(){
139                        this.inherited(arguments);
140                        if(this.opt.enableCache){
141                                this._lineFreePool = this._lineFreePool.concat(this._lineUsePool);
142                                this._lineUsePool = [];
143                                this._rectFreePool = this._rectFreePool.concat(this._rectUsePool);
144                                this._rectUsePool = [];
145                        }
146                },
147                createLine: function(creator, params){
148                        var line;
149                        if(this.opt.enableCache && this._lineFreePool.length > 0){
150                                line = this._lineFreePool.pop();
151                                line.setShape(params);
152                                // was cleared, add it back
153                                creator.add(line);
154                        }else{
155                                line = creator.createLine(params);
156                        }
157                        if(this.opt.enableCache){
158                                this._lineUsePool.push(line);
159                        }
160                        return line;
161                },
162                createRect: function(creator, params){
163                        var rect;
164                        if(this.opt.enableCache && this._rectFreePool.length > 0){
165                                rect = this._rectFreePool.pop();
166                                rect.setShape(params);
167                                // was cleared, add it back
168                                creator.add(rect);
169                        }else{
170                                rect = creator.createRect(params);
171                        }
172                        if(this.opt.enableCache){
173                                this._rectUsePool.push(rect);
174                        }
175                        return rect;
176                },
177               
178                render: function(dim, offsets){
179                        // summary:
180                        //              Render the plot on the chart.
181                        // dim: Object
182                        //              An object of the form { width, height }.
183                        // offsets: Object
184                        //              An object of the form { l, r, t, b }.
185                        // returns: dojox/charting/plot2d/Grid
186                        //              A reference to this plot for functional chaining.
187                        if(this.zoom){
188                                return this.performZoom(dim, offsets);
189                        }
190                        this.dirty = this.isDirty();
191                        if(!this.dirty){ return this; }
192                        this.cleanGroup();
193                        var s = this.getGroup(), ta = this.chart.theme, lineStroke, ticks;
194                        if((has("ios") && has("ios") < 6) || has("android") || (has("safari") && !has("ios"))){
195                                // clipping seems buggy in some mobile Webkit browser and Safari desktop
196                                // it does not clip correctly if only lines are present => create a invisible rectangle...
197                                var w = Math.max(0, dim.width  - offsets.l - offsets.r),
198                                        h = Math.max(0, dim.height - offsets.t - offsets.b);
199                                s.createRect({ x: offsets.l, y: offsets.t, width: w, height: h});
200                        }
201                        if(this._vAxis){
202                                // draw horizontal stripes and lines
203                                ticks = this._vAxis.getTicks();
204                                var vScaler = this._vAxis.getScaler();
205                                if(ticks != null && vScaler != null){
206                                        var vt = vScaler.scaler.getTransformerFromModel(vScaler);
207                                        if(this.opt.hStripes){
208                                                this._renderHRect(ticks, ta.grid, dim, offsets, vScaler, vt);
209                                        }
210                                        if(this.opt.hMinorLines){
211                                                lineStroke = this.opt.minorHLine || (ta.grid && ta.grid.minorLine) || ta.axis.minorTick;
212                                                this._renderHLines(ticks.minor, lineStroke, dim, offsets, vScaler, vt);
213                                        }
214                                        if(this.opt.hMajorLines){
215                                                lineStroke = this.opt.majorHLine || (ta.grid && ta.grid.majorLine) || ta.axis.majorTick;
216                                                this._renderHLines(ticks.major, lineStroke, dim, offsets, vScaler, vt);
217                                        }
218                                }
219                               
220                        }
221                        if(this._hAxis){
222                                // draw vertical stripes and lines
223                                ticks = this._hAxis.getTicks();
224                                var hScaler = this._hAxis.getScaler();
225                                if(ticks != null && hScaler != null){
226                                        var ht = hScaler.scaler.getTransformerFromModel(hScaler);
227                                        if(this.opt.vStripes){
228                                                this._renderVRect(ticks, ta.grid, dim, offsets, hScaler, ht);
229                                        }
230                                        if(ticks && this.opt.vMinorLines){
231                                                lineStroke = this.opt.minorVLine || (ta.grid && ta.grid.minorLine) || ta.axis.minorTick;
232                                                this._renderVLines(ticks.minor, lineStroke, dim, offsets, hScaler, ht);
233                                        }
234                                        if(ticks && this.opt.vMajorLines){
235                                                lineStroke = this.opt.majorVLine || (ta.grid && ta.grid.majorLine) || ta.axis.majorTick;
236                                                this._renderVLines(ticks.major, lineStroke, dim, offsets, hScaler, ht);
237                                        }
238
239                                }
240                        }
241                        this.dirty = false;
242                        return this;    //      dojox/charting/plot2d/Grid
243                },
244                _renderHLines: function(ticks, lineStroke, dim, offsets, vScaler, vt){
245                        var s = this.getGroup();
246                        arr.forEach(ticks, function(tick){
247                                if(!this.opt.renderOnAxis && tick.value == (this._vAxis.opt.leftBottom?vScaler.bounds.from:vScaler.bounds.to)){
248                                        return;
249                                }
250                                var y = dim.height - offsets.b - vt(tick.value);
251                                var hLine = this.createLine(s, {
252                                        x1: offsets.l,
253                                        y1: y,
254                                        x2: dim.width - offsets.r,
255                                        y2: y
256                                }).setStroke(lineStroke);
257                                if(this.animate){
258                                        this._animateGrid(hLine, "h", offsets.l, offsets.r + offsets.l - dim.width);
259                                }
260                        }, this);
261                },
262                _renderVLines: function(ticks, lineStroke, dim, offsets, hScaler, ht){
263                        var s = this.getGroup();
264                        arr.forEach(ticks, function(tick){
265                                if(!this.opt.renderOnAxis && tick.value == (this._hAxis.opt.leftBottom?hScaler.bounds.from:hScaler.bounds.to)){
266                                        return;
267                                }
268                                var x = offsets.l + ht(tick.value);
269                                var vLine = this.createLine(s, {
270                                        x1: x,
271                                        y1: offsets.t,
272                                        x2: x,
273                                        y2: dim.height - offsets.b
274                                }).setStroke(lineStroke);
275                                if(this.animate){
276                                        this._animateGrid(vLine, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
277                                }
278                        }, this);
279                },
280                _renderHRect: function(ticks, theme, dim, offsets, vScaler, vt){
281                        var fill, tick, y, y2, hStripe;
282                        var allTicks = ticks.major.concat(ticks.minor);
283                        allTicks.sort(sortTicks);
284                        if(allTicks[0].value > vScaler.bounds.from){
285                                allTicks.splice(0, 0, {value: vScaler.bounds.from});
286                        }
287                        if(allTicks[allTicks.length - 1].value < vScaler.bounds.to){
288                                allTicks.push({value: vScaler.bounds.to});
289                        }
290                        var s = this.getGroup();
291                        for(var j = 0; j < allTicks.length - 1; j++){
292                                tick = allTicks[j];
293                                y = dim.height - offsets.b - vt(tick.value);
294                                y2 = dim.height - offsets.b - vt(allTicks[j+1].value);
295
296                                fill = (j%2 == 0)?(this.opt.hAlternateFill ||(theme && theme.alternateFill)):
297                                        (this.opt.hFill || (theme && theme.fill));
298                                if(fill){
299                                        hStripe = this.createRect(s, {
300                                                x: offsets.l,
301                                                y: y,
302                                                width: dim.width - offsets.r,
303                                                height: y - y2
304                                        }).setFill(fill);
305                                        if(this.animate){
306                                                this._animateGrid(hStripe, "h", offsets.l, offsets.r + offsets.l - dim.width);
307                                        }
308                                }
309                        }
310                },
311                _renderVRect: function(ticks, theme, dim, offsets, hScaler, ht){
312                        var fill, tick, x, x2, vStripe;
313                        var allTicks = ticks.major.concat(ticks.minor);
314                        allTicks.sort(sortTicks);
315                        if(allTicks[0].value > hScaler.bounds.from){
316                                allTicks.splice(0, 0, {value: hScaler.bounds.from});
317                        }
318                        if(allTicks[allTicks.length - 1].value < hScaler.bounds.to){
319                                allTicks.push({value: hScaler.bounds.to});
320                        }
321                        var s = this.getGroup();
322                        for(var j = 0; j < allTicks.length - 1; j++){
323                                tick = allTicks[j];
324                                x = offsets.l + ht(tick.value);
325                                x2 = offsets.l + ht(allTicks[j+1].value);
326
327                                fill = (j%2 == 0)?(this.opt.vAlternateFill ||(theme && theme.alternateFill)):
328                                        (this.opt.vFill || (theme && theme.fill));
329                                if(fill){
330                                        vStripe = this.createRect(s, {
331                                                x: x,
332                                                y: offsets.t,
333                                                width: x2 - x,
334                                                height: dim.width - offsets.r
335                                        }).setFill(fill);
336                                        if(this.animate){
337                                                this._animateGrid(vStripe, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
338                                        }
339                                }
340                        }
341                },
342                _animateGrid: function(shape, type, offset, size){
343                        var transStart = type == "h" ? [offset, 0] : [0, offset];
344                        var scaleStart = type == "h" ? [1/size, 1] : [1, 1/size];
345                        fx.animateTransform(lang.delegate({
346                                shape: shape,
347                                duration: 1200,
348                                transform: [
349                                        {name: "translate", start: transStart, end: [0, 0]},
350                                        {name: "scale", start: scaleStart, end: [1, 1]},
351                                        {name: "original"}
352                                ]
353                        }, this.animate)).play();
354                }
355        });
356});
Note: See TracBrowser for help on using the repository browser.