Display text in OpenGL mode perpendicular to viewing axis

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
xray
Newbie
Newbie
Posts: 15
Joined: Thu Dec 20, 2007 12:00 am

Display text in OpenGL mode perpendicular to viewing axis

Post by xray » Tue Mar 09, 2010 1:37 pm

Hi,

in OpenGL mode all shown text rotates with the graphics/axes which makes it unreadable most of the time
(Please see: OpenGLModeText.png).
In normal 3D mode the text is always displayed perpendicular to the viewing axis.
(Please see: Normal3DModeText.png).
This is the preferred solution because in this way the text is readable in most cases.
How can I achieve the same result in OpenGL mode?

Thanks and best regards
Attachments
3DText.zip
(192.2 KiB) Downloaded 524 times

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

Re: Display text in OpenGL mode perpendicular to viewing axis

Post by Yeray » Thu Mar 11, 2010 9:20 am

Hi xray,

I'm afraid that OpenGL rotates the labels with the chart and I can't think on a way to workaround this right now.
What you could try is with GDIPlus where the labels don't seem to be rotated.

Code: Select all

         Chart1.Canvas:=TGDIPlusCanvas.Create;
         (Chart1.Canvas as TGDIPlusCanvas).AntiAlias:=True;
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

KevinKillion
Newbie
Newbie
Posts: 11
Joined: Wed Jul 07, 2010 12:00 am

Re: Display text in OpenGL mode perpendicular to viewing axis

Post by KevinKillion » Thu Feb 17, 2011 10:47 pm

Hmmmm. Well, it should be simple enough to draw the text labels myself using the onAfterDraw event.

1) If I draw to a OpenGL canvas using onAfterDraw, wil my text still appear to be rotated?

2) I need to know WHERE to draw the text. How do I retrieve the x-y coordinates (in Canvas coordinates, NOT in chart coordinates) of each series point?

KevinKillion
Newbie
Newbie
Posts: 11
Joined: Wed Jul 07, 2010 12:00 am

Still can't make both points AND text look good

Post by KevinKillion » Fri Feb 18, 2011 12:31 am

BACKGROUND: SPIN PLOTS

I'm trying to create a "spin" chart using TChart. A spin chart lets an analyst view a 3D scatter plot and spin it around by pitch, yaw and roll. Here is an animated GIF that is a good illustration:
macspin example.gif
macspin example.gif (140.35 KiB) Viewed 8432 times
With a modest number of points (up to 20 or 30, say), it would be desirable to be able to label each point. And that's where the challenge starts with TChart!!

NORMAL TCHART TOOLS

If I use normal TChart tools, plotted points look flat when we rotate 90 degrees. If we use OpenGL, text labels aren't drawn facing the viewer when we rotate, and vanish entirely once we rotate more than 90 degrees.

WHAT IF DRAW THE TEXT OURSELVES?

Here are some results using onAfterDraw to draw onto a chart that showing at an oblique angle:

Using a conventional chart:
-- TextOut(x, y, 'Hello') draws the text at a fixed x-y position on the chart. The text does not move as the chart is rotated.
-- TextOut3D(x, y, z, 'Hello') draws the text treating the x-y-z as chart coordinates, not canvas coordinates, so the text moves as the chart is rotated.
-- In both cases, the text is drawn facing the viewer (yea!)

Using an OpenGL chart created with TTeeOpenGL:
-- TextOut and TextOut3D appear to do exactly the same thing: the coordinates are treated as chart coords rather than canvas coords, so they move as the chart is rotated.
-- In both cases, the chart is drawn facing the original "outward" direction (towards positive-z). The text turns into a straight line when viewed at 90 degrees, and vanishes if we rotate any further.
-- I haven't found a way to draw text on an OpenGL chart that does NOT screw up the text when a chart is rotated.

CONCLUSIONS SO FAR

-- Given that we want 360 degree rotation with text labels, it seems using OpenGL and TTeeOpenGL is gorgeous, but worthless
-- In conventional charts, the only available point styles that can have depth (so they don't turn into lines at 90 degrees) are rectangle and triangle, NOT circles/spheres. So we can't draw a set of points without conveying a sense of the original axes (which is meaningless in most "spin" type applications.
-- The worst problem in conventional charts is that the z-ordering of drawn objects can get screwed up.
-- Solution? None yet, but I'm hopeful!

Given the huge breadth of styles and options in TChart, it's surprising that "spin" charts aren't a stock option.

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

Re: Display text in OpenGL mode perpendicular to viewing axis

Post by Yeray » Tue Feb 22, 2011 12:23 pm

Hi Kevin,

In GDI and GDIPlus, it works fine with the following code:

Code: Select all

uses Series, TeePoin3;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var i: Integer;
    tmpX, tmpY, tmpZ: Integer;
    P               : TPoint;
begin
  for i:=0 to Chart1[0].Count-1 do
  begin
    tmpX:=Chart1[0].CalcXPos(i);
    tmpY:=Chart1[0].CalcYPos(i);
    tmpZ:=(Chart1[0] as TPoint3DSeries).CalcZPos(i);

    P:=Chart1.Canvas.Calculate3DPosition(tmpX, tmpY, tmpZ);

    Chart1.Canvas.TextOut(P.X+2,P.Y+2,FloatToStr(Chart1[0].YValue[i]));
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.Aspect.Orthogonal:=false;
  Chart1.Aspect.Zoom:=90;
  Chart1.Aspect.Rotation:=310;
  Chart1.Legend.Visible:=false;

  with Chart1.AddSeries(TPoint3DSeries) as TPoint3DSeries do
  begin
    Pointer.Style:=psCircle;
    LinePen.Visible:=False;
    FillSampleValues(10);
  end;

  Chart1.Draw;
end;
However, with OpenGL, this doesn't work perfect. I've added to the wish list the possibility to calculate the 3D positions of the points (TV52015408).
The following approach doesn't work fine with the elevation. It seems that the Calculate3DPositions method doesn't work as it should right now.

Code: Select all

uses TeeOpenGL, Series, TeeTools;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var i: Integer;
    tmpX, tmpY: Integer;
begin

  for i:=0 to Chart1[0].Count-1 do
  with Chart1.Tools[i] as TAnnotationTool do
  begin
    tmpX:=Round(Chart1[0].CalcXPos(i));
    tmpY:=Round(Chart1[0].CalcYPos(i));

    Chart1.Canvas.Calculate2DPosition(tmpX, tmpY, Chart1[0].MiddleZ);
    Left:=tmpX;
    Top:=Chart1.ClientRect.Top - tmpY;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  with TTeeOpenGL.Create(self) do
  begin
    TeePanel:=Chart1;
    Active:=true;
  end;

  Chart1.Aspect.Orthogonal:=false;
  Chart1.Aspect.Zoom:=50;
  Chart1.Aspect.Rotation:=310;
  Chart1.Legend.Visible:=false;

  with Chart1.AddSeries(TPointSeries)  as TPointSeries do
  begin
    Pointer.Style:=psCircle;
    FillSampleValues(10);
  end;

  for i:=0 to Chart1[0].Count-1 do
  with Chart1.Tools.Add(TAnnotationTool) as TAnnotationTool do
  begin
    Text:=FloatToStr(Chart1[0].YValue[i]);
    Shape.Transparent:=true;
  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

Post Reply