Wrong axis display with ISO surface / Trianulation problems

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
ulibru
Newbie
Newbie
Posts: 54
Joined: Tue Jul 21, 2009 12:00 am

Wrong axis display with ISO surface / Trianulation problems

Post by ulibru » Fri May 18, 2012 9:57 am

I have a chart with an ISO surface.
The bottom axis is logarithmic with min=0, max=24000
As shown in the picture
Image
the bottom axis does not show the usual start label min=1 and max=24000. Furthermore the ticks below 100 are also not displayed.
IMO there is no setting to create a correctly displayed axis.

Also the displayed surface seems to have triangulation problems.

Best regards
Uli

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

Re: Wrong axis display with ISO surface / Trianulation problems

Post by Yeray » Fri May 18, 2012 3:13 pm

Hi Uli,
ulibru wrote:the bottom axis does not show the usual start label min=1 and max=24000
When the axis is set to be logarithmic, the increment for the labels is also logarithmic and with base 10: 1, 10, 100, 1000.
If you want you can change the LogarithmicBase. Otherwise, could you please explain how would you expect it to work?
ulibru wrote:Furthermore the ticks below 100 are also not displayed.
You are right, I've added it to the wish list to be revised (TV52016193).
ulibru wrote:Also the displayed surface seems to have triangulation problems.
I'm afraid this a known problem already in the defect list (TV52013073).
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

ulibru
Newbie
Newbie
Posts: 54
Joined: Tue Jul 21, 2009 12:00 am

Re: Wrong axis display with ISO surface / Trianulation problems

Post by ulibru » Fri May 18, 2012 3:45 pm

Hi Yeray,

I don't want to change the logarithmic base. I just miss the standard display of 1 for the lowest label (as usual with 2D charts).
Of course a label display of the max limit (here e.g. 24000) with the standard 1, 10, 100, 1000, 10000 labels would be the cherry on the icecake (also with all other charts).

Best regards
Uli

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

Re: Wrong axis display with ISO surface / Trianulation problems

Post by Yeray » Mon May 21, 2012 2:28 pm

Hi Uli,

Have you tried using custom labels?

Code: Select all

  with Chart1.Axes.Bottom.Items do
  begin
    Clear;
    Add(1,'1');
    Add(10,'10');
    Add(100,'100');
    Add(1000,'1.000');
    Add(10000,'10.000');
    Add(24000,'24.000');
  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

ulibru
Newbie
Newbie
Posts: 54
Joined: Tue Jul 21, 2009 12:00 am

Re: Wrong axis display with ISO surface / Trianulation problems

Post by ulibru » Tue May 22, 2012 8:06 am

Yeray,

now I have tried :D
Your proposal allows to set custom axis labels. Though this needs some extra effort in case of axis zooming, e.g. display of range from 150 to 3800. It needs some logic to create nice labels.

But beside of the label setting I have noticed a strange behaviour of the minor ticks when using custom labels. So there are new minor ticks created on the logarithmic scale as a side-effect. How to avoid this?

Uli

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

Re: Wrong axis display with ISO surface / Trianulation problems

Post by Yeray » Tue May 22, 2012 4:20 pm

Hi Uli,
ulibru wrote:But beside of the label setting I have noticed a strange behaviour of the minor ticks when using custom labels. So there are new minor ticks created on the logarithmic scale as a side-effect. How to avoid this?
I'm trying to reproduce it with the code below but I don't see anything strange in the minor ticks:

Code: Select all

uses TeeGDIPlus;

procedure TForm1.FormCreate(Sender: TObject);
var x, z: Integer;
begin
  Chart1.Canvas:=TGDIPlusCanvas.Create;

  Chart1.Legend.Visible:=false;
  Chart1.Aspect.Orthogonal:=false;
  Chart1.Chart3DPercent:=100;
  Chart1.Aspect.HorizOffset:=50;
  Chart1.Aspect.VertOffset:=-120;

  Chart1.Axes.Depth.Visible:=true;

  with Chart1.AddSeries(TIsoSurfaceSeries) as TIsoSurfaceSeries do
  begin
    IrregularGrid:=true;
    for x:=0 to 10 do
      for z:=0 to 10 do
        AddXYZ(exp(x), exp(z), z);
  end;

  Chart1.Axes.Bottom.Logarithmic:=true;
  with Chart1.Axes.Bottom.Items do
  begin
    Clear;
    Add(1,'1');
    Add(10,'10');
    Add(100,'100');
    Add(1000,'1.000');
    Add(10000,'10.000');
  end;
end;
test.png
test.png (77.38 KiB) Viewed 26224 times
Do you see any relevant difference between the code above and what you are doing?
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

ulibru
Newbie
Newbie
Posts: 54
Joined: Tue Jul 21, 2009 12:00 am

Re: Wrong axis display with ISO surface / Trianulation problems

Post by ulibru » Tue May 22, 2012 5:48 pm

Yeray,

I have used your example with following modifications:
length of bottom ticks = 20
length of minor ticks = 10
minor ticks count = 8 (8 minor ticks between major ticks 10/100 = position 20, 30, 40, 50, 60, 70, 80, 90 with logarithmic axis)
This is just for better view.

Your code:

Code: Select all

    Clear;
    Add(1,'1');
    Add(10,'10');
    Add(100,'100');
    Add(1000,'1000');
    Add(10000,'10000');
Result = ok
Image

One line added to code:

Code: Select all

    Clear;
    Add(1,'1');
    Add(10,'10');
    Add(100,'100');
    Add(1000,'1000');
    Add(10000,'10000');
    Add(Chart1.Axes.Bottom.Maximum,System.SysUtils.Format('%1.0f',[Chart1.Axes.Bottom.Maximum]));
Result = wrong !
Image

Please see ticks before and after 10000 !

Regards
Uli

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

Re: Wrong axis display with ISO surface / Trianulation problems

Post by Yeray » Wed May 23, 2012 9:39 am

Hi Uli,

I see it now. Thanks for the explanation.
The MinorTicks drawn for the last tick (22026) are calculated using an increment that depends on the LogarithmicBase (10). If I'm not wrong, you are a source code customer, so feel free to explore the exact calculation process in the ProcessMinorTicks procedure, in TeEngine.pas.
I've added to the wish list the possibility to study this further (TV52016198). But at this moment I'm afraid I'm not sure about how the MinorTicks should be drawn in an interval that doesn't match the LogarithmicBase, in a Logarithmic axis.
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

ulibru
Newbie
Newbie
Posts: 54
Joined: Tue Jul 21, 2009 12:00 am

Re: Wrong axis display with ISO surface / Trianulation problems

Post by ulibru » Wed May 23, 2012 11:21 am

But at this moment I'm afraid I'm not sure about how the MinorTicks should be drawn in an interval that doesn't match the LogarithmicBase, in a Logarithmic axis.
Hi Yeray,

the basic idea was just to get a label (maybe together with a major tick) at the end of the axis.
Indeed it is not necessary to create new minor ticks. They can simply match the log base as before. No change.

I've checked ProcessMinorTicks but honestly speaking this is beyond my skills. I fear to create an undesired side-effect by changing the procedure.
IMO minor ticks are only allowed to occur on positions defined by logbase (10) and the number of ticks between the major ticks. So just don't draw minor ticks on other positions.
If you can tell me more precisely where to modify the code I'll try.

regards
Uli

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

Re: Wrong axis display with ISO surface / Trianulation problems

Post by Yeray » Thu May 24, 2012 9:18 am

Hi Uli,
ulibru wrote:the basic idea was just to get a label (maybe together with a major tick) at the end of the axis.
Indeed it is not necessary to create new minor ticks. They can simply match the log base as before. No change.

I've checked ProcessMinorTicks but honestly speaking this is beyond my skills. I fear to create an undesired side-effect by changing the procedure.
In that method I read:

Code: Select all

      if FLogarithmic then
      begin
        tmpTicks:=nil;
        try
          if tmpNumTicks>0 then  // 7.0 fix first tick
          begin
            tmpValue:=CalcPosPoint(Tick[tmpNumTicks-1])/LogarithmicBase;
            DrawLogMinorTicks(tmpValue);

            for t:=0 to tmpNumTicks-3 do  // 8.02
                DrawLogMinorTicks(CalcPosPoint(Tick[t]));

            DrawLogMinorTicks(CalcPosPoint(Tick[tmpNumTicks-1]));
          end;
        finally
          tmpTicks:=nil;
        end;
      end
If you comment the two lines

Code: Select all

            tmpValue:=CalcPosPoint(Tick[tmpNumTicks-1])/LogarithmicBase;
            DrawLogMinorTicks(tmpValue);
To have this:

Code: Select all

      if FLogarithmic then
      begin
        tmpTicks:=nil;
        try
          if tmpNumTicks>0 then  // 7.0 fix first tick
          begin
            //tmpValue:=CalcPosPoint(Tick[tmpNumTicks-1])/LogarithmicBase;
            //DrawLogMinorTicks(tmpValue);

            for t:=0 to tmpNumTicks-3 do  // 8.02
                DrawLogMinorTicks(CalcPosPoint(Tick[t]));

            DrawLogMinorTicks(CalcPosPoint(Tick[tmpNumTicks-1]));
          end;
        finally
          tmpTicks:=nil;
        end;
      end
It seems to behave as you described. However, this is not a very good/elegant solution as it simply doesn't draw the minor ticks in the last interval, regardless if you want them or not.

A more elegant solution would be not to add the non LogarithmicBase custom label:

Code: Select all

    Clear;
    Add(1,'1');
    Add(10,'10');
    Add(100,'100');
    Add(1000,'1000');
    Add(10000,'10000');
//    Add(Chart1.Axes.Bottom.Maximum,System.SysUtils.Format('%1.0f',[Chart1.Axes.Bottom.Maximum]));
and draw it manually at OnAfterDraw event as follows:

Code: Select all

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var XPos, YPos, ZPos, TLength: Integer;
    text: String;
begin
  with Chart1.Canvas, Chart1.Axes.Bottom do
  begin
    Pen.Assign(Ticks);
    Font.Assign(LabelsFont);
    text:=FormatFloat('#,##0', Maximum);
    TLength:=TickLength;
    XPos:=IEndPos;
    YPos:=PosAxis;
    ZPos:=Round(Chart1.Width3D*ZPosition*0.01);
    VertLine3D(XPos, YPos, YPos+TLength, ZPos);
    TextOut3D(XPos-(TextWidth(text) div 2), PosLabels, ZPos, text);
  end;
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

ulibru
Newbie
Newbie
Posts: 54
Joined: Tue Jul 21, 2009 12:00 am

Re: Wrong axis display with ISO surface / Trianulation problems

Post by ulibru » Thu May 24, 2012 10:16 am

Hello Yeray,

many thanks, I can live with the "elegant" solution. (I've also learnt something about VertLine3D and TextOut3D).
There is only one little problem left: my chart panel has a gradient color (blue) and the labels are white colored.
Now the added label just shows a white rectangle.
If I use a white background with black fonts everything is ok.

So how to get the proper blue background color for the added label? :D

Best regards
Uli

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

Re: Wrong axis display with ISO surface / Trianulation problems

Post by Yeray » Thu May 24, 2012 11:20 am

Hi Uli,
ulibru wrote:There is only one little problem left: my chart panel has a gradient color (blue) and the labels are white colored.
Now the added label just shows a white rectangle.
Here it is the code I'm using and the result I obtain:

Code: Select all

uses TeeSurfa, TeeGDIPlus;

procedure TForm1.FormCreate(Sender: TObject);
var x, z: Integer;
begin
  Chart1.Canvas:=TGDIPlusCanvas.Create;

  Chart1.Legend.Visible:=false;
  Chart1.Aspect.Orthogonal:=false;
  Chart1.Chart3DPercent:=100;
  Chart1.Aspect.HorizOffset:=50;
  Chart1.Aspect.VertOffset:=-120;

  Chart1.Axes.Depth.Visible:=true;

  Chart1.Gradient.EndColor:=clBlue;

  with Chart1.AddSeries(TIsoSurfaceSeries) as TIsoSurfaceSeries do
  begin
    IrregularGrid:=true;
    for x:=0 to 10 do
      for z:=0 to 10 do
        AddXYZ(exp(x), exp(z), z);
  end;

  with Chart1.Axes.Bottom do
  begin
    Logarithmic:=true;
    LabelsFont.Color:=clWhite;
    MinorTickLength:=5;
    TickLength:=10;

    with Items do
    begin
      Clear;
      Add(1,'1');
      Add(10,'10');
      Add(100,'100');
      Add(1000,'1.000');
      Add(10000,'10.000');
    end;
  end;
end;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var XPos, YPos, ZPos, TLength: Integer;
    text: String;
begin
  with Chart1.Canvas, Chart1.Axes.Bottom do
  begin
    Pen.Assign(Ticks);
    Font.Assign(LabelsFont);
    text:=FormatFloat('#,##0', Maximum);
    TLength:=TickLength;
    XPos:=IEndPos;
    YPos:=PosAxis;
    ZPos:=Round(Chart1.Width3D*ZPosition*0.01);
    VertLine3D(XPos, YPos, YPos+TLength, ZPos);
    TextOut3D(XPos-(TextWidth(text) div 2), PosLabels, ZPos, text);
  end;
end;
axisLabel.png
axisLabel.png (91.12 KiB) Viewed 26196 times
Isn't this what you are doing and obtaining?
If not, please try to modify the code above so we can reproduce the problem here.
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

ulibru
Newbie
Newbie
Posts: 54
Joined: Tue Jul 21, 2009 12:00 am

Re: Wrong axis display with ISO surface / Trianulation problems

Post by ulibru » Thu May 24, 2012 12:32 pm

Yeray,

your example code works fine here.
But now I wonder.

With my program I get

Image

As I have edited the chart during designtime I wonder which parameter is responsible for the wrong display. I use the same AfterDraw code like your example. I'm confused now.

Uli

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

Re: Wrong axis display with ISO surface / Trianulation problems

Post by Yeray » Thu May 24, 2012 1:53 pm

Hi Uli,

It's probably that the brush style is bsSolid in your case at that moment.
You can force it to bsClear adding thisto the OnAfterDraw function, before calling the TextOut3D function:

Code: Select all

  with Chart1.Canvas, Chart1.Axes.Bottom do
  begin
    Pen.Assign(Ticks);
    Font.Assign(LabelsFont);
    Brush.Style:=bsClear;
    //...
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

ulibru
Newbie
Newbie
Posts: 54
Joined: Tue Jul 21, 2009 12:00 am

Re: Wrong axis display with ISO surface / Trianulation problems

Post by ulibru » Thu May 24, 2012 3:28 pm

Hi Yeray,

thanks, Brush.Style has solved the problem.
But where is it set at design time? I wonder.

A final remark: the solution to use AfterDraw is not complete. So e.g. simply inverting the axis does not call the event and the label is at a wrong position.
Viewing the chart in e.g. top view or front view does not show the label.

It seems better I forget it all.

Thanks for your support.
Uli

Post Reply