Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions maui/src/Calendar/Views/CalendarView/MonthView/MonthView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,24 @@ internal void SetFocusOnViewChanged()

#region Private Methods

/// <summary>
/// Finds the special date icon details for a given date using a loop to avoid delegate allocation.
/// </summary>
/// <param name="dateTime">The date to look up.</param>
/// <returns>The matching CalendarIconDetails or null.</returns>
CalendarIconDetails? GetSpecialDateIcon(DateTime dateTime)
{
for (int i = 0; i < _specialDates.Count; i++)
{
if (CalendarViewHelper.IsSameDate(_calendarViewInfo.View, _specialDates[i].Date, dateTime, _calendarViewInfo.Identifier))
{
return _specialDates[i];
}
}

return null;
}

/// <summary>
/// Method to find the range is present in current view or not.
/// </summary>
Expand Down Expand Up @@ -1635,7 +1653,7 @@ void DrawMonthCells(ICanvas canvas, bool isRTL, float weekNumberWidth, float mon
// The current date is today date and not a range then need to considered the today text style.
bool isTodayDate = todayDate.Date.Equals(dateTime.Date);
//// Stores the special dates icon details for drawing.
CalendarIconDetails? calendarSpecialDayIconDetails = _specialDates.FirstOrDefault(details => CalendarViewHelper.IsSameDate(_calendarViewInfo.View, details.Date, dateTime, _calendarViewInfo.Identifier));
CalendarIconDetails? calendarSpecialDayIconDetails = GetSpecialDateIcon(dateTime);
CalendarTextStyle textStyle = GetMonthCellStyle(dateTime, isTodayDate, isLeadingAndTrailingDates, isBlackoutDate, isDisabledDate, _calendarViewInfo.ShowOutOfRangeDates, calendarSpecialDayIconDetails != null, ref fillColor, cellBackground, trailingLeadingDateBackground, weekendsBackground, todayBackground, disabledDatesBackground, specialDatesBackground, cultureCalendar);
//// If background color is not transparent then the background color for month cell is applied.
if (fillColor != Colors.Transparent)
Expand Down Expand Up @@ -3080,7 +3098,7 @@ private void OnDateSemanticsNodeClicked(SemanticsNode node)

string blackOutDate = CalendarViewHelper.IsDateInDateCollection(dateTime, _disabledDates) ? SfCalendarResources.GetLocalizedString("Blackout Date") : string.Empty;
string disabledDate = CalendarViewHelper.IsDisabledDate(dateTime, _calendarViewInfo.View, _calendarViewInfo.EnablePastDates, _calendarViewInfo.MinimumDate, _calendarViewInfo.MaximumDate, _calendarViewInfo.SelectionMode, _calendarViewInfo.RangeSelectionDirection, _selectedRange, _calendarViewInfo.AllowViewNavigation, _calendarViewInfo.Identifier) ? SfCalendarResources.GetLocalizedString("Disabled Date") : string.Empty;
CalendarIconDetails? calendarSpecialDayIconDetails = _specialDates.FirstOrDefault(details => CalendarViewHelper.IsSameDate(_calendarViewInfo.View, details.Date, dateTime, _calendarViewInfo.Identifier));
CalendarIconDetails? calendarSpecialDayIconDetails = GetSpecialDateIcon(dateTime);
string specialDate = calendarSpecialDayIconDetails == null ? string.Empty : SfCalendarResources.GetLocalizedString("Special Date");
string dateType = string.IsNullOrEmpty(specialDate) ? !string.IsNullOrEmpty(blackOutDate) ? blackOutDate : disabledDate : specialDate;
string dateText = isGregorianCalendar ? dateTime.ToString("dddd, dd/MMMM/yyyy") + dateType : dateTime.ToString("dddd, dd/MMMM/yyyy", cultureInfo) + dateType;
Expand Down
13 changes: 10 additions & 3 deletions maui/src/Charts/Axis/Layouts/CartesianAxisLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -499,10 +499,17 @@ void InternalCreateSegments(ChartSeries series)

static ChartAxis? GetAxisByName(string name, ObservableCollection<ChartAxis>? axes)
{
var item = (from x in axes where x.Name == name select x).ToList();
if (item != null && item.Count > 0)
if (axes == null)
{
return null;
}

foreach (var axis in axes)
{
return item[0];
if (axis.Name == name)
{
return axis;
}
}

return null;
Expand Down
14 changes: 8 additions & 6 deletions maui/src/Charts/Segment/PolarAreaSegment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,14 @@ void DrawPath(ICanvas canvas, List<float>? fillPoints, List<float>? strokePoints

List<float> GenerateInteriorPoints(float animationValue)
{
var fillPoints = new List<float>();

if (Series is not PolarSeries series)
{
return fillPoints;
return new List<float>();
}

int capacity = (_pointsCount + 2) * 2;
var fillPoints = new List<float>(capacity);

if (series.ActualXAxis != null && series.ActualYAxis != null && _xValues != null && _yValues != null)
{
PointF pointF = series.TransformVisiblePoint(_xValues[0], _yValues[0], animationValue);
Expand Down Expand Up @@ -252,13 +253,14 @@ List<float> GenerateInteriorPoints(float animationValue)

List<float> GenerateStrokePoints(float animationValue)
{
var strokePoints = new List<float>();

if (Series is not PolarSeries series)
{
return strokePoints;
return new List<float>();
}

int capacity = (_pointsCount + 2) * 2;
var strokePoints = new List<float>(capacity);

if (series.ActualXAxis != null && series.ActualYAxis != null && _xValues != null && _yValues != null)
{
PointF startPoint = series.TransformVisiblePoint(_xValues[0], _yValues[0], animationValue);
Expand Down
1 change: 1 addition & 0 deletions maui/src/Charts/Series/ChartSeries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1582,6 +1582,7 @@ internal void DataLabelSettings_PropertyChanged(object? sender, System.Component

if (e.PropertyName == nameof(dataLabelSettings.LabelStyle))
{
dataLabelSettings.LabelStyle.PropertyChanged -= LabelStyle_PropertyChanged;
dataLabelSettings.LabelStyle.PropertyChanged += LabelStyle_PropertyChanged;
dataLabelSettings.LabelStyle.Parent = Parent;
}
Expand Down
23 changes: 20 additions & 3 deletions maui/src/Picker/SfTimePicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,23 @@ internal void UpdateFormat()

#region Private Methods

/// <summary>
/// Checks if the collection contains a string that parses to the specified integer value,
/// avoiding LINQ Select/Contains allocation overhead.
/// </summary>
static bool ContainsParsedValue(ObservableCollection<string> collection, int value)
{
for (int i = 0; i < collection.Count; i++)
{
if (int.TryParse(collection[i], out int parsed) && parsed == value)
{
return true;
}
}

return false;
}

/// <summary>
/// Method trigged whenever the base panel selection is changed.
/// </summary>
Expand Down Expand Up @@ -1002,7 +1019,7 @@ void UpdateHourColumn(PickerSelectionChangedEventArgs e, string hourFormat, Time
}

int minute = 0;
if (_minuteColumn.ItemsSource != null && _minuteColumn.ItemsSource is ObservableCollection<string> minuteCollection && minuteCollection.Select(m => int.Parse(m)).Contains(previousSelectedTime.Value.Minutes))
if (_minuteColumn.ItemsSource != null && _minuteColumn.ItemsSource is ObservableCollection<string> minuteCollection && ContainsParsedValue(minuteCollection, previousSelectedTime.Value.Minutes))
{
minute = previousSelectedTime.Value.Minutes;
}
Expand All @@ -1015,7 +1032,7 @@ void UpdateHourColumn(PickerSelectionChangedEventArgs e, string hourFormat, Time
}

int second = 0;
if (_secondColumn.ItemsSource != null && _secondColumn.ItemsSource is ObservableCollection<string> secondCollection && secondCollection.Select(m => int.Parse(m)).Contains(previousSelectedTime.Value.Seconds))
if (_secondColumn.ItemsSource != null && _secondColumn.ItemsSource is ObservableCollection<string> secondCollection && ContainsParsedValue(secondCollection, previousSelectedTime.Value.Seconds))
{
second = previousSelectedTime.Value.Seconds;
}
Expand Down Expand Up @@ -1064,7 +1081,7 @@ void UpdateMinuteColumn(PickerSelectionChangedEventArgs e, TimeSpan? previousSel
}

int second = 0;
if (_secondColumn.ItemsSource != null && _secondColumn.ItemsSource is ObservableCollection<string> secondCollection && secondCollection.Select(m => int.Parse(m)).Contains(previousSelectedTime.Value.Seconds))
if (_secondColumn.ItemsSource != null && _secondColumn.ItemsSource is ObservableCollection<string> secondCollection && ContainsParsedValue(secondCollection, previousSelectedTime.Value.Seconds))
{
second = previousSelectedTime.Value.Seconds;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
using Syncfusion.Maui.Toolkit.Charts;

namespace Syncfusion.Maui.Toolkit.UnitTest.Charts
{
public class PerformanceOptimizationTests
{
#region CartesianAxisLayout - GetAxisByName

[Fact]
public void CartesianChart_NamedAxes_AssociateCorrectly()
{
var chart = new SfCartesianChart();
var xAxis = new NumericalAxis { Name = "xAxis1" };
var yAxis = new NumericalAxis { Name = "yAxis1" };

chart.XAxes.Add(xAxis);
chart.YAxes.Add(yAxis);

var series = new LineSeries
{
XAxisName = "xAxis1",
YAxisName = "yAxis1"
};
chart.Series.Add(series);

Assert.Equal("xAxis1", xAxis.Name);
Assert.Equal("yAxis1", yAxis.Name);
Assert.Equal("xAxis1", series.XAxisName);
Assert.Equal("yAxis1", series.YAxisName);
}

[Fact]
public void CartesianChart_MultipleNamedAxes_FindsCorrectAxis()
{
var chart = new SfCartesianChart();
var xAxis1 = new NumericalAxis { Name = "primary" };
var xAxis2 = new NumericalAxis { Name = "secondary" };
var yAxis1 = new NumericalAxis { Name = "left" };
var yAxis2 = new NumericalAxis { Name = "right" };

chart.XAxes.Add(xAxis1);
chart.XAxes.Add(xAxis2);
chart.YAxes.Add(yAxis1);
chart.YAxes.Add(yAxis2);

var series1 = new LineSeries
{
XAxisName = "primary",
YAxisName = "left"
};
var series2 = new LineSeries
{
XAxisName = "secondary",
YAxisName = "right"
};

chart.Series.Add(series1);
chart.Series.Add(series2);

Assert.Equal(2, chart.XAxes.Count);
Assert.Equal(2, chart.YAxes.Count);
Assert.Equal("secondary", series2.XAxisName);
Assert.Equal("right", series2.YAxisName);
}

[Fact]
public void CartesianChart_NullAxisName_DoesNotThrow()
{
var chart = new SfCartesianChart();
var xAxis = new NumericalAxis();
var yAxis = new NumericalAxis();

chart.XAxes.Add(xAxis);
chart.YAxes.Add(yAxis);

var series = new LineSeries();
chart.Series.Add(series);

Assert.Null(series.XAxisName);
Assert.Null(series.YAxisName);
}

#endregion

#region DataLabelSettings - LabelStyle PropertyChanged handler

[Fact]
public void DataLabelSettings_LabelStyle_CanBeReassigned()
{
var settings = new CartesianDataLabelSettings();
var labelStyle1 = new ChartDataLabelStyle { TextColor = Colors.Red };
var labelStyle2 = new ChartDataLabelStyle { TextColor = Colors.Blue };

settings.LabelStyle = labelStyle1;
Assert.Equal(Colors.Red, settings.LabelStyle.TextColor);

settings.LabelStyle = labelStyle2;
Assert.Equal(Colors.Blue, settings.LabelStyle.TextColor);
}

[Fact]
public void DataLabelSettings_LabelStyle_ReassignmentDoesNotThrow()
{
var series = new ColumnSeries();
var settings = new CartesianDataLabelSettings();
series.DataLabelSettings = settings;

var exception = Record.Exception(() =>
{
for (int i = 0; i < 10; i++)
{
settings.LabelStyle = new ChartDataLabelStyle
{
TextColor = Colors.Red,
FontSize = 12 + i
};
}
});

Assert.Null(exception);
}

#endregion

#region PolarAreaSegment - List capacity optimization

[Fact]
public void PolarAreaSeries_AddedToChart_DoesNotThrow()
{
var chart = new SfPolarChart();
var primaryAxis = new NumericalAxis();
var secondaryAxis = new NumericalAxis();
chart.PrimaryAxis = primaryAxis;
chart.SecondaryAxis = secondaryAxis;

var series = new PolarAreaSeries();
chart.Series.Add(series);

Assert.Single(chart.Series);
Assert.IsType<PolarAreaSeries>(chart.Series[0]);
}

[Fact]
public void PolarAreaSeries_WithData_InitializesCorrectly()
{
var chart = new SfPolarChart();
chart.PrimaryAxis = new NumericalAxis();
chart.SecondaryAxis = new NumericalAxis();

var series = new PolarAreaSeries
{
IsClosed = true
};
chart.Series.Add(series);

Assert.True(series.IsClosed);
}

#endregion
}
}
Loading