如何使用jqplot和堆积条形图更改一个特定条形图的颜色

时间:2014-12-19 16:58:16

标签: colors charts jqplot diagram

我有一个直截了当的问题。是否可以以任何方式更改堆积条形图中一个条形的颜色(使用jqplot选项或依赖于hack)?

我有这个:

enter image description here

我想要这个:

enter image description here

因此,您已经可以假设我使用3种不同的颜色作为堆积条形图:

seriesColors: ['#afafaf', '#c4c6c4', '#dbdcdd']

问题是我想为1个特定的栏添加一种特定的颜色。

这是JS代码:

$(document).ready(
    function() {

        var el = [ 3, 6, 0, 10, 12 ];
        var ael = [ 14, 5, 0, 4, 2 ];
        var ipv = [ 4, 9, 0, 8, 4 ];
        var months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May' ];
        var colors = ['blue', 'red', 'white'];

        plot3 = $.jqplot('elDiagram', [ el, ael, ipv ], {
            stackSeries : true,
            seriesColors: colors,
            captureRightClick : true,
            seriesDefaults : {
                renderer : $.jqplot.BarRenderer,
                rendererOptions : {
                    barMargin : 30,
                    varyBarColor : true,
                    highlightMouseDown : true,
                    barWidth: 60
                },
                pointLabels : {
                    show : true
                }
            },
            axes : {
                xaxis : {
                    renderer : $.jqplot.CategoryAxisRenderer,
                    ticks : months,
                    tickOptions : {
                        mark : 'outside'
                    }
                },
                yaxis : {
                    tickOptions : {
                        show : false
                    },
                    padMin : 0
                }
            },
            series : [ {
                label : 'bla1'
            }, {
                label : 'bla2'
            }, {
                label : 'bla3'
            } ],
            legend : {
                show : true,
                location : 'ne',
                placement : 'inside'
            }
        });     
    });

谢谢!

1 个答案:

答案 0 :(得分:0)

好的,解决方案是一个黑客,我将在这里展示和描述:

  1. 你需要覆盖名为$ .jqplot.BarRenderer.prototype.draw的函数并更改一些行
  2. 您需要覆盖名为getStart的函数(sidx,didx,comp,plot,axis)
  3. 你需要覆盖名为$ .jqplot.ShapeRenderer.prototype.draw的函数并更改一些行
  4. 1:

    $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options, plot) {
       var i;
       // Ughhh, have to make a copy of options b/c it may be
       // modified later.
       var opts = $.extend({}, options);
    
       .................................
       <other code>
       .................................
    
       var clr = opts.fillStyle || this.color;
       this._dataColors.push(clr);
       this.renderer.shapeRenderer.draw(ctx, points, opts, i, pos); // changed line
    

    我改变了这条线,我将i和pos参数添加到函数中。原因是指示栏中的当前栏和位置。

    2:

    function getStart(sidx, didx, comp, plot, axis) {
       // check if sign change
       var seriesIndex = sidx, prevSeriesIndex = sidx - 1, start, prevVal, aidx = (axis === 'x') ? 0 : 1;
       // is this not the first series?
       if (seriesIndex > 0) {
           prevVal = plot.series[prevSeriesIndex]._plotData[didx][aidx];
           // is there a sign change
           if ((comp * prevVal) < 0) {
               start = getStart(prevSeriesIndex, didx, comp, plot, axis);
           }
           // no sign change.
           else {
               start = plot.series[prevSeriesIndex].gridData[didx][aidx];
           }
       }
       // if first series, return value at 0
       else {
           start = (aidx === 0) ? plot.series[seriesIndex]._xaxis.series_u2p(0) : plot.series[seriesIndex]._yaxis.series_u2p(0);
       }
       return start;
    }
    

    这里没有任何改变。您只需要复制该函数,因为新的覆盖函数无法从jQPlot库中使用它。

    3:

    $.jqplot.ShapeRenderer.prototype.draw = function(ctx, points, options, currentBar, position) {
        ctx.save();
        var opts = (options != null) ? options : {};
        var fill = (opts.fill != null) ? opts.fill : this.fill;
        var closePath = (opts.closePath != null) ? opts.closePath : this.closePath;
        var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect;
        var strokeRect = (opts.strokeRect != null) ? opts.strokeRect
                : this.strokeRect;
        var clearRect = (opts.clearRect != null) ? opts.clearRect : this.clearRect;
        var isarc = (opts.isarc != null) ? opts.isarc : this.isarc;
        var linePattern = (opts.linePattern != null) ? opts.linePattern
                : this.linePattern;
        var ctxPattern = $.jqplot.LinePattern(ctx, linePattern);
        ctx.lineWidth = opts.lineWidth || this.lineWidth;
        ctx.lineJoin = opts.lineJoin || this.lineJoin;
        ctx.lineCap = opts.lineCap || this.lineCap;
        ctx.strokeStyle = (opts.strokeStyle || opts.color) || this.strokeStyle;
        ctx.fillStyle = opts.fillStyle || this.fillStyle;
        if (currentBar == activeColumn && position == 0) { // adding different color for the specific bar
            ctx.fillStyle = defaultColors[0];
        } else if (currentBar == activeColumn && position == 1) {
            ctx.fillStyle = defaultColors[1];
        } else if (currentBar == activeColumn && position == 2) {
            ctx.fillStyle = defaultColors[2];
        }
        ctx.beginPath();
        if (isarc) {
            ctx.arc(points[0], points[1], points[2], points[3], points[4], true);
            if (closePath) {
                ctx.closePath();
            }
            if (fill) {
                ctx.fill();
            } else {
                ctx.stroke();
            }
            ctx.restore();
            return;
        } else if (clearRect) {
            ctx.clearRect(points[0], points[1], points[2], points[3]);
            ctx.restore();
            return;
        } else if (fillRect || strokeRect) {
            if (fillRect) {
                ctx.fillRect(points[0], points[1], points[2], points[3]);
            }
            if (strokeRect) {
                ctx.strokeRect(points[0], points[1], points[2], points[3]);
                ctx.restore();
                return;
            }
        } else if (points && points.length) {
            var move = true;
            for ( var i = 0; i < points.length; i++) {
                // skip to the first non-null point and move to it.
                if (points[i][0] != null && points[i][1] != null) {
                    if (move) {
                        ctxPattern.moveTo(points[i][0], points[i][1]);
                        move = false;
                    } else {
                        ctxPattern.lineTo(points[i][0], points[i][1]);
                    }
                } else {
                    move = true;
                }
            }
            if (closePath) {
                ctxPattern.closePath();
            }
            if (fill) {
                ctx.fill();
            } else {
                ctx.stroke();
            }
        }
        ctx.restore();
    };
    

    在这里,你需要检查你当前所在的栏是否是默认栏。代码的重要部分是:

    if (currentBar == activeColumn && position == 0) { // adding different color for the specific bar
        ctx.fillStyle = defaultColors[0];
    } else if (currentBar == activeColumn && position == 1) {
        ctx.fillStyle = defaultColors[1];
    } else if (currentBar == activeColumn && position == 2) {
        ctx.fillStyle = defaultColors[2];
    }
    

    我为那个酒吧添加了3种不同颜色,只是为了拥有“更加花哨”的图表:)