Created
April 18, 2019 17:40
-
-
Save LanceMcCarthy/b64ee5afdd27b125b8b47816799306e0 to your computer and use it in GitHub Desktop.
Creating a Pie Chart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public partial class MainPage : ContentPage | |
{ | |
public MainPage() | |
{ | |
InitializeComponent(); | |
CreatePieChart(); | |
} | |
private void CreatePieChart() | |
{ | |
// Data for the series. | |
var dataPoints = new List<ChartDataPoint> | |
{ | |
new ChartDataPoint { Title = "Work", Value = 9 }, | |
new ChartDataPoint { Title = "Commute", Value = 1.5 }, | |
new ChartDataPoint { Title = "Leisure", Value = 6 }, | |
new ChartDataPoint { Title = "Sleep", Value = 7.5 }, | |
}; | |
// Colors for the series. | |
var colors = new List<Color> | |
{ | |
Color.FromHex("#BAB65A"), | |
Color.FromHex("#6196D1"), | |
Color.FromHex("#3D4268"), | |
Color.FromHex("#8A56E2"), | |
}; | |
// Root container to hold the chart and any legend | |
var container = new Grid(); | |
container.RowDefinitions.Add(new RowDefinition { Height = new GridLength(3, GridUnitType.Star) }); | |
container.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); | |
// ***** Part 1 - PIE SERIES GENERATION ***** // | |
// Sum up all the values to be displayed | |
var totalValue = dataPoints.Sum(d => d.Value); | |
// Variable to keep track of where each slice ended. | |
double currentPosition = 0; | |
// Iterate over the data points to create slices. | |
for (int i = 0; i < dataPoints.Count; i++) | |
{ | |
// Determine the what percentage that data item's value is of the whole | |
double slicePercentage = dataPoints[i].Value / totalValue; | |
// Calculate the sweep angle using that percentage amount. | |
double sweep = slicePercentage * 360; | |
// Create the ArcSegment using the current position and sweep | |
var segment = new RadArcSegment | |
{ | |
Center = new Point(0.5, 0.5), | |
Size = new Size(1, 1), | |
StartAngle = currentPosition, | |
SweepAngle = sweep, | |
}; | |
// Important - Calculate the last segment's ending angle in order to have a valid start angle for the next loop. | |
currentPosition = currentPosition + sweep - 360; | |
// Prepare the required PathFigure and add the ArcSegment | |
var figure = new RadPathFigure { StartPoint = new Point(0.5, 0.5) }; | |
figure.Segments.Add(segment); | |
// Create the PathGeometry and add the PathFigure | |
var geometry = new RadPathGeometry(); | |
geometry.Figures.Add(figure); | |
// Construct the RadPath | |
// - Select a Fill color from the brushes parameter (important: use a modulus to wrap to the beginning) | |
// - Use the Geometry created from the value | |
var slice = new RadPath | |
{ | |
Fill = new RadSolidColorBrush(colors[i % colors.Count]), | |
Geometry = geometry, | |
HorizontalOptions = LayoutOptions.Center, | |
VerticalOptions = LayoutOptions.Center, | |
WidthRequest = 100, | |
HeightRequest = 100, | |
Margin = new Thickness(0, 20, 0, 0) | |
}; | |
// This isn't necessary, but added for completion. | |
Grid.SetRow(slice, 0); | |
// Finally, add it to the container. | |
container.Children.Add(slice); | |
} | |
// ***** Part 2 - LEGEND GENERATION ***** // | |
// Create a horizontal StackLayout to hold the legend items | |
var legendPanel = new StackLayout | |
{ | |
Orientation = StackOrientation.Horizontal, | |
HorizontalOptions = LayoutOptions.Center, | |
VerticalOptions = LayoutOptions.Center, | |
Margin = new Thickness(0, 16, 0, 0), | |
Spacing = 5 | |
}; | |
// Iterate over the data points and create a legend item with a matching color | |
for (int i = 0; i < dataPoints.Count; i++) | |
{ | |
// Use a RadBorder with only a bottom thickness and match the color to the slice | |
var legendItem = new RadBorder | |
{ | |
BorderColor = colors[i % colors.Count], | |
BorderThickness = new Thickness(0, 0, 0, 2) | |
}; | |
// Create a Label for each data point and use the Title property | |
var label = new Label | |
{ | |
Text = dataPoints[i].Title, | |
FontSize = 12, | |
Margin = new Thickness(0, 0, 0, 2), | |
TextColor = Color.DimGray | |
}; | |
legendItem.Content = label; | |
legendPanel.Children.Add(legendItem); | |
} | |
// Insert the legend panel in the root container's 2nd row. | |
Grid.SetRow(legendPanel, 1); | |
container.Children.Add(legendPanel); | |
// ***** Part 3 - Add the container to the UI ***** // | |
this.Content = container; | |
} | |
} | |
public class ChartDataPoint | |
{ | |
public string Title { get; set; } | |
public double Value { get; set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment