stacked bars

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
strobbekoen
Newbie
Newbie
Posts: 23
Joined: Tue Feb 10, 2009 12:00 am

stacked bars

Post by strobbekoen » Mon Aug 13, 2012 11:01 am

Hi,

I have groups of bar series in a chart, with 2 stack groups.
Each color and group is a bar series.
I have the MultiBar property set to mbStacked, and StackGroup set to 0 for first group and 1 for the second.
Each group is on a custom y-axis, bottom axis is shared for all series.
The bars of the groups do not lign up on the bottom axis, while with a single group they do. See attachments.

Is there any way to make them lign up when stacked ?
Attachments
iqo2_periodic2.gif
iqo2_periodic2.gif (20.01 KiB) Viewed 8706 times
iqo2_periodic.gif
iqo2_periodic.gif (16.49 KiB) Viewed 8649 times

Yeray
Site Admin
Site Admin
Posts: 9612
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: stacked bars

Post by Yeray » Mon Aug 13, 2012 2:19 pm

Hi,
strobbekoen wrote:Is there any way to make them lign up when stacked ?
The stacked style wasn't thought to be split in different axes. That's why an offset is applied to the groups. However, this offset could be undone ie using the OnGetBarStyle as follows (having 2 stack groups):

Code: Select all

Procedure TForm1.SeriesGetBarStyle(Sender:TCustomBarSeries; ValueIndex:Integer; var TheBarStyle:TBarStyle);
begin
  if Sender.StackGroup=0 then
    Sender.OffsetPercent:=50
  else
    Sender.OffsetPercent:=-50;
end;
Note an extra repaint may be needed for the change to be applied to the first two columns too.
FYI, here it is the code of my Create method, where I set up the chart and the series in my testing program:

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
var nGroup, nSeries: Integer;
begin
  Chart1.Legend.Visible:=false;
  Chart1.MarginLeft:=10;

  for nGroup:=0 to 1 do
  begin
    with Chart1.CustomAxes.Add as TChartAxis do
    begin
      StartPosition:=nGroup * (100 div 2);
      EndPosition:=(nGroup + 1) * (100 div 2);
    end;

    for nSeries:=0 to 4 do
      with Chart1.AddSeries(TBarSeries) as TBarSeries do
      begin
        CustomVertAxis:=Chart1.CustomAxes[nGroup];
        MultiBar:=mbStacked;
        StackGroup:=nGroup;
        Marks.Visible:=false;
        Transparency:=20;
        FillSampleValues(10);

        OnGetBarStyle:=SeriesGetBarStyle;
      end;
  end;

  Chart1.Draw;
end;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

strobbekoen
Newbie
Newbie
Posts: 23
Joined: Tue Feb 10, 2009 12:00 am

Re: stacked bars

Post by strobbekoen » Mon Aug 13, 2012 3:23 pm

Thank you for the helpful answer, it works.

Since I create the series at run time, I set the OffsetPercent directly when creating the series instead of using the event.

I attached a few more shots:

iqo2_periodic3 and iqo2_periodic4 display the same period in weeks, but one with a single stackgroup, the other with two.
You can see the bar width has changed, I assume because the chart calculates the bar width thinking the bars of the two stackgroups will not be aligned on the bottom axis (as was the issue originally); so there is more white space.
Is it possible to remove this white space and get the same bar widths as for the single stackgroup ?

iqo2_periodic4 displays the same period as above in days (so there are more points).
I use Chart3DPercent (set to 5) to display the bars in 3D.
The bottom axis ticks (with the labels) are in the center of the front of the bars, while the grid is aligned to the center of the back of the bars.
As the bars get more narrow, this creates a visual effect that the bars are slightly misaligned (alignment is actually correct though).
As far as I can think of is to calibrate the 3D percentage according to the number of data points instead of a fixed value.
Or maybe you have a better alternative ?

Many thanks.

strobbekoen
Newbie
Newbie
Posts: 23
Joined: Tue Feb 10, 2009 12:00 am

Re: stacked bars

Post by strobbekoen » Mon Aug 13, 2012 3:25 pm

Sorry, I forgot the attachments.
Attachments
iqo2_periodic5.gif
iqo2_periodic5.gif (109.56 KiB) Viewed 8592 times
iqo2_periodic4.gif
iqo2_periodic4.gif (18.58 KiB) Viewed 8611 times
iqo2_periodic3.gif
iqo2_periodic3.gif (21.98 KiB) Viewed 8598 times

Yeray
Site Admin
Site Admin
Posts: 9612
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: stacked bars

Post by Yeray » Tue Aug 14, 2012 9:26 am

Hi,
strobbekoen wrote:iqo2_periodic3 and iqo2_periodic4 display the same period in weeks, but one with a single stackgroup, the other with two.
You can see the bar width has changed, I assume because the chart calculates the bar width thinking the bars of the two stackgroups will not be aligned on the bottom axis (as was the issue originally); so there is more white space.
Is it possible to remove this white space and get the same bar widths as for the single stackgroup ?
You could use the CustomBarWidth property to define the bars width. However, it means this width should be calculated by you. Find below an example of it:

Code: Select all

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var nGroup, nSeries, tmpWidth: Integer;
begin
  Chart1.Legend.Visible:=false;
  Chart1.MarginLeft:=10;

  for nGroup:=0 to 1 do
  begin
    with Chart1.CustomAxes.Add as TChartAxis do
    begin
      StartPosition:=nGroup * (100 div 2);
      EndPosition:=(nGroup + 1) * (100 div 2);
    end;

    for nSeries:=0 to 4 do
      with Chart1.AddSeries(TBarSeries) as TBarSeries do
      begin
        CustomVertAxis:=Chart1.CustomAxes[nGroup];
        OffsetPercent:=50+(nGroup*-1)*100;
        MultiBar:=mbStacked;
        StackGroup:=nGroup;
        Marks.Visible:=false;
        Transparency:=20;
        FillSampleValues(10);

        if nSeries=0 then
        begin
          Chart1.Draw;
          tmpWidth:=Round((BarWidthPercent*0.01)*(GetHorizAxis.IAxisSize div 11));
          Chart1.Axes.Bottom.MinimumOffset:=tmpWidth;
          Chart1.Axes.Bottom.MaximumOffset:=tmpWidth;
        end;

        CustomBarWidth:=tmpWidth;
      end;
  end;
end;
strobbekoen wrote:iqo2_periodic4 displays the same period as above in days (so there are more points).
I use Chart3DPercent (set to 5) to display the bars in 3D.
The bottom axis ticks (with the labels) are in the center of the front of the bars, while the grid is aligned to the center of the back of the bars.
As the bars get more narrow, this creates a visual effect that the bars are slightly misaligned (alignment is actually correct though).
As far as I can think of is to calibrate the 3D percentage according to the number of data points instead of a fixed value.
Or maybe you have a better alternative ?
I don't know what will be the best alternative, but I can think on:

- Use the AxisBehind (true by default) to move the grid to the front:

Code: Select all

  Chart1.AxisBehind:=false;
- Move the bottom axis to the back. Note you may need to increment the TickLength too.
All this still gives an unaligned aspect.

Code: Select all

  Chart1.Chart3DPercent:=5;
  with Chart1.Axes.Bottom do
  begin
    ZPosition:=100;
    TickLength:=10;
  end;
- Use the grid centered property to move the grid between the bars.

Code: Select all

  Chart1.Axes.Bottom.Grid.Centered:=true;
- Simply hide the bottom axis grid:

Code: Select all

  Chart1.Axes.Bottom.Grid.Visible:=false;
And congratulations for the application. Looks promising :!:
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

strobbekoen
Newbie
Newbie
Posts: 23
Joined: Tue Feb 10, 2009 12:00 am

Re: stacked bars

Post by strobbekoen » Tue Aug 14, 2012 10:21 am

Thank you for the suggestions and the compliment.
I will try your suggestions and see which one works best. Thanks for the help :)

Post Reply