chart

Donut chart with center total

Donut chart with center total

Загрузка превью…

src/chart/c-chart-19.vue

<!--
  Замена библиотеки: см. docs/PORTING.md §19/§27. Тело графика — `DonutChart`
  из `vue-chrts` вместо recharts `Pie`. Иное API: `data` — плоский массив
  чисел (не объекты), сегменты сопоставляются `categories` по индексу.
  3D drop-shadow фильтр и per-segment линейные градиенты не переносятся —
  `DonutChart` красит сегмент одним цветом из `categories`, без `url(#...)`.
  Центральная надпись (сумма/подпись) воспроизведена через default-слот
  `DonutChart`, который абсолютно позиционируется поверх графика — тот же
  приём, что и в оригинале (`Label content` внутри `Pie`).
-->
<script setup lang="ts">
import { DonutChart } from "vue-chrts"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { ChartContainer, type ChartConfig } from "@/components/ui/chart"

const chartData = [
  { source: "direct", visits: 4200 },
  { source: "search", visits: 3600 },
  { source: "social", visits: 2800 },
  { source: "email", visits: 1900 },
  { source: "referral", visits: 1400 },
]

const total = chartData.reduce((s, d) => s + d.visits, 0)

const chartConfig = {
  visits: { label: "Visits" },
  direct: { label: "Direct", color: "var(--chart-1)" },
  search: { label: "Search", color: "var(--chart-2)" },
  social: { label: "Social", color: "var(--chart-3)" },
  email: { label: "Email", color: "var(--chart-4)" },
  referral: { label: "Referral", color: "var(--chart-5)" },
} satisfies ChartConfig

const categories = {
  direct: { name: "Direct", color: "var(--chart-1)" },
  search: { name: "Search", color: "var(--chart-2)" },
  social: { name: "Social", color: "var(--chart-3)" },
  email: { name: "Email", color: "var(--chart-4)" },
  referral: { name: "Referral", color: "var(--chart-5)" },
}

const donutData = chartData.map((d) => d.visits)
</script>

<template>
  <Card class="w-full max-w-xs">
    <CardHeader class="items-center pb-0">
      <CardTitle>Traffic Sources</CardTitle>
      <CardDescription>Where your visitors come from</CardDescription>
    </CardHeader>
    <CardContent class="flex-1 pb-0">
      <ChartContainer :config="chartConfig" class="mx-auto aspect-square max-h-[280px]">
        <DonutChart
          :data="donutData"
          :categories="categories"
          :radius="95"
          :arc-width="30"
          :pad-angle="0.02"
          :height="280"
          :duration="0"
          hide-tooltip
          hide-legend
        >
          <div class="flex flex-col items-center">
            <span class="fill-foreground text-3xl font-bold tabular-nums">{{ (total / 1000).toFixed(1) }}k</span>
            <span class="fill-muted-foreground text-xs">Total Visits</span>
          </div>
        </DonutChart>
      </ChartContainer>
    </CardContent>
  </Card>
</template>

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-chart-19.json

Зависимости реестра

npm-зависимости

  • vue-chrts

Источник: порт из ReUI (Keenthemes, MIT)