关于 antv-t8-ntv
Narrative Text Visualization Skill 使用带语义标注的类 Markdown 语言 T8 Syntax,指导创建结构化数据叙述。它面向叙述式报告制作,并可生成用于 HTML、React 或 Vue 的前端渲染代码。
主要功能
- 01类 Markdown 的 T8 Syntax
- 02数据实体语义标注
- 03结构化叙述报告
- 04生成 HTML、React 和 Vue 渲染代码
- 05内置饼图和折线迷你图
适用场景
- 01将有来源的指标整理为带标注的报告
- 02创建结构分明的叙述摘要
- 03生成 T8 内容和 React 渲染代码
- 04在叙述文本中展示数据趋势
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ antvis/ chart-visualization-skills --skill antv-t8-ntv安装后在 Claude Code 中输入/antv-t8-ntv确认已加载。
详细介绍
叙事文本可视化技能
此技能提供了一套工作流,使用 T8 Syntax 将数据转换为结构化的叙事文本可视化内容。T8 Syntax 是一种类似 Markdown 的声明式语言,可用于创建带有语义实体注释的数据叙事。
什么是 T8
T8 是 AntV 技术栈下的一种文本可视化解决方案,专为基于洞察的叙事文本展示而设计。无需手动构建 DOM 元素,只需编写简单易读的语法来描述数据叙事内容。
主要特性:
- 适合大模型使用:语法直观,AI 模型可以轻松生成
- 声明式且易读:描述想要的内容,而不是如何构建
- 与框架无关:适用于 React、Vue 或原生 JavaScript
- 样式标准化:默认呈现专业外观
- 内置数据可视化:迷你图表(饼图、折线图)是语法原生支持的内容
- 轻量:gzip 压缩前小于 20KB
工作流
生成叙事文本可视化内容时,请遵循以下步骤:
1. 理解需求
分析用户的请求,确定:
- 要分析的主题或数据
- 所需叙事类型(报告、摘要、文章)
- 要突出的关键洞察
- 是否有特定数据来源或指标
2. 生成 T8 Syntax 内容
按照下方规范使用 T8 Syntax 创建叙事文本。内容必须包括:
- 合适的文档结构(标题、段落、列表)
- 为所有有意义的数据点添加实体注释
- 为实体添加适当的元数据(来源、评估等)
3. 生成前端代码
根据用户偏好的框架,创建用于渲染 T8 内容的 HTML、React 或 Vue 代码。
4. 验证输出
确保:
- 所有数据均来自可靠来源
- 内容长度达到最低要求(800 词或等量内容)
- 全文包含恰当的实体注释
- 结构清晰、逻辑连贯
T8 Syntax 规范
T8 Syntax 是一种类似 Markdown 的语言,用于创建带有语义实体注释的叙事文本。它能让数据分析报告更具表现力和视觉吸引力。
文档结构
标题(6 个级别)
使用标准 Markdown 标题语法:
# Level 1 Heading (Main Title)
## Level 2 Heading (Section)
### Level 3 Heading (Subsection)
#### Level 4 Heading
##### Level 5 Heading
###### Level 6 Heading
规则:
- 每个标题必须单独占一行
- 在
#符号后添加一个空格 - 标题在渲染结果中构建视觉层级
段落
普通文本段落之间以空行分隔:
This is the first paragraph with some content.
This is the second paragraph, separated by a blank line.
规则:
- 段落可以跨越多行
- 使用空行分隔不同段落
- 段落内的文本会自然流动
列表
T8 Syntax 支持无序列表和有序列表。
无序列表:
- First item
- Second item
- Third item
有序列表:
1. First step
2. Second step
3. Third step
规则:
- 每个列表项必须单独占一行
- 在项目符号(
-、*)或数字后添加一个空格 - 列表可以包含实体和文本格式
文本格式
T8 Syntax 支持使用 Markdown 语法设置行内文本格式:
粗体: This is **bold text** that stands out.
斜体: This is *italic text* for emphasis.
下划线: This is __underlined text__ for importance.
链接: Visit [our website](https://example.com) for more information.
规则:
- 格式标记必须成对匹配(开头和结尾)
- 格式可以与实体结合使用
- 链接使用
[text](URL)语法,其中 URL 以http://、https://或/开头
实体注释语法
T8 Syntax 的核心功能是实体注释——为特定数据点标记语义含义和元数据。
基本实体语法
[displayText](entityType)
displayText:向读者显示的文本entityType:该实体的语义类型
示例:
The [sales revenue](metric_name) reached [¥1.5 million](metric_value) this quarter.
带元数据的实体
[displayText](entityType, key1=value1, key2=value2, key3="string value")
元数据规则:
- 多个元数据字段之间用逗号分隔
- 数字和布尔值:直接填写(例如,
origin=1500000、active=true) - 字符串:用双引号括起来(例如,
unit="元"、region="Asia")
示例:
Revenue grew by [15.3%](ratio_value, origin=0.153, assessment="positive") compared to last year.
实体类型参考
使用以下实体类型标注不同种类的数据:
| Entity Type | Description | When to Use | Examples |
|---|---|---|---|
metric_name | 指标或 KPI 的名称 | 提及所测量的内容时 | "revenue"(收入)、"user count"(用户数)、"market share"(市场份额) |
metric_value | 主要指标值 | 报告的主要数字/数值 | "¥1.5 million"(150 万日元)、"50,000 users"(50,000 名用户)、"250 units"(250 个单位) |
other_metric_value | 次要或辅助指标值 | 提供背景信息的其他指标 | "average order value: $120"(平均订单金额:120 美元) |
delta_value | 绝对变化/差值 | 显示不同时间段之间的数值变化时 | "+1,200 units"(增加 1,200 个单位)、"-$50K"(减少 5 万美元)、"increased by 500"(增加了 500) |
ratio_value | 百分比变化/比率 | 显示百分比变化时 | "+15.3%"、"-5.2%"、"grew 23%"(增长了 23%) |
contribute_ratio | 贡献百分比 | 显示某项所占百分比时 | "accounts for 45%"(占 45%)、"represents 30% of total"(占总量的 30%) |
trend_desc | 趋势描述 | 描述变化方向/模式时 | "steadily rising"(稳步上升)、"declining trend"(下降趋势)、"stable"(稳定) |
dim_value | 维度值/类别 | 地理、类别或细分数据 | "North America"(北美)、"Enterprise segment"(企业细分)、"Q3"(第 3 季度) |
time_desc | 时间段或时间戳 | 指定事件发生时间时 | "Q3 2024"(2024 年第 3 季度)、"January-March"(1 月至 3 月)、"fiscal year 2023"(2023 财年) |
proportion | 比例或比率 | 表示整体中的部分时 | "3 out of 5"(5 个中的 3 个)、"60% of customers"(60% 的客户) |
rank | 排名或位置 | 表示列表中的顺序或位置时 | "ranked 1st"(排名第 1)、"top 3"(前 3 名)、"5th place"(第 5 名) |
difference | 比较差异 | 突出两个项目之间的差异时 | "difference of $50K"(相差 5 万美元)、"gap of 200 units"(相差 200 个单位) |
anomaly | 异常或意外数值 | 指出异常值或异常情况时 | "unusual spike"(异常飙升)、"unexpected drop"(意外下降) |
association | 关系或相关性 | 描述指标之间的联系时 | "strongly correlated"(强相关)、"linked to"(与……相关)、"related"(有关联) |
distribution | 数据分布模式 | 描述数据的分布情况时 | "evenly distributed"(均匀分布)、"concentrated in"(集中在)、"spread across"(分布于) |
seasonality | 季节性模式或趋势 | 描述周期性季节模式时 | "seasonal peak"(季节性峰值)、"holiday period"(节假日期间)、"Q4 surge"(第 4 季度激增) |
常见元数据字段
添加以下可选字段,以提供更丰富的数据背景信息:
origin(数字)
显示文本背后的原始数值。
示例:
[¥1.5M](metric_value, origin=1500000)[23.7%](ratio_value, origin=0.237)[5.2K users](metric_value, origin=5200)[3 out of 4](proportion, origin=0.75)
**用途:**支持数据可视化、排序和计算
assessment(string)
评估某项变化是正向、负向还是中性。
有效值: "positive"、"negative"、"equal"、"neutral"
示例:
[增长 15%](ratio_value, assessment="positive")[下降 8%](ratio_value, assessment="negative")[保持不变](trend_desc, assessment="equal")
使用原因: 可显示视觉指示器(颜色、图标),标明趋势的好坏
unit(string)
数值的计量单位。
示例:
[¥1,500,000](metric_value, unit="元", origin=1500000)[150](metric_value, unit="units")
detail(any)
用于图表渲染的其他上下文或细分数据。某些实体类型必须提供此项。
以下实体类型必须提供:
rank:表示排名数据的数字数组- 示例:
[表现最佳](rank, detail=[5, 8, 12, 15, 20])
- 示例:
difference:用于展示对比数值的数组- 示例:
[差距缩小](difference, detail=[100, 80, 60, 40])
- 示例:
anomaly:用于标出异常值的数字数组- 示例:
[异常峰值](anomaly, detail=[10, 12, 11, 45, 13])
- 示例:
association:用于相关性数据的 {x, y} 对象数组- 示例:
[强相关](association, detail=[{"x":1,"y":2},{"x":2,"y":4},{"x":3,"y":6}])
- 示例:
distribution:用于展示数据分布情况的数字数组- 示例:
[分布不均](distribution, detail=[5, 15, 45, 25, 10])
- 示例:
seasonality:包含数据数组和可选范围的对象- 示例:
[Q4 达到峰值](seasonality, detail={"data":[10,12,15,30],"range":[0,40]})
- 示例:
其他类型可选:
[稳步增长](trend_desc, detail=[100, 120, 145, 180, 210])
数据要求
重要: 所有数据都必须来自真实可信的公开来源:
- 官方公告/财务报告
- 权威媒体(Reuters、Bloomberg、TechCrunch 等)
- 行业研究机构(IDC、Canalys、Counterpoint Research 等)
- 切勿使用虚构、由 AI 猜测或模拟的数据
- 使用具体数字(例如“1.46 亿台”“7058 台”),不要使用含糊的近似数
完整的 T8 语法示例
# 2024 Smartphone Market Analysis
## Market Overview
Global [smartphone shipments](metric_name) reached [1.2 billion units](metric_value, origin=1200000000) in [2024](time_desc), showing a [modest decline of 2.1%](ratio_value, origin=-0.021, assessment="negative") year-over-year.
The **premium segment** (devices over $800) showed *remarkable* [resilience](trend_desc, assessment="positive"), growing by [5.8%](ratio_value, origin=0.058, assessment="positive"). [Average selling price](other_metric_value) was [$420](metric_value, origin=420, unit="USD").
## Key Findings
1. [Asia-Pacific](dim_value) remains the __largest market__
2. [Premium devices](dim_value) showed **strong growth**
3. Budget segment faced *headwinds*
## Regional Breakdown
### Asia-Pacific
[Asia-Pacific](dim_value) remains the largest market with [680 million units](metric_value, origin=680000000) shipped, though this represents a [decline of 180 million units](delta_value, origin=-180000000, assessment="negative") from the previous year.
Key markets:
- [China](dim_value): [320M units](metric_value, origin=320000000) - down [8.5%](ratio_value, origin=-0.085, assessment="negative"), [ranked 1st](rank, detail=[320, 180, 90, 65, 45]) globally, accounting for [47%](contribute_ratio, origin=0.47, assessment="positive") of regional sales
- [India](dim_value): [180M units](metric_value, origin=180000000) - up [12.3%](ratio_value, origin=0.123, assessment="positive"), [ranked 2nd](rank, detail=[320, 180, 90, 65, 45])
- [Southeast Asia](dim_value): [180M units](metric_value, origin=180000000) - [stable](trend_desc, assessment="equal")
For detailed methodology, visit [our research page](https://example.com/methodology).
在 HTML、React 和 Vue 中使用 T8
在 HTML 中使用(通过 CDN)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>T8 Narrative Text</title>
</head>
<body>
<div id="container"></div>
<script src="https://unpkg.com/@antv/t8/dist/t8.min.js"></script>
<script>
// T8 is available as a global variable
const { Text } = window.T8;
// Initialize T8 instance
const text = new Text(document.getElementById('container'));
// Render narrative text using T8 Syntax
const narrativeText = `
# Sales Report
This quarter, [bookings](metric_name) are higher than usual. They are [¥348k](metric_value, origin=348.12).
[Bookings](metric_name) are up [¥180.3k](delta_value, assessment="positive") relative to the same time last quarter.
`;
text.theme('light').render(narrativeText);
</script>
</body>
</html>
安装:
npm install @antv/t8
# or
yarn add @antv/t8
在 React 中使用
import { Text } from '@antv/t8';
import { useEffect, useRef } from 'react';
function T8Component() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!containerRef.current) return;
// Initialize T8 instance
const text = new Text(containerRef.current);
// Render narrative text using T8 Syntax
const narrativeText = `
# Sales Report
This quarter, [bookings](metric_name) are higher than usual. They are [¥348k](metric_value, origin=348.12).
[Bookings](metric_name) are up [¥180.3k](delta_value, assessment="positive") relative to the same time last quarter.
`;
text.theme('light').render(narrativeText);
// Cleanup on unmount
return () => {
text.unmount();
};
}, []);
return <div ref={containerRef} />;
}
export default T8Component;
在 Vue 3 中使用
<template>
<div ref="containerRef"></div>
</template>
<script setup lang="ts">
import { Text } from '@antv/t8';
import { ref, onMounted, onBeforeUnmount } from 'vue';
const containerRef = ref<HTMLDivElement>();
let textInstance: Text | null = null;
onMounted(() => {
if (!containerRef.value) return;
// Initialize T8 instance
textInstance = new Text(containerRef.value);
// Render narrative text using T8 Syntax
const narrativeText = `
# Sales Report
This quarter, [bookings](metric_name) are higher than usual. They are [¥348k](metric_value, origin=348.12).
[Bookings](metric_name) are up [¥180.3k](delta_value, assessment="positive") relative to the same time last quarter.
`;
textInstance.theme('light').render(narrativeText);
});
onBeforeUnmount(() => {
if (textInstance) {
textInstance.unmount();
}
});
</script>
在 Vue 2 中使用
<template>
<div ref="container"></div>
</template>
<script>
import { Text } from '@antv/t8';
export default {
name: 'T8Component',
data() {
return {
textInstance: null,
};
},
mounted() {
// Initialize T8 instance
this.textInstance = new Text(this.$refs.container);
// Render narrative text using T8 Syntax
const narrativeText = `
# Sales Report
This quarter, [bookings](metric_name) are higher than usual. They are [¥348k](metric_value, origin=348.12).
[Bookings](metric_name) are up [¥180.3k](delta_value, assessment="positive") relative to the same time last quarter.
`;
this.textInstance.theme('light').render(narrativeText);
},
beforeDestroy() {
if (this.textInstance) {
this.textInstance.unmount();
}
},
};
</script>
写作指南和最佳实践
内容要求
- 最低长度: 不少于 800 个词(根据数据复杂度调整)
- 结构: 层次清晰,各部分之间逻辑连贯
- 分析: 不要只罗列数字,还要解释其意义和背景
- 语气: 自然、流畅、客观且专业
- 实体使用: 为所有有意义的数据点添加注释,包括指标、数值、趋势、时间、变化和百分比
实体注释最佳实践
- 全面覆盖: 标注所有定量数据,而不只是主要数值
- 类型恰当: 选择最能描述语义的实体类型
- 添加元数据: 在适用时包含
origin、assessment和其他相关字段 - 行文自然: 让实体自然融入易读的正文
注释内容
✅ 应注释:
- 所有数值(收入、数量、测量值)
- 所有百分比(变化、贡献、占比)
- 指标名称和 KPI
- 时间段
- 地理区域和类别
- 趋势描述
- 对比和变化
❌ 不应注释:
- 不包含具体数据信息的通用文本
- 衔接短语和过渡语
- 不代表可衡量概念的背景信息
输出格式
为用户生成 T8 Syntax 内容时:
- 直接输出 T8 Syntax 内容,不要用代码块包裹
- 根据用户偏好提供前端代码(HTML/React/Vue)
- 确保所有实体都使用适当的元数据进行了标注
- 确认内容符合最低长度和质量要求
渲染后的输出提供:
- 数据实体的丰富语义标记
- 交互式实体高亮
- 清晰的视觉层次
- 专业的报告式排版
- 适配所有设备的响应式设计