拼ui 一些业务逻辑x实现

This commit is contained in:
2026-03-19 06:15:09 +08:00
parent f5c6f143c0
commit 49e45ac464
1118 changed files with 246518 additions and 5368 deletions
@@ -0,0 +1,182 @@
# 运行时数据注入(UIToolKit
本章介绍:在 UI Toolkit 工作流下,如何在运行时给 `ChartElement` 注入数据。
对应脚本:`EasyChartDataSource`
---
## 1. 这套方案适合什么场景?
- 你的图表是 UI Toolkit 体系(`UIDocument` + UXML + `ChartElement`
- 你希望提供一套“业务侧更容易调用”的注入 APIlabels / values / x-y / pie / ring
- 或者你希望直接拿一段 JSON 注入(`ChartFeed`
---
## 2. 快速上手(最推荐的流程)
1. 在场景里准备 `UIDocument`,并确保 UXML 里有 `ChartElement`
2. 在挂着 `UIDocument` 的 GameObject 上添加组件:`EasyChartDataSource`
3. 在 Inspector 里填写:
- `uiDocument`
- `chartElementName`(默认 `main-chart`,对应 UXML 中 `ChartElement``name`
- `profile`(可选,但强烈建议填:让样式/Series 类型来自你在编辑器配置好的 `ChartProfile`
4. 在运行时用代码调用:
- `SetCategoryLabels(...)`
- `SetSeriesValues(...)` / `SetSeriesXY(...)`
-`ApplyJson(...)`
组件内部会:
-`UIDocument.rootVisualElement` 里找到目标 `ChartElement`
- 必要时用 `profile` 初始化图表 Data
- 修改 `ChartElement.Data` 并调用 `RefreshData()`
---
## 3. Inspector 字段说明
`EasyChartDataSource` 的核心配置字段:
- `uiDocument`
- 指向当前 UI 的 `UIDocument`
- 如果不填,脚本会尝试 `GetComponent<UIDocument>()`
- `chartElementName`
- 目标 `ChartElement``name`UXML/USS 的那个 name)。默认值为 `main-chart`
- 如果你希望用 JSON 中的 `chartId/chartName` 自动定位,也可以让 `ChartElement``name` 与之保持一致(见第 5 节)。
- `profile`
- 可选。
- 如果赋值,组件会将 `ChartElement.Profile = profile`,用于初始化/保持样式、Series 结构等。
- `playAnimationOnRefresh`
- 每次注入后调用 `RefreshData(..., playAnimation: playAnimationOnRefresh)`
- `allowCreateSeriesFromFeed`
- 当你用 JSON`ApplyJson`)注入时,如果 feed 中的 series 无法匹配到现有 Serie
- `false`(默认):不创建新 Serie,只更新匹配到的部分。
- `true`:允许根据 feed 创建新的 Serie(可能触发重建 renderers)。
---
## 4. 常用注入 API(不写 JSON
### 4.1 设置类目轴标签
`SetCategoryLabels(labels, axisId = AxisId.XBottom)`
- 会把该轴设为 Category,并覆盖 `labels`
### 4.2 单序列 y 值(自动 x=0..n-1
`SetSeriesValues("Sales", values)`
- 默认会找到/创建一条 Serie(默认类型为 Line,不强制改类型)。
- 写入 `SeriesData.value`,并把 `SeriesData.x` 设为索引。
### 4.3 XY 点
`SetSeriesXY("Scatter", x, y)`
-`x[]` 写入 `SeriesData.x`,把 `y[]` 写入 `SeriesData.value`
### 4.4 Pie / Ring 注入
- `SetPie(serieName, names, values)`
- 强制该 Serie 为 `Pie` 类型。
- 使用 `SeriesData.name` 作为切片名,`SeriesData.value` 为数值。
- `SetRing(serieName, names, percents)`
- 强制该 Serie 为 `RingChart` 类型。
- 使用 `SeriesData.name` 作为环名,`SeriesData.value` 为进度值。
---
## 5. JSON 注入(ChartFeed
你可以用:`ApplyJson(json)`
该方法会把 JSON 解析为 `ChartFeed` 并应用到 `ChartElement.Data`
### 5.1 `ChartFeed` 结构
```json
{
"chartId": "optional",
"chartName": "optional",
"axes": [
{
"axisId": "XBottom",
"labels": ["Mon", "Tue", "Wed"]
}
],
"series": [
{
"serieId": "optional",
"name": "optional",
"type": "Line",
"datas": [
{ "x": 0, "value": 12 },
{ "x": 1, "value": 18 }
]
}
]
}
```
对应字段见运行时代码 `Scripts/Runtime/Feed/ChartFeed.cs`
### 5.2 ChartElement 的定位规则(`chartId` / `chartName`
`ApplyJson` 内部会尝试:
- 如果 feed 提供了 `chartId`:优先 `rootVisualElement.Q<ChartElement>(chartId)`
- 其次如果提供了 `chartName`:尝试 `Q<ChartElement>(chartName)`
- 都找不到才退回到 `chartElementName`(默认 `main-chart`
因此:
- 如果你只有一个图表,保持默认值也没问题。
- 如果你一个 UI 里有多个 `ChartElement`,建议让每个图表的 `name` 与 feed 的 `chartId``chartName` 对齐。
### 5.3 series 匹配与类型覆盖
`ApplyJson` 会先检查 JSON 内是否出现过 `"type":`,若出现则认为你希望允许类型覆盖(`allowTypeOverride=true`)。
Serie 匹配规则:
- 如果 `serieId` 非空:按 `Serie.id` 匹配
- 否则如果 `name` 非空:按 `Serie.name` 匹配
- 否则(索引模式):按 feed 的序号匹配(第 i 条对第 i 条)
当无法匹配到 Serie 时:
- `allowCreateSeriesFromFeed=false`(默认):该条 feed 会被跳过(不创建)。
- `allowCreateSeriesFromFeed=true`:会创建新的 Serie,并使用 feed 的 `type/name/serieId`
对已匹配到的 Serie
- 仅当 `allowTypeOverride=true` 且不是索引模式时,才会允许覆盖 `id/name/type`
---
## 6. 常见问题与排错
- **不显示 / TryGetChart 失败**
- 确认 `uiDocument` 赋值正确
- 确认 UXML 中 `ChartElement``name``chartElementName` 一致
- **JSON 解析失败**
- `EasyChartDataSource` 解析 JSON 时:
- 会优先尝试 Newtonsoft(若项目里存在 `Newtonsoft.Json`
- 否则使用 Unity `JsonUtility`,并把 `type/axisId` 的字符串写法转换为枚举整数再解析
- 建议先用一份已知能解析的 JSON(例如从编辑器 JSON 面板生成)再改。
- **注入后 Series 对不上 / 更新错了线**
- 优先使用 `serieId` 做稳定匹配。
- 如果只用 `name`,且同名 Serie 存在多个,脚本会使用第一个并给 warning。
- **JSON 想新增 Serie 但没新增**
-`allowCreateSeriesFromFeed` 打开。