Skip to content

Instantly share code, notes, and snippets.

@LanceMcCarthy
Created April 18, 2019 17:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LanceMcCarthy/b64ee5afdd27b125b8b47816799306e0 to your computer and use it in GitHub Desktop.
Save LanceMcCarthy/b64ee5afdd27b125b8b47816799306e0 to your computer and use it in GitHub Desktop.
Creating a Pie Chart
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