auto bar width problems

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Trusler
Newbie
Newbie
Posts: 3
Joined: Fri Nov 15, 2002 12:00 am

auto bar width problems

Post by Trusler » Thu Jan 19, 2012 4:06 pm

AutoBarWidth makes bars too skinny as soon as a line series is added to the chart.

To duplicate:
1) Drop a TChart on a form.
2) Invoke the editor
3) Add 2 vertical bar series. The bar width will be as expected.
4) Add a line series. The bar width of any bar series will be reduced to a few pixels (about 10% of available space, rather than default 70%)

Is this a bug?
How can this problem be overcome?

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

Re: auto bar width problems

Post by Yeray » Fri Jan 20, 2012 4:51 pm

Hi Trusler,

I see it at a normal behaviour. Note that adding a Line series in the editor, it adds 25 points to it, while the bar series have 6 points each. This means some place between the bars is needed to fit all the line points.
It can be seen clearer if you set the chart to 2D and you set the line series pointer to be visible.
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

Trusler
Newbie
Newbie
Posts: 3
Joined: Fri Nov 15, 2002 12:00 am

Re: auto bar width problems

Post by Trusler » Sun Jan 22, 2012 4:33 pm

My particular context at the moment is 2D bar charts with a smoothed line series. Marks are useless with precise functions, since there would ideally be one point calculated per horizontal pixel. In any case, marks are not relevant to the issue, as you'll see from my example. To reproduce, simply drop a TChart on a form and add series with the default, random data.

In Figure 1, we have 2 bar series.
one.jpg
one.jpg (109.14 KiB) Viewed 6361 times
In Figure 2, we've added a 3rd bar series, and the widths have adjusted by being reduced by 1/3, as we would expect, so that the width of all bars collectively remains the same.
two.jpg
two.jpg (121.35 KiB) Viewed 6358 times
In figure 3, we add a smoothed line series. The bar widths collapse almost to a single pixel, and the collective width of all bars has shrunk disproportionally to a very low level.
three.jpg
three.jpg (129.57 KiB) Viewed 6362 times
Interestingly, adding more line series has no effect on auto bar width - the effect is immediately total, unlike adding bar series, where bars only gradually and proportionally narrow.

Arguably, a line series should have no effect on bar series widths, as they do not compete for space on the bottom axis. A naive implementation would have the introduction of a line series reduce the auto bar width proportionally, as if the line series were being counted as a bar series. But reducing the auto bar width to nearly nothing and rendering them unreadable is not a reasonable nor a naive implementation. Also, it clearly runs contrary to the intent of the auto-bar width feature, which is to have useful bar widths when possible.

Hence, I think you can see that this is a bug.

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

Re: auto bar width problems

Post by Yeray » Mon Jan 23, 2012 11:34 am

Hi Trusler,
Trusler wrote:In figure 3, we add a smoothed line series. The bar widths collapse almost to a single pixel, and the collective width of all bars has shrunk disproportionally to a very low level.
Trusler wrote: Interestingly, adding more line series has no effect on auto bar width - the effect is immediately total, unlike adding bar series, where bars only gradually and proportionally narrow.

Arguably, a line series should have no effect on bar series widths, as they do not compete for space on the bottom axis. A naive implementation would have the introduction of a line series reduce the auto bar width proportionally, as if the line series were being counted as a bar series. But reducing the auto bar width to nearly nothing and rendering them unreadable is not a reasonable nor a naive implementation. Also, it clearly runs contrary to the intent of the auto-bar width feature, which is to have useful bar widths when possible.
Right. I see it here too. Find below the example that shows the problem:

Code: Select all

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D:=false;
  Chart1.Legend.Visible:=false;

  for i:=0 to 5 do
  begin
    with Chart1.AddSeries(TBarSeries) as TBarSeries do
    begin
      FillSampleValues;
      Marks.Visible:=false;
    end;
  end;

  with (Chart1.AddSeries(TLineSeries) as TLineSeries) do
  begin
    FillSampleValues;
    Smoothed:=true;
  end;
end;
And find below the modification of the example above that would work around the issue and also will let me explain better the cause of the issue:

Code: Select all

uses Series, Math;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D:=false;
  Chart1.Legend.Visible:=false;

  for i:=0 to 5 do
  begin
    with Chart1.AddSeries(TBarSeries) as TBarSeries do
    begin
      FillSampleValues;
      Marks.Visible:=false;
      AutoBarSize:=false;
      CustomBarWidth:=10;
    end;
  end;

  with (Chart1.AddSeries(TLineSeries) as TLineSeries) do
  begin
    FillSampleValues;
    Smoothed:=true;
  end;

  recalcBarWidths;
end;

procedure TForm1.recalcBarWidths;
var i, nBarSeries, nValues, BarWidth: Integer;
begin
  Chart1.Draw;

  nBarSeries:=0;
  nValues:=0;
  for i:=0 to Chart1.SeriesCount-1 do
  begin
    if Chart1[i] is TBarSeries then
    begin
      Inc(nBarSeries);
      nValues:=Max(nValues,Chart1[i].Count);
    end;
  end;

  BarWidth:=Chart1.Axes.Bottom.IAxisSize div (nBarSeries*nValues);
  BarWidth:=Round((Chart1[0] as TBarSeries).BarWidthPercent*0.01*BarWidth);
  for i:=0 to Chart1.SeriesCount-1 do
  begin
    if Chart1[i] is TBarSeries then
      (Chart1[i] as TBarSeries).CustomBarWidth:=BarWidth;
  end;
end;
The recalcBarWidths procedure is doing something very similar than what TeeChart does internally to calculate the Bars widths when AutoBarSize=true.
The main difference is that TeeChart sources are considering all the series to get "nValues", not only the TBarSeries as above.
So, TeeChart is also considering the number of points in the smoothed line to calculate the bars width.
I've added it to the wish list to be revised asap (TV52016011).
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

Post Reply