TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
-
Nitin
- Newbie
- Posts: 52
- Joined: Fri Jun 30, 2006 12:00 am
Post
by Nitin » Wed Aug 12, 2009 1:09 pm
Hi TeaChart Team,
I am using the nearest point tool to get the nearest point out of 100 fast line serieses. I am able to get the nearest point value correctly. Now i want to draw a vertical dashed line from that nearest point to my bottom axis with a circle at the point. For drawing the line i am using the DrawLine tool. I have 3000 data points in each series. Using the draw line tool i am able to draw the line also but after a certain value of x-axis (if the valueIndex > 2000 or so) - the line is not getting drawn. Please see the code below -
Code: Select all
private void TeeChart_MouseMove(object sender, MouseEventArgs e)
{
if (TeeChart.Series.Count <= 0) return;
CalCulateNearestPoint(e);
}
private void CalCulateNearestPoint(MouseEventArgs e)
{
int[] NearestPoints;
int SeriesIndex, ValueIndex;
double Dist, tmp;
Point P1, P2;
NearestPoints = new int[TeeChart.Series.Count];
P1 = new Point(0, 0);
P2 = new Point(TeeChart.Width, TeeChart.Height);
SeriesIndex = 0;
ValueIndex = 0;
for (int i = 0; i < NearestPoints.Length; i++)
{
_NearestPointTool.Series = TeeChart.Series[i];
NearestPoints[i] = _NearestPointTool.GetNearestPoint(new Point(e.X, e.Y));
}
_NearestPointTool.Series = null;
Dist = Distance(P1, P2);
int StartPt = -1;
int EndPt = -1;
for (int i = 0; i < NearestPoints.Length; i++)
{
P1.X = TeeChart.Series[i].CalcXPos(NearestPoints[i]);
P1.Y = TeeChart.Series[i].CalcYPos(NearestPoints[i]);
P2.X = e.X;
P2.Y = e.Y;
tmp = Distance(P1, P2);
if ((i == 0) || (tmp < Dist))
{
Dist = tmp;
SeriesIndex = i;
ValueIndex = NearestPoints[i];
}
}
if (_DrawLine != null)
TeeChart.Tools.Remove(_DrawLine);
TeeChart.Tools.Add(_DrawLine = new DrawLine());
_DrawLine.EnableDraw = false;
_DrawLine.Button = MouseButtons.XButton2;
_DrawLine.Series = TeeChart.Series[SeriesIndex];
_DrawLine.Pen.Color = Color.Gray;
_DrawLine.Pen.Width = 1;
_DrawLine.Pen.DashPattern = new float[] { 4.0f, 4.0f, 2.0f, 2.0f, 4.0f };
_DrawLine.Pen.Style = System.Drawing.Drawing2D.DashStyle.Custom;
_DrawLine.Pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
_DrawLine.Pen.DashCap = System.Drawing.Drawing2D.DashCap.Round;
DrawLineItem _DrawLineItem = new DrawLineItem(_DrawLine);
_DrawLineItem.StartPos = new Steema.TeeChart.Drawing.PointDouble((double)ValueIndex, 0);
_DrawLineItem.EndPos = new Steema.TeeChart.Drawing.PointDouble((double)ValueIndex, TeeChart.Series[SeriesIndex].YValues[ValueIndex]);
_DrawLine.Invalidate();
if (_AnnotationTool != null)
TeeChart.Tools.Remove(_AnnotationTool);
_AnnotationTool = new Annotation(TeeChart.Chart);
TeeChart.Tools.Add(_AnnotationTool);
_AnnotationTool.Text = "Series: " + TeeChart.Series[SeriesIndex].Title + " - ValueIndex: " + TeeChart.Series[SeriesIndex].YValues[ValueIndex].ToString() + " - Label: " + lTimeStamps[ValueIndex];
_AnnotationTool.Left = e.X + 5;
_AnnotationTool.Top = e.Y - 25;
}
private double Distance(Point Pt1, Point Pt2)
{
int dx, dy;
dx = Pt1.X - Pt2.X;
dy = Pt1.Y - Pt2.Y;
return Math.Sqrt((dx * dx) + (dy * dy));
}
Once the 'ValueIndex' goes beyond 2000 or 2100, line is not getting drawn.
Please let me know if i am doing something wrong.
-
Nitin
- Newbie
- Posts: 52
- Joined: Fri Jun 30, 2006 12:00 am
Post
by Nitin » Thu Aug 13, 2009 10:42 am
Also, the same logic for calcualting the nearest point out of 100 serieses is not working when i have zoomed the chart. Please let me know how i can get the nearest point when my chart is in zoomed state.
-
Yeray
- Site Admin
- Posts: 9612
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Thu Aug 13, 2009 11:16 am
Hi Nitin,
Could you please take a look at this example? I've mixed the interpolation demo with your code and the result doesn't look too bad.
If there is any feature that still doesn't work as expected, please don't hesitate to let us know.
Code: Select all
public Form1()
{
InitializeComponent();
InitializeChart();
}
int SeriesIndex, ValueIndex;
NearestPoint _NearestPointTool;
Annotation _AnnotationTool;
private void InitializeChart()
{
chartController1.Chart = tChart1;
tChart1.Aspect.View3D = false;
for (int i = 0; i < 10; i++)
{
new FastLine(tChart1.Chart);
tChart1[i].FillSampleValues(1000);
}
_AnnotationTool = new Annotation(tChart1.Chart);
_NearestPointTool = new NearestPoint(tChart1.Chart);
tChart1.MouseMove += new MouseEventHandler(tChart1_MouseMove);
tChart1.AfterDraw += new Steema.TeeChart.PaintChartEventHandler(tChart1_AfterDraw);
}
void tChart1_MouseMove(object sender, MouseEventArgs e)
{
tChart1.Header.Text = "";
CalculateNearestPoint(e);
if (tChart1.Series[0] is Steema.TeeChart.Styles.FastLine)
{
_AnnotationTool.Text = "Series: " + tChart1.Series[SeriesIndex].Title + " - ValueIndex: " + tChart1.Series[SeriesIndex].YValues[ValueIndex].ToString();
_AnnotationTool.Left = e.X + 5;
_AnnotationTool.Top = e.Y - 25;
}
}
void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
{
double xval = tChart1.Series[SeriesIndex].XValues[ValueIndex];
int xs = tChart1.Axes.Bottom.CalcXPosValue(xval);
int ys;
g.Brush.Visible = true;
g.Brush.Solid = true;
if (tChart1.Series[SeriesIndex] is Steema.TeeChart.Styles.FastLine)
{
ys = tChart1.Series[SeriesIndex].GetVertAxis.CalcYPosValue(InterpolateLineSeries(tChart1.Series[SeriesIndex] as Steema.TeeChart.Styles.FastLine, xval));
g.Brush.Color = tChart1.Series[SeriesIndex].Color;
g.Line(xs, tChart1.Axes.Left.CalcYPosValue(0), xs, ys);
g.Ellipse(new Rectangle(xs - 4, ys - 4, 8, 8));
}
}
private double InterpolateLineSeries(Steema.TeeChart.Styles.FastLine series, int firstindex, int lastindex, double xvalue)
{
int index;
for (index = firstindex; index <= lastindex; index++)
{
if (index == -1 || series.XValues.Value[index] > xvalue) break;
}
// safeguard
if (index < 1) index = 1;
else if (index >= series.Count) index = series.Count - 1;
double dx = series.XValues[index] - series.XValues[index - 1];
double dy = series.YValues[index] - series.YValues[index - 1];
if (dx != 0.0) return dy * (xvalue - series.XValues[index - 1]) / dx + series.YValues[index - 1];
else return 0.0;
}
private double InterpolateLineSeries(Steema.TeeChart.Styles.FastLine series, double xvalue)
{
return InterpolateLineSeries(series, series.FirstVisibleIndex, series.LastVisibleIndex, xvalue);
}
private void CalculateNearestPoint(MouseEventArgs e)
{
int[] NearestPoints;
double Dist, tmp;
Point P1, P2;
NearestPoints = new int[tChart1.Series.Count];
P1 = new Point(0, 0);
P2 = new Point(tChart1.Width, tChart1.Height);
SeriesIndex = 0;
ValueIndex = 0;
for (int i = 0; i < NearestPoints.Length; i++)
{
_NearestPointTool.Series = tChart1.Series[i];
NearestPoints[i] = _NearestPointTool.GetNearestPoint(new Point(e.X, e.Y));
}
_NearestPointTool.Series = null;
Dist = Distance(P1, P2);
for (int i = 0; i < NearestPoints.Length; i++)
{
if (NearestPoints[i] > -1)
{
P1.X = tChart1.Series[i].CalcXPos(NearestPoints[i]);
P1.Y = tChart1.Series[i].CalcYPos(NearestPoints[i]);
P2.X = e.X;
P2.Y = e.Y;
tmp = Distance(P1, P2);
if ((i == 0) || (tmp < Dist))
{
Dist = tmp;
SeriesIndex = i;
ValueIndex = NearestPoints[i];
}
}
}
}
private double Distance(Point Pt1, Point Pt2)
{
int dx, dy;
dx = Pt1.X - Pt2.X;
dy = Pt1.Y - Pt2.Y;
return Math.Sqrt((dx * dx) + (dy * dy));
}
-
Nitin
- Newbie
- Posts: 52
- Joined: Fri Jun 30, 2006 12:00 am
Post
by Nitin » Fri Aug 14, 2009 12:09 pm
Thanks for your reply Yeray. I have implemented the way you have suggested. It is working fine. But there is performance issue with it. If i have 2 serieses and each of the series is having 250000 data points in it then the below part of the code is becoming a performance issue.
Code: Select all
private double InterpolateLineSeries(Steema.TeeChart.Styles.FastLine _Series, int FirstVisibleIndex, int LastVisibleIndex, double xvalue)
{
int index;
for (index = FirstVisibleIndex; index <= LastVisibleIndex; index++)
{
if (index == -1 || _Series.XValues.Value[index] > xvalue) break;
}
}
Because if the mouse position goes to the end of X-axis then i have to iterate through the whole data series of 250000 data points to get the index value.
-
Yeray
- Site Admin
- Posts: 9612
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Fri Aug 14, 2009 12:52 pm
Hi Nitin,
Well, if your XValues are ordered you always can apply a searching algorithm to improve the performance considerably.