Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new

Chart

Displays data through chart compositions, legends, and tooltips.

Interactive preview

Rendered from the shared Frontfriend stories with React Base, the same preview Studio shows. Styling comes from your Design System; the code below is native to Reka UI.

Installation

Complete project setup first. Your configuration must select vue/reka and include your Design System ID.

pnpm exec frontfriend download chart -f vue --primitive reka

Review dependencies reported by the downloader and keep your source changes in version control.

Usage

<script setup lang="ts">
import { ChartContainer } from "@/components/ui/chart";
import { ChartLegendContent } from "@/components/ui/chart";
import * as UI from "@/components/ui/chart";

const chartConfig = {
  desktop: { label: "Desktop", color: "#0067BB" },
  mobile: { label: "Mobile", color: "#B9EAFE" },
  visitors: { label: "Visitors", color: "#16A34A" },
};

const Component = UI.ChartContainer;

const args = {
  "config": chartConfig,
  "height": 280,
  "showLegend": true,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <ChartContainer
    :config="args.config"
    :style="{ width: '500px', maxWidth: '100%', height: args.height + 'px' }"
    ><svg
      viewBox="0 0 300 200"
      role="img"
      aria-label="Monthly desktop and mobile usage"
      class="w-full h-full"
    >
      <g v-for="(value, index) in [100, 160, 130, 40, 110, 115]" :key="index">
        <rect
          :x="index * 50 + 4"
          :y="180 - value"
          width="18"
          :height="value"
          :fill="args.config.desktop.color"
        />
        <rect
          :x="index * 50 + 24"
          :y="180 - value / 2"
          width="18"
          :height="value / 2"
          :fill="args.config.mobile.color"
        />
      </g></svg
    ><ChartLegendContent v-if="args.showLegend"
      >{{ args.config.desktop.label }} ·
      {{ args.config.mobile.label }}</ChartLegendContent
    ></ChartContainer
  >
</template>

No component-specific props are declared in registry metadata; inherited HTML/Radix/Reka props are supported by the component implementation.

Subcomponents

  • ChartContainer
  • ChartLegendContent
  • ChartTooltipContent

Examples

Default

<script setup lang="ts">
import { Card } from "@/components/ui/card";
import { ChartContainer } from "@/components/ui/chart";
import { ChartLegendContent } from "@/components/ui/chart";
import * as UI from "@/components/ui/chart";

const chartConfig = {
  desktop: { label: "Desktop", color: "#0067BB" },
  mobile: { label: "Mobile", color: "#B9EAFE" },
  visitors: { label: "Visitors", color: "#16A34A" },
};

const Component = UI.ChartContainer;

const args = {
  "config": chartConfig,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <Card class="w-[500px] max-w-full h-[500px] p-4"
    ><ChartContainer :config="chartConfig" class="w-full h-[304px] relative"
      ><svg viewBox="0 0 300 160" class="w-full h-full">
        <polygon
          points="0,140 50,90 100,110 150,50 200,80 250,40 300,70 300,160 0,160"
          fill="#B9EAFE"
          opacity="0.6"
        />
        <polyline
          points="0,140 50,90 100,110 150,50 200,80 250,40 300,70"
          fill="none"
          stroke="#0067BB"
          stroke-width="2"
        /></svg
      ><ChartLegendContent
        >Desktop &middot; Mobile</ChartLegendContent
      ></ChartContainer
    ></Card
  >
</template>

Bar Chart Example

<script setup lang="ts">
import { Card } from "@/components/ui/card";
import { ChartContainer } from "@/components/ui/chart";
import { ChartLegendContent } from "@/components/ui/chart";
import * as UI from "@/components/ui/chart";

const chartConfig = {
  desktop: { label: "Desktop", color: "#0067BB" },
  mobile: { label: "Mobile", color: "#B9EAFE" },
  visitors: { label: "Visitors", color: "#16A34A" },
};

const Component = UI.ChartContainer;

const args = {
  "config": chartConfig,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <Card class="w-[500px] max-w-full h-[500px] p-4"
    ><ChartContainer
      :config="chartConfig"
      class="mx-auto aspect-square h-[400px] w-full"
      ><div class="flex h-[320px] items-end justify-around gap-2">
        <div class="w-8 rounded bg-[#0067BB]" style="height: 60%" />
        <div class="w-8 rounded bg-[#0067BB]" style="height: 90%" />
        <div class="w-8 rounded bg-[#0067BB]" style="height: 75%" />
        <div class="w-8 rounded bg-[#0067BB]" style="height: 40%" />
        <div class="w-8 rounded bg-[#0067BB]" style="height: 65%" />
        <div class="w-8 rounded bg-[#0067BB]" style="height: 70%" />
      </div>
      <ChartLegendContent>Desktop</ChartLegendContent></ChartContainer
    ></Card
  >
</template>

Pie Chart Example

<script setup lang="ts">
import { Card } from "@/components/ui/card";
import { ChartContainer } from "@/components/ui/chart";
import { ChartLegendContent } from "@/components/ui/chart";
import * as UI from "@/components/ui/chart";

const chartConfig = {
  desktop: { label: "Desktop", color: "#0067BB" },
  mobile: { label: "Mobile", color: "#B9EAFE" },
  visitors: { label: "Visitors", color: "#16A34A" },
};

const Component = UI.ChartContainer;

const args = {
  "config": chartConfig,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <Card class="w-[500px] max-w-full h-[500px] p-4"
    ><ChartContainer
      :config="chartConfig"
      class="mx-auto aspect-square h-[400px] w-full relative"
      ><svg viewBox="0 0 120 120" class="mx-auto h-[320px]">
        <circle
          cx="60"
          cy="60"
          r="50"
          fill="transparent"
          stroke="#16A34A"
          stroke-width="20"
          stroke-dasharray="120 314"
        />
        <circle
          cx="60"
          cy="60"
          r="50"
          fill="transparent"
          stroke="#B9EAFE"
          stroke-width="20"
          stroke-dasharray="80 314"
          stroke-dashoffset="-120"
        />
        <circle
          cx="60"
          cy="60"
          r="50"
          fill="transparent"
          stroke="#DC2626"
          stroke-width="20"
          stroke-dasharray="114 314"
          stroke-dashoffset="-200"
        /></svg
      ><ChartLegendContent
        >Chrome &middot; Safari &middot; Firefox</ChartLegendContent
      ></ChartContainer
    ></Card
  >
</template>

Line Chart Example

<script setup lang="ts">
import { Card } from "@/components/ui/card";
import { ChartContainer } from "@/components/ui/chart";
import { ChartLegendContent } from "@/components/ui/chart";
import * as UI from "@/components/ui/chart";

const chartConfig = {
  desktop: { label: "Desktop", color: "#0067BB" },
  mobile: { label: "Mobile", color: "#B9EAFE" },
  visitors: { label: "Visitors", color: "#16A34A" },
};

const Component = UI.ChartContainer;

const args = {
  "config": chartConfig,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <Card class="w-[500px] max-w-full h-[500px] p-4"
    ><ChartContainer
      :config="chartConfig"
      class="mx-auto aspect-square h-[400px] w-full"
      ><svg viewBox="0 0 300 160" class="w-full h-[320px]">
        <polyline
          points="0,120 50,60 100,90 150,130 200,70 250,50 300,80"
          fill="none"
          stroke="#0067BB"
          stroke-width="2"
        /></svg
      ><ChartLegendContent>Desktop</ChartLegendContent></ChartContainer
    ></Card
  >
</template>

Radar Chart Example

<script setup lang="ts">
import { Card } from "@/components/ui/card";
import { ChartContainer } from "@/components/ui/chart";
import { ChartLegendContent } from "@/components/ui/chart";
import * as UI from "@/components/ui/chart";

const chartConfig = {
  desktop: { label: "Desktop", color: "#0067BB" },
  mobile: { label: "Mobile", color: "#B9EAFE" },
  visitors: { label: "Visitors", color: "#16A34A" },
};

const Component = UI.ChartContainer;

const args = {
  "config": chartConfig,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <Card class="w-[500px] max-w-full h-[500px] p-4"
    ><ChartContainer
      :config="chartConfig"
      class="mx-auto aspect-square h-[400px] w-full"
      ><svg viewBox="0 0 200 200" class="mx-auto h-[320px]">
        <polygon
          points="100,20 170,70 150,160 50,160 30,70"
          fill="none"
          stroke="#cbd5e1"
          stroke-width="1"
        />
        <polygon
          points="100,50 145,80 130,140 70,140 60,80"
          fill="#0067BB"
          fill-opacity="0.6"
          stroke="#0067BB"
        /></svg
      ><ChartLegendContent>Desktop</ChartLegendContent></ChartContainer
    ></Card
  >
</template>

Radial Chart Example

<script setup lang="ts">
import { Card } from "@/components/ui/card";
import { ChartContainer } from "@/components/ui/chart";
import { ChartLegendContent } from "@/components/ui/chart";
import * as UI from "@/components/ui/chart";

const chartConfig = {
  desktop: { label: "Desktop", color: "#0067BB" },
  mobile: { label: "Mobile", color: "#B9EAFE" },
  visitors: { label: "Visitors", color: "#16A34A" },
};

const Component = UI.ChartContainer;

const args = {
  "config": chartConfig,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <Card class="w-[500px] max-w-full h-[500px] p-4"
    ><ChartContainer
      :config="chartConfig"
      class="mx-auto aspect-square h-[400px] w-full"
      ><svg viewBox="0 0 120 120" class="mx-auto h-[320px]">
        <circle
          cx="60"
          cy="60"
          r="50"
          fill="transparent"
          stroke="#16A34A"
          stroke-width="8"
          stroke-dasharray="220 314"
        />
        <circle
          cx="60"
          cy="60"
          r="38"
          fill="transparent"
          stroke="#B9EAFE"
          stroke-width="8"
          stroke-dasharray="150 239"
        />
        <circle
          cx="60"
          cy="60"
          r="26"
          fill="transparent"
          stroke="#DC2626"
          stroke-width="8"
          stroke-dasharray="120 163"
        /></svg
      ><ChartLegendContent>Visitors</ChartLegendContent></ChartContainer
    ></Card
  >
</template>

API reference

Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Reka UI.

ChartContainer

Prop Type Default Description
class HTMLAttributes["class"] —
config ChartConfig —
cursor boolean —
id HTMLAttributes["id"] —

ChartLegendContent

Prop Type Default Description
class HTMLAttributes["class"] —
hideIcon boolean —
nameKey string —
verticalAlign "bottom" | "top" —

ChartStyle

Prop Type Default Description
id HTMLAttributes["id"] —

ChartTooltipContent

Prop Type Default Description
class HTMLAttributes["class"] —
color string —
config ChartConfig —
hideIndicator boolean —
hideLabel boolean —
indicator "line" | "dot" | "dashed" —
labelFormatter (d: number | Date) => string —
labelKey string —
nameKey string —
payload Record<string, any> —
x number | Date —

Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.