Height in GetAxesChartRectEventArgs for 3D charts

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
biqpaulson
Newbie
Newbie
Posts: 93
Joined: Thu Apr 17, 2008 12:00 am

Height in GetAxesChartRectEventArgs for 3D charts

Post by biqpaulson » Thu Apr 13, 2017 2:03 pm

I have been using the GetAxesChartRect handler to get the height and width of the charts which for 2D (X and Y axis only), this seems to work fine.

For 3D charts the height is the height of the Y axis. This means that the depth is being ignored, from what I can see.

Is there a similar handler for 3D charts as GetAxesChartRectEventArgs?
Am I missing some information about the use of GetAxesChartRectEventArgs when there are 3D charts?
Is there a way to get the actual Chart Rectangle information for 3D charts before the draw?

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Height in GetAxesChartRectEventArgs for 3D charts

Post by Christopher » Tue Apr 18, 2017 8:28 am

Hello,
biqpaulson wrote: Is there a similar handler for 3D charts as GetAxesChartRectEventArgs?
Am I missing some information about the use of GetAxesChartRectEventArgs when there are 3D charts?
Is there a way to get the actual Chart Rectangle information for 3D charts before the draw?
In the semantics of TeeChart, the ChartRect is the 2D rectangle (not a 3D cube) along which the left and bottom axes are drawn. In fact, there is no 3D cube, in TeeChart terms, around which the left, bottom and depth axes are drawn. What defines the length of the Depth axis is the tChart1.Aspect.Chart3DPercent, and the calculation involves the tChart1.Chart.ChartBounds.Width (which is usually the same as tChart1.Width).

Anyhow - what is it exactly that you want to achieve with the Depth axis in the GetAxesChartRect event?
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

biqpaulson
Newbie
Newbie
Posts: 93
Joined: Thu Apr 17, 2008 12:00 am

Re: Height in GetAxesChartRectEventArgs for 3D charts

Post by biqpaulson » Wed May 03, 2017 6:39 pm

We are using the GetAxesChartRect, per a previous suggestion http://www.teechart.net/support/viewtop ... 12&start=0 from you, to get the height and width of the full chart's rectangle. This works fine for 2D charts but for 3D charts the e.AxesChartRect height is coming back as really small when there is a large 3D value. So I was wondering what/where to get the actual height of the full chart when the charts are in 3D mode.

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Height in GetAxesChartRectEventArgs for 3D charts

Post by Christopher » Thu May 04, 2017 9:29 am

Hello,
biqpaulson wrote:We are using the GetAxesChartRect, per a previous suggestion http://www.teechart.net/support/viewtop ... 12&start=0 from you, to get the height and width of the full chart's rectangle. This works fine for 2D charts but for 3D charts the e.AxesChartRect height is coming back as really small when there is a large 3D value. So I was wondering what/where to get the actual height of the full chart when the charts are in 3D mode.
Yes, you can - here's some code that demonstrates the required calculation by drawing lines around the 3D cube of a 3D TChart:

Code: Select all

    private void InitializeChart()
    {
      tChart1.Series.Add(typeof(Line)).FillSampleValues();
      tChart1.Series.Add(typeof(Line)).FillSampleValues();
      tChart1.Series.Add(typeof(Line)).FillSampleValues();

      tChart1.Aspect.View3D = true;
      tChart1.Aspect.Orthogonal = false;
      tChart1.Aspect.Chart3DPercent = 80;
      tChart1.Aspect.Zoom = 75;

      tChart1.AfterDraw += TChart1_AfterDraw;
    }

    private void TChart1_AfterDraw(object sender, Graphics3D g)
    {
      Func<int, int, int, Point> CalcPoint = (x, y, z) =>
      {
        return g.Calc3DPoint(x, y, z);
      };

      int w = g.Chart.Aspect.Width3D;
      Rectangle r = g.Chart.ChartRect;

      Point[] lines = new Point[8];
      lines[0] = CalcPoint(r.Left, r.Top, 0);
      lines[1] = CalcPoint(r.Left, r.Bottom, 0);
      lines[2] = CalcPoint(r.Right, r.Bottom, 0);
      lines[3] = CalcPoint(r.Right, r.Top, 0);

      lines[4] = CalcPoint(r.Left, r.Top, w);
      lines[5] = CalcPoint(r.Left, r.Bottom, w);
      lines[6] = CalcPoint(r.Right, r.Bottom, w);
      lines[7] = CalcPoint(r.Right, r.Top, w);

      g.Pen.Color = Color.Red;
      g.Pen.Width = 3;

      g.Line(lines[0], lines[1]);
      g.Line(lines[1], lines[2]);
      g.Line(lines[2], lines[3]);
      g.Line(lines[3], lines[0]);

      g.Line(lines[4], lines[5]);
      g.Line(lines[5], lines[6]);
      g.Line(lines[6], lines[7]);
      g.Line(lines[7], lines[4]);

      g.Line(lines[0], lines[4]);
      g.Line(lines[1], lines[5]);
      g.Line(lines[2], lines[6]);
      g.Line(lines[3], lines[7]);
    }
Which gives me:
TChart636294865567955870.png
TChart636294865567955870.png (40.04 KiB) Viewed 19835 times
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

biqpaulson
Newbie
Newbie
Posts: 93
Joined: Thu Apr 17, 2008 12:00 am

Re: Height in GetAxesChartRectEventArgs for 3D charts

Post by biqpaulson » Mon May 08, 2017 7:03 pm

Ugh! I thought I had it but then Pie charts started not giving me the correct value back.

I am trying to get the room in 2D of the whole 3D chart.

The GetAxesChartRect method only gives the face of the 3D chart and ignores the depth.

Your stuff only shows drawing a box IN the 3D plane using 3D points. If I try to get a box around them I get a chart size that is larger than the panel it is on.

I also tried:

Code: Select all

Dim Calc2DPoint As Func(Of Integer, Integer, Integer, Point) = Function(x, y, z)
                                                                           Dim pt3D As Point = g.Calc3DPoint(x, y, z)
                                                                           Dim tmpX As Integer = pt3D.X
                                                                           Dim tmpY As Integer = pt3D.Y
                                                                           'Dim tmpX As Integer = x
                                                                           'Dim tmpY As Integer = y
                                                                           Dim pt As Point
                                                                           g.Calculate2DPosition(tmpX, tmpY, z)
                                                                           pt.X = tmpX
                                                                           pt.Y = tmpY
                                                                           Return pt
                                                                       End Function
Since I cannot find documentation that explains the Calculate2DPostion I don't even know if I am doing it right but the above definitely does not work for pie charts.

What I need conceptually is this:
A) Make a 3D chart like the one you have above (a 3D chart).
B) Put a white panel in front of the chart but make the panel such that when you put the panel in front of the chart the panel in front fully conceal the entire chart (hence 2D plane) but everything else on the charts panel is not obscured. (like leave the chart labels, legend,....)
C) Get the 2D x, y, width and height of the obscuring panel.

biqpaulson
Newbie
Newbie
Posts: 93
Joined: Thu Apr 17, 2008 12:00 am

Re: Height in GetAxesChartRectEventArgs for 3D charts

Post by biqpaulson » Mon May 08, 2017 7:11 pm

Or maybe:

The dimensions of the 3d projection into 2d space.  Which will result in an area that describes what the bounds of the chart are (again, not including legends, labels, etc)

Or maybe better:
Take the 3D chart, shine a flashlight on it, I want the dimensions of the shadow on the wall.

I need this because I need to control this area's minimum size.

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Height in GetAxesChartRectEventArgs for 3D charts

Post by Christopher » Wed May 10, 2017 9:00 am

Hello!

Okay, how about this code:

Code: Select all

    private void InitializeChart()
    {
      //tChart1.Series.Add(typeof(Line)).FillSampleValues();
      //tChart1.Series.Add(typeof(Line)).FillSampleValues();
      //tChart1.Series.Add(typeof(Line)).FillSampleValues();

      tChart1.Series.Add(typeof(Pie)).FillSampleValues();

      tChart1.Aspect.View3D = true;
      tChart1.Aspect.Orthogonal = false;
      tChart1.Aspect.Chart3DPercent = 80;
      tChart1.Aspect.Zoom = 75;

      tChart1.AfterDraw += TChart1_AfterDraw;
    }

    private void TChart1_AfterDraw(object sender, Graphics3D g)
    {
      Func<int, int, int, Point> CalcPoint = (x, y, z) =>
      {
        return g.Calc3DPoint(x, y, z);
      };

      Func<Point[]> PlotPoints = () =>
      {
        int w = g.Chart.Aspect.Width3D;

        Rectangle rect = (tChart1[0] is Pie) ? ((Pie)tChart1[0]).CircleRect : g.Chart.ChartRect;

        if ((tChart1[0] is Pie)) rect.Offset(0, -w);

        Rectangle r = rect;

        Point[] lines = new Point[8];
        lines[0] = CalcPoint(r.Left, r.Top, 0);
        lines[1] = CalcPoint(r.Left, r.Bottom, 0);
        lines[2] = CalcPoint(r.Right, r.Bottom, 0);
        lines[3] = CalcPoint(r.Right, r.Top, 0);

        lines[4] = CalcPoint(r.Left, r.Top, w);
        lines[5] = CalcPoint(r.Left, r.Bottom, w);
        lines[6] = CalcPoint(r.Right, r.Bottom, w);
        lines[7] = CalcPoint(r.Right, r.Top, w);

        return lines;
      };

      Action DrawFrame = () =>
      {
        Point[] lines = PlotPoints();
        g.Pen.Color = Color.Red;
        g.Pen.Width = 3;

        g.Line(lines[0], lines[1]);
        g.Line(lines[1], lines[2]);
        g.Line(lines[2], lines[3]);
        g.Line(lines[3], lines[0]);

        g.Line(lines[4], lines[5]);
        g.Line(lines[5], lines[6]);
        g.Line(lines[6], lines[7]);
        g.Line(lines[7], lines[4]);

        g.Line(lines[0], lines[4]);
        g.Line(lines[1], lines[5]);
        g.Line(lines[2], lines[6]);
        g.Line(lines[3], lines[7]);
      };

      Action DrawPlane = () =>
      {
        g.Pen.Color = Color.Blue;
        g.Pen.Width = 3;
        g.Brush.Color = Color.Yellow;
        g.Brush.Transparency = 60;

        Point[] lines = PlotPoints();
        Point[] polygon = new Point[4];
        Array.Copy(lines, polygon, 4);
        g.Polygon(polygon);
      };

      Action Calc2DDimensions = () =>
      {
        Point[] lines = PlotPoints();
        Point[] polygon = new Point[4];
        Array.Copy(lines, polygon, 4);

        Rectangle rect = g.RectFromPolygon(4, polygon);
        int x, y;
        Graphics3D.RectCenter(rect, out x, out y);

        Point vertTop = new Point(x, y - (rect.Height / 2));
        Point vertBottom = new Point(x, y + (rect.Height / 2));
        Point horizLeft = new Point(x - (rect.Width / 2), y);
        Point horizRight = new Point(x + (rect.Width / 2), y);

        g.Pen.Color = Color.Fuchsia;
        g.Pen.Width = 3;
        g.Line(vertTop, vertBottom);
        g.Line(horizLeft, horizRight);

        g.TextOut(vertTop.X, vertTop.Y, "2D Height of Plane: " + rect.Height.ToString());
        g.TextOut(horizRight.X, horizRight.Y, "2D Width of Plane: " + rect.Width.ToString());
      };

      //DrawFrame();
      DrawPlane();
      Calc2DDimensions();
    }
Using the line series I obtain:
TChart636300034389355647.png
TChart636300034389355647.png (61.34 KiB) Viewed 19796 times
and using the pie series I obtain:
TChart636300034628848380.png
TChart636300034628848380.png (29.07 KiB) Viewed 19800 times
I hope this is of some help to you!
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

biqpaulson
Newbie
Newbie
Posts: 93
Joined: Thu Apr 17, 2008 12:00 am

Re: Height in GetAxesChartRectEventArgs for 3D charts

Post by biqpaulson » Tue May 16, 2017 1:01 pm

Hi Christopher:

"Almost" -- ;-> If you refer to the two pictures that I included, you can see what we are looking for: "The area of the 3d chart projected into 2d space." We are looking for the RED area.

Remember, the reason we want this is to be able to detect and control how "small" the chart gets, because sometime (since we offer a lot of controls for the user), the chart can get so small that nothing is rendered. We want to stop that from happening. Is there any way we can get this functionality?

Thanks!
pic1.png
pic1.png (56.41 KiB) Viewed 19758 times
pic2.png
pic2.png (25.01 KiB) Viewed 19765 times

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Height in GetAxesChartRectEventArgs for 3D charts

Post by Christopher » Tue May 16, 2017 5:36 pm

Hello,
biqpaulson wrote: "Almost" -- ;-> If you refer to the two pictures that I included, you can see what we are looking for: "The area of the 3d chart projected into 2d space." We are looking for the RED area.
I see. Well, I may suggest that it shouldn't be difficult to obtain this area from what I've already given you. You could try something similar to this:

Code: Select all

    private void TChart1_AfterDraw(object sender, Graphics3D g)
    {
      Func<int, int, int, Point> CalcPoint = (x, y, z) =>
      {
        return g.Calc3DPoint(x, y, z);
      };

      Func<Point[]> PlotPoints = () =>
      {
        int w = g.Chart.Aspect.Width3D;

        Rectangle rect = (tChart1[0] is Pie) ? ((Pie)tChart1[0]).CircleRect : g.Chart.ChartRect;

        //if ((tChart1[0] is Pie)) rect.Offset(0, -w);

        Rectangle r = rect;

        Point[] lines = new Point[8];
        lines[0] = CalcPoint(r.Left, r.Top, 0);
        lines[1] = CalcPoint(r.Left, r.Bottom, 0);
        lines[2] = CalcPoint(r.Right, r.Bottom, 0);
        lines[3] = CalcPoint(r.Right, r.Top, 0);

        lines[4] = CalcPoint(r.Left, r.Top, w);
        lines[5] = CalcPoint(r.Left, r.Bottom, w);
        lines[6] = CalcPoint(r.Right, r.Bottom, w);
        lines[7] = CalcPoint(r.Right, r.Top, w);

        return lines;
      };

      Action DrawCalcAnotherPlane = () =>
      {
        g.Pen.Color = Color.Blue;
        g.Pen.Width = 3;
        g.Brush.Color = Color.Yellow;
        g.Brush.Transparency = 60;

        Point[] lines = PlotPoints();

        List<Point> point = new List<Point>();
        point.Add(lines[0]);
        point.Add(lines[1]);
        point.Add(lines[1]);
        point.Add(lines[2]);
        point.Add(lines[2]);
        point.Add(lines[3]);
        point.Add(lines[3]);
        point.Add(lines[0]);

        point.Add(lines[4]);
        point.Add(lines[5]);
        point.Add(lines[5]);
        point.Add(lines[6]);
        point.Add(lines[6]);
        point.Add(lines[7]);
        point.Add(lines[7]);
        point.Add(lines[4]);

        point.Add(lines[0]);
        point.Add(lines[4]);
        point.Add(lines[1]);
        point.Add(lines[5]);
        point.Add(lines[2]);
        point.Add(lines[6]);
        point.Add(lines[3]);
        point.Add(lines[7]);

        Rectangle rect = g.RectFromPolygon(point.Count, point.ToArray());
        g.Brush.Visible = false;
        g.Rectangle(rect);

        int x, y;
        Graphics3D.RectCenter(rect, out x, out y);

        Point vertTop = new Point(x, y - (rect.Height / 2));
        Point vertBottom = new Point(x, y + (rect.Height / 2));
        Point horizLeft = new Point(x - (rect.Width / 2), y);
        Point horizRight = new Point(x + (rect.Width / 2), y);

        g.Pen.Color = Color.Fuchsia;
        g.Pen.Width = 3;
        g.Line(vertTop, vertBottom);
        g.Line(horizLeft, horizRight);

        g.TextOut(vertTop.X, vertTop.Y, "2D Height of Plane: " + rect.Height.ToString());
        g.TextOut(horizRight.X, horizRight.Y, "2D Width of Plane: " + rect.Width.ToString());
      };

      DrawCalcAnotherPlane();
    }
which gives me:
TChart636305526895053960.png
TChart636305526895053960.png (28.99 KiB) Viewed 19758 times
and
TChart636305526774326971.png
TChart636305526774326971.png (62.87 KiB) Viewed 19758 times
biqpaulson wrote: Remember, the reason we want this is to be able to detect and control how "small" the chart gets, because sometime (since we offer a lot of controls for the user), the chart can get so small that nothing is rendered. We want to stop that from happening. Is there any way we can get this functionality?
Okay, if I'm not mistaken the technique I proposed to you worked for you with 2D charts - with any luck this conversation will help you get it to work with 3D charts as well. If not, do please let me know.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

biqpaulson
Newbie
Newbie
Posts: 93
Joined: Thu Apr 17, 2008 12:00 am

Re: Height in GetAxesChartRectEventArgs for 3D charts

Post by biqpaulson » Thu Jun 08, 2017 3:34 pm

The latest work-around works great! Thanks! That will do the job nicely.

Post Reply