Charting with PixieDust.Charting
PixieDust.Charting wraps Plotly.js in C# components that integrate with FlightPlan's DOM tree. Charts bind directly to DbResults/DataTable - no manual data transformation needed.
Setup
Every page using charts must include the Plotly script:
content.Add(new RawHtml("<script src=\"/js/plotly-2.35.2.min.js\"></script>"));
Or inherit from FilteredBasePage which includes it automatically.
Quick Reference
// Bar Chart
new BarChart()
.FromData(data, "category_column", "value_column")
.WithStackBy("group_column") // Optional: stacked bars
.WithTitle("Chart Title") // Optional
.WithHeight(400) // Fixed height in pixels
.WithFill() // Or: grow to fill container
.WithLegend("top", horizontal: true)
.WithoutLegend()
// Pie/Donut Chart
new PieChart()
.FromData(data, "label_column", "value_column")
.WithHole(0.4) // 0 = pie, 0.4+ = donut
.WithMaxSlices(5) // Top N + "Other"
.WithMaxLabelLength(20) // Truncate long labels
.WithFill()
.WithLegend("top", horizontal: true)
Bar Charts
Simple Bar Chart
var data = Adapter.GetMonthlySales(); // Returns: month, sales
var chart = new BarChart()
.FromData(data, "month", "sales")
.WithHeight(300);
content.Add(new ChartElement(chart));
Stacked Bar Chart
When your data has multiple values per category:
-- SQL Query returns: month_label, status, count SELECT FORMAT(date, 'MMM yyyy') as month_label, status, COUNT(*) as cnt FROM Orders GROUP BY FORMAT(date, 'MMM yyyy'), status, YEAR(date), MONTH(date) ORDER BY YEAR(date), MONTH(date)
var data = Adapter.GetOrdersByStatus();
var chart = new BarChart()
.FromData(data, "month_label", "cnt")
.WithStackBy("status") // Each status becomes a colored segment
.WithLegend("top", horizontal: true)
.WithFill();
Pie and Donut Charts
Simple Pie Chart
var data = Adapter.GetSalesByRegion(); // Returns: region, total
var chart = new PieChart()
.FromData(data, "region", "total")
.WithHeight(300);
Donut Chart
Add a hole to create a donut:
var chart = new PieChart()
.FromData(data, "region", "total")
.WithHole(0.4) // 0.4 = 40% hole (typical donut)
.WithFill();
Handling Many Categories
When you have too many slices, use WithMaxSlices():
var chart = new PieChart()
.FromData(data, "category", "count")
.WithHole(0.4)
.WithMaxSlices(5) // Top 5 + "Other"
.WithFill();
For long labels, use WithMaxLabelLength():
var chart = new PieChart()
.FromData(data, "long_category_name", "count")
.WithHole(0.4)
.WithMaxLabelLength(15) // "Very Long Categ..."
.WithFill();
Sizing: Height vs Fill
Fixed Height
Use when the chart has a specific size:
var chart = new BarChart()
.FromData(data, "x", "y")
.WithHeight(300); // Always 300px tall
Fill Container
Use when the chart should grow/shrink with its container:
var chart = new BarChart()
.FromData(data, "x", "y")
.WithFill(); // Grows to fill available space
Important: For WithFill() to work, the container must use Panel.Fill():
var chartPanel = parent.Add(Panel.Col().Grow().Fill()); var card = chartPanel.Add(Panel.Col().Grow().Fill().Card()); card.Add(new ChartElement(chart.WithFill()));
Legend Options
Position
.WithLegend("top") // Above chart
.WithLegend("bottom") // Below chart
.WithLegend("left") // Left side
.WithLegend("right") // Right side (default)
Orientation
.WithLegend("top", horizontal: true) // Items side by side
.WithLegend("top", horizontal: false) // Items stacked vertically
Hide Legend
.WithoutLegend()
Adding Charts to the DOM
Charts are added via ChartElement:
var chart = new BarChart()
.FromData(data, "month", "sales")
.WithFill();
container.Add(new ChartElement(chart));
Complete Example
// Create the panel structure
var chartArea = parent.Add(Panel.Col().Grow().Fill());
var card = chartArea.Add(Panel.Col().Grow().Fill().Card());
// Get data
var data = Adapter.GetMonthlyTrend(filters);
// Add title and chart
card.Add(new Div(CoreCss.ChartTitle).WithText("Monthly Trend"));
card.Add(new ChartElement(
new BarChart()
.FromData(data, "month_label", "count")
.WithStackBy("status")
.WithLegend("top", horizontal: true)
.WithFill()));
Data Requirements
Bar Chart Data
| Column | Description |
|---|---|
| Category column | X-axis labels (e.g., "month_label") |
| Value column | Bar heights (e.g., "count") |
| Stack column (optional) | Groups for stacking (e.g., "status") |
Pie Chart Data
| Column | Description |
|---|---|
| Label column | Slice names (e.g., "region") |
| Value column | Slice sizes (e.g., "total") |
Troubleshooting
Chart Not Showing
- Check Plotly script is included
- Check ChartElement is added to DOM
- Check data has rows (DbResults.RowCount > 0)
Chart Not Growing to Fill Space
Ensure the flex chain is complete:
parent.Add(Panel.Col().Grow().Fill()) // ← Fill() required
.Add(Panel.Col().Grow().Fill().Card())
.Add(new ChartElement(chart.WithFill()))
Legend Taking Too Much Space
- Use .WithLegend("top", horizontal: true) for horizontal layout
- Use .WithMaxSlices(5) to reduce items
- Use .WithMaxLabelLength(15) to shorten labels
- Use .WithoutLegend() if labels show on chart
Stacked Bars All Same Color
Ensure you're calling .WithStackBy("column") with the correct column name that contains the grouping values.
Class Reference
BaseChart (inherited by all charts)
| Method | Description |
|---|---|
| WithTitle(string) | Chart title |
| WithHeight(int) | Fixed height in pixels |
| WithFill(int minHeight = 200) | Grow to fill container |
| WithLegend(string, bool) | Position: top, bottom, left, right |
| WithoutLegend() | Hide legend |
BarChart
| Method | Description |
|---|---|
| FromData(DataTable, categoryColumn, valueColumn) | Bind data |
| WithStackBy(string columnName) | Enable stacking |
PieChart
| Method | Description |
|---|---|
| FromData(DataTable, labelColumn, valueColumn) | Bind data |
| WithHole(double size) | 0 = pie, 0.4+ = donut |
| WithMaxSlices(int max) | Limit slices, rest becomes "Other" |
| WithMaxLabelLength(int max) | Truncate long labels |