source: Dev/trunk/src/client/dojox/treemap/_utils.js @ 536

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

Added Dojo 1.9.3 release.

File size: 6.0 KB
Line 
1define(["dojo/_base/array"], function(arr){
2        var utils = {
3                group: function(/*Array*/items, /*Array*/groupingFunctions,  /*Function*/measureFunction){
4                        var response = {
5                                children: []
6                        };
7                        var merge = function(obj, entry){
8                                if(!obj.__treeValue){
9                                        obj.__treeValue = 0;
10                                }
11                                obj.__treeValue += measureFunction(entry);
12                                return obj;
13                        };
14                        // we go over each entry in the array
15                        arr.forEach(items, function(entry){
16                                var r = response;
17                                // for this entry, for each rowField we
18                                // look at the actual value for this rowField
19                                // and create a holding object for this
20                                // value in response if it does not exist
21                                arr.forEach(groupingFunctions, function(groupingFunction, j){
22                                        // actual value for the rowField
23                                        var data = groupingFunction(entry);
24                                        // create child if undefined
25                                        var child = utils.find(r.children, function(item){
26                                                return (item.__treeName == data);
27                                        });
28                                        if(!child){
29                                                r.children.push(child = {
30                                                        __treeName: data,
31                                                        __treeID: data+Math.random(),
32                                                        children: []
33                                                });
34                                        }
35                                        child = merge(child, entry);
36                                        if(j != groupingFunctions.length - 1){
37                                                // branch & prepare response for
38                                                // next call
39                                                r = child;
40                                        }else{
41                                                // add the entry to the leaf!
42                                                child.children.push(entry);
43                                        }
44                                });
45                                r = merge(r, entry);
46                        });
47                        return response;
48                },
49                find: function(/*Array*/array, /*Function*/callback){
50                        var l = array.length;
51                        for (var i = 0; i < l; ++i) {
52                                if (callback.call(null, array[i])){                                     
53                                        return array[i];
54                                }
55                        }
56                        return null;
57                },
58                solve: function(items, width, height, areaFunc, rtl){
59                        //
60                        // Create temporary TreeMap elements
61                        //
62                        var treeMapElements = utils.initElements(items, areaFunc);
63                        var dataTotal = treeMapElements.total;
64                        var elements = treeMapElements.elements;
65       
66                        var realSize = dataTotal;
67       
68                        if(dataTotal == 0){
69                                if(elements.length == 0){
70                                        return {
71                                                items: items, rects: [], total: 0
72                                        };
73                                }
74                                arr.forEach(elements, function(element){
75                                        element.size = element.sizeTmp = 100;
76                                });
77                                dataTotal = elements.length * 100;
78                        }
79       
80                        //
81                        //      Sort the TreeMap elements
82                        //
83                        elements.sort(function(b, a){
84                                return a.size - b.size;
85                        });
86       
87                        utils._compute(width, height, elements, dataTotal);
88       
89                        //
90                        // Restore initial Sort order
91                        //
92                        elements.sort(function(a, b){
93                                return a.index - b.index;
94                        });
95       
96                        var result = {};
97                        result.elements = elements;
98                        result.size = realSize;
99       
100                        rects = arr.map(elements, function(element){
101                                return {
102                                        x: rtl?width - element.x - element.width:element.x, y: element.y, w: element.width, h: element.height
103                                };
104                        });
105       
106                        result.rectangles = rects;
107       
108                        return result;
109                },
110                initElements: function(items, areaFunc){
111                        var total = 0;
112                        var elements = arr.map(items, function(item, index){
113                                var size = areaFunc != null ? areaFunc(item) : 0;
114                                if(size < 0){
115                                        throw new Error("item size dimension must be positive");
116                                }
117                                total += size;
118                                return {
119                                        index: index, size: size, sizeTmp: size
120                                };
121                        });
122                        return {
123                                elements: elements, total: total
124                        };
125                },
126                _compute: function(width, height, elements, total){
127                        var valueScale = ((width * height) / total) / 100;
128       
129                        arr.forEach(elements, function(element){
130                                element.sizeTmp *= valueScale;
131                        });
132       
133                        var start = 0;
134                        var end = 0;
135                        var aspectCurr = -1 >>> 1; // int.MaxValue;
136                        var aspectLast;
137                        var offsetX = 0;
138                        var offsetY = 0;
139                        var tmp_width = width;
140                        var tmp_height = height;
141       
142                        var vert = tmp_width > tmp_height;
143       
144                        while(end != elements.length){
145                                aspectLast = utils._trySolution(elements, start, end, vert, tmp_width, tmp_height);
146       
147                                if((aspectLast > aspectCurr) || (aspectLast < 1)){
148                                        var currX = 0;
149                                        var currY = 0;
150       
151                                        for(var n = start; n < end; n++){
152                                                elements[n].x = offsetX + currX;
153                                                elements[n].y = offsetY + currY;
154                                                if(vert){
155                                                        currY += elements[n].height;
156                                                }else{
157                                                        currX += elements[n].width;
158                                                }
159                                        }
160       
161                                        if(vert){
162                                                offsetX += elements[start].width;
163                                        }else{
164                                                offsetY += elements[start].height;
165                                        }
166       
167                                        tmp_width = width - offsetX;
168                                        tmp_height = height - offsetY;
169       
170                                        vert = tmp_width > tmp_height;
171       
172                                        start = end;
173                                        end = start;
174       
175                                        aspectCurr = -1 >>> 1; // int.MaxValue;
176                                        continue;
177                                }else{
178                                        for(var n = start; n <= end; n++){
179                                                elements[n].width = elements[n].widthTmp;
180                                                elements[n].height = elements[n].heightTmp;
181                                        }
182                                        aspectCurr = aspectLast;
183                                }
184                                end++;
185                        }
186       
187                        var currX1 = 0;
188                        var currY1 = 0;
189       
190                        for(var n = start; n < end; n++){
191                                elements[n].x = offsetX + currX1;
192                                elements[n].y = offsetY + currY1;
193                                if(vert){
194                                        currY1 += elements[n].height;
195                                }else{
196                                        currX1 += elements[n].width;
197                                }
198                        }
199       
200                },
201                _trySolution: function(elements, start, end, vert, tmp_width, tmp_height){
202                        var total = 0;
203                        var aspect = 0;
204                        var localWidth = 0;
205                        var localHeight = 0;
206       
207                        for(var n = start; n <= end; n++){
208                                total += elements[n].sizeTmp;
209                        }
210       
211                        if(vert){
212                                if(tmp_height == 0){
213                                        localWidth = localHeight = 0;
214                                }else{
215                                        localWidth = total / tmp_height * 100;
216                                        localHeight = tmp_height;
217                                }
218                        }else{
219                                if(tmp_width == 0){
220                                        localWidth = localHeight = 0;
221                                }else{
222                                        localHeight = total / tmp_width * 100;
223                                        localWidth = tmp_width;
224                                }
225                        }
226       
227                        for(var n = start; n <= end; n++){
228                                if(vert){
229                                        elements[n].widthTmp = localWidth;
230                                        if(total == 0){
231                                                elements[n].heightTmp = 0;
232                                        }else{
233                                                elements[n].heightTmp = localHeight * elements[n].sizeTmp / total;
234                                        }
235                                }else{
236                                        if(total == 0){
237                                                elements[n].widthTmp = 0;
238                                        }else{
239                                                elements[n].widthTmp = localWidth * elements[n].sizeTmp / total;
240                                        }
241                                        elements[n].heightTmp = localHeight;
242                                }
243                        }
244                        aspect = Math.max(elements[end].heightTmp / elements[end].widthTmp, elements[end].widthTmp
245                                        / elements[end].heightTmp);
246                        if(aspect == undefined){
247                                return 1;
248                        }
249                        return aspect;
250                }
251        };
252        return utils;
253});
Note: See TracBrowser for help on using the repository browser.