source: Dev/branches/rest-dojo-ui/client/dojox/charting/plot2d/Bubble.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.8 KB
Line 
1define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array",
2                "./Base", "./common", "dojox/lang/functional", "dojox/lang/functional/reversed",
3                "dojox/lang/utils", "dojox/gfx/fx"],
4        function(lang, declare, arr, Base, dc, df, dfr, du, fx){
5/*=====
6var Base = dojox.charting.plot2d.Base;
7=====*/
8
9        var purgeGroup = dfr.lambda("item.purgeGroup()");
10
11        return declare("dojox.charting.plot2d.Bubble", Base, {
12                //      summary:
13                //              A plot representing bubbles.  Note that data for Bubbles requires 3 parameters,
14                //              in the form of:  { x, y, size }, where size determines the size of the bubble.
15                defaultParams: {
16                        hAxis: "x",             // use a horizontal axis named "x"
17                        vAxis: "y",             // use a vertical axis named "y"
18                        animate: null   // animate bars into place
19                },
20                optionalParams: {
21                        // theme component
22                        stroke:         {},
23                        outline:        {},
24                        shadow:         {},
25                        fill:           {},
26                        font:           "",
27                        fontColor:      ""
28                },
29
30                constructor: function(chart, kwArgs){
31                        //      summary:
32                        //              Create a plot of bubbles.
33                        //      chart: dojox.charting.Chart
34                        //              The chart this plot belongs to.
35                        //      kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
36                        //              Optional keyword arguments object to help define plot parameters.
37                        this.opt = lang.clone(this.defaultParams);
38            du.updateWithObject(this.opt, kwArgs);
39            du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
40            this.series = [];
41                        this.hAxis = this.opt.hAxis;
42                        this.vAxis = this.opt.vAxis;
43                        this.animate = this.opt.animate;
44                },
45
46                //      override the render so that we are plotting only circles.
47                render: function(dim, offsets){
48                        //      summary:
49                        //              Run the calculations for any axes for this plot.
50                        //      dim: Object
51                        //              An object in the form of { width, height }
52                        //      offsets: Object
53                        //              An object of the form { l, r, t, b}.
54                        //      returns: dojox.charting.plot2d.Bubble
55                        //              A reference to this plot for functional chaining.
56                        if(this.zoom && !this.isDataDirty()){
57                                return this.performZoom(dim, offsets);
58                        }
59                        this.resetEvents();
60                        this.dirty = this.isDirty();
61                        if(this.dirty){
62                                arr.forEach(this.series, purgeGroup);
63                                this._eventSeries = {};
64                                this.cleanGroup();
65                                var s = this.group;
66                                df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
67                        }
68
69                        var t = this.chart.theme,
70                                ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
71                                vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
72                                events = this.events();
73
74                        for(var i = this.series.length - 1; i >= 0; --i){
75                                var run = this.series[i];
76                                if(!this.dirty && !run.dirty){
77                                        t.skip();
78                                        this._reconnectEvents(run.name);
79                                        continue;
80                                }
81                                run.cleanGroup();
82                                if(!run.data.length){
83                                        run.dirty = false;
84                                        t.skip();
85                                        continue;
86                                }
87
88                                if(typeof run.data[0] == "number"){
89                                        console.warn("dojox.charting.plot2d.Bubble: the data in the following series cannot be rendered as a bubble chart; ", run);
90                                        continue;
91                                }
92
93                                var theme = t.next("circle", [this.opt, run]), s = run.group,
94                                        points = arr.map(run.data, function(v, i){
95                                                return v ? {
96                                                        x: ht(v.x) + offsets.l,
97                                                        y: dim.height - offsets.b - vt(v.y),
98                                                        radius: this._vScaler.bounds.scale * (v.size / 2)
99                                                } : null;
100                                        }, this);
101
102                                var frontCircles = null, outlineCircles = null, shadowCircles = null;
103
104                                // make shadows if needed
105                                if(theme.series.shadow){
106                                        shadowCircles = arr.map(points, function(item){
107                                                if(item !== null){
108                                                        var finalTheme = t.addMixin(theme, "circle", item, true),
109                                                                shadow = finalTheme.series.shadow;
110                                                        var shape = s.createCircle({
111                                                                cx: item.x + shadow.dx, cy: item.y + shadow.dy, r: item.radius
112                                                        }).setStroke(shadow).setFill(shadow.color);
113                                                        if(this.animate){
114                                                                this._animateBubble(shape, dim.height - offsets.b, item.radius);
115                                                        }
116                                                        return shape;
117                                                }
118                                                return null;
119                                        }, this);
120                                        if(shadowCircles.length){
121                                                run.dyn.shadow = shadowCircles[shadowCircles.length - 1].getStroke();
122                                        }
123                                }
124
125                                // make outlines if needed
126                                if(theme.series.outline){
127                                        outlineCircles = arr.map(points, function(item){
128                                                if(item !== null){
129                                                        var finalTheme = t.addMixin(theme, "circle", item, true),
130                                                                outline = dc.makeStroke(finalTheme.series.outline);
131                                                        outline.width = 2 * outline.width + theme.series.stroke.width;
132                                                        var shape = s.createCircle({
133                                                                cx: item.x, cy: item.y, r: item.radius
134                                                        }).setStroke(outline);
135                                                        if(this.animate){
136                                                                this._animateBubble(shape, dim.height - offsets.b, item.radius);
137                                                        }
138                                                        return shape;
139                                                }
140                                                return null;
141                                        }, this);
142                                        if(outlineCircles.length){
143                                                run.dyn.outline = outlineCircles[outlineCircles.length - 1].getStroke();
144                                        }
145                                }
146
147                                //      run through the data and add the circles.
148                                frontCircles = arr.map(points, function(item){
149                                        if(item !== null){
150                                                var finalTheme = t.addMixin(theme, "circle", item, true),
151                                                        rect = {
152                                                                x: item.x - item.radius,
153                                                                y: item.y - item.radius,
154                                                                width:  2 * item.radius,
155                                                                height: 2 * item.radius
156                                                        };
157                                                var specialFill = this._plotFill(finalTheme.series.fill, dim, offsets);
158                                                specialFill = this._shapeFill(specialFill, rect);
159                                                var shape = s.createCircle({
160                                                        cx: item.x, cy: item.y, r: item.radius
161                                                }).setFill(specialFill).setStroke(finalTheme.series.stroke);
162                                                if(this.animate){
163                                                        this._animateBubble(shape, dim.height - offsets.b, item.radius);
164                                                }
165                                                return shape;
166                                        }
167                                        return null;
168                                }, this);
169                                if(frontCircles.length){
170                                        run.dyn.fill   = frontCircles[frontCircles.length - 1].getFill();
171                                        run.dyn.stroke = frontCircles[frontCircles.length - 1].getStroke();
172                                }
173
174                                if(events){
175                                        var eventSeries = new Array(frontCircles.length);
176                                        arr.forEach(frontCircles, function(s, i){
177                                                if(s !== null){
178                                                        var o = {
179                                                                element: "circle",
180                                                                index:   i,
181                                                                run:     run,
182                                                                shape:   s,
183                                                                outline: outlineCircles && outlineCircles[i] || null,
184                                                                shadow:  shadowCircles && shadowCircles[i] || null,
185                                                                x:       run.data[i].x,
186                                                                y:       run.data[i].y,
187                                                                r:       run.data[i].size / 2,
188                                                                cx:      points[i].x,
189                                                                cy:      points[i].y,
190                                                                cr:      points[i].radius
191                                                        };
192                                                        this._connectEvents(o);
193                                                        eventSeries[i] = o;
194                                                }
195                                        }, this);
196                                        this._eventSeries[run.name] = eventSeries;
197                                }else{
198                                        delete this._eventSeries[run.name];
199                                }
200
201                                run.dirty = false;
202                        }
203                        this.dirty = false;
204                        return this;    //      dojox.charting.plot2d.Bubble
205                },
206                _animateBubble: function(shape, offset, size){
207                        fx.animateTransform(lang.delegate({
208                                shape: shape,
209                                duration: 1200,
210                                transform: [
211                                        {name: "translate", start: [0, offset], end: [0, 0]},
212                                        {name: "scale", start: [0, 1/size], end: [1, 1]},
213                                        {name: "original"}
214                                ]
215                        }, this.animate)).play();
216                }
217        });
218});
Note: See TracBrowser for help on using the repository browser.