Skip to content
Merged
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
30 changes: 21 additions & 9 deletions maui/src/Charts/Axis/CategoryAxis.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using System.Diagnostics.CodeAnalysis;

namespace Syncfusion.Maui.Toolkit.Charts
Expand Down Expand Up @@ -32,8 +32,8 @@ protected sealed override DoubleRange ApplyRangePadding(DoubleRange range, doubl
internal void GroupData()
{
List<string> groupingValues = [];
var groupingValuesSet = new HashSet<string>();
List<object> groupedDatas = [];
var groupingValuesSet = new HashSet<string>(StringComparer.Ordinal);

foreach (var item in RegisteredSeries)
{
Expand All @@ -43,7 +43,7 @@ internal void GroupData()
{
if (groupedDatas.Count != 0)
{
for (int j = 0; j <= xValues.Count - 1; j++)
for (int j = 0; j < xValues.Count; j++)
{
if (groupingValuesSet.Add(xValues[j]))
{
Expand All @@ -60,9 +60,9 @@ internal void GroupData()
}
}
}
else if (series.ActualXValues != null)
else if (series.ActualXValues is List<double> doubleValues)
{
foreach (var val in (series.ActualXValues as List<double>)!)
foreach (var val in doubleValues)
{
var str = val.ToString();
groupingValues.Add(str);
Expand All @@ -77,7 +77,7 @@ internal void GroupData()
}

var distinctXValues = groupingValues.Distinct().ToList();
var indexMap = new Dictionary<string, int>(distinctXValues.Count);
var indexMap = new Dictionary<string, int>(distinctXValues.Count, StringComparer.Ordinal);
for (int i = 0; i < distinctXValues.Count; i++)
{
indexMap[distinctXValues[i]] = i;
Expand All @@ -89,11 +89,23 @@ internal void GroupData()

if (series.ActualXValues is List<string> list)
{
series.GroupedXValuesIndexes = list.Select(val => (double)indexMap[val]).ToList();
var indexes = new List<double>(list.Count);
foreach (var val in list)
{
indexes.Add(indexMap.TryGetValue(val, out int idx) ? idx : -1);
}

series.GroupedXValuesIndexes = indexes;
}
else if (series.ActualXValues != null)
else if (series.ActualXValues is List<double> doubleList)
{
series.GroupedXValuesIndexes = (series.ActualXValues as List<double>)!.Select(val => (double)indexMap[val.ToString()]).ToList();
var indexes = new List<double>(doubleList.Count);
foreach (var val in doubleList)
{
indexes.Add(indexMap.TryGetValue(val.ToString(), out int idx) ? idx : -1);
}

series.GroupedXValuesIndexes = indexes;
}

series.GroupedXValues = distinctXValues;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2505,5 +2505,157 @@ public void PointToValue_ShouldReturnCorrectValue_ForVerticalAxis()

#endregion

#region GroupData Performance Tests

[Fact]
public void GroupData_WithDuplicateValues_ProducesCorrectIndexes()
{
var axis = new CategoryAxis();
var series1 = new LineSeries
{
ActualXValues = new List<string> { "A", "B", "A", "C", "B" },
ActualData = [1, 2, 3, 4, 5]
};

axis.RegisteredSeries = [series1];

axis.GroupData();

var expectedDistinctXValues = new List<string> { "A", "B", "C" };
var expectedIndexes = new List<double> { 0, 1, 0, 2, 1 };

Assert.Equal(expectedDistinctXValues, series1.GroupedXValues);
Assert.Equal(expectedIndexes, series1.GroupedXValuesIndexes);
}

[Fact]
public void GroupData_WithDoubleXValues_ProducesCorrectIndexes()
{
var axis = new CategoryAxis();
var series1 = new LineSeries
{
ActualXValues = new List<double> { 1.0, 2.0, 3.0 },
ActualData = [10, 20, 30]
};

var series2 = new LineSeries
{
ActualXValues = new List<double> { 2.0, 3.0, 4.0 },
ActualData = [40, 50, 60]
};

axis.RegisteredSeries = [series1, series2];

axis.GroupData();

var expectedDistinctXValues = new List<string> { "1", "2", "3", "4" };
var expectedIndexesSeries1 = new List<double> { 0, 1, 2 };
var expectedIndexesSeries2 = new List<double> { 1, 2, 3 };

Assert.Equal(expectedDistinctXValues, series1.GroupedXValues);
Assert.Equal(expectedIndexesSeries1, series1.GroupedXValuesIndexes);
Assert.Equal(expectedIndexesSeries2, series2.GroupedXValuesIndexes);
}

[Fact]
public void GroupData_WithMultipleSeriesOverlappingValues_DeduplicatesCorrectly()
{
var axis = new CategoryAxis();
var series1 = new LineSeries
{
ActualXValues = new List<string> { "X", "Y", "Z" },
ActualData = [1, 2, 3]
};

var series2 = new LineSeries
{
ActualXValues = new List<string> { "X", "Y", "Z" },
ActualData = [4, 5, 6]
};

axis.RegisteredSeries = [series1, series2];

axis.GroupData();

var expectedDistinctXValues = new List<string> { "X", "Y", "Z" };
var expectedIndexes = new List<double> { 0, 1, 2 };

Assert.Equal(expectedDistinctXValues, series1.GroupedXValues);
Assert.Equal(expectedIndexes, series1.GroupedXValuesIndexes);
Assert.Equal(expectedIndexes, series2.GroupedXValuesIndexes);
}

[Fact]
public void GroupData_WithSingleSeries_ProducesCorrectResults()
{
var axis = new CategoryAxis();
var series1 = new LineSeries
{
ActualXValues = new List<string> { "Mon", "Tue", "Wed", "Thu", "Fri" },
ActualData = [10, 20, 30, 40, 50]
};

axis.RegisteredSeries = [series1];

axis.GroupData();

var expectedDistinctXValues = new List<string> { "Mon", "Tue", "Wed", "Thu", "Fri" };
var expectedIndexes = new List<double> { 0, 1, 2, 3, 4 };

Assert.Equal(expectedDistinctXValues, series1.GroupedXValues);
Assert.Equal(expectedIndexes, series1.GroupedXValuesIndexes);
}

[Fact]
public void GroupData_WithLargeDataset_CompletesWithCorrectResults()
{
var axis = new CategoryAxis();
int dataSize = 1000;
var xValues1 = new List<string>(dataSize);
var xValues2 = new List<string>(dataSize);
var data1 = new List<object>(dataSize);
var data2 = new List<object>(dataSize);

for (int i = 0; i < dataSize; i++)
{
xValues1.Add($"Item_{i}");
data1.Add(i);
}

for (int i = 500; i < dataSize + 500; i++)
{
xValues2.Add($"Item_{i}");
data2.Add(i);
}

var series1 = new LineSeries
{
ActualXValues = xValues1,
ActualData = data1
};

var series2 = new LineSeries
{
ActualXValues = xValues2,
ActualData = data2
};

axis.RegisteredSeries = [series1, series2];

axis.GroupData();

// Should have 1500 distinct values (0-999 from series1, 1000-1499 from series2)
Assert.Equal(1500, series1.GroupedXValues.Count);

// First series indexes should be 0..999
Assert.Equal(0.0, series1.GroupedXValuesIndexes[0]);
Assert.Equal(999.0, series1.GroupedXValuesIndexes[999]);

// Second series: "Item_500" should map to index 500
Assert.Equal(500.0, series2.GroupedXValuesIndexes[0]);
}

#endregion

}
}