/* * Flot plugin to order bars side by side. * * Released under the MIT license by Benjamin BUFFET, 20-Sep-2010. * * This plugin is an alpha version. * * To activate the plugin you must specify the parameter "order" for the specific serie : * * $.plot($("#placeholder"), [{ data: [ ... ], bars :{ order = null or integer }]) * * If 2 series have the same order param, they are ordered by the position in the array; * * The plugin adjust the point by adding a value depanding of the barwidth * Exemple for 3 series (barwidth : 0.1) : * * first bar décalage : -0.15 * second bar décalage : -0.05 * third bar décalage : 0.05 * */ (function($){ function init(plot){ var orderedBarSeries; var nbOfBarsToOrder; var borderWidth; var borderWidthInXabsWidth; var pixelInXWidthEquivalent = 1; var isHorizontal = false; /* * This method add shift to x values */ function reOrderBars(plot, serie, datapoints){ var shiftedPoints = null; if(serieNeedToBeReordered(serie)){ checkIfGraphIsHorizontal(serie); calculPixel2XWidthConvert(plot); retrieveBarSeries(plot); calculBorderAndBarWidth(serie); if(nbOfBarsToOrder >= 2){ var position = findPosition(serie); var decallage = 0; var centerBarShift = calculCenterBarShift(); if (isBarAtLeftOfCenter(position)){ decallage = -1*(sumWidth(orderedBarSeries,position-1,Math.floor(nbOfBarsToOrder / 2)-1)) - centerBarShift; }else{ decallage = sumWidth(orderedBarSeries,Math.ceil(nbOfBarsToOrder / 2),position-2) + centerBarShift + borderWidthInXabsWidth*2; } shiftedPoints = shiftPoints(datapoints,serie,decallage); datapoints.points = shiftedPoints; } } return shiftedPoints; } function serieNeedToBeReordered(serie){ return serie.bars != null && serie.bars.show && serie.bars.order != null; } function calculPixel2XWidthConvert(plot){ var gridDimSize = isHorizontal ? plot.getPlaceholder().innerHeight() : plot.getPlaceholder().innerWidth(); var minMaxValues = isHorizontal ? getAxeMinMaxValues(plot.getData(),1) : getAxeMinMaxValues(plot.getData(),0); var AxeSize = minMaxValues[1] - minMaxValues[0]; pixelInXWidthEquivalent = AxeSize / gridDimSize; } function getAxeMinMaxValues(series,AxeIdx){ var minMaxValues = new Array(); for(var i = 0; i < series.length; i++){ minMaxValues[0] = series[i].data[0][AxeIdx]; minMaxValues[1] = series[i].data[series[i].data.length - 1][AxeIdx]; } return minMaxValues; } function retrieveBarSeries(plot){ orderedBarSeries = findOthersBarsToReOrders(plot.getData()); nbOfBarsToOrder = orderedBarSeries.length; } function findOthersBarsToReOrders(series){ var retSeries = new Array(); for(var i = 0; i < series.length; i++){ if(series[i].bars.order != null && series[i].bars.show){ retSeries.push(series[i]); } } return retSeries.sort(sortByOrder); } function sortByOrder(serie1,serie2){ var x = serie1.bars.order; var y = serie2.bars.order; return ((x < y) ? -1 : ((x > y) ? 1 : 0)); } function calculBorderAndBarWidth(serie){ borderWidth = serie.bars.lineWidth ? serie.bars.lineWidth : 2; borderWidthInXabsWidth = borderWidth * pixelInXWidthEquivalent; } function checkIfGraphIsHorizontal(serie){ if(serie.bars.horizontal){ isHorizontal = true; } } function findPosition(serie){ var pos = 0 for (var i = 0; i < orderedBarSeries.length; ++i) { if (serie == orderedBarSeries[i]){ pos = i; break; } } return pos+1; } function calculCenterBarShift(){ var width = 0; if(nbOfBarsToOrder%2 != 0) width = (orderedBarSeries[Math.ceil(nbOfBarsToOrder / 2)].bars.barWidth)/2; return width; } function isBarAtLeftOfCenter(position){ return position <= Math.ceil(nbOfBarsToOrder / 2); } function sumWidth(series,start,end){ var totalWidth = 0; for(var i = start; i <= end; i++){ totalWidth += series[i].bars.barWidth+borderWidthInXabsWidth*2; } return totalWidth; } function shiftPoints(datapoints,serie,dx){ var ps = datapoints.pointsize; var points = datapoints.points; var j = 0; for(var i = isHorizontal ? 1 : 0;i < points.length; i += ps){ points[i] += dx; //Adding the new x value in the serie to be abble to display the right tooltip value, //using the index 3 to not overide the third index. serie.data[j][3] = points[i]; j++; } return points; } plot.hooks.processDatapoints.push(reOrderBars); } var options = { series : { bars: {order: null} // or number/string } }; $.plot.plugins.push({ init: init, options: options, name: "orderBars", version: "0.2" }); })(jQuery);