运行时数据注入(UGUI)
对应脚本:UGUIRuntimeJsonInjection、UGUIRuntimeJsonInjectionEditor
本章介绍:在 UGUI 工作流(UGUIChartBridge)下,如何通过 JSON 在运行时把数据注入到图表中。
1. 这套方案适合什么场景?
- 你有一份来自服务器/业务层的 JSON(或你希望在运行时快速手工编辑 JSON)
- 你希望像编辑器里
JSON Injection面板一样,直接“生成示例 → 修改 → 应用” - 你已经通过
ChartProfile把样式、轴、Series 类型等结构配置好了
这套注入逻辑的定位是:更新数据为主,结构变更(比如新增 Series、强行覆盖 Series 类型)不是它的主要目标。
2. 快速上手(最推荐的流程)
- 在场景中搭好
UGUIChartBridge(并确保Profile已赋值)。 - 在同一个 GameObject 上添加组件:
UGUIRuntimeJsonInjection。 - 点击 Generate Example JSON 生成一份与你当前 Profile 匹配的示例 JSON。
- 在
JSON Content文本框里修改数据。 - 点击 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。
- 生成示例 JSON 时,是否包一层接口返回壳:
-
Auto Generate(
AutoGenerateJson)- 当你切换
Example Mode / Data Mode / API Envelope时,自动重新生成示例 JSON。
- 当你切换
3.2 JSON Content
- JSON Content(
JsonContent)- 你要注入的 JSON 字符串。
- 如果为空,点击 Apply 时会直接警告并返回。
4. JSON 格式(ChartFeed)
底层的数据模型是 ChartFeed:
{
"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 时:
- 若 JSON 是 API 壳(含
data字段),会先尝试把data里的对象抽出来。 - 调用
ChartJsonUtils.TryDeserializeFeed(json, out feed)反序列化为ChartFeed。- 会优先尝试 Newtonsoft(如果项目里有),否则回退到 Unity
JsonUtility。 type: "Line"/axisId: "XBottom"这类字符串,也会在回退路径中被规范化为枚举值再解析。
- 会优先尝试 Newtonsoft(如果项目里有),否则回退到 Unity
- 调用
ChartJsonUtils.ApplyFeedToProfile(_bridge.Profile, feed)把 feed 写回 Profile。 - 调用
_bridge.Refresh()触发重绘。
6. 常见问题与排错
-
点击 Apply 没反应 / 控制台有 warning:No 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。
- 当 feed 的
- 检查
-
在编辑器 PlayMode 注入后,Profile 资产被改脏了
- 注入的本质是“把 feed 应用到
ChartProfile上”。如果你把资产直接拖到桥接上,运行时改动可能会让该资产处于 dirty 状态。 - 如果你不希望影响资产,建议在运行时对 Profile 做一份实例化拷贝再注入。
- 注入的本质是“把 feed 应用到