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
Display text in OpenGL mode perpendicular to viewing axis
Display text in OpenGL mode perpendicular to viewing axis
- Attachments
-
- 3DText.zip
- (192.2 KiB) Downloaded 524 times
Re: Display text in OpenGL mode perpendicular to viewing axis
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.
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,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
-
- Newbie
- Posts: 11
- Joined: Wed Jul 07, 2010 12:00 am
Re: Display text in OpenGL mode perpendicular to viewing axis
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?
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?
-
- Newbie
- Posts: 11
- Joined: Wed Jul 07, 2010 12:00 am
Still can't make both points AND text look good
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:
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.
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:
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.
Re: Display text in OpenGL mode perpendicular to viewing axis
Hi Kevin,
In GDI and GDIPlus, it works fine with the following code:
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.
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;
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,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |