拼ui 一些业务逻辑x实现
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
# Runtime Data Injection (UI Toolkit)
|
||||
|
||||
This chapter explains how to inject data into `ChartElement` at runtime in a UI Toolkit workflow.
|
||||
|
||||
Related component: `EasyChartDataSource`
|
||||
|
||||
---
|
||||
|
||||
## 1. When should you use this approach?
|
||||
|
||||
- Your chart is built with UI Toolkit (`UIDocument` + UXML + `ChartElement`)
|
||||
- You want a set of injection APIs that are easier to call from gameplay/business logic (labels / values / x-y / pie / ring)
|
||||
- Or you want to inject a JSON payload directly (`ChartFeed`)
|
||||
|
||||
---
|
||||
|
||||
## 2. Quick start (recommended flow)
|
||||
|
||||
1. Prepare a `UIDocument` in the scene, and make sure there is a `ChartElement` in your UXML.
|
||||
2. Add `EasyChartDataSource` to the same GameObject that has the `UIDocument`.
|
||||
3. Fill in the Inspector fields:
|
||||
- `uiDocument`
|
||||
- `chartElementName` (default: `main-chart`, matches the `name` of the `ChartElement` in UXML)
|
||||
- `profile` (optional, but strongly recommended: lets style/Series type come from an editor-authored `ChartProfile`)
|
||||
4. At runtime, call from code:
|
||||
- `SetCategoryLabels(...)`
|
||||
- `SetSeriesValues(...)` / `SetSeriesXY(...)`
|
||||
- or `ApplyJson(...)`
|
||||
|
||||
Internally, the component will:
|
||||
|
||||
- Find the target `ChartElement` from `UIDocument.rootVisualElement`
|
||||
- Initialize chart data from `profile` when needed
|
||||
- Modify `ChartElement.Data` and call `RefreshData()`
|
||||
|
||||
---
|
||||
|
||||
## 3. Inspector fields
|
||||
|
||||
Key fields of `EasyChartDataSource`:
|
||||
|
||||
- `uiDocument`
|
||||
- Points to the current UI `UIDocument`.
|
||||
- If not set, the script will try `GetComponent<UIDocument>()`.
|
||||
|
||||
- `chartElementName`
|
||||
- The `name` of the target `ChartElement` (the UXML/USS name). Default is `main-chart`.
|
||||
- If you want JSON `chartId/chartName` to locate the chart automatically, keep the `ChartElement.name` consistent with those values (see section 5).
|
||||
|
||||
- `profile`
|
||||
- Optional.
|
||||
- If set, the component assigns `ChartElement.Profile = profile` to initialize/preserve styles, Series structure, etc.
|
||||
|
||||
- `playAnimationOnRefresh`
|
||||
- After each injection, call `RefreshData(..., playAnimation: playAnimationOnRefresh)`.
|
||||
|
||||
- `allowCreateSeriesFromFeed`
|
||||
- When injecting via JSON (`ApplyJson`), if a series in the feed does not match any existing Serie:
|
||||
- `false` (default): do not create new Serie; only update matched ones.
|
||||
- `true`: allow creating new Serie from the feed (may rebuild renderers).
|
||||
|
||||
---
|
||||
|
||||
## 4. Common injection APIs (without JSON)
|
||||
|
||||
### 4.1 Set category axis labels
|
||||
|
||||
`SetCategoryLabels(labels, axisId = AxisId.XBottom)`
|
||||
|
||||
- Sets the axis to Category and overwrites `labels`.
|
||||
|
||||
### 4.2 Single-series Y values (auto x=0..n-1)
|
||||
|
||||
`SetSeriesValues("Sales", values)`
|
||||
|
||||
- Finds/creates a Serie by default (default type is Line; it does not force the type to change).
|
||||
- Writes to `SeriesData.value` and sets `SeriesData.x` to the index.
|
||||
|
||||
### 4.3 XY points
|
||||
|
||||
`SetSeriesXY("Scatter", x, y)`
|
||||
|
||||
- Writes `x[]` into `SeriesData.x` and `y[]` into `SeriesData.value`.
|
||||
|
||||
### 4.4 Pie / Ring injection
|
||||
|
||||
- `SetPie(serieName, names, values)`
|
||||
- Forces the Serie type to `Pie`.
|
||||
- Uses `SeriesData.name` as slice name and `SeriesData.value` as slice value.
|
||||
|
||||
- `SetRing(serieName, names, percents)`
|
||||
- Forces the Serie type to `RingChart`.
|
||||
- Uses `SeriesData.name` as ring name and `SeriesData.value` as progress value.
|
||||
|
||||
---
|
||||
|
||||
## 5. JSON injection (ChartFeed)
|
||||
|
||||
You can call: `ApplyJson(json)`
|
||||
|
||||
This method parses JSON into `ChartFeed` and applies it to `ChartElement.Data`.
|
||||
|
||||
### 5.1 `ChartFeed` schema
|
||||
|
||||
```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 }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
See the runtime code `Scripts/Runtime/Feed/ChartFeed.cs` for the exact fields.
|
||||
|
||||
### 5.2 ChartElement lookup rules (`chartId` / `chartName`)
|
||||
|
||||
Internally, `ApplyJson` tries:
|
||||
|
||||
- If `chartId` is provided: `rootVisualElement.Q<ChartElement>(chartId)` first
|
||||
- Else if `chartName` is provided: try `Q<ChartElement>(chartName)`
|
||||
- If still not found: fall back to `chartElementName` (default `main-chart`)
|
||||
|
||||
Therefore:
|
||||
|
||||
- If you only have one chart, keeping the default is fine.
|
||||
- If you have multiple `ChartElement` in one UI, it's recommended to align each chart's `name` with the feed `chartId` or `chartName`.
|
||||
|
||||
### 5.3 Series matching and type override
|
||||
|
||||
`ApplyJson` checks whether the JSON contains `"type":`. If present, it assumes you want to allow type override (`allowTypeOverride=true`).
|
||||
|
||||
Serie matching rules:
|
||||
|
||||
- If `serieId` is not empty: match by `Serie.id`
|
||||
- Else if `name` is not empty: match by `Serie.name`
|
||||
- Else (index mode): match by feed index (i-th to i-th)
|
||||
|
||||
When no Serie can be matched:
|
||||
|
||||
- `allowCreateSeriesFromFeed=false` (default): the feed series is skipped (no creation).
|
||||
- `allowCreateSeriesFromFeed=true`: create a new Serie using the feed `type/name/serieId`.
|
||||
|
||||
For matched Serie:
|
||||
|
||||
- Only when `allowTypeOverride=true` and it's not index mode, overriding `id/name/type` is allowed.
|
||||
|
||||
---
|
||||
|
||||
## 6. Common issues & troubleshooting
|
||||
|
||||
- **Not visible / TryGetChart failed**
|
||||
- Make sure `uiDocument` is assigned correctly
|
||||
- Make sure the `ChartElement` `name` in UXML matches `chartElementName`
|
||||
|
||||
- **JSON parse failed**
|
||||
- When `EasyChartDataSource` parses JSON:
|
||||
- it tries Newtonsoft first (if `Newtonsoft.Json` exists in your project)
|
||||
- otherwise falls back to Unity `JsonUtility`, normalizing string forms like `type/axisId` into enum integers before parsing
|
||||
- Recommendation: start from a known-good JSON (e.g. generated from the editor JSON panel) and modify it.
|
||||
|
||||
- **Series mismatch after injection / updated the wrong line**
|
||||
- Prefer `serieId` for stable matching.
|
||||
- If you only use `name` and there are multiple series with the same name, the script uses the first one and logs a warning.
|
||||
|
||||
- **JSON wanted to add a Serie but none was added**
|
||||
- Enable `allowCreateSeriesFromFeed`.
|
||||
Reference in New Issue
Block a user