foxcharts: how to make SideLegend order = StackedBar order?

Topics: Bug Information
Apr 14, 2010 at 3:09 PM

I've got a few vertical stacked-bar charts.   In all cases, by default, the sideLegend is (somewhat illogically) in 'descending' order, the opposite of the bars on the chart.  Bug?

You can easily repro this behaviour with the "Main Charts sample":

1)  Set the Chart Type to Full-stacked Bars.

2) examine the colors... you'll see that the SideLegend's GR1-GR5 presented in the reverse order of the stacked values they represent.  Is there an easy way to change this?  I want them to be in the same order.

All comments most appreciated... 

Apr 14, 2010 at 5:37 PM

Hi,

Indeed with stacked bars the legend in position 1,2,3,4,11,&12 do not tally with the stacked position. This needs to be corrected. Meanwhile the other positions do tally and since this effect is only on the stacked graphs, I dont think it will quickly be repaired. If you cant live without this bug,there seems only a private subclassing with correct position a solution. Is this workable for you?

 

Regards,

Koen

Apr 17, 2010 at 11:21 PM
Edited Apr 17, 2010 at 11:28 PM

Hi,

If you are interested, I have changed the method _drawsidelegends so the legend will tally the chart on stacked charttypes. Please subclass the original FoxCharts , copy the original _drawsidelegends and replace the coding between   *Save the current _CharIndex and * Restore the current _CharIndex  with the following:

 

 

   *Save the current _CharIndex
    lnOrigIndex = this._ChartIndex
    
    if inlist(this.Charttype,3,9,16,10)
    
        && sidelegends down-up
        for i = lnCount to 1 step -1
            if m.y1 <= 0
                exit
            endif
            this._ChartIndex = m.lnCount - 1

            lcCaption = this._aSideLegends((m.lnCount - i) +1,1)
            if empty(m.lcCaption)
                loop
            endif

            this.SideLegend.caption = m.lcCaption
            this.SideLegend._drawString(m.x1 + m.lnWidth + 3, m.y1)
            this._UpdateCoordinates("Legend", m.x1, m.y1, m.lnWidth + this.SideLegend._Width + 5, m.lnLegendHeight, m.i, m.lcCaption)
            this._PrepareBrushes(m.x1, m.y1, m.lnWidth, m.lnHeight, .t., m.i)
            this.oGfx.FillRectangle(this._oMainBrush, m.x1, m.y1, m.lnWidth, m.lnHeight)
            this.oGfx.DrawRectangle(this._oBorderPen, m.x1, m.y1, m.lnWidth, m.lnHeight)

            if llHorizontal && Horizontal side legends
                x1 = m.x1 + m.lnWidth + 10 + this.SideLegend._Width
            else
                y1 = m.y1 + lnLegendHeight
            endif

        next
    ELSE
        &&sidelegends down-up
        for i = 1 to lnCount

            if y1 <= 0
                exit
            endif

            this._ChartIndex = m.i

            lcCaption = this._aSideLegends(m.i,1)
            if empty(m.lcCaption)
                loop
            endif

            this.SideLegend.caption = m.lcCaption
            this.SideLegend._drawString(m.x1 + m.lnWidth + 3, m.y1)

            this._UpdateCoordinates("Legend", m.x1, m.y1, m.lnWidth + this.SideLegend._Width + 5, m.lnLegendHeight, m.i, m.lcCaption)

            do case
                case this.Charttype = 5 ;
                        and this._3D = 0 ;
                        and this.BrushType = 3 ; && Line, Plain, Monochrome
                    and not this.Multichart
                    loLinePen = .pen.New(this._oClrBlack, 3)
                    loLinePen.DashStyle = i - 1 && _Screen.System.Drawing.Drawing2D.DashStyle.Dash
                    this.oGfx.DrawLine(loLinePen, m.x1, .y1 + m.lnHeight / 2, m.x1 + m.lnWidth, y1 + m.lnHeight / 2)

                case (this.Charttype = 4 ; && Point
                    or (this.Charttype = 5 and this._3D = 0 and this.LineCaps = .t.)) ; && Plain line
                    and not this.Multichart
                    local loPath as xfcGraphicsPath
                    loPath = this._aShapes(i,1)

                    if vartype(loPath) <> "O"
                        return  &&&potential C0005
                    endif

                    if inlist(lower(loPath.class),"xfcbitmap", "xfcimage")
                        this.oGfx.DrawImage(loPath, m.x1, m.y1, m.lnWidth, m.lnHeight)
                    else

                        this._DrawShape(m.x1 + m.lnWidth / 2, m.y1 + m.lnHeight / 2, 0, "Legend")
                        if this._aShapes(i,3) > m.lnLegendHeight
                            lnLegendHeight = this._aShapes(i,3) + 1
*                    y1 = y1 + This._aShapes(i,3) + 3
                        endif
                    endif

                otherwise

                    this._PrepareBrushes(m.x1, m.y1, m.lnWidth, m.lnHeight, .t., m.i)
                    this.oGfx.FillRectangle(this._oMainBrush, m.x1, m.y1, m.lnWidth, m.lnHeight)
                    this.oGfx.DrawRectangle(this._oBorderPen, m.x1, m.y1, m.lnWidth, m.lnHeight)

            endcase

            if llHorizontal && Horizontal side legends
                x1 = m.x1 + m.lnWidth + 10 + this.SideLegend._Width
            else
                y1 = m.y1 + lnLegendHeight
            endif

        endfor
    endif

* Restore the current _CharIndex


 

Regards,

 

Koen

Apr 21, 2010 at 5:14 PM

Koen,

Thank you so much!   Perfect...

-bob

 

Apr 21, 2010 at 9:36 PM
Bob, glad it serves you. Koen