markstar 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,427 @@
1
+ # Dashboard 数据大屏指南
2
+
3
+ > Agent 在 Step 0 检测到大屏关键词后加载此文件。提供布局模式、KPI 卡片、动态背景和完整 HTML 骨架。
4
+
5
+ ---
6
+
7
+ ## 1. 布局模式
8
+
9
+ 根据用户描述中涉及的图表数量,自动选择布局。KPI 卡片不计入图表数(它们独占顶部行)。
10
+
11
+ | 图表数 | 布局 | Grid 模板 | 适用场景 |
12
+ |--------|------|-----------|---------|
13
+ | 1 | 2 列:KPI 列 + 图表列 | `grid-template-columns: 0.35fr 0.65fr` | 1 个主图表 |
14
+ | 2 | 2 列均分 | `grid-template-columns: 1fr 1fr` | 2 图并排 |
15
+ | 3 | 上方 2 列 + 下方跨整行 | 第一行 2 列,`.span-full` 跨整行 | 2 图 + 1 宽图 |
16
+ | 4 | 2×2 | `grid-template-columns: 1fr 1fr` + `grid-template-rows: 1fr 1fr` | 4 图均分 |
17
+ | 5 | 上方跨行 + 下方 2×2 | `.span-full` + 2×2 网格 | 主图 + 4 辅图 |
18
+ | 6 | 2×3 | `grid-template-columns: 1fr 1fr 1fr` + `grid-template-rows: 1fr 1fr` | 6 图均分 |
19
+ | ≥7 | 3×3 每格定高 | `grid-template-columns: 1fr 1fr 1fr`,行高 320px | 信息密集面板 |
20
+
21
+ **规则**:
22
+ - KPI 卡片始终独占顶部一行,放在 grid 容器外,作为 `.kpi-row`
23
+ - 图表网格放在 `.chart-grid` 容器中
24
+ - 超过 9 个图表就取最重要的 9 个,其余根据用户是否需要省略
25
+
26
+ ---
27
+
28
+ ## 2. KPI 卡片
29
+
30
+ ### HTML 结构
31
+
32
+ ```html
33
+ <div class="kpi-row">
34
+ <div class="kpi-card">
35
+ <div class="kpi-label">2025 年总出货量</div>
36
+ <div class="kpi-value">2.85<span class="kpi-unit">亿台</span></div>
37
+ <div class="kpi-change down">▼ 0.6%</div>
38
+ </div>
39
+ <div class="kpi-card">
40
+ <div class="kpi-label">华为市场份额</div>
41
+ <div class="kpi-value">16.4<span class="kpi-unit">%</span></div>
42
+ <div class="kpi-change up">▲ 从榜外到第一</div>
43
+ </div>
44
+ <div class="kpi-card">
45
+ <div class="kpi-label">前五品牌合计份额</div>
46
+ <div class="kpi-value">79.4<span class="kpi-unit">%</span></div>
47
+ <div class="kpi-change up">▲ 同比 +1.2pp</div>
48
+ </div>
49
+ </div>
50
+ ```
51
+
52
+ ### CSS
53
+
54
+ ```css
55
+ .kpi-row {
56
+ display: flex;
57
+ gap: 16px;
58
+ margin-bottom: 16px;
59
+ }
60
+ .kpi-card {
61
+ flex: 1;
62
+ background: linear-gradient(135deg, rgba(30,41,59,0.9) 0%, rgba(30,41,59,0.6) 100%);
63
+ border: 1px solid #334155;
64
+ border-radius: 10px;
65
+ padding: 16px 20px;
66
+ position: relative;
67
+ overflow: hidden;
68
+ }
69
+ .kpi-card::before {
70
+ content: '';
71
+ position: absolute;
72
+ top: 0; left: 16px; right: 16px;
73
+ height: 2px;
74
+ border-radius: 0 0 2px 2px;
75
+ }
76
+ .kpi-card:nth-child(1)::before { background: linear-gradient(90deg, #00DDFF, transparent); }
77
+ .kpi-card:nth-child(2)::before { background: linear-gradient(90deg, #37A2FF, transparent); }
78
+ .kpi-card:nth-child(3)::before { background: linear-gradient(90deg, #FF0087, transparent); }
79
+ .kpi-card:nth-child(4)::before { background: linear-gradient(90deg, #FFBF00, transparent); }
80
+ .kpi-label {
81
+ font-size: 13px;
82
+ color: #94A3B8;
83
+ margin-bottom: 6px;
84
+ letter-spacing: 0.5px;
85
+ }
86
+ .kpi-value {
87
+ font-size: 32px;
88
+ font-weight: 700;
89
+ color: #E2E8F0;
90
+ font-family: "DIN Alternate", "Microsoft YaHei", "PingFang SC", sans-serif;
91
+ letter-spacing: 1px;
92
+ }
93
+ .kpi-unit {
94
+ font-size: 16px;
95
+ font-weight: 400;
96
+ color: #94A3B8;
97
+ margin-left: 4px;
98
+ }
99
+ .kpi-change {
100
+ font-size: 12px;
101
+ margin-top: 4px;
102
+ }
103
+ .kpi-change.up { color: #34D399; }
104
+ .kpi-change.down { color: #F87171; }
105
+ ```
106
+
107
+ ---
108
+
109
+ ## 3. 动态背景
110
+
111
+ ### 方案 2:科技网格线(默认,性能好)
112
+
113
+ 纯 CSS 实现,不依赖 JS。作为 body 的叠加背景层。
114
+
115
+ ```css
116
+ body::before {
117
+ content: '';
118
+ position: fixed;
119
+ top: 0; left: 0; right: 0; bottom: 0;
120
+ pointer-events: none;
121
+ z-index: 0;
122
+ background-image:
123
+ linear-gradient(rgba(0,221,255,0.04) 1px, transparent 1px),
124
+ linear-gradient(90deg, rgba(0,221,255,0.04) 1px, transparent 1px);
125
+ background-size: 60px 60px;
126
+ animation: gridPulse 4s ease-in-out infinite alternate;
127
+ }
128
+ @keyframes gridPulse {
129
+ 0% { opacity: 0.6; }
130
+ 100% { opacity: 1; }
131
+ }
132
+ ```
133
+
134
+ ### 方案 1:浮动粒子(用户要求"粒子/星空"时启用)
135
+
136
+ ```css
137
+ .particles {
138
+ position: fixed;
139
+ top: 0; left: 0; right: 0; bottom: 0;
140
+ pointer-events: none;
141
+ z-index: 0;
142
+ overflow: hidden;
143
+ }
144
+ .particle {
145
+ position: absolute;
146
+ width: 2px;
147
+ height: 2px;
148
+ background: rgba(0,221,255,0.3);
149
+ border-radius: 50%;
150
+ animation: floatUp linear infinite;
151
+ }
152
+ .particle:nth-child(odd) { background: rgba(55,162,255,0.25); }
153
+ .particle:nth-child(3n) { background: rgba(255,0,135,0.2); }
154
+
155
+ @keyframes floatUp {
156
+ 0% { transform: translateY(100vh) scale(0); opacity: 0; }
157
+ 10% { opacity: 1; }
158
+ 90% { opacity: 1; }
159
+ 100% { transform: translateY(-10vh) scale(1.5); opacity: 0; }
160
+ }
161
+ ```
162
+
163
+ 生成粒子元素的 JS(放在 `<script>` 中):
164
+
165
+ ```javascript
166
+ (function() {
167
+ var container = document.createElement('div');
168
+ container.className = 'particles';
169
+ for (var i = 0; i < 40; i++) {
170
+ var p = document.createElement('div');
171
+ p.className = 'particle';
172
+ p.style.left = Math.random() * 100 + '%';
173
+ p.style.animationDuration = (8 + Math.random() * 12) + 's';
174
+ p.style.animationDelay = Math.random() * 10 + 's';
175
+ container.appendChild(p);
176
+ }
177
+ document.body.appendChild(container);
178
+ })();
179
+ ```
180
+
181
+ ---
182
+
183
+ ## 4. Dashboard HTML 骨架(完整)
184
+
185
+ ```html
186
+ <!DOCTYPE html>
187
+ <html lang="zh-CN">
188
+ <head>
189
+ <meta charset="UTF-8">
190
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
191
+ <title><!-- 大屏标题 --></title>
192
+ <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
193
+ <style>
194
+ * { margin: 0; padding: 0; box-sizing: border-box; }
195
+ body {
196
+ font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", sans-serif;
197
+ background: #0F172A;
198
+ color: #E2E8F0;
199
+ min-height: 100vh;
200
+ padding: 20px 24px;
201
+ overflow-x: hidden;
202
+ position: relative;
203
+ }
204
+
205
+ /* ---------- 科技网格背景 ---------- */
206
+ body::before {
207
+ content: '';
208
+ position: fixed;
209
+ top: 0; left: 0; right: 0; bottom: 0;
210
+ pointer-events: none;
211
+ z-index: 0;
212
+ background-image:
213
+ linear-gradient(rgba(0,221,255,0.04) 1px, transparent 1px),
214
+ linear-gradient(90deg, rgba(0,221,255,0.04) 1px, transparent 1px);
215
+ background-size: 60px 60px;
216
+ animation: gridPulse 4s ease-in-out infinite alternate;
217
+ }
218
+ @keyframes gridPulse {
219
+ 0% { opacity: 0.6; }
220
+ 100% { opacity: 1; }
221
+ }
222
+
223
+ /* ---------- 全屏容器 ---------- */
224
+ .dashboard {
225
+ position: relative;
226
+ z-index: 1;
227
+ max-width: 1600px;
228
+ margin: 0 auto;
229
+ }
230
+
231
+ /* ---------- 标题行 ---------- */
232
+ .dashboard-header {
233
+ text-align: center;
234
+ margin-bottom: 20px;
235
+ padding-bottom: 12px;
236
+ border-bottom: 1px solid #1E293B;
237
+ }
238
+ .dashboard-header h1 {
239
+ font-size: 28px;
240
+ font-weight: 700;
241
+ color: #E2E8F0;
242
+ letter-spacing: 2px;
243
+ background: linear-gradient(90deg, #00DDFF, #37A2FF, #FF0087);
244
+ -webkit-background-clip: text;
245
+ -webkit-text-fill-color: transparent;
246
+ background-clip: text;
247
+ }
248
+ .dashboard-header .subtitle {
249
+ font-size: 13px;
250
+ color: #64748B;
251
+ margin-top: 4px;
252
+ }
253
+
254
+ /* ---------- KPI 卡片行 ---------- */
255
+ .kpi-row {
256
+ display: flex;
257
+ gap: 16px;
258
+ margin-bottom: 16px;
259
+ }
260
+ .kpi-card {
261
+ flex: 1;
262
+ background: linear-gradient(135deg, rgba(30,41,59,0.9) 0%, rgba(30,41,59,0.6) 100%);
263
+ border: 1px solid #334155;
264
+ border-radius: 10px;
265
+ padding: 16px 20px;
266
+ position: relative;
267
+ overflow: hidden;
268
+ backdrop-filter: blur(4px);
269
+ }
270
+ .kpi-card::before {
271
+ content: '';
272
+ position: absolute;
273
+ top: 0; left: 16px; right: 16px;
274
+ height: 2px;
275
+ border-radius: 0 0 2px 2px;
276
+ }
277
+ .kpi-card:nth-child(1)::before { background: linear-gradient(90deg, #00DDFF, transparent); }
278
+ .kpi-card:nth-child(2)::before { background: linear-gradient(90deg, #37A2FF, transparent); }
279
+ .kpi-card:nth-child(3)::before { background: linear-gradient(90deg, #FF0087, transparent); }
280
+ .kpi-card:nth-child(4)::before { background: linear-gradient(90deg, #FFBF00, transparent); }
281
+ .kpi-label {
282
+ font-size: 13px;
283
+ color: #94A3B8;
284
+ margin-bottom: 6px;
285
+ letter-spacing: 0.5px;
286
+ }
287
+ .kpi-value {
288
+ font-size: 32px;
289
+ font-weight: 700;
290
+ color: #E2E8F0;
291
+ font-family: "DIN Alternate", "Microsoft YaHei", "PingFang SC", sans-serif;
292
+ letter-spacing: 1px;
293
+ }
294
+ .kpi-unit {
295
+ font-size: 16px;
296
+ font-weight: 400;
297
+ color: #94A3B8;
298
+ margin-left: 4px;
299
+ }
300
+ .kpi-change {
301
+ font-size: 12px;
302
+ margin-top: 4px;
303
+ }
304
+ .kpi-change.up { color: #34D399; }
305
+ .kpi-change.down { color: #F87171; }
306
+
307
+ /* ---------- 图表网格 ---------- */
308
+ .chart-grid {
309
+ display: grid;
310
+ gap: 16px;
311
+ }
312
+ /* 布局由 Agent 根据图表数量选择对应的 class,参考布局模式表 */
313
+ .chart-grid.cols-2 { grid-template-columns: 1fr 1fr; }
314
+ .chart-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
315
+ .chart-grid.rows-2 { grid-template-rows: 1fr 1fr; }
316
+
317
+ .chart-panel {
318
+ background: rgba(30,41,59,0.8);
319
+ border: 1px solid #334155;
320
+ border-radius: 10px;
321
+ padding: 12px 14px 8px;
322
+ backdrop-filter: blur(4px);
323
+ display: flex;
324
+ flex-direction: column;
325
+ min-height: 340px;
326
+ }
327
+ .chart-panel .panel-title {
328
+ font-size: 14px;
329
+ font-weight: 600;
330
+ color: #CBD5E1;
331
+ margin-bottom: 4px;
332
+ padding-left: 8px;
333
+ border-left: 3px solid #00DDFF;
334
+ }
335
+ .chart-panel .chart-inner {
336
+ flex: 1;
337
+ width: 100%;
338
+ min-height: 280px;
339
+ }
340
+ .span-full { grid-column: 1 / -1; }
341
+
342
+ /* ---------- 脚注 ---------- */
343
+ .dashboard-footer {
344
+ text-align: center;
345
+ margin-top: 16px;
346
+ font-size: 12px;
347
+ color: #475569;
348
+ line-height: 1.6;
349
+ }
350
+ </style>
351
+ </head>
352
+ <body>
353
+ <div class="dashboard">
354
+ <div class="dashboard-header">
355
+ <h1><!-- 大屏标题 --></h1>
356
+ <div class="subtitle"><!-- 数据来源说明 --></div>
357
+ </div>
358
+
359
+ <!-- KPI 卡片行 -->
360
+ <div class="kpi-row">
361
+ <!-- 由 Agent 填入 2-4 个 kpi-card -->
362
+ </div>
363
+
364
+ <!-- 图表网格 -->
365
+ <div class="chart-grid <!-- cols-2 / cols-3 / rows-2 -->">
366
+ <!-- 由 Agent 填入 .chart-panel,每个含 .panel-title + .chart-inner -->
367
+ </div>
368
+
369
+ <div class="dashboard-footer"><!-- 脚注 --></div>
370
+ </div>
371
+
372
+ <script>
373
+ // 初始化所有图表
374
+ (function() {
375
+ var panels = document.querySelectorAll('.chart-inner');
376
+ // 每个 panel 的 option 由 Agent 在下方定义
377
+ var options = [
378
+ // Agent 将各块的 option 按顺序填在这里
379
+ ];
380
+ panels.forEach(function(el, i) {
381
+ if (options[i]) {
382
+ var chart = echarts.init(el, null, { backgroundColor: 'transparent' });
383
+ // 深色主题公共 textStyle
384
+ if (options[i].textStyle === undefined) {
385
+ options[i].textStyle = { color: '#CBD5E1' };
386
+ }
387
+ chart.setOption(options[i]);
388
+ window.addEventListener('resize', function() { chart.resize(); });
389
+ }
390
+ });
391
+ })();
392
+ </script>
393
+ </body>
394
+ </html>
395
+ ```
396
+
397
+ ---
398
+
399
+ ## 5. 深色 ECharts 通用配置
400
+
401
+ 大屏中所有图表共享此配置基础:
402
+
403
+ ```javascript
404
+ // 每个 option 必须追加的深色主题设置
405
+ var darkBase = {
406
+ textStyle: { color: '#CBD5E1' },
407
+ legend: { textStyle: { color: '#94A3B8' } },
408
+ tooltip: { backgroundColor: 'rgba(15,23,42,0.92)', borderColor: '#334155', textStyle: { color: '#E2E8F0' } },
409
+ // 使用 Theme B 调色板
410
+ color: ['#00DDFF','#37A2FF','#FF0087','#FFBF00','#00E396','#FEBE4A','#A78BFA','#34D399','#FF6B6B']
411
+ };
412
+
413
+ // 合并方式:先将 darkBase 浅合并到业务 option(不覆盖业务已显式设置的属性)
414
+ // 实际生成代码时直接内联到每个 option 对象中
415
+ ```
416
+
417
+ ---
418
+
419
+ ## 6. Agent 生成指引
420
+
421
+ 大屏模式下 Agent 按以下要点执行:
422
+
423
+ 1. **确定内容**:从用户描述中提取每个子图的主题 → 对每个子图执行原 flow 的 Step 1(场景分析)确定图表类型
424
+ 2. **确定布局**:数图表数量 → 查布局模式表 → 为 `.chart-grid` 选择 `cols-2` / `cols-3` 和 `rows-2`
425
+ 3. **生成 option**:每个 panel 独立获取数据、整理、生成 option(共享 Theme B 调色板)
426
+ 4. **KPI 卡片**:从数据中提炼 2-4 个关键指标(总量、最高值、同比变化、合计占比等)
427
+ 5. **特殊图表**:地图场景需在 `<script>` 前添加 China GeoJSON fetch 逻辑
@@ -0,0 +1,198 @@
1
+ # 数据处理策略
2
+
3
+ ## 数据获取降级链
4
+
5
+ 按以下优先级执行,上一级获取不到数据时自动进入下一级。任何一级成功获取数据后停止。
6
+
7
+ ### 级别 1:项目文件
8
+
9
+ **操作**:
10
+ 1. 使用 Glob 工具搜索当前项目目录下的数据文件:
11
+ ```
12
+ pattern: **/*.{csv,json,xlsx,xls}
13
+ ```
14
+ 2. 如果找到多个文件,优先选择文件名与用户查询最相关的
15
+ 3. 使用 Read 工具读取文件内容:
16
+ - CSV:解析为二维表,第一行作为列名
17
+ - JSON:解析为数组或对象结构
18
+ - Excel(.xlsx/.xls):Read 工具可直接读取
19
+
20
+ **成功条件**:能提取到至少 2 条数据记录
21
+
22
+ **失败时**:进入级别 2
23
+
24
+ ---
25
+
26
+ ### 级别 2:Web 搜索
27
+
28
+ **操作**:
29
+ 1. 使用 web_search 工具搜索相关公开数据,搜索词格式:
30
+ ```
31
+ "<用户查询关键词> 数据 历年 统计"
32
+ ```
33
+ 2. 从搜索结果摘要中提取数值。如果摘要信息不完整,使用 WebFetch 打开 1-2 个最相关的结果页面
34
+ 3. 从页面内容中提取表格、列表等结构化数据
35
+
36
+ **成功条件**:能提取到至少 2 条完整数据记录(含标签和数值)
37
+
38
+ **输出标注**:数据来源 URL
39
+
40
+ **失败时**:进入级别 3
41
+
42
+ ---
43
+
44
+ ### 级别 3:示例数据
45
+
46
+ **操作**:
47
+ 1. 根据用户查询主题,生成合理模拟数据
48
+ 2. 数据应尽可能贴近真实场景的数值范围和趋势
49
+ 3. 数据量适中:时间序列 5-15 个点,分类 3-10 个类别
50
+
51
+ **输出标注**:必须在输出中明确标注「⚠️ 已使用示例数据,非真实数据」
52
+
53
+ ---
54
+
55
+ ## 数据格式转换规则
56
+
57
+ ### CSV → ECharts
58
+
59
+ CSV 内容示例:
60
+ ```csv
61
+ 年份,GDP,人均GDP
62
+ 2020,101.4,7.2
63
+ 2021,114.9,8.1
64
+ 2022,121.0,8.5
65
+ ```
66
+
67
+ 转换规则:
68
+ 1. 第一行为列名(维度名 + 系列名)
69
+ 2. 第一列默认为 xAxis 分类轴
70
+ 3. 后续列各为一个 series
71
+
72
+ 对应的 ECharts 格式:
73
+ ```javascript
74
+ xAxis: { type: 'category', data: ['2020', '2021', '2022'] },
75
+ series: [
76
+ { name: 'GDP', type: 'line', data: [101.4, 114.9, 121.0] },
77
+ { name: '人均GDP', type: 'line', data: [7.2, 8.1, 8.5] }
78
+ ]
79
+ ```
80
+
81
+ ### JSON → ECharts
82
+
83
+ JSON 数组:
84
+ ```json
85
+ [
86
+ { "年份": "2020", "GDP": 101.4, "人均GDP": 7.2 },
87
+ { "年份": "2021", "GDP": 114.9, "人均GDP": 8.1 }
88
+ ]
89
+ ```
90
+
91
+ 转换为:
92
+ ```javascript
93
+ // 取第一个 key 为 xAxis
94
+ xAxis: { type: 'category', data: ['2020', '2021'] },
95
+ // 其余 key 各为 series
96
+ series: [
97
+ { name: 'GDP', type: 'line', data: [101.4, 114.9] },
98
+ { name: '人均GDP', type: 'line', data: [7.2, 8.1] }
99
+ ]
100
+ ```
101
+
102
+ JSON 对象(键值对):
103
+ ```json
104
+ { "北京": 2154, "上海": 3815, "广州": 2501 }
105
+ ```
106
+
107
+ 转换为:
108
+ ```javascript
109
+ // 饼图
110
+ series: [{
111
+ type: 'pie',
112
+ data: [
113
+ { name: '北京', value: 2154 },
114
+ { name: '上海', value: 3815 },
115
+ { name: '广州', value: 2501 }
116
+ ]
117
+ }]
118
+
119
+ // 柱状图
120
+ xAxis: { type: 'category', data: ['北京', '上海', '广州'] },
121
+ series: [{ type: 'bar', data: [2154, 3815, 2501] }]
122
+ ```
123
+
124
+ ### Web 搜索结果 → ECharts
125
+
126
+ 从网页表格提取:
127
+ 1. 识别 `<table>` 或 Markdown 表格
128
+ 2. 提取表头为列名,提取数据行为数值
129
+ 3. 按 CSV 转换规则处理
130
+
131
+ 从网页文本提取:
132
+ 1. 识别「年份+数值」或「名称+数值」模式
133
+ 2. 手动整理为键值对格式
134
+ 3. 按 JSON 对象转换规则处理
135
+
136
+ ---
137
+
138
+ ## 数据质量检查
139
+
140
+ 生成 option 前必须检查:
141
+
142
+ 1. **数值有效性**:所有数值可解析为数字(`!isNaN(Number(value))`)
143
+ 2. **维度一致性**:xAxis.data 长度与每个 series.data 长度一致
144
+ 3. **数值规模**:差异过大(如一个系列 1000-2000,另一个 0.1-0.5)→ 考虑双 yAxis
145
+ 4. **空值处理**:缺失值用 `null` 或 `'-'` 替代(ECharts 会断开连线)
146
+ 5. **中文/特殊字符**:确保 UTF-8 编码正确处理
147
+
148
+ ### 异常数据处理
149
+
150
+ ```javascript
151
+ // 清洗示例
152
+ function cleanValue(val) {
153
+ if (val === null || val === undefined || val === '') return null;
154
+ var num = Number(String(val).replace(/[,%¥$]/g, '').trim());
155
+ return isNaN(num) ? null : num;
156
+ }
157
+ ```
158
+
159
+ ---
160
+
161
+ ## 双 yAxis 使用准则
162
+
163
+ 满足以下条件时使用双 yAxis:
164
+
165
+ - 两个系列的数值量级相差 10 倍以上
166
+ - 两个系列的数值单位不同(如「亿元」和「%」)
167
+
168
+ ```javascript
169
+ yAxis: [
170
+ { type: 'value', name: 'GDP(万亿元)' },
171
+ { type: 'value', name: '增长率(%)' }
172
+ ],
173
+ series: [
174
+ { name: 'GDP', type: 'bar', data: [...] }, // 使用左侧 yAxis
175
+ { name: '增长率', type: 'line', yAxisIndex: 1, data: [...] } // 使用右侧 yAxis
176
+ ]
177
+ ```
178
+
179
+ ---
180
+
181
+ ## 示例数据生成指引
182
+
183
+ 当使用示例数据时,确保:
184
+
185
+ - **时间序列**:生成 5-15 个时间点,数值体现合理趋势(上升/下降/波动)
186
+ - **分类对比**:3-10 个分类,数值适度差异(不至于全一样)
187
+ - **占比**:各部分真实加总等于整体的概念
188
+ - **地域**:至少包含 5 个以上省份/城市
189
+ - **标注**:数据前加注释 `// ⚠️ 示例数据,非真实数据`
190
+
191
+ ```javascript
192
+ // ⚠️ 示例数据,非真实数据
193
+ var exampleData = {
194
+ years: ['2016', '2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025'],
195
+ gdp: [74.6, 83.2, 91.9, 98.7, 101.4, 114.9, 121.0, 126.1, 134.9, 143.2],
196
+ growthRate: [6.8, 6.9, 6.7, 6.0, 2.2, 8.4, 3.0, 5.2, 5.0, 4.8]
197
+ };
198
+ ```