Example #1
0
        /// <inheritdoc cref="ChartElement{TDrawingContext}.Measure(Chart{TDrawingContext})"/>
        public override void Measure(Chart <TDrawingContext> chart)
        {
            var cartesianChart = (CartesianChart <TDrawingContext>)chart;
            var primaryAxis    = cartesianChart.YAxes[ScalesYAt];
            var secondaryAxis  = cartesianChart.XAxes[ScalesXAt];

            var drawLocation           = cartesianChart.DrawMarginLocation;
            var drawMarginSize         = cartesianChart.DrawMarginSize;
            var secondaryScale         = new Scaler(drawLocation, drawMarginSize, primaryAxis);
            var previousSecondaryScale =
                primaryAxis.PreviousDataBounds is null ? null : new Scaler(drawLocation, drawMarginSize, primaryAxis);
            var primaryScale = new Scaler(drawLocation, drawMarginSize, secondaryAxis);

            var uw  = secondaryScale.MeasureInPixels(secondaryAxis.UnitWidth); //secondaryScale.ToPixels(1f) - secondaryScale.ToPixels(0f);
            var uwm = 0.5f * uw;
            var sw  = Stroke?.StrokeThickness ?? 0;
            var p   = primaryScale.ToPixels(pivot);

            var pos   = cartesianChart.SeriesContext.GetStackedColumnPostion(this);
            var count = cartesianChart.SeriesContext.GetStackedColumnSeriesCount();
            var cp    = 0f;

            if (count > 1)
            {
                uw /= count;
                uwm = 0.5f * uw;
                cp  = (pos - count / 2f) * uw + uwm;
            }

            if (uw > MaxBarWidth)
            {
                uw  = (float)MaxBarWidth;
                uwm = uw / 2f;
            }

            var actualZIndex = ZIndex == 0 ? ((ISeries)this).SeriesId : ZIndex;

            if (Fill is not null)
            {
                Fill.ZIndex = actualZIndex + 0.1;
                Fill.SetClipRectangle(cartesianChart.Canvas, new LvcRectangle(drawLocation, drawMarginSize));
                cartesianChart.Canvas.AddDrawableTask(Fill);
            }
            if (Stroke is not null)
            {
                Stroke.ZIndex = actualZIndex + 0.2;
                Stroke.SetClipRectangle(cartesianChart.Canvas, new LvcRectangle(drawLocation, drawMarginSize));
                cartesianChart.Canvas.AddDrawableTask(Stroke);
            }
            if (DataLabelsPaint is not null)
            {
                DataLabelsPaint.ZIndex = actualZIndex + 0.3;
                //DataLabelsPaint.SetClipRectangle(cartesianChart.Canvas, new LvcRectangle(drawLocation, drawMarginSize));
                cartesianChart.Canvas.AddDrawableTask(DataLabelsPaint);
            }
            var dls            = (float)DataLabelsSize;
            var toDeletePoints = new HashSet <ChartPoint>(everFetched);

            var stacker = cartesianChart.SeriesContext.GetStackPosition(this, GetStackGroup());

            if (stacker is null)
            {
                throw new NullReferenceException("Unexpected null stacker");
            }

            var rx = (float)Rx;
            var ry = (float)Ry;

            foreach (var point in Fetch(cartesianChart))
            {
                var visual    = point.Context.Visual as TVisual;
                var secondary = secondaryScale.ToPixels(point.SecondaryValue);

                if (point.IsNull)
                {
                    if (visual is not null)
                    {
                        visual.X                 = p;
                        visual.Y                 = secondary - uwm + cp;
                        visual.Width             = 0;
                        visual.Height            = uw;
                        visual.RemoveOnCompleted = true;
                        point.Context.Visual     = null;
                    }
                    continue;
                }

                if (visual is null)
                {
                    var yi = secondary - uwm + cp;
                    if (previousSecondaryScale is not null)
                    {
                        yi = previousSecondaryScale.ToPixels(point.SecondaryValue) - uwm + cp;
                    }

                    var r = new TVisual
                    {
                        X      = p,
                        Y      = yi,
                        Width  = 0,
                        Height = uw,
                        Rx     = rx,
                        Ry     = ry
                    };

                    visual = r;
                    point.Context.Visual = visual;
                    OnPointCreated(point);

                    _ = everFetched.Add(point);
                }

                if (Fill is not null)
                {
                    Fill.AddGeometryToPaintTask(cartesianChart.Canvas, visual);
                }
                if (Stroke is not null)
                {
                    Stroke.AddGeometryToPaintTask(cartesianChart.Canvas, visual);
                }

                var sizedGeometry = visual;

                var sy       = stacker.GetStack(point);
                var primaryI = primaryScale.ToPixels(sy.Start);
                var primaryJ = primaryScale.ToPixels(sy.End);
                var y        = secondary - uwm + cp;

                sizedGeometry.X                 = primaryJ;
                sizedGeometry.Y                 = y;
                sizedGeometry.Width             = primaryI - primaryJ;
                sizedGeometry.Height            = uw;
                sizedGeometry.Rx                = rx;
                sizedGeometry.Ry                = ry;
                sizedGeometry.RemoveOnCompleted = false;

                point.Context.HoverArea = new RectangleHoverArea().SetDimensions(secondary - uwm + cp, primaryJ, uw, primaryI - primaryJ);

                _ = toDeletePoints.Remove(point);

                if (DataLabelsPaint is not null)
                {
                    var label = (TLabel?)point.Context.Label;

                    if (label is null)
                    {
                        var l = new TLabel {
                            X = secondary - uwm + cp, Y = p, RotateTransform = (float)DataLabelsRotation
                        };

                        _ = l.TransitionateProperties(nameof(l.X), nameof(l.Y))
                            .WithAnimation(animation =>
                                           animation
                                           .WithDuration(AnimationsSpeed ?? cartesianChart.AnimationsSpeed)
                                           .WithEasingFunction(EasingFunction ?? cartesianChart.EasingFunction));

                        l.CompleteAllTransitions();
                        label = l;
                        point.Context.Label = label;
                    }

                    DataLabelsPaint.AddGeometryToPaintTask(cartesianChart.Canvas, label);
                    label.Text     = DataLabelsFormatter(new TypedChartPoint <TModel, TVisual, TLabel, TDrawingContext>(point));
                    label.TextSize = dls;
                    label.Padding  = DataLabelsPadding;
                    var labelPosition = GetLabelPosition(
                        primaryJ, y, primaryI - primaryJ, uw, label.Measure(DataLabelsPaint), DataLabelsPosition,
                        SeriesProperties, point.PrimaryValue > Pivot, drawLocation, drawMarginSize);
                    label.X = labelPosition.X;
                    label.Y = labelPosition.Y;
                }

                OnPointMeasured(point);
            }

            foreach (var point in toDeletePoints)
            {
                if (point.Context.Chart != cartesianChart.View)
                {
                    continue;
                }
                SoftDeleteOrDisposePoint(point, primaryScale, secondaryScale);
                _ = everFetched.Remove(point);
            }
        }
Example #2
0
        /// <inheritdoc cref="ChartElement{TDrawingContext}.Measure(Chart{TDrawingContext})"/>
        public override void Measure(Chart <TDrawingContext> chart)
        {
            var cartesianChart = (CartesianChart <TDrawingContext>)chart;
            var primaryAxis    = cartesianChart.YAxes[ScalesYAt];
            var secondaryAxis  = cartesianChart.XAxes[ScalesXAt];

            var drawLocation         = cartesianChart.DrawMarginLocation;
            var drawMarginSize       = cartesianChart.DrawMarginSize;
            var secondaryScale       = new Scaler(drawLocation, drawMarginSize, secondaryAxis);
            var primaryScale         = new Scaler(drawLocation, drawMarginSize, primaryAxis);
            var previousPrimaryScale =
                primaryAxis.PreviousDataBounds == null ? null : new Scaler(drawLocation, drawMarginSize, primaryAxis, true);
            var previousSecondaryScale =
                secondaryAxis.PreviousDataBounds == null ? null : new Scaler(drawLocation, drawMarginSize, secondaryAxis, true);

            var uw  = secondaryScale.ToPixels((float)secondaryAxis.UnitWidth) - secondaryScale.ToPixels(0f);
            var puw = previousSecondaryScale == null ? 0 : previousSecondaryScale.ToPixels((float)secondaryAxis.UnitWidth) - previousSecondaryScale.ToPixels(0f);

            uw  -= (float)GroupPadding;
            puw -= (float)GroupPadding;

            var uwm = 0.5f * uw;

            var pos   = cartesianChart.SeriesContext.GetColumnPostion(this);
            var count = cartesianChart.SeriesContext.GetColumnSeriesCount();
            var cp    = 0f;

            if (!IgnoresBarPosition && count > 1)
            {
                uw  /= count;
                puw /= count;
                uwm  = 0.5f * uw;
                cp   = (pos - count / 2f) * uw + uwm;
            }

            if (uw > MaxBarWidth)
            {
                uw  = (float)MaxBarWidth;
                uwm = uw * 0.5f;
                puw = uw;
            }

            var p = primaryScale.ToPixels(pivot);

            var actualZIndex = ZIndex == 0 ? ((ISeries)this).SeriesId : ZIndex;

            if (Fill != null)
            {
                Fill.ZIndex = actualZIndex + 0.1;
                Fill.SetClipRectangle(cartesianChart.Canvas, new RectangleF(drawLocation, drawMarginSize));
                cartesianChart.Canvas.AddDrawableTask(Fill);
            }
            if (Stroke != null)
            {
                Stroke.ZIndex = actualZIndex + 0.2;
                Stroke.SetClipRectangle(cartesianChart.Canvas, new RectangleF(drawLocation, drawMarginSize));
                cartesianChart.Canvas.AddDrawableTask(Stroke);
            }
            if (DataLabelsPaint != null)
            {
                DataLabelsPaint.ZIndex = actualZIndex + 0.3;
                DataLabelsPaint.SetClipRectangle(cartesianChart.Canvas, new RectangleF(drawLocation, drawMarginSize));
                cartesianChart.Canvas.AddDrawableTask(DataLabelsPaint);
            }

            var dls            = (float)DataLabelsSize;
            var toDeletePoints = new HashSet <ChartPoint>(everFetched);

            var rx = (float)Rx;
            var ry = (float)Ry;

            foreach (var point in Fetch(cartesianChart))
            {
                var visual    = point.Context.Visual as TVisual;
                var primary   = primaryScale.ToPixels(point.PrimaryValue);
                var secondary = secondaryScale.ToPixels(point.SecondaryValue);
                var b         = Math.Abs(primary - p);

                if (point.IsNull)
                {
                    if (visual != null)
                    {
                        visual.X                 = secondary - uwm + cp;
                        visual.Y                 = p;
                        visual.Width             = uw;
                        visual.Height            = 0;
                        visual.RemoveOnCompleted = true;
                        point.Context.Visual     = null;
                    }
                    continue;
                }

                if (visual == null)
                {
                    var xi  = secondary - uwm + cp;
                    var pi  = p;
                    var uwi = uw;
                    var hi  = 0f;

                    if (previousSecondaryScale != null && previousPrimaryScale != null)
                    {
                        var previousP       = previousPrimaryScale.ToPixels(pivot);
                        var previousPrimary = previousPrimaryScale.ToPixels(point.PrimaryValue);
                        var bp  = Math.Abs(previousPrimary - previousP);
                        var cyp = point.PrimaryValue > pivot ? previousPrimary : previousPrimary - bp;

                        xi  = previousSecondaryScale.ToPixels(point.SecondaryValue) - uwm + cp;
                        pi  = cartesianChart.IsZoomingOrPanning ? cyp : previousP;
                        uwi = puw;
                        hi  = cartesianChart.IsZoomingOrPanning ? bp : 0;
                    }

                    var r = new TVisual
                    {
                        X      = xi,
                        Y      = pi,
                        Width  = uwi,
                        Height = 0
                    };

                    if (_isRounded)
                    {
                        var rounded = (IRoundedRectangleChartPoint <TDrawingContext>)r;
                        rounded.Rx = rx;
                        rounded.Ry = ry;
                    }

                    visual = r;
                    point.Context.Visual = visual;
                    OnPointCreated(point);
                    r.CompleteAllTransitions();

                    _ = everFetched.Add(point);
                }

                if (Fill != null)
                {
                    Fill.AddGeometryToPaintTask(cartesianChart.Canvas, visual);
                }
                if (Stroke != null)
                {
                    Stroke.AddGeometryToPaintTask(cartesianChart.Canvas, visual);
                }

                var cy = point.PrimaryValue > pivot ? primary : primary - b;
                var x  = secondary - uwm + cp;

                visual.X      = x;
                visual.Y      = cy;
                visual.Width  = uw;
                visual.Height = b;
                if (_isRounded)
                {
                    var rounded = (IRoundedRectangleChartPoint <TDrawingContext>)visual;
                    rounded.Rx = rx;
                    rounded.Ry = ry;
                }
                visual.RemoveOnCompleted = false;

                var ha = new RectangleHoverArea().SetDimensions(secondary - uwm + cp, cy, uw, b);
                point.Context.HoverArea = ha;

                OnPointMeasured(point);
                _ = toDeletePoints.Remove(point);

                if (DataLabelsPaint != null)
                {
                    var label = (TLabel?)point.Context.Label;

                    if (label == null)
                    {
                        var l = new TLabel {
                            X = secondary - uwm + cp, Y = p
                        };

                        _ = l.TransitionateProperties(nameof(l.X), nameof(l.Y))
                            .WithAnimation(animation =>
                                           animation
                                           .WithDuration(AnimationsSpeed ?? cartesianChart.AnimationsSpeed)
                                           .WithEasingFunction(EasingFunction ?? cartesianChart.EasingFunction));

                        l.CompleteAllTransitions();
                        label = l;
                        point.Context.Label = l;
                    }

                    DataLabelsPaint.AddGeometryToPaintTask(cartesianChart.Canvas, label);

                    label.Text     = DataLabelsFormatter(new TypedChartPoint <TModel, TVisual, TLabel, TDrawingContext>(point));
                    label.TextSize = dls;
                    label.Padding  = DataLabelsPadding;
                    var labelPosition = GetLabelPosition(
                        x, cy, uw, b, label.Measure(DataLabelsPaint), DataLabelsPosition, SeriesProperties, point.PrimaryValue > Pivot);
                    label.X = labelPosition.X;
                    label.Y = labelPosition.Y;
                }
            }

            foreach (var point in toDeletePoints)
            {
                if (point.Context.Chart != cartesianChart.View)
                {
                    continue;
                }
                SoftDeletePoint(point, primaryScale, secondaryScale);
                _ = everFetched.Remove(point);
            }
        }
Example #3
0
        /// <inheritdoc cref="ChartElement{TDrawingContext}.Measure(Chart{TDrawingContext})"/>
        public override void Measure(Chart <TDrawingContext> chart)
        {
            var cartesianChart = (CartesianChart <TDrawingContext>)chart;
            var primaryAxis    = cartesianChart.YAxes[ScalesYAt];
            var secondaryAxis  = cartesianChart.XAxes[ScalesXAt];

            var drawLocation         = cartesianChart.DrawMarginLocation;
            var drawMarginSize       = cartesianChart.DrawMarginSize;
            var secondaryScale       = new Scaler(drawLocation, drawMarginSize, secondaryAxis);
            var primaryScale         = new Scaler(drawLocation, drawMarginSize, primaryAxis);
            var previousPrimaryScale = primaryAxis.PreviousDataBounds is null
                ? null
                : new Scaler(drawLocation, drawMarginSize, primaryAxis, true);
            var previousSecondaryScale = secondaryAxis.PreviousDataBounds is null
                ? null
                : new Scaler(drawLocation, drawMarginSize, secondaryAxis, true);

            var helper  = new MeasureHelper(secondaryScale, cartesianChart, this, secondaryAxis, primaryScale.ToPixels(pivot));
            var pHelper = previousSecondaryScale == null || previousPrimaryScale == null
                ? null
                : new MeasureHelper(
                previousSecondaryScale, cartesianChart, this, secondaryAxis, previousPrimaryScale.ToPixels(pivot));

            var actualZIndex = ZIndex == 0 ? ((ISeries)this).SeriesId : ZIndex;

            if (Fill is not null)
            {
                Fill.ZIndex = actualZIndex + 0.1;
                Fill.SetClipRectangle(cartesianChart.Canvas, new LvcRectangle(drawLocation, drawMarginSize));
                cartesianChart.Canvas.AddDrawableTask(Fill);
            }
            if (Stroke is not null)
            {
                Stroke.ZIndex = actualZIndex + 0.2;
                Stroke.SetClipRectangle(cartesianChart.Canvas, new LvcRectangle(drawLocation, drawMarginSize));
                cartesianChart.Canvas.AddDrawableTask(Stroke);
            }
            if (DataLabelsPaint is not null)
            {
                DataLabelsPaint.ZIndex = actualZIndex + 0.3;
                //DataLabelsPaint.SetClipRectangle(cartesianChart.Canvas, new LvcRectangle(drawLocation, drawMarginSize));
                cartesianChart.Canvas.AddDrawableTask(DataLabelsPaint);
            }

            var dls            = (float)DataLabelsSize;
            var toDeletePoints = new HashSet <ChartPoint>(everFetched);

            var rx = (float)Rx;
            var ry = (float)Ry;

            foreach (var point in Fetch(cartesianChart))
            {
                var visual    = point.Context.Visual as TVisual;
                var primary   = primaryScale.ToPixels(point.PrimaryValue);
                var secondary = secondaryScale.ToPixels(point.SecondaryValue);
                var b         = Math.Abs(primary - helper.p);

                if (point.IsNull)
                {
                    if (visual is not null)
                    {
                        visual.X                 = secondary - helper.uwm + helper.cp;
                        visual.Y                 = helper.p;
                        visual.Width             = helper.uw;
                        visual.Height            = 0;
                        visual.RemoveOnCompleted = true;
                        point.Context.Visual     = null;
                    }
                    continue;
                }

                if (visual is null)
                {
                    var xi  = secondary - helper.uwm + helper.cp;
                    var pi  = helper.p;
                    var uwi = helper.uw;
                    var hi  = 0f;

                    if (previousSecondaryScale is not null && previousPrimaryScale is not null && pHelper is not null)
                    {
                        var previousPrimary = previousPrimaryScale.ToPixels(point.PrimaryValue);
                        var bp  = Math.Abs(previousPrimary - pHelper.p);
                        var cyp = point.PrimaryValue > pivot ? previousPrimary : previousPrimary - bp;

                        xi  = previousSecondaryScale.ToPixels(point.SecondaryValue) - pHelper.uwm + pHelper.cp;
                        pi  = cartesianChart.IsZoomingOrPanning ? cyp : pHelper.p;
                        uwi = pHelper.uw;
                        hi  = cartesianChart.IsZoomingOrPanning ? bp : 0;
                    }

                    var r = new TVisual
                    {
                        X      = xi,
                        Y      = pi,
                        Width  = uwi,
                        Height = hi
                    };

                    if (_isRounded)
                    {
                        var rounded = (IRoundedRectangleChartPoint <TDrawingContext>)r;
                        rounded.Rx = rx;
                        rounded.Ry = ry;
                    }

                    visual = r;
                    point.Context.Visual = visual;
                    OnPointCreated(point);

                    _ = everFetched.Add(point);
                }

                if (Fill is not null)
                {
                    Fill.AddGeometryToPaintTask(cartesianChart.Canvas, visual);
                }
                if (Stroke is not null)
                {
                    Stroke.AddGeometryToPaintTask(cartesianChart.Canvas, visual);
                }

                var cy = point.PrimaryValue > pivot ? primary : primary - b;
                var x  = secondary - helper.uwm + helper.cp;

                visual.X      = x;
                visual.Y      = cy;
                visual.Width  = helper.uw;
                visual.Height = b;
                if (_isRounded)
                {
                    var rounded = (IRoundedRectangleChartPoint <TDrawingContext>)visual;
                    rounded.Rx = rx;
                    rounded.Ry = ry;
                }
                visual.RemoveOnCompleted = false;

                var ha = new RectangleHoverArea().SetDimensions(secondary - helper.uwm + helper.cp, cy, helper.uw, b);
                point.Context.HoverArea = ha;

                _ = toDeletePoints.Remove(point);

                if (DataLabelsPaint is not null)
                {
                    var label = (TLabel?)point.Context.Label;

                    if (label is null)
                    {
                        var l = new TLabel {
                            X = secondary - helper.uwm + helper.cp, Y = helper.p, RotateTransform = (float)DataLabelsRotation
                        };

                        _ = l.TransitionateProperties(nameof(l.X), nameof(l.Y))
                            .WithAnimation(animation =>
                                           animation
                                           .WithDuration(AnimationsSpeed ?? cartesianChart.AnimationsSpeed)
                                           .WithEasingFunction(EasingFunction ?? cartesianChart.EasingFunction));

                        l.CompleteAllTransitions();
                        label = l;
                        point.Context.Label = l;
                    }

                    DataLabelsPaint.AddGeometryToPaintTask(cartesianChart.Canvas, label);

                    label.Text     = DataLabelsFormatter(new TypedChartPoint <TModel, TVisual, TLabel, TDrawingContext>(point));
                    label.TextSize = dls;
                    label.Padding  = DataLabelsPadding;
                    var labelPosition = GetLabelPosition(
                        x, cy, helper.uw, b, label.Measure(DataLabelsPaint),
                        DataLabelsPosition, SeriesProperties, point.PrimaryValue > Pivot, drawLocation, drawMarginSize);
                    label.X = labelPosition.X;
                    label.Y = labelPosition.Y;
                }

                OnPointMeasured(point);
            }

            foreach (var point in toDeletePoints)
            {
                if (point.Context.Chart != cartesianChart.View)
                {
                    continue;
                }
                SoftDeleteOrDisposePoint(point, primaryScale, secondaryScale);
                _ = everFetched.Remove(point);
            }
        }
Example #4
0
    /// <inheritdoc cref="ChartElement{TDrawingContext}.Measure(Chart{TDrawingContext})"/>
    public override void Measure(Chart <TDrawingContext> chart)
    {
        if (GetCustomMeasureHandler() is not null)
        {
            GetCustomMeasureHandler() !(chart);
            return;
        }

        var cartesianChart = (CartesianChart <TDrawingContext>)chart;
        var primaryAxis    = cartesianChart.YAxes[ScalesYAt];
        var secondaryAxis  = cartesianChart.XAxes[ScalesXAt];

        var drawLocation           = cartesianChart.DrawMarginLocation;
        var drawMarginSize         = cartesianChart.DrawMarginSize;
        var secondaryScale         = new Scaler(drawLocation, drawMarginSize, primaryAxis);
        var previousSecondaryScale =
            primaryAxis.PreviousDataBounds is null ? null : new Scaler(drawLocation, drawMarginSize, primaryAxis);
        var primaryScale = new Scaler(drawLocation, drawMarginSize, secondaryAxis);

        var uw  = secondaryScale.MeasureInPixels(primaryAxis.UnitWidth); //secondaryScale.ToPixels(0f) - secondaryScale.ToPixels(primaryAxis.UnitWidth);
        var uwm = 0.5f * uw;

        var gp = (float)GroupPadding;

        if (uw - gp < 1)
        {
            gp -= uw - gp;
        }
        uw -= gp;
        //puw -= (float)GroupPadding;

        var sw = Stroke?.StrokeThickness ?? 0;
        var p  = primaryScale.ToPixels((float)Pivot);

        var pos   = cartesianChart.SeriesContext.GetColumnPostion(this);
        var count = cartesianChart.SeriesContext.GetColumnSeriesCount();
        var cp    = 0f;

        if (!IgnoresBarPosition && count > 1)
        {
            uw /= count;
            uwm = 0.5f * uw;
            cp  = (pos - count / 2f) * uw + uwm;
        }

        if (uw > MaxBarWidth)
        {
            uw  = (float)MaxBarWidth;
            uwm = uw / 2f;
        }

        var actualZIndex = ZIndex == 0 ? ((ISeries)this).SeriesId : ZIndex;

        if (Fill is not null)
        {
            Fill.ZIndex = actualZIndex + 0.1;
            Fill.SetClipRectangle(cartesianChart.Canvas, new LvcRectangle(drawLocation, drawMarginSize));
            cartesianChart.Canvas.AddDrawableTask(Fill);
        }
        if (Stroke is not null)
        {
            Stroke.ZIndex = actualZIndex + 0.1;
            Stroke.SetClipRectangle(cartesianChart.Canvas, new LvcRectangle(drawLocation, drawMarginSize));
            cartesianChart.Canvas.AddDrawableTask(Stroke);
        }
        if (DataLabelsPaint is not null)
        {
            DataLabelsPaint.ZIndex = actualZIndex + 0.1;
            //DataLabelsPaint.SetClipRectangle(cartesianChart.Canvas, new LvcRectangle(drawLocation, drawMarginSize));
            cartesianChart.Canvas.AddDrawableTask(DataLabelsPaint);
        }

        var dls            = (float)DataLabelsSize;
        var toDeletePoints = new HashSet <ChartPoint>(everFetched);

        var rx = (float)Rx;
        var ry = (float)Ry;

        foreach (var point in Fetch(cartesianChart))
        {
            var visual    = point.Context.Visual as TVisual;
            var primary   = primaryScale.ToPixels(point.PrimaryValue);
            var secondary = secondaryScale.ToPixels(point.SecondaryValue);
            var b         = Math.Abs(primary - p);

            if (point.IsNull)
            {
                if (visual is not null)
                {
                    visual.X                 = p;
                    visual.Y                 = secondary - uwm + cp;
                    visual.Width             = 0;
                    visual.Height            = uw;
                    visual.RemoveOnCompleted = true;
                    point.Context.Visual     = null;
                }
                continue;
            }

            if (visual is null)
            {
                var yi = secondary - uwm + cp;
                if (previousSecondaryScale is not null)
                {
                    yi = previousSecondaryScale.ToPixels(point.SecondaryValue) - uwm + cp;
                }

                var r = new TVisual
                {
                    X      = p,
                    Y      = yi,
                    Width  = 0,
                    Height = uw
                };

                if (_isRounded)
                {
                    var rounded = (IRoundedRectangleChartPoint <TDrawingContext>)r;
                    rounded.Rx = rx;
                    rounded.Ry = ry;
                }

                visual = r;
                point.Context.Visual = visual;
                OnPointCreated(point);

                _ = everFetched.Add(point);
            }

            if (Fill is not null)
            {
                Fill.AddGeometryToPaintTask(cartesianChart.Canvas, visual);
            }
            if (Stroke is not null)
            {
                Stroke.AddGeometryToPaintTask(cartesianChart.Canvas, visual);
            }

            var sizedGeometry = visual;

            var cx = point.PrimaryValue > Pivot ? primary - b : primary;
            var y  = secondary - uwm + cp;

            sizedGeometry.X      = cx;
            sizedGeometry.Y      = y;
            sizedGeometry.Width  = b;
            sizedGeometry.Height = uw;
            if (_isRounded)
            {
                var rounded = (IRoundedRectangleChartPoint <TDrawingContext>)visual;
                rounded.Rx = rx;
                rounded.Ry = ry;
            }
            sizedGeometry.RemoveOnCompleted = false;

            point.Context.HoverArea = new RectangleHoverArea().SetDimensions(cx, y, b, uw);

            _ = toDeletePoints.Remove(point);

            if (DataLabelsPaint is not null)
            {
                var label = (TLabel?)point.Context.Label;

                if (label is null)
                {
                    var l = new TLabel {
                        X = p, Y = secondary - uwm + cp, RotateTransform = (float)DataLabelsRotation
                    };

                    _ = l.TransitionateProperties(nameof(l.X), nameof(l.Y))
                        .WithAnimation(animation =>
                                       animation
                                       .WithDuration(AnimationsSpeed ?? cartesianChart.AnimationsSpeed)
                                       .WithEasingFunction(EasingFunction ?? cartesianChart.EasingFunction));

                    l.CompleteAllTransitions();
                    label = l;
                    point.Context.Label = l;
                }

                DataLabelsPaint.AddGeometryToPaintTask(cartesianChart.Canvas, label);
                label.Text     = DataLabelsFormatter(new ChartPoint <TModel, TVisual, TLabel>(point));
                label.TextSize = dls;
                label.Padding  = DataLabelsPadding;
                var labelPosition = GetLabelPosition(
                    cx, y, b, uw, label.Measure(DataLabelsPaint), DataLabelsPosition, SeriesProperties,
                    point.PrimaryValue > Pivot, drawLocation, drawMarginSize);
                label.X = labelPosition.X;
                label.Y = labelPosition.Y;
            }

            OnPointMeasured(point);
        }

        foreach (var point in toDeletePoints)
        {
            if (point.Context.Chart != cartesianChart.View)
            {
                continue;
            }
            SoftDeleteOrDisposePoint(point, primaryScale, secondaryScale);
            _ = everFetched.Remove(point);
        }
    }