1 | dojo.provide("util.docscripts.cheat.floatup"); |
---|
2 | (function(d){ |
---|
3 | |
---|
4 | function getMax(list){ |
---|
5 | return Math.max.apply(Math, list) |
---|
6 | } |
---|
7 | |
---|
8 | function getMin(list){ |
---|
9 | return Math.min.apply(Math, list); |
---|
10 | } |
---|
11 | |
---|
12 | function sum(ar){ |
---|
13 | var t = 0; |
---|
14 | dojo.forEach(ar, function(v){ t += v }); |
---|
15 | return t; |
---|
16 | } |
---|
17 | |
---|
18 | d.NodeList.prototype.floatup = function(selector){ |
---|
19 | |
---|
20 | selector = selector || "> *"; |
---|
21 | |
---|
22 | return this.forEach(function(n){ |
---|
23 | |
---|
24 | var targets = d.query(selector, n), |
---|
25 | colWidth = 254, |
---|
26 | cols = 4, |
---|
27 | useHighest = true, |
---|
28 | numTargets = targets.length, |
---|
29 | targetData = d.map(targets, function(n){ return [n, Math.floor(d.position(n).h)] }); |
---|
30 | heights = d.map(targetData, function(o){ return o[1]; }), |
---|
31 | totalHeight = sum(heights), |
---|
32 | // optimum is either the largest height or an average of the total height over the cols |
---|
33 | avgHeight = totalHeight / cols, |
---|
34 | maxHeight = getMax(heights), |
---|
35 | optimumHeight = Math.max(avgHeight, maxHeight), |
---|
36 | threshold = 75 // pixels to allow over/under optimum |
---|
37 | ; |
---|
38 | |
---|
39 | function inBounds(val){ |
---|
40 | // returns bool if passed height is within bounds of optimum |
---|
41 | var upper = optimumHeight + threshold, lower = optimumHeight - threshold; |
---|
42 | if(val == optimumHeight || (val <= upper && val >= lower)){ |
---|
43 | return true; |
---|
44 | }else{ |
---|
45 | return false; |
---|
46 | } |
---|
47 | } |
---|
48 | |
---|
49 | function getOptimumPositions(data, sizes, cols){ |
---|
50 | // return an Array of Arrays. Each item in the top level array will be an Array |
---|
51 | // of reference to the nodes that needs to be in the corresponding col |
---|
52 | |
---|
53 | var col = 0; |
---|
54 | var ret = new Array(cols + 1); |
---|
55 | d.forEach(ret, function(i, idx){ ret[idx] = []; }); |
---|
56 | |
---|
57 | function colFromHeap(ar){ |
---|
58 | //console.warn("making col", col, ar, sum(ar), sizes.length, data.length, ret[col]); |
---|
59 | d.forEach(ar, function(size){ |
---|
60 | var idx = d.indexOf(sizes, size); |
---|
61 | if(~idx){ |
---|
62 | ret[col].push(data[idx][0]); |
---|
63 | data.splice(idx, 1); |
---|
64 | sizes.splice(idx, 1); |
---|
65 | }else{ |
---|
66 | // console.warn("ugh?", size, sizes, idx); |
---|
67 | } |
---|
68 | |
---|
69 | }); |
---|
70 | // console.log(ret[col]); |
---|
71 | col++; |
---|
72 | } |
---|
73 | var pass = 0; |
---|
74 | |
---|
75 | while(sizes.length){ |
---|
76 | |
---|
77 | var heap = []; |
---|
78 | |
---|
79 | // first size |
---|
80 | heap.push(useHighest ? getMax(sizes) : sizes[0]); |
---|
81 | if(!inBounds(sum(heap))){ |
---|
82 | d.forEach(sizes, function(size){ |
---|
83 | var now = sum(heap); |
---|
84 | if(inBounds(now + size) || size < optimumHeight - now){ |
---|
85 | heap.push(size); |
---|
86 | } |
---|
87 | }); |
---|
88 | } |
---|
89 | |
---|
90 | colFromHeap(heap); |
---|
91 | } |
---|
92 | |
---|
93 | return ret; |
---|
94 | } |
---|
95 | |
---|
96 | var stuff = getOptimumPositions(targetData, heights, cols); |
---|
97 | d.forEach(stuff, function(col, idx){ |
---|
98 | |
---|
99 | var colNode = d.create("div", { |
---|
100 | style:{ width: colWidth + "px", "float":"left" } |
---|
101 | }, n); |
---|
102 | |
---|
103 | d.forEach(col, function(node){ |
---|
104 | d.place(node, colNode); |
---|
105 | }); |
---|
106 | }); |
---|
107 | |
---|
108 | }); |
---|
109 | |
---|
110 | }; |
---|
111 | |
---|
112 | })(dojo); |
---|