design-a-chart
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDesign a Chart From a User Goal
基于用户目标设计图表
Use this scenario loop: trigger → inspect → decide → build → verify. Do not begin with a chart type, even when the request names one.
遵循以下场景循环:trigger → inspect → decide → build → verify。即使请求中指定了图表类型,也不要从选择图表类型开始。
Setup
准备步骤
Turn the request into this brief before writing chart code:
ts
interface ChartBrief {
question: string
decision: string
observation: string
metric: { value: string; unit: string; denominator?: string }
comparison:
'time' | 'category' | 'distribution' | 'relationship' | 'composition'
evidence: readonly string[]
}
export const brief: ChartBrief = {
question:
'Which acquisition channel improved conversion without losing volume?',
decision: 'Choose where to increase next-month spend',
observation: 'one row per channel and month',
metric: { value: 'conversionRate', unit: '%', denominator: 'sessions' },
comparison: 'time',
evidence: ['conversion rate', 'sessions', 'month', 'channel'],
}If the question, observation, unit, denominator, or decision is unknown, inspect the data and surrounding product before choosing marks.
在编写图表代码之前,先将用户请求转化为如下概要:
ts
interface ChartBrief {
question: string
decision: string
observation: string
metric: { value: string; unit: string; denominator?: string }
comparison:
'time' | 'category' | 'distribution' | 'relationship' | 'composition'
evidence: readonly string[]
}
export const brief: ChartBrief = {
question:
'Which acquisition channel improved conversion without losing volume?',
decision: 'Choose where to increase next-month spend',
observation: 'one row per channel and month',
metric: { value: 'conversionRate', unit: '%', denominator: 'sessions' },
comparison: 'time',
evidence: ['conversion rate', 'sessions', 'month', 'channel'],
}如果问题、观测数据、单位、分母或决策信息不明确,在选择标记(marks)之前先检查数据及相关产品信息。
Core Patterns
核心模式
Match the form to the reader's comparison
让图表形式匹配读者的对比需求
- Change over ordered time → line; discrete periods → bars.
- Named-category magnitude → sorted horizontal bars or dots.
- Distribution → histogram, ECDF, box, violin, or faceted histograms.
- Relationship → scatterplot; add size only for a meaningful third quantity.
- Composition → stack for totals, normalized stack for proportions, mosaic for two categorical dimensions.
- Flow, hierarchy, network, or spatial questions → use their first-party layouts only when topology is the question.
Read the visual-task matrix for the full routing table.
- 有序时间维度的变化 → line图;离散时间段 → bars图。
- 分类维度的数值大小 → 排序后的水平bars图或dots图。
- 数据分布 → histogram、ECDF、box、violin图或分面histogram。
- 变量关系 → scatterplot;仅当存在有意义的第三个量化指标时才添加尺寸维度。
- 数据构成 → 堆叠图展示总计,归一化堆叠图展示占比,马赛克图展示两个分类维度的构成。
- 流向、层级、网络或空间类问题 → 仅当拓扑结构是核心问题时,才使用对应的原生布局。
查看可视化任务矩阵获取完整的选型对照表。
Separate observed, target, and projected values
区分观测值、目标值和预测值
ts
import { areaY, defineChart, lineY, ruleY } from '@tanstack/charts'
import { scaleLinear } from '@tanstack/charts/scales/linear'
import { scalePoint } from '@tanstack/charts/scales/point'
const rows = [
{ month: 'Jan', actual: 82, forecast: null, low: null, high: null },
{ month: 'Feb', actual: 91, forecast: null, low: null, high: null },
{ month: 'Mar', actual: null, forecast: 96, low: 88, high: 106 },
{ month: 'Apr', actual: null, forecast: 103, low: 90, high: 119 },
]
export const chart = defineChart({
marks: [
areaY(rows, { x: 'month', y1: 'low', y2: 'high', fillOpacity: 0.15 }),
lineY(rows, { x: 'month', y: 'actual', strokeWidth: 2.5 }),
lineY(rows, { x: 'month', y: 'forecast', strokeDasharray: '5 4' }),
ruleY([100], { strokeDasharray: '2 3' }),
],
x: { scale: scalePoint },
y: { scale: scaleLinear, axis: { label: 'Indexed revenue' } },
})Use different channels for status and uncertainty. A continuous unqualified line implies equal epistemic status.
ts
import { areaY, defineChart, lineY, ruleY } from '@tanstack/charts'
import { scaleLinear } from '@tanstack/charts/scales/linear'
import { scalePoint } from '@tanstack/charts/scales/point'
const rows = [
{ month: 'Jan', actual: 82, forecast: null, low: null, high: null },
{ month: 'Feb', actual: 91, forecast: null, low: null, high: null },
{ month: 'Mar', actual: null, forecast: 96, low: 88, high: 106 },
{ month: 'Apr', actual: null, forecast: 103, low: 90, high: 119 },
]
export const chart = defineChart({
marks: [
areaY(rows, { x: 'month', y1: 'low', y2: 'high', fillOpacity: 0.15 }),
lineY(rows, { x: 'month', y: 'actual', strokeWidth: 2.5 }),
lineY(rows, { x: 'month', y: 'forecast', strokeDasharray: '5 4' }),
ruleY([100], { strokeDasharray: '2 3' }),
],
x: { scale: scalePoint },
y: { scale: scaleLinear, axis: { label: 'Indexed revenue' } },
})使用不同的视觉渠道区分数据状态和不确定性。一条连续无修饰的线条意味着所有数据的认知状态相同。
Define proof before polish
在优化视觉效果前先验证准确性
For every chart, verify:
- the visual answers the stated question;
- axes, legend, title, or adjacent copy identify units and comparison;
- ordering, aggregation, missing-value policy, and baseline are deliberate;
- exact-value tasks have a table or textual equivalent;
- the smallest supported container preserves the important comparison;
- pointer, keyboard, updates, and empty states tell the same story.
对于每个图表,需验证:
- 可视化内容能够回答提出的问题;
- 坐标轴、图例、标题或相邻文本明确标注了单位和对比维度;
- 排序、聚合、缺失值处理规则和基线设置是经过审慎考虑的;
- 需要精确数值的场景配有对应的表格或文本说明;
- 在最小支持的容器尺寸下仍能保留核心的对比信息;
- 指针交互、键盘交互、数据更新和空状态都传递一致的信息。
Common Mistakes
常见错误
CRITICAL Starting with the requested chart type
严重错误:从用户要求的图表类型开始
Wrong: implement “make this a pie chart” before identifying the comparison.
Correct: restate the decision and recommend the form that makes that comparison perceptually direct. If the user retains a weaker form, state its analytical limitation and preserve the underlying semantics.
A familiar chart can answer a different question than the user needs.
Source:
docs/guides/choosing-a-chart.md错误做法:在明确对比需求之前就直接实现“制作饼图”的请求。
正确做法:重新梳理用户的决策需求,推荐能让对比感知更直接的图表形式。如果用户坚持使用效果较差的形式,需说明其分析局限性并保留底层语义。
熟悉的图表可能无法满足用户真正的需求。
来源:
docs/guides/choosing-a-chart.mdHIGH Showing a rate without its denominator
高风险错误:仅展示比率而不显示分母
Wrong: show conversion rate alone.
Correct: keep sessions or eligible population in the prepared row and expose it beside the rate or in the tooltip.
Normalized values can reverse interpretation when volume changes.
Source: F-217;
API-FRICTION.mddocs/reference/transforms.md错误做法:仅展示转化率。
正确做法:在预处理数据中保留会话数或合格用户群体,并将其显示在比率旁边或工具提示中。
当数据量变化时,归一化后的数值可能会逆转解读结果。
来源: F-217;
API-FRICTION.mddocs/reference/transforms.mdCRITICAL Rendering projections as observed history
严重错误:将预测数据当作历史观测数据渲染
Wrong: connect actuals and forecasts with one undifferentiated line.
Correct: encode the forecast boundary, projected segment, and uncertainty explicitly.
Continuous treatment implies equal certainty.
Source: ;
docs/examples/lines-and-areas.mddocs/reference/marks/difference.md错误做法:用一条无差别的线条连接实际数据和预测数据。
正确做法:明确标记预测边界、预测段和不确定性范围。
连续展示会让用户认为所有数据的确定性相同。
来源:;
docs/examples/lines-and-areas.mddocs/reference/marks/difference.mdHIGH Choosing area or angle for precise ranking
高风险错误:使用面积或角度进行精确排名
Wrong: rank close values with wedges, bubbles, or interior stack layers.
Correct: use aligned position or length when exact ordering is the reader's task.
Area and angle emphasize shape or part-to-whole relationships, not precise rank.
Source: ;
docs/guides/choosing-a-chart.mddocs/examples/bars-and-rankings.md错误做法:用扇形、气泡或堆叠图内层来对相近数值进行排名。
正确做法:当读者需要精确排序时,使用对齐的位置或长度维度。
面积和角度更适合强调形状或整体与部分的关系,而非精确排名。
来源:;
docs/guides/choosing-a-chart.mddocs/examples/bars-and-rankings.mdHIGH Tension: analytical honesty versus visual simplicity
高风险矛盾:分析准确性与视觉简洁性的冲突
Simplifying aggregation can hide denominators, lineage, uncertainty, or missing-value policy. Preserve the evidence needed to interpret the result before reducing visual detail.
See also: § Common Mistakes
prepare-chart-data/SKILL.md简化聚合操作可能会隐藏分母、数据来源、不确定性或缺失值处理规则。在减少视觉细节之前,需保留解读结果所需的证据。
另请参阅: § 常见错误
prepare-chart-data/SKILL.mdReferences
参考资料
- Analytical task and visual-form matrix
See also: and — the analytical task determines both the transform and mark composition.
prepare-chart-data/SKILL.mdcompose-marks-and-views/SKILL.md- 分析任务与可视化形式矩阵
另请参阅: 和 —— 分析任务决定了数据转换和标记组合方式。
prepare-chart-data/SKILL.mdcompose-marks-and-views/SKILL.md