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)
- Prepare a
UIDocumentin the scene, and make sure there is aChartElementin your UXML. - Add
EasyChartDataSourceto the same GameObject that has theUIDocument. - Fill in the Inspector fields:
uiDocumentchartElementName(default:main-chart, matches thenameof theChartElementin UXML)profile(optional, but strongly recommended: lets style/Series type come from an editor-authoredChartProfile)
- At runtime, call from code:
SetCategoryLabels(...)SetSeriesValues(...)/SetSeriesXY(...)- or
ApplyJson(...)
Internally, the component will:
- Find the target
ChartElementfromUIDocument.rootVisualElement - Initialize chart data from
profilewhen needed - Modify
ChartElement.Dataand callRefreshData()
3. Inspector fields
Key fields of EasyChartDataSource:
-
uiDocument- Points to the current UI
UIDocument. - If not set, the script will try
GetComponent<UIDocument>().
- Points to the current UI
-
chartElementName- The
nameof the targetChartElement(the UXML/USS name). Default ismain-chart. - If you want JSON
chartId/chartNameto locate the chart automatically, keep theChartElement.nameconsistent with those values (see section 5).
- The
-
profile- Optional.
- If set, the component assigns
ChartElement.Profile = profileto initialize/preserve styles, Series structure, etc.
-
playAnimationOnRefresh- After each injection, call
RefreshData(..., playAnimation: playAnimationOnRefresh).
- After each injection, call
-
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).
- When injecting via JSON (
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.valueand setsSeriesData.xto the index.
4.3 XY points
SetSeriesXY("Scatter", x, y)
- Writes
x[]intoSeriesData.xandy[]intoSeriesData.value.
4.4 Pie / Ring injection
-
SetPie(serieName, names, values)- Forces the Serie type to
Pie. - Uses
SeriesData.nameas slice name andSeriesData.valueas slice value.
- Forces the Serie type to
-
SetRing(serieName, names, percents)- Forces the Serie type to
RingChart. - Uses
SeriesData.nameas ring name andSeriesData.valueas progress value.
- Forces the Serie type to
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
{
"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
chartIdis provided:rootVisualElement.Q<ChartElement>(chartId)first - Else if
chartNameis provided: tryQ<ChartElement>(chartName) - If still not found: fall back to
chartElementName(defaultmain-chart)
Therefore:
- If you only have one chart, keeping the default is fine.
- If you have multiple
ChartElementin one UI, it’s recommended to align each chart’snamewith the feedchartIdorchartName.
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
serieIdis not empty: match bySerie.id - Else if
nameis not empty: match bySerie.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 feedtype/name/serieId.
For matched Serie:
- Only when
allowTypeOverride=trueand it’s not index mode, overridingid/name/typeis allowed.
6. Common issues & troubleshooting
-
Not visible / TryGetChart failed
- Make sure
uiDocumentis assigned correctly - Make sure the
ChartElementnamein UXML matcheschartElementName
- Make sure
-
JSON parse failed
- When
EasyChartDataSourceparses JSON:- it tries Newtonsoft first (if
Newtonsoft.Jsonexists in your project) - otherwise falls back to Unity
JsonUtility, normalizing string forms liketype/axisIdinto enum integers before parsing
- it tries Newtonsoft first (if
- Recommendation: start from a known-good JSON (e.g. generated from the editor JSON panel) and modify it.
- When
-
Series mismatch after injection / updated the wrong line
- Prefer
serieIdfor stable matching. - If you only use
nameand there are multiple series with the same name, the script uses the first one and logs a warning.
- Prefer
-
JSON wanted to add a Serie but none was added
- Enable
allowCreateSeriesFromFeed.
- Enable