aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/SideChains/RealTimeGraphEx/FastGraphs/RealTimeGraphExShapeErase.cs
blob: 0268b08c161f1ab2895a1ce0758b94a8ee229df1 (generated by cgit v1.3.1 (git 2.54.0) at 2026-07-31 17:46:18 +0000
45'>245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
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.Media.Imaging;
using RealTimeGraphEx.Models;
using RealTimeGraphEx.Enums;

namespace RealTimeGraphEx.FastGraphs
{
    public class RealTimeGraphExShapeErase : RealTimeGraphExShapeScroll
    {
        #region Cross Thread Fields

        protected Color _markerColor;
        protected bool _showMarker;
        protected bool _endReached;
        protected int _currentReplaceIndex;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the graph marker color.
        /// </summary>
        public Color MarkerColor
        {
            get { return (Color)GetValue(MarkerColorProperty); }
            set { SetValue(MarkerColorProperty, value); }
        }
        public static readonly DependencyProperty MarkerColorProperty =
            DependencyProperty.Register("MarkerBrush", typeof(Color), typeof(RealTimeGraphExShapeErase), new PropertyMetadata(Colors.Red, new PropertyChangedCallback(CrossModelChanged)));

        /// <summary>
        /// Gets or sets whether to display the marker on the graph.
        /// </summary>
        public bool ShowMarker
        {
            get { return (bool)GetValue(ShowMarkerProperty); }
            set { SetValue(ShowMarkerProperty, value); }
        }
        public static readonly DependencyProperty ShowMarkerProperty =
            DependencyProperty.Register("ShowMarker", typeof(bool), typeof(RealTimeGraphExShapeErase), new PropertyMetadata(true, new PropertyChangedCallback(CrossModelChanged)));

        #endregion

        #region Constructors

        public RealTimeGraphExShapeErase()
            : base()
        {
           
        }

        #endregion

        #region Override Method

        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;
        }

        protected internal override void OnRenderGraph()
        {
            if (_graphController != null && _graphController.dataSeries.Points != null && _graphController.dataSeries.Points.Count > 0  && _width > 1 && _height > 1)
            {
                for (int i = 0; i < _graphController.dataSeries.Points.Count; i++)
                {
                    double value = _graphController.dataSeries.Points[i];
                    NormalizeValue(ref value);
                    double valuePrecentage = ConvertYToImageYFliped(value);

                    if (xValueCounter <= _width)
                    {
                        if (!_endReached)
                        {
                            graphColumns.Add((int)xValueCounter, (int)valuePrecentage, (int)xValueCounter + _shapeWidth, (int)(_maximum - valuePrecentage), (int)value);
                            xValueCounter += (_shapeWidth + _shapeGap + 1);
                            currentColumnIndex = graphColumns.TotalColumns - 1;
                        }
                        else
                        {
                            currentColumnIndex = _currentReplaceIndex;
                            graphColumns.Replace((int)xValueCounter, (int)valuePrecentage, (int)xValueCounter + _shapeWidth, (int)(_maximum - valuePrecentage), (int)value, _currentReplaceIndex++);
                            xValueCounter += (_shapeWidth + _shapeGap + 1);

                            if (xValueCounter > _width)
                            {
                                xValueCounter = 0;
                                _currentReplaceIndex = 0;
                            }
                        }
                    }
                    else
                    {
                        _endReached = true;
                        xValueCounter = 0;
                        currentColumnIndex = 0;
                        currentColumnIndex = currentColumnIndex = graphColumns.TotalColumns - 1;
                        graphColumns.Replace((int)xValueCounter, (int)valuePrecentage, (int)xValueCounter + _shapeWidth, (int)(_maximum - valuePrecentage), (int)value, _currentReplaceIndex++);
                        xValueCounter += (_shapeWidth + _shapeGap + 1);
                    }
                }

                updateCounter++;

                if (updateCounter >= 1 && !_isPaused)
                {
                    updateCounter = 0;

                    if (!_disableRendering)
                    {
                        WriteableBitmap bmp = BitmapFactory.New((int)_width, (int)_height);
                        bmp.Clear(Colors.Transparent);

                        Color lineColor = _graphController.dataSeries.GetStrokeColor() != null ? _graphController.dataSeries.GetStrokeColor().Value : _stroke;
                        Color fillColor = _graphController.dataSeries.GetFillColor() != null ? _graphController.dataSeries.GetFillColor().Value : _fill;

                        int right = graphColumns.TotalColumns - currentColumnIndex;
                        double r_opacity = right > 0 ? 255 / right : 255;
                        double l_opacity = currentColumnIndex > 0 ? 255 / currentColumnIndex : 255;

                        for (int i = 0; i < graphColumns.TotalColumns; i++)
                        {
                            var rec = graphColumns.Columns[i];
                            Color processedLineColor = lineColor;
                            Color processedFillColor = fillColor;

                            switch (_shapeType)
                            {
                                case ShapeTypeEnum.Column:
                                    #region Column

                                    int calculatedOpacity = 255;
                                    if (_opacityAnimationType == OpacityTypeEnum.FadeOut)
                                    {
                                        byte opacity = (byte)((((rec.X) * 100 / _width) * 255) / 100);
                                        processedLineColor.A = opacity;
                                        processedFillColor.A = opacity;
                                    }
                                    else if (_opacityAnimationType == OpacityTypeEnum.CrossFade)
                                    {
                                        if (i < currentColumnIndex && currentColumnIndex > 0)
                                        {
                                            calculatedOpacity = (int)((i + 1) * l_opacity);
                                        }
                                        else
                                        {
                                            calculatedOpacity = (int)(((right) - Math.Abs(currentColumnIndex - (i))) * r_opacity);
                                        }

                                        byte opacity = (byte)(calculatedOpacity);

                                        processedLineColor.A = opacity;
                                        processedFillColor.A = opacity;
                                    }

                                    if (_fillGraph)
                                    {
                                        bmp.FillRectangle(rec.X, rec.Y, rec.Right, rec.Bottom, processedFillColor);
                                        bmp.DrawRectangle(rec.X, rec.Y, rec.Right, rec.Bottom, processedLineColor);
                                    }
                                    else
                                    {
                                        bmp.DrawRectangle(rec.X, rec.Y, rec.Right, rec.Bottom, processedLineColor);
                                    }
                                    #endregion
                                    break;
                                case ShapeTypeEnum.Circle:
                                    #region Circle
                                    calculatedOpacity = 255;

                                    if (_opacityAnimationType == OpacityTypeEnum.FadeOut)
                                    {
                                        byte opacity = (byte)((((rec.X) * 100 / _width) * 255) / 100);
                                        processedLineColor.A = opacity;
                                        processedFillColor.A = opacity;
                                    }
                                    else if (_opacityAnimationType == OpacityTypeEnum.CrossFade)
                                    {
                                        if (i < currentColumnIndex && currentColumnIndex > 0)
                                        {
                                            calculatedOpacity = (int)((i + 1) * l_opacity);
                                        }
                                        else
                                        {
                                            calculatedOpacity = (int)(((right) - Math.Abs(currentColumnIndex - (i))) * r_opacity);
                                        }

                                        byte opacity = (byte)(calculatedOpacity);

                                        processedLineColor.A = opacity;
                                        processedFillColor.A = opacity;
                                    }

                                    if (_fillGraph)
                                    {
                                        bmp.FillEllipseCentered(rec.X, rec.Y, _shapeWidth, _shapeWidth, processedFillColor);
                                        bmp.DrawEllipseCentered(rec.X, rec.Y, _shapeWidth, _shapeWidth, processedLineColor);
                                    }
                                    else
                                    {
                                        bmp.DrawEllipseCentered(rec.X, rec.Y, _shapeWidth, _shapeWidth, processedLineColor);
                                    }
                                    #endregion
                                    break;
                                case ShapeTypeEnum.Rectangle:
                                    #region Rectangle
                                    calculatedOpacity = 255;

                                    if (_opacityAnimationType == OpacityTypeEnum.FadeOut)
                                    {
                                        byte opacity = (byte)((((rec.X) * 100 / _width) * 255) / 100);
                                        processedLineColor.A = opacity;
                                        processedFillColor.A = opacity;
                                    }
                                    else if (_opacityAnimationType == OpacityTypeEnum.CrossFade)
                                    {
                                        if (i < currentColumnIndex && currentColumnIndex > 0)
                                        {
                                            calculatedOpacity = (int)((i + 1) * l_opacity);
                                        }
                                        else
                                        {
                                            calculatedOpacity = (int)(((right) - Math.Abs(currentColumnIndex - (i))) * r_opacity);
                                        }

                                        byte opacity = (byte)(calculatedOpacity);

                                        processedLineColor.A = opacity;
                                        processedFillColor.A = opacity;
                                    }

                                    if (_fillGraph)
                                    {
                                        bmp.FillRectangle(rec.X, rec.Y, rec.X + _shapeWidth, rec.Y + _shapeWidth, processedFillColor);
                                        bmp.DrawRectangle(rec.X, rec.Y, rec.X + _shapeWidth, rec.Y + _shapeWidth, processedLineColor);
                                    }
                                    else
                                    {
                                        bmp.DrawRectangle(rec.X, rec.Y, rec.X + _shapeWidth, rec.Y + _shapeWidth, processedLineColor);
                                    }
                                    #endregion
                                    break;
                            }

                        }

                        if (_showMarker)
                        {
                            bmp.DrawLine((int)(xValueCounter), 0, (int)(xValueCounter), (int)_height, _markerColor);
                        }

                        bmp.Freeze();

                        img.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            img.Source = bmp;
                        }), System.Windows.Threading.DispatcherPriority.Send);
                    }
                }
            }
        }

        #endregion
    }
}