拼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,155 @@
# 运行时数据注入(UGUI
对应脚本:`UGUIRuntimeJsonInjection``UGUIRuntimeJsonInjectionEditor`
本章介绍:在 UGUI 工作流(`UGUIChartBridge`)下,如何通过 JSON 在运行时把数据注入到图表中。
---
## 1. 这套方案适合什么场景?
- 你有一份来自服务器/业务层的 JSON(或你希望在运行时快速手工编辑 JSON)
- 你希望像编辑器里 `JSON Injection` 面板一样,直接“生成示例 → 修改 → 应用”
- 你已经通过 `ChartProfile` 把样式、轴、Series 类型等结构配置好了
这套注入逻辑的定位是:**更新数据为主**,结构变更(比如新增 Series、强行覆盖 Series 类型)不是它的主要目标。
---
## 2. 快速上手(最推荐的流程)
1. 在场景中搭好 `UGUIChartBridge`(并确保 `Profile` 已赋值)。
2. 在同一个 GameObject 上添加组件:`UGUIRuntimeJsonInjection`
3. 点击 **Generate Example JSON** 生成一份与你当前 Profile 匹配的示例 JSON。
4.`JSON Content` 文本框里修改数据。
5. 点击 **Apply JSON to Chart**
你会看到组件内部:
- 解析 JSON → 转成 `ChartFeed`
-`ChartFeed` 应用到 `UGUIChartBridge.Profile`
- 调用 `_bridge.Refresh()` 刷新图表
---
## 3. 组件与 Inspector 字段说明
`UGUIRuntimeJsonInjection` 必须和 `UGUIChartBridge` 在同一个物体上(脚本有 `[RequireComponent(typeof(UGUIChartBridge))]`)。
### 3.1 JSON Generation Settings
- **Example Mode`ChartJsonExampleMode`**
- 控制“生成示例 JSON”时的格式。
- 一般建议先用 `Standard``Standard_Axis`(更直观)。
- **Data Mode`ChartJsonDatasMode`**
- 控制 `datas` 的数据表达方式。
- `Standard``datas` 为对象数组(例如 `{ "x": 0, "value": 12 }`)。
- `Values``datas` 为纯数值数组(更短)。
- 备注:该格式需要走 `ChartJsonUtils` 的“灵活解析器”(基于 Newtonsoft 的反射解析)。如果你的项目里没有 Newtonsoft(`Newtonsoft.Json` / `Unity.Newtonsoft.Json`),可能会解析失败。
- 因此 **推荐默认使用 `Standard`**,除非你确认项目已引入 Newtonsoft。
- **API Envelope`UseApiEnvelope`**
- 生成示例 JSON 时,是否包一层接口返回壳:
- `{ "code": 200, "message": "success", "data": { ...真正的ChartFeed... } }`
- 应用时也会尝试自动从壳里提取 `data`
- **Auto Generate`AutoGenerateJson`**
- 当你切换 `Example Mode / Data Mode / API Envelope` 时,自动重新生成示例 JSON。
### 3.2 JSON Content
- **JSON Content`JsonContent`**
- 你要注入的 JSON 字符串。
- 如果为空,点击 Apply 时会直接警告并返回。
---
## 4. JSON 格式(ChartFeed
底层的数据模型是 `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 }
]
}
]
}
```
字段对应代码:
- `chartId` / `chartName`
-`UGUIRuntimeJsonInjection` 的注入路径里 **不会覆盖** Profile 的 `chartId/chartName`(它调用 `ChartJsonUtils.ApplyFeedToProfile(profile, feed)`,内部 `allowMetaOverwrite=false`)。
- 但这两个字段可以用来帮助别的注入器(例如 `EasyChartDataSource`)在 UI 树里“按名字/ID 寻找 ChartElement”。
- `axes[]`
- `axisId``AxisId` 枚举(如 `XBottom``XTop``YLeft``YRight` 等)。
- `labels` 存在时会把该轴视为 Category,并直接覆盖 labels。
- `series[]`
- **匹配优先级**
- 如果给了 `serieId`:按 `Serie.id` 精确匹配
- 否则如果给了 `name`:按 `Serie.name` 匹配
- 否则(`serieId``name` 都为空):按索引匹配(第 0 个 feed 对应 Profile 第 0 个 serie
- `type`
- 主要用于生成示例 JSON。
- 在当前注入路径中:
- 对已存在且能匹配到的 Serie:**不会强制改类型**(因为这里不允许覆盖 meta)。
- 对“索引模式 + 超出 Profile 数量”而新建出来的 Serie:会使用 feed 里的 `type` 作为新 Serie 的类型。
- `datas[]` 对应每个点:
- `x/y/z/value` 数值
- `id/name`(可选)
- `useColor/color`(可选)
---
## 5. 应用时发生了什么?(注入流程)
点击 **Apply JSON to Chart** 时:
1. 若 JSON 是 API 壳(含 `data` 字段),会先尝试把 `data` 里的对象抽出来。
2. 调用 `ChartJsonUtils.TryDeserializeFeed(json, out feed)` 反序列化为 `ChartFeed`
- 会优先尝试 Newtonsoft(如果项目里有),否则回退到 Unity `JsonUtility`
- `type: "Line"` / `axisId: "XBottom"` 这类字符串,也会在回退路径中被规范化为枚举值再解析。
3. 调用 `ChartJsonUtils.ApplyFeedToProfile(_bridge.Profile, feed)` 把 feed 写回 Profile。
4. 调用 `_bridge.Refresh()` 触发重绘。
---
## 6. 常见问题与排错
- **点击 Apply 没反应 / 控制台有 warningNo UGUIChartBridge or ChartProfile found**
- 确认对象上有 `UGUIChartBridge`
- 确认 `UGUIChartBridge.Profile` 已赋值
- **报错:Failed to parse JSON**
- 先用 Generate 生成一份能解析的 JSON,再在它的基础上改。
- 如果你的接口返回有外层包裹,优先勾选 `API Envelope`,或确保 JSON 的 `data` 字段内才是 `ChartFeed`
- **JSON 生效了但数据没变 / 只变了一部分**
- 检查 `series` 的匹配方式(`serieId` / `name` / 索引模式)。
- 如果你使用的是 `serieId/name` 匹配:确保 Profile 里确实存在对应的 Serie(该注入路径在这种模式下不会自动创建新 Serie)。
- 如果你使用的是“索引模式”(`serieId``name` 都为空):
- 当 feed 的 `series[]` 数量 **超过** Profile 的 Series 数量时,会自动补创建新的 Serie。
- 如果你不希望自动创建,请给每条 serie 明确填 `name``serieId`
- **在编辑器 PlayMode 注入后,Profile 资产被改脏了**
- 注入的本质是“把 feed 应用到 `ChartProfile` 上”。如果你把资产直接拖到桥接上,运行时改动可能会让该资产处于 dirty 状态。
- 如果你不希望影响资产,建议在运行时对 Profile 做一份实例化拷贝再注入。