@page "/components/charts/bar"

<PageTitle>Bar Chart — Lumeo</PageTitle>

<PageHeader Title="Bar Chart" Description="Compare discrete categories side-by-side. Ideal for monthly comparisons, ranking, or showing multiple series over the same categories." />

<Stack Gap="8">
    <ComponentDemo Title="Basic Bar Chart" Description="Side-by-side grouped bars comparing this year's revenue against last year across twelve months." Code="@_basicCode">
        <Container>
            <BarChart Categories="_categories" Series="_series" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Stacked Vertical" Description="Stack two product lines to show combined monthly revenue and relative contribution of each." Code="@_stackedVerticalCode">
        <Container>
            <BarChart Categories="_categories" Series="_stackedSeries" Stacked="true" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Horizontal Bar" Description="Horizontal orientation works well for ranking category labels that are too long to fit on a vertical axis." Code="@_horizontalCode">
        <Container>
            <BarChart Categories="_regions" Series="_regionSeries" Horizontal="true" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Horizontal Stacked" Description="Combine horizontal layout with stacking to show part-to-whole breakdowns across departments." Code="@_stackedCode">
        <Container>
            <BarChart Categories="_categories" Series="_series" Horizontal="true" Stacked="true" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="With Data Labels" Description="Display the exact value on top of each bar — useful for presentations where reading specific numbers matters." Code="@_labelsCode">
        <Container>
            <BarChart Categories="_shortCategories" Series="_labelSeries" ShowDataLabels="true" LabelPosition="top" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Custom Color Palette + DataZoom" Description="Override the default palette with brand colors and enable the DataZoom slider to scroll through a dense dataset." Code="@_zoomCode">
        <Container>
            <BarChart Categories="_months24" Series="_zoom24Series" Colors="_brandColors" DataZoom="true" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Interactive label density" Description="Drag the slider to change the number of categories and watch Smart rotate labels as the axis gets crowded." Code="@_interactiveCode">
        <Container>
            <Stack Gap="4">
                <Stack Direction="Stack.StackDirection.Horizontal" Gap="6" Wrap="true" Align="end">
                    <Stack Gap="1" Class="min-w-[260px] flex-1">
                        <span class="text-sm font-medium">Categories: @_categoryCount</span>
                        <Slider Min="5" Max="36" Step="1" Value="_categoryCount" ValueChanged="OnSliderChanged" />
                    </Stack>
                    <Stack Gap="1">
                        <span class="text-sm font-medium">Strategy</span>
                        <ToggleGroup Type="ToggleGroup.ToggleGroupType.Single" Variant="ToggleGroup.ToggleGroupVariant.Outline" Value="@_strategy.ToString()" ValueChanged="OnStrategyChanged">
                            <ToggleGroupItem Value="Smart">Smart</ToggleGroupItem>
                            <ToggleGroupItem Value="ShowAll">ShowAll</ToggleGroupItem>
                            <ToggleGroupItem Value="Auto">Auto</ToggleGroupItem>
                        </ToggleGroup>
                    </Stack>
                </Stack>
                <BarChart Categories="@_interactiveLabels" Series="@_interactiveSeries" LabelStrategy="@_strategy" Height="300px" />
                <span class="text-xs text-muted-foreground">Move the slider to see Smart's auto-rotate kick in at 11 / 17 / 25 categories.</span>
            </Stack>
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Loading state" Description="Shape-aware skeleton renders automatically before ECharts mounts and while IsLoading is true — no empty-whitespace flash, no layout shift. Click Simulate to fake a 2-second fetch, or flip the switch to pin the skeleton for inspection." Code="@_loadingCode">
        <Container>
            <Stack Gap="4">
                <Stack Direction="Stack.StackDirection.Horizontal" Gap="4" Align="center" Wrap="true">
                    <Button OnClick="SimulateLoadingAsync" Disabled="@_isLoading">Simulate loading</Button>
                    <Stack Direction="Stack.StackDirection.Horizontal" Gap="2" Align="center">
                        <Switch @bind-Value="_keepLoading" Id="keep-loading" />
                        <label for="keep-loading" class="text-sm text-muted-foreground cursor-pointer">Hold skeleton open</label>
                    </Stack>
                    <Stack Direction="Stack.StackDirection.Horizontal" Gap="2" Align="center">
                        <label class="text-sm text-muted-foreground">Duration: @(_simulateBarDurationMs / 1000.0)s</label>
                        <input type="range" min="500" max="10000" step="500" @bind-value="_simulateBarDurationMs" @bind-value:event="oninput" class="w-32 accent-primary" />
                    </Stack>
                    <Stack Direction="Stack.StackDirection.Horizontal" Gap="2" Align="center">
                        <label class="text-sm text-muted-foreground">Cycle: @_phantomBarCycleMs ms</label>
                        <input type="range" min="300" max="3000" step="100" @bind-value="_phantomBarCycleMs" @bind-value:event="oninput" class="w-32 accent-primary" />
                    </Stack>
                </Stack>
                <BarChart Categories="_shortCategories" Series="_labelSeries" PhantomCycleMs="@_phantomBarCycleMs" IsLoading="@IsLoadingComputed" Height="320px" />
            </Stack>
        </Container>
    </ComponentDemo>
</Stack>

<Stack Gap="6" Class="mt-12">
    <Heading Level="2">API Reference</Heading>
    <Stack Gap="8">
        <Stack>
            <Heading Level="3" Class="mb-3">BarChart</Heading>
            <Stack Class="rounded-lg border border-border/40 overflow-x-auto">
                <table class="w-full min-w-[600px] text-sm">
                    <thead>
                        <tr class="border-b border-border/40 bg-muted/40">
                            <th class="text-left p-3 font-medium text-foreground">Property</th>
                            <th class="text-left p-3 font-medium text-foreground">Type</th>
                            <th class="text-left p-3 font-medium text-foreground">Default</th>
                            <th class="text-left p-3 font-medium text-foreground">Description</th>
                        </tr>
                    </thead>
                    <tbody class="divide-y divide-border/40">
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Categories</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">List&lt;string&gt;</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">[]</td>
                            <td class="p-3 text-muted-foreground">X-axis category labels.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Series</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">List&lt;ChartSeriesData&gt;</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">[]</td>
                            <td class="p-3 text-muted-foreground">Data series with Name and Values.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Horizontal</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Rotates bars to grow horizontally.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Stacked</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Stacks series on top of each other.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowLegend</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Shows or hides the chart legend.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowTooltip</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Enables the hover tooltip.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Colors</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">List&lt;string&gt;?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Custom color palette for series.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">DataZoom</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Enables zoom slider for large datasets.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Toolbox</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Shows save/restore/zoom toolbox.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowDataLabels</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Renders value labels on each bar.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LabelPosition</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">"top"</td>
                            <td class="p-3 text-muted-foreground">Label position: "top", "inside", "bottom".</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LabelStrategy</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">ChartLabelStrategy</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">Smart</td>
                            <td class="p-3 text-muted-foreground">How category-axis labels are rendered. Smart auto-rotates at higher densities; ShowAll forces all horizontal; Auto thins overlapping labels.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LabelRotate</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">int?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Manual rotation override in degrees on top of LabelStrategy.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">IsLoading</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">When true, renders a shape-matched loading skeleton in place of the chart. Bind to your async fetch state.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowLoadingSkeleton</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Set to false to opt out of the skeleton (chart area stays empty while IsLoading is true).</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">SkeletonKind</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">ChartSkeletonKind</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">(chart default)</td>
                            <td class="p-3 text-muted-foreground">Override the skeleton silhouette (Bars, Line, Area, Pie, Scatter, Grid, Generic).</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">SkeletonStyle</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">ChartSkeletonStyle</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">Phantom</td>
                            <td class="p-3 text-muted-foreground">Phantom renders the real chart with placeholder data and morphs to real data via ECharts animation. Silhouette falls back to the legacy SVG skeleton overlay.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowLoadingLabel</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Shows a small "Loading&hellip;" pill in the top-right corner whenever <code class="rounded bg-muted px-1 py-0.5 text-xs font-mono">IsLoading</code> is true. Layered on top of any <code class="rounded bg-muted px-1 py-0.5 text-xs font-mono">SkeletonStyle</code>. Set to false for bare visuals. <strong>(rc.18)</strong></td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LoadingText</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">"Loading&hellip;"</td>
                            <td class="p-3 text-muted-foreground">Label rendered next to the spinner inside the loading pill. Set to empty to show the spinner alone. <strong>(rc.18)</strong></td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Width</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">"100%"</td>
                            <td class="p-3 text-muted-foreground">CSS width of the chart container.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Height</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">"350px"</td>
                            <td class="p-3 text-muted-foreground">CSS height of the chart container.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Theme</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">ECharts theme name override; null follows global Lumeo theme.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">PhantomCycleMs</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">int</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">1400</td>
                            <td class="p-3 text-muted-foreground">Phantom-mode refresh interval in milliseconds; lower cycles placeholder data faster.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LabelFormat</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">ECharts formatter string applied to bar data labels.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ColorPalette</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">List&lt;string&gt;?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Alternate color palette applied when Colors is unset.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">AnimationDuration</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">int?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Override ECharts bar-grow animation duration in milliseconds.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">AnimationEasing</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">ECharts easing function name for entry animation.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">MarkLine</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">EChartMarkLine?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Reference lines (avg, max, target) overlaid on the bars.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">MarkPoint</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">EChartMarkPoint?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Marker points highlighting extrema or annotations on bars.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">MarkArea</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">EChartMarkArea?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Shaded regions highlighting value ranges behind the bars.</td>
                        </tr>
                    </tbody>
                </table>
            </Stack>
        </Stack>
    </Stack>
</Stack>

@code {
    private List<string> _categories = new() { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
    private List<string> _shortCategories = new() { "Q1", "Q2", "Q3", "Q4" };
    private List<string> _regions = new() { "North America", "Western Europe", "Asia Pacific", "Latin America", "Middle East", "Africa" };

    private List<BarChart.ChartSeriesData> _series = new()
    {
        new() { Name = "This Year",  Values = new() { 41200, 38400, 52100, 61800, 57300, 74200, 68900, 72500, 81300, 88700, 79400, 95600 } },
        new() { Name = "Last Year",  Values = new() { 35000, 31200, 44800, 53100, 48900, 62400, 58700, 61200, 69800, 74300, 65100, 82200 } }
    };

    private List<BarChart.ChartSeriesData> _stackedSeries = new()
    {
        new() { Name = "SaaS",       Values = new() { 28400, 31100, 38700, 42300, 45800, 51200, 53600, 58900, 62100, 67400, 71800, 79300 } },
        new() { Name = "On-Premise", Values = new() { 19700, 17600, 21400, 18900, 17200, 16300, 15800, 14700, 13900, 12800, 11600, 10400 } }
    };

    private List<BarChart.ChartSeriesData> _regionSeries = new()
    {
        new() { Name = "Revenue ($K)", Values = new() { 184300, 142700, 211500, 63200, 47800, 28900 } }
    };

    private List<BarChart.ChartSeriesData> _labelSeries = new()
    {
        new() { Name = "Actual",  Values = new() { 142800, 161300, 154700, 178200 } },
        new() { Name = "Target",  Values = new() { 150000, 155000, 160000, 175000 } }
    };

    private List<string> _months24 = new()
    {
        "Jan 24", "Feb 24", "Mar 24", "Apr 24", "May 24", "Jun 24",
        "Jul 24", "Aug 24", "Sep 24", "Oct 24", "Nov 24", "Dec 24",
        "Jan 25", "Feb 25", "Mar 25", "Apr 25", "May 25", "Jun 25",
        "Jul 25", "Aug 25", "Sep 25", "Oct 25", "Nov 25", "Dec 25"
    };

    private List<BarChart.ChartSeriesData> _zoom24Series = new()
    {
        new() { Name = "New Customers", Values = new() { 312, 287, 341, 398, 423, 512, 487, 531, 604, 672, 598, 741, 328, 304, 367, 421, 448, 539, 513, 557, 631, 698, 624, 779 } },
        new() { Name = "Renewals",      Values = new() { 891, 843, 912, 967, 1034, 1128, 1087, 1142, 1213, 1289, 1198, 1347, 1024, 968, 1047, 1103, 1171, 1264, 1224, 1278, 1352, 1428, 1334, 1491 } }
    };

    private List<string> _brandColors = new() { "#6366f1", "#f59e0b" };

    private string _basicCode = @"<BarChart Categories=""_categories"" Series=""_series"" />";

    private string _stackedVerticalCode = @"<BarChart Categories=""_categories"" Series=""_stackedSeries"" Stacked=""true"" />";

    private string _horizontalCode = @"<BarChart Categories=""_regions"" Series=""_regionSeries"" Horizontal=""true"" />";

    private string _stackedCode = @"<BarChart Categories=""_categories"" Series=""_series"" Horizontal=""true"" Stacked=""true"" />";

    private string _labelsCode = @"<BarChart Categories=""_shortCategories"" Series=""_labelSeries"" ShowDataLabels=""true"" LabelPosition=""top"" />";

    private string _zoomCode = @"<BarChart Categories=""_months24"" Series=""_zoom24Series"" Colors=""_brandColors"" DataZoom=""true"" />";

    // --- Interactive label density demo ---
    private int _categoryCount = 12;
    private ChartLabelStrategy _strategy = ChartLabelStrategy.Smart;
    private List<string> _interactiveLabels = new();
    private List<BarChart.ChartSeriesData> _interactiveSeries = new();

    protected override void OnInitialized()
    {
        RebuildInteractive();
    }

    private void OnSliderChanged(double v)
    {
        _categoryCount = (int)v;
        RebuildInteractive();
    }

    private void OnStrategyChanged(string? value)
    {
        if (!string.IsNullOrEmpty(value) && Enum.TryParse<ChartLabelStrategy>(value, out var parsed))
        {
            _strategy = parsed;
        }
    }

    private void RebuildInteractive()
    {
        var months = new[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
        _interactiveLabels = new List<string>(_categoryCount);
        var values = new List<double>(_categoryCount);
        for (int i = 0; i < _categoryCount; i++)
        {
            var month = months[i % 12];
            var year = 24 + (i / 12); // 'Jan 24', 'Feb 24', ..., 'Jan 25', ...
            _interactiveLabels.Add($"{month} '{year}");
            // Deterministic fake values so the chart renders a clear wave.
            values.Add(Math.Round(60 + 40 * Math.Sin(i * 0.6) + (i * 1.5), 1));
        }
        _interactiveSeries = new List<BarChart.ChartSeriesData>
        {
            new() { Name = "Revenue (K)", Values = values }
        };
    }

    private string _interactiveCode = @"<Slider Min=""5"" Max=""36"" Value=""_categoryCount"" ValueChanged=""OnSliderChanged"" />
<ToggleGroup Value=""@_strategy.ToString()"" ValueChanged=""OnStrategyChanged"">
    <ToggleGroupItem Value=""Smart"">Smart</ToggleGroupItem>
    <ToggleGroupItem Value=""ShowAll"">ShowAll</ToggleGroupItem>
    <ToggleGroupItem Value=""Auto"">Auto</ToggleGroupItem>
</ToggleGroup>
<BarChart Categories=""@_interactiveLabels"" Series=""@_interactiveSeries"" LabelStrategy=""@_strategy"" Height=""300px"" />";

    // --- Loading state demo ---
    private bool _isLoading;
    private bool _keepLoading;
    // Skeleton shows whenever either toggle is active — simulate flips on for 2s, the switch
    // latches it permanently for inspection/design-review.
    private bool IsLoadingComputed => _isLoading || _keepLoading;
    private int _simulateBarDurationMs = 2000;
    private int _phantomBarCycleMs = 1400;

    private List<LineChart.ChartSeriesData> _loadingLineSeries = new()
    {
        new() { Name = "Revenue", Values = new() { 120, 148, 135, 172 } }
    };

    private List<PieChart.PieChartData> _loadingPieData = new()
    {
        new() { Name = "Direct",  Value = 42 },
        new() { Name = "Organic", Value = 31 },
        new() { Name = "Referral",Value = 18 },
        new() { Name = "Social",  Value = 9  }
    };

    private async Task SimulateLoadingAsync()
    {
        _isLoading = true;
        StateHasChanged();
        await Task.Delay(_simulateBarDurationMs);
        _isLoading = false;
        StateHasChanged();
    }

    private string _loadingCode = @"<Button OnClick=""SimulateLoadingAsync"" Disabled=""@_isLoading"">Simulate loading</Button>
<Switch @bind-Value=""_keepLoading"" />

<BarChart Categories=""_shortCategories"" Series=""_labelSeries"" IsLoading=""@IsLoadingComputed"" />
<LineChart Categories=""_shortCategories"" Series=""_loadingLineSeries"" IsLoading=""@IsLoadingComputed"" />
<PieChart Data=""_loadingPieData"" IsLoading=""@IsLoadingComputed"" />

@code {
    private bool _isLoading;
    private bool _keepLoading;
    private bool IsLoadingComputed => _isLoading || _keepLoading;

    private async Task SimulateLoadingAsync()
    {
        _isLoading = true;
        StateHasChanged();
        await Task.Delay(2000);
        _isLoading = false;
    }
}";
}
