source: Dev/trunk/src/client/dojox/charting/plot2d/CartesianBase.js @ 483

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

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 10.5 KB
Line 
1define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/has",
2                "./Base", "../scaler/primitive", "dojox/gfx", "dojox/gfx/fx", "dojox/lang/utils"],
3        function(lang, declare, hub, has, Base, primitive, gfx, fx, du){
4        /*=====
5        declare("dojox.charting.plot2d.__CartesianCtorArgs", dojox.charting.plot2d.__PlotCtorArgs, {
6                // hAxis: String?
7                //              The horizontal axis name.
8                hAxis: "x",
9
10                // vAxis: String?
11                //              The vertical axis name
12                vAxis: "y",
13
14                // labels: Boolean?
15                //              For plots that support labels, whether or not to draw labels for each data item.  Default is false.
16                labels:                 false,
17
18                // fixed: Boolean?
19        //              Whether a fixed precision must be applied to data values for display. Default is true.
20                fixed:                  true,
21
22                // precision: Number?
23        //              The precision at which to round data values for display. Default is 0.
24                precision:              1,
25
26                // labelOffset: Number?
27                //              The amount in pixels by which to offset labels when using "outside" labelStyle.  Default is 10.
28                labelOffset:    10,
29
30                // labelStyle: String?
31                //              Options as to where to draw labels.  This must be either "inside" or "outside". By default
32                //      the labels are drawn "inside" the shape representing the data point (a column rectangle for a Columns plot
33                //      or a marker for a Line plot for instance). When "outside" is used the labels are drawn above the data point shape.
34                labelStyle:             "inside",
35
36                // htmlLabels: Boolean?
37                //              Whether or not to use HTML to render slice labels. Default is true.
38                htmlLabels:             true,
39
40                // omitLabels: Boolean?
41                //              Whether labels that do not fit in an item render are omitted or not.    This applies only when labelStyle
42                //              is "inside".    Default is false.
43                omitLabels: true,
44
45                // labelFunc: Function?
46                //              An optional function to use to compute label text. It takes precedence over
47                //              the default text when available.
48                //      |               function labelFunc(value, fixed, precision) {}
49                //              `value` is the data value to display
50                //              `fixed` is true if fixed precision must be applied.
51                //              `precision` is the requested precision to be applied.
52                labelFunc: null
53        });
54        =====*/
55
56        return declare("dojox.charting.plot2d.CartesianBase", Base, {
57                baseParams: {
58                        hAxis:                  "x",
59                        vAxis:                  "y",
60                        labels:                 false,
61                        labelOffset:    10,
62                        fixed:                  true,
63                        precision:              1,
64                        labelStyle:             "inside",
65                        htmlLabels:             true,           // use HTML to draw labels
66                        omitLabels:             true,
67                        labelFunc:              null
68        },
69
70                // summary:
71                //              Base class for cartesian plot types.
72                constructor: function(chart, kwArgs){
73                        // summary:
74                        //              Create a cartesian base plot for cartesian charts.
75                        // chart: dojox/chart/Chart
76                        //              The chart this plot belongs to.
77                        // kwArgs: dojox.charting.plot2d.__CartesianCtorArgs?
78                        //              An optional arguments object to help define the plot.
79                        this.axes = ["hAxis", "vAxis"];
80                        this.zoom = null;
81                        this.zoomQueue = [];    // zooming action task queue
82                        this.lastWindow = {vscale: 1, hscale: 1, xoffset: 0, yoffset: 0};
83                        this.hAxis = (kwArgs && kwArgs.hAxis) || "x";
84                        this.vAxis = (kwArgs && kwArgs.vAxis) || "y";
85                        this.series = [];
86                        this.opt = lang.clone(this.baseParams);
87                        du.updateWithObject(this.opt, kwArgs);
88                },
89                clear: function(){
90                        // summary:
91                        //              Clear out all of the information tied to this plot.
92                        // returns: dojox/charting/plot2d/CartesianBase
93                        //              A reference to this plot for functional chaining.
94                        this.inherited(arguments);
95                        this._hAxis = null;
96                        this._vAxis = null;
97                        return this;    //      dojox/charting/plot2d/CartesianBase
98                },
99                cleanGroup: function(creator, noClip){
100                        this.inherited(arguments);
101                        if(!noClip && this.chart._nativeClip){
102                                var offsets = this.chart.offsets, dim = this.chart.dim;
103                                var w = Math.max(0, dim.width  - offsets.l - offsets.r),
104                                        h = Math.max(0, dim.height - offsets.t - offsets.b);
105                                this.group.setClip({ x: offsets.l, y: offsets.t, width: w, height: h });
106                                if(!this._clippedGroup){
107                                        this._clippedGroup = this.group.createGroup();
108                                }
109                        }
110                },
111                purgeGroup: function(){
112                        this.inherited(arguments);
113                        this._clippedGroup = null;
114                },
115                getGroup: function(){
116                        return this._clippedGroup || this.group;
117                },
118                setAxis: function(axis){
119                        // summary:
120                        //              Set an axis for this plot.
121                        // axis: dojox/charting/axis2d/Base
122                        //              The axis to set.
123                        // returns: dojox/charting/plot2d/CartesianBase
124                        //              A reference to this plot for functional chaining.
125                        if(axis){
126                                this[axis.vertical ? "_vAxis" : "_hAxis"] = axis;
127                        }
128                        return this;    //      dojox/charting/plot2d/CartesianBase
129                },
130                toPage: function(coord){
131                        // summary:
132                        //              Compute page coordinates from plot axis data coordinates.
133                        // coord: Object?
134                        //              The coordinates in plot axis data coordinate space. For cartesian charts that is of the following form:
135                        //              `{ hAxisName: 50, vAxisName: 200 }`
136                        //              If not provided return the transform method instead of the result of the transformation.
137                        // returns: Object
138                        //              The resulting page pixel coordinates. That is of the following form:
139                        //              `{ x: 50, y: 200 }`
140                        var ah = this._hAxis, av = this._vAxis,
141                                sh = ah.getScaler(), sv = av.getScaler(),
142                                th = sh.scaler.getTransformerFromModel(sh),
143                                tv = sv.scaler.getTransformerFromModel(sv),
144                                c = this.chart.getCoords(),
145                                o = this.chart.offsets, dim = this.chart.dim;
146                        var t = function(coord){
147                                var r = {};
148                                r.x = th(coord[ah.name]) + c.x + o.l;
149                                r.y = c.y + dim.height - o.b - tv(coord[av.name]);
150                                return r;
151                        };
152                        // if no coord return the function so that we can capture the current transforms
153                        // and reuse them later on
154                        return coord?t(coord):t; // Object
155                },
156                toData: function(coord){
157                        // summary:
158                        //              Compute plot axis data coordinates from page coordinates.
159                        // coord: Object
160                        //              The pixel coordinate in page coordinate space. That is of the following form:
161                        //              `{ x: 50, y: 200 }`
162                        //              If not provided return the tranform method instead of the result of the transformation.
163                        // returns: Object
164                        //              The resulting plot axis data coordinates. For cartesian charts that is of the following form:
165                        //              `{ hAxisName: 50, vAxisName: 200 }`
166                        var ah = this._hAxis, av = this._vAxis,
167                                sh = ah.getScaler(), sv = av.getScaler(),
168                                th = sh.scaler.getTransformerFromPlot(sh),
169                                tv = sv.scaler.getTransformerFromPlot(sv),
170                                c = this.chart.getCoords(),
171                                o = this.chart.offsets, dim = this.chart.dim;
172                        var t = function(coord){
173                                var r = {};
174                                r[ah.name] = th(coord.x - c.x - o.l);
175                                r[av.name] = tv(c.y + dim.height - coord.y  - o.b);
176                                return r;
177                        };
178                        // if no coord return the function so that we can capture the current transforms
179                        // and reuse them later on
180                        return coord?t(coord):t; // Object
181                },
182                isDirty: function(){
183                        // summary:
184                        //              Returns whether or not this plot needs to be rendered.
185                        // returns: Boolean
186                        //              The state of the plot.
187                        return this.dirty || this._hAxis && this._hAxis.dirty || this._vAxis && this._vAxis.dirty;      //      Boolean
188                },
189                createLabel: function(group, value, bbox, theme){
190                        if(this.opt.labels){
191                                var x, y, label = this.opt.labelFunc?this.opt.labelFunc.apply(this, [value, this.opt.fixed, this.opt.precision]):
192                                        this._getLabel(isNaN(value.y)?value:value.y);
193                                if(this.opt.labelStyle == "inside"){
194                                        var lbox = gfx._base._getTextBox(label, { font: theme.series.font } );
195                                        x = bbox.x + bbox.width / 2;
196                                        y = bbox.y + bbox.height / 2 + lbox.h / 4;
197                                        if(lbox.w > bbox.width || lbox.h > bbox.height){
198                                                return;
199                                        }
200
201                                }else{
202                                        x = bbox.x + bbox.width / 2;
203                                        y = bbox.y - this.opt.labelOffset;
204                                }
205                                this.renderLabel(group, x, y, label, theme, this.opt.labelStyle == "inside");
206                        }
207                },
208                performZoom: function(dim, offsets){
209                        // summary:
210                        //              Create/alter any zooming windows on this plot.
211                        // dim: Object
212                        //              An object of the form { width, height }.
213                        // offsets: Object
214                        //              An object of the form { l, r, t, b }.
215                        // returns: dojox/charting/plot2d/CartesianBase
216                        //              A reference to this plot for functional chaining.
217
218                        // get current zooming various
219                        var vs = this._vAxis.scale || 1,
220                                hs = this._hAxis.scale || 1,
221                                vOffset = dim.height - offsets.b,
222                                hBounds = this._hScaler.bounds,
223                                xOffset = (hBounds.from - hBounds.lower) * hBounds.scale,
224                                vBounds = this._vScaler.bounds,
225                                yOffset = (vBounds.from - vBounds.lower) * vBounds.scale,
226                                // get incremental zooming various
227                                rVScale = vs / this.lastWindow.vscale,
228                                rHScale = hs / this.lastWindow.hscale,
229                                rXOffset = (this.lastWindow.xoffset - xOffset)/
230                                        ((this.lastWindow.hscale == 1)? hs : this.lastWindow.hscale),
231                                rYOffset = (yOffset - this.lastWindow.yoffset)/
232                                        ((this.lastWindow.vscale == 1)? vs : this.lastWindow.vscale),
233
234                                shape = this.getGroup(),
235                                anim = fx.animateTransform(lang.delegate({
236                                        shape: shape,
237                                        duration: 1200,
238                                        transform:[
239                                                {name:"translate", start:[0, 0], end: [offsets.l * (1 - rHScale), vOffset * (1 - rVScale)]},
240                                                {name:"scale", start:[1, 1], end: [rHScale, rVScale]},
241                                                {name:"original"},
242                                                {name:"translate", start: [0, 0], end: [rXOffset, rYOffset]}
243                                        ]}, this.zoom));
244
245                        lang.mixin(this.lastWindow, {vscale: vs, hscale: hs, xoffset: xOffset, yoffset: yOffset});
246                        //add anim to zooming action queue,
247                        //in order to avoid several zooming action happened at the same time
248                        this.zoomQueue.push(anim);
249                        //perform each anim one by one in zoomQueue
250                        hub.connect(anim, "onEnd", this, function(){
251                                this.zoom = null;
252                                this.zoomQueue.shift();
253                                if(this.zoomQueue.length > 0){
254                                        this.zoomQueue[0].play();
255                                }
256                        });
257                        if(this.zoomQueue.length == 1){
258                                this.zoomQueue[0].play();
259                        }
260                        return this;    //      dojox/charting/plot2d/CartesianBase
261                },
262                initializeScalers: function(dim, stats){
263                        // summary:
264                        //              Initializes scalers using attached axes.
265                        // dim: Object
266                        //              Size of a plot area in pixels as {width, height}.
267                        // stats: Object
268                        //              Min/max of data in both directions as {hmin, hmax, vmin, vmax}.
269                        // returns: dojox/charting/plot2d/CartesianBase
270                        //              A reference to this plot for functional chaining.
271                        if(this._hAxis){
272                                if(!this._hAxis.initialized()){
273                                        this._hAxis.calculate(stats.hmin, stats.hmax, dim.width);
274                                }
275                                this._hScaler = this._hAxis.getScaler();
276                        }else{
277                                this._hScaler = primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
278                        }
279                        if(this._vAxis){
280                                if(!this._vAxis.initialized()){
281                                        this._vAxis.calculate(stats.vmin, stats.vmax, dim.height);
282                                }
283                                this._vScaler = this._vAxis.getScaler();
284                        }else{
285                                this._vScaler = primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
286                        }
287                        return this;    //      dojox/charting/plot2d/CartesianBase
288                }
289        });
290});
Note: See TracBrowser for help on using the repository browser.