chart
Lighthouse scores radial with labels
Lighthouse scores radial with labels
Загрузка превью…
src/chart/c-chart-25.vue
<!--
Пробел в API: у vue-chrts нет `RadialBarChart` (recharts: несколько
концентричных дуг, каждая растёт от 0 независимо, вложенные кольца одной
толщины) — см. docs/PORTING.md §19/§27, список компонентов vue-chrts не
содержит ничего радиального, кроме `DonutChart` (полный круг делится на
сегменты-дуги подряд, а не концентрические независимые кольца). Взят
`DonutChart` как ближайший из существующих полярных примитивов —
структурно другой график (сегменты вместо колец), расхождение заведомо
значительное и осознанное, не подгонка под зелёный гейт. Glow-фильтр и
per-category линейные градиенты не переносятся (та же причина, что у
c-chart-19.vue). `ChartLegend` — всегда видимая часть кадра, легенда
воспроизведена через `ChartLegendContent` с ручным `payload`.
-->
<script setup lang="ts">
import { DonutChart } from "vue-chrts"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { ChartContainer, ChartLegendContent, type ChartConfig } from "@/components/ui/chart"
const chartData = [
{ name: "mobile", score: 58 },
{ name: "desktop", score: 76 },
{ name: "api", score: 92 },
]
const chartConfig = {
score: { label: "Score" },
mobile: { label: "Mobile", color: "var(--chart-4)" },
desktop: { label: "Desktop", color: "var(--chart-2)" },
api: { label: "API", color: "var(--chart-1)" },
} satisfies ChartConfig
const categories = {
mobile: { name: "Mobile", color: "var(--chart-4)" },
desktop: { name: "Desktop", color: "var(--chart-2)" },
api: { name: "API", color: "var(--chart-1)" },
}
const donutData = chartData.map((d) => d.score)
const legendPayload = [
{ dataKey: "mobile", value: "mobile", color: "var(--chart-4)", name: "mobile" },
{ dataKey: "desktop", value: "desktop", color: "var(--chart-2)", name: "desktop" },
{ dataKey: "api", value: "api", color: "var(--chart-1)", name: "api" },
]
</script>
<template>
<Card class="w-full max-w-xs">
<CardHeader class="items-center pb-0">
<CardTitle>Lighthouse Scores</CardTitle>
<CardDescription>Performance audit by platform</CardDescription>
</CardHeader>
<CardContent class="flex-1 pb-0">
<!--
`recharts`' `.recharts-legend-wrapper` is `position: absolute` inside
the SAME fixed-height chart box — see c-chart-20.vue for the full
explanation. Placed as an absolute sibling in the same
`ChartContainer` instead of a second, normal-flow one.
-->
<ChartContainer :config="chartConfig" class="relative mx-auto aspect-square max-h-[300px]">
<DonutChart
:data="donutData"
:categories="categories"
:radius="110"
:arc-width="22"
:pad-angle="0.02"
:height="300"
:duration="0"
hide-tooltip
hide-legend
/>
<ChartLegendContent :payload="legendPayload" name-key="name" class="absolute inset-x-0 bottom-0 -translate-y-2 pt-0" />
</ChartContainer>
</CardContent>
</Card>
</template>