Bar Chart - Interactive
Showing total visitors for the last 3 months
介绍 Charts。一组图表组件,你可以将它们复制并粘贴到你的应用中。
🌐 Introducing Charts. A collection of chart components that you can copy and paste into your apps.
图表设计时就具有很好的外观。它们与其他组件配合良好,并且可以完全自定义以适应你的项目。
🌐 Charts are designed to look great out of the box. They work well with the other components and are fully customizable to fit your project.
组件
🌐 Component
我们在底层使用 Unovis。
🌐 We use Unovis under the hood.
我们在设计 chart 组件时考虑到了组合性。你使用 Unovis 组件构建图表,只有在需要的时间和地点才引入自定义组件,例如 ChartTooltip。
🌐 We designed the chart component with composition in mind. You build your charts using Unovis components and only bring in custom components, such as ChartTooltip, when and where you need it.
<script setup lang="ts">
import { VisGroupedBar, VisXYContainer } from '@unovis/vue'
import { ChartContainer, ChartTooltipContent } from '@/components/ui/chart'
</script>
<template>
<ChartContainer :config="chartConfig">
<VisXYContainer :data="data">
<VisGroupedBar :x="(d) => d.month" :y="(d) => d.value" />
<ChartTooltip :template="componentToString(chartConfig, ChartTooltipContent)" />
</VisXYContainer>
</ChartContainer>
</template>我们不对 Unovis 进行封装。这意味着你不会被锁定在某种抽象中。当新的 Unovis 版本发布时,你可以按照官方升级路径升级你的图表。
🌐 We do not wrap Unovis. This means you're not locked into an abstraction. When a new Unovis version is released, you can follow the official upgrade path to upgrade your charts.
组件是你的。
安装
🌐 Installation
pnpm dlx shadcn-vue@latest add chart
用法
🌐 Usage
<script setup lang="ts">
import type { ChartConfig } from '@/components/ui/chart'
import { VisGroupedBar, VisXYContainer } from '@unovis/vue'
import {
ChartContainer,
ChartCrosshair,
ChartTooltip,
ChartTooltipContent,
componentToString,
} from '@/components/ui/chart'
const chartData = [
{ date: new Date("2024-01-01"), desktop: 186, mobile: 80 },
{ date: new Date("2024-02-01"), desktop: 305, mobile: 200 },
{ date: new Date("2024-03-01"), desktop: 237, mobile: 120 },
];
type Data = (typeof chartData)[number]
const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfig
</script>
<template>
<ChartContainer :config="chartConfig" class="min-h-[400px] w-full">
<VisXYContainer :data="chartData">
<VisGroupedBar
:x="(d: Data) => d.date"
:y="[(d: Data) => d.desktop, (d: Data) => d.mobile]"
:color="[chartConfig.desktop.color, chartConfig.mobile.color]"
/>
<ChartTooltip />
<ChartCrosshair
:template="
componentToString(chartConfig, ChartTooltipContent, {
labelFormatter(d) {
return new Date(d).toLocaleDateString('en-US', {
month: 'long',
});
},
})
"
:color="[chartConfig.desktop.color, chartConfig.mobile.color]"
/>
</VisXYContainer>
</ChartContainer>
</template>你的第一个图表
🌐 Your First Chart
让我们来创建你的第一个图表。我们将创建一个柱状图,添加网格、坐标轴、提示信息和图例。
🌐 Let's build your first chart. We'll build a bar chart, add a grid, axis, tooltip and legend.
::步骤 首先定义你的数据 ::
以下数据代表每个月的桌面和移动用户数量。
const chartData = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
]::步骤 定义你的图表配置 ::
图表配置保存图表的配置。在这里你可以放置可读的字符串,例如标签、图标和用于主题的颜色令牌。
import type { ChartConfig } from '@/components/ui/chart'
const chartConfig = {
desktop: {
label: 'Desktop',
color: 'var(--chart-1)',
},
mobile: {
label: 'Mobile',
color: 'var(--chart-2)',
},
} satisfies ChartConfig::步骤 构建你的图表 ::
你现在可以使用 Unovis 组件构建你的图表。
<script setup lang="ts">
import type { ChartConfig } from '@/components/ui/chart'
import { VisGroupedBar, VisXYContainer } from '@unovis/vue'
import { ChartContainer } from '@/components/ui/chart'
const chartData = [
{ date: new Date('2024-01-01'), desktop: 186, mobile: 80 },
{ date: new Date('2024-02-01'), desktop: 305, mobile: 200 },
{ date: new Date('2024-03-01'), desktop: 237, mobile: 120 },
{ date: new Date('2024-04-01'), desktop: 73, mobile: 190 },
{ date: new Date('2024-05-01'), desktop: 209, mobile: 130 },
{ date: new Date('2024-06-01'), desktop: 214, mobile: 140 },
]
type Data = typeof chartData[number]
const chartConfig = {
desktop: {
label: 'Desktop',
color: '#2563eb',
},
mobile: {
label: 'Mobile',
color: '#60a5fa',
},
} satisfies ChartConfig
</script>
<template>
<ChartContainer :config="chartConfig" class="min-h-[200px] w-full">
<VisXYContainer :data="chartData">
<VisGroupedBar
:x="(d: Data) => d.date"
:y="[(d: Data) => d.desktop, (d: Data) => d.mobile]"
:color="[chartConfig.desktop.color, chartConfig.mobile.color]"
:rounded-corners="4"
bar-padding="0.1"
group-padding="0"
/>
</VisXYContainer>
</ChartContainer>
</template><script setup lang="ts">
import type { ChartConfig } from '@/components/ui/chart'
import { VisGroupedBar, VisXYContainer } from '@unovis/vue'
import { ChartContainer } from '@/components/ui/chart'
const chartData = [
{ date: new Date('2024-01-01'), desktop: 186, mobile: 80 },
{ date: new Date('2024-02-01'), desktop: 305, mobile: 200 },
{ date: new Date('2024-03-01'), desktop: 237, mobile: 120 },
{ date: new Date('2024-04-01'), desktop: 73, mobile: 190 },
{ date: new Date('2024-05-01'), desktop: 209, mobile: 130 },
{ date: new Date('2024-06-01'), desktop: 214, mobile: 140 },
]
type Data = typeof chartData[number]
const chartConfig = {
desktop: {
label: 'Desktop',
color: '#2563eb',
},
mobile: {
label: 'Mobile',
color: '#60a5fa',
},
} satisfies ChartConfig
</script>
<template>
<ChartContainer :config="chartConfig" class="min-h-[200px] w-full">
<VisXYContainer :data="chartData">
<VisGroupedBar
:x="(d: Data) => d.date"
:y="[(d: Data) => d.desktop, (d: Data) => d.mobile]"
:color="[chartConfig.desktop.color, chartConfig.mobile.color]"
:rounded-corners="4"
bar-padding="0.1"
group-padding="0"
/>
</VisXYContainer>
</ChartContainer>
</template>添加轴
🌐 Add an Axis
要向图表添加坐标轴,我们使用 VisAxis 组件。
🌐 To add axes to the chart, we use the VisAxis component.
::步骤
导入 VisAxis 组件
::
import { VisAxis, VisGroupedBar, VisXYContainer } from '@unovis/vue'::步骤
将 VisAxis 组件添加到你的图表中
::
<template>
<VisAxis
type="x"
:x="(d: Data) => d.date"
:tick-line="false"
:domain-line="false"
:grid-line="false"
:tick-format="(d: number) => {
const date = new Date(d)
return date.toLocaleDateString('en-US', {
month: 'short',
})
}"
:tick-values="chartData.map(d => d.date)"
/>
<VisAxis
type="y"
:tick-format="(d: number) => ''"
:tick-line="false"
:domain-line="false"
:grid-line="true"
/>
</template><script setup lang="ts">
import type { ChartConfig } from '@/components/ui/chart'
import { VisAxis, VisGroupedBar, VisXYContainer } from '@unovis/vue'
import { ChartContainer } from '@/components/ui/chart'
const chartData = [
{ date: new Date('2024-01-01'), desktop: 186, mobile: 80 },
{ date: new Date('2024-02-01'), desktop: 305, mobile: 200 },
{ date: new Date('2024-03-01'), desktop: 237, mobile: 120 },
{ date: new Date('2024-04-01'), desktop: 73, mobile: 190 },
{ date: new Date('2024-05-01'), desktop: 209, mobile: 130 },
{ date: new Date('2024-06-01'), desktop: 214, mobile: 140 },
]
type Data = typeof chartData[number]
const chartConfig = {
desktop: {
label: 'Desktop',
color: '#2563eb',
},
mobile: {
label: 'Mobile',
color: '#60a5fa',
},
} satisfies ChartConfig
</script>
<template>
<ChartContainer :config="chartConfig" class="min-h-[200px] w-full">
<VisXYContainer :data="chartData">
<VisGroupedBar
:x="(d: Data) => d.date"
:y="[(d: Data) => d.desktop, (d: Data) => d.mobile]"
:color="[chartConfig.desktop.color, chartConfig.mobile.color]"
:rounded-corners="4"
bar-padding="0.1"
group-padding="0"
/>
<VisAxis
type="x"
:x="(d: Data) => d.date"
:tick-line="false"
:domain-line="false"
:grid-line="false"
:tick-format="(d: number) => {
const date = new Date(d)
return date.toLocaleDateString('en-US', {
month: 'short',
})
}"
:tick-values="chartData.map(d => d.date)"
/>
<VisAxis
type="y"
:tick-format="(d: number) => ''"
:tick-line="false"
:domain-line="false"
:grid-line="true"
/>
</VisXYContainer>
</ChartContainer>
</template>添加工具提示
🌐 Add Tooltip
要添加工具提示,我们将使用来自 chart 的自定义 ChartTooltip 和 ChartTooltipContent 组件。
🌐 To add a tooltip, we'll use the custom ChartTooltip and ChartTooltipContent components from chart.
::步骤
导入 ChartTooltip 和 ChartTooltipContent 组件
::
import { ChartTooltip, ChartTooltipContent, componentToString } from '@/components/ui/chart'::步骤 将组件添加到你的图表 ::
<ChartTooltip />
<ChartCrosshair :template="componentToString(chartConfig, ChartTooltipContent)" /><script setup lang="ts">
import type { ChartConfig } from '@/components/ui/chart'
import { VisAxis, VisGroupedBar, VisXYContainer } from '@unovis/vue'
import { ChartContainer, ChartCrosshair, ChartTooltip, ChartTooltipContent, componentToString } from '@/components/ui/chart'
const chartData = [
{ date: new Date('2024-01-01'), desktop: 186, mobile: 80 },
{ date: new Date('2024-02-01'), desktop: 305, mobile: 200 },
{ date: new Date('2024-03-01'), desktop: 237, mobile: 120 },
{ date: new Date('2024-04-01'), desktop: 73, mobile: 190 },
{ date: new Date('2024-05-01'), desktop: 209, mobile: 130 },
{ date: new Date('2024-06-01'), desktop: 214, mobile: 140 },
]
type Data = typeof chartData[number]
const chartConfig = {
desktop: {
label: 'Desktop',
color: '#2563eb',
},
mobile: {
label: 'Mobile',
color: '#60a5fa',
},
} satisfies ChartConfig
</script>
<template>
<ChartContainer :config="chartConfig" class="min-h-[200px] w-full">
<VisXYContainer :data="chartData">
<VisGroupedBar
:x="(d: Data) => d.date"
:y="[(d: Data) => d.desktop, (d: Data) => d.mobile]"
:color="[chartConfig.desktop.color, chartConfig.mobile.color]"
:rounded-corners="4"
bar-padding="0.1"
group-padding="0"
/>
<VisAxis
type="x"
:x="(d: Data) => d.date"
:tick-line="false"
:domain-line="false"
:grid-line="false"
:tick-format="(d: number) => {
const date = new Date(d)
return date.toLocaleDateString('en-US', {
month: 'short',
})
}"
:tick-values="chartData.map(d => d.date)"
/>
<VisAxis
type="y"
:tick-format="(d: number) => ''"
:tick-line="false"
:domain-line="false"
:grid-line="true"
/>
<ChartTooltip />
<ChartCrosshair
:template="componentToString(chartConfig, ChartTooltipContent, {
labelFormatter(d) {
return new Date(d).toLocaleDateString('en-US', {
month: 'long',
})
},
})"
:color="[chartConfig.desktop.color, chartConfig.mobile.color]"
/>
</VisXYContainer>
</ChartContainer>
</template>将鼠标悬停以查看工具提示。很简单,对吧?两个组件,我们就有了一个漂亮的工具提示。
添加图例
🌐 Add Legend
我们将对图例做同样的处理。我们将使用 chart 中的 ChartLegend 和 ChartLegendContent 组件。
🌐 We'll do the same for the legend. We'll use the ChartLegend and ChartLegendContent components from chart.
::步骤
导入 ChartLegendContent 组件。
::
import { ChartLegendContent } from '@/components/ui/chart'::步骤 将组件添加到你的图表中。 ::
<template>
<ChartContainer :config="chartConfig" class="min-h-[200px] w-full">
<VisXYContainer :data="chartData" />
<ChartLegendContent />
</ChartContainer>
</template><script setup lang="ts">
import type { ChartConfig } from '@/components/ui/chart'
import { VisAxis, VisGroupedBar, VisXYContainer } from '@unovis/vue'
import { ChartContainer, ChartCrosshair, ChartLegendContent, ChartTooltip, ChartTooltipContent, componentToString } from '@/components/ui/chart'
const chartData = [
{ date: new Date('2024-01-01'), desktop: 186, mobile: 80 },
{ date: new Date('2024-02-01'), desktop: 305, mobile: 200 },
{ date: new Date('2024-03-01'), desktop: 237, mobile: 120 },
{ date: new Date('2024-04-01'), desktop: 73, mobile: 190 },
{ date: new Date('2024-05-01'), desktop: 209, mobile: 130 },
{ date: new Date('2024-06-01'), desktop: 214, mobile: 140 },
]
type Data = typeof chartData[number]
const chartConfig = {
desktop: {
label: 'Desktop',
color: '#2563eb',
},
mobile: {
label: 'Mobile',
color: '#60a5fa',
},
} satisfies ChartConfig
</script>
<template>
<ChartContainer :config="chartConfig" class="min-h-[200px] w-full">
<VisXYContainer :data="chartData">
<VisGroupedBar
:x="(d: Data) => d.date"
:y="[(d: Data) => d.desktop, (d: Data) => d.mobile]"
:color="[chartConfig.desktop.color, chartConfig.mobile.color]"
:rounded-corners="4"
bar-padding="0.1"
group-padding="0"
/>
<VisAxis
type="x"
:x="(d: Data) => d.date"
:tick-line="false"
:domain-line="false"
:grid-line="false"
:tick-format="(d: number) => {
const date = new Date(d)
return date.toLocaleDateString('en-US', {
month: 'short',
})
}"
:tick-values="chartData.map(d => d.date)"
/>
<VisAxis
type="y"
:tick-format="(d: number) => ''"
:tick-line="false"
:domain-line="false"
:grid-line="true"
/>
<ChartTooltip />
<ChartCrosshair
:template="componentToString(chartConfig, ChartTooltipContent, {
labelFormatter(d) {
return new Date(d).toLocaleDateString('en-US', {
month: 'long',
})
},
})"
:color="[chartConfig.desktop.color, chartConfig.mobile.color]"
/>
</VisXYContainer>
<ChartLegendContent />
</ChartContainer>
</template>完成了。你已经创建了你的第一个图表!接下来做什么?
🌐 Done. You've built your first chart! What's next?
图表配置
🌐 Chart Config
图表配置是你定义图表的标签、图标和颜色的地方。
🌐 The chart config is where you define the labels, icons and colors for a chart.
它有意与图表数据分离。
🌐 It is intentionally decoupled from chart data.
这允许你在图表之间共享配置和颜色令牌。对于数据或颜色令牌存储在远程或不同格式的情况,它也可以独立工作。
🌐 This allows you to share config and color tokens between charts. It can also works independently for cases where your data or color tokens live remotely or in a different format.
<script setup lang="ts">
import type { ChartConfig } from '@/components/ui/chart'
import { Monitor } from 'lucide-vue-next'
const chartConfig = {
desktop: {
label: 'Desktop',
icon: Monitor,
// A color like 'hsl(220, 98%, 61%)' or 'var(--color-name)'
color: 'var(--chart-1)',
// OR a theme object with 'light' and 'dark' keys
theme: {
light: 'var(--chart-1)',
dark: 'var(--chart-2)',
},
},
} satisfies ChartConfig
</script>主题
🌐 Theming
Charts 内置了对主题的支持。你可以使用 CSS 变量(推荐)或任何颜色格式的颜色值,例如 hex、hsl 或 oklch。
🌐 Charts has built-in support for theming. You can use css variables (recommended) or color values in any color format, such as hex, hsl or oklch.
CSS 变量
🌐 CSS Variables
::步骤 在你的 CSS 文件中定义你的颜色 ::
@layer base {
:root {
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
}
}::步骤
将颜色添加到你的 chartConfig
::
const chartConfig = {
desktop: {
label: 'Desktop',
color: 'var(--chart-1)',
},
mobile: {
label: 'Mobile',
color: 'var(--chart-2)',
},
} satisfies ChartConfighex、hsl 或 oklch
🌐 hex, hsl or oklch
你也可以直接在图表配置中定义颜色。使用你喜欢的颜色格式。
🌐 You can also define your colors directly in the chart config. Use the color format you prefer.
const chartConfig = {
desktop: {
label: 'Desktop',
color: '#2563eb',
},
} satisfies ChartConfig使用颜色
🌐 Using Colors
要在图表中使用主题颜色,请使用 var(--color-KEY) 格式引用颜色。
🌐 To use the theme colors in your chart, reference the colors using the format var(--color-KEY).
组件
🌐 Components
<VisGroupedBar
:x="(d) => d.month"
:y="(d) => d.desktop"
color="var(--color-desktop)"
/>图表数据
🌐 Chart Data
const chartData = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
]工具提示
🌐 Tooltip
图表提示包含标签、名称、指示器和值。你可以组合使用这些元素来自定义提示。
🌐 A chart tooltip contains a label, name, indicator and value. You can use a combination of these to customize your tooltip.
你可以使用 hideLabel、hideIndicator 属性开启或关闭其中的任何一个,并使用 indicator 属性自定义指示器样式。
🌐 You can turn on/off any of these using the hideLabel, hideIndicator props and customize the indicator style using the indicator prop.
使用 labelKey 和 nameKey 来为工具提示标签和名称使用自定义键。
🌐 Use labelKey and nameKey to use a custom key for the tooltip label and name.
图表附带 ChartTooltip 和 ChartTooltipContent 组件。你可以使用这两个组件为图表添加自定义提示信息。
🌐 Chart comes with the ChartTooltip and ChartTooltipContent components. You can use these two components to add custom tooltips to your chart.
import { ChartTooltip, ChartTooltipContent } from '@/components/ui/chart'<template>
<ChartTooltip />
<ChartCrosshair
:template="componentToString(chartConfig, ChartTooltipContent)"
/>
</template>属性
🌐 Props
使用以下属性自定义工具提示。
🌐 Use the following props to customize the tooltip.
| 属性 | 类型 | 描述 |
|---|---|---|
labelKey | 字符串 | 用于标签的配置或数据键。 |
nameKey | 字符串 | 用于名称的配置或数据键。 |
indicator | dot line 或 dashed | 工具提示的指示器样式。 |
hideLabel | 布尔值 | 是否隐藏标签。 |
hideIndicator | 布尔值 | 是否隐藏指示器。 |
颜色
🌐 Colors
颜色自动从图表配置中引用。
🌐 Colors are automatically referenced from the chart config.
自定义
🌐 Custom
要为工具提示标签和名称使用自定义键,请使用 labelKey 和 nameKey 属性。
🌐 To use a custom key for tooltip label and names, use the labelKey and nameKey props.
const chartData = [
{ browser: 'chrome', visitors: 187, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
]
const chartConfig = {
visitors: {
label: 'Total Visitors',
},
chrome: {
label: 'Chrome',
color: 'var(--chart-1)',
},
safari: {
label: 'Safari',
color: 'var(--chart-2)',
},
} satisfies ChartConfig<template>
<ChartCrosshair
:template="componentToString(chartConfig, ChartTooltipContent, {
labelKey: 'visitors',
nameKey: 'browser',
})"
/>
</template>这将使用 Total Visitors 作为标签,Chrome 和 Safari 作为工具提示名称。
🌐 This will use Total Visitors for label and Chrome and Safari for the tooltip names.
图例
🌐 Legend
你可以使用自定义 <ChartLegendContent> 组件为你的图表添加图例。
🌐 You can use the custom <ChartLegendContent> components to add a legend to your chart.
import { ChartLegendContent } from '@/components/ui/chart'<template>
<ChartLegendContent />
</template>颜色
🌐 Colors
颜色自动从图表配置中引用。
🌐 Colors are automatically referenced from the chart config.
自定义
🌐 Custom
要为图例名称使用自定义键,请使用 nameKey 属性。
🌐 To use a custom key for legend names, use the nameKey prop.
const chartData = [
{ browser: 'chrome', visitors: 187, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
]
const chartConfig = {
chrome: {
label: 'Chrome',
color: 'hsl(var(--chart-1))',
},
safari: {
label: 'Safari',
color: 'hsl(var(--chart-2))',
},
} satisfies ChartConfig<template>
<ChartLegendContent name-key="browser" />
</template>这将使用 Chrome 和 Safari 作为图例名称。
🌐 This will use Chrome and Safari for the legend names.