Page 1 of 2

Down Sampling version 3.0

Posted: Thu May 24, 2007 4:10 pm
by 9642161
I modified the sample that you supplied with version 3 to contain 2 fastline series. What I am finding when I change the sample size is the first series has the correct number of points but the count on the fastline series is showing 0. The second series has the correct point count and number of points.


public partial class Form1 : Form
{

private Steema.TeeChart.Styles.Points points;
private Steema.TeeChart.Styles.FastLine fastLine;
private Steema.TeeChart.Functions.DownSampling downSampling;
private Nullable<double>[] xValues, yValues;


public Form1()
{
InitializeComponent();

InitializeChart();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void CreateArrays()
{
int length = 2000;

xValues = new Nullable<double>[length];
yValues = new Nullable<double>[length];

Random rnd = new Random();
for (int i = 0; i < length; i++)
{
xValues = i;
if (i % 20 == 0)
{
yValues = null;
}
else
{
yValues = rnd.Next(100);
}
}
}

private void InitializeChart()
{
CreateArrays();
tChart1.Aspect.View3D = false;
tChart1.Zoom.Direction = ZoomDirections.Horizontal;
tChart1.Series.Add(points = new Steema.TeeChart.Styles.Points());
tChart1.Series.Add(fastLine = new Steema.TeeChart.Styles.FastLine());

downSampling = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
points.Add(xValues, yValues);
points.Active = false;

downSampling.DisplayedPointCount = 1000;
downSampling.Method = Steema.TeeChart.Functions.DownSamplingMethod.MinMaxFirstLastNull;
fastLine.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
fastLine.DataSource = points;
fastLine.Function = downSampling;


CreateArrays();
tChart1.Series.Add(points = new Steema.TeeChart.Styles.Points());
tChart1.Series.Add(fastLine = new Steema.TeeChart.Styles.FastLine());

points.Add(xValues, yValues);
points.Active = false;

fastLine.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
fastLine.DataSource = points;
fastLine.Function = downSampling;

}

private void tChart1_Zoomed(object sender, EventArgs e)
{
tChart1[1].CheckDataSource(); //series 1 is the function series
tChart1[3].CheckDataSource();
}

private void tChart1_UndoneZoom(object sender, EventArgs e)
{
tChart1.Axes.Bottom.SetMinMax(0, tChart1[0].Count); //series 0 is the original series, although you could use any value to set the maximum
tChart1[1].CheckDataSource();
tChart1[3].CheckDataSource();
}

private void udPointCount_ValueChanged(object sender, EventArgs e)
{
downSampling.DisplayedPointCount = (int)udPointCount.Value;
tChart1.Axes.Bottom.SetMinMax(0, tChart1[0].Count);
tChart1[1].CheckDataSource();
tChart1[3].CheckDataSource();

//tChart1[1].Count is 0
//tChart1[3].Count is showing the correct number

}

}

Am I implementing it correctly

Thanks

Posted: Thu May 24, 2007 4:22 pm
by Chris
Hello,

Were you able to reproduce this problem with any of the pre-release versions of v3 or is this issue new to the release version?

Posted: Thu May 24, 2007 4:42 pm
by 9642161
Christopher

I did only some simple single series testing on the pre release version similiar to the sample. I started to roll out down sampling with my application after release and found the first series was not being displayed when changing the number of sample point so I modified your sample to have multiple series to see if I could reproduce. I thought that I maybe doing something incorrectly so I thought I would post to see if I have implemented correctly.

Posted: Fri May 25, 2007 8:18 am
by Chris
Keith,

Ok, no problem. What is happening here is that one object is being expected to behave as if it were two. To fix this simply double up the required objects, e.g.

Code: Select all

public partial class Form1 : Form
	{

		private Steema.TeeChart.Styles.Points points;
		private Steema.TeeChart.Styles.FastLine fastLine;
		private Steema.TeeChart.Styles.Points points1;
		private Steema.TeeChart.Styles.FastLine fastLine1;
		private Steema.TeeChart.Functions.DownSampling downSampling;
		private Steema.TeeChart.Functions.DownSampling downSampling1;
		private Nullable<double>[] xValues, yValues;


		public Form1()
		{
			InitializeComponent();

			InitializeChart();
		}

		private void Form1_Load(object sender, EventArgs e)
		{

		}

		private void CreateArrays()
		{
			int length = 2000;

			xValues = new Nullable<double>[length];
			yValues = new Nullable<double>[length];

			Random rnd = new Random();
			for (int i = 0; i < length; i++)
			{
				xValues[i] = i;
				if (i % 20 == 0)
				{
					yValues[i] = null;
				}
				else
				{
					yValues[i] = rnd.Next(100);
				}
			}
		}

		private void InitializeChart()
		{
			CreateArrays();
			tChart1.Aspect.View3D = false;
			tChart1.Zoom.Direction = ZoomDirections.Horizontal;
			tChart1.Series.Add(points = new Steema.TeeChart.Styles.Points());
			tChart1.Series.Add(fastLine = new Steema.TeeChart.Styles.FastLine());

			downSampling = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
			downSampling1 = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
			points.Add(xValues, yValues);
			points.Active = false;

			downSampling.DisplayedPointCount = 1000;
			downSampling.Method = Steema.TeeChart.Functions.DownSamplingMethod.MinMaxFirstLastNull;
			fastLine.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
			fastLine.DataSource = points;
			fastLine.Function = downSampling;


			CreateArrays();
			tChart1.Series.Add(points1 = new Steema.TeeChart.Styles.Points());
			tChart1.Series.Add(fastLine1 = new Steema.TeeChart.Styles.FastLine());

			points1.Add(xValues, yValues);
			points1.Active = false;

			fastLine1.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
			fastLine1.DataSource = points1;
			fastLine1.Function = downSampling1;

		}

		private void tChart1_Zoomed(object sender, EventArgs e)
		{
			tChart1[1].CheckDataSource(); //series 1 is the function series
			tChart1[3].CheckDataSource();
		}

		private void tChart1_UndoneZoom(object sender, EventArgs e)
		{
			tChart1.Axes.Bottom.SetMinMax(0, tChart1[0].Count); //series 0 is the original series, although you could use any value to set the maximum
			tChart1[1].CheckDataSource();
			tChart1[3].CheckDataSource();
		}

		private void udPointCount_ValueChanged(object sender, EventArgs e)
		{
			downSampling.DisplayedPointCount = (int)udPointCount.Value;
			tChart1.Axes.Bottom.SetMinMax(0, tChart1[0].Count);
			tChart1[1].CheckDataSource();
			tChart1[3].CheckDataSource();

			//tChart1[1].Count is 0
			//tChart1[3].Count is showing the correct number

		}

	} 

Posted: Fri May 25, 2007 2:03 pm
by 9642161
Hi

That corrected one issue now I seem to have a issue with zooming as it looks like the count on the points is not dropping as I narrow my zoom. I changed the sample to DataTime as this is close to what we are doing. As I zoom in I check the count on the fastline series and it is not dropping. Is there something that I am doing wrong?

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Steema.TeeChart;


namespace DownSample
{
public partial class Form1 : Form
{

private Steema.TeeChart.Styles.Points points;
private Steema.TeeChart.Styles.FastLine fastLine;
private Steema.TeeChart.Functions.DownSampling downSampling;
private Steema.TeeChart.Functions.DownSampling downSampling1;
private Nullable<double>[] xValues, yValues;


public Form1()
{
InitializeComponent();

InitializeChart();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void CreateArrays()
{
int length = 2000;

xValues = new Nullable<double>[length];
yValues = new Nullable<double>[length];

Random rnd = new Random();
for (int i = 0; i < length; i++)
{
DateTime dt = DateTime.Now - new TimeSpan(0, 0, i, 0);

xValues = dt.ToOADate();

if (i % 20 == 0)
{
yValues = null;
}
else
{
yValues = rnd.Next(100);
}
}
}

private void InitializeChart()
{
CreateArrays();
tChart1.Aspect.View3D = false;
tChart1.Zoom.Direction = ZoomDirections.Horizontal;
tChart1.Series.Add(points = new Steema.TeeChart.Styles.Points());
tChart1.Series.Add(fastLine = new Steema.TeeChart.Styles.FastLine());

downSampling = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
downSampling1 = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
points.Add(xValues, yValues);
points.XValues.DateTime = true;
points.Active = false;

downSampling.DisplayedPointCount = 1000;
downSampling.Method = Steema.TeeChart.Functions.DownSamplingMethod.MinMaxFirstLastNull;
fastLine.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
fastLine.DataSource = points;
fastLine.Function = downSampling;


CreateArrays();
downSampling1.DisplayedPointCount = 1000;
downSampling1.Method = Steema.TeeChart.Functions.DownSamplingMethod.MinMaxFirstLastNull;

tChart1.Series.Add(points = new Steema.TeeChart.Styles.Points());
tChart1.Series.Add(fastLine = new Steema.TeeChart.Styles.FastLine());

points.Add(xValues, yValues);
points.XValues.DateTime = true;
points.Active = false;

fastLine.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
fastLine.DataSource = points;
fastLine.Function = downSampling1;

}

private void tChart1_Zoomed(object sender, EventArgs e)
{
tChart1[1].CheckDataSource(); //series 1 is the function series
tChart1[3].CheckDataSource();
}

private void tChart1_UndoneZoom(object sender, EventArgs e)
{
//tChart1.Axes.Bottom.SetMinMax(0, tChart1[0].Count); //series 0 is the original series, although you could use any value to set the maximum
tChart1[1].CheckDataSource();
tChart1[3].CheckDataSource();
}

private void udPointCount_ValueChanged(object sender, EventArgs e)
{
((Steema.TeeChart.Functions.DownSampling)tChart1[1].Function).DisplayedPointCount = (int)udPointCount.Value;
((Steema.TeeChart.Functions.DownSampling)tChart1[3].Function).DisplayedPointCount = (int)udPointCount.Value;
//downSampling.DisplayedPointCount = (int)udPointCount.Value;
//downSampling1.DisplayedPointCount = (int)udPointCount.Value;
//tChart1.Axes.Bottom.SetMinMax(0, tChart1[0].Count);
tChart1[1].CheckDataSource();
tChart1[3].CheckDataSource();

}

}
}

Posted: Mon May 28, 2007 7:43 am
by Chris
Hello Keith,

Yes, the problem is that you're not setting XValues.DateTime = true; to both the Points series and the FastLine series. Replacing the InitializeChart() of my example with the following:

Code: Select all

		private void InitializeChart()
		{
			CreateArrays();
			tChart1.Aspect.View3D = false;
			tChart1.Zoom.Direction = ZoomDirections.Horizontal;
			tChart1.Series.Add(points = new Steema.TeeChart.Styles.Points());
			tChart1.Series.Add(fastLine = new Steema.TeeChart.Styles.FastLine());

			downSampling = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
			downSampling1 = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
			points.Add(xValues, yValues);
			points.Active = false;
			points.XValues.DateTime = true;

			downSampling.DisplayedPointCount = 1000;
			downSampling.Method = Steema.TeeChart.Functions.DownSamplingMethod.MinMaxFirstLastNull;
			fastLine.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
			fastLine.XValues.DateTime = true;
			fastLine.DataSource = points;
			fastLine.Function = downSampling;


			CreateArrays();
			tChart1.Series.Add(points1 = new Steema.TeeChart.Styles.Points());
			tChart1.Series.Add(fastLine1 = new Steema.TeeChart.Styles.FastLine());

			points1.Add(xValues, yValues);
			points1.Active = false;
			points1.XValues.DateTime = true;

			fastLine1.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
			fastLine1.XValues.DateTime = true;
			fastLine1.DataSource = points1;
			fastLine1.Function = downSampling1;

		}
Works as expected.

Posted: Mon May 28, 2007 12:04 pm
by 9642161
Christopher

If I take the code I supplied you and modify it to add fastLine.XValues.DateTime = true;

I do not see the count change as I zoom in, I also notice that you only set the downSampling.DisplayedPointCount = 1000;

downSampling1 DisplayedPointCount is not set, is this correct.

We do not know how many series will be displayed so that is why the sample creates new instances of the same variable for each series.

Posted: Mon May 28, 2007 2:11 pm
by Chris
Hello Keith,

I hope that the following class performs as you expect:

Code: Select all

		public partial class Form1 : Form
		{

			private Steema.TeeChart.Styles.Points points;
			private Steema.TeeChart.Styles.FastLine fastLine;
			private Steema.TeeChart.Functions.DownSampling downSampling;
			private Steema.TeeChart.Functions.DownSampling downSampling1;
			private Nullable<double>[] xValues, yValues;


			public Form1()
			{
				InitializeComponent();

				InitializeChart();
			}

			private void Form1_Load(object sender, EventArgs e)
			{

			}

			private void CreateArrays()
			{
				int length = 2000;

				xValues = new Nullable<double>[length];
				yValues = new Nullable<double>[length];

				Random rnd = new Random();
				for(int i = 0; i < length; i++)
				{
					DateTime dt = DateTime.Now - new TimeSpan(0, 0, i, 0);

					xValues[i] = dt.ToOADate();

					if(i % 20 == 0)
					{
						yValues[i] = null;
					}
					else
					{
						yValues[i] = rnd.Next(100);
					}
				}
			}

			private void InitializeChart()
			{
				CreateArrays();
				tChart1.Aspect.View3D = false;
				tChart1.Zoom.Direction = ZoomDirections.Horizontal;
				tChart1.Series.Add(new Steema.TeeChart.Styles.Points());
				tChart1.Series.Add(new Steema.TeeChart.Styles.FastLine());

				downSampling = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
				downSampling1 = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
				points = tChart1[0] as Steema.TeeChart.Styles.Points;
				points.Add(xValues, yValues);
				points.XValues.DateTime = true;
				points.Active = false;

				downSampling.DisplayedPointCount = 1000;
				downSampling.Method = Steema.TeeChart.Functions.DownSamplingMethod.MinMaxFirstLastNull;
				fastLine = tChart1[1] as Steema.TeeChart.Styles.FastLine;
				fastLine.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
				fastLine.XValues.DateTime = true;
				fastLine.DataSource = points;
				fastLine.Function = downSampling;


				CreateArrays();
				downSampling1.DisplayedPointCount = 1000;
				downSampling1.Method = Steema.TeeChart.Functions.DownSamplingMethod.MinMaxFirstLastNull;

				tChart1.Series.Add(new Steema.TeeChart.Styles.Points());
				tChart1.Series.Add(new Steema.TeeChart.Styles.FastLine());
				points = tChart1[2] as Steema.TeeChart.Styles.Points;
				points.Add(xValues, yValues);
				points.XValues.DateTime = true;
				points.Active = false;

				fastLine = tChart1[3] as Steema.TeeChart.Styles.FastLine;
				fastLine.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
				fastLine.XValues.DateTime = true;
				fastLine.DataSource = points;
				fastLine.Function = downSampling1;

			}

			private void tChart1_Zoomed(object sender, EventArgs e)
			{
				tChart1[1].CheckDataSource(); //series 1 is the function series 
				tChart1[3].CheckDataSource();
			}

			private void tChart1_UndoneZoom(object sender, EventArgs e)
			{
				//tChart1.Axes.Bottom.SetMinMax(0, tChart1[0].Count); //series 0 is the original series, although you could use any value to set the maximum 
				tChart1[1].CheckDataSource();
				tChart1[3].CheckDataSource();
			}

			private void udPointCount_ValueChanged(object sender, EventArgs e)
			{
				((Steema.TeeChart.Functions.DownSampling)tChart1[1].Function).DisplayedPointCount = (int)udPointCount.Value;
				((Steema.TeeChart.Functions.DownSampling)tChart1[3].Function).DisplayedPointCount = (int)udPointCount.Value;
				//downSampling.DisplayedPointCount = (int)udPointCount.Value; 
				//downSampling1.DisplayedPointCount = (int)udPointCount.Value; 
				//tChart1.Axes.Bottom.SetMinMax(0, tChart1[0].Count); 
				tChart1[1].CheckDataSource();
				tChart1[3].CheckDataSource();

			}

		}

Posted: Mon May 28, 2007 2:27 pm
by 9642161
Christopher

When I check the count after the zoom the count stays the same it does not matter how much I zoom in the count remains the same.

Posted: Mon May 28, 2007 3:32 pm
by Chris
Keith,

Yes, there does seem to be an issue using DateTime values. Shame it wasn't detected in beta stage, sorry about that. I'll see if I can fix it in the next couple of days so that it's in the next release.

Posted: Mon May 28, 2007 3:37 pm
by 9642161
Christopher

Sorry for not testing the downsampling method furthur and catching it for you.

Posted: Tue May 29, 2007 11:42 am
by Chris
Keith,

Good news! The problem isn't as serious as I first thought and won't necessarily require a source modification.

The issue here is that you're adding your DateTime values to the xValues array in "reverse" order. If instead of doing:

Code: Select all

DateTime dt = DateTime.Now - new TimeSpan(0, 0, i, 0);
you did:

Code: Select all

DateTime dt = DateTime.Now + new TimeSpan(0, 0, i, 0);
Everything seems to be ok. The reason for this is that the xvalues have to be in ascending order for the downsampling algorithmn to work (in fact, what is important here is that they are in any known order). If you were to add the values in using the Add(double x, double y) instead of Add(Array xValues, Array yValues) then the values would be sorted as they were added to the valuelists; however, adding the arrays directly to the valuelists means they aren't sorted, for performance purposes.

So, if you're happy with the way this works, great! If not, please suggest to me how you would like the issue to be dealt with.

Posted: Thu May 31, 2007 12:02 pm
by 9642161
Christopher

That resolved the issue with the count being reduced as I zoom in. I now have an issue when I do an unzoom with the down sampling that the chart is not resetting the zoom.

Posted: Thu May 31, 2007 2:36 pm
by Chris
Hello Keith,

Did you uncomment out the call to SetMinMax() in UndoneZoom? Are you sure this event is correctly hooked up?

Posted: Thu May 31, 2007 3:10 pm
by 9642161
Christopher

If you are using Down sampling do you need to set the MinMax within the unzoom to reset back to the original view?