diff --git a/maui/src/Charts/Area/Partial/CartesianChartArea.cs b/maui/src/Charts/Area/Partial/CartesianChartArea.cs index 5bb4cab4..fc9e7df3 100644 --- a/maui/src/Charts/Area/Partial/CartesianChartArea.cs +++ b/maui/src/Charts/Area/Partial/CartesianChartArea.cs @@ -1,4 +1,4 @@ -using System.Collections.ObjectModel; +using System.Collections.ObjectModel; namespace Syncfusion.Maui.Toolkit.Charts { @@ -103,8 +103,23 @@ internal void CalculateSbsPosition() { if (!stackingSeries.IsSbsValueCalculated && _seriesGroup != null) { - var stackingSeriesType = stackingSeries.GetType(); - string groupID = _seriesGroup.FirstOrDefault(x => x.Value.Any(s => s.GroupingLabel == stackingSeries.GroupingLabel && s.GetType() == stackingSeriesType)).Key; + string? groupID = null; + foreach (var group in _seriesGroup) + { + foreach (var s in group.Value) + { + if (s.GroupingLabel == stackingSeries.GroupingLabel && s.GetType() == stackingSeries.GetType()) + { + groupID = group.Key; + break; + } + } + + if (groupID != null) + { + break; + } + } StackingSeriesBase stackingSeriesBase; int size = SideBySideSeriesPosition.Count > 0 && groupingKeys.Count > 0 && groupingKeys.TryGetValue(groupID, out var groupValue) ? SideBySideSeriesPosition[groupValue].Count : 0; @@ -354,15 +369,23 @@ internal void InvalidateMinWidth() internal void ResetSBSSegments() { - var sideBySideSeries = VisibleSeries?.Where(series => series.IsSideBySide).ToList(); - - if (sideBySideSeries != null && sideBySideSeries.Count > 0) + if (VisibleSeries == null) { - SideBySideSeriesPosition = null; + return; + } - foreach (var chartSeries in sideBySideSeries) + bool hasSbsSeries = false; + foreach (var series in VisibleSeries) + { + if (series.IsSideBySide) { - chartSeries.SegmentsCreated = false; + if (!hasSbsSeries) + { + SideBySideSeriesPosition = null; + hasSbsSeries = true; + } + + series.SegmentsCreated = false; } } } @@ -407,7 +430,22 @@ static double GetSBSMaxWidth(List seriesGroup) internal void UpdateStackingSeries() { //if visible series count is 0 or not contain any stacking series then return. - if (VisibleSeries == null || VisibleSeries.Count == 0 || !VisibleSeries.Any(series => series is StackingSeriesBase && !series.SegmentsCreated)) + if (VisibleSeries == null || VisibleSeries.Count == 0) + { + return; + } + + bool hasStackingToCreate = false; + foreach (var series in VisibleSeries) + { + if (series is StackingSeriesBase && !series.SegmentsCreated) + { + hasStackingToCreate = true; + break; + } + } + + if (!hasStackingToCreate) { return; } diff --git a/maui/src/Charts/Layouts/ChartZoomPanView.cs b/maui/src/Charts/Layouts/ChartZoomPanView.cs index fa5a08d5..47b3a5a7 100644 --- a/maui/src/Charts/Layouts/ChartZoomPanView.cs +++ b/maui/src/Charts/Layouts/ChartZoomPanView.cs @@ -115,14 +115,16 @@ void GenerateSelectionElements(ICanvas canvas, ObservableCollection a { if (axis.IsVertical) { - startPoint = new Point(isOpposed ? actualArrangeRect.X : actualArrangeRect.X + actualArrangeRect.Width, selectedRect.Top); - endPoint = new Point(isOpposed ? actualArrangeRect.X : actualArrangeRect.X + actualArrangeRect.Width, selectedRect.Bottom); + double xCoord = isOpposed ? actualArrangeRect.X : actualArrangeRect.X + actualArrangeRect.Width; + startPoint = new Point(xCoord, selectedRect.Top); + endPoint = new Point(xCoord, selectedRect.Bottom); tooltipPosition = isOpposed ? TooltipPosition.Right : TooltipPosition.Left; } else { - startPoint = new Point(selectedRect.Left, isOpposed ? actualArrangeRect.Y + actualArrangeRect.Height : actualArrangeRect.Y); - endPoint = new Point(selectedRect.Right, isOpposed ? actualArrangeRect.Y + actualArrangeRect.Height : actualArrangeRect.Y); + double yCoord = isOpposed ? actualArrangeRect.Y + actualArrangeRect.Height : actualArrangeRect.Y; + startPoint = new Point(selectedRect.Left, yCoord); + endPoint = new Point(selectedRect.Right, yCoord); tooltipPosition = isOpposed ? TooltipPosition.Top : TooltipPosition.Bottom; } @@ -177,7 +179,7 @@ void GenerateAxisTrackballInfos(PointF startPoint, PointF endPoint, TooltipPosit ChartZoomPanView.MapChartLabelStyle(chart, axisPointInfo2.Helper, axis.TrackballLabelStyle); } - Rect actualArrangeRect = new Rect(axis.ArrangeRect.X, axis.ArrangeRect.Y, axis.ArrangeRect.X + axis.ArrangeRect.Width, axis.ArrangeRect.Y + axis.ArrangeRect.Height); + Rect actualArrangeRect = new Rect(axisRect.X, axisRect.Y, axisRect.X + axisRect.Width, axisRect.Y + axisRect.Height); axisPointInfo1.Helper.Show(actualArrangeRect, new Rect(startPoint.X - 1, startPoint.Y - 1, _dimension, _dimension), false); axisPointInfo2.Helper.Show(actualArrangeRect, new Rect(endPoint.X - 1, endPoint.Y - 1, _dimension, _dimension), false); diff --git a/maui/src/Charts/Series/CartesianSeries.cs b/maui/src/Charts/Series/CartesianSeries.cs index 5e1e23dc..0bf81606 100644 --- a/maui/src/Charts/Series/CartesianSeries.cs +++ b/maui/src/Charts/Series/CartesianSeries.cs @@ -15,6 +15,7 @@ public abstract class CartesianSeries : ChartSeries double _xAxisMax = double.MinValue; double _yAxisMin = double.MaxValue; double _yAxisMax = double.MinValue; + List? _cachedIndexedXValues; #endregion @@ -1027,26 +1028,44 @@ internal override void UpdateRange() return null; } - double xIndexValues = 0d; var xValues = ActualXValues as List; if (IsIndexed || xValues == null) { if (ActualXAxis is CategoryAxis categoryAxis && !categoryAxis.ArrangeByIndex || ActualXAxis == null) { - xValues = GroupedXValuesIndexes.Count > 0 ? GroupedXValuesIndexes : (from val in (ActualXValues as List) select (xIndexValues++)).ToList(); + xValues = GroupedXValuesIndexes.Count > 0 ? GroupedXValuesIndexes : GetOrCreateIndexedXValues(); } else { - xValues = xValues != null ? (from val in xValues select (xIndexValues++)).ToList() : (from val in (ActualXValues as List) select (xIndexValues++)).ToList(); + xValues = GetOrCreateIndexedXValues(); } } return xValues; } + List GetOrCreateIndexedXValues() + { + int count = ActualXValues is List dList ? dList.Count : (ActualXValues as List)?.Count ?? 0; + if (_cachedIndexedXValues != null && _cachedIndexedXValues.Count == count) + { + return _cachedIndexedXValues; + } + + var indexedValues = new List(count); + for (int i = 0; i < count; i++) + { + indexedValues.Add(i); + } + + _cachedIndexedXValues = indexedValues; + return _cachedIndexedXValues; + } + internal override void OnDataSourceChanged(object oldValue, object newValue) { + _cachedIndexedXValues = null; ResetAutoScroll(); InvalidateSideBySideSeries(); foreach (var item in EmptyPointIndexes) @@ -1059,6 +1078,7 @@ internal override void OnDataSourceChanged(object oldValue, object newValue) internal override void OnDataSource_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { + _cachedIndexedXValues = null; ResetAutoScroll(); base.OnDataSource_CollectionChanged(sender, e); } diff --git a/maui/src/Charts/Series/ChartSeriesPartial.cs b/maui/src/Charts/Series/ChartSeriesPartial.cs index 9bf224cd..f168e17d 100644 --- a/maui/src/Charts/Series/ChartSeriesPartial.cs +++ b/maui/src/Charts/Series/ChartSeriesPartial.cs @@ -1411,16 +1411,19 @@ void ResetDataPoint() if (ItemsSource != null) { - var items = ItemsSource is IList ? ItemsSource as IList : null; - if (items == null) + bool hasData = false; + if (ItemsSource is IList list) { - if (ItemsSource is IEnumerable source) - { - items = source.Cast().ToList(); - } + hasData = list.Count > 0; + } + else if (ItemsSource is IEnumerable source) + { + var enumerator = source.GetEnumerator(); + hasData = enumerator.MoveNext(); + (enumerator as IDisposable)?.Dispose(); } - if (items != null && items.Count > 0) + if (hasData) { GenerateDataPoints(); } diff --git a/maui/src/Charts/Series/StackingSeriesBase.cs b/maui/src/Charts/Series/StackingSeriesBase.cs index 5d6cd0d4..09c5bfcc 100644 --- a/maui/src/Charts/Series/StackingSeriesBase.cs +++ b/maui/src/Charts/Series/StackingSeriesBase.cs @@ -330,17 +330,14 @@ void RefreshSeries() void ResetVisibleSeries() { - if (ChartArea != null) + if (ChartArea?.VisibleSeries == null) { - var visibleSeries = ChartArea.VisibleSeries; - var stackingSeries = visibleSeries?.Where(series => series.IsStacking).ToList(); - - if (stackingSeries == null) - { - return; - } + return; + } - foreach (var chartSeries in stackingSeries) + foreach (var chartSeries in ChartArea.VisibleSeries) + { + if (chartSeries.IsStacking) { chartSeries.SegmentsCreated = false; }