123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- /*
- * Flot plugin to order bars side by side.
- *
- * Released under the MIT license by Benjamin BUFFET, 20-Sep-2010.
- * Modifications made by Steven Hall <github.com/emmerich>, 01-May-2013.
- *
- * 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
- *
- */
- // INFO: decalage/decallage is French for gap. It's used to denote the spacing applied to each
- // bar.
- (function($){
- function init(plot){
- var orderedBarSeries;
- var nbOfBarsToOrder;
- var borderWidth;
- var borderWidthInXabsWidth;
- var pixelInXWidthEquivalent = 1;
- var isHorizontal = false;
- // A mapping of order integers to decallage.
- var decallageByOrder = {};
- /*
- * 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 we haven't already calculated the decallage for this order value, do it.
- if(typeof decallageByOrder[serie.bars.order] === 'undefined') {
- if (isBarAtLeftOfCenter(position)){
- decallageByOrder[serie.bars.order] = -1*(sumWidth(orderedBarSeries,position-1,Math.floor(nbOfBarsToOrder / 2)-1)) - centerBarShift;
- }else{
- decallageByOrder[serie.bars.order] = sumWidth(orderedBarSeries,Math.ceil(nbOfBarsToOrder / 2),position-2) + centerBarShift + borderWidthInXabsWidth*2;
- }
- }
- // Lookup the decallage based on the series' order value.
- decallage = decallageByOrder[serie.bars.order];
- 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]) ? series[i].data[0][AxeIdx]: null;
- minMaxValues[1] = (series[i].data[series[i].data.length - 1]) ? series[i].data[series[i].data.length - 1][AxeIdx]: null;
- }
- return minMaxValues;
- }
- function retrieveBarSeries(plot){
- orderedBarSeries = findOthersBarsToReOrders(plot.getData());
- nbOfBarsToOrder = orderedBarSeries.length;
- }
- function findOthersBarsToReOrders(series){
- var retSeries = new Array();
- var orderValuesSeen = [];
- for(var i = 0; i < series.length; i++){
- if(series[i].bars.order != null && series[i].bars.show &&
- orderValuesSeen.indexOf(series[i].bars.order) < 0){
- orderValuesSeen.push(series[i].bars.order);
- 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 = typeof serie.bars.lineWidth !== 'undefined' ? 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);
|