Skip to content

Commit 390baf6

Browse files
committed
chore: 优化 scale skill
1 parent 197b5be commit 390baf6

6 files changed

Lines changed: 103 additions & 39 deletions

File tree

cli/index/full.index.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,14 +1187,15 @@
11871187
"在图表中添加标注层"
11881188
],
11891189
"anti_patterns": [
1190-
"只有单个 Mark 时不需要 view 容器,直接用对应 type 即可"
1190+
"只有单个 Mark 时不需要 view 容器,直接用对应 type 即可",
1191+
"children 中嵌套 type: 'view'——当某个子 Mark 需要独立数据时,直接在该 Mark 上指定 data 字段,而非再套一层 view + children"
11911192
],
11921193
"related": [
11931194
"g2-core-chart-init",
11941195
"g2-comp-annotation",
11951196
"g2-comp-facet-rect"
11961197
],
1197-
"embedding_text": "Title: G2 视图组合(view + children)\nDescription: G2 v5 通过 type: 'view' 容器和 children 数组实现多 Mark 叠加、\nTags: view, children, 视图组合, 多Mark叠加, layer, 复合图表, spec\nUse Cases: 在同一坐标系中叠加多种图形(折线+散点、面积+折线); 为多个子 Mark 共享数据源; 在图表中添加标注层\nAnti-patterns: 只有单个 Mark 时不需要 view 容器,直接用对应 type 即可\n## 核心概念\n\n```\nchart.options({\n type: 'view', // 容器类型\n [...], // 父级数据(子 Mark 可继承)\n encode: {...}, // 父级编码(子 Mark 可继承)\n children: [ // 子 Mark 列表(按顺序渲染,后面的在上层)\n { type: 'area', ... },\n { type: 'line', ... },\n { type: 'point', ... },\n ],\n});\n```\n\n**数据继承规则**:\n- 子 Mark 若未指定 `data`,继承父级 `data`\n- 子 Mark 若未指定 `encode`,继承父级 `encode` 中对应通道\n\n\n## 常见错误与修正\n"
1198+
"embedding_text": "Title: G2 视图组合(view + children)\nDescription: G2 v5 通过 type: 'view' 容器和 children 数组实现多 Mark 叠加、\nTags: view, children, 视图组合, 多Mark叠加, layer, 复合图表, spec\nUse Cases: 在同一坐标系中叠加多种图形(折线+散点、面积+折线); 为多个子 Mark 共享数据源; 在图表中添加标注层\nAnti-patterns: 只有单个 Mark 时不需要 view 容器,直接用对应 type 即可; children 中嵌套 type: 'view'——当某个子 Mark 需要独立数据时,直接在该 Mark 上指定 data 字段,而非再套一层 view + children\n## 核心概念\n\n```\nchart.options({\n type: 'view', // 容器类型\n [...], // 父级数据(子 Mark 可继承)\n encode: {...}, // 父级编码(子 Mark 可继承)\n children: [ // 子 Mark 列表(按顺序渲染,后面的在上层)\n { type: 'area', ... },\n { type: 'line', ... },\n { type: 'point', ... },\n ],\n});\n```\n\n**数据继承规则**:\n- 子 Mark 若未指定 `data`,继承父级 `data`\n- 子 Mark 若未指定 `encode`,继承父级 `encode` 中对应通道\n\n\n## 常见错误与修正\n"
11981199
},
11991200
{
12001201
"id": "g2-data-ema",

cli/index/g2.index.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,14 +1187,15 @@
11871187
"在图表中添加标注层"
11881188
],
11891189
"anti_patterns": [
1190-
"只有单个 Mark 时不需要 view 容器,直接用对应 type 即可"
1190+
"只有单个 Mark 时不需要 view 容器,直接用对应 type 即可",
1191+
"children 中嵌套 type: 'view'——当某个子 Mark 需要独立数据时,直接在该 Mark 上指定 data 字段,而非再套一层 view + children"
11911192
],
11921193
"related": [
11931194
"g2-core-chart-init",
11941195
"g2-comp-annotation",
11951196
"g2-comp-facet-rect"
11961197
],
1197-
"embedding_text": "Title: G2 视图组合(view + children)\nDescription: G2 v5 通过 type: 'view' 容器和 children 数组实现多 Mark 叠加、\nTags: view, children, 视图组合, 多Mark叠加, layer, 复合图表, spec\nUse Cases: 在同一坐标系中叠加多种图形(折线+散点、面积+折线); 为多个子 Mark 共享数据源; 在图表中添加标注层\nAnti-patterns: 只有单个 Mark 时不需要 view 容器,直接用对应 type 即可\n## 核心概念\n\n```\nchart.options({\n type: 'view', // 容器类型\n [...], // 父级数据(子 Mark 可继承)\n encode: {...}, // 父级编码(子 Mark 可继承)\n children: [ // 子 Mark 列表(按顺序渲染,后面的在上层)\n { type: 'area', ... },\n { type: 'line', ... },\n { type: 'point', ... },\n ],\n});\n```\n\n**数据继承规则**:\n- 子 Mark 若未指定 `data`,继承父级 `data`\n- 子 Mark 若未指定 `encode`,继承父级 `encode` 中对应通道\n\n\n## 常见错误与修正\n"
1198+
"embedding_text": "Title: G2 视图组合(view + children)\nDescription: G2 v5 通过 type: 'view' 容器和 children 数组实现多 Mark 叠加、\nTags: view, children, 视图组合, 多Mark叠加, layer, 复合图表, spec\nUse Cases: 在同一坐标系中叠加多种图形(折线+散点、面积+折线); 为多个子 Mark 共享数据源; 在图表中添加标注层\nAnti-patterns: 只有单个 Mark 时不需要 view 容器,直接用对应 type 即可; children 中嵌套 type: 'view'——当某个子 Mark 需要独立数据时,直接在该 Mark 上指定 data 字段,而非再套一层 view + children\n## 核心概念\n\n```\nchart.options({\n type: 'view', // 容器类型\n [...], // 父级数据(子 Mark 可继承)\n encode: {...}, // 父级编码(子 Mark 可继承)\n children: [ // 子 Mark 列表(按顺序渲染,后面的在上层)\n { type: 'area', ... },\n { type: 'line', ... },\n { type: 'point', ... },\n ],\n});\n```\n\n**数据继承规则**:\n- 子 Mark 若未指定 `data`,继承父级 `data`\n- 子 Mark 若未指定 `encode`,继承父级 `encode` 中对应通道\n\n\n## 常见错误与修正\n"
11981199
},
11991200
{
12001201
"id": "g2-data-ema",

skills/g2/references/core/g2-core-view-composition.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use_cases:
3030

3131
anti_patterns:
3232
- "只有单个 Mark 时不需要 view 容器,直接用对应 type 即可"
33+
- "children 中嵌套 type: 'view'——当某个子 Mark 需要独立数据时,直接在该 Mark 上指定 data 字段,而非再套一层 view + children"
3334

3435
difficulty: "intermediate"
3536
completeness: "full"
@@ -159,7 +160,54 @@ chart.options({
159160
});
160161
```
161162

162-
### 错误 2:子 Mark 的 encode 字段名与数据不匹配
163+
### 错误 2:children 中嵌套 view(为子 Mark 单独变换数据时的常见误区)
164+
165+
```javascript
166+
// ❌ 错误:在 children 里再套一层 type:'view' + children
167+
chart.options({
168+
type: 'view',
169+
data,
170+
children: [
171+
{ type: 'line', encode: { x: 'time', y: 'value' } },
172+
{
173+
type: 'view', // ❌ 不必要的嵌套 view
174+
data: data.map(d => ({ // 只是想用派生数据
175+
time: d.time,
176+
min: d.value - 0.1,
177+
max: d.value + 0.1,
178+
})),
179+
children: [
180+
{ type: 'rangeY', encode: { x: 'time', y: 'min', y1: 'max' } },
181+
],
182+
},
183+
],
184+
});
185+
186+
// ✅ 正确:直接在子 Mark 上指定 data,无需嵌套 view
187+
chart.options({
188+
type: 'view',
189+
data,
190+
children: [
191+
{ type: 'line', encode: { x: 'time', y: 'value' } },
192+
{
193+
type: 'rangeY',
194+
data: data.map(d => ({ // ✅ 直接在 Mark 上声明独立 data
195+
time: d.time,
196+
min: d.value - 0.1,
197+
max: d.value + 0.1,
198+
})),
199+
encode: { x: 'time', y: 'min', y1: 'max' },
200+
style: { fillOpacity: 0.1 },
201+
},
202+
],
203+
});
204+
```
205+
206+
**规则**`children` 数组的每个元素必须是 Mark(`line`/`point`/`interval` 等),
207+
当某个 Mark 需要独立或派生数据时,在该 Mark 节点上直接写 `data`,而不是再包一层 `view`
208+
G2 不支持在 `children` 内嵌套 `view`
209+
210+
### 错误 3:子 Mark 的 encode 字段名与数据不匹配
163211
```javascript
164212
// ❌ 错误:父级和子级 encode 的字段名应保持一致
165213
chart.options({

skills/g2/references/recipes/g2-recipe-timeseries-compare.md

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,7 @@ chart.options({
116116
y: 'count',
117117
color: 'metric',
118118
},
119-
scale: {
120-
x: { type: 'time' }, // 字符串日期需显式声明
121-
},
119+
// 无需 scale.x.type,data 中已使用 new Date(),G2 自动识别
122120
labels: [
123121
{
124122
text: 'metric',
@@ -178,9 +176,6 @@ chart.options({
178176
style: { lineWidth: 2 },
179177
},
180178
],
181-
scale: {
182-
x: { type: 'time' },
183-
},
184179
axis: {
185180
x: { labelFormatter: 'YYYY-MM' },
186181
y: { labelFormatter: (v) => `${(v/10000).toFixed(1)}` },
@@ -238,25 +233,26 @@ chart.options({
238233

239234
## 常见错误与修正
240235

241-
### 错误:字符串日期未声明 time scale 导致排序错乱
236+
### 错误:日期用字符串而非 Date 对象,导致排序错乱
242237
```javascript
243-
// ❌ 错误:字符串日期默认被当作分类,按数据原始顺序排列
238+
// ❌ 错误:字符串日期在数据乱序时 x 轴按原始顺序渲染
244239
chart.options({
245240
type: 'line',
246241
data: [
247242
{ date: '2024-03', value: 130 },
248243
{ date: '2024-01', value: 100 }, // 乱序数据
249244
],
250245
encode: { x: 'date', y: 'value' },
251-
// 缺少 scale: { x: { type: 'time' } },x 轴会按数据顺序显示
252246
});
253247

254-
// ✅ 正确:声明 time scale,G2 自动按时间排序
248+
// ✅ 正确:转为 Date 对象并排序,G2 自动按时间处理,无需 scale.x.type
249+
const data = rawData
250+
.map(d => ({ ...d, date: new Date(d.date) }))
251+
.sort((a, b) => a.date - b.date);
255252
chart.options({
256253
type: 'line',
257254
data,
258255
encode: { x: 'date', y: 'value' },
259-
scale: { x: { type: 'time' } }, // ✅ 字符串日期需要显式声明
260256
});
261257
```
262258

skills/g2/references/scales/g2-scale-time.md

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -99,40 +99,61 @@ chart.options({
9999
});
100100
```
101101

102-
## 字符串日期需显式声明 type
102+
## 字符串日期(推荐转为 Date 对象)
103+
104+
G2 v5 对 `YYYY-MM-DD` 格式的字符串有一定自动识别能力,但行为依赖内部推断,**不稳定**
105+
推荐在数据预处理阶段统一转为 `Date` 对象,避免歧义:
103106

104107
```javascript
105-
// 数据中日期是字符串格式
106-
const data = [
108+
// ✅ 推荐:预处理时转为 Date 对象
109+
const rawData = [
107110
{ date: '2024-01-01', value: 100 },
108111
{ date: '2024-02-01', value: 130 },
109112
];
113+
const data = rawData.map(d => ({ ...d, date: new Date(d.date) }));
110114

111115
chart.options({
112116
type: 'line',
113117
data,
114118
encode: { x: 'date', y: 'value' },
115-
scale: {
116-
x: { type: 'time' }, // 必须显式声明,否则被当作 ordinal scale
117-
},
119+
// 无需 scale.x.type,G2 自动识别 Date 对象为 Time Scale
118120
});
119121
```
120122

123+
**不要**在字符串日期上显式写 `scale: { x: { type: 'time' } }`,这是多余的配置,
124+
且在某些场景(如 fold 后数据类型变化)会引发渲染异常。
125+
121126
## 常见错误与修正
122127

123-
### 错误 1:日期字符串未声明 time scale 导致排序错误
128+
### 错误 1:显式声明 type: 'time'(不必要且有风险)
124129
```javascript
125-
// ❌ 错误:字符串日期不声明 type: 'time',会被当作分类数据,顺序可能错乱
130+
// ❌ 不推荐:在字符串日期上显式写 type: 'time'
131+
chart.options({
132+
type: 'line',
133+
data: [{ date: '2024-01-01', value: 100 }],
134+
encode: { x: 'date', y: 'value' },
135+
scale: { x: { type: 'time' } }, // ❌ 多余,可能引发异常
136+
});
137+
138+
// ✅ 正确:转为 Date 对象,让 G2 自动处理
139+
const data = rawData.map(d => ({ ...d, date: new Date(d.date) }));
140+
chart.options({
141+
type: 'line',
142+
data,
143+
encode: { x: 'date', y: 'value' },
144+
});
145+
```
146+
147+
### 错误 2:数据乱序导致折线错乱
148+
```javascript
149+
// ❌ 错误:数据顺序混乱,折线会连错
126150
const data = [
127-
{ date: '2024-03-01', value: 110 },
128-
{ date: '2024-01-01', value: 100 }, // 数据无序
151+
{ date: new Date('2024-03-01'), value: 110 },
152+
{ date: new Date('2024-01-01'), value: 100 }, // 时间倒序
129153
];
130-
chart.options({ type: 'line', data, encode: { x: 'date', y: 'value' } });
131-
// 结果:x 轴顺序是数据原始顺序,不按时间排序
132-
133-
// ✅ 方案 1:将字符串转为 Date 对象(推荐)
134-
const processedData = data.map(d => ({ ...d, date: new Date(d.date) }));
135154

136-
// ✅ 方案 2:显式声明 time scale
137-
chart.options({ scale: { x: { type: 'time' } } });
155+
// ✅ 正确:按时间排序后再传入
156+
const data = rawData
157+
.map(d => ({ ...d, date: new Date(d.date) }))
158+
.sort((a, b) => a.date - b.date);
138159
```

web/server.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,8 @@ function buildMessages(query, systemPrompt, intent, currentCode) {
168168

169169
// ── AI SDK (unified) ──────────────────────────────────────────────────────────
170170

171-
const {
172-
callAI,
173-
AgentLoop,
174-
PROVIDER_CONFIG: SDK_PROVIDER_CONFIG
175-
} = require('../eval/utils/ai-sdk');
171+
const { callAI, AgentLoop } = require('../eval/utils/ai-sdk');
172+
const { PROVIDERS } = require('../eval/utils/provider-registry');
176173
const ProviderRegistry = require('../eval/utils/provider-registry');
177174
const {
178175
TOOLS,
@@ -191,7 +188,7 @@ function resolveProviderModel(reqProvider, reqModel) {
191188
const model =
192189
reqModel ||
193190
process.env.AI_MODEL ||
194-
SDK_PROVIDER_CONFIG[provider]?.defaultModel ||
191+
PROVIDERS[provider]?.defaultModel ||
195192
'qwen3-coder-480b-a35b-instruct';
196193
return { provider, model };
197194
}

0 commit comments

Comments
 (0)