Page 1 of 1

Transparent rectangles with different XYZ extend

Posted: Tue Jun 28, 2011 8:50 am
by 10547842
Hi,

I am currently using TChart 2011 and I'd like to draw multiple
semi-transparent rectangles with different X,Y,Z extends like
shown in the clustering example.
Capture.JPG
Capture.JPG (45.31 KiB) Viewed 9768 times
Which series I do have to uses to achieve that, because the normal
TPoint3DSeries does not allow for varying X,Y,Z extends per 3D rectangle?

best regards,

X-Ray

Re: Transparent rectangles with different XYZ extend

Posted: Thu Jun 30, 2011 10:13 am
by narcis
Hi X-Ray,

You can use Canvas.Cube, BeginBlending and EndBlending methods in the OnAfterDraw event, for example:

Code: Select all

uses TeePoin3, TeCanvas;

procedure TForm1.FormCreate(Sender: TObject);
var Series1: TPoint3DSeries;
begin
  Series1:=TPoint3DSeries.Create(Self);
  Series1.LinePen.Visible:=False;

  Chart1.AddSeries(Series1).FillSampleValues;
end;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var tmpBlend: TTeeBlend;
    Rect    : TRect;
    P       : TFourPoints;
    Z0      : Integer;
    Z1      : Integer;
begin
  Rect:=TeeRect(100, 200, 150, 250);
  Z0:=20;
  Z1:=50;

  with Chart1.Canvas, Rect do
  begin
    P[0]:=Calculate3DPosition(Left, Top, Z0);
    P[1]:=Calculate3DPosition(Left, Top, Z1);
    P[2]:=Calculate3DPosition(Right, Bottom, Z1);
    P[3]:=Calculate3DPosition(Right, Bottom, Z0);

    tmpBlend:=BeginBlending(RectFromPolygon(P, 4), 80);
    Cube(Rect, Z0, Z1);
    EndBlending(tmpBlend);
  end;
end;

Re: Transparent rectangles with different XYZ extend

Posted: Thu Jun 30, 2011 11:42 am
by 10547842
Hi Narcis,

Thank you, but this was not what I meant.
I need a series that contains individually sizable transparent rectangles as Items where I can set the X,Y,Z extend for
each rectangle separately in units of the plot and not in pixels. You have now created one cube which size
is given in pixels (absolute scale) and that stays fixed at a certain position.

I'd like to draw, right like in the given plot, boxes around clustered Items in a PCA score plot.
And I know the X,Y,Z coordinates of all cluster centers as well as the extend of each cluster in PCA score coordinates.

What is the best way to achieve that?

best regards,

X-Ray

Re: Transparent rectangles with different XYZ extend

Posted: Thu Jun 30, 2011 1:03 pm
by narcis
Hi X-Ray,
I need a series that contains individually sizable transparent rectangles as Items where I can set the X,Y,Z extend for
each rectangle separately in units of the plot and not in pixels. You have now created one cube which size
is given in pixels (absolute scale) and that stays fixed at a certain position.
I'm afraid such a series doesn't exist. However, custom drawing is still a valid option as you can convert from axis values to screen coordinates and viceversa using methods like CalcPosValue and CalcPosPoint.
I'd like to draw, right like in the given plot, boxes around clustered Items in a PCA score plot.
And I know the X,Y,Z coordinates of all cluster centers as well as the extend of each cluster in PCA score coordinates.
Have you checked the clustering demo? Would that be useful for you? Also, you could create your custom series derived from existing ones and override its drawing methods to plot cubes as you wish.

Re: Transparent rectangles with different XYZ extend

Posted: Thu Jun 30, 2011 2:50 pm
by 10547842
Hi Narcis,

>I'm afraid such a series doesn't exist. However, custom drawing is still a valid option as you can convert from axis values to screen coordinates and viceversa >using methods like CalcPosValue and CalcPosPoint.

At the moment I am creating individual TPoint3DSeries for each Cluster/Rectangle.

First I am calculating all cluster extends in Pixels by
calling (XSize,YSize and ZSize are before calculated in PCA score coordinates of course):

XSize := PCAChart.BottomAxis.CalcSizeValue(XSize);
YSize := PCAChart.LeftAxis.CalcSizeValue(YSize);
ZSize := PCAChart.DepthAxis.CalcSizeValue(ZSize);

And then I create i TPoint3DSeries and for each series I do something like this:

with Point3DSeries do
begin
Pointer.Style := psRectangle;
Pointer.Visible := True;
Pointer.HorizSize := Round(XSizes);
Pointer.VertSize := Round(YSizes[i]);
Pointer.Depth := Round(ZSizes[i]);
Pointer.Transparency := 60;
end;

Unfortunately the final sizes of the rectangles are off, they are too big and I have no clue why.
Somehow the calculations in "CalcSizeValue" are wrong. Do you have an idea what could be wrong?

Capture.JPG
Capture.JPG (49.07 KiB) Viewed 9693 times
>Have you checked the clustering demo?
Yes, and it is very nice, but we are using our own proprietary clustering algorithms and we need TChart just for display purpose.

best regards,

X-Ray

Re: Transparent rectangles with different XYZ extend

Posted: Fri Jul 01, 2011 7:45 am
by yeray
Hello X-Ray,
xray wrote:Unfortunately the final sizes of the rectangles are off, they are too big and I have no clue why.
Somehow the calculations in "CalcSizeValue" are wrong. Do you have an idea what could be wrong?
Maybe the chart hasn't been drawn yet when you call these methods? Please, check it. Note that the axes functions like CalcXPos, CalcSizeValue, etc need the chart to be drawn so the internal values can be used to make the necessary calculations.

Re: Transparent rectangles with different XYZ extend

Posted: Tue Jul 05, 2011 10:19 am
by 10547842
Hi Yeray,

>Maybe the chart hasn't been drawn yet when you call these methods?
Yes, that was the first obstacle, but after solving that the plot is still off.

Now I tried the approach that was suggested by Narcis, drawing cubes in the TChart OnAfterDraw event.
In this case the extends of the cubes seem to be OK but now the positions are off.
This is the code that was used to convert from PCA score coordinates to drawing coordinates/pixels;

Code: Select all

    for i := 1 to NrOfRows do
    begin
      if FClusterAnalyser.IsDataSetARepresentant(i - 1) then
      begin
        IsItemInClusters(FClusterAnalyser.Clusters, i, ClusterIndex);
        if not FClusterAnalyser.Clusters[ClusterIndex][0].Hide then
        begin
          // Get Cluster extend in pixels
          XSize := PCAChart.BottomAxis.CalcSizeValue(FClusterAnalyser.GetMaxDistanceX(ClusterIndex));
          YSize := PCAChart.LeftAxis.CalcSizeValue(FClusterAnalyser.GetMaxDistanceY(ClusterIndex));
          ZSize := PCAChart.DepthAxis.CalcSizeValue(FClusterAnalyser.GetMaxDistanceZ(ClusterIndex));
          // Get Cluster center in pixels
          FClusterAnalyser.CalculateCenterOfCluster(ClusterIndex, Xc, Yc, Zc);
          XCenter := PCAChart.BottomAxis.CalcSizeValue(Xc - PCAChart.BottomAxis.Minimum);
          YCenter := PCAChart.LeftAxis.CalcSizeValue(Yc - PCAChart.LeftAxis.Minimum);
          ZCenter := PCAChart.DepthAxis.CalcSizeValue(Zc - PCAChart.DepthAxis.Minimum);
          DeltaY := PCAChart.LeftAxis.CalcSizeValue(PCAChart.LeftAxis.Maximum - PCAChart.LeftAxis.Minimum);
          // Prepare drawing
          Rect := TeeRect( Round(XCenter - (XSize / 2)),
                          -Round(YCenter - (YSize / 2)) + DeltaY,
                           Round(XCenter + (XSize / 2)),
                          -Round(YCenter + (YSize / 2)) + DeltaY);
          Z1 := Round(ZCenter - (ZSize / 2));
          Z0 := Round(ZCenter + (ZSize / 2));
          PCAChart.Canvas.Cube(Rect, Z0, Z1);
         end;
      end;
    end; 


Here is the resulting drawing:
Capture.JPG
Capture.JPG (52.52 KiB) Viewed 9672 times
I know that the center coordinates returned by:

FClusterAnalyser.CalculateCenterOfCluster(ClusterIndex, Xc, Yc, Zc);

are correct!

Can you maybe tell me what I am doing wrong in the conversion from coordinates to Pixels?

best regards,

X-Ray

Re: Transparent rectangles with different XYZ extend

Posted: Tue Jul 05, 2011 12:12 pm
by 10547842
Hi Yeray,

OK, I just solved it, it should look like this:

Code: Select all

  // Get Cluster extend in pixels
  XSize := PCAChart.BottomAxis.CalcSizeValue(FClusterAnalyser.GetMaxDistanceX(ClusterIndex));
  YSize := PCAChart.LeftAxis.CalcSizeValue(FClusterAnalyser.GetMaxDistanceY(ClusterIndex));
  ZSize := PCAChart.DepthAxis.CalcSizeValue(FClusterAnalyser.GetMaxDistanceZ(ClusterIndex));
  // Get Cluster center in pixels
  FClusterAnalyser.CalculateCenterOfCluster(ClusterIndex, Xc, Yc, Zc);
  XCenter := PCAChart.BottomAxis.CalcPosValue(Xc);
  YCenter := PCAChart.LeftAxis.CalcPosValue(Yc);
  ZCenter := PCAChart.DepthAxis.CalcPosValue(Zc);
  // Prepare drawing
  Rect := TeeRect(Round(XCenter - (XSize / 2)),
                            Round(YCenter - (YSize / 2)),
                            Round(XCenter + (XSize / 2)),
                            Round(YCenter + (YSize / 2)));
  Z1 := Round(ZCenter - (ZSize / 2));
  Z0 := Round(ZCenter + (ZSize / 2));
   PCAChart.Canvas.Cube(Rect, Z0, Z1);
best regards,

X-Ray

Re: Transparent rectangles with different XYZ extend

Posted: Tue Jul 05, 2011 2:17 pm
by yeray
Hello X-Ray,

I'm glad to hear you've achieved it!
And thanks for sharing your solution and experiences.