定价

GaugeChart 使用手册

v1.7.5 · @snowui-design-system/components

许可阅读:首次阅读组件文档、源码或 npm 使用流程,先读完整 LICENSE;同任务同版本去重。公开 API 配置与内部实现修改分别按许可处理;全部组件使用统一运行包,源码权益以许可为准。

组件介绍

用半环或半饼展示多项数据占比,支持分段、渐变、环厚与出现动效,适合比例概览。

使用选择

用于半环形比例数据展示。当前数据模型与 CircularChart 一样以各项之和计算占比;任务完成进度使用 Progress。

  • 当前组件展示半环形比例数据,并非 min/max 单指标仪表;data 每项使用 name 和正 value,占比按有效显示项之和计算。

  • 省略 data 会显示示例数据,空数组展示空图;中心文案与内容用 centerTitle、centerSubtitle 或公开角色配置。

  • 根默认可访问名称随 LocaleProvider 切换,使用 gaugeChart.name;显式 aria-label 优先。业务名称、数据值与数字格式保持调用方内容。

快速开始

以下示例展示推荐的基本组合。更多场景与组合限制见后文。

<script lang="ts">	import { Button, Frame, Icon, Text } from '@snowui-design-system/components';	import { DotCircle } from '@snowui-design-system/resource-svelte';	import { GaugeChart } from '@snowui-design-system/components';	// Sample data for this week’s documentation review.	const channels = [	    { name: 'Ready', value: 72, color: 'var(--primary)' },	    { name: 'Review', value: 18, color: 'var(--secondary-purple)' },	    { name: 'Planned', value: 10, color: 'var(--secondary-orange)' }	];	let trafficChart: { replay: () => void; reverseAppearance: () => void } | undefined;</script> <div style="display: flex; flex-direction: column; align-items: center; width: var(--size-full); gap: var(--gap-4) var(--gap-3);">    <GaugeChart bind:this={trafficChart} data={channels} width={360} height={180} ringThickness={32}        centerTitle="Docs" centerSubtitle="This week" appearOnView defaultAppearanceProgress={0}        aria-label="Sample weekly documentation review" />    <div style="display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: var(--gap-4) var(--gap-3);" aria-label="Review status legend">        {#each channels as item}            <Frame singleLine gap={0}><Icon as="leading" size={12} style={`color: ${item.color};`}><DotCircle weight="fill" /></Icon><Text lines={1} style="font-size: var(--text-14); line-height: var(--leading-14); color: var(--black-100);">{item.name}</Text></Frame>        {/each}    </div>    <div style="display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: var(--gap-4) var(--gap-3);">        <Button onclick={() => trafficChart?.replay()}>Replay animation</Button>        <Button onclick={() => trafficChart?.reverseAppearance()}>Reverse animation</Button>    </div></div>

API

关键字 类型 默认值 描述
data GaugeChartItem[] DEFAULT_DATA 比例数据数组;每项必填 name(名称)与 value(有限正数),可选 color、percentFormat。按输入顺序过滤非正数和非法值,再取前 maxItems 项;百分比分母是实际显示项之和。省略 data 时使用内置示例数据;显式空数组或全部无效时保留最终尺寸并渲染空图表。 默认行为:内置 5 项示例数据。
width number | string 320 整体宽度,推荐正数(px 设计值转 rem);字符串直接作为 CSS 长度,但 SVG 几何仅以 parseFloat 提取数值,不换算单位,不支持可靠的百分比、calc() 或 CSS 变量几何。
minWidth number | string `${SECTOR_CHART_MIN_WIDTH}px` 响应式最小显示宽度;数字与 width 使用相同的 px 设计值转 rem 规则,字符串直接作为 CSS 长度。默认固定 40 CSS px;设为与 width 相同可阻止自动缩小,设为更小值允许缩到该下限。仅 enableResponsive=true 时生效。
height number | string 160 整体高度,推荐正数(px 设计值转 rem),通常为 width 的一半;改变高度会改变圆心与可用半径。字符串解析限制与 width 相同。
ringThickness number | string 32 环厚,推荐非负数字(px 设计值);内半径为 max(0, 外半径 − 环厚)。外半径为 max(1, min(width / 2, height) − hoverThicknessGrowth − 1),环厚达到它时形成实心半饼图。字符串仅提取数值,不换算单位。
cornerRadius number | string | "auto" "auto" 扇区端部圆角;非负数值或数字字符串表示 320px 宽基准的 px 设计值,按 width / 320 缩放;auto 使用基准值 4。最终受环厚和扇区角度限制;0 为直角。
separatorWidth number | string | "auto" "auto" 扇区间透明隔断;非负数值或数字字符串表示 320px 宽基准的 px 设计值,按 width / 320 缩放;auto 使用基准值 2,0 关闭间隔。通过路径几何留空,透出真实背景。
colors (GaugeChartColor | undefined)[] — 按过滤后显示索引覆盖颜色;每项支持语义色、CSS 颜色/变量、linear-gradient 字符串或 { type?, angle?, stops } 渐变对象。undefined 空位回退当前 colorMode;数据项 color 优先于调色板。不支持背景 utility 类名。
colorMode GaugeChartColorMode "sequence" sequence 按 Primary 与 9 个 Secondary 色序循环;monochromeFade 使用同一主色从首项 100% 均匀降至末项 20%(单项为 100%);monochrome 所有项使用同一颜色。三种模式均允许数据项和调色板逐项覆盖。
color GaugeChartColor — 同时覆盖 monochromeFade 与 monochrome 的回退主色,优先于 monochromeColor / mutedMonochromeColor;sequence 不使用它。支持与数据项 color 相同的纯色、语义色和渐变。
monochromeColor GaugeChartColor "Primary" 仅在 monochromeFade 且未传 color 时使用的回退主色;支持纯色和渐变。透明度从首项 100% 降到末项 20%,数据项 color 与 colors 仍优先。
mutedMonochromeColor GaugeChartColor "Black4" 仅在 monochrome 且未传 color 时使用的回退色;默认 Black4 是主题自适应的低对比色,扇区填充自身不再降低透明度。数据项 color 与 colors 仍优先。
hoverThicknessGrowth number | string 4 hover / focus 时向外增厚的非负 px 设计值;内半径与圆心不变,0 关闭几何增厚但保留数据提示。字符串只提取数值,不按 width / 320 缩放;没有 hoverScaleSize 别名。
startDirection StartDirection "left" left 从左端开始向右揭示,right 从右端开始向左揭示;只改变出现顺序和扫描方向,不旋转数据排布。
showBaseLayer boolean false 是否显示最终几何的同色 4% 透明度底层;默认不渲染。开启后底层不参与出现动效与命中,便于观察填充进度;不改变真实扇区和数据。
appearMotion boolean true 是否启用图形出现动效;false 时直接显示完整填充,并使 replay / reverseAppearance 不播放。此开关不关闭独立的 hover 增厚反馈。
appearOnView boolean true 非受控模式中,锚点到达指定视口位置时自动播放一次;同源 iframe 中按最外层同源页面的真实位置判断。false 可改用实例方法播放。appearanceProgress 优先;scrollAppearance 开启时由滚动驱动。
appearanceProgress number — 受控填充进度,数值限制到 0..1;提供后显示由调用方决定,自动播放和实例播放方法不改变受控画面。appearMotion=false 仍直接完整显示;外部进度变化不会触发 onAppearanceProgressChange。
defaultAppearanceProgress number 0 非受控模式首次初始化的进度,限制到 0..1,只读取一次;后续改变此属性不重置动画。有 appearanceProgress 时不决定画面;默认 0 为描边态。
appearanceDuration number — 实例播放与自动出现的总时长,单位 ms;未传时固定 1000,不随扇区数改变。非正数在下一动画帧直接到终点;不改变滚动或受控进度映射。
appearAnchorId string — 页面内触发锚点元素的 id;未传时使用图表根元素,传入不存在的 id 不回退根元素。仅用于自动出现或滚动时间轴,不改变图表位置。
appearAnchorPoint AnchorPoint "top" 选用锚点的 top(顶部)、center(垂直中心)或 bottom(底部)与视口触发线比较;不影响扇区绘制方向。
appearViewportPoint number | "top" | "center" | "bottom" 0.7 视口触发线:数字限制到 0..1,或使用 top=0、center=0.5、bottom=1。默认 0.7 为视口高度 70%;配合 appearAnchorPoint 决定触发/滚动起点。
scrollAppearance boolean | { distance?: number | string } false true 开启 window 滚动驱动的非受控时间轴;同源 iframe 同时响应外层页面滚动。对象可用 distance 覆盖滚动距离。锚点越过触发线后进度由距离决定,向回滚动会逆向恢复。不监听嵌套 ScrollArea;appearanceProgress / appearMotion=false 优先。
scrollAppearanceDistance number | string 320 滚动进度从 0 到 1 所需的 CSS px 距离;数字或数字字符串,最低按 1 处理。scrollAppearance.distance 优先;只在滚动时间轴开启时生效,不换算字符串单位。
onAppearanceProgressChange (progress: number) => void — 内部进度写入时接收 progress(0..1),包括初始化中的直接完成、自动播放、实例方法与滚动更新;可同步外部进度读数。默认值初始化本身不通知;不用于监听外部 appearanceProgress,返回值被忽略,不能取消更新。
maxItems number 10 过滤后保留的前 N 项数量,不排序、不自动合并 Other;取整并限制到 1..28,0 / NaN 回退 10。百分比只基于保留项,超过 28 类的业务应先聚合小类以保留总量;全无效时渲染空图表。
showCenterLabel boolean true 是否渲染中心内容区域;false 同时隐藏默认动态标签、segment-value / segment-name 模板与静态 center-label。隐藏中心不关闭显式启用的 HoverPanel。
centerTitle string "" 无 hover / focus 项时显示的中心标题,复用默认数值行排版;悬停或聚焦扇区时被百分比或 labelFormatter 第一行替换,离开后恢复。空字符串不占标题行;showCenterLabel=false 隐藏,静态 center-label 优先。
centerSubtitle string "" 无 hover / focus 项时显示的中心副标题,复用默认名称行排版;悬停或聚焦时被当前项名称或 labelFormatter 第二行替换,离开后恢复。可单独设置;不生成 HoverPanel 数据。
hoverMode ChartHoverMode "cell" cell 按环带角度命中,跨过透明隔断仍保持所属扇区,排除中心空洞与图外;item 只响应扇区路径命中。两种模式均保留扇区键盘 focus 提示。
showHoverPanel boolean true 默认根据当前 hover / focus 扇区显示结构化面板,同时保留动态中心标签。false 关闭面板;但存在可见静态 center-label 时组件自动启用面板承载扇区信息。
hoverPanelVariant ChartHoverPanelVariant "light" 面板视觉:light 为默认浅色玻璃样式,dark 为深色样式,surface 为主题表面样式;仅改变面板外观,不改变数据和命中。
hoverPanelPlacement ChartHoverPanelPlacement "pointer" 面板位置:pointer 跟随指针;anchor-top / anchor-side 相对当前指针点定位(键盘焦点使用图心);pin-top-left / pin-top / pin-top-right / pin-right / pin-bottom-right / pin-bottom / pin-bottom-left / pin-left / pin-center 固定在图表对应位置,边缘保留 8px 并参与视口碰撞处理。
showHoverPanelLabel boolean false 是否在面板行数据上方额外显示当前扇区名称;false 只显示数据行。仅面板开启且存在当前项时有可见效果。
percentFormat NumberFormatOptions — 中心百分比、面板百分比与扇区 aria-label 的数字格式;支持 fractionDigits、locale 等 NumberFormatOptions。优先级为数据项 percentFormat → 本属性 → NumberFormatContext → 默认一位小数;labelFormatter 只覆盖中心文本。 默认行为:NumberFormats 百分比默认。
labelFormatter (item: GaugeChartItem, percent: number) => string — hover / focus 时接收 item(当前有效数据项)与 percent(0..100 百分数),返回中心文字;以换行拆成数值行与名称行,最多使用两行。静态 center-label 或 showCenterLabel=false 时不调用;不改变面板和扇区 aria-label 的百分比。
loading boolean — 数据等待状态。保留 width / height 对应的最终占位和中心内容,将扇区固定在出现动效起点并暂停交互;变为 false 后按当前视口条件播放出现动效。图表不渲染 Skeleton,也会读取上层 Frame 的 loading 上下文;显式空 data={[]} 不回退默认演示数据。
children Snippet — 无参数 Snippet,渲染在 showCenterLabel=true 的中心区域。直系 Text as="segment-value" / "segment-name" 是动态标签模板,由组件写入当前两行文字;直系 Frame as="center-label" 提供常驻内容并自动启用面板。静态内容不自动套用默认中心排版;只需默认文字时无需传 children。中心用于展示,不用于交互工具栏。
class string "" 追加到图表根 Frame 的 class 字符串;不传时为空。仅表达调用方公开根样式,不穿透内部 SVG 和标签结构。
style string "" 追加到根 Frame 的 inline style 字符串,在组件注入的变量之后合并。可表达外部布局;图表几何优先使用 width、height、ringThickness 等公开 Props。
enableResponsive boolean true 默认在容器放不下时等比缩小图表本体,支持 flex 并排收缩,最小显示宽度由 minWidth 决定(默认 40px),与图表宽度相同时不收缩;HoverPanel 不缩放;false 保留声明尺寸。也透传至 Frame。
enableContext boolean true 透传 Frame 的上下文能力开关;当前组件自己的 width、height、颜色与出现进度仍由对应 Props 决定。
enableScaleObserver boolean false 透传 Frame 的旧版尺寸观察兼容能力,默认关闭;不等同于百分比图表尺寸,不建议新示例依赖此迁移期入口。
enableDefaultMotion boolean true 透传 Frame 默认外层动效能力;不接管图表内部出现时间轴和扇区 hover 增厚,后者分别由 appearMotion / appearanceProgress 与 hoverThicknessGrowth 控制。

未重新声明的继承能力请查所属基础组件文档;本表只列本组件源码具名公开属性。

使用边界与详细说明

HoverPanel 使用共享三列布局;圆点—名称优先 --gap-1,名称—数值优先 --gap-2,两处均至少保留 4 CSS px,并跟随 LTR / RTL 逻辑方向。默认 16px 根字号下仍为 4px / 8px,较大 Token 保留;面板纵向分区和图表中心注释不套用此下限。

设计原则

  • 专业图表组件:当前维护位置为 components/src/components/;该目录是迁移期技术位置。运行包使用与原始源码交付按 LICENSE 执行,不再以高级功能划分付费运行权益。

  • 默认 10 项,最多 28 项:默认 maxItems=10。显式提高 maxItems 时最多显示 28 项,颜色序列与 CircularChart 完全一致,10 项后仍按序循环。

  • 颜色优先级:data[i].color → colors[i] → colorMode 对应回退色。单项颜色只影响当前扇区,不会传递给后续扇区。

  • 尺寸基准:cornerRadius 与 separatorWidth 都表示 320px 宽仪表图下的设计基准值。组件内部统一按 width / 320 等比缩放,数字和字符串数字都按基准值理解。

  • 透明间隔:扇区间隔在 path 几何阶段通过 padAngle + padRadius 生成,贯穿内外圆弧并透出真实背景;不绘制固定白色 stroke,也不使用后置 gap mask。

  • 图层结构:base layer 由 showBaseLayer 控制,默认关闭,开启时绘制 4% 同色占位层;fill layer 负责真实填充与出现动效;hit layer 使用完整扇区 path 负责 hover / focus / aria。

  • Hover 强调:每个扇区从当前几何立即转向最新 hover / focus 目标,取消未完成的旧动画,不积压重播;hover / focus 时扇区不位移,仅外半径缓动增加 hoverThicknessGrowth;中心标签上方显示百分比,下方显示当前项名称。

共享纯逻辑位于 components/src/lib/chart/:颜色、渐变、几何基准缩放、圆环扇区 path 与出现时间轴。GaugeChart 自身保留半圆圆心、起始方向、中心标签和 hover 状态管理。


2.1 Props

其余未声明属性透传到根 Frame。根使用 role="group" 和 aria-label="仪表图"(zh-CN 默认,随 locale 切换);SVG 不隐藏可聚焦扇区,每个扇区命中项以 role="button" 和包含名称、百分比的独立 aria-label 暴露给辅助技术。

2.2 方法

方法 描述
replay() 非受控出现动效从 0 重新播放到 1
resetAppearance() 非受控出现动效立即重置到 0
reverseAppearance() 非受控出现动效先进入完成态,再沿同一时间轴从 1 反向回退到 0

2.3 数据结构

type GaugeChartColor = string | GaugeChartGradient; interface GaugeChartGradient {  type?: "linear";  angle?: number;  stops: (string | { color: string; offset?: number | string; opacity?: number })[];} interface GaugeChartItem {  name: string;  value: number;  color?: GaugeChartColor;  percentFormat?: NumberFormatOptions;}

百分比数字格式优先级:labelFormatter(中心标签)→ item.percentFormat → 组件 percentFormat → NumberFormatContext → NumberFormats 默认值。扇区命中层 aria-label 不使用 labelFormatter,但会消费 percentFormat。

value <= 0 或非数字项会被过滤;显式空数组或全部无效时渲染空图表,省略 data 才使用内置示例数据。不支持直接传入 .bg-gradient-blue 这类背景工具类名,因为 SVG path 消费的是 fill。


布局模型

主布局模型:内禀原子布局。

  • 根层为 Frame,内部本体层统一承载 SVG 绘图区与中心标签,负责等比缩放;HoverPanel 与本体层并列,保持原有尺寸。

  • 图表尺寸由 width / height 与 SVG 几何算法决定;作为外部布局子项时表现为 Hug。

  • 不接入三槽位协议,不承担通用子元素排列。

  • 根层显式传入 enableResponsive / enableContext / enableScaleObserver / enableDefaultMotion,并透传 class、style 与未声明属性。

详见 LayoutProtocol.md §12.7(源码参考:specs/maintainers/LayoutProtocol.md)。


动效

场景 实现 bridge 变量
顺序出现 与 CircularChart 一致,默认总时长固定为 1000ms,不随扇区数量变化;整张图表使用图表级缓出时间分配:前段时长接近,越靠后的扇区时长越长;单段内部线性填充;透明度跟随填充进度完成;反向进度沿同一公式回退 组件内部确定性时间轴
滚动出现 scrollAppearance 按锚点与视口触发线距离映射到 appearanceProgress 组件内部滚动监听
扇区 hover 强调 每个扇区从当前几何立即转向最新 hover / focus 目标,取消未完成的旧动画,不积压重播;进入时外半径从 R 缓动到 R + hoverThicknessGrowth,离开时缓动回 R;内半径不变,扇区不位移 组件内部 requestAnimationFrame + cubicOut,300ms;减少动效时直接到达最终状态
扇区亮度反馈 filter: brightness(1.04) --snowui-frame-color-motion-*
中心标签进入 opacity + scale --snowui-frame-appear-motion-* / --snowui-frame-control-motion-*

使用示例

<GaugeChart centerTitle="Docs" centerSubtitle="This week"  data={[{ name: "Ready", value: 72 }, { name: "Review", value: 18 }, { name: "Plan", value: 10 }]} />
<GaugeChart  data={[    { name: "Primary", value: 32 },    { name: "Growth", value: 24 },    { name: "Support", value: 18 },    { name: "Explore", value: 14 },    { name: "Other", value: 12 }  ]}/>
<GaugeChart  colors={[undefined, "var(--secondary-blue)", "linear-gradient(135deg, var(--black-100) 0%, var(--secondary-blue) 100%)"]}  data={[    { name: "Done", value: 62, color: "var(--secondary-mint)" },    { name: "Doing", value: 24 },    { name: "Remain", value: 14 }  ]}/>
<script lang="ts">  let chart: { replay: () => void; reverseAppearance: () => void } | undefined;</script> <Button onclick={() => chart?.replay?.()}>重新填充</Button><Button onclick={() => chart?.reverseAppearance?.()}>反向回退</Button><GaugeChart bind:this={chart} startDirection="right" appearOnView={false} defaultAppearanceProgress={1} />
<GaugeChart  width={320}  height={160}  data={[    { name: "Growth", value: 24 },    { name: "Support", value: 18 }  ]}>  <Text as="segment-value" />  <Text as="segment-name" /></GaugeChart>

GaugeChart 样式覆盖

先阅读 完整 LICENSE;同任务、同版本、同范围去重。

优先用组件公开 Props 匹配合适样式,尽可能保留原有视觉。确需改写时按 样式选择与改写顺序 使用自己的 class(含项目已有 Tailwind)或实例 style。以下名称来自源码实际消费的公开 override;先核对目标作用域,不修改私有 DOM。采用 SnowUI Token 时选择正确类别,外部应用不被要求安装一方 utilities。

变量 用途与默认参考
--snowui-gauge-chart-height-override 整体高度(默认 160px)
--snowui-gauge-chart-label-color-override 中心标签主色(默认 var(--black-100))
--snowui-gauge-chart-label-font-size-override 中心标签数值字号(320 宽基准默认 18px,随图表缩放)
--snowui-gauge-chart-label-font-weight-override 中心标签主行字重(默认 700)
--snowui-gauge-chart-label-muted-color-override 中心标签次色(默认 var(--black-40))
--snowui-gauge-chart-label-muted-font-weight-override 中心标签次行字重(默认 400)
--snowui-gauge-chart-width-override 整体宽度(默认 320px)

设计指南 · Token · 组合边界

GaugeChart 类型与状态

必填属性:无具名必填属性。

可双向绑定:本组件未声明具名双向绑定属性;状态更新通过公开回调或所属宿主处理。

继承声明:无接口继承。继承能力以基类公开文档为准;Omit 中的字段已排除,不能按基类原样使用。

共享 Frame API · 返回 API

以下为公开属性实际引用的类型声明,来自源码;Svelte Snippet 表示内容片段,ComponentProps 表示对应组件的 Props。

GaugeChartItem

来源:components/src/components/GaugeChart.svelte

export interface GaugeChartItem {        name: string;        value: number;        color?: GaugeChartColor;        percentFormat?: NumberFormatOptions;    }

GaugeChartColor

来源:components/src/components/GaugeChart.svelte

export type GaugeChartColor = ChartColor;

ChartColor

来源:components/src/lib/chart/colors.ts

export type ChartColor = SnowUIColor | string | ChartGradient;

SnowUIColor

来源:components/src/lib/color.ts

export type SnowUIColor = keyof typeof SNOWUI_COLOR_TOKENS;

ChartGradient

来源:components/src/lib/chart/colors.ts

export interface ChartGradient {    type?: "linear";    angle?: number;    stops: (string | ChartGradientStop)[];}

ChartGradientStop

来源:components/src/lib/chart/colors.ts

export interface ChartGradientStop {    color: SnowUIColor | string;    offset?: number | string;    opacity?: number;}

NumberFormatOptions

来源:components/src/lib/number-format.ts

export interface NumberFormatOptions {    fractionDigits?: number;    valueLabelFractionDigits?: number;    percentFractionDigits?: number;    preserveTrailingZeros?: boolean;    useGrouping?: boolean;    emptyValue?: string;    locale?: string;    notation?: NumberNotation;    compactThreshold?: number;    compactFractionDigits?: number;}

NumberNotation

来源:components/src/lib/number-format.ts

export type NumberNotation = "standard" | "compact" | "auto";

GaugeChartColorMode

来源:components/src/components/GaugeChart.svelte

export type GaugeChartColorMode = ChartColorMode;

ChartColorMode

来源:components/src/lib/chart/colors.ts

export type ChartColorMode = "sequence" | "monochromeFade" | "monochrome";

StartDirection

来源:components/src/components/GaugeChart.svelte

type StartDirection = "left" | "right";

AnchorPoint

来源:components/src/components/GaugeChart.svelte

type AnchorPoint = "top" | "center" | "bottom";

ChartHoverMode

来源:components/src/components/GaugeChart.svelte

type ChartHoverMode = "item" | "cell";

ChartHoverPanelVariant

来源:components/src/lib/chart/hover-panel.ts

export type ChartHoverPanelVariant = "dark" | "light" | "surface";

ChartHoverPanelPlacement

来源:components/src/lib/chart/hover-panel.ts

export type ChartHoverPanelPlacement =    | "anchor-top"    | "anchor-side"    | "pointer"    | "pin-top-left"    | "pin-top"    | "pin-top-right"    | "pin-right"    | "pin-bottom-right"    | "pin-bottom"    | "pin-bottom-left"    | "pin-left"    | "pin-center";