Skip to content

Commit b1d83cc

Browse files
author
tineshsf4652
authored
Update README.md
1 parent 57971b6 commit b1d83cc

File tree

1 file changed

+307
-1
lines changed

1 file changed

+307
-1
lines changed

README.md

Lines changed: 307 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,308 @@
11
# How-to-create-Parallel-coordinate-chart-in-.NET-MAUI
2-
Learn to create a Parallel Coordinate Chart in .NET MAUI using SfCartesianChart with multiple series and axis crossing for parallel axis arrangement.
2+
This article offers a comprehensive guide to creating a Parallel Coordinate Chart in .NET MAUI.
3+
4+
You can achieve the parallel coordinates chart using the [.NET MAUI Cartesian Chart](https://www.syncfusion.com/maui-controls/maui-cartesian-charts) by incorporating multiple spline or line series and utilizing axis crossing support to arrange the chart axes in parallel.
5+
6+
A **Parallel Coordinate Chart** for visualizing multidimensional data, where each axis represents a variable, and data points are displayed as lines connecting these parallel axes. This guide walks you through the steps to implement such a visualization effectively in .NET MAUI.
7+
8+
The following steps and code examples illustrate how to create the parallel coordinates chart using [SfCartesianChart](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.SfCartesianChart.html).
9+
10+
**Step 1:** Create a custom parallel coordinates chart by inheriting from the SfCartesianChart class and initializing the chart setup through the GenerateChart method.
11+
12+
**C#**
13+
```csharp
14+
public class ParallelCoordinateChart:SfCartesianChart
15+
{
16+
public ParallelCoordinateChart()
17+
{
18+
GenerateChart();
19+
}
20+
}
21+
```
22+
23+
24+
**Step 2:** This method manages the complete chart setup, including the configuration of axes, series, and visual styling elements such as color palettes.
25+
26+
**C#**
27+
28+
```csharp
29+
private void GenerateChart()
30+
{
31+
var xAxes = GenerateXAxes();
32+
var yAxes = GenerateYAxesList();
33+
this.XAxes.Add(xAxes);
34+
foreach(var yaxis in yAxes)
35+
{
36+
this.YAxes.Add(yaxis);
37+
}
38+
39+
var paletteBrushes = new List<Brush>
40+
{
41+
new SolidColorBrush(Color.FromArgb("#800080")),
42+
new SolidColorBrush(Color.FromArgb("#6495ED")),
43+
new SolidColorBrush(Color.FromArgb("#32CD32")),
44+
new SolidColorBrush(Color.FromArgb("#FFD700")),
45+
new SolidColorBrush(Color.FromArgb("#FF6347")),
46+
new SolidColorBrush(Color.FromArgb("#8A2BE2")),
47+
};
48+
this.PaletteBrushes = paletteBrushes;
49+
50+
var serieslist = GenerateSeries(yAxes);
51+
foreach(var series in serieslist)
52+
{
53+
this.Series.Add(series);
54+
}
55+
}
56+
```
57+
58+
59+
**Step 3:** Generate the X-axis for the chart and create a list of Y-axes, each representing a different variable from the view model data source.
60+
61+
**C#**
62+
```csharp
63+
private NumericalAxis GenerateXAxes()
64+
{
65+
var xAxes = new NumericalAxis()
66+
{
67+
Minimum = 0,
68+
Maximum = 4,
69+
Interval = 1,
70+
ShowMajorGridLines = false,
71+
PlotOffsetStart = 20,
72+
PlotOffsetEnd = 50,
73+
CrossesAt = double.MaxValue,
74+
};
75+
76+
xAxes.LabelCreated += (s, e) =>
77+
{
78+
e.Label = e.Position switch
79+
{
80+
0 => "Model",
81+
1 => "Horsepower",
82+
2 => "Torque",
83+
3 => "FuelEfficiency",
84+
4 => "Price",
85+
_ => string.Empty
86+
};
87+
};
88+
89+
return xAxes;
90+
}
91+
92+
private List<NumericalAxis> GenerateYAxesList()
93+
{
94+
var viewmodelData = new ViewModel().Source;
95+
var firstItem = viewmodelData.First();
96+
var properties = firstItem.GetType().GetProperties();
97+
var list = new List<NumericalAxis>();
98+
foreach ( var property in properties)
99+
{
100+
if(property.Name == "CarModel")
101+
{
102+
var yaxes = new NumericalAxis()
103+
{
104+
Minimum = 0,
105+
Maximum = 4,
106+
Interval = 1,
107+
CrossesAt = 0,
108+
ShowMajorGridLines = false,
109+
LabelsPosition = AxisElementPosition.Inside,
110+
};
111+
yaxes.LabelCreated += (s, e) =>
112+
{
113+
e.Label = e.Position switch
114+
{
115+
0 => "CarA",
116+
1 => "CarB",
117+
2 => "CarC",
118+
3 => "CarD",
119+
4 => "CarE",
120+
_ => string.Empty
121+
};
122+
};
123+
list.Add(yaxes);
124+
}
125+
else if(property.Name == "Horsepower")
126+
{
127+
var yaxes = new NumericalAxis()
128+
{
129+
Minimum = 100,
130+
Maximum = 240,
131+
Interval = 20,
132+
CrossesAt = 1,
133+
ShowMajorGridLines = false,
134+
LabelsPosition = AxisElementPosition.Inside,
135+
};
136+
list.Add(yaxes);
137+
}
138+
else if (property.Name == "Torque")
139+
{
140+
var yaxes = new NumericalAxis()
141+
{
142+
Minimum = 100,
143+
Maximum = 500,
144+
Interval = 50,
145+
CrossesAt = 2,
146+
ShowMajorGridLines = false,
147+
LabelsPosition = AxisElementPosition.Inside,
148+
};
149+
list.Add(yaxes);
150+
}
151+
else if (property.Name == "FuelEfficiency")
152+
{
153+
var yaxes = new NumericalAxis()
154+
{
155+
Minimum = 5,
156+
Maximum = 40,
157+
Interval = 5,
158+
CrossesAt = 3,
159+
ShowMajorGridLines = false,
160+
LabelsPosition = AxisElementPosition.Inside,
161+
};
162+
list.Add(yaxes);
163+
}
164+
else if(property.Name == "Price")
165+
{
166+
var yaxes = new NumericalAxis()
167+
{
168+
Minimum = 10000,
169+
Maximum = 50000,
170+
Interval = 5000,
171+
CrossesAt = 4,
172+
ShowMajorGridLines = false,
173+
LabelsPosition = AxisElementPosition.Inside,
174+
};
175+
list.Add(yaxes);
176+
}
177+
}
178+
return list;
179+
}
180+
```
181+
182+
183+
**Step 4:** Generates and returns a list of series to visualize data points across the parallel axes, normalizes raw data values to a standardized scale, and maps car model names to their corresponding indices on the X-axis.
184+
185+
**C#**
186+
187+
```csharp
188+
private List<SplineSeries> GenerateSeries(List<NumericalAxis> yAxes)
189+
{
190+
var viewModel = new ViewModel();
191+
var seriesList = new List<SplineSeries>();
192+
foreach (var chartModel in viewModel.DataSource)
193+
{
194+
var itemSource = new ObservableCollection<SeriesModel>();
195+
196+
for (int axisIndex = 0; axisIndex < yAxes.Count; axisIndex++)
197+
{
198+
double yValue = 0;
199+
var model = chartModel.Variable[0] as Model;
200+
201+
switch (axisIndex)
202+
{
203+
case 0:
204+
yValue = Normalize(CarModelIndex(model.CarModel), 0, 4);
205+
break;
206+
207+
case 1:
208+
yValue = Normalize(model.Horsepower, 100, 240);
209+
break;
210+
211+
case 2:
212+
yValue = Normalize(model.Torque, 100, 500);
213+
break;
214+
215+
case 3:
216+
yValue = Normalize(model.FuelEfficiency, 5, 40);
217+
break;
218+
219+
case 4:
220+
yValue = Normalize(model.Price, 10000, 50000);
221+
break;
222+
}
223+
itemSource.Add(new SeriesModel(axisIndex, yValue));
224+
}
225+
var series = new SplineSeries()
226+
{
227+
ItemsSource = itemSource,
228+
XBindingPath = nameof(SeriesModel.XValues),
229+
YBindingPath = nameof(SeriesModel.YValues),
230+
};
231+
232+
seriesList.Add(series);
233+
}
234+
return seriesList;
235+
}
236+
237+
private double Normalize(double value, double min, double max)
238+
{
239+
double diff = max - min;
240+
return ((value - min) / diff) * 4;
241+
}
242+
243+
private int CarModelIndex(string carModel)
244+
{
245+
return carModel switch
246+
{
247+
"Car A" => 0,
248+
"Car B" => 1,
249+
"Car C" => 2,
250+
"Car D" => 3,
251+
"Car E" => 4,
252+
_ => -1
253+
};
254+
}
255+
```
256+
257+
**Step 5:** This ViewModel class contains DataSource and Source. It generates a collection of Model objects with car details using GenerateData method, then wraps each Model in a ChartModel and adds it to DataSource.
258+
259+
**C#**
260+
261+
```csharp
262+
public class ViewModel
263+
{
264+
public ObservableCollection<ChartModel> DataSource { get; set; }
265+
266+
public ObservableCollection<Model> Source { get; set; }
267+
268+
public ViewModel()
269+
{
270+
Source = GenerateData();
271+
DataSource = new ObservableCollection<ChartModel>();
272+
foreach (var data in Source)
273+
{
274+
DataSource.Add(new ChartModel(new List<object> { data }));
275+
}
276+
}
277+
278+
private ObservableCollection<Model> GenerateData()
279+
{
280+
var data = new ObservableCollection<Model>()
281+
{
282+
new Model { CarModel = "Car A", Horsepower = 220, Torque = 400, FuelEfficiency = 10, Price = 50000 },
283+
new Model { CarModel = "Car B", Horsepower = 150, Torque = 350, FuelEfficiency = 15, Price = 15000 },
284+
new Model { CarModel = "Car C", Horsepower = 200, Torque = 150, FuelEfficiency = 20, Price = 30000 },
285+
new Model { CarModel = "Car D", Horsepower = 180, Torque = 300, FuelEfficiency = 30, Price = 25000 },
286+
new Model { CarModel = "Car E", Horsepower = 120, Torque = 200, FuelEfficiency = 35, Price = 40000 }
287+
};
288+
289+
return data;
290+
}
291+
}
292+
```
293+
294+
295+
**Step 6:** The Content page contains the ParallelCoordinateChart control, which renders the parallel coordinate chart on the page.
296+
297+
**XAML**
298+
299+
```xml
300+
<ContentPage.Content>
301+
<local:ParallelCoordinateChart/>
302+
</ContentPage.Content>
303+
```
304+
305+
**Output:**
306+
307+
![ParallelCoordinateChart1](https://github.com/user-attachments/assets/1625c2c0-7d14-420d-b591-5fb29426b90d)
308+

0 commit comments

Comments
 (0)