[483] | 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); |
---|