using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Media; using System.Windows.Shapes; namespace RealTimeGraphEx.ReachGraphs { public class RealTimeGraphExReachMultiLineErase : RealTimeGraphExReachMultiLineScroll { #region Cross Thread Fields protected Brush _markerColor; protected bool _showMarker; protected bool _endReached; protected int _currentReplaceIndex; protected Rectangle marker; #endregion #region Constructors public RealTimeGraphExReachMultiLineErase() : base() { } #endregion #region Properties /// /// Gets or sets the graph marker color. /// public Brush MarkerColor { get { return (Brush)GetValue(MarkerColorProperty); } set { SetValue(MarkerColorProperty, value); } } public static readonly DependencyProperty MarkerColorProperty = DependencyProperty.Register("MarkerBrush", typeof(Brush), typeof(RealTimeGraphExReachMultiLineErase), new PropertyMetadata(Brushes.Red, new PropertyChangedCallback(CrossModelChanged))); /// /// Gets or sets whether to display the marker on the graph. /// public bool ShowMarker { get { return (bool)GetValue(ShowMarkerProperty); } set { SetValue(ShowMarkerProperty, value); } } public static readonly DependencyProperty ShowMarkerProperty = DependencyProperty.Register("ShowMarker", typeof(bool), typeof(RealTimeGraphExReachMultiLineErase), new PropertyMetadata(true, new PropertyChangedCallback(CrossModelChanged))); #endregion #region Override Methods protected override void Initialize() { base.Initialize(); marker = new Rectangle() { VerticalAlignment = System.Windows.VerticalAlignment.Stretch, Width = 1, Fill = MarkerColor, HorizontalAlignment = System.Windows.HorizontalAlignment.Left, Margin = new Thickness(-2, 0, 0, 0) }; if (!gridLinesAndImageWrapperGrid.Children.Contains(marker)) { gridLinesAndImageWrapperGrid.Children.Add(marker); } } protected override void OnSetCrossThreadFields() { base.OnSetCrossThreadFields(); this.Dispatcher.Invoke(() => { _markerColor = MarkerColor; _showMarker = ShowMarker; }, System.Windows.Threading.DispatcherPriority.Send); } protected override void OnClearGraph() { base.OnClearGraph(); _currentReplaceIndex = 0; _endReached = false; this.Dispatcher.Invoke(() => { marker.RenderTransform = new TranslateTransform(0, 0); }); } protected internal override void OnRenderGraph() { if (_graphController != null && _graphController.dataSeriesCollection.Count > 0 && _graphController.TotalPoints > 0 && _width > 1 && _height > 1) { for (int i = 0; i < _graphController.dataSeriesCollection[0].Points.Count; i++) //Match { if (xValueCounter <= _width) { if (!_endReached) { for (int j = 0; j < _graphController.dataSeriesCollection.Count; j++) { double value = _graphController.dataSeriesCollection[j].Points[i]; double valuePrecentage = value; _graphPolygons[j].Add(xValueCounter, valuePrecentage, value); } xValueCounter += _scaleFactor; } else { for (int j = 0; j < _graphController.dataSeriesCollection.Count; j++) { double value = _graphController.dataSeriesCollection[j].Points[i]; double valuePrecentage = value; _graphPolygons[j].Replace(xValueCounter, valuePrecentage, value, _currentReplaceIndex); if (j == _graphController.dataSeriesCollection.Count - 1) { _currentReplaceIndex++; } } xValueCounter += _scaleFactor; if (_currentReplaceIndex > _graphPolygons[0].TotalPoints - 1) { xValueCounter = 0; _currentReplaceIndex = 0; } } } else { _endReached = true; xValueCounter = 0; for (int j = 0; j < _graphController.dataSeriesCollection.Count; j++) { double value = _graphController.dataSeriesCollection[j].Points[i]; double valuePrecentage = value; _graphPolygons[j].Replace(xValueCounter, valuePrecentage, value, _currentReplaceIndex); if (j == _graphController.dataSeriesCollection.Count - 1) { _currentReplaceIndex++; } } xValueCounter += _scaleFactor; } } updateCounter++; if (updateCounter >= 1 && !_isPaused) { OnDrawVisuals(); } } } protected override void OnDrawVisuals() { base.OnDrawVisuals(); if (_graphPolygons.Count > 0) { double scale = _width / (_graphPolygons[0].TotalPoints - 1); this.Dispatcher.Invoke(() => { marker.RenderTransform = new TranslateTransform((_currentReplaceIndex * scale) - 2, 0); }); } } #endregion } }