关于 visx
visx 是基于 D3 基础组件构建自定义数据可视化的 React 库。这项入门技能提供图表模式,适合需要交互式、响应式图表并有特定仪表板设计要求的开发者。
主要功能
- 01基于 D3 基础组件的 React 组件
- 02折线图与柱状图模式
- 03响应式图表容器
- 04工具提示交互模式
- 05SVG 样式指导
适用场景
- 01创建自定义交互式图表
- 02构建仪表板可视化
- 03制作适配容器的响应式图表
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ cerico/ macfair --skill visx安装后在 Claude Code 中输入/visx确认已加载。
详细介绍
visx
使用 visx(Airbnb 的 React + D3 库)通过 React 构建数据可视化。
状态:起步阶段
模式会随着使用不断演进。
适用场景
- 构建超出基础图表库能力范围的自定义图表
- 交互式数据探索
- 有特定设计要求的仪表板
- 需要 D3 的强大能力并遵循 React 模式
为什么选择 visx,而非其他方案
| 库 | 适用场景 |
|---|---|
| visx | 自定义、交互式、设计特定的图表 |
| Recharts | 快速构建标准图表 |
| Chart.js | 简单的基于画布的图表 |
| D3 direct | 需要最大控制力,且不使用 React |
visx = 以 React 组件形式提供的 D3 基础构件。完全可控,适配 React。
设置
# Core
pnpm add @visx/group @visx/scale @visx/shape @visx/axis @visx/grid
# Common additions
pnpm add @visx/tooltip @visx/responsive @visx/gradient @visx/curve
# All of visx (larger bundle)
pnpm add @visx/visx
基础模式
折线图
import { LinePath } from '@visx/shape'
import { scaleLinear, scaleTime } from '@visx/scale'
import { AxisBottom, AxisLeft } from '@visx/axis'
import { Group } from '@visx/group'
interface DataPoint {
date: Date
value: number
}
const data: DataPoint[] = [
{ date: new Date('2024-01'), value: 10 },
{ date: new Date('2024-02'), value: 25 },
{ date: new Date('2024-03'), value: 15 },
]
const width = 600
const height = 400
const margin = { top: 20, right: 20, bottom: 40, left: 40 }
const innerWidth = width - margin.left - margin.right
const innerHeight = height - margin.top - margin.bottom
const xScale = scaleTime({
domain: [Math.min(...data.map(d => d.date)), Math.max(...data.map(d => d.date))],
range: [0, innerWidth],
})
const yScale = scaleLinear({
domain: [0, Math.max(...data.map(d => d.value))],
range: [innerHeight, 0],
})
export function LineChart() {
return (
<svg width={width} height={height}>
<Group left={margin.left} top={margin.top}>
<AxisBottom scale={xScale} top={innerHeight} />
<AxisLeft scale={yScale} />
<LinePath
data={data}
x={d => xScale(d.date)}
y={d => yScale(d.value)}
stroke="currentColor"
strokeWidth={2}
/>
</Group>
</svg>
)
}
柱状图
import { Bar } from '@visx/shape'
import { scaleBand, scaleLinear } from '@visx/scale'
import { Group } from '@visx/group'
interface DataPoint {
label: string
value: number
}
const data: DataPoint[] = [
{ label: 'A', value: 30 },
{ label: 'B', value: 80 },
{ label: 'C', value: 45 },
]
const xScale = scaleBand({
domain: data.map(d => d.label),
range: [0, innerWidth],
padding: 0.2,
})
const yScale = scaleLinear({
domain: [0, Math.max(...data.map(d => d.value))],
range: [innerHeight, 0],
})
export function BarChart() {
return (
<svg width={width} height={height}>
<Group left={margin.left} top={margin.top}>
{data.map(d => (
<Bar
key={d.label}
x={xScale(d.label)}
y={yScale(d.value)}
width={xScale.bandwidth()}
height={innerHeight - yScale(d.value)}
fill="currentColor"
/>
))}
</Group>
</svg>
)
}
响应式容器
import { ParentSize } from '@visx/responsive'
export function ResponsiveChart() {
return (
<ParentSize>
{({ width, height }) => (
<LineChart width={width} height={height} />
)}
</ParentSize>
)
}
工具提示
import { useTooltip, TooltipWithBounds } from '@visx/tooltip'
import { localPoint } from '@visx/event'
const { showTooltip, hideTooltip, tooltipData, tooltipLeft, tooltipTop } = useTooltip()
// In your component:
<circle
onMouseMove={(event) => {
const point = localPoint(event)
showTooltip({
tooltipData: dataPoint,
tooltipLeft: point.x,
tooltipTop: point.y,
})
}}
onMouseLeave={hideTooltip}
/>
{tooltipData && (
<TooltipWithBounds left={tooltipLeft} top={tooltipTop}>
{tooltipData.value}
</TooltipWithBounds>
)}
使用 Tailwind 设置样式
visx 会渲染 SVG,可通过 className 或内联样式设置样式:
<LinePath
stroke="hsl(var(--primary))"
className="transition-all duration-200"
/>
参考资料
- visx 文档:https://airbnb.io/visx/
- visx 图库:https://airbnb.io/visx/gallery
- D3 比例尺:https://github.com/d3/d3-scale
待办事项
- 构建首个真实图表以确立模式
- 添加面积图模式
- 添加饼图/环形图模式
- 添加动画模式
- 与 tRPC 数据获取集成
评论
支持 Markdown