Pie Chart Widget - Complete Documentation¶
Overview¶
A versatile pie chart widget similar to Embedded Wizard's implementation, supporting both traditional pie charts and donut charts with extensive customization options.
Features¶
✅ Pie & Donut - Full pie or donut chart (with inner radius)
✅ Multiple Styles - Solid, Gradient, Outlined, 3D effect
✅ Flexible Labels - Inside, Outside, or Separate legend
✅ Value Display - Percentage, Absolute, or Both
✅ Slice Explosion - Highlight slices by pulling them out
✅ Interactive Mode - Clickable slices with selection
✅ Custom Colors - Per-slice color customization
✅ Start Angle - Create half-pies or gauge-style charts
✅ Memory Efficient - Minimal RAM usage (~20 bytes per slice)
API Reference¶
Creation¶
mgui_widget_t* gui_pie_chart_create(
mgui_widget_t* parent,
int16_t x, int16_t y,
int16_t width, int16_t height,
uint8_t num_slices
);
Parameters:
- num_slices - Number of slices (max 16)
Data Functions¶
// Set single slice value
void gui_pie_chart_set_value(mgui_widget_t* obj, uint8_t slice_index, int16_t value);
// Set multiple values at once
void gui_pie_chart_set_values(mgui_widget_t* obj, const int16_t* values, uint8_t count);
Appearance Functions¶
// Set slice color
void gui_pie_chart_set_slice_color(mgui_widget_t* obj, uint8_t slice_index, mgui_color_t color);
// Set slice label
void gui_pie_chart_set_slice_label(mgui_widget_t* obj, uint8_t slice_index, const char* label);
// Set chart style
void gui_pie_chart_set_style(mgui_widget_t* obj, gui_pie_chart_style_t style);
Chart Styles:
- PIE_CHART_STYLE_SOLID - Solid filled slices
- PIE_CHART_STYLE_GRADIENT - Gradient filled slices
- PIE_CHART_STYLE_OUTLINED - Only borders, no fill
- PIE_CHART_STYLE_3D - 3D effect with shadow
Geometry Functions¶
// Set pie radius
void gui_pie_chart_set_radius(mgui_widget_t* obj, uint16_t radius);
// Set inner radius (creates donut chart)
void gui_pie_chart_set_inner_radius(mgui_widget_t* obj, uint16_t inner_radius);
// Set start angle (0 = right/east, 90 = bottom, etc.)
void gui_pie_chart_set_start_angle(mgui_widget_t* obj, int16_t angle);
Slice Explosion¶
// Explode/separate a slice from the pie
void gui_pie_chart_explode_slice(mgui_widget_t* obj, uint8_t slice_index,
bool explode, uint8_t distance);
Display Options¶
// Set label display mode
void gui_pie_chart_set_label_mode(mgui_widget_t* obj, gui_pie_chart_label_mode_t mode);
// Set value display mode
void gui_pie_chart_set_value_mode(mgui_widget_t* obj, gui_pie_chart_value_mode_t mode);
Label Modes:
- PIE_CHART_LABEL_NONE - No labels
- PIE_CHART_LABEL_INSIDE - Labels inside slices
- PIE_CHART_LABEL_OUTSIDE - Labels outside with connecting lines
- PIE_CHART_LABEL_LEGEND - Separate legend box
Value Display Modes:
- PIE_CHART_VALUE_NONE - No values shown
- PIE_CHART_VALUE_PERCENTAGE - Show percentages (e.g., "25%")
- PIE_CHART_VALUE_ABSOLUTE - Show absolute values (e.g., "250")
- PIE_CHART_VALUE_BOTH - Show both (e.g., "250 (25%)")
Interaction Functions¶
// Enable/disable slice selection
void gui_pie_chart_set_interactive(mgui_widget_t* obj, bool interactive);
// Get selected slice index (-1 if none)
int8_t gui_pie_chart_get_selected(mgui_widget_t* obj);
Usage Examples¶
Example 1: Simple Pie Chart¶
// Create pie chart
mgui_widget_t* chart = gui_pie_chart_create(
screen, 20, 20, 300, 300, 5 // 5 slices
);
// Set market share data
const int16_t market_data[] = {35, 25, 20, 15, 5};
gui_pie_chart_set_values(chart, market_data, 5);
// Set colors
gui_pie_chart_set_slice_color(chart, 0, MGUI_COLOR_BLUE);
gui_pie_chart_set_slice_color(chart, 1, MGUI_COLOR_GREEN);
gui_pie_chart_set_slice_color(chart, 2, MGUI_COLOR_ORANGE);
gui_pie_chart_set_slice_color(chart, 3, MGUI_COLOR_RED);
gui_pie_chart_set_slice_color(chart, 4, MGUI_COLOR_GRAY);
// Add labels
gui_pie_chart_set_slice_label(chart, 0, "Company A");
gui_pie_chart_set_slice_label(chart, 1, "Company B");
// ... etc
// Configure display
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_SOLID);
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_OUTSIDE);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_PERCENTAGE);
Example 2: Donut Chart¶
// Create chart
mgui_widget_t* chart = gui_pie_chart_create(
screen, 350, 20, 300, 300, 6
);
// Set data
gui_pie_chart_set_value(chart, 0, 30);
gui_pie_chart_set_value(chart, 1, 20);
gui_pie_chart_set_value(chart, 2, 15);
gui_pie_chart_set_value(chart, 3, 15);
gui_pie_chart_set_value(chart, 4, 10);
gui_pie_chart_set_value(chart, 5, 10);
// Configure as DONUT (key difference!)
gui_pie_chart_set_radius(chart, 120);
gui_pie_chart_set_inner_radius(chart, 60); // Creates hole
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_GRADIENT);
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_INSIDE);
Example 3: Interactive Pie with Explosion¶
// Callback for slice clicks
void slice_clicked(mgui_widget_t* obj, mgui_event_t event) {
int8_t selected = gui_pie_chart_get_selected(obj);
DEBUG_PRINT("Slice %d selected", selected);
}
// Create chart
mgui_widget_t* chart = gui_pie_chart_create(
screen, 20, 350, 250, 250, 4
);
// Set data...
gui_pie_chart_set_values(chart, quarterly_sales, 4);
// Enable interaction
gui_pie_chart_set_interactive(chart, true);
gui_widget_set_click_handler(chart, slice_clicked);
// Clicking a slice will automatically explode it!
Example 4: Pie Chart with Legend¶
mgui_widget_t* chart = gui_pie_chart_create(
screen, 300, 350, 280, 250, 7
);
// Set data for 7 days
const int16_t activity[] = {8, 9, 7, 10, 9, 5, 6};
gui_pie_chart_set_values(chart, activity, 7);
// Add labels
const char* days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
for (int i = 0; i < 7; i++) {
gui_pie_chart_set_slice_label(chart, i, days[i]);
}
// Show legend (displays outside the pie)
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_LEGEND);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_PERCENTAGE);
Example 5: Exploded Pie (Highlight Largest)¶
mgui_widget_t* chart = gui_pie_chart_create(
screen, 400, 50, 250, 250, 5
);
// Data with one dominant value
const int16_t data[] = {10, 15, 45, 20, 10};
gui_pie_chart_set_values(chart, data, 5);
// Explode the largest slice (index 2)
gui_pie_chart_explode_slice(chart, 2, true, 20); // Pull out by 20px
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_3D);
Example 6: Half Pie / Gauge Style¶
mgui_widget_t* chart = gui_pie_chart_create(
screen, 650, 450, 200, 150, 5
);
// Start from left (creates semi-circle)
gui_pie_chart_set_start_angle(chart, 180);
// Equal segments for gauge
for (int i = 0; i < 5; i++) {
gui_pie_chart_set_value(chart, i, 20);
}
// Color gradient (green to red)
gui_pie_chart_set_slice_color(chart, 0, MGUI_COLOR_GREEN);
gui_pie_chart_set_slice_color(chart, 1, MGUI_COLOR_YELLOW);
gui_pie_chart_set_slice_color(chart, 2, MGUI_COLOR_ORANGE);
gui_pie_chart_set_slice_color(chart, 3, MGUI_COLOR_ORANGE);
gui_pie_chart_set_slice_color(chart, 4, MGUI_COLOR_RED);
// Make it a gauge (donut)
gui_pie_chart_set_radius(chart, 90);
gui_pie_chart_set_inner_radius(chart, 60);
Example 7: Real-Time Sensor Distribution¶
mgui_widget_t* sensor_pie = NULL;
void init_sensor_pie(mgui_widget_t* parent) {
sensor_pie = gui_pie_chart_create(
parent, 650, 250, 200, 200, 4
);
gui_pie_chart_set_style(sensor_pie, PIE_CHART_STYLE_GRADIENT);
gui_pie_chart_set_label_mode(sensor_pie, PIE_CHART_LABEL_INSIDE);
}
// Update periodically
void update_sensors(int16_t temp, int16_t humid, int16_t press, int16_t light) {
gui_pie_chart_set_value(sensor_pie, 0, temp);
gui_pie_chart_set_value(sensor_pie, 1, humid);
gui_pie_chart_set_value(sensor_pie, 2, press);
gui_pie_chart_set_value(sensor_pie, 3, light);
}
Example 8: Minimal Pie (MCU-Friendly)¶
// Minimal configuration for low-end MCUs
mgui_widget_t* chart = gui_pie_chart_create(
screen, 20, 20, 150, 150, 3 // Just 3 slices
);
gui_pie_chart_set_value(chart, 0, 50);
gui_pie_chart_set_value(chart, 1, 30);
gui_pie_chart_set_value(chart, 2, 20);
// Minimal styling (saves RAM and CPU)
gui_pie_chart_set_slice_color(chart, 0, MGUI_COLOR_BLUE);
gui_pie_chart_set_slice_color(chart, 1, MGUI_COLOR_GREEN);
gui_pie_chart_set_slice_color(chart, 2, MGUI_COLOR_RED);
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_SOLID);
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_NONE);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_NONE);
gui_pie_chart_set_radius(chart, 60);
More example¶
// pie_chart_examples.c - Comprehensive Pie Chart Examples
#include "gui_widget.h"
// ============================================================================
// Example 1: Basic Pie Chart (Market Share)
// ============================================================================
void example_market_share_pie(mgui_widget_t* parent) {
// Create pie chart
mgui_widget_t* chart = gui_pie_chart_create(
parent,
20, 20, // Position
300, 300, // Size
5 // 5 slices
);
// Set market share data
const int16_t market_data[] = {35, 25, 20, 15, 5};
gui_pie_chart_set_values(chart, market_data, 5);
// Set colors and labels
const char* companies[] = {"Company A", "Company B", "Company C", "Company D", "Others"};
const mgui_color_t colors[] = {
MGUI_COLOR_BLUE,
MGUI_COLOR_GREEN,
MGUI_COLOR_ORANGE,
MGUI_COLOR_RED,
MGUI_COLOR_GRAY
};
for (int i = 0; i < 5; i++) {
gui_pie_chart_set_slice_color(chart, i, colors[i]);
gui_pie_chart_set_slice_label(chart, i, companies[i]);
}
// Configure appearance
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_SOLID);
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_OUTSIDE);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_PERCENTAGE);
DEBUG_PRINT("Market share pie chart created");
}
// ============================================================================
// Example 2: Donut Chart (Budget Breakdown)
// ============================================================================
void example_budget_donut(mgui_widget_t* parent) {
// Create donut chart (pie with inner radius)
mgui_widget_t* chart = gui_pie_chart_create(
parent,
350, 20, // Position
300, 300, // Size
6 // 6 categories
);
// Set budget data
gui_pie_chart_set_value(chart, 0, 30); // Housing
gui_pie_chart_set_value(chart, 1, 20); // Food
gui_pie_chart_set_value(chart, 2, 15); // Transportation
gui_pie_chart_set_value(chart, 3, 15); // Utilities
gui_pie_chart_set_value(chart, 4, 10); // Entertainment
gui_pie_chart_set_value(chart, 5, 10); // Savings
// Set labels and colors
gui_pie_chart_set_slice_label(chart, 0, "Housing");
gui_pie_chart_set_slice_color(chart, 0, MGUI_COLOR_RED);
gui_pie_chart_set_slice_label(chart, 1, "Food");
gui_pie_chart_set_slice_color(chart, 1, MGUI_COLOR_ORANGE);
gui_pie_chart_set_slice_label(chart, 2, "Transport");
gui_pie_chart_set_slice_color(chart, 2, MGUI_COLOR_YELLOW);
gui_pie_chart_set_slice_label(chart, 3, "Utilities");
gui_pie_chart_set_slice_color(chart, 3, MGUI_COLOR_GREEN);
gui_pie_chart_set_slice_label(chart, 4, "Entertainment");
gui_pie_chart_set_slice_color(chart, 4, MGUI_COLOR_BLUE);
gui_pie_chart_set_slice_label(chart, 5, "Savings");
gui_pie_chart_set_slice_color(chart, 5, MGUI_COLOR_CYAN);
// Configure as donut (set inner radius)
gui_pie_chart_set_radius(chart, 120);
gui_pie_chart_set_inner_radius(chart, 60); // Creates donut hole
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_GRADIENT);
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_INSIDE);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_PERCENTAGE);
DEBUG_PRINT("Budget donut chart created");
}
// ============================================================================
// Example 3: Interactive Pie Chart with Explosion
// ============================================================================
mgui_widget_t* interactive_pie = NULL;
void pie_slice_clicked(mgui_widget_t* obj, mgui_event_t event) {
if (event & MGUI_EVENT_CLICKED) {
int8_t selected = gui_pie_chart_get_selected(obj);
if (selected >= 0) {
DEBUG_PRINT("Slice %d clicked!", selected);
// Show details, update info panel, etc.
}
}
}
void example_interactive_pie(mgui_widget_t* parent) {
interactive_pie = gui_pie_chart_create(
parent,
20, 350, // Position
250, 250, // Size
4 // 4 quarters
);
// Quarterly sales data
const int16_t quarterly_sales[] = {120, 145, 132, 178};
gui_pie_chart_set_values(interactive_pie, quarterly_sales, 4);
// Set colors
const mgui_color_t quarter_colors[] = {
MGUI_COLOR_RED,
MGUI_COLOR_ORANGE,
MGUI_COLOR_YELLOW,
MGUI_COLOR_GREEN
};
for (int i = 0; i < 4; i++) {
char label[8];
snprintf(label, sizeof(label), "Q%d", i + 1);
gui_pie_chart_set_slice_label(interactive_pie, i, label);
gui_pie_chart_set_slice_color(interactive_pie, i, quarter_colors[i]);
}
// Enable interaction
gui_pie_chart_set_interactive(interactive_pie, true);
gui_widget_set_click_handler(interactive_pie, pie_slice_clicked);
// Configure
gui_pie_chart_set_style(interactive_pie, PIE_CHART_STYLE_3D);
gui_pie_chart_set_label_mode(interactive_pie, PIE_CHART_LABEL_OUTSIDE);
gui_pie_chart_set_value_mode(interactive_pie, PIE_CHART_VALUE_BOTH);
DEBUG_PRINT("Interactive pie chart created - click on slices!");
}
// ============================================================================
// Example 4: Pie Chart with Legend
// ============================================================================
void example_pie_with_legend(mgui_widget_t* parent) {
mgui_widget_t* chart = gui_pie_chart_create(
parent,
300, 350, // Position
280, 250, // Size (leave room for legend)
7 // 7 days
);
// Weekly activity data
const char* days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
const int16_t activity[] = {8, 9, 7, 10, 9, 5, 6};
const mgui_color_t day_colors[] = {
MGUI_COLOR_RED,
MGUI_COLOR_ORANGE,
MGUI_COLOR_YELLOW,
MGUI_COLOR_GREEN,
MGUI_COLOR_CYAN,
MGUI_COLOR_BLUE,
MGUI_COLOR_PURPLE
};
gui_pie_chart_set_values(chart, activity, 7);
for (int i = 0; i < 7; i++) {
gui_pie_chart_set_slice_label(chart, i, days[i]);
gui_pie_chart_set_slice_color(chart, i, day_colors[i]);
}
// Show legend instead of labels on pie
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_LEGEND);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_PERCENTAGE);
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_SOLID);
DEBUG_PRINT("Pie chart with legend created");
}
// ============================================================================
// Example 5: Simple 3-Slice Pie (Yes/No/Maybe)
// ============================================================================
void example_simple_survey_pie(mgui_widget_t* parent) {
mgui_widget_t* chart = gui_pie_chart_create(
parent,
650, 20,
200, 200,
3 // 3 slices
);
// Survey results
gui_pie_chart_set_value(chart, 0, 45); // Yes
gui_pie_chart_set_value(chart, 1, 30); // No
gui_pie_chart_set_value(chart, 2, 25); // Maybe
gui_pie_chart_set_slice_label(chart, 0, "Yes");
gui_pie_chart_set_slice_color(chart, 0, MGUI_COLOR_GREEN);
gui_pie_chart_set_slice_label(chart, 1, "No");
gui_pie_chart_set_slice_color(chart, 1, MGUI_COLOR_RED);
gui_pie_chart_set_slice_label(chart, 2, "Maybe");
gui_pie_chart_set_slice_color(chart, 2, MGUI_COLOR_YELLOW);
// Simple style
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_SOLID);
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_INSIDE);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_PERCENTAGE);
gui_pie_chart_set_radius(chart, 80);
DEBUG_PRINT("Simple survey pie chart created");
}
// ============================================================================
// Example 6: Real-Time Data Pie (Sensor Distribution)
// ============================================================================
mgui_widget_t* sensor_pie = NULL;
void example_sensor_distribution(mgui_widget_t* parent) {
sensor_pie = gui_pie_chart_create(
parent,
650, 250,
200, 200,
4 // 4 sensor types
);
// Initial sensor readings
gui_pie_chart_set_value(sensor_pie, 0, 25); // Temperature
gui_pie_chart_set_value(sensor_pie, 1, 30); // Humidity
gui_pie_chart_set_value(sensor_pie, 2, 20); // Pressure
gui_pie_chart_set_value(sensor_pie, 3, 25); // Light
gui_pie_chart_set_slice_label(sensor_pie, 0, "Temp");
gui_pie_chart_set_slice_color(sensor_pie, 0, MGUI_COLOR_RED);
gui_pie_chart_set_slice_label(sensor_pie, 1, "Humid");
gui_pie_chart_set_slice_color(sensor_pie, 1, MGUI_COLOR_BLUE);
gui_pie_chart_set_slice_label(sensor_pie, 2, "Press");
gui_pie_chart_set_slice_color(sensor_pie, 2, MGUI_COLOR_YELLOW);
gui_pie_chart_set_slice_label(sensor_pie, 3, "Light");
gui_pie_chart_set_slice_color(sensor_pie, 3, MGUI_COLOR_GREEN);
gui_pie_chart_set_style(sensor_pie, PIE_CHART_STYLE_GRADIENT);
gui_pie_chart_set_label_mode(sensor_pie, PIE_CHART_LABEL_INSIDE);
gui_pie_chart_set_value_mode(sensor_pie, PIE_CHART_VALUE_ABSOLUTE);
DEBUG_PRINT("Sensor distribution pie created");
}
// Update sensor readings
void update_sensor_data(int16_t temp, int16_t humid, int16_t press, int16_t light) {
if (!sensor_pie) return;
gui_pie_chart_set_value(sensor_pie, 0, temp);
gui_pie_chart_set_value(sensor_pie, 1, humid);
gui_pie_chart_set_value(sensor_pie, 2, press);
gui_pie_chart_set_value(sensor_pie, 3, light);
}
// ============================================================================
// Example 7: Minimal Pie Chart (MCU-Friendly)
// ============================================================================
void example_minimal_pie(mgui_widget_t* parent) {
// Minimal configuration for low-end MCUs
mgui_widget_t* chart = gui_pie_chart_create(
parent,
20, 20,
150, 150,
3 // Just 3 slices
);
// Simple data
gui_pie_chart_set_value(chart, 0, 50);
gui_pie_chart_set_value(chart, 1, 30);
gui_pie_chart_set_value(chart, 2, 20);
// Minimal styling (saves RAM and CPU)
gui_pie_chart_set_slice_color(chart, 0, MGUI_COLOR_BLUE);
gui_pie_chart_set_slice_color(chart, 1, MGUI_COLOR_GREEN);
gui_pie_chart_set_slice_color(chart, 2, MGUI_COLOR_RED);
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_SOLID);
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_NONE);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_NONE);
gui_pie_chart_set_radius(chart, 60);
DEBUG_PRINT("Minimal pie chart created (MCU-friendly)");
}
// ============================================================================
// Example 8: Exploded Pie Chart (Highlight Largest)
// ============================================================================
void example_exploded_pie(mgui_widget_t* parent) {
mgui_widget_t* chart = gui_pie_chart_create(
parent,
400, 50,
250, 250,
5
);
// Data with one dominant value
const int16_t data[] = {10, 15, 45, 20, 10};
gui_pie_chart_set_values(chart, data, 5);
// Colors
const mgui_color_t colors[] = {
MGUI_COLOR_LIGHT_GRAY,
MGUI_COLOR_GRAY,
MGUI_COLOR_BLUE, // Largest - will be exploded
MGUI_COLOR_DARK_GRAY,
MGUI_COLOR_LIGHT_GRAY
};
for (int i = 0; i < 5; i++) {
gui_pie_chart_set_slice_color(chart, i, colors[i]);
}
// Explode the largest slice (index 2)
gui_pie_chart_explode_slice(chart, 2, true, 20);
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_3D);
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_OUTSIDE);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_PERCENTAGE);
DEBUG_PRINT("Exploded pie chart created (largest slice highlighted)");
}
// ============================================================================
// Example 9: Half Pie / Gauge Style
// ============================================================================
void example_gauge_pie(mgui_widget_t* parent) {
mgui_widget_t* chart = gui_pie_chart_create(
parent,
650, 450,
200, 150, // Wider than tall
5
);
// Create semi-circle (gauge-like)
gui_pie_chart_set_start_angle(chart, 180); // Start from left
// Data for gauge sections
gui_pie_chart_set_value(chart, 0, 20); // Low
gui_pie_chart_set_value(chart, 1, 20); // Med-Low
gui_pie_chart_set_value(chart, 2, 20); // Medium
gui_pie_chart_set_value(chart, 3, 20); // Med-High
gui_pie_chart_set_value(chart, 4, 20); // High
// Color gradient from green to red
gui_pie_chart_set_slice_color(chart, 0, MGUI_COLOR_GREEN);
gui_pie_chart_set_slice_color(chart, 1, MGUI_COLOR_YELLOW);
gui_pie_chart_set_slice_color(chart, 2, MGUI_COLOR_ORANGE);
gui_pie_chart_set_slice_color(chart, 3, (mgui_color_t){.value = 0xFF8000}); // Orange-red
gui_pie_chart_set_slice_color(chart, 4, MGUI_COLOR_RED);
// Make it a gauge (donut with inner radius)
gui_pie_chart_set_radius(chart, 90);
gui_pie_chart_set_inner_radius(chart, 60);
gui_pie_chart_set_style(chart, PIE_CHART_STYLE_GRADIENT);
gui_pie_chart_set_label_mode(chart, PIE_CHART_LABEL_NONE);
gui_pie_chart_set_value_mode(chart, PIE_CHART_VALUE_NONE);
DEBUG_PRINT("Gauge-style half pie created");
}
// ============================================================================
// Example 10: Comparison Pies (Side by Side)
// ============================================================================
void example_comparison_pies(mgui_widget_t* parent) {
// First pie - Last Year
mgui_widget_t* last_year = gui_pie_chart_create(
parent, 50, 450, 150, 150, 4
);
const int16_t ly_data[] = {30, 25, 25, 20};
gui_pie_chart_set_values(last_year, ly_data, 4);
// Second pie - This Year
mgui_widget_t* this_year = gui_pie_chart_create(
parent, 220, 450, 150, 150, 4
);
const int16_t ty_data[] = {35, 30, 20, 15};
gui_pie_chart_set_values(this_year, ty_data, 4);
// Same colors for both
const mgui_color_t colors[] = {
MGUI_COLOR_BLUE,
MGUI_COLOR_GREEN,
MGUI_COLOR_ORANGE,
MGUI_COLOR_RED
};
for (int i = 0; i < 4; i++) {
gui_pie_chart_set_slice_color(last_year, i, colors[i]);
gui_pie_chart_set_slice_color(this_year, i, colors[i]);
}
// Configure both
gui_pie_chart_set_style(last_year, PIE_CHART_STYLE_SOLID);
gui_pie_chart_set_style(this_year, PIE_CHART_STYLE_SOLID);
gui_pie_chart_set_label_mode(last_year, PIE_CHART_LABEL_INSIDE);
gui_pie_chart_set_label_mode(this_year, PIE_CHART_LABEL_INSIDE);
gui_pie_chart_set_value_mode(last_year, PIE_CHART_VALUE_PERCENTAGE);
gui_pie_chart_set_value_mode(this_year, PIE_CHART_VALUE_PERCENTAGE);
DEBUG_PRINT("Comparison pies created (side by side)");
}
// ============================================================================
// Memory Usage Information
// ============================================================================
void pie_chart_memory_info(void) {
DEBUG_PRINT("Pie Chart Memory Usage:");
DEBUG_PRINT(" 3 slices: ~180 bytes");
DEBUG_PRINT(" 5 slices: ~260 bytes");
DEBUG_PRINT(" 8 slices: ~380 bytes");
DEBUG_PRINT(" 16 slices: ~710 bytes (max)");
DEBUG_PRINT("");
DEBUG_PRINT("Per slice: ~20 bytes (value, color, label, flags, explode)");
DEBUG_PRINT("Base struct: ~80 bytes");
}
// ============================================================================
// Performance Tips
// ============================================================================
void pie_chart_performance_tips(void) {
DEBUG_PRINT("Pie Chart Performance Tips:");
DEBUG_PRINT("");
DEBUG_PRINT("For STM32F1/ATmega (low-end):");
DEBUG_PRINT(" - Use 3-5 slices maximum");
DEBUG_PRINT(" - Use SOLID style (fastest)");
DEBUG_PRINT(" - Disable labels (LABEL_NONE)");
DEBUG_PRINT(" - Disable values (VALUE_NONE)");
DEBUG_PRINT(" - Smaller radius (<80px)");
DEBUG_PRINT("");
DEBUG_PRINT("For STM32F4/ESP32 (mid-range):");
DEBUG_PRINT(" - Use up to 8 slices");
DEBUG_PRINT(" - GRADIENT and 3D styles OK");
DEBUG_PRINT(" - Labels and values OK");
DEBUG_PRINT(" - Interactive mode OK");
DEBUG_PRINT("");
DEBUG_PRINT("For STM32H7 (high-end):");
DEBUG_PRINT(" - Use up to 16 slices");
DEBUG_PRINT(" - All features enabled");
DEBUG_PRINT(" - Multiple pies simultaneously");
DEBUG_PRINT(" - Smooth animations");
}
Memory Usage¶
| Number of Slices | RAM Usage | Notes |
|---|---|---|
| 3 slices | ~180 bytes | Minimal |
| 5 slices | ~260 bytes | Typical |
| 8 slices | ~380 bytes | Good balance |
| 16 slices | ~710 bytes | Maximum |
Per Slice: ~20 bytes (value, color, label pointer, explode flags)
Additional Memory: - Extended struct: ~80 bytes - Angle cache: 2 bytes per slice - Labels: strlen + 1 bytes each (optional)
Performance Considerations¶
For Low-End MCUs (STM32F1, ATmega):¶
✅ Use 3-5 slices maximum
✅ Use PIE_CHART_STYLE_SOLID (fastest)
✅ Disable labels (LABEL_NONE)
✅ Disable values (VALUE_NONE)
✅ Smaller radius (<80px)
✅ Avoid explosion/interaction
For Mid-Range MCUs (STM32F4, ESP32):¶
✅ Use up to 8 slices
✅ Gradient and 3D styles OK
✅ Labels and values OK
✅ Interactive mode OK
✅ Donut charts OK
For High-End MCUs (STM32H7):¶
✅ Use up to 16 slices
✅ All features enabled
✅ Multiple charts simultaneously
✅ Smooth animations
Chart Types¶
Traditional Pie Chart¶
Donut Chart¶
// Circle with hole in center
gui_pie_chart_set_radius(chart, 120);
gui_pie_chart_set_inner_radius(chart, 60);
Half Pie / Semi-Circle¶
// Start from different angle to show half
gui_pie_chart_set_start_angle(chart, 180); // Left
// or
gui_pie_chart_set_start_angle(chart, 270); // Top
Gauge Style¶
// Combine half-pie with donut
gui_pie_chart_set_start_angle(chart, 180);
gui_pie_chart_set_inner_radius(chart, 60);
Comparison with Other Widgets¶
| Feature | Pie Chart | Bar Chart | Progress Bar |
|---|---|---|---|
| Data type | Proportional | Absolute/Relative | Single value |
| Multiple values | ✅ Yes | ✅ Yes | ❌ No |
| Visual style | Circular | Linear | Linear |
| Space efficient | ✅ Good | ⚠️ Moderate | ✅ Good |
| Easy to read | ⚠️ <5 slices | ✅ Yes | ✅ Yes |
| Interaction | ✅ Yes | ✅ Yes | ❌ No |
| Memory | ~20B/slice | ~18B/bar | ~30B total |
Common Use Cases¶
Business & Analytics¶
- Market share distribution
- Budget breakdown
- Sales by category
- Revenue by product
- Resource allocation
Embedded Systems¶
- Sensor distribution
- Battery composition
- Memory usage breakdown
- Network traffic distribution
- Task time allocation
Surveys & Polls¶
- Yes/No/Maybe results
- Rating distributions
- Choice selections
- Preference analysis
System Monitoring¶
- Disk space usage
- CPU core utilization
- Memory allocation
- Process distribution
Best Practices¶
DO:¶
✅ Use for proportional data (parts of a whole)
✅ Limit to 5-8 slices for readability
✅ Use different colors for each slice
✅ Start largest slice at 12 o'clock (top)
✅ Explode important slices to highlight them
✅ Use donut charts for better label space
DON'T:¶
❌ Use for comparing absolute values (use bar chart)
❌ Use >10 slices (unreadable)
❌ Use similar colors for adjacent slices
❌ Forget to set slice colors (all will be same)
❌ Explode all slices (defeats the purpose)
❌ Use 3D style on low-end MCUs (slow)
Troubleshooting¶
Q: Slices don't show
A: Check that all values are > 0 and colors are set
Q: Pie is too small
A: Increase radius with gui_pie_chart_set_radius()
Q: Labels overlap
A: Use LABEL_LEGEND mode or reduce number of slices
Q: Slow performance
A: Use SOLID style, disable labels/values, reduce slice count
Q: High RAM usage
A: Each slice uses ~20 bytes; reduce count or don't use labels
Q: Explosion doesn't work
A: Must call gui_pie_chart_explode_slice() with distance > 0
Future Enhancements¶
Potential features for future versions: - [ ] Animation on value change - [ ] Rotation animation - [ ] Multiple data series (nested pies) - [ ] Custom slice patterns - [ ] Export to image - [ ] Touch gestures - [ ] Smooth gradient colors - [ ] Shadow effects
Integration Checklist¶
- [ ] Add
MGUI_WIDGET_PIE_CHARTto widget types enum - [ ] Add extended struct to
gui_types.h - [ ] Add widget data to
mgui_widget_tunion - [ ] Include
gui_widget_pie_chart.cin build - [ ] Add
gui_draw_pie_chart()togui_draw.c - [ ] Add
case MGUI_WIDGET_PIE_CHART:in switch statements - [ ] Include
fast_sin()andfast_cos()functions - [ ] Define
MGUI_WIDGET_ENABLE_PIE_CHARTin config - [ ] Test with examples
Mathematical Notes¶
Angle Calculation¶
Percentage Calculation¶
Point on Circle¶
Explosion Offset¶
Conclusion¶
The Pie Chart widget provides an intuitive way to visualize proportional data in embedded GUIs. With support for both traditional pie charts and donut charts, multiple styling options, and interactive features, it's suitable for everything from simple dashboards to complex analytics displays.
Memory efficient design makes it practical even on low-end MCUs, while the full feature set enables sophisticated visualizations on more capable hardware. The slice explosion feature is particularly useful for highlighting important data points or creating engaging interactive experiences.
Perfect for displaying market share, budget breakdowns, survey results, or any data where the relationship between parts and the whole is important.