In a program I am currently building, a series of arrays are stored for each trace that is taken of a part. Each trace is composed of several arrays of doubles all with a length of 4096. Up to 4 traces can be taken.
The pertinent array for this issue is the Angle array, which is an array of values interpolated from -90 to 90 degrees over 4096 data points (so approx. .044 degrees per index). This array is plotted on a C# chart control against another array of thickness data (also 4096 points).
My chart control also implements the MouseMove event which draws a cursor attached to the X axis (-90 to 90 degrees) on the chart with an interval of .1. The idea is that when a user mouses over the chart, an annotation will popup at the top of the chart displaying the thickness data for the moused over angle.
In the background, each time the MouseMove event is fired off, the X position of the cursor on the chart is put into a function to find the index of the closest angle in the Angle array of trace 1. Here's the search code:
private int FindIndexOfAngle(double Angle)
{
int closestX = Array.BinarySearch(Traces[0].AngleArray, Angle);
if (closestX < 0)
{
closestX = ~closestX; // If closestX is bitwise complement of index of next highest value from binary search
double closestY = Traces[0].AngleArray[closestX] - Angle;
if (Traces[0].AngleArray[closestX - 1] - Angle < closestY) closestX = closestX - 1;
}
return closestX;
}
And here is the chart MouseMove event:
private void chartMain_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (chartMain.Series.Count > 0)
{
Point mousePoint = new Point(e.X, e.Y);
chartMain.ChartAreas[0].CursorX.SetCursorPixelPosition(mousePoint, true);
double pX = chartMain.ChartAreas[0].CursorX.Position;
if (pX >= -90 && pX <= 90)
{
chartMain.ChartAreas[0].CursorX.LineColor = Color.Red;
//if (pX == 90) chartMain.ChartAreas[0].CursorX.Position = 89.9;
RectangleAnnotation anno = new RectangleAnnotation();
int index = FindIndexOfAngle(pX);
anno.Text = pX.ToString("0.00") + " degrees";
if (Surface == Traces.Count)
{
for (int x = 0; x < Traces.Count; x++)
{
if (MeasurementSettings.PlotRawData) anno.Text += "\nTrace " + (x + 1) + ": " + Traces[x].ThicknessRaw[index].ToString("0.000 000") + " " + MainSettings.UnitsName;
else anno.Text += "\nTrace " + (x + 1) + ": " + Traces[x].ThicknessFiltered[index].ToString("0.000 000") + " " + MainSettings.UnitsName;
}
}
else
{
if (MeasurementSettings.PlotRawData) anno.Text += "\nTrace " + (Surface + 1) + ": " + Traces[Surface].ThicknessRaw[index].ToString("0.000 000") + " " + MainSettings.UnitsName;
else anno.Text += "\nTrace " + (Surface + 1) + ": " + Traces[Surface].ThicknessFiltered[index].ToString("0.000 000") + " " + MainSettings.UnitsName;
}
anno.Font = new Font("Microsoft Sans Serif", 12);
anno.AnchorX = 50;
anno.AnchorY = 14;
chartMain.Annotations.Clear();
chartMain.Annotations.Add(anno);
}
else chartMain.ChartAreas[0].CursorX.LineColor = Color.Transparent;
}
else chartMain.ChartAreas[0].CursorX.LineColor = Color.Transparent;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
This index is then used to display the thickness value for each trace displayed on the screen (up to 4 at a time).
When only 1 trace active, this works extremely well. But as soon as 2 or more traces are active, it slows down dramatically.
How can I speed this up, short of increasing the interval?