source: Dev/branches/rest-dojo-ui/client/dojox/charting/DataSeries.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: 4.9 KB
Line 
1define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base/connect", "dojox/lang/functional"],
2        function(Lang, declare, ArrayUtil, Hub, df){
3
4        return declare("dojox.charting.DataSeries", null, {
5                constructor: function(store, kwArgs, value){
6                        //      summary:
7                        //              Series adapter for dojo.data stores.
8                        //      store: Object:
9                        //              A dojo.data store object.
10                        //      kwArgs: Object:
11                        //              A store-specific keyword parameters used for fetching items.
12                        //              See dojo.data.api.Read.fetch().
13                        //      value: Function|Object|String|Null:
14                        //              Function, which takes a store, and an object handle, and
15                        //              produces an output possibly inspecting the store's item. Or
16                        //              a dictionary object, which tells what names to extract from
17                        //              an object and how to map them to an output. Or a string, which
18                        //              is a numeric field name to use for plotting. If undefined, null
19                        //              or empty string (the default), "value" field is extracted.
20                        this.store = store;
21                        this.kwArgs = kwArgs;
22       
23                        if(value){
24                                if(Lang.isFunction(value)){
25                                        this.value = value;
26                                }else if(Lang.isObject(value)){
27                                        this.value = Lang.hitch(this, "_dictValue",
28                                                df.keys(value), value);
29                                }else{
30                                        this.value = Lang.hitch(this, "_fieldValue", value);
31                                }
32                        }else{
33                                this.value = Lang.hitch(this, "_defaultValue");
34                        }
35       
36                        this.data = [];
37       
38                        this._events = [];
39       
40                        if(this.store.getFeatures()["dojo.data.api.Notification"]){
41                                this._events.push(
42                                        Hub.connect(this.store, "onNew", this, "_onStoreNew"),
43                                        Hub.connect(this.store, "onDelete", this, "_onStoreDelete"),
44                                        Hub.connect(this.store, "onSet", this, "_onStoreSet")
45                                );
46                        }
47       
48                        this.fetch();
49                },
50       
51                destroy: function(){
52                        //      summary:
53                        //              Clean up before GC.
54                        ArrayUtil.forEach(this._events, Hub.disconnect);
55                },
56       
57                setSeriesObject: function(series){
58                        //      summary:
59                        //              Sets a dojox.charting.Series object we will be working with.
60                        //      series: dojox.charting.Series:
61                        //              Our interface to the chart.
62                        this.series = series;
63                },
64       
65                // value transformers
66       
67                _dictValue: function(keys, dict, store, item){
68                        var o = {};
69                        ArrayUtil.forEach(keys, function(key){
70                                o[key] = store.getValue(item, dict[key]);
71                        });
72                        return o;
73                },
74       
75                _fieldValue: function(field, store, item){
76                        return store.getValue(item, field);
77                },
78       
79                _defaultValue: function(store, item){
80                        return store.getValue(item, "value");
81                },
82       
83                // store fetch loop
84       
85                fetch: function(){
86                        //      summary:
87                        //              Fetches data from the store and updates a chart.
88                        if(!this._inFlight){
89                                this._inFlight = true;
90                                var kwArgs = Lang.delegate(this.kwArgs);
91                                kwArgs.onComplete = Lang.hitch(this, "_onFetchComplete");
92                                kwArgs.onError = Lang.hitch(this, "onFetchError");
93                                this.store.fetch(kwArgs);
94                        }
95                },
96       
97                _onFetchComplete: function(items, request){
98                        this.items = items;
99                        this._buildItemMap();
100                        this.data = ArrayUtil.map(this.items, function(item){
101                                return this.value(this.store, item);
102                        }, this);
103                        this._pushDataChanges();
104                        this._inFlight = false;
105                },
106       
107                onFetchError: function(errorData, request){
108                        //      summary:
109                        //              As stub to process fetch errors. Provide so user can attach to
110                        //              it with dojo.connect(). See dojo.data.api.Read fetch() for
111                        //              details: onError property.
112                        this._inFlight = false;
113                },
114       
115                _buildItemMap: function(){
116                        if(this.store.getFeatures()["dojo.data.api.Identity"]){
117                                var itemMap = {};
118                                ArrayUtil.forEach(this.items, function(item, index){
119                                        itemMap[this.store.getIdentity(item)] = index;
120                                }, this);
121                                this.itemMap = itemMap;
122                        }
123                },
124       
125                _pushDataChanges: function(){
126                        if(this.series){
127                                this.series.chart.updateSeries(this.series.name, this);
128                                this.series.chart.delayedRender();
129                        }
130                },
131       
132                // store notification handlers
133       
134                _onStoreNew: function(){
135                        // the only thing we can do is to re-fetch items
136                        this.fetch();
137                },
138       
139                _onStoreDelete: function(item){
140                        // we cannot do anything with deleted item, the only way is to compare
141                        // items for equality
142                        if(this.items){
143                                var flag = ArrayUtil.some(this.items, function(it, index){
144                                        if(it === item){
145                                                this.items.splice(index, 1);
146                                                this._buildItemMap();
147                                                this.data.splice(index, 1);
148                                                return true;
149                                        }
150                                        return false;
151                                }, this);
152                                if(flag){
153                                        this._pushDataChanges();
154                                }
155                        }
156                },
157       
158                _onStoreSet: function(item){
159                        if(this.itemMap){
160                                // we can use our handy item map, if the store supports Identity
161                                var id = this.store.getIdentity(item), index = this.itemMap[id];
162                                if(typeof index == "number"){
163                                        this.data[index] = this.value(this.store, this.items[index]);
164                                        this._pushDataChanges();
165                                }
166                        }else{
167                                // otherwise we have to rely on item's equality
168                                if(this.items){
169                                        var flag = ArrayUtil.some(this.items, function(it, index){
170                                                if(it === item){
171                                                        this.data[index] = this.value(this.store, it);
172                                                        return true;
173                                                }
174                                                return false;
175                                        }, this);
176                                        if(flag){
177                                                this._pushDataChanges();
178                                        }
179                                }
180                        }
181                }
182        });
183});
Note: See TracBrowser for help on using the repository browser.