using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RealTimeGraphX.Renderers { /// /// Represents an heart beat monitor style graph renderer. /// /// The type of the graph data series. /// The type of the x-axis data point. /// The type of the y-axis data point. /// public class GraphEraseRenderer : GraphRendererBase where XDataPoint : GraphDataPointBase where YDataPoint : GraphDataPointBase where TDataSeries : class, IGraphDataSeries { private Dictionary _series_replace_index_dictionary = new Dictionary(); /// /// Returns an array of absolute graph data points to render. /// This method is called per data series. /// /// A collection of all data series that is currently in the rendering pass. /// The current data series to render. /// Pending data series object to render. /// protected override List OnRender(IEnumerable seriesCollection, TDataSeries series, PendingSeries toRender) { int replace_index = 0; int new_items = toRender.NewItemsCount; if (_series_replace_index_dictionary.ContainsKey(series)) { replace_index = _series_replace_index_dictionary[series]; } else { _series_replace_index_dictionary.Add(series, 0); } XDataPoint min_x = toRender.XX.Min(); XDataPoint max_x = toRender.XX.Max(); YDataPoint min_y = Input.Range.MinimumY; YDataPoint max_y = Input.Range.MaximumY; if (Input.Range.AutoY) { min_y = seriesCollection.SelectMany(x => x.YY).Min(); max_y = seriesCollection.SelectMany(x => x.YY).Max(); } var min_x_erase = Input.Range.MaximumX > max_x ? min_x : max_x - Input.Range.MaximumX; OnEffectiveRangeXChanged(min_x_erase, max_x); OnEffectiveRangeYChanged(min_y, max_y); if (max_x - min_x > Input.Range.MaximumX) { for (int i = 0; i < new_items; i++) { int value_index = toRender.XX.Count - new_items + i; toRender.YY[replace_index++] = toRender.YY[value_index]; toRender.XX.RemoveAt(value_index); toRender.YY.RemoveAt(value_index); if (replace_index >= toRender.XX.Count) { replace_index = 0; if (series == _series_replace_index_dictionary.Last().Key) { foreach (var s in _series_replace_index_dictionary.Keys.ToList()) { _series_replace_index_dictionary[s] = replace_index; } } } } } min_x = toRender.XX.Min(); max_x = toRender.XX.Max(); var dxList = toRender.XX.Select(x => x.ComputeRelativePosition(min_x, max_x)).ToList(); var dyList = toRender.YY.Select(x => x.ComputeRelativePosition(min_y, max_y)).ToList(); List points = new List(); for (int i = 0; i < dxList.Count; i++) { float image_x = ConvertXValueToRendererValue(dxList[i]); float image_y = ConvertYValueToRendererValue(dyList[i]); GraphPoint point = new GraphPoint(image_x, image_y); points.Add(point); } CurrentXPosition = points[replace_index].X; _series_replace_index_dictionary[series] = replace_index; return points; } } }