1/* 2 * Flot plugin to order bars side by side. This is improved version of Benjamin BUFFET work 3 * originally from http://en.benjaminbuffet.com/labs/flot/. 4 * 5 * Released under the MIT license by Przemyslaw Koltermann, 12-Feb-2013. 6 * 7 * This plugin is an alpha version. 8 * 9 * To activate the plugin you must specify the parameter "order" for the specific serie : 10 * 11 * $.plot($("#placeholder"), [{ data: [ ... ], bars :{ order = null or integer }]) 12 * 13 * If 2 series have the same order param, they are displayed in the same position; 14 * 15 * The plugin adjust the point by adding a value depanding of the barwidth 16 * Exemple for 3 series (barwidth : 0.1) : 17 * 18 * first bar décalage : -0.15 19 * second bar décalage : -0.05 20 * third bar décalage : 0.05 21 * 22 */ 23 24(function($){ 25 function init(plot){ 26 var orderedBarSeries; 27 var nbOfBarsToOrder; 28 var seriesPos = new Array(); 29 var sameSeries = new Array(); 30 var borderWidth; 31 var borderWidthInXabsWidth; 32 var pixelInXWidthEquivalent = 1; 33 var isHorizontal = false; 34 35 /* 36 * This method add shift to x values 37 */ 38 function reOrderBars(plot, serie, datapoints){ 39 var shiftedPoints = null; 40 41 if(serieNeedToBeReordered(serie)){ 42 checkIfGraphIsHorizontal(serie); 43 calculPixel2XWidthConvert(plot); 44 retrieveBarSeries(plot); 45 calculBorderAndBarWidth(serie); 46 47 if(nbOfBarsToOrder >= 2){ 48 var position = findPosition(serie); 49 var decallage = 0; 50 51 var centerBarShift = calculCenterBarShift(); 52 53 if (isBarAtLeftOfCenter(position)){ 54 decallage = -1*(sumWidth(orderedBarSeries,position-1,Math.floor(nbOfBarsToOrder / 2)-1)) - centerBarShift; 55 }else{ 56 decallage = sumWidth(orderedBarSeries,Math.ceil(nbOfBarsToOrder / 2),position-2) + centerBarShift + borderWidthInXabsWidth*2; 57 } 58 59 shiftedPoints = shiftPoints(datapoints,serie,decallage); 60 datapoints.points = shiftedPoints; 61 } else if (nbOfBarsToOrder == 1){ 62 // To be consistent with the barshift at other uneven numbers of bars, where 63 // the center bar is centered around the point, we also need to shift a single bar 64 // left by half its width 65 var centerBarShift = -1*calculCenterBarShift(); 66 shiftedPoints = shiftPoints(datapoints,serie,centerBarShift); 67 datapoints.points = shiftedPoints; 68 } 69 } 70 return shiftedPoints; 71 } 72 73 function serieNeedToBeReordered(serie){ 74 return serie.bars != null 75 && serie.bars.show 76 && serie.bars.order != null; 77 } 78 79 function calculPixel2XWidthConvert(plot){ 80 var gridDimSize = isHorizontal ? plot.getPlaceholder().innerHeight() : plot.getPlaceholder().innerWidth(); 81 var minMaxValues = isHorizontal ? getAxeMinMaxValues(plot.getData(),1) : getAxeMinMaxValues(plot.getData(),0); 82 var AxeSize = minMaxValues[1] - minMaxValues[0]; 83 pixelInXWidthEquivalent = AxeSize / gridDimSize; 84 } 85 86 function getAxeMinMaxValues(series,AxeIdx){ 87 var minMaxValues = new Array(); 88 for(var i = 0; i < series.length; i++){ 89 minMaxValues[0] = series[i].data[0][AxeIdx]; 90 minMaxValues[1] = series[i].data[series[i].data.length - 1][AxeIdx]; 91 } 92 if(typeof minMaxValues[0] == 'string'){ 93 minMaxValues[0] = 0; 94 minMaxValues[1] = series[0].data.length - 1; 95 } 96 return minMaxValues; 97 } 98 99 function retrieveBarSeries(plot){ 100 orderedBarSeries = findOthersBarsToReOrders(plot.getData()); 101 nbOfBarsToOrder = orderedBarSeries.length; 102 } 103
104 function findOthersBarsToReOrders(series){ 105 var retSeries = new Array(); 106 107 for(var i = 0; i < series.length; i++){ 108 if(series[i].bars.order != null && series[i].bars.show){ 109 retSeries.push(series[i]); 110 } 111 } 112 113 return sortByOrder(retSeries); 114 } 115 116 function sortByOrder(series){ 117 var n = series.length; 118 do { 119 for (var i=0; i < n - 1; i++) { 120 if (series[i].bars.order > series[i + 1].bars.order) { 121 var tmp = series[i]; 122 series[i] = series[i + 1]; 123 series[i + 1] = tmp; 124 } 125 else if (series[i].bars.order == series[i + 1].bars.order) { 126 127 //check if any of the series has set sameSeriesArrayIndex 128 var sameSeriesIndex; 129 if (series[i].sameSeriesArrayIndex) { 130 if(series[i + 1].sameSeriesArrayIndex !== undefined) { 131 sameSeriesIndex = series[i].sameSeriesArrayIndex; 132 series[i + 1].sameSeriesArrayIndex = sameSeriesIndex; 133 sameSeries[sameSeriesIndex].push(series[i + 1]); 134 sameSeries[sameSeriesIndex].sort(sortByWidth); 135
136 series[i] = sameSeries[sameSeriesIndex][0]; 137 removeElement(series, i + 1); 138 } 139 } 140 141 else if (series[i + 1].sameSeriesArrayIndex) { 142 if(series[i].sameSeriesArrayIndex !== undefined) { 143 sameSeriesIndex = series[i + 1].sameSeriesArrayIndex; 144 series[i].sameSeriesArrayIndex = sameSeriesIndex; 145 sameSeries[sameSeriesIndex].push(series[i]); 146 sameSeries[sameSeriesIndex].sort(sortByWidth); 147 148 series[i] = sameSeries[sameSeriesIndex][0]; 149 removeElement(series, i + 1); 150 151 } 152 } 153 154 else { 155 sameSeriesIndex = sameSeries.length; 156 sameSeries[sameSeriesIndex] = new Array(); 157 series[i].sameSeriesArrayIndex = sameSeriesIndex; 158 series[i + 1].sameSeriesArrayIndex = sameSeriesIndex; 159 sameSeries[sameSeriesIndex].push(series[i]); 160 sameSeries[sameSeriesIndex].push(series[i + 1]); 161 sameSeries[sameSeriesIndex].sort(sortByWidth); 162
163 series[i] = sameSeries[sameSeriesIndex][0]; 164 removeElement(series, i + 1); 165 } 166 i--; 167 n--; 168 169 170 //leave the wider serie and the other one move to 171 } 172 } 173 n = n-1; 174 } 175 while (n>1); 176 for (var i=0; i < series.length; i++) { 177 if (series[i].sameSeriesArrayIndex) { 178 seriesPos[series[i].sameSeriesArrayIndex] = i; 179 } 180 } 181 return series; 182 } 183 184 function sortByWidth(serie1,serie2){ 185 var x = serie1.bars.barWidth ? serie1.bars.barWidth : 1; 186 var y = serie2.bars.barWidth ? serie2.bars.barWidth : 1; 187 return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 188 } 189 function removeElement(arr, from, to) { 190 var rest = arr.slice((to || from) + 1 || arr.length); 191 arr.length = from < 0 ? arr.length + from : from; 192 arr.push.apply(arr, rest); 193 return arr; 194 } 195 196 function calculBorderAndBarWidth(serie){ 197 borderWidth = typeof serie.bars.lineWidth === "number" ? serie.bars.lineWidth : 2; 198 borderWidthInXabsWidth = borderWidth * pixelInXWidthEquivalent; 199 } 200 201 function checkIfGraphIsHorizontal(serie){ 202 if(serie.bars.horizontal){ 203 isHorizontal = true; 204 } 205 } 206 207 function findPosition(serie){ 208 var ss = sameSeries; 209 var pos = 0; 210 if (serie.sameSeriesArrayIndex) { 211 pos = seriesPos[serie.sameSeriesArrayIndex]; 212 } 213 else { 214 for (var i = 0; i < orderedBarSeries.length; ++i) { 215 if (serie == orderedBarSeries[i]){ 216 pos = i; 217 break; 218 } 219 } 220 } 221 return pos+1; 222 } 223 224 function calculCenterBarShift(){ 225 var width = 0; 226 227 if(nbOfBarsToOrder%2 != 0) 228 // Since the array indexing starts at 0, we need to use Math.floor instead of 229 // Math.ceil otherwise we will get an error if there is only one bar 230 width = (orderedBarSeries[Math.floor(nbOfBarsToOrder / 2)].bars.barWidth)/2; 231 232 return width; 233 } 234 235 function isBarAtLeftOfCenter(position){ 236 return position <= Math.ceil(nbOfBarsToOrder / 2); 237 } 238 239 function sumWidth(series,start,end){ 240 var totalWidth = 0; 241 242 for(var i = start; i <= end; i++){ 243 totalWidth += series[i].bars.barWidth+borderWidthInXabsWidth*2; 244 } 245 246 return totalWidth; 247 } 248 249 function shiftPoints(datapoints,serie,dx){ 250 var ps = datapoints.pointsize; 251 var points = datapoints.points; 252 var j = 0; 253 for(var i = isHorizontal ? 1 : 0;i < points.length; i += ps){ 254 points[i] += dx; 255 //Adding the new x value in the serie to be abble to display the right tooltip value, 256 //using the index 3 to not overide the third index. 257 serie.data[j][3] = points[i]; 258 j++; 259 } 260 261 return points; 262 } 263 264 plot.hooks.processDatapoints.push(reOrderBars); 265 266 } 267 268 var options = { 269 series : { 270 bars: {order: null} // or number/string 271 } 272 }; 273 274 $.plot.plugins.push({ 275 init: init, 276 options: options, 277 name: "orderBars", 278 version: "0.2" 279 }); 280 281})(jQuery); 282
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.