OpenSencillo  2015.009
Long live the simplicity of PHP
 All Data Structures Namespaces Files Functions Pages
jquery.flot.orderBars.js
1 /*
2  * Flot plugin to order bars side by side.
3  *
4  * Released under the MIT license by Benjamin BUFFET, 20-Sep-2010.
5  * Modifications made by Steven Hall <github.com/emmerich>, 01-May-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 ordered by the position in the array;
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 // INFO: decalage/decallage is French for gap. It's used to denote the spacing applied to each
25 // bar.
26 (function($){
27  function init(plot){
28  var orderedBarSeries;
29  var nbOfBarsToOrder;
30  var borderWidth;
31  var borderWidthInXabsWidth;
32  var pixelInXWidthEquivalent = 1;
33  var isHorizontal = false;
34 
35  // A mapping of order integers to decallage.
36  var decallageByOrder = {};
37 
38  /*
39  * This method add shift to x values
40  */
41  function reOrderBars(plot, serie, datapoints){
42  var shiftedPoints = null;
43 
44  if(serieNeedToBeReordered(serie)){
45  checkIfGraphIsHorizontal(serie);
46  calculPixel2XWidthConvert(plot);
47  retrieveBarSeries(plot);
48  calculBorderAndBarWidth(serie);
49 
50  if(nbOfBarsToOrder >= 2){
51  var position = findPosition(serie);
52  var decallage = 0;
53 
54  var centerBarShift = calculCenterBarShift();
55 
56  // If we haven't already calculated the decallage for this order value, do it.
57  if(typeof decallageByOrder[serie.bars.order] === 'undefined') {
58  if (isBarAtLeftOfCenter(position)){
59  decallageByOrder[serie.bars.order] = -1*(sumWidth(orderedBarSeries,position-1,Math.floor(nbOfBarsToOrder / 2)-1)) - centerBarShift;
60  }else{
61  decallageByOrder[serie.bars.order] = sumWidth(orderedBarSeries,Math.ceil(nbOfBarsToOrder / 2),position-2) + centerBarShift + borderWidthInXabsWidth*2;
62  }
63  }
64 
65  // Lookup the decallage based on the series' order value.
66  decallage = decallageByOrder[serie.bars.order];
67 
68  shiftedPoints = shiftPoints(datapoints,serie,decallage);
69  datapoints.points = shiftedPoints;
70  }
71  }
72  return shiftedPoints;
73  }
74 
75  function serieNeedToBeReordered(serie){
76  return serie.bars != null
77  && serie.bars.show
78  && serie.bars.order != null;
79  }
80 
81  function calculPixel2XWidthConvert(plot){
82  var gridDimSize = isHorizontal ? plot.getPlaceholder().innerHeight() : plot.getPlaceholder().innerWidth();
83  var minMaxValues = isHorizontal ? getAxeMinMaxValues(plot.getData(),1) : getAxeMinMaxValues(plot.getData(),0);
84  var AxeSize = minMaxValues[1] - minMaxValues[0];
85  pixelInXWidthEquivalent = AxeSize / gridDimSize;
86  }
87 
88  function getAxeMinMaxValues(series,AxeIdx){
89  var minMaxValues = new Array();
90  for(var i = 0; i < series.length; i++){
91  minMaxValues[0] = (series[i].data[0]) ? series[i].data[0][AxeIdx]: null;
92  minMaxValues[1] = (series[i].data[series[i].data.length - 1]) ? series[i].data[series[i].data.length - 1][AxeIdx]: null;
93  }
94  return minMaxValues;
95  }
96 
97  function retrieveBarSeries(plot){
98  orderedBarSeries = findOthersBarsToReOrders(plot.getData());
99  nbOfBarsToOrder = orderedBarSeries.length;
100  }
101 
102  function findOthersBarsToReOrders(series){
103  var retSeries = new Array();
104  var orderValuesSeen = [];
105 
106  for(var i = 0; i < series.length; i++){
107  if(series[i].bars.order != null && series[i].bars.show &&
108  orderValuesSeen.indexOf(series[i].bars.order) < 0){
109 
110  orderValuesSeen.push(series[i].bars.order);
111  retSeries.push(series[i]);
112  }
113  }
114  return retSeries.sort(sortByOrder);
115  }
116 
117  function sortByOrder(serie1,serie2){
118  var x = serie1.bars.order;
119  var y = serie2.bars.order;
120  return ((x < y) ? -1 : ((x > y) ? 1 : 0));
121  }
122 
123  function calculBorderAndBarWidth(serie){
124  borderWidth = typeof serie.bars.lineWidth !== 'undefined' ? serie.bars.lineWidth : 2;
125  borderWidthInXabsWidth = borderWidth * pixelInXWidthEquivalent;
126  }
127 
128  function checkIfGraphIsHorizontal(serie){
129  if(serie.bars.horizontal){
130  isHorizontal = true;
131  }
132  }
133 
134  function findPosition(serie){
135  var pos = 0
136  for (var i = 0; i < orderedBarSeries.length; ++i) {
137  if (serie == orderedBarSeries[i]){
138  pos = i;
139  break;
140  }
141  }
142 
143  return pos+1;
144  }
145 
146  function calculCenterBarShift(){
147  var width = 0;
148 
149  if(nbOfBarsToOrder%2 != 0)
150  width = (orderedBarSeries[Math.ceil(nbOfBarsToOrder / 2)].bars.barWidth)/2;
151 
152  return width;
153  }
154 
155  function isBarAtLeftOfCenter(position){
156  return position <= Math.ceil(nbOfBarsToOrder / 2);
157  }
158 
159  function sumWidth(series,start,end){
160  var totalWidth = 0;
161 
162  for(var i = start; i <= end; i++){
163  totalWidth += series[i].bars.barWidth+borderWidthInXabsWidth*2;
164  }
165 
166  return totalWidth;
167  }
168 
169  function shiftPoints(datapoints,serie,dx){
170  var ps = datapoints.pointsize;
171  var points = datapoints.points;
172  var j = 0;
173  for(var i = isHorizontal ? 1 : 0;i < points.length; i += ps){
174  points[i] += dx;
175  //Adding the new x value in the serie to be abble to display the right tooltip value,
176  //using the index 3 to not overide the third index.
177  serie.data[j][3] = points[i];
178  j++;
179  }
180 
181  return points;
182  }
183 
184  plot.hooks.processDatapoints.push(reOrderBars);
185 
186  }
187 
188  var options = {
189  series : {
190  bars: {order: null} // or number/string
191  }
192  };
193 
194  $.plot.plugins.push({
195  init: init,
196  options: options,
197  name: "orderBars",
198  version: "0.2"
199  });
200 
201 })(jQuery);