Jquery flot multi bars 多个柱状图并列显示问题

honeyth 2015-04-23

最近在用jquery的flot画图,折线图饼图都没啥问题,一到柱状图就来事了,如果多个数据源,柱子都重叠到一起了,像这样:


Jquery flot multi bars 多个柱状图并列显示问题
 

度娘谷哥搜了一大圈,找了一个插件,专门处理这种情况的,但是郁闷的调了半天愣是没反应,该什么样还什么样,眼看工期将至,一咬牙,看源码吧。原来这个插件是在动态调整每个bar的barLeft属性,见代码红色处(jquery.flot.multibar.js):

(function ($) {
    function init(plot) {
        var multiple = true;
        var sArray = [];
        var totWidth = 0;
        
        function procRawData(plot, series, data, datapoints) {
            if(series.bars.show) {
                sArray.push(series);
                
            }
        }
        
        function procDatapoints(plot, series, datapoints) {
            //Ensure we only process these once
            if(series.bars.show && series.bars.barLeft==undefined) {
                if(totWidth==0) {
                    for(var j = 0; j < sArray.length; j++) {
                        totWidth+=sArray[j].bars.barWidth;
                    }
                }
                var runWidth=0;
                for(var k = 0; k < sArray.length; k++) {
                    s=sArray[k];
                    if(s==series) {
                        break;
                    }
                    runWidth+=s.bars.barWidth;
                }
                series.bars.barLeft = runWidth-(totWidth/2);
            }
        }
        
        function checkMultipleBarsEnabled(plot, options) {
            if (options.multiplebars) {
                multiple = options.multiplebars;
                sArray=[];
                totWidth=0;

                plot.hooks.processRawData.push(procRawData);
                plot.hooks.processDatapoints.push(procDatapoints);
            }
        }
    
        plot.hooks.processOptions.push(checkMultipleBarsEnabled);
    }
    
    var options = { multiplebars: true };

    $.plot.plugins.push({
        init: init,
        options: options,
        name: "multiplebars",
        version: "0.1"
    });
})(jQuery);

但是可恶的是,jquery.flot.js自己却重新给barLeft赋值了,见红色代码(jquery.flot.js):

function drawSeriesBars(series) {
            function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {
                var points = datapoints.points, ps = datapoints.pointsize;

                for (var i = 0; i < points.length; i += ps) {
                    if (points[i] == null)
                        continue;
                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
                }
            }

            ctx.save();
            ctx.translate(plotOffset.left, plotOffset.top);

            // FIXME: figure out a way to add shadows (for instance along the right edge)
            ctx.lineWidth = series.bars.lineWidth;
            ctx.strokeStyle = series.color;

            var barLeft;
            
	            switch (series.bars.align) {
	                case "left":
	                    barLeft = 0;
	                    break;
	                case "right":
	                    barLeft = -series.bars.barWidth;
	                    break;
	                default:
	                    barLeft = -series.bars.barWidth / 2;
	            }
          
            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);
            ctx.restore();
        }

 所以,果断的加上判断,要用bars自己的barLeft:

function drawSeriesBars(series) {
            function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {
                var points = datapoints.points, ps = datapoints.pointsize;

                for (var i = 0; i < points.length; i += ps) {
                    if (points[i] == null)
                        continue;
                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
                }
            }

            ctx.save();
            ctx.translate(plotOffset.left, plotOffset.top);

            // FIXME: figure out a way to add shadows (for instance along the right edge)
            ctx.lineWidth = series.bars.lineWidth;
            ctx.strokeStyle = series.color;

            var barLeft;
            if(series.bars.barLeft != undefined){
            	barLeft = series.bars.barLeft;
            }else{
	            switch (series.bars.align) {
	                case "left":
	                    barLeft = 0;
	                    break;
	                case "right":
	                    barLeft = -series.bars.barWidth;
	                    break;
	                default:
	                    barLeft = -series.bars.barWidth / 2;
	            }
          }

            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);
            ctx.restore();
        }

终于显示成如下样子了:


Jquery flot multi bars 多个柱状图并列显示问题
 

相关推荐