Spaces:
Runtime error
Runtime error
Download TaskTrackingSystem.WebApp/Components/Shared/Charts/DonutChart.razor from Yuruyuruu/task-tracking-system: direct link, hf CLI and curl.
- Browser
- Download file 3.82 kB
-
https://huggingface.co/spaces/Yuruyuruu/task-tracking-system/resolve/main/TaskTrackingSystem.WebApp/Components/Shared/Charts/DonutChart.razor
- Command line
-
hf download hf://spaces/Yuruyuruu/task-tracking-system/TaskTrackingSystem.WebApp/Components/Shared/Charts/DonutChart.razor
-
curl -L -o DonutChart.razor https://huggingface.co/spaces/Yuruyuruu/task-tracking-system/resolve/main/TaskTrackingSystem.WebApp/Components/Shared/Charts/DonutChart.razor
3.82 kB
| TaskTrackingSystem.WebApp.Components.Shared.Charts | |
| <div class="@WrapperClass"> | |
| (!Items.Any() || Items.Sum(item => item.Value) <= 0) | |
| { | |
| <div class="flex h-56 items-center justify-center text-sm text-slate-400">@EmptyText</div> | |
| } | |
| else | |
| { | |
| <div class="flex justify-center"> | |
| <svg viewBox="0 0 190 190" class="h-56 w-56" role="img" aria-label="Task distribution pie chart"> | |
| @foreach (var slice in Slices) | |
| { | |
| if (slice.IsFullCircle) | |
| { | |
| <circle cx="95" cy="95" r="72" fill="@slice.Color" stroke="var(--surface)" stroke-width="2" /> | |
| } | |
| else | |
| { | |
| <path d="@slice.Path" fill="@slice.Color" stroke="var(--surface)" stroke-width="2" stroke-linejoin="round" /> | |
| } | |
| } | |
| </svg> | |
| </div> | |
| (ShowLegend) | |
| { | |
| <div class="mt-3 space-y-3"> | |
| @foreach (var item in Items) | |
| { | |
| <div class="flex items-center justify-between rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3"> | |
| <div class="flex items-center gap-3"> | |
| <span class="h-3 w-3 rounded-full" style="background-color: @item.Color"></span> | |
| <span class="text-sm text-slate-600">@item.Label</span> | |
| </div> | |
| <span class="text-sm font-semibold text-slate-900">@AppLocalization.Number(item.Value, ValueFormat)</span> | |
| </div> | |
| } | |
| </div> | |
| } | |
| } | |
| </div> | |
| { | |
| [Parameter] public IReadOnlyList<ChartDataPoint> Items { get; set; } = Array.Empty<ChartDataPoint>(); | |
| [Parameter] public bool ShowLegend { get; set; } = true; | |
| [Parameter] public string EmptyText { get; set; } = AppLocalization.Text("report.noChartData", "No data available."); | |
| [Parameter] public string ValueFormat { get; set; } = "0"; | |
| [Parameter] public string WrapperClass { get; set; } = string.Empty; | |
| private IReadOnlyList<Slice> Slices => BuildSlices(); | |
| private IReadOnlyList<Slice> BuildSlices() | |
| { | |
| const double center = 95; | |
| const double radius = 72; | |
| var total = Items.Sum(item => Math.Max(0, item.Value)); | |
| var startAngle = -90.0; | |
| var slices = new List<Slice>(); | |
| foreach (var item in Items) | |
| { | |
| var value = Math.Max(0, item.Value); | |
| if (value <= 0 || total <= 0) | |
| { | |
| continue; | |
| } | |
| var sweep = 360 * value / total; | |
| var endAngle = startAngle + sweep; | |
| if (sweep >= 359.999) | |
| { | |
| slices.Add(new Slice(item.Color, string.Empty, true)); | |
| startAngle = endAngle; | |
| continue; | |
| } | |
| var start = PointOnCircle(center, center, radius, startAngle); | |
| var end = PointOnCircle(center, center, radius, endAngle); | |
| var largeArc = sweep > 180 ? 1 : 0; | |
| var path = $"M {center:0.##} {center:0.##} L {start.X:0.##} {start.Y:0.##} A {radius:0.##} {radius:0.##} 0 {largeArc} 1 {end.X:0.##} {end.Y:0.##} Z"; | |
| slices.Add(new Slice(item.Color, path, false)); | |
| startAngle = endAngle; | |
| } | |
| return slices; | |
| } | |
| private static (double X, double Y) PointOnCircle(double centerX, double centerY, double radius, double angleDegrees) | |
| { | |
| var radians = angleDegrees * Math.PI / 180; | |
| return (centerX + radius * Math.Cos(radians), centerY + radius * Math.Sin(radians)); | |
| } | |
| private sealed record Slice(string Color, string Path, bool IsFullCircle); | |
| } | |