Documentation Index Fetch the complete documentation index at: https://docs.cristalyse.com/llms.txt
Use this file to discover all available pages before exploring further.
View Live Example See pie charts in action with interactive examples
Overview
Pie charts are perfect for displaying proportional data and percentages. Cristalyse supports both traditional pie charts and donut charts with smooth animations, customizable styling, and interactive features.
Basic Pie Chart
Create a simple pie chart to show proportions:
final marketData = [
{ 'company' : 'Apple' , 'marketShare' : 28.5 },
{ 'company' : 'Samsung' , 'marketShare' : 22.1 },
{ 'company' : 'Google' , 'marketShare' : 15.8 },
{ 'company' : 'Xiaomi' , 'marketShare' : 12.3 },
{ 'company' : 'Others' , 'marketShare' : 21.3 },
];
CristalyseChart ()
. data (marketData)
. mapping (
pieValue : 'marketShare' ,
pieCategory : 'company' ,
)
. geomPie (
outerRadius : 150 ,
showLabels : true ,
showPercentages : true ,
)
. theme ( ChartTheme . defaultTheme ())
. build ()
Donut Chart
Create a donut chart with a hollow center:
final salesData = [
{ 'region' : 'North America' , 'sales' : 450000 },
{ 'region' : 'Europe' , 'sales' : 320000 },
{ 'region' : 'Asia Pacific' , 'sales' : 280000 },
{ 'region' : 'Latin America' , 'sales' : 150000 },
{ 'region' : 'Middle East' , 'sales' : 100000 },
];
CristalyseChart ()
. data (salesData)
. mapping (
pieValue : 'sales' ,
pieCategory : 'region' ,
)
. geomPie (
outerRadius : 180 ,
innerRadius : 80 , // Creates donut effect
showLabels : true ,
showPercentages : false ,
)
. theme ( ChartTheme . defaultTheme ())
. build ()
Exploded Pie Chart
Create separation between slices for emphasis:
final budgetData = [
{ 'category' : 'Development' , 'amount' : 450000 },
{ 'category' : 'Marketing' , 'amount' : 280000 },
{ 'category' : 'Operations' , 'amount' : 320000 },
{ 'category' : 'Sales' , 'amount' : 180000 },
];
CristalyseChart ()
. data (budgetData)
. mapping (
pieValue : 'amount' ,
pieCategory : 'category' ,
)
. geomPie (
outerRadius : 160 ,
explodeSlices : true ,
explodeDistance : 15 ,
showLabels : true ,
showPercentages : true ,
)
. theme ( ChartTheme . defaultTheme ())
. build ()
Styling Options
Custom Colors
Override default color mapping:
CristalyseChart ()
. data (data)
. mapping (
pieValue : 'value' ,
pieCategory : 'category' ,
)
. geomPie (
outerRadius : 150 ,
colors : [
Colors .blue,
Colors .green,
Colors .orange,
Colors .red,
Colors .purple,
],
)
. build ()
Stroke Styling
Add borders to pie slices:
CristalyseChart ()
. data (data)
. mapping (
pieValue : 'value' ,
pieCategory : 'category' ,
)
. geomPie (
outerRadius : 150 ,
strokeWidth : 2.0 ,
strokeColor : Colors .white,
showLabels : true ,
)
. build ()
Custom Label Styling
Customize label appearance:
CristalyseChart ()
. data (data)
. mapping (
pieValue : 'value' ,
pieCategory : 'category' ,
)
. geomPie (
outerRadius : 150 ,
showLabels : true ,
showPercentages : true ,
labelRadius : 180 ,
labelStyle : TextStyle (
fontSize : 14 ,
fontWeight : FontWeight .bold,
color : Colors .black87,
),
)
. build ()
Animation Options
Progressive Slice Animation
Slices animate in sequence:
CristalyseChart ()
. data (data)
. mapping (
pieValue : 'value' ,
pieCategory : 'category' ,
)
. geomPie (
outerRadius : 150 ,
animationDuration : Duration (milliseconds : 1500 ),
)
. animate (
duration : Duration (milliseconds : 1500 ),
curve : Curves .easeInOutCubic,
)
. build ()
Custom Start Angle
Control where the pie starts:
CristalyseChart ()
. data (data)
. mapping (
pieValue : 'value' ,
pieCategory : 'category' ,
)
. geomPie (
outerRadius : 150 ,
startAngle : - pi / 2 , // Start at top (12 o'clock)
)
. build ()
Transform pie chart labels by passing a callback to the labels parameter.
Simple Custom Labels
For basic formatting, you can use a simple callback:
CristalyseChart ()
. data (salesData)
. mappingPie (value : 'revenue' , category : 'region' )
. geomPie (
outerRadius : 150 ,
showLabels : true ,
showPercentages : false ,
labels : (value) => ' \$ ${ value } K' , // $450K
)
. build ()
For robust, locale-aware formatting, use NumberFormat:
import 'package:intl/intl.dart' ;
// Currency formatting
CristalyseChart ()
. data (revenueData)
. mappingPie (value : 'revenue' , category : 'department' )
. geomPie (
outerRadius : 150 ,
showLabels : true ,
showPercentages : false ,
labels : NumberFormat . simpleCurrency ().format, // $1,234.56
)
. build ()
// Compact user counts
CristalyseChart ()
. data (userData)
. mappingPie (value : 'users' , category : 'platform' )
. geomPie (
outerRadius : 150 ,
showLabels : true ,
showPercentages : false ,
labels : NumberFormat . compact ().format, // 1.2K
)
. build ()
When showPercentages: true, your callback receives ratio values (0.0-1.0):
// Default percentage formatting
CristalyseChart ()
. data (surveyData)
. mappingPie (value : 'responses' , category : 'rating' )
. geomPie (
outerRadius : 150 ,
showLabels : true ,
showPercentages : true , // Uses NumberFormat.percentPattern()
)
. build ()
// Custom percentage with NumberFormat
CristalyseChart ()
. data (surveyData)
. mappingPie (value : 'responses' , category : 'rating' )
. geomPie (
outerRadius : 150 ,
showLabels : true ,
showPercentages : true ,
labels : NumberFormat . percentPattern ().format, // 23%
)
. build ()
Real-World Examples
E-commerce Sales by Category
final ecommerceData = [
{ 'category' : 'Electronics' , 'sales' : 2850000 , 'color' : Colors .blue},
{ 'category' : 'Clothing' , 'sales' : 1920000 , 'color' : Colors .green},
{ 'category' : 'Home & Garden' , 'sales' : 1450000 , 'color' : Colors .orange},
{ 'category' : 'Books' , 'sales' : 890000 , 'color' : Colors .red},
{ 'category' : 'Sports' , 'sales' : 720000 , 'color' : Colors .purple},
];
CristalyseChart ()
. data (ecommerceData)
. mapping (
pieValue : 'sales' ,
pieCategory : 'category' ,
)
. geomPie (
outerRadius : 180 ,
innerRadius : 60 ,
showLabels : true ,
showPercentages : true ,
labelRadius : 220 ,
strokeWidth : 3 ,
strokeColor : Colors .white,
explodeSlices : true ,
explodeDistance : 8 ,
)
. theme ( ChartTheme . defaultTheme ())
. build ()
Project Time Allocation
final projectData = [
{ 'phase' : 'Planning' , 'hours' : 120 },
{ 'phase' : 'Development' , 'hours' : 480 },
{ 'phase' : 'Testing' , 'hours' : 160 },
{ 'phase' : 'Deployment' , 'hours' : 80 },
{ 'phase' : 'Documentation' , 'hours' : 60 },
];
CristalyseChart ()
. data (projectData)
. mapping (
pieValue : 'hours' ,
pieCategory : 'phase' ,
)
. geomPie (
outerRadius : 160 ,
showLabels : true ,
showPercentages : true ,
labelStyle : TextStyle (
fontSize : 12 ,
fontWeight : FontWeight .w600,
),
)
. theme ( ChartTheme . defaultTheme ())
. build ()
Advanced Features
Interactive Pie Charts
Add hover effects and click handling:
CristalyseChart ()
. data (data)
. mapping (
pieValue : 'value' ,
pieCategory : 'category' ,
)
. geomPie (
outerRadius : 150 ,
showLabels : true ,
onSliceClick : (data, index) {
print ( 'Clicked slice: ${ data [ 'category' ]} ' );
},
)
. interactions (
enableHover : true ,
enableClick : true ,
)
. build ()
Responsive Sizing
Automatically adjust based on container size:
LayoutBuilder (
builder : (context, constraints) {
final radius = math. min (constraints.maxWidth, constraints.maxHeight) / 3 ;
return CristalyseChart ()
. data (data)
. mapping (
pieValue : 'value' ,
pieCategory : 'category' ,
)
. geomPie (
outerRadius : radius,
innerRadius : radius * 0.4 ,
showLabels : constraints.maxWidth > 300 ,
)
. build ();
},
)
Best Practices
When to Use Pie Charts
Good for:
Showing parts of a whole
Displaying percentages
Comparing proportions (5-7 categories max)
Simple data visualization
Avoid for:
Too many categories (>7)
Comparing exact values
Time series data
Negative values
Design Tips
Limit to 5-7 slices for readability
Use contrasting colors
Order slices by size (largest first)
Consider donut charts for modern look
Use exploded slices sparingly for emphasis
Optimize for large datasets by grouping small values
Use appropriate animation durations
Consider static rendering for print/export
Test on different screen sizes
Common Patterns
Market Share Analysis
final marketShare = [
{ 'company' : 'Leader' , 'share' : 35.2 },
{ 'company' : 'Challenger' , 'share' : 24.8 },
{ 'company' : 'Follower' , 'share' : 18.5 },
{ 'company' : 'Niche' , 'share' : 12.1 },
{ 'company' : 'Others' , 'share' : 9.4 },
];
CristalyseChart ()
. data (marketShare)
. mapping (pieValue : 'share' , pieCategory : 'company' )
. geomPie (
outerRadius : 160 ,
showLabels : true ,
showPercentages : true ,
explodeSlices : true ,
explodeDistance : 10 ,
)
. build ()
Survey Results
final surveyResults = [
{ 'response' : 'Very Satisfied' , 'count' : 45 },
{ 'response' : 'Satisfied' , 'count' : 38 },
{ 'response' : 'Neutral' , 'count' : 12 },
{ 'response' : 'Dissatisfied' , 'count' : 3 },
{ 'response' : 'Very Dissatisfied' , 'count' : 2 },
];
CristalyseChart ()
. data (surveyResults)
. mapping (pieValue : 'count' , pieCategory : 'response' )
. geomPie (
outerRadius : 150 ,
innerRadius : 50 ,
showLabels : true ,
showPercentages : true ,
)
. build ()