数据可视化组件库
用于展示复杂数据的图表、进度条和统计面板。
组件配额 3
状态 ACTIVE
01. 贡献热力图 (Heatmap)
类似 GitHub 的提交记录热力图,展示数据频率。
Activity Heatmap
Less More
---
interface Props {
data?: number[];
cellSize?: number;
gap?: number;
colors?: string[];
title?: string;
}
const {
data = Array.from({ length: 35 }).map(() => Math.floor(Math.random() * 5)),
cellSize = 14,
gap = 4,
colors = ['#161b22', '#0e4429', '#006d32', '#26a641', '#39d353'],
title = "Activity Heatmap"
} = Astro.props;
---
<div class="heatmap-container">
{title && <div class="heatmap-title">{title}</div>}
<div class="heatmap-preview">
<div class="grid" style={{
gridTemplateColumns: `repeat(7, ${cellSize}px)`,
gap: `${gap}px`
}}>
{data.map((level, i) => (
<div
class={`cell level-${level}`}
style={{
width: `${cellSize}px`,
height: `${cellSize}px`,
backgroundColor: colors[level]
}}
title={`Level ${level}`}
></div>
))}
</div>
</div>
<div class="heatmap-legend">
<span>Less</span>
<div class="legend-cells">
{colors.map((color, i) => (
<div class="legend-cell" style={{ backgroundColor: color }}></div>
))}
</div>
<span>More</span>
</div>
</div>
<style>
.heatmap-container {
display: flex;
flex-direction: column;
gap: 0.75rem;
padding: 1.25rem;
background: var(--glass-bg);
border: var(--glass-border);
border-radius: 12px;
box-shadow: var(--glass-shadow);
}
.heatmap-title {
font-size: 0.8rem;
font-family: var(--font-mono);
color: var(--color-neutral);
text-transform: uppercase;
letter-spacing: 1px;
}
.heatmap-preview {
display: flex;
justify-content: center;
}
.grid {
display: grid;
}
.cell {
border-radius: 2px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
}
.cell:hover {
transform: scale(1.2);
z-index: 2;
box-shadow: 0 0 10px rgba(255, 255, 255, 0.1);
}
.heatmap-legend {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 0.5rem;
font-size: 0.7rem;
color: var(--color-neutral);
}
.legend-cells {
display: flex;
gap: 3px;
}
.legend-cell {
width: 10px;
height: 10px;
border-radius: 2px;
}
</style> 组件特性
- 数据映射:将数值自动映射到五个等级的颜色。
- 动态网格:基于 CSS Grid,支持自定义行列比例。
- 交互缩放:鼠标悬停时方格平滑放大,并显示详细信息。
- 图例展示:内置 Legend 区域,清晰展示颜色等级含义。
使用建议
常用于展示 GitHub 贡献、用户活跃度或任何时间序列的频率数据。可以根据项目主题修改 colors 数组来适配不同的色彩倾向(如蓝色系或紫色系)。
示例配置
const data = [
{ date: '2023-01-01', count: 5 },
{ date: '2023-01-02', count: 12 },
// ...
]; Attributes
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| data | 活跃度数据数组,0-4 表示不同强度 | `number[]` | [] |
| cellSize | 每个方格的大小 (px) | `number` | 14 |
| gap | 方格之间的间距 (px) | `number` | 4 |
| colors | 五个等级对应的颜色数组 | `string[]` | ['#161b22', '#0e4429', '#006d32', '#26a641', '#39d353'] |
| title | 热力图顶部的标题内容 | `string` | 'Activity Heatmap' |
02. 圆形进度条 (Circular Progress)
动态展示百分比进度的圆形容器,支持自定义颜色和发光特效。
---
interface Props {
percent?: number;
size?: number;
strokeWidth?: number;
showText?: boolean;
color?: string;
}
const {
percent = 75,
size = 120,
strokeWidth = 10,
showText = true,
color = 'var(--color-primary-start)'
} = Astro.props;
const radius = (size / 2) - strokeWidth;
const center = size / 2;
const circumference = 2 * Math.PI * radius;
const offset = circumference - (percent / 100) * circumference;
---
<div class="circular-progress-preview">
<svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
<circle
class="bg"
cx={center}
cy={center}
r={radius}
stroke-width={strokeWidth}
/>
<circle
class="progress"
cx={center}
cy={center}
r={radius}
stroke-width={strokeWidth}
stroke-dasharray={circumference}
stroke-dashoffset={offset}
style={{ stroke: color }}
/>
{showText && (
<text x={center} y={center} text-anchor="middle" dominant-baseline="middle" class="text">
{percent}%
</text>
)}
</svg>
</div>
<style>
.circular-progress-preview {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
svg {
transform: rotate(-90deg);
}
circle {
fill: none;
stroke-linecap: round;
}
.bg {
stroke: rgba(var(--color-primary-rgb), 0.05);
}
.progress {
filter: drop-shadow(0 0 8px var(--color-primary-start));
transition: stroke-dashoffset 1s cubic-bezier(0.4, 0, 0.2, 1);
}
.text {
fill: var(--color-text-title);
font-size: 1.5rem;
font-weight: 800;
font-family: var(--font-mono);
transform: rotate(90deg);
transform-origin: center;
}
</style> 组件特性
- SVG 渲染:基于原生 SVG,支持任意缩放而不失真。
- 平滑动画:内置 CSS 过渡动画,进度切换自然流畅。
- 高度定制:可自由调整粗细、大小、颜色及文字显示。
- 响应式设计:适配各种容器尺寸。
使用建议
适用于展示任务进度、资源占用、仪表盘等场景。可以通过 color 参数配合主题变量,实现不同状态(如成功、警告、错误)的视觉反馈。
Attributes
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| percent | 当前的进度百分比 (0-100) | `number` | 75 |
| size | 组件的宽度和高度 (px) | `number` | 120 |
| strokeWidth | 进度条的线条粗细 | `number` | 10 |
| showText | 是否显示中间的百分比文字 | `boolean` | true |
| color | 进度条的颜色 (支持 CSS 颜色值) | `string` | var(--color-primary-start) |
03. 数字雨背景 (Digital Rain)
经典的黑客帝国风格代码雨特效,基于 Canvas 渲染,高度可配置。
---
interface Props {
speed?: number;
fontSize?: number;
color?: string;
density?: number;
class?: string;
}
const {
speed = 1,
fontSize = 14,
color = "var(--color-primary-start)",
density = 0.5,
class: className
} = Astro.props;
---
<div class:list={["digital-rain-container", className]}>
<canvas id="digitalRainCanvas"></canvas>
<div class="overlay"></div>
</div>
<script define:vars={{ speed, fontSize, color, density }}>
const canvas = document.getElementById('digitalRainCanvas');
const ctx = canvas.getContext('2d');
let width, height, columns;
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$+-*/=%\"'#&_(),.;:?!\\|{}<>[]^~";
let drops = [];
function init() {
width = canvas.parentElement.offsetWidth;
height = canvas.parentElement.offsetHeight;
canvas.width = width;
canvas.height = height;
columns = Math.floor(width / fontSize);
drops = [];
for (let i = 0; i < columns; i++) {
drops[i] = Math.random() * -height;
}
}
function draw() {
ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = color;
ctx.font = `${fontSize}px monospace`;
for (let i = 0; i < drops.length; i++) {
if (Math.random() > (1 - density)) {
const text = chars[Math.floor(Math.random() * chars.length)];
ctx.fillText(text, i * fontSize, drops[i]);
}
drops[i] += fontSize * speed;
if (drops[i] > height && Math.random() > 0.975) {
drops[i] = 0;
}
}
}
init();
let interval = setInterval(draw, 33);
window.addEventListener('resize', () => {
init();
});
</script>
<style>
.digital-rain-container {
position: relative;
width: 100%;
height: 300px;
background: #000;
border-radius: 8px;
overflow: hidden;
border: 1px solid rgba(var(--color-primary-rgb), 0.2);
}
canvas {
display: block;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
rgba(0, 0, 0, 0.2) 50%,
transparent 50%
);
background-size: 100% 4px;
pointer-events: none;
}
</style> 组件特性
- 高性能渲染:基于原生 Canvas API 绘制,即使在大量字符下落时也能保持流畅。
- 动态适配:自动监听容器尺寸变化并重新初始化,确保全屏或局部展示都能完美填充。
- 氛围增强:叠加了一层细微的扫描线效果,模拟老式显示器的质感。
- 全字符集:内置了包括字母、数字、特殊符号在内的丰富字符集,随机掉落。
使用建议
建议作为页面的局部背景(如卡片内部)或全屏背景使用。为了保证文字可读性,建议在上方覆盖一层半透明的遮罩或使用高对比度的文字颜色。
Attributes
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| speed | 下落速度倍率 | `number` | 1 |
| fontSize | 字符大小 (px) | `number` | 14 |
| color | 字符颜色 | `string` | 'var(--color-primary-start)' |
| density | 字符密度 (0-1) | `number` | 0.5 |
| class | 自定义样式类名 | `string` | '' |