Page 1 of 1

auto bar width problems

Posted: Thu Jan 19, 2012 4:06 pm
by 5886857
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?

Re: auto bar width problems

Posted: Fri Jan 20, 2012 4:51 pm
by yeray
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.

Re: auto bar width problems

Posted: Sun Jan 22, 2012 4:33 pm
by 5886857
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 6304 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 6301 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 6305 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.

Re: auto bar width problems

Posted: Mon Jan 23, 2012 11:34 am
by yeray
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).