protected override double GetYData(int xPosition, double yPosition) { double YData; GraphLine normalisationTrace = traces.Find(t => t.Index == NormalisationIndex); switch (NormalisationType) { case Graphing.NormalisationType.OnAverageValue: double finalValue = normalisationTrace.DataPoints[normalisationTrace.DataPoints.Count - 1].Y; double averageValue = finalValue / (normalisationTrace.DataPoints.Count - 1); YData = yPosition + (xPosition * averageValue); break; case Graphing.NormalisationType.OnEveryValue: double offsetValue = normalisationTrace.DataPoints[xPosition].Y; YData = yPosition + offsetValue; break; default: YData = base.GetYData(xPosition, yPosition); break; } return(YData); }
/// <summary> /// Returns the trace that represents the trace with the lowest final value; the lowest cumulative time overall /// </summary> protected GraphLine GetBestTrace() { GraphLine bestTrace = null; if (traces.Count > 0) { double lowestTotal = 0; int tracesChecked = 0; foreach (GraphLine line in traces) { if (line.Show) { if (tracesChecked++ == 0) { bestTrace = line; lowestTotal = line.DataPoints.Last().Y; } else { if (line.DataPoints.Last().Y < lowestTotal) { bestTrace = line; } } } } } return(bestTrace); }
private List <GraphLine> GetNormalisedLinesOnAverageValue() { GraphLine normalisationTrace = traces.Find(t => t.Index == NormalisationIndex); double finalValue = normalisationTrace.DataPoints[normalisationTrace.DataPoints.Count - 1].Y; double averageValue = finalValue / (normalisationTrace.DataPoints.Count - 1); List <GraphLine> normalisedLines = new List <GraphLine>(); List <DataPoint> normalisedPoints; DataPoint pointToNormalise; int pointIndex; for (int lineIndex = 0; lineIndex < traces.Count; lineIndex++) { normalisedPoints = new List <DataPoint>(); pointIndex = 0; while (pointIndex < traces[lineIndex].DataPoints.Count && pointIndex < normalisationTrace.DataPoints.Count) { pointToNormalise = traces[lineIndex].DataPoints[pointIndex]; normalisedPoints.Add(new DataPoint(pointToNormalise.X, pointToNormalise.Y - averageValue * pointIndex, pointToNormalise.index, pointToNormalise.isCycled)); pointIndex++; } normalisedLines.Add(new GraphLine(normalisedPoints, traces[lineIndex].Index, traces[lineIndex].Show, traces[lineIndex].LineColour)); } return(normalisedLines); }
private List <GraphLine> GetCycledLines() { //The traces are still in data form; they have not yet been normalised. //For now, we assume that the traces are cumulative. If they are not then the mathematics becomes somewhat simpler. //We also assume that we want to cycle based on the trace value, rather than a constant. This can be altered later too. //The upper and lower cycling limits could be based on a different calculation (e.g. lap ahead, lap behind calculations, // or even the difference between the line ahead and the line behind being a percentage of the line ahead. //TODO: work out what sort of model accurately represents line cycling. //Use the normalisation trace for cycling on. GraphLine cycleLine = traces.Find(l => l.Index == NormalisationIndex); List <GraphLine> newTraces = new List <GraphLine>(); List <DataPoint> cycledPoints; DataPoint pointToAlter; double cycleLimit; bool lineCycled; int pointIndex; for (int lineIndex = 0; lineIndex < traces.Count; lineIndex++) { pointIndex = 0; cycledPoints = new List <DataPoint>(); while (pointIndex < traces[lineIndex].DataPoints.Count && pointIndex < cycleLine.DataPoints.Count) { lineCycled = false; pointToAlter = traces[lineIndex].DataPoints[pointIndex]; //Cycling is evaluated on every point. if (pointIndex > 0) //The first points are never cycled { //The limit is given by the most recent lap time of the normalisation trace. cycleLimit = (cycleLine.DataPoints[pointIndex].Y - cycleLine.DataPoints[pointIndex - 1].Y) / 2; //Continue to cycle either up or down until it is within bounds. while (pointToAlter.Y > cycleLine.DataPoints[pointIndex].Y + cycleLimit || pointToAlter.Y < cycleLine.DataPoints[pointIndex].Y - cycleLimit) { if (pointToAlter.Y > cycleLine.DataPoints[pointIndex].Y + cycleLimit) { //Getting too far ahead so cycle down pointToAlter.Y -= cycleLimit * 2; lineCycled = true; } else if (pointToAlter.Y < cycleLine.DataPoints[pointIndex].Y - cycleLimit) { pointToAlter.Y += cycleLimit * 2; lineCycled = true; } } } cycledPoints.Add(new DataPoint(pointToAlter.X, pointToAlter.Y, pointToAlter.index, lineCycled)); pointIndex++; } newTraces.Add(new GraphLine(cycledPoints, traces[lineIndex].Index, traces[lineIndex].Show, traces[lineIndex].LineColour)); } return(newTraces); }
private GraphLine GetLine(GraphLine lineOfData) { GraphLine newLine = new GraphLine(lineOfData.Index, lineOfData.Show, lineOfData.LineColour); foreach (DataPoint p in lineOfData.DataPoints) { newLine.AddDataPoint(GetPointOrdinate(p.X, horizontalAxis, true), GetPointOrdinate(p.Y, verticalAxis, false), p.isCycled); } return(newLine); }
protected virtual GraphLine[] CalculateLines(List <GraphLine> tracesToCalculateFrom) { GraphLine[] linesToDraw = new GraphLine[tracesToCalculateFrom.Count]; int lineIndex = 0; foreach (var lineOfData in tracesToCalculateFrom) { linesToDraw[lineIndex++] = GetLine(lineOfData); } return(linesToDraw); }
public void AddTrace(GraphLine trace) { this.originalTraces.Add(trace); SetupAxes(); Invalidate(); }
void CyclingGraph_CycleValueChanged(object sender, GraphLine e) { Invalidate(); }