Page 1 of 1

null points in 3d graphs

Posted: Fri Sep 21, 2007 7:37 am
by 13046157
Hi,

What I am trying to achieve is to draw a series of lines in real-world coordinates. I have been able to do this in 2D using a line series and adding null points between the line coordinates to break the line series at appropriate points, using 'Add(Double.NaN, Double.NaN, Color.Transparent)'. This also requires lines1.TreatNulls to be set to ...TreatNullsStyle.DoNotPaint.

I would like to do the same thing with 3D coordinates, however I find that the various 3D series do not seem to have the ability to support nulls in this way. That is, they don't have the TreatNulls property, and they don't support Double.NaN or null in the Add(x,y,z,color) methods.

Is there any other way I can make this work?

Posted: Fri Sep 21, 2007 7:57 am
by narcis
Hi Courteous,

Yes, you can add null values to 3D series just setting point's color to Color.Transparent.

Posted: Sun Sep 23, 2007 11:58 pm
by 13046157
Hi Narcis,

I've tried adding a null point to a 3d series using Color.Transparent, but the problem is that the lines are drawn to and from the null points. I can avoid this with 2d series by setting the x,y values to Double.NaN, but doing that with a 3d series results in an overflow exception. I assume it is because the 3d Add methods don't support nullable parameters as do the 2d ones.

More help please!

Posted: Mon Sep 24, 2007 8:27 am
by narcis
Hi Courteous,

Could you please try adding null values as the example in the last message of this thread?

Thanks in advance.

Posted: Tue Sep 25, 2007 6:39 am
by 13046157
Narcis,

I think I've tried what you are suggesting, without success. To hopefully make clear what my issue is, I've included some code examples:

The 2d case (that works):

Code: Select all

line1.XValues.Order = Steema.TeeChart.Styles.ValueListOrder.None;
line1.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
line1.DefaultNullValue = Double.NaN;

line1.Clear();

for (int pti = 0; pti < Count; pti++) {
   if (Double.IsNaN(X[pti])) {
      line1.Add(Double.NaN, Double.NaN, Color.Transparent);
   } else {
      line1.Add(X[pti], Y[pti], Color.Blue);
   }
}
The above works. Point (x1,y1) joins to (x2,y2), but point (x3=NaN,y3=NaN) does not.

The 3d case:

Code: Select all

points3D1.XValues.Order = Steema.TeeChart.Styles.ValueListOrder.None;
points3D1.DefaultNullValue = Double.NaN;

points3D1.Clear();
int nonnani = -1;

for (int pti = 0; pti < Count; pti++) {
   if (Double.IsNaN(X[pti])) {
      if (nonnani != -1) {
         //Attempt 1-> Overflow exception  
         points3D1.Add(null, null, null, Color.Transparent); 
         
         //Attempt 2 -> Draws lines to and from null points (bad)
         //points3D1.Add(X[nonnani], Y[nonnani], 0, Color.Transparent); 

         //Attempt 3 -> Draws lines to and from null points (bad)
         //points3D1.Add(X[nonnani], Y[nonnani], 0, "", Color.Transparent); 
 
         //Attempt 4 -> Overflow exception
         //points3D1.Add(Double.NaN, Double.NaN, Double.NaN, 
         //    Color.Transparent);  
      }
					
   } else {
      nonnani = pti;
      points3D1.Add(X[pti], Y[pti], 0, Color.Blue);
   }
}
Any further thoughts?

Posted: Tue Sep 25, 2007 9:08 am
by narcis
Hi Courteous,

Thanks for the information.

I've added your request to our wish-list to be implemented for future releases. In the meantime you can do something as the code below. It basically sets the LinePen.Color to Color.Transparent and in the AfterDraw event manually draw the lines for the non-transparent points. Also, the GetPointerStyle "hides" the pointer for null points.

Code: Select all

		private void Form1_Load(object sender, EventArgs e)
		{
			Random y = new Random();

			for (int x = 0; x < 10; x++)
			{
				for (int z = 0; z < 10; z++)
				{
					if ((x==5) && (z==5))
						points3D1.Add(x, y.Next(), z, Color.Transparent);
					else
						points3D1.Add(x, y.Next(), z);					
				}
			}

			points3D1.LinePen.Color = Color.Transparent;
		}

		private void points3D1_GetPointerStyle(Steema.TeeChart.Styles.Points3D series, Steema.TeeChart.Styles.GetPointerStyleEventArgs e)
		{
			if (series.ValueColor(e.ValueIndex)==Color.Transparent)
			{
				e.Style = Steema.TeeChart.Styles.PointerStyles.Nothing;
			}
		}

		private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
		{
			for (int i = 1; i < points3D1.Count; i++)
			{
				if ((points3D1.ValueColor(i-1) != Color.Transparent) && (points3D1.ValueColor(i) != Color.Transparent))
				{
					g.Pen.Color = Color.Black;
					g.Line(points3D1.CalcXPos(i - 1), points3D1.CalcYPos(i - 1), points3D1.CalcZPos(i - 1),
									points3D1.CalcXPos(i), points3D1.CalcYPos(i), points3D1.CalcZPos(i));
				}
			}
		}

Posted: Wed Sep 26, 2007 4:39 am
by 13046157
Thanks, that has helped, but unfortunately it leads to another related problem.

When I zoom in on the lines as drawn in a 3d points series, they are at least partly drawn outside the axes bounds.

I have attempted to use clipping to resolve this. g.ClipRectangle(g.Chart.ChartRect) seems to fix it in 2d mode. For 3d mode,
I've tried g.ClipCube(g.Chart.ChartRect, zmin, zmax), but I'm not sure how to get zmin and zmax. I can get the minimum and maximum extent of the depth axis (eg. tChart_EventMap.Chart.Axes.Depth.Minimum) but this needs to be converted to an integer (pixels?) somehow to be passed into ClipCube.

I would use points3D1.CalcZPosValue(), but it doesn't seem to exist.

Any advice appreciated.

Posted: Wed Sep 26, 2007 7:28 am
by narcis
Hi Courteous,

Ok, try using depth axis pixel positions: tChart1.Axes.Depth.IStartPos and tChart1.Axes.Depth.IEndPos.

Posted: Thu Sep 27, 2007 12:39 am
by 13046157
Thanks Narcis, that partly works. The image does not appear quite how I expect it to though...

What I am doing is drawing a horizontal line (using point3d style) across the back of the box. Either drawing a line with Line(), or plotting points with a line between them gives the same affect.

When unzoomed, rotation works correctly.

But if I zoom in so that I can only see part of the line, then rotate around a vertical axis (so +x moves towards the viewer), the view doesn't seem to work properly. For small rotation angles say less than 45 degrees, the line appears to stop at the front of the box on the left hand side, suggesting that it is not drawn along the back.

However when the rotation is increased to near 90 degrees (looking along the x axis) the line end then appears to move towards the back where it should be.

I believe this is because the line is not being clipped properly at the left hand end when in 3d mode.

It's probably hard to visualise with the text, but doing what I've said should allow you to see what I mean. If not, I'll have to provide you some code.[/img]

Posted: Thu Sep 27, 2007 11:09 am
by narcis
Hi Courteous,

I've modified the original example I posted adding ClipCube like this:

Code: Select all

		private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
		{
			g.ClipCube(tChart1.Chart.ChartRect, tChart1.Axes.Depth.IStartPos, tChart1.Axes.Depth.IEndPos);
			for (int i = 1; i < points3D1.Count; i++)
			{
				if ((points3D1.ValueColor(i-1) != Color.Transparent) && (points3D1.ValueColor(i) != Color.Transparent))
				{
					g.Pen.Color = Color.Black;
					g.Line(points3D1.CalcXPos(i - 1), points3D1.CalcYPos(i - 1), points3D1.CalcZPos(i - 1),
									points3D1.CalcXPos(i), points3D1.CalcYPos(i), points3D1.CalcZPos(i));
				}
			}
		}
This works fine here but there's a known issue that is that the "ChartCube" outline is permanently drawn leaving odd traces of previous positions. This is because of an issue with the classes used to draw the rectangle (ControlPaint).

Regarding the issue you now report, would you be so kind to send us a simple example project we can run "as-is" or modify the example above so that we can reproduce the issue here?

You can post your files at news://www.steema.net/steema.public.attachments newsgroup or at our upload page.

Thanks in advance.

Posted: Mon Oct 01, 2007 12:32 am
by 13046157
OK, I've uploaded an example to show the issue. Note that all I've done is draw lines across the back of the chart with the GUI editor, and I see the problem there. I'm guessing the problem I see when I draw the lines manually and use ClipCube are a reflection of the same thing.

Run the project, zoom in around the centre horizontal line, so the zoomed area should show about half the line's length. Then rotate the chart, paying attention to the left hand end of the line. If you rotate far enough, you can actually see the point on the end of the line, even though the wall is meant to be opaque, and (I assume) the line should be clipped to the chart boundaries.

I haven't done it in this example, but lines drawn manually show the same symptoms.

Posted: Mon Oct 01, 2007 8:53 am
by narcis
Hi Courteous,

Thanks for the example project, I've been able to reproduce the problem here and added it (TF02012476) to our defect list to be enhanced for future releases.