1 /** 2 * @class Legacy-compatible NCList for 1.2.1 backward compatibility. 3 */ 4 function NCList_v0() {} 5 6 NCList_v0.prototype.importExisting = function(nclist, sublistIndex, 7 lazyIndex, baseURL, 8 lazyUrlTemplate) { 9 this.topList = nclist; 10 this.sublistIndex = sublistIndex; 11 this.lazyIndex = lazyIndex; 12 this.baseURL = baseURL; 13 this.lazyUrlTemplate = lazyUrlTemplate; 14 }; 15 16 NCList_v0.prototype.fill = function(intervals, sublistIndex) { 17 //intervals: array of arrays of [start, end, ...] 18 //sublistIndex: index into a [start, end] array for storing a sublist 19 // array. this is so you can use those arrays for something 20 // else, and keep the NCList_v0 bookkeeping from interfering. 21 // That's hacky, but keeping a separate copy of the intervals 22 // in the NCList_v0 seems like a waste (TODO: measure that waste). 23 //half-open? 24 this.sublistIndex = sublistIndex; 25 var myIntervals = intervals;//.concat(); 26 //sort by OL 27 myIntervals.sort(function(a, b) { 28 if (a[0] != b[0]) 29 return a[0] - b[0]; 30 else 31 return b[1] - a[1]; 32 }); 33 var sublistStack = new Array(); 34 var curList = new Array(); 35 this.topList = curList; 36 curList.push(myIntervals[0]); 37 var curInterval, topSublist; 38 for (var i = 1, len = myIntervals.length; i < len; i++) { 39 curInterval = myIntervals[i]; 40 //if this interval is contained in the previous interval, 41 if (curInterval[1] < myIntervals[i - 1][1]) { 42 //create a new sublist starting with this interval 43 sublistStack.push(curList); 44 curList = new Array(curInterval); 45 myIntervals[i - 1][sublistIndex] = curList; 46 } else { 47 //find the right sublist for this interval 48 while (true) { 49 if (0 == sublistStack.length) { 50 curList.push(curInterval); 51 break; 52 } else { 53 topSublist = sublistStack[sublistStack.length - 1]; 54 if (topSublist[topSublist.length - 1][1] > curInterval[1]) { 55 //curList is the first (deepest) sublist that 56 //curInterval fits into 57 curList.push(curInterval); 58 break; 59 } else { 60 curList = sublistStack.pop(); 61 } 62 } 63 } 64 } 65 } 66 }; 67 68 NCList_v0.prototype.binarySearch = function(arr, item, itemIndex) { 69 var low = -1; 70 var high = arr.length; 71 var mid; 72 73 while (high - low > 1) { 74 mid = (low + high) >>> 1; 75 if (arr[mid][itemIndex] > item) 76 high = mid; 77 else 78 low = mid; 79 } 80 81 //if we're iterating rightward, return the high index; 82 //if leftward, the low index 83 if (1 == itemIndex) return high; else return low; 84 }; 85 86 NCList_v0.prototype.iterHelper = function(arr, from, to, fun, finish, 87 inc, searchIndex, testIndex, path) { 88 var len = arr.length; 89 var i = this.binarySearch(arr, from, searchIndex); 90 while ((i < len) 91 && (i >= 0) 92 && ((inc * arr[i][testIndex]) < (inc * to)) ) { 93 94 if ("object" == typeof arr[i][this.lazyIndex]) { 95 var ncl = this; 96 // lazy node 97 if (arr[i][this.lazyIndex].state) { 98 if ("loading" == arr[i][this.lazyIndex].state) { 99 // node is currenly loading; finish this query once it 100 // has been loaded 101 finish.inc(); 102 arr[i][this.lazyIndex].callbacks.push( 103 function(parentIndex) { 104 return function(o) { 105 ncl.iterHelper(o, from, to, fun, finish, inc, 106 searchIndex, testIndex, 107 path.concat(parentIndex)); 108 finish.dec(); 109 }; 110 }(i) 111 ); 112 } else if ("loaded" == arr[i][this.lazyIndex].state) { 113 // just continue below 114 } else { 115 console.log("unknown lazy type: " + arr[i]); 116 } 117 } else { 118 // no "state" property means this node hasn't been loaded, 119 // start loading 120 arr[i][this.lazyIndex].state = "loading"; 121 arr[i][this.lazyIndex].callbacks = []; 122 finish.inc(); 123 dojo.xhrGet( 124 { 125 url: Util.resolveUrl( 126 this.baseURL, 127 this.lazyUrlTemplate.replace( 128 /\{chunk\}/g, 129 arr[i][this.lazyIndex].chunk 130 ) 131 ), 132 handleAs: "json", 133 load: function(lazyFeat, lazyObj, 134 sublistIndex, parentIndex) { 135 return function(o) { 136 lazyObj.state = "loaded"; 137 lazyFeat[sublistIndex] = o; 138 ncl.iterHelper(o, from, to, 139 fun, finish, inc, 140 searchIndex, testIndex, 141 path.concat(parentIndex)); 142 for (var c = 0; 143 c < lazyObj.callbacks.length; 144 c++) 145 lazyObj.callbacks[c](o); 146 finish.dec(); 147 }; 148 }(arr[i], arr[i][this.lazyIndex], this.sublistIndex, i), 149 error: function() { 150 finish.dec(); 151 } 152 }); 153 } 154 } else { 155 fun(arr[i], path.concat(i)); 156 } 157 158 if (arr[i][this.sublistIndex]) 159 this.iterHelper(arr[i][this.sublistIndex], from, to, 160 fun, finish, inc, searchIndex, testIndex, 161 path.concat(i)); 162 i += inc; 163 } 164 }; 165 166 NCList_v0.prototype.iterate = function(from, to, fun, postFun) { 167 // calls the given function once for each of the 168 // intervals that overlap the given interval 169 //if from <= to, iterates left-to-right, otherwise iterates right-to-left 170 171 //inc: iterate leftward or rightward 172 var inc = (from > to) ? -1 : 1; 173 //searchIndex: search on start or end 174 var searchIndex = (from > to) ? 0 : 1; 175 //testIndex: test on start or end 176 var testIndex = (from > to) ? 1 : 0; 177 var finish = new Finisher(postFun); 178 this.iterHelper(this.topList, from, to, fun, finish, 179 inc, searchIndex, testIndex, []); 180 finish.finish(); 181 }; 182 183 NCList_v0.prototype.histogram = function(from, to, numBins, callback) { 184 //calls callback with a histogram of the feature density 185 //in the given interval 186 187 var result = new Array(numBins); 188 var binWidth = (to - from) / numBins; 189 for (var i = 0; i < numBins; i++) result[i] = 0; 190 //this.histHelper(this.topList, from, to, result, numBins, (to - from) / numBins); 191 this.iterate(from, to, 192 function(feat) { 193 var firstBin = 194 Math.max(0, ((feat[0] - from) / binWidth) | 0); 195 var lastBin = 196 Math.min(numBins, ((feat[1] - from) / binWidth) | 0); 197 for (var bin = firstBin; bin <= lastBin; bin++) 198 result[bin]++; 199 }, 200 function() { 201 callback(result); 202 } 203 ); 204 }; 205 206 /* 207 208 Copyright (c) 2007-2009 The Evolutionary Software Foundation 209 210 Created by Mitchell Skinner <mitch_skinner@berkeley.edu> 211 212 This package and its accompanying libraries are free software; you can 213 redistribute it and/or modify it under the terms of the LGPL (either 214 version 2.1, or at your option, any later version) or the Artistic 215 License 2.0. Refer to LICENSE for the full license text. 216 217 */ 218