拼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,73 @@
# Quick Overview
This manual is intended for a workflow where you configure charts (the `ChartProfile` asset) in the Unity Editor via **`EasyChartLibraryWindow`**.
- Menu entry: `EasyChart/Library Editor`
- Manual viewer: `EasyChart/Manual`
---
## Table of Contents
### A. Getting Started & Workflows
- [Quick overview](./00_00-Index.md)
- [Quick start: create your first chart in 2 minutes](./00_01-QuickStart.md)
- [UIToolKit workflow (recommended)](./00_02-WorkflowAndLibrary.md)
- [UGUI workflow](./00_03-UGUIWorkflow.md)
- [Runtime data injection (UIToolKit)](./00_04-RuntimeDataInjectionUIToolKit.md)
- [Runtime data injection (UGUI)](./00_05-RuntimeDataInjectionUGUI.md)
### B. Editor & Panels
- [Editor workflow and panels](./01_01-EditorWorkflow.md)
- [Library panel (asset tree)](./01_02-LibraryPanel.md)
- [JSON Injection panel](./01_03-JsonInjectionPanel.md)
- [Preview panel](./02_04-PreviewPanel.md)
- [Inspector panel](./02_05-InspectorPanel.md)
- [Series panel](./02_06-SeriesPanel.md)
### C. Series Configuration (Goal-Oriented)
- [Line chart](./03_01-LineChart.md)
- [Bar chart](./03_02-BarChart.md)
- [Scatter chart](./03_03-ScatterChart.md)
- [Heatmap chart](./03_04-HeatmapChart.md)
- [Radar chart](./03_05-RadarChart.md)
- [Pie chart](./03_06-PieChart.md)
- [Ring chart](./03_07-RingChart.md)
### D. Reference (Lookup by Field)
- [Common recipes](./04_08-CommonRecipes.md)
- [FAQ (fastest troubleshooting path)](./04_09-FAQ.md)
### E. Updates & Roadmap
- [Roadmap / update plan](./05_01-UpdatePlan.md)
---
## Conventions & Terminology
- **ChartProfile**: A chart configuration asset (reusable; previewable in the editor).
- **Series / Serie**: A data series (e.g. one line in a line chart, or one group of bars in a bar chart).
- **SeriesData**: The set of data points in a series.
- **Axis**: Axis configuration (`AxisType=Category/Value`).
- **Category**: Category axis (uses the `labels` list).
- **Value**: Value axis (continuous numeric range).
---
## Recommended Project Structure
Recommended to create a dedicated folder in your project for chart assets:
- `Assets/EasyChart/Library/Custom/`: your own `ChartProfile` assets
- `Assets/EasyChart/Docs/Manual/`: this manual (Markdown chapters)
---
## Manual Version
- This manual will be kept in sync with EasyChart field and editor feature updates.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 11aa7e499832b984d9612138369fe18c
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/00_00-Index.md
uploadId: 857482
@@ -0,0 +1,93 @@
# Quick Start: Create Your First Chart in 2 Minutes
Goal of this chapter: follow the fastest recommended EasyChart path to complete the loop of **Edit → Export → Use in UI**.
---
## Open the Editor Window
In the Unity menu bar, choose:
- `EasyChart/Library Editor`
You will see a window with sections like a library tree, configuration panels, and a preview area (later chapters explain each area).
---
## Clone a Library (Recommended)
If you want to get started quickly and keep a consistent style, it's recommended to:
- Select an existing Library from the top toolbar (e.g. a built-in Demo library)
- Click **Clone** on the toolbar to create your personal library (e.g. `MyLibrary`)
This way, all subsequent changes happen in your own library, avoiding modifications to the original examples.
---
## Clone a ChartProfile (Recommended)
In the library tree, find a chart (`ChartProfile`) close to what you want, then right-click:
- `Clone`
After cloning, you'll get a new Profile (a "variant" of the original). Select it, and the Inspector on the right will show all editable settings.
---
## Modify Settings and Save
Minimal recommended changes:
- `coordinateSystem`: make sure it matches your intended Series (e.g. Line/Bar/Scatter use `Cartesian2D`)
- `series`: confirm `type` is correct, and fill in `seriesData`
- `axes`: at minimum, make sure X/Y axis types match the meaning of your data
After editing, click the save button on the top toolbar (if your version has it), or let Unity auto-save the asset.
---
## Export to UXML (Reusable in UI Builder)
The recommended workflow is exporting the Profile to a reusable `.uxml`:
- Right-click your Profile in the tree
- Choose `Export to UXML`
The exported UXML will be placed under:
- `Assets/EasyChart/LibraryUxml/` (Mirror/Backup operations also manage exported assets under this root)
---
## Use It in the QuickStart Scene via UIDocument + UI Builder
Open the demo scene:
- `Assets/EasyChart/Demo/Scenes/EasyChart_QuickStart.unity`
Then in the Project window, locate:
- `Assets/EasyChart/Demo/UIToolKit/NewUXMLTemplate.uxml`
Double-click to open it (or open with UI Builder). Next:
- Drag the chart `.uxml` you just exported into the hierarchy of `NewUXMLTemplate.uxml`
- Save the UXML
- Make sure the `UIDocument` in the scene references your updated `NewUXMLTemplate.uxml`
Run the scene, and you should see the chart rendered in the UI Toolkit UI.
---
## Alternative: Export as a UGUI Prefab
If you prefer a UGUI (Canvas/RectTransform) workflow, you can also export the selected Profile as a UGUI prefab in the Library Editor and place it directly into your scene UI (exact menu entry and details depend on your current version).
---
## What to Read Next
- To understand the recommended UI Toolkit workflow: `00_02-WorkflowAndLibrary.md`
- To use charts with UGUI (Canvas/RectTransform): `00_03-UGUIWorkflow.md`
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 2b29849ac25f2d84d966fd376339a0e6
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/00_01-QuickStart.md
uploadId: 857482
@@ -0,0 +1,428 @@
# UI Toolkit Workflow (Recommended)
Goal of this chapter: explain the overall recommended EasyChart approach (primarily for UI Toolkit):
1. Edit `ChartProfile` in the editor with **`EasyChartLibraryWindow`**
2. **Export** `ChartProfile` **to `.uxml`** as your chart library assets
3. Compose pages in UI Toolkit using **UI Builder** / UXML, enabling fast UI assembly
This chapter focuses on **UI Toolkit (recommended)**. If you need the UGUI (Canvas/RectTransform) workflow, see:
- `00_03-UGUIWorkflow.md`
## 0. Why the UI Toolkit workflow is recommended
The key idea is to separate the "chart configuration source" (`ChartProfile`) from the "UI artifact" (exported UXML).
- `ChartProfile`: defines what the chart looks like, which axes it uses, what Series it has, and how data should be interpreted. This is best maintained centrally in the editor.
- Exported `.uxml`: places the chart into a page as a UI Toolkit component. This is best suited for reuse, composition, and version control.
What you get:
- Reusable configuration (multiple pages can share one chart style)
- Composable pages (drag & drop in UI Builder; no need to rebuild UI from scratch each time)
- Clearer collaboration (Profile as the "source", UXML as the "product/component library")
---
## 1. Why export to UXML
In a project, `ChartProfile` describes "what the chart looks like", "which axes it uses", "which Series it has", and "how data points are interpreted".
After exporting to `.uxml`, you get a reusable UI asset for UI Toolkit:
- Can be dragged directly in UI Builder
- Can be reused by multiple pages (same chart style)
- Can be managed by version control and asset pipelines (your "chart library")
---
## 2. Recommended workflow (from configuration to page)
### Step 1: Clone your working library and charts (recommended)
- Open from the Unity menu: `EasyChart/Library Editor`
Recommended process:
- **Clone Library**: clone your own Library first (avoid modifying the built-in demo library directly)
- **Clone ChartProfile**: in your library tree, right-click a Profile close to your target look, then choose `Clone` to create a variant
- Modify in the Inspector on the right:
- `coordinateSystem`
- `series`
- `axes`
> Recommendation: keep your own Profiles under `Assets/EasyChart/Library/Custom/` (or a team-agreed folder).
### Step 2: Export to UXML (generate library assets)
You can export from the Library Editor:
- For a Profile: `Export to UXML`
- For a folder:
- `Export Folder to UXML (Mirror)`
- `Export Folder to UXML (Backup)`
- For all:
- `Export All UXML (Mirror)`
- `Export All UXML (Backup)`
Export root folder:
- `Assets/EasyChart/LibraryUxml/`
With multiple Libraries, the usual structure is:
- `Assets/EasyChart/LibraryUxml/<LibraryName>/...`
The `_Backups` subfolder is used for backup exports (and some JSON backups generated during exporting):
- `Assets/EasyChart/LibraryUxml/<LibraryName>/_Backups/...`
The exported UXML usually looks like:
- A `<ec:ChartElement profile-name="..." />`
- `profile-name` corresponds to the ChartProfile key (usually the asset file name)
- Width/height styles for the chart are written into the UXML as well
> Key point: treat exported `.uxml` as **reusable chart components**, not something you hand-write for every UI.
### Mirror vs Backup (which one should you use?)
- **Mirror**:
- used to "mirror the current Profile state into UXML"
- typically overwrites exports with the same name, and may remove stale files that no longer exist (keep the mirror consistent)
- **Backup**:
- used to "export a snapshot" by time/tag
- not recommended as the primary path that your pages reference (better for history/rollback)
### Step 3: Compose pages in UI Builder
In UI Builder:
- Open your page UXML
- Drag the exported chart `.uxml` from the Project window
- Combine it with other UI (Label, Button, ListView, etc.) into a full page
For the quickest export-pipeline verification, you can use the demo scene and template:
- Scene: `Assets/EasyChart/Demo/Scenes/EasyChart_QuickStart.unity`
- Template: `Assets/EasyChart/Demo/UIToolKit/NewUXMLTemplate.uxml`
Drag the exported chart `.uxml` into `NewUXMLTemplate.uxml`, then make sure the `UIDocument` in the scene references that template.
#### Exact steps in UI Builder (recommended order)
1. Open UI Builder (or double-click your page `.uxml`).
2. In the Project window, locate the exported chart `.uxml` (usually under `Assets/EasyChart/LibraryUxml/<LibraryName>/...`).
3. Drag the `.uxml` into the page hierarchy (recommended to put it inside a container `VisualElement`).
4. Save the page UXML.
5. Back in the scene, make sure `UIDocument` references the page `.uxml` you just saved.
#### What's inside an exported chart UXML
Exported `.uxml` typically contains an `EasyChart.ChartElement` with attributes like:
- `profile-name`: usually the ChartProfile asset file name (key)
- `profile-guid`: a more stable way to locate the asset
Therefore:
- If you only modify the Profile, the page will not change automatically: you need to re-export (Mirror) so the UXML gets updated.
- If you rename the Profile asset, the exported `profile-name` will also change (so keep naming stable when possible).
### Step 4: Load/replace data at runtime (depends on your product)
`ChartProfile`/UXML defines the "style and structure", while your data usually comes from business logic.
- Static display: fill data directly in the Profile `seriesData`
- Dynamic display: write/replace `seriesData` at runtime (and keep `SeriesData.id` stable)
---
## 3. Folder layout recommendations for your chart library
Recommended to separate the "source configuration" and the "exported artifacts":
- `Assets/EasyChart/Library/Custom/`: the `ChartProfile` assets you maintain
- `Assets/EasyChart/LibraryUxml/`: exported UXML (both Mirror and Backup exports live under this root)
When using multiple Libraries, exported assets are typically organized by library name:
- `Assets/EasyChart/LibraryUxml/<LibraryName>/...`
Recommended conventions:
- **Maintain Profiles only under `Assets/EasyChart/Library/...`** (as the source of truth)
- **Pages reference only Mirror exports** (as your component library)
- Treat Backup exports purely as **historical snapshots**
> Benefits:
> - Your configuration source stays readable and editable
> - Exported artifacts are reusable, composable, and can be used directly in UI Builder
---
## 4. Common issues & troubleshooting
- **Can't find the exported chart UXML in UI Builder**
- First check whether files were generated under `Assets/EasyChart/LibraryUxml/`
- If you use multiple Libraries, check under `Assets/EasyChart/LibraryUxml/<LibraryName>/`
- Mirror/Backup exports may appear under `_Backups`; pages should not reference files under `_Backups`
- **The page references the UXML, but nothing shows at runtime**
- Make sure the scene `UIDocument` references the page `.uxml` you edited
- In the Library Editor, use Preview to verify the Profile renders correctly (rule out Profile configuration issues first)
- **You modified the Profile but the page didn't change**
- The Profile is the "source"; the page references exported UXML
- After modifying a Profile, re-export (Mirror), then return to the page and refresh/save
- **The component is visible in UI Builder, but still doesn't show at runtime**
- First verify the scene `UIDocument` truly references the intended page (not an older page)
- Then verify the Profile renders correctly in the Library Editor Preview
---
## 5. What to read next
- To quickly complete a single chart end-to-end: `00_01-QuickStart.md`
- To use charts with UGUI (Canvas/RectTransform): `00_03-UGUIWorkflow.md`
---
## 6. Editor workflow & panels quick reference (Library Editor)
This section consolidates the editor workflow and panel explanations that were previously spread across multiple chapters, serving as a quick reference when working in `EasyChart/Library Editor`.
### 6.1 What are you editing? (ChartProfile)
The chart selected in the Library Editor is essentially a `ChartProfile` asset.
- It's a reusable configuration: the same Profile can be referenced by multiple scenes/prefabs.
- It's previewable: changes in the editor can be previewed immediately.
### 6.2 Main areas of the Library Editor
You can think of the window as four areas:
- Left: Library (asset tree)
- Center: Preview
- Right: Inspector (configuration)
- Right: Series (series and data)
Additionally, there is usually a JSON Injection panel on the left.
### 6.3 Library panel (asset tree)
Overview:
- Displays folders and `ChartProfile` (`.asset`) files in a tree.
- Selecting a `ChartProfile` drives binding and refresh for Inspector/Series/Preview.
- Supports create/rename/delete, drag-move, and sorting.
Selection logic:
- Selecting a folder: clears the Inspector/Series panels (no Profile to edit).
- Selecting a ChartProfile: binds the right panels to that Profile.
Common actions (title bar and right-click menu; may vary by version):
- Folder: New Folder / New Chart / Export Folder to UXML (Mirror/Backup) / Rename / Delete
- ChartProfile: Export to UXML / Clone / Rename / Delete
### 6.4 Preview panel
Preview renders the currently selected `ChartProfile` directly, so you can validate changes while editing.
Common issues:
- Preview is empty: make sure there is at least 1 `Serie` and its `seriesData` is not empty.
- Data exists but looks wrong: verify CoordinateSystem matches the SeriesType, and axis ranges are not excluding your data.
### 6.5 Inspector panel
Inspector edits the serialized fields of the Profile (coordinate system, axes, grid, interaction, legend, etc.), and drives Preview updates.
Tip:
- If some field changes appear to have no effect, confirm the page references the exported UXML, not the Profile directly.
### 6.6 Series panel
The Series panel edits `ChartProfile.series` from a "chart-structure" perspective:
- Add/remove/reorder series
- Choose `type` for each serie and edit `settings`
- Edit `seriesData` (data points)
### 6.7 JSON Injection panel
Purpose: represent the current Profile as copyable JSON, and support parsing JSON to write back into the current Profile.
Recommended workflow:
1. Generate example JSON from the current Profile
2. Copy it into an external editor for batch edits
3. Paste it back and ApplyToChart
---
## 7. Axes & ranges (Axis & Range)
### 7.1 AxisType: Category vs Value
- Category: use `labels` to define discrete categories (A/B/C, or Mon/Tue/Wed).
- Value: continuous numeric range (0~100, -3~3, 0~1e6).
#### 7.1.1 When to use Category
- The X axis is a sequence of text labels
- You want points to land on `labels[i]`
- Typical: bar charts (one bar group per category), line charts (aligned by categories)
Key points for Category:
- `labels[0]` corresponds to category index `0`
- `labels[1]` corresponds to category index `1`
#### 7.1.2 When to use Value
- X or Y is a continuous numeric value (timestamp, money, temperature, etc.)
- You want to scale/pan the axis by numeric values
Key points for Value:
- Axis range is usually computed by auto range (if enabled)
- You can lock only one side (e.g. fix min=0 and keep max auto)
### 7.2 Category axis: labels and LabelPlacement
`labels` determines the number of categories and the label text.
`LabelPlacement` affects alignment:
- `Tick`: labels align to tick marks; better for Line/Scatter.
- `CellCenter`: labels align to the center of a cell; better for Bar/Heatmap.
Common symptom:
- Bars appear between two labels: set `LabelPlacement` to `CellCenter`.
### 7.3 Value axis: autoRangeMin / autoRangeMax
If the range is "locked" and data is not visible, revert to full auto range first:
- Enable `autoRangeMin/autoRangeMax`
After it's visible, add business constraints gradually (e.g. make bar chart Y start at 0).
#### 7.3.1 Common template: Y axis starts at 0
- `axisType = Value`
- Fix `minValue = 0`
- `autoRangeMax = true`
#### 7.3.2 Common template: lock only Max (e.g. percentages)
- Fix `maxValue = 100`
- `autoRangeMin = true`
### 7.4 rounding / unit / labelFormat
- rounding: snap the range to "nicer" numbers.
- unit: display unit scaling (K/M, ten-thousand/million, etc.).
- labelFormat: control number formatting (N0/N2/F1/percent, etc.).
#### 7.4.1 Unit display (showUnit / unitText)
When values are large (e.g. 10,000+), a common approach is showing a unit at the end of the axis (e.g. "k", "M").
#### 7.4.2 Quick troubleshooting
- Labels misaligned / bars centered between labels: check Category axis `LabelPlacement`
- Range looks weird (too large/too small): check if min/max is locked; check rounding/unit
- Too many decimals in ticks: set `labelFormat`
---
## 8. Series and data (Serie / SeriesData)
### 8.1 Serie (one series)
Each element in `ChartProfile.series` is a `Serie`:
- `name`
- `type`
- `visible`
- `settings`
- `labelSettings`
- `seriesData`
Note: `settings` is usually a polymorphic object (`SerializeReference`). When you change `type`, the editor will try to preserve the last used settings for each type (better editing experience).
### 8.2 SeriesData (one data point)
Common `SeriesData` fields:
- `id`: stable identifier (tooltip/hover/hidden state).
- `x`: X coordinate or Category index.
- `value`: main value.
- `y`: second dimension (scatter/heatmap, etc.).
- `z`: third dimension (e.g. sizeMapping).
- `name`: point name (often used by Radar/Pie/Ring).
- `useColor` + `color`: point-level color override.
If interactions are enabled, keep `SeriesData.id` stable to avoid generating a new set of ids on every data refresh.
### 8.3 Matching SerieType and coordinate system
- Cartesian2D: Line/Bar/Scatter/Heatmap
- Polar2D: Radar
It's not recommended to mix Polar and Cartesian series in a single (non-Pie) ChartProfile. If you do mix them, be careful about whether axes/grid semantics remain consistent.
### 8.4 Common data patterns (by type)
#### 8.4.1 Line
- Common: Category X + Value Y
- Data point: `x=category index`, `value=value`
- Continuous: Value X + Value Y
- Data point: `x=x value`, `value=y value`
#### 8.4.2 Bar
- Category X + Value Y
- One point per bar: `x=category index`, `value=bar height`
- Grouped: multiple Bar series share the same Category X
- Stacked: series with `stacked=true` and the same `stackGroup` will stack
#### 8.4.3 Scatter
- Common: X=Value, Y=Value
- Recommended to explicitly write `x/y` for data points
#### 8.4.4 Heatmap
- Triplet: `x=column index`, `y=row index`, `value=intensity`
#### 8.4.5 Radar
- Typical: `x=dimension index`, `value=value of that dimension`, `name=dimension label`
### 8.5 Common data pitfalls (symptom-driven)
- Category chart uses Category axis on X, but point `x` is not 0/1/2...
- Symptom: points/bars don't align with labels
- Fix: ensure `x=category index`, or change X axis to Value
- NaN/Infinity appears
- Symptom: chart doesn't render, range explodes
- Fix: filter invalid values at the data source
- Chart is not visible (but `seriesData` is not empty)
- Check: coordinate system matches (Cartesian vs Polar)
- Check: AxisType matches your data meaning
- Interactions/tooltip mapping feels wrong
- Check: `SeriesData.id` is stable (don't randomly regenerate ids on each refresh)
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 0bbaa7b4363982f4ebefccc797cd0dcd
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/00_02-WorkflowAndLibrary.md
uploadId: 857482
@@ -0,0 +1,129 @@
# UGUI Workflow
Goal of this chapter: use EasyChart with a UGUI workflow (Canvas/RectTransform), and understand the choice between two rendering modes:
- `ScreenSpaceOverlay`: best visual quality (no RenderTexture), but typically visible only in the Game view
- `WorldSpace`: visible in both Scene/Game views (uses RenderTexture), suitable for 3D world-space UI
---
## 1. Recommended approach: UGUIChartBridge
Recommended component: `UGUIChartBridge`.
Its role is:
- Still uses **UI Toolkit `ChartElement`** as the core chart renderer
- Bridges the chart so it "fits" onto a target UGUI `RectTransform`
So you get the best of both:
- Chart capability + UI Toolkit rendering
- UGUI scene/prefab layout workflow and habits
---
## 2. Common prerequisites
No matter which mode you choose, prepare the following first:
- A `ChartProfile` to display (recommended: clone one from `EasyChart/Library Editor` and modify it)
- A `PanelSettings` asset, and assign it to `UGUIChartBridge` via `Panel Settings Asset`
> Note: providing `Panel Settings Asset` is usually better for font rendering and overall stability.
---
## 3. Screen Space Overlay (recommended for HUD/panels)
### Use cases
- HUD, UI panels, dialogs
- You care most about clarity and visual quality
### Characteristics
- No RenderTexture
- Typically visible only in the Game view
### Setup steps (overview)
1. Create a `Canvas`
2. Under the Canvas, create a node with `RectTransform` (`Image` or an empty GameObject both work)
3. Add `UGUIChartBridge`
4. Configure:
- `Profile`
- `Panel Settings Asset`
- `Render Mode = ScreenSpaceOverlay`
- `Sort Order` (controls overlay order; effective only in Screen Space Overlay mode)
Key points:
- This mode renders the chart inside a runtime-created/reused `UIDocument`.
- If the chart is covered by other UI, increase `Sort Order` first.
---
## 4. World Space (recommended for 3D world-space panels)
### Use cases
- Billboards/screens/panels inside a 3D world
- You want to see the result in the Scene view as well
### Characteristics
- Uses RenderTexture
- Usually visible in both Scene and Game views
- Visual quality can be affected by RenderTexture resolution
### Setup steps (overview)
1. Create a `Canvas`
2. Set `Render Mode = World Space`
3. Under the Canvas, create a node with `RectTransform` (recommended: `RawImage`)
4. Add `UGUIChartBridge`
5. Configure:
- `Profile`
- `Panel Settings Asset`
- `Render Mode = WorldSpace`
Key points:
- World Space mode creates and maintains a `RenderTexture` and displays it via `RawImage`.
- Clarity is strongly tied to the `RenderTexture` resolution, which usually comes from the target `RectTransform` width/height.
- If the chart looks blurry, make the target `RectTransform` larger first (e.g. 600x400+).
---
## 5. Mode selection (quick conclusion)
- Prefer **ScreenSpaceOverlay** when:
- you're building traditional UI (HUD/panels)
- clarity is your top priority
- Prefer **WorldSpace** when:
- your chart needs to appear in a 3D world
- you want it visible in the Scene view
---
## 6. Common issues & troubleshooting
- **Not visible at runtime**
- Make sure the target `RectTransform` size is not 0
- Make sure `Profile` is assigned, and the Profile renders correctly in Library Editor Preview
- If fonts look wrong, check whether `Panel Settings Asset` is missing
- **Blurry chart in World Space mode**
- Increase the target `RectTransform` size (this increases RenderTexture resolution)
- Avoid frequent aggressive scaling at runtime (may trigger RenderTexture resizing)
---
## 7. Alternative: export as a UGUI Prefab
If your version provides `Export UGUI Prefab`:
- You can export the Profile to a UGUI prefab and use it directly under a Canvas
- Coverage for interaction/compatibility depends on the exporter version
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: f9cd0878be8f4f3478a0d1f8b33871b8
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/00_03-UGUIWorkflow.md
uploadId: 857482
@@ -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`.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: ad05086ead6baa54ea109ad556ef4642
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/00_04-RuntimeDataInjectionUIToolKit.md
uploadId: 857482
@@ -0,0 +1,155 @@
# Runtime Data Injection (UGUI)
Related scripts: `UGUIRuntimeJsonInjection`, `UGUIRuntimeJsonInjectionEditor`
This chapter explains how to inject data into charts at runtime via JSON in a UGUI workflow (`UGUIChartBridge`).
---
## 1. When should you use this approach?
- You have JSON coming from a server/business layer (or you want to quickly edit JSON at runtime)
- You want an editor-like workflow: "Generate example → Modify → Apply" (similar to the `JSON Injection` panel)
- You already configured the chart structure (style/axes/Series types) via `ChartProfile`
This injector is primarily designed for **updating data**. Structural changes (e.g. adding Series, force-overriding Series types) are not its main goal.
---
## 2. Quick start (recommended flow)
1. Set up `UGUIChartBridge` in the scene (and make sure `Profile` is assigned).
2. Add `UGUIRuntimeJsonInjection` to the same GameObject.
3. Click **Generate Example JSON** to generate sample JSON that matches your current Profile.
4. Modify the data in the `JSON Content` text box.
5. Click **Apply JSON to Chart**.
Internally, the component will:
- Parse JSON → convert to `ChartFeed`
- Apply `ChartFeed` to `UGUIChartBridge.Profile`
- Call `_bridge.Refresh()` to redraw
---
## 3. Component and Inspector fields
`UGUIRuntimeJsonInjection` must be on the same GameObject as `UGUIChartBridge` (the script has `[RequireComponent(typeof(UGUIChartBridge))]`).
### 3.1 JSON Generation Settings
- **Example Mode (`ChartJsonExampleMode`)**
- Controls the format when generating example JSON.
- Generally recommended to start with `Standard` or `Standard_Axis` (more intuitive).
- **Data Mode (`ChartJsonDatasMode`)**
- Controls how `datas` is represented.
- `Standard`: `datas` is an array of objects (e.g. `{ "x": 0, "value": 12 }`).
- `Values`: `datas` is an array of raw numbers (shorter).
- Note: this format requires the "flexible parser" in `ChartJsonUtils` (reflection-based parsing via Newtonsoft). If your project does not include Newtonsoft (`Newtonsoft.Json` / `Unity.Newtonsoft.Json`), parsing may fail.
- Therefore **`Standard` is recommended by default**, unless you're sure Newtonsoft is available.
- **API Envelope (`UseApiEnvelope`)**
- When generating example JSON, whether to wrap it with an API envelope:
- `{ "code": 200, "message": "success", "data": { ...the real ChartFeed... } }`
- When applying, it will also try to extract `data` automatically.
- **Auto Generate (`AutoGenerateJson`)**
- Automatically regenerates example JSON when you change `Example Mode / Data Mode / API Envelope`.
### 3.2 JSON Content
- **JSON Content (`JsonContent`)**
- The JSON string to inject.
- If empty, clicking Apply will log a warning and return.
---
## 4. JSON format (ChartFeed)
The underlying data model is `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 }
]
}
]
}
```
Field-to-code mapping notes:
- `chartId` / `chartName`
- In the `UGUIRuntimeJsonInjection` injection path, it **will not overwrite** the Profile `chartId/chartName` (it calls `ChartJsonUtils.ApplyFeedToProfile(profile, feed)` with `allowMetaOverwrite=false`).
- But these fields can help other injectors (e.g. `EasyChartDataSource`) locate a `ChartElement` by name/ID in the UI tree.
- `axes[]`
- `axisId` is the `AxisId` enum (e.g. `XBottom`, `XTop`, `YLeft`, `YRight`).
- If `labels` exists, that axis is treated as Category and labels are overwritten.
- `series[]`
- **Matching priority**:
- If `serieId` is provided: match by `Serie.id`
- Else if `name` is provided: match by `Serie.name`
- Else (both `serieId` and `name` are empty): match by index (feed 0 -> profile 0)
- `type`
- Mainly used when generating example JSON.
- In the current injection path:
- For existing matched Serie: it **will not force the type to change** (meta overwrite is not allowed).
- For newly created Serie in "index mode + feed exceeds Profile series count": it will use the feed `type` as the new Serie type.
- `datas[]` for each point:
- numeric `x/y/z/value`
- optional `id/name`
- optional `useColor/color`
---
## 5. What happens when you apply? (injection flow)
When you click **Apply JSON to Chart**:
1. If the JSON is wrapped in an API envelope (contains `data`), it first tries to extract the object under `data`.
2. Calls `ChartJsonUtils.TryDeserializeFeed(json, out feed)` to deserialize into `ChartFeed`.
- Tries Newtonsoft first (if available); otherwise falls back to Unity `JsonUtility`.
- String values like `type: "Line"` / `axisId: "XBottom"` are normalized to enum values in the fallback path before parsing.
3. Calls `ChartJsonUtils.ApplyFeedToProfile(_bridge.Profile, feed)` to write the feed back into the Profile.
4. Calls `_bridge.Refresh()` to redraw.
---
## 6. Common issues & troubleshooting
- **Click Apply does nothing / console warns: No UGUIChartBridge or ChartProfile found**
- Make sure the object has `UGUIChartBridge`
- Make sure `UGUIChartBridge.Profile` is assigned
- **Error: Failed to parse JSON**
- Generate a known-good JSON first, then modify it.
- If your API response has an outer wrapper, enable `API Envelope`, or ensure the JSON `data` field contains the `ChartFeed`.
- **JSON applied but data didn't change / only partially changed**
- Check how `series` is matched (`serieId` / `name` / index mode).
- If you use `serieId/name` matching: make sure the corresponding Serie exists in the Profile (this injection path won't auto-create new Serie in this mode).
- If you use "index mode" (both `serieId` and `name` are empty):
- When feed `series[]` count **exceeds** the Profile series count, it will auto-create additional Serie.
- If you don't want auto-creation, provide an explicit `name` or `serieId` for each serie.
- **After injecting in Play Mode, the Profile asset became dirty**
- Injection essentially "applies the feed to the `ChartProfile`". If you drag the asset directly into the bridge, runtime changes may mark the asset dirty.
- If you don't want to modify the asset, instantiate a runtime copy of the Profile and inject into that copy.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 9b5cedc13ea816948a0163432c6dafd9
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/00_05-RuntimeDataInjectionUGUI.md
uploadId: 857482
@@ -0,0 +1,168 @@
# Editor Workflow and Panel Guide
This chapter helps you understand **what to edit where** in `EasyChart/Library Editor`, and the common editing workflows (create, clone, preview, export).
---
## 1. What are you editing? (ChartProfile)
The chart selected in the Library Editor is essentially a `ChartProfile` asset.
- It is a **reusable configuration**: the same Profile can be referenced by multiple scenes/prefabs.
- It is a **previewable configuration**: after modifying it in the editor, you can see the preview update immediately.
Recommendation: put your own Profiles under `Assets/EasyChart/Library/Custom/` (or a folder agreed by your team).
---
## 2. The three core areas of the Library Editor
Although UI details may change slightly across versions, you can understand the overall layout like this:
### 2.1 Left: Library Tree
This shows the folder structure where chart assets (`ChartProfile`) are located.
Common actions:
- Right-click a folder:
- `New Folder...`: create a subfolder
- `New Chart...`: create a new `ChartProfile`
- Right-click a chart:
- `Clone`: duplicate a new Profile (to create variants)
- `Export to UXML`: export (if your workflow needs to sync/export configuration into UXML)
- `Ping`: locate the asset in the Project window
- `Rename...` / `Delete`
> Tip: use `Clone` to create variants like "same chart with different colors / different data scale", instead of configuring from scratch.
### 2.2 Right: Inspector
This is where you do most of your editing.
It typically includes:
- **Basic settings**:
- `coordinateSystem`
- `padding` (if present)
- `animationDuration` (if present)
- **Series list**: each Serie represents a line, a group of bars, a scatter series, etc.
- **Axes**:
- choose which `XAxisId/YAxisId` to use
- configure display/labels/range/ticks of the corresponding `AxisConfig`
- **Legend / Tooltip / Grid**: if your version exposes these settings
> Practical tip: configure `coordinateSystem`, `Series`, and `Axes` first. The rest is "nice to have".
### 2.3 Preview
Use it to check:
- whether data exists
- whether axis ranges are correct
- whether labels are crowded/misaligned
- Tooltip / Legend interactions (if enabled)
When preview looks wrong, troubleshoot in this order:
1. Is `coordinateSystem` correct?
2. Does `series` contain at least 1 serie and data points?
3. Does the axis `axisType` match the meaning of your data `x/y`?
4. Is the Value axis range locked manually (`autoRangeMin/autoRangeMax`)?
### 2.4 JSON Injection
Below the left panel there is a **JSON Injection** area, used to:
- quickly generate an "injection JSON example" for the selected `ChartProfile`
- apply your pasted/edited JSON back to the selected Profile (`ApplyToChart`)
Common controls:
- **API Envelope**: whether to wrap with `{ code, message, data }`.
- When enabled: generated JSON will be wrapped; parsing can also recognize it and automatically extract `data`.
- **Feed Mode**: the structure/field completeness of the example JSON (to support different injection protocols).
- **Datas Format**: the point format inside the `datas` field (e.g. compact arrays, or more readable objects).
- **ApplyToChart**: parse JSON from the text box and write it back into the selected `ChartProfile`.
---
## 3. Recommended editing flow (from zero to reusable)
### Step 1: Create or select a ChartProfile
- New: right-click the target folder and choose `New Chart...`
- Existing: click to select in the left tree
If you prefer the "clone first, then modify" approach (recommended):
- First, use **Clone** in the top toolbar to create your own Library
- Then in your own library, right-click a Profile -> `Clone` to create variants
### Step 2: Decide the coordinate system
- `Cartesian2D`: Line/Bar/Scatter/Heatmap
- `Polar2D`: Radar
> Tip: decide the coordinate system first, then choose SeriesType, to avoid style/axis confusion after switching later.
### Step 3: Configure Series
- Add Series
- Set `type`
- Fill `seriesData`
Tip: start with a small number of points (38) to validate the look, then scale up.
### Step 4: Configure Axes
Most common combination:
- X: Category
- put text into `labels`
- Y: Value
- enable auto range (default)
When you want more professional axis formatting:
- Use `labelFormat` (e.g. `F1`, `N0`)
- Use `autoRangeMin/autoRangeMax` to lock only one side of the range
- If the Value axis needs a unit:
- `showUnit=true`
- `unitText="items"/"10k"`
- use `unitLabelStyle` to adjust font/color/position
### Step 5: Clone variants (recommended)
When you need multiple versions of the same chart (colors, font size, slightly different axis display):
- Right-click the chart -> `Clone`
- Modify only the differences
This keeps style consistent and is easier for version management.
When you want to use the chart in UI:
- UI Toolkit: export to UXML, then compose the page in UI Builder (see demo scene `Assets/EasyChart/Demo/Scenes/EasyChart_QuickStart.unity` and template `Assets/EasyChart/Demo/UIToolKit/NewUXMLTemplate.uxml`)
- UGUI: export to a UGUI prefab and use it in a Canvas/RectTransform workflow
---
## 4. Common pitfalls (quick diagnosis)
- **Nothing shows up**
- Is `seriesData` empty?
- Does `AxisType` match the meaning of your data (does the Category axis have labels)?
- **Value axis looks weird (range too large/too small)**
- Check `autoRangeMin/autoRangeMax`
- Check whether rounding/unit snapped the range to an unsuitable unit
- **Bars and labels are misaligned**
- Check `LabelPlacement` (Tick vs CellCenter)
---
## Next
- `00_02-WorkflowAndLibrary.md`: axis types, label placement, auto range, rounding, and unit display are merged into section 7
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: b670d01dcf088d140acda07de2d3964f
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/01_01-EditorWorkflow.md
uploadId: 857482
@@ -0,0 +1,162 @@
# Library Panel (Asset Tree)
This chapter explains the **Library** panel on the left side of `Unity Easy Chart/Library Editor`. It manages your chart assets (`ChartProfile`) and folder structure, and determines which Profile the panels on the right are currently editing.
---
## Feature Overview
- **Structure Display**: shows folders and `ChartProfile` (`.asset`) under the library root in a tree.
- **Selection Drives Editing**: selecting a `ChartProfile` triggers:
- Inspector binds to that Profile
- Series binds to that Profile `series`
- Preview refresh
- JSON Injection generates example JSON (and can Apply back to that Profile)
- **Asset Management**: create/rename/delete, drag-move, expand/collapse, etc.
---
## UI Structure
The header bar at the top of the Library panel typically contains (left to right):
- **Library**: title.
- **(Current Library Name)**: shows the selected library/root name (useful if you have multiple libraries).
- **Menu**: entry for common actions (similar to right-click, but centralized).
- **Help**: opens this chapter.
In the global window toolbar at the top, on the right side of the Library dropdown you may see:
- **+**: add a new Library.
- **-**: delete the current Library.
- **Clone**: duplicate the current Library (see below).
Below the header is:
- **TreeView**:
- folders
- `ChartProfile` assets (chart configuration assets)
---
## Selection Logic (Important)
- **When a Folder is Selected**:
- Inspector/Series on the right are cleared (no Profile to edit).
- JSON Injection switches to a "no selected Profile" example or keeps the current example (implementation-dependent).
- **When a ChartProfile is Selected**:
- Inspector/Series immediately bind to the Profile's serialized data.
- Any field change triggers a delayed Preview refresh (`delayCall`).
Tip: if the right panels are empty, first confirm a `ChartProfile` (not a folder) is selected on the left.
---
## Common Actions (Header Menu)
Clicking **Menu** (the small menu icon) opens an action menu. Common items include:
- **New Chart**: create a new `ChartProfile` under the target folder.
- **New Folder**: create a new folder under the target folder.
- **Refresh**: rescan and rebuild the tree (useful after manual moves/copies in the Project view).
- **Expand All**: expand all folders.
- **Collapse All**: collapse all folders.
- **Rename / Delete**: rename/delete the currently selected item.
- If the library root is selected, these are typically disabled.
- **Export UGUI Prefab** (available when a Profile is selected): export the selected Profile as a UGUI prefab (for runtime display).
### How the Target Folder is Determined
**New Chart / New Folder** create assets under the "target folder":
- If a **folder** is selected: the target is that folder.
- If a **ChartProfile** is selected: the target is usually the Profile's parent folder.
- If nothing is selected or unclear: the target usually falls back to the library root.
---
## Clone Library
When you need to duplicate a full chart library (including Profiles and UXML) into a new library (for branching/versions/theme variants), use **Clone** in the top toolbar.
### Entry and Usage
- Click the **Clone** icon to the right of the Library dropdown.
- Enter the new library name and confirm.
### What Gets Cloned
- `Assets/EasyChart/Library/<CurrentLibrary>` is copied to `Assets/EasyChart/Library/<NewLibrary>`.
- `Assets/EasyChart/LibraryUxml/<CurrentLibrary>` is copied to `Assets/EasyChart/LibraryUxml/<NewLibrary>` (if the source UXML folder exists).
### Limitations and Naming Rules
- The `<Root>` library cannot be cloned.
- The new name is sanitized (invalid filename characters removed); blank names are ignored.
- If the target library already exists (folder already exists), it will prompt and cancel.
### After Cloning
- Automatically switches the current Library selection to the new library.
- Refreshes the Library dropdown and tree view, and triggers refresh for right panels/preview.
---
## Common Actions (Context Menu)
You can also **right-click** items in the tree:
### Right-click a Folder
- **New Folder...**: create a subfolder.
- **New Chart...**: create a new `ChartProfile` in that folder.
- **Export Folder to UXML (Mirror/Backup)**: export the folder contents to UXML (backup/distribution/versioning).
- **Rename...**: rename the folder.
- **Delete**: delete the folder (destructive; be careful).
### Right-click a ChartProfile
- **Export to UXML**: export UXML for the current Profile.
- **Clone**: clone a new Profile (quickly derive a similar chart).
- **Rename...**: rename the asset (also tries to sync-update `profile.name` / `profile.chartName`).
- **Ping**: locate the asset in the Project view.
- **Delete**: delete the asset.
---
## Drag-move and Sorting
The Library tree supports dragging folders or `ChartProfile`:
- **Drag a ChartProfile onto a folder**: triggers `AssetDatabase.MoveAsset` to move the `.asset` into the target folder.
- **Drag a folder onto a folder**: moves the whole folder under the target folder.
Notes:
- If the target is invalid (dragging into itself/child folder), it will be rejected (cursor shows Rejected).
- After moving, the tree refreshes automatically.
---
## Rename (Double-click and Inline Editing)
**Double-clicking** a tree item enters inline rename (equivalent to running Rename).
Internally, names are sanitized (invalid filename characters removed). If the new name is blank or unchanged, rename is canceled.
---
## Common Issues & Troubleshooting
- **Right panels are empty**:
- First confirm a `ChartProfile` (not a folder) is selected.
- **Renamed but chartName didn't update**:
- ChartProfile may have additional sync logic; verify the `Chart Name` field in Inspector.
- **Drag failed**:
- Common causes: dragging onto itself/child folder, or a name conflict at target path.
---
## Help
- Click the rightmost **Help** icon in the header to open this chapter.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 4260ec2e45b714e48a5196263b82348e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/01_02-LibraryPanel.md
uploadId: 857482
@@ -0,0 +1,138 @@
# JSON Injection Panel
This chapter explains the **JSON Injection** panel at the bottom-left of `Unity Easy Chart/Library Editor`.
Its purpose is to represent the current `ChartProfile` configuration (or externally imported configuration) as readable/copyable JSON, and supports **ApplyToChart** to parse the JSON and write it back into the selected Profile.
---
## Location and purpose
- **Location**: below the Library panel (tree view).
- **Main uses**:
- **Export**: convert the selected `ChartProfile` into example JSON (Feed)
- **Edit**: manually edit the JSON in the text box
- **Import/Apply**: click **ApplyToChart** to parse and apply JSON into the selected `ChartProfile`
Use cases:
- **Debugging**: quickly validate whether a specific field takes effect.
- **Batch edits**: copy JSON to an external editor (multi-cursor/find-replace), then paste back and Apply.
- **Integrations**: e.g. your toolchain/scripts generate a Feed and you Apply it in the editor.
---
## Controls (header bar)
The header bar typically contains (left to right):
- **Min/Max** (label changes)
- Toggles panel height.
- `Min`: collapse to a smaller height (more like an auxiliary tool).
- `Max`: expand to a larger height (better for long JSON).
- **ApplyToChart** (icon button)
- Attempts to parse the JSON in the text box as a Feed and apply it to the selected `ChartProfile`.
- On success it will:
- mark the asset dirty and call `SaveAssets()`
- refresh the Series list
- refresh Preview
- **Help** (icon button)
- Opens this chapter.
---
## Controls (button row)
Below the header there is a row of buttons (may wrap):
- **API Envelope** (icon toggle)
- Controls whether the example JSON is wrapped in an "API response" envelope.
- Useful when you want to send the Feed directly to an HTTP API/service.
- Toggling regenerates the example and overwrites the text box (see "overwrite rules").
- **Feed Mode** (dropdown)
- Controls which levels/fields are included in the example JSON.
- Options come from an internal enum (common ones include):
- `Lite`
- `Standard / ID`
- `Standard / Default`
- `Standard / With Axes`
- `Full`
- General recommendations:
- **Quickly inspect structure**: use `Lite`
- **Need stable references**: use `Standard / ID`
- **Need to include axes config**: use `Standard / With Axes`
- **Need full copy/migration**: use `Full`
- **Datas Format** (dropdown)
- Controls the output format of `seriesData` (data points).
- Common options:
- `Values`: more compact, mostly "values only".
- `Standard`: default format, good for editing and Apply.
- `Full`: more complete (may include more fields/structure), good for migration/restoration.
- **Copy** (icon button)
- Copies the current text box content to the clipboard.
---
## Text box and "overwrite rules" (important)
The JSON text box is editable. To prevent your manual edits from being overwritten automatically, the panel has a "dirty" flag logic:
- **As soon as you manually change the text box**, it is considered "user modified" (dirty).
- When dirty:
- the editor will not automatically overwrite your content with example JSON.
- However, switching the following options will **force overwrite** (and clear dirty):
- `API Envelope`
- `Feed Mode`
- `Datas Format`
- or when switching the selected Profile (resets to that Profile's example)
Recommendation:
- If you plan to do major edits:
- Copy to an external editor first
- Paste back and Apply when done
---
## ApplyToChart behavior and notes
- **ApplyToChart modifies the selected `ChartProfile` asset**.
- If JSON parsing fails, an error is logged to the Console:
- `ApplyToChart failed: invalid JSON or unsupported format.`
- In `Full` mode, more meta/structural information may be overwritten (IDs/config, etc.), which is more powerful but also more dangerous.
Recommendations:
- Before applying, make sure:
- the correct `ChartProfile` is selected on the left
- JSON format is valid (brackets/commas)
- you understand what the current Feed Mode will overwrite
---
## Recommended workflows
### 1) Export from current Profile and tweak
- Select a `ChartProfile`
- Choose appropriate `Feed Mode` / `Datas Format`
- Copy to an external editor for tweaks
- Paste back
- ApplyToChart
### 2) Import configuration from external sources
- Paste external JSON into the text box
- ApplyToChart
- Fine-tune further in Inspector / Series
---
## Help
- Click the rightmost **Help** icon in the header to open this chapter.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 6c519df14f129ed4d94055b6ee239d3a
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/01_03-JsonInjectionPanel.md
uploadId: 857482
@@ -0,0 +1,78 @@
# Preview Panel
This chapter explains the **Preview** panel at the top of the middle area in `Unity Easy Chart/Library Editor`.
The purpose of Preview is to render the currently selected `ChartProfile` directly, so you can see results immediately while editing.
---
## When does Preview refresh
Preview refresh is **delayed** (to avoid excessive redraw while you are continuously dragging/typing):
- When you modify any bound field in **Inspector** or **Series**, it triggers `ScheduleUpdatePreview()`.
- When you click **ApplyToChart** in **JSON Injection**, it triggers a refresh.
- When you switch to another `ChartProfile` in the left **Library** tree, Preview refreshes to the new Profile.
Implementation-wise, the refresh is scheduled via `EditorApplication.delayCall`, so you may feel it updates "a moment after" your change. This is expected.
---
## What does Preview display
- Preview draws using a runtime chart component (e.g. `ChartElement`).
- Preview reads data from the currently selected `ChartProfile` and renders it.
You can think of Preview as:
- **what you edit is what it renders**
- **what you see is (mostly) the runtime effect**
---
## Common issues and troubleshooting
### 1) Preview is empty
Check first:
- Is a `ChartProfile` selected?
- Is there at least one `Serie`?
- Is `seriesData` empty (no data points)?
### 2) Data exists but looks wrong / not visible
Common causes:
- **Coordinate system and SeriesType mismatch**: e.g. the Profile is `Polar2D` but the Series type is not Radar.
- **Axis range and data range mismatch**: e.g. all values are outside the axis range.
- **Category axis visible count (VisibleCount) is too small**: only a small segment is shown.
### 3) Console shows "Preview refresh failed"
If an exception occurs during refresh, the Console logs:
- `[EasyChartLibraryWindow] Preview refresh failed: ...`
This usually means:
- some configuration combination is invalid
- or some field value is unexpected (e.g. null / NaN)
Recommended handling:
- revert the most recent change first
- then re-apply changes step by step to locate which field triggers the exception
---
## Tips
- Preview only focuses on rendering results. Structural issues usually need to be fixed in **Inspector/Series/JSON Injection**.
- If you modify many fields in a short time, Preview may refresh only after your last change (for performance).
---
## Help
- Click the rightmost **Help** icon in the title bar to open this chapter.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 0d724273b42b2b94fba94bc277901cd7
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/02_04-PreviewPanel.md
uploadId: 857482
@@ -0,0 +1,201 @@
# Inspector Panel
This chapter explains the **Inspector** panel at the bottom of the middle area in `Unity Easy Chart/Library Editor`.
Inspector is designed to edit the serialized fields of the currently selected `ChartProfile` from a "configuration" perspective (coordinate system, axes, grid, interactions, legend, etc.), and drive the Preview to update.
---
## Panel structure overview
After you select a `ChartProfile` in the left Library tree, Inspector builds a set of foldouts (Foldout), typically including:
- **Chart Settings**: basic chart settings (e.g. background, name)
- **Coordinate System**: coordinate system selection and related options
- **Axis Settings**: axis configuration (X/Y or Angle/Radius)
- **Grid Settings**: grid-related configuration
- **Hover Settings**: hover/tooltip related configuration
- **Legend Settings**: legend configuration
Tip:
- If you select a folder instead of a `ChartProfile`, Inspector will be empty (this is expected).
---
## Chart Settings (common)
### Chart Name
Inspector contains a `Chart Name` text field (from `ChartProfile.chartName`). It is not only a display name, it also participates in asset renaming:
- When you type a new name and then **lose focus** or press **Enter**:
- the editor attempts to rename the `.asset` file to that name
- and tries to keep `profile.name` and `profile.chartName` in sync
Notes:
- The name will be sanitized for filenames (invalid characters are removed/replaced).
- If renaming fails (e.g. name conflict), an Error dialog is shown and the field is reverted.
### Background
`Background` is usually a sub-foldout that contains background color/alpha fields (depending on version).
---
## Coordinate System
This area shows the `coordinateSystem` selector.
The coordinate system affects:
- available Series types/semantics (e.g. Polar2D is commonly Radar; Pie is a special layout)
- whether Axis Settings shows Cartesian (X/Y) or Polar (Angle/Radius) configuration
Recommendation:
- decide the coordinate system before you start configuring, to avoid large adjustments later.
---
## Axis Settings
### Axis selection (X Axis / Y Axis)
In Cartesian mode, the top provides X/Y axis dropdowns:
- **X Axis**: e.g. `XBottom` / `XTop`
- **Y Axis**: e.g. `YLeft` / `YRight`
When the selection changes, it will:
- ensure the axes list contains an element for that AxisId (auto-create if needed)
- refresh the Axis field UI below
- trigger a Preview refresh
### Common fields of a single Axis
Each Axis configuration typically contains:
- `axisType`: Category / Value, etc.
- `visible`: whether to show
- `color` / `width`: axis line style
#### LabelTexts (Category axis labels)
Inspector provides `LabelTexts` (internal field name `labels`) to configure category labels.
#### Range
Common fields include:
- `minValue` / `maxValue`
- `autoRangeMin` / `autoRangeMax`
- `autoRangeRounding`
- `autoRangeUnit`
#### Ticks / VisibleCount
If the axis supports auto ticks:
- When `autoTicks` is enabled, it shows `splitCount`.
- For **Category Axis**, this field is displayed as **VisibleCount** (number of visible categories).
#### Category Auto Scroll
If the axis supports category scrolling, common fields include:
- `categoryAutoScroll`: whether to auto scroll (marquee effect).
- `categorySmoothScroll`: whether to scroll smoothly.
- `categoryScrollInterval`: scroll interval.
- `categoryScrollStep`: scroll step per tick.
#### Unit (unit display)
Common fields:
- `showUnit`: whether to show unit.
- `unitText`: unit text (e.g. `ms`/`%`/`MB`).
- `unitLabelStyle`: unit label style.
---
## Polar Axis
When `coordinateSystem = Polar2D`, Axis Settings shows `polarAxes`:
- **Angle Axis** (angleAxis)
- **Radius Axis** (radiusAxis)
Common field meanings are similar to Cartesian:
- `labels`: angle/dimension labels (Radar dimension names typically come from here).
- `visible/color/width`: axis line style.
- `showLabels/fontSize/labelColor/labelPosition/labelOffset`: label display controls.
- `autoRangeMin/autoRangeMax/minValue/maxValue`: radius axis range.
- `autoTicks/splitCount`: tick count.
---
## Grid Settings (fields, Cartesian2D only)
Grid Settings is visible in Cartesian2D. Key fields come from `cartesianGrid`:
- **xGridColor / xGridLineWidth**: X-direction grid line color and width.
- **yGridColor / yGridLineWidth**: Y-direction grid line color and width.
If you need dashed lines:
- `xGridDashed` / `yGridDashed`: enable dashed.
- `xGridDashLength` / `yGridDashLength`: dash segment length.
- `xGridDashGap` / `yGridDashGap`: dash gap.
- `xGridDashOffset` / `yGridDashOffset`: dash offset.
---
## Hover Settings (fields, Cartesian2D only)
Hover Settings is visible in Cartesian2D. Key fields come from `hover`:
- **cursorLineColor**: hover cursor line color.
- **cursorLineWidth**: line width.
- **cursorLineDashed**: dashed or not.
- **cursorLineDashLength / cursorLineDashGap / cursorLineDashOffset**: dash parameters.
---
## Legend Settings (fields)
Legend Settings comes from `legendSettings` (it may be auto-hidden in some cases; see below).
- **enabled**: whether to show legend.
- **position**: legend position (Top/Bottom/Left/Right).
- **fontSize / color**: text size and color.
- **backgroundColor**: legend background color.
- **itemSpacing**: spacing between legend items.
- **offset**: offset relative to the edge.
- When offset is default, a common offset is applied based on position (e.g. Bottom defaults to `y=-30`).
---
## Legend Settings (may be auto-hidden)
When the chart is a "pure Pie series" (only Pie/Ring/Pie3D, with no non-Pie series), Legend Settings may be hidden automatically.
This avoids showing meaningless or conflicting legend configuration in some layouts.
---
## Editing tips and troubleshooting
- **When making many changes**: use `Save` in the top toolbar to save the asset.
- **When changing key structure** (e.g. coordinate system, axis type, Series Type):
- after the change, check whether Preview refreshes correctly
- if inconsistent, try switching selection to trigger a rebuild
---
## Help
- Click the rightmost **Help** icon in the title bar to open this chapter.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 5a262ad8814ea474da864e1e0d337a54
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/02_05-InspectorPanel.md
uploadId: 857482
@@ -0,0 +1,166 @@
# Series Panel (Data and Series)
This chapter explains the **Series** panel on the right side of `Unity Easy Chart/Library Editor`.
The Series panel edits `ChartProfile.series` from a "chart structure" perspective: you can add/remove/reorder series, set each Serie's type and parameters, and directly edit `seriesData` (data points).
---
## Panel structure overview
After you select a `ChartProfile`, the Series panel shows:
- a list of Serie cards (each card corresponds to `series[i]`)
- a **+ Add Series** button at the bottom
Each Serie card typically consists of three parts:
- **Header**: fold toggle + title
- **Body**: Name / Id / Type / Settings / Data
- **Footer** (bottom-right controls): ↑ ↓ X
---
## Header: Collapse/Expand
- On the left side of the Header there is a small toggle:
- `▼` means expanded
- `▶` means collapsed
- The fold state is remembered (stored by Profile + index) to reduce visual clutter for long configurations.
---
## Name and Serie Id
### Name
- The `Name` field displays and edits the name of the Serie.
- When you change Name, the card title updates and triggers a Preview refresh.
### Serie Id (read-only)
If the Serie supports an `id` field, the panel shows:
- **Serie Id** (read-only text field)
- **Copy** button to copy the id to the clipboard
This id is commonly used for:
- interaction/highlighting/external systems referencing a serie
- keeping references stable (especially when you reorder/add/remove series)
---
## Type (series type) and compatibility tips
### Type dropdown
- `Type` is used to select the SerieType (Line/Bar/Scatter/Pie/Radar...).
- The dropdown provides options based on the registry. If the current type is not in the list, it will be temporarily inserted to keep it visible.
### Compatibility warning
When the SeriesType is incompatible with the Profile `coordinateSystem`, the Series panel shows a warning message:
- rendering is still allowed (not forcibly blocked)
- but it warns that axis/grid semantics may be inconsistent
Typical example:
- Profile is `Polar2D` but the SeriesType is Line/Bar (not recommended)
### Pro-only type restrictions
Some types are not available in the Free version (e.g. RingChart / HorizontalBar / Heatmap / Pie3D).
- When you try to select these types without Pro installed:
- a hint text will be shown
- and the dropdown will automatically revert to the previous type (it will not modify the asset)
---
## Settings (series parameters)
The Series panel shows a group of Settings for each serie:
- The root foldout name changes by type (e.g. `LineSettings` / `BarSettings` / `PieSettings` ...).
- Some types have more detailed sub-foldouts (e.g. Ring layout/valueMapping, etc.).
Notes:
- Switching Type may trigger a "Settings instance replacement" (managedReference structure changes).
- When replacement happens, the UI rebuild is delayed by one frame to avoid invalid serialized handles.
---
## Data: seriesData (data points)
The Series panel directly shows the `seriesData` array (Unity's default array editor).
- It is expanded by default (easier to edit).
- When you add/remove/modify points, it triggers a Preview refresh.
Recommendation:
- If you have many data points, use the JSON Injection panel for batch editing.
---
## Footer: Reorder and delete (render order)
Each serie card has three buttons at the bottom-right:
- **↑**: move the serie up (`MoveArrayElement(index, index-1)`)
- **↓**: move the serie down (`MoveArrayElement(index, index+1)`)
- **X**: delete the serie (`DeleteArrayElementAtIndex(index)`)
Render order tip:
- Usually, **later series are drawn on top**.
- So you can use ↑↓ to control overlap (e.g. points/lines on top of bars).
---
## + Add Series
Click **+ Add Series** at the bottom:
- Inserts a new element at the end of the `series` array.
- Note: if there is already at least one serie, Unity's `InsertArrayElementAtIndex(arraySize)` will **duplicate the last element** (including type/settings).
- If this is the first serie, a default type is chosen based on coordinate system:
- Polar2D: defaults to Radar
- otherwise: defaults to Line
After adding, it typically will:
- auto-fill a name (e.g. `Serie N`)
- call `EnsureRuntimeData()`
- refresh the Series list and Preview
---
## Recommended workflows
### 1) Create a basic chart from scratch
- + Add Series
- Choose Line or Bar in Type
- Add a few points in seriesData
- Adjust axis range/visible count in Inspector
### 2) Adjust overlap
- Use ↑↓ to adjust series order
- Observe layering changes in Preview
### 3) Large data / batch editing
- Switch `Datas Format` in JSON Injection
- Copy to an external editor to batch-generate/replace data
- Paste back and ApplyToChart
---
## Help
- Click the rightmost **Help** icon in the title bar to open this chapter.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 4ce98ab3f7ab88143bf05de78e49c2dc
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/02_06-SeriesPanel.md
uploadId: 857482
@@ -0,0 +1,111 @@
# Line Chart (Line)
This chapter explains the key points of configuring a Line chart in EasyChart: how to set it up, how data is interpreted, and which fields affect rendering.
---
## 1. Use cases
- Trend changes (time series / category-based)
- Comparing multiple curves (same X dimension)
- Line styles such as smooth / step / straight
---
## 2. Minimum viable setup (checklist)
1. `ChartProfile.coordinateSystem = Cartesian2D`
2. Axes (Axis Settings)
- X: usually **Category** (fill `labels`) or **Value** (numeric X axis)
- Y: usually **Value**
3. Series (Series panel)
- Add 1 `Serie`
- `Serie.type = Line`
- `Serie.seriesData` has at least 2 points (a line needs at least two points)
---
## 3. Inspector fields (what you see in panels)
- **ChartProfile / Coordinate System**
- `coordinateSystem`
- **Axis Settings** (depends on coordinate system)
- Cartesian: `cartesian.xAxisId / cartesian.yAxisId`
- Axis list: `axes[]` (each Axis has `axisType/labels/min/max/autoRange/...`)
- **Series** (each curve)
- `series[i].type = Line`
- `series[i].settings`: actual type is `LineSettings`
- `stroke`: line stroke (type/color/width/texture, etc.)
- `point`: point marker style (toggle/size/texture, etc.)
- `hover`: hover emphasis (enables pick radius / highlight)
- `area`: area fill (fill under the line)
- `series[i].labelSettings`: point labels (visibility/format/decimals/offset, etc.)
---
## 4. SeriesData field interpretation (runtime behavior)
Line chart uses:
- **X coordinate**: `SeriesData.x`
- **Y value**: `SeriesData.value`
- `SeriesData.y` is **not used for rendering** in line charts (do not treat `y` as the Y value).
Two common patterns:
### 4.1 Category X + Value Y (most common)
- X axis: `AxisType.Category`
- `AxisConfig.labels = ["A","B","C",...]`
- Data points:
- `x = category index` (0/1/2..., mapped into labels)
- `value = numeric value`
### 4.2 Value X + Value Y (numeric X axis)
- X axis: `AxisType.Value`
- Data points:
- `x = X value`
- `value = Y value`
> Additional note: when your axis dimensions are **X=Value, Y=Category**, runtime treats it as a transposed Cartesian layout (`transposed`) and swaps how X/Y are interpreted during rendering (useful for horizontal layouts).
---
## 5. Common style settings (LineSettings)
- **Line type**: `LineSettings.stroke.lineType`
- `Straight`: straight lines
- `Step`: step line
- `Smooth`: smooth curve
- **Stroke width/color**: `LineSettings.stroke.width` / `LineSettings.stroke.color`
- **Point markers**: `LineSettings.point.show/size/textureFill`
- **Area fill**: `LineSettings.area.show` + `LineSettings.area.textureFill`
---
## 6. Common pitfalls and troubleshooting (by symptoms)
- **Line breaks / not visible**
- Check whether `SeriesData.value` contains `NaN/Infinity`
- A line needs at least 2 valid points
- **Points do not align with labels (Category X)**
- Check that `x` is an index within 0..(labels.Count-1)
- Do not write `x` as a category string (EasyChart uses index, not string)
- **I filled `y`, but the chart is wrong**
- Line chart uses `value` as the Y value, not `y`
---
## 7. Further reading
- Axes/range, Series and data: `00_02-WorkflowAndLibrary.md`
- Common recipes: `04_08-CommonRecipes.md`
- FAQ: `04_09-FAQ.md`
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 3f6f8a04529522241b3aebdd60d113dc
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/03_01-LineChart.md
uploadId: 857482
@@ -0,0 +1,123 @@
# Bar Chart (Bar)
This chapter explains bar charts in EasyChart: the data interpretation rules (`SeriesData.x/value`), how grouping/stacking really behaves, and commonly used style fields.
---
## 1. Use cases
- Category comparisons (compare values of A/B/C)
- Grouped comparison (multiple Bar series side-by-side under the same category)
- Stacked totals (stack bars within the same category)
---
## 2. Minimum viable setup (checklist)
1. `ChartProfile.coordinateSystem = Cartesian2D`
2. Axes
- X: usually `AxisType.Category` (fill `labels`)
- Y: usually `AxisType.Value` (recommended to start from 0)
3. Series
- Add 1 `Serie`
- `Serie.type = Bar`
- `Serie.seriesData` has at least 1 point
---
## 3. Inspector fields
- **Axis Settings**
- `cartesian.xAxisId / cartesian.yAxisId`
- `axes[]` (AxisConfig for X/Y)
- **Series**
- `series[i].type = Bar`
- `series[i].settings`: actual type is `BarSettings`
- `barWidth`
- `stacked` / `stackGroup`
- `barGap` / `categoryGap`
- `cornerRadius` / `cornerSegments`
- `textureFill` (color/texture)
- `border` / `background`
- `hover` (enables picking/highlight)
---
## 4. SeriesData field interpretation (runtime behavior)
Bar charts primarily use:
- **Category / horizontal position**: `SeriesData.x`
- Runtime rounds `x` with `RoundToInt`, so **treat it as a category index**.
- **Bar height**: `SeriesData.value`
- `SeriesData.y` / `SeriesData.z` are **not used for rendering** in Bar charts (do not treat `y` as height).
---
## 5. Most common template: Category X + Value Y
### 5.1 X axis (Category)
- `AxisType = Category`
- `labels = ["A","B","C",...]`
- Recommended: `labelPlacement = CellCenter` (easier to center-align bars)
### 5.2 Data pattern
- `x = category index` (0/1/2...)
- `value = bar height`
---
## 6. Grouped bars (multiple series side-by-side): the actual rule
Key points:
- multiple `Serie`, all `type=Bar`
- all series share the same X categories (same labels)
- each series uses the same `x` index to land in the same category
Spacing fields:
- `BarSettings.barGap`: gap between bar groups within a category
- `BarSettings.categoryGap`: extra gap between categories (affects edge padding)
---
## 7. Stacked bars (stacked): the actual rule
Stacking happens between Bar series with the same stackGroup:
- `BarSettings.stacked = true`
- `BarSettings.stackGroup = "Group1"`
Runtime stacking notes:
- for the same `x` (category index), it accumulates positive and negative values separately (positive/negative stacks are separate)
- the top of each stacked segment = current accumulated base + `value`
---
## 8. Common pitfalls and troubleshooting
- **Bars appear between labels / not aligned**
- Check X axis `labelPlacement` (recommend `CellCenter`)
- Ensure `x` is an integer index (runtime rounds)
- **Bars do not start from 0**
- Check whether Y axis (Value Axis) has `autoRangeMin` disabled and `minValue=0` locked
- **Stacking result is wrong**
- Check that all series that should stack use the same `stackGroup`
- Remember: positive and negative values stack separately
---
## 9. Further reading
- Axes/range, Series and data: `00_02-WorkflowAndLibrary.md`
- Common recipes: `04_08-CommonRecipes.md`
- FAQ: `04_09-FAQ.md`
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 21fda245bf059b246a9dd9a47a8474da
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/03_02-BarChart.md
uploadId: 857482
@@ -0,0 +1,107 @@
# Scatter Chart (Scatter)
This chapter explains the data field conventions for Scatter charts in EasyChart, especially the compatibility behavior of `SeriesData.y/value`, and how the `z` dimension drives `sizeMapping`.
---
## 1. Use cases
- Correlation analysis (two numeric dimensions X/Y)
- Distribution visualization (point cloud)
- Outlier detection
---
## 2. Minimum viable setup (checklist)
1. `ChartProfile.coordinateSystem = Cartesian2D`
2. Axes
- Common: X=Value, Y=Value
3. Series
- Add 1 `Serie`
- `Serie.type = Scatter`
- `Serie.seriesData` has at least 2 points
---
## 3. Inspector fields
- `series[i].type = Scatter`
- `series[i].settings`: actual type is `ScatterSettings`
- `point`: point style (visible/size/texture)
- `hover`: hover highlight (enabled/pickRadius/scale, etc. depending on version)
- `sizeMapping`: point size mapping
---
## 4. SeriesData field interpretation (runtime behavior)
Scatter chart uses:
- **X coordinate**: `SeriesData.x`
- **Y coordinate**: prefers `SeriesData.y`
- Compatibility: if `y == 0` and `value != 0`, runtime uses `value` as y
- **Size mapping dimension**: `SeriesData.z` (when `sizeMapping.enabled=true`)
So there are two common patterns:
### 4.1 Recommended (explicit X/Y)
- `x = X value`
- `y = Y value`
### 4.2 Compatibility (legacy data: use value as y)
- `x = X value`
- `value = Y value`
- `y = 0`
> Recommendation: for new data, write `y` directly to avoid mixing meanings with `value`.
---
## 5. Standard template: Value X + Value Y
- X axis: `AxisType = Value`
- Y axis: `AxisType = Value`
- Data: use pattern 4.1 (x/y)
---
## 6. sizeMapping: actual behavior
When `ScatterSettings.sizeMapping.enabled = true`:
- point radius is mapped from `SeriesData.z`
- mapping range: `minValue/maxValue` -> `minSize/maxSize`
- if `clamp = true`, t is clamped to 0..1
- `curve` applies a curve transform to t (non-linear mapping)
If sizeMapping "doesn't work", check first:
- did you actually set `z` values (default 0)
- is `minValue/maxValue` equal (degenerates mapping)
---
## 7. Common pitfalls and troubleshooting
- **All points are on a horizontal line**
- you may have filled only `value`, but also set `y` to a non-zero value (compatibility won't trigger)
- recommend using `y` consistently as the Y coordinate
- **Hover does not respond**
- `ScatterSettings.hover.enabled` must be enabled
- too small `pickRadius` makes picking difficult
- **Points are too small / too large**
- adjust `ScatterSettings.point.size`
- or check `minSize/maxSize` in sizeMapping
---
## 8. Further reading
- Axes/range, Series and data: `00_02-WorkflowAndLibrary.md`
- Common recipes: `04_08-CommonRecipes.md`
- FAQ: `04_09-FAQ.md`
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 542aa64652c73f942b75583261cd6b10
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/03_03-ScatterChart.md
uploadId: 857482
@@ -0,0 +1,134 @@
# Heatmap Chart (Heatmap)
This chapter explains the rules for Heatmaps in EasyChart: how coordinates/cells are mapped, how `SeriesData` fields are interpreted, and how the value-to-color range is calculated. It also notes that Heatmap is a Pro feature.
---
## 1. Use cases
- 2D matrix visualization (rows/columns)
- Density/intensity visualization
---
## 2. Important note (Pro feature)
- The renderer for `SerieType.Heatmap` is registered by `EasyChartProBootstrap`.
- If EasyChartPro is not installed/enabled, this serie may be treated as a "dynamic renderer" and attempted to be created, but it usually won't render.
---
## 3. Minimum viable setup (checklist)
1. `ChartProfile.coordinateSystem = Cartesian2D`
2. Axes (Axis Settings)
- Most common: X=Category (columns), Y=Category (rows)
- X/Y can also use Value axes (see section 7)
3. Series
- Add 1 `Serie`
- `Serie.type = Heatmap`
- `Serie.seriesData` has at least 1 point
---
## 4. Inspector fields
- **Series**
- `series[i].type = Heatmap`
- `series[i].settings`: actual type is `HeatmapSettings`
- `renderMode`: Grid / Gradient / Contour
- `cellGapPx`
- `xSplitCount` / `ySplitCount` (used when X/Y are Value axes)
- `autoRange / minValue / maxValue`
- `lowColor / midColor / highColor`
- `clamp`
- `influenceMode`: None / Bleed / Smooth
- sub settings: `bleed / smooth / gradient / contour`
---
## 5. SeriesData field interpretation (runtime behavior)
Each Heatmap data point corresponds to one "cell/pixel area". Runtime uses:
- **X coordinate (column)**: `SeriesData.x`
- **Y coordinate (row)**: `SeriesData.y`
- **Intensity**: `SeriesData.value`
- **Color override**: if `SeriesData.useColor = true`, runtime uses `SeriesData.color` directly and skips interpolation from `low/mid/high`.
> Note: Heatmap `x/y` do not accept string categories. With Category axes, you still use indices.
---
## 6. Standard template: 2D Category (X/Y) + value intensity (most common)
### 6.1 X axis (Category: columns)
- `AxisType = Category`
- `labels = ["Col0","Col1",...]`
### 6.2 Y axis (Category: rows)
- `AxisType = Category`
- `labels = ["Row0","Row1",...]`
### 6.3 Data pattern
- `x = column index` (runtime applies `RoundToInt`)
- `y = row index` (runtime applies `RoundToInt`)
- `value = intensity`
### 6.4 Important detail: cell count vs `labelPlacement` for Category axes
Runtime uses the axis `labelPlacement` to decide whether to split into `labels.Count` cells or `labels.Count-1` cells:
- `CategoryLabelPlacement.CellCenter`
- X cell count = `labels.Count`
- Y cell count = `labels.Count`
- Others (non CellCenter)
- X cell count = `max(1, labels.Count - 1)`
- Y cell count = `max(1, labels.Count - 1)`
This directly affects the valid range of indices you should write into `x/y`.
---
## 7. Heatmap with Value axes (X/Y are numeric axes)
When X or Y uses `AxisType.Value`:
- Cell count no longer comes from labels. It comes from:
- X: `HeatmapSettings.xSplitCount`
- Y: `HeatmapSettings.ySplitCount`
- `SeriesData.x/y` are normalized using `_xMin/_xMax` and `_yMin/_yMax`, then mapped into cell indices.
This is suitable for intensity/density distribution over a continuous value range.
---
## 8. Common pitfalls and troubleshooting
- **All cells look the same / low contrast**
- Check whether `HeatmapSettings.autoRange` is enabled
- Or manually set `minValue/maxValue`
- Also check whether all points have almost the same `value`
- **Colors do not follow low/mid/high**
- Check whether some points set `useColor=true` (it overrides palette interpolation)
- **Cells are misaligned (out-of-range / off-by-one)**
- Check whether Category axis `labelPlacement` is `CellCenter`
- Use section 6.4 to determine correct cell count and index ranges
- **Cell gaps are too large/too tight**
- Adjust `HeatmapSettings.cellGapPx`
---
## 9. Further reading
- Axes/range, Series and data: `00_02-WorkflowAndLibrary.md`
- Common recipes: `04_08-CommonRecipes.md`
- FAQ: `04_09-FAQ.md`
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 16dbae96d4b518240828a14e5919d1b7
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/03_04-HeatmapChart.md
uploadId: 857482
@@ -0,0 +1,110 @@
# Radar Chart (Radar)
This chapter explains how Radar charts work in EasyChart: where dimension labels come from, how value ranges are calculated, and how data point order is interpreted, mapped to Inspector fields.
---
## 1. Use cases
- Multi-dimensional metric comparison
- Ability/attribute radar
---
## 2. Minimum viable setup (checklist)
1. `ChartProfile.coordinateSystem = Polar2D`
2. Series
- Add 1 `Serie`
- `Serie.type = Radar`
- `Serie.seriesData` is recommended to have at least 3 points (with <= 2 dimensions, runtime will not draw / hover won't work)
3. PolarAxes (recommended)
- `polarAxes.angleAxis.labels`: dimension names
- `polarAxes.radiusAxis`: value range (auto/manual)
---
## 3. Inspector fields
- **ChartProfile / Coordinate System**
- `coordinateSystem = Polar2D`
- **PolarAxes** (recommended for configuring Radar axes)
- `polarAxes.angleAxis.labels`: dimension labels
- `polarAxes.radiusAxis.autoRangeMin/autoRangeMax/minValue/maxValue/autoRangeRounding/labelFormat/...`
- **Series**
- `series[i].type = Radar`
- `series[i].settings`: actual type is `RadarSettings`
- `radar`: layout (startAngleDeg / clockwise / innerRadius / outerRadius / plot / background)
- `stroke`: polyline style
- `area`: area fill
- `point`: point style (point visibility also affects hover pick radius)
- `series[i].labelSettings`: data point labels (can show dimension name and value)
---
## 4. SeriesData field interpretation (runtime behavior)
Key point for Radar: **dimension order is defined by the index of items in the `seriesData` list**.
- **Value**: uses `SeriesData.value`
- **Dimension index**: uses the position `i` in `seriesData` (0..dimensionCount-1)
- `SeriesData.x` is **not used for positioning** in Radar rendering (do not rely on x to represent dimensions)
Where does dimensionCount come from:
1. Prefer `Data.PolarAxes.angleAxis.labels.Count`
2. If angleAxis.labels is not configured, it uses labels from a Category Axis (see section 5)
3. Otherwise, fall back to `seriesData.Count` (or the maximum count among multiple series)
---
## 5. Actual priority order for dimension labels
Runtime resolves dimension names in this priority order:
1. `polarAxes.angleAxis.labels[i]`
2. `labels[i]` from a `AxisType.Category` axis in `axes[]`
- it prefers the Category axis that matches `Data.XAxisId`
3. `seriesData[i].name`
4. If none exists, it shows `Dim i`
> Recommendation: for Radar, manage dimension names via `polarAxes.angleAxis.labels`. Use `SeriesData.name` as a fallback.
---
## 6. How radius value range is calculated
Radar radius range is calculated from `SeriesData.value`:
- By default, it computes auto range from values across all Radar series
- If you configure `polarAxes.radiusAxis`:
- `autoRangeMin/autoRangeMax` decides whether min/max are automatic
- `minValue/maxValue` take effect when the corresponding auto range is disabled
- `autoRangeRounding` rounds auto min/max to tens/hundreds/custom unit
- `labelFormat` affects tooltip/label formatting
---
## 7. Common pitfalls and troubleshooting
- **Radar chart not visible**
- Check `coordinateSystem` is `Polar2D`
- Dimension count must be > 2 (labels or seriesData must be at least 3)
- **Dimensions do not match / order is wrong**
- Radar does not use `x`. It uses `seriesData` list order as dimension order
- Put points in `seriesData` in the intended dimension order
- **Hover is hard to trigger**
- Radar pick radius is related to `RadarSettings.point.size`
- If `point.show=false`, pick radius becomes 0 (almost impossible to hover)
---
## 8. Further reading
- Series and data: `00_02-WorkflowAndLibrary.md`
- Common recipes: `04_08-CommonRecipes.md`
- FAQ: `04_09-FAQ.md`
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: ab1dd2fe7e872d147a2d94687affecef
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/03_05-RadarChart.md
uploadId: 857482
@@ -0,0 +1,174 @@
# Pie Chart (Pie)
This chapter explains how Pie charts work in EasyChart: how data fields are interpreted, how layout/aggregation/legend/interactions take effect, and which behaviors have hidden prerequisites, mapped to Inspector fields.
---
## 1. Use cases
- Showing proportions/composition
- Emphasizing the share of each category in the whole
Not suitable for:
- Too many categories (usually > 812 becomes hard to read)
- Precise comparison of tiny differences (a bar chart is usually better)
---
## 2. Minimum viable setup (checklist)
1. `coordinateSystem`: Pie does not rely on Cartesian/Polar coordinate systems (keep your Profile setting)
2. Add 1 `Serie`:
- `type = Pie`
- `settings = PieSettings`
- `seriesData` has at least 1 point
3. Ensure each point has `value > 0`
> Note: Pie currently ignores points with `value <= 0`.
---
## 3. Important limitations (runtime behavior)
- **Only the first visible Pie serie is drawn**: the renderer iterates `Data.Series`, finds the first visible serie with `type=Pie`, draws it, then `break`s.
- Slice hidden state comes from `ChartInteractionState.HiddenPieSliceIds`, which is added/removed when clicking legend items.
---
## 4. SeriesData field interpretation (runtime behavior)
Pie mainly uses:
- `value`: numeric value (weight) of the slice
- `name`: slice name (recommended)
- `useColor + color`: per-slice custom color (optional)
- `id`: stable slice identifier (for hidden/interaction state; keep it stable)
### 4.1 Recommended pattern: explicit name + value
- `SeriesData.name = "Apple"`
- `SeriesData.value = 12`
### 4.2 Name fallback when name is empty
When `SeriesData.name` is empty, Pie may try to use **labels**, but with an important prerequisite:
- If `ChartData.CoordinateSystem == None` (typically pure Pie / no coordinate system), runtime **skips label fallback** and uses only `SeriesData.name`.
When coordinate system is not None, the fallback order is:
- Prefer Category axis labels that match `Data.Cartesian.xAxisId`
- Otherwise, use labels from any Category axis
- Final fallback: `Slice {index}`
> Therefore: if you do not want to depend on axis configuration, fill `SeriesData.name` directly.
### 4.3 Color source
- If `useColor=true` on the point: use `SeriesData.color`
- Otherwise: use the built-in palette in order
---
## 5. Common settings (PieSettings)
Pie `settings` is `PieSettings`, mainly including:
- `layout`: layout (angle/radius/gaps/center offset, etc.)
- `hover`: hover interaction (explode)
- `aggregation`: aggregation (TopN + Others)
- `legend`: Pie-specific legend settings (replaces global legend only for "pure Pie chart" cases)
### 4.1 layout (PieLayoutSettings)
Common fields:
- `startAngleDeg`: start angle (default -90 makes the first slice start at the top)
- `clockwise`: clockwise/counter-clockwise
- `angleRangeDeg`: angle range (default 360; use 180 for half-pie, etc.)
- `outerRadius`: outer radius
- `<= 0`: auto
- `0~1`: normalized by control size
- `> 1`: pixels
- `innerRadius`: inner radius (Pie usually 0; >0 creates a hole, but RingChart is recommended for ring/progress style)
- `innerRadiusColor`: inner fill color
- `sliceGapPx`: gap between slices (pixels)
- `sliceGapType`: gap mode (Radial/Translate/Uniform)
- `cornerRadius`: corner radius (pixels, limited by slice thickness)
- `plot.padding`: padding (avoid clipping slices/outside labels)
- `plot.centerOffset`: center offset
### 4.2 hover (PieHoverSettings)
- `hover.enabled`: enable hover interaction
- `hover.explodeType`:
- `Translate`: translate the whole slice
- `Pull`: pull out / stretch
- `Color`: brighten
- `Stroke`: stroke emphasis
- `hover.explodeDistance`: translate/pull distance (pixels)
### 4.3 aggregation (PieAggregationSettings)
When there are many categories, you can merge small items into `Others`:
- `aggregation.enabled = true`
- `keepTopN`: keep top N, merge the rest
- `sortByValue`: sort by `value` before taking TopN
- `othersName`: name for Others
- `useOthersColor + othersColor`: Others color
> Note: aggregation only takes effect when `keepTopN > 0` and slice count exceeds N.
---
## 6. Legend (PieLegendSettings) and "hide slice" interaction
When the chart is a "pure Pie chart" (only Pie/RingChart/Pie3D and no other types):
- Legend prefers `PieSettings.legend` (or the legend on RingChartSettings/Pie3DSettings), instead of `ChartData.legend`.
- Clicking a legend item toggles `HiddenPieSliceIds`:
- normal slices: `SeriesData.id` (if empty, uses index string)
- aggregated Others: always `__ec_pie_others__`
`PieLegendSettings.source` affects where legend items come from:
- `Slice`: one entry per slice (default)
- `RingSlice`: provides label source for RingChart/RingSlice scenarios (prefers PolarAxes.angleAxis.labels)
- `Series`: one entry per serie (not slice-level)
---
## 7. Labels (SerieLabelSettings)
Pie labels are controlled by `Serie.labelSettings`:
- `show`: whether to show
- `fontSize / color / decimalPlaces`: font and value format
- `showName`: whether to include slice name
- `position`: `Outside/Inside/Center`
- `offset`: offset
---
## 8. Common pitfalls (by symptoms)
- **Some slices are not visible**
- Check whether the point `value` is `<= 0`
- **Slice name is not what I expect**
- Recommended: fill `SeriesData.name` directly
- If you rely on labels: ensure you have a Category axis with `labels`, and the order matches data point indices
- **Slice colors change each time / hard to control**
- For slices that need fixed colors: set `useColor=true` + `color` on the point
- **Hidden/interaction state is unstable**
- Ensure each point `SeriesData.id` is stable (do not regenerate ids on each refresh)
---
## 9. Next
- Ring chart (RingChart): `03_07-RingChart.md`
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 2bffa5abab7faa442b8f86f43817e37f
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/03_06-PieChart.md
uploadId: 857482
@@ -0,0 +1,170 @@
# Ring Chart (RingChart)
This chapter explains what RingChart really means (it is not a donut pie), and aligns its `SeriesData` interpretation, `RingChartSettings` configuration, and Pro/base differences with runtime behavior.
---
## 1. What is RingChart? (very important)
In the current EasyChart implementation:
- `SerieType.RingChart` renders **multiple progress rings** (one ring per data point)
- each ring is a **full 360° background ring + one progress arc**
- it is not a pie chart that splits the circle into multiple slices
If you want a donut pie chart that shows composition:
- it is closer to `SerieType.Pie` + `layout.innerRadius > 0`
- but you should choose based on intent:
- composition/proportion: use Pie
- multi-metric progress/completion: use RingChart
---
## 2. Important note (Pro feature)
- The renderer for `SerieType.RingChart` is registered by `EasyChartProBootstrap`.
- Without Pro installed/enabled, this serie usually won't render.
---
## 3. Minimum viable setup (checklist)
1. Add 1 `Serie`
- `type = RingChart`
- `settings = RingChartSettings`
- `seriesData` has at least 1 point
2. Each point has `value > 0`
> Note: RingChart ignores points with `value <= 0`.
---
## 4. SeriesData field interpretation (runtime behavior)
RingChart mainly uses:
- `value`: the raw progress value
- `name`: ring name
- `useColor + color`: ring color (per-point override)
- `id`: stable identifier (for legend/hidden state; keep it stable)
### 4.1 Percent mode (default): value supports both 0~1 and 0~100
When `RingChartSettings.valueMapping.mode = Percent` (default):
- `value <= 0`: the ring is filtered out
- `0~1`: treated as ratio (0.72 = 72%)
- `> 1`: treated as percent (72 = 72%, runtime divides by 100)
Recommendation: standardize one convention within your team (all 0~1 or all 0~100) to avoid mistakes.
### 4.2 Range mode: map value to 0..1
When `RingChartSettings.valueMapping.mode = Range`:
- It first determines the range `min/max`:
- `autoRange=true`: compute from values across all rings
- `autoRange=false`: use `minValue/maxValue`
- Then it maps to `(value-min)/(max-min)` and clamps to 0..1
### 4.3 Name fallback when name is empty
When `SeriesData.name` is empty, RingChart tries to fall back to labels:
- If `ChartData.CoordinateSystem == None`: it won't use labels, and falls back to `Ring {i}`
- Otherwise it prefers: `Data.PolarAxes.angleAxis.labels[i]`
- Otherwise: labels from Cartesian/any Category axis `labels[i]`
- Final fallback: `Ring {i}`
If you do not want to depend on PolarAxes configuration, fill `SeriesData.name` directly.
---
## 5. Inspector fields (RingChartSettings)
- `series[i].type = RingChart`
- `series[i].settings`: actual type is `RingChartSettings`
- `layout`: angles/radius/inner-outer ring/padding/center offset
- `valueMapping`: Percent/Range mapping rules
- `hover`: hover emphasis (Translate/Pull/Color/Stroke)
- `legend`: RingChart legend settings (effective for pure Pie charts)
- `showBackground/backgroundAlpha/backgroundColor`: background ring
- `cornerRadius`: rounded cap
- `ringGapPx`: gap between rings
### 5.1 layout (RingChartLayoutSettings)
Common fields:
- `startAngleDeg`: start angle
- `clockwise`: clockwise/counter-clockwise
- `angleRangeDeg`: default 360; use for half-ring progress, etc.
- `outerRadius`: outer radius (<=0 auto; 0~1 normalized; >1 pixels)
- `innerRadius`: inner radius (0~1 normalized or pixels)
- `plot.padding`: padding (avoid clipping hover/labels)
- `plot.centerOffset`: center offset
### 5.2 hover (PieHoverSettings)
- `hover.enabled`: enable
- `hover.explodeType`:
- `Translate`: translate the whole ring
- `Pull`: pull/stretch
- `Color`: brighten
- `Stroke`: stroke emphasis
- `hover.explodeDistance`: translate/pull distance (pixels)
### 5.3 Background ring and spacing
- `showBackground`: draw background ring
- `backgroundAlpha`: background ring alpha (multiplied into final color alpha)
- `backgroundColor`: background ring color (when alpha=0, it falls back to ring color)
- `ringGapPx`: gap between rings
- `cornerRadius`: rounded cap (limited by ring thickness)
---
## 6. Legend and hide interaction (shared HiddenPieSliceIds with Pie)
- RingChart shares `ChartInteractionState.HiddenPieSliceIds` with Pie.
- Hidden key for each ring: prefer `SeriesData.id`, otherwise use the index string.
- Legend label source is affected by `PieLegendSettings.source`:
- `RingSlice` prefers `polarAxes.angleAxis.labels`.
---
## 7. Labels (SerieLabelSettings)
RingChart labels also use `Serie.labelSettings`:
- `show`: whether to show
- `showName`: whether to show name
- `decimalPlaces`: decimals (note: this displays the raw `value`, not a percent text multiplied by 100)
- `position`:
- `Outside`: outside label + leader line
- `Center`: centered on the ring
---
## 6. Common pitfalls (by symptoms)
- **I thought it was a donut pie, but it looks wrong**
- This is a multi-ring progress chart: each point is one progress ring
- **Progress is wrong (e.g. I set 75 but it is almost full)**
- `value>1` is treated as percent and divided by 100
- For 75%: use `0.75` or `75`
- **Some rings are not visible**
- Check whether `value <= 0` is being filtered
- **Interaction/hidden state is unstable**
- Ensure `SeriesData.id` is stable
---
## 8. Further reading
- Pie (composition/proportion): `03_06-PieChart.md`
- Series data structure: `00_02-WorkflowAndLibrary.md`
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: fbaf24c6bef7e9f4ba07bd263dbaf37c
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/03_07-RingChart.md
uploadId: 857482
@@ -0,0 +1,224 @@
# Common Recipes
This chapter provides copy-ready recipes for common charts (Series + Axes + common pitfalls) to help you create and troubleshoot quickly.
---
## 0. Before you start: minimum checklist
When you see "nothing shows" or "it looks weird", check in this order:
1. Does `coordinateSystem` match the SeriesType (Cartesian2D vs Polar2D)
2. Does `series` contain at least 1 serie, and does that serie have `seriesData.Count > 0`
3. Do axis types match what your data means:
- Category axis: `labels` is not empty, and data `x/y` are indices (0/1/2...)
- Value axis: data `x/y` are continuous numeric values
4. Do you have any NaN/Infinity
5. Did you lock Value axis range (`autoRangeMin/autoRangeMax` or fixed min/max) so data is outside the range
---
## 1. Line chart (Line): Category X + numeric Y
### Target
- X: category labels (A/B/C/D)
- Y: numeric values
- line points aligned to categories
### Recipe
1. `coordinateSystem = Cartesian2D`
2. X axis:
- `axisType = Category`
- `labels = [A, B, C, D]`
- `LabelPlacement = Tick`
3. Y axis:
- `axisType = Value`
- `autoRangeMin/autoRangeMax = true`
4. Series:
- `type = Line`
- points: `x=category index`, `y=value`
Data example (conceptual):
```txt
(x=0, y=10)
(x=1, y=20)
(x=2, y=15)
(x=3, y=30)
```
### Common pitfalls
- **Points do not align with labels**: check `x` starts from 0 and is within range (labels.Count)
- **Line looks broken/jumpy**: check NaN/Infinity
---
## 2. Bar chart (Bar): centered categories + Y starts from 0
### Target
- one bar per category
- labels centered under bars
- Y axis starts from 0 to avoid misleading scaling
### Recipe
1. `coordinateSystem = Cartesian2D`
2. X axis:
- `axisType = Category`
- fill `labels` with categories
- `LabelPlacement = CellCenter`
3. Y axis:
- `axisType = Value`
- force start at 0 (e.g. `minValue=0` + `autoRangeMax=true`, or equivalent)
4. Series:
- `type = Bar`
- adjust bar width via `BarSettings.barWidth`
Data example:
```txt
(x=0, y=12)
(x=1, y=18)
(x=2, y=9)
```
### Common pitfalls
- **Bars appear between labels**: switch `LabelPlacement` to `CellCenter`
- **Bars too dense/too sparse**: adjust `barWidth`, `barGap`, `categoryGap`
---
## 3. Grouped bars (Grouped Bar): multiple series share the same categories
### Recipe
- multiple `Serie`, all `type = Bar`
- each Serie uses the same `x=category index` convention
- use `Serie.name` as group name (used by legend/tooltip)
Example (conceptual):
```txt
Serie A:
(x=0, y=10) (x=1, y=12)
Serie B:
(x=0, y=8) (x=1, y=15)
```
---
## 4. Stacked bars (Stacked Bar): stacked + stackGroup
### Recipe
- Bar series that should stack:
- `BarSettings.stacked = true`
- `BarSettings.stackGroup = "Group1"` (same group stacks)
### Common pitfalls
- **Stack height looks wrong**: ensure all stacked series use exactly the same `stackGroup`
---
## 5. Scatter chart (Scatter): Value X/Y + hover + sizeMapping
### Target
- X/Y are continuous numeric values
- point grows on hover
- point size can be mapped by a dimension (sizeMapping)
### Recipe
1. `coordinateSystem = Cartesian2D`
2. Set both X/Y axes to `Value`
3. `type = Scatter`
4. Data points: at least `x/value`, optionally use `z` as third dimension
5. `ScatterSettings.hover.enabled = true`
### Common pitfalls
- **Points are too small**: increase `PointSettings.size`
- **Hover does not respond**: check `HoverHighlightSettings.enabled` and `pickRadius`
---
## 6. Heatmap chart (Heatmap): (x, y, value) triplets
### Target
- X/Y are Category axes (2D labels)
- color is determined by value
### Recipe
1. `coordinateSystem = Cartesian2D`
2. X axis: Category + labels (column labels)
3. Y axis: Category + labels (row labels)
4. `type = Heatmap`
5. Data points:
- `x = column index`
- `y = row index`
- `value = intensity`
Example (conceptual):
```txt
(x=0, y=0, value=0.2)
(x=1, y=0, value=0.8)
(x=0, y=1, value=0.5)
```
### Common pitfalls
- **All cells look the same**: check `HeatmapSettings.autoRange/minValue/maxValue/clamp`
- **Cells too small/too dense**: adjust `cellSizePx` / `cellGapPx`
---
## 7. Radar chart (Radar): dimension index + value
### Recipe
1. `coordinateSystem = Polar2D`
2. `type = Radar`
3. Data points:
- `x = dimension index`
- `value = numeric value`
- `name = dimension name` (recommended for labels/tooltip)
Example:
```txt
(x=0, value=72, name="Attack")
(x=1, value=55, name="Defense")
(x=2, value=90, name="Speed")
```
### Common pitfalls
- **Radar labels are missing/messy**: ensure your dimension label source is consistent (do not depend on Cartesian axes)
- **Radar not visible**: check `coordinateSystem` is Polar2D
---
## 8. Interaction/tooltip stability: SeriesData.id
If you enabled selection/tooltip/hover, it is generally recommended:
- keep each point `SeriesData.id` stable
> Otherwise, if you generate new ids every refresh, interaction state cannot be associated correctly.
---
## Next
- Next: `04_09-FAQ.md` (common issues + the fastest troubleshooting path)
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 3150243976518e347ac36c43af89f4fc
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/04_08-CommonRecipes.md
uploadId: 857482
@@ -0,0 +1,173 @@
# FAQ (Common Issues and the Fastest Troubleshooting Path)
This chapter helps you locate the cause with the shortest path when you encounter "nothing shows", "wrong rendering", or "weird interactions".
---
## 0. Fast troubleshooting path (30-second version)
Check in order. This usually solves 80% of issues:
1. **Does coordinate system match SeriesType**
- Cartesian2D: Line/Bar/Scatter/Heatmap
- Polar2D: Radar
2. **Do you actually have data**
- `series.Count > 0`
- the serie has `seriesData.Count > 0`
3. **Do axis types match what your data means**
- Category axis: `labels` is not empty; data `x/y` are indices (0/1/2...)
- Value axis: `x/y` are continuous numeric values
4. **Any NaN / Infinity**
5. **Is data excluded by Value axis range**
- Check if min/max are fixed
- Check if `autoRangeMin/autoRangeMax` are disabled
---
## 1. I clicked Preview but nothing shows
### Possible causes
- `seriesData` is empty
- `Serie.visible = false`
- coordinate system does not match SerieType (e.g. Radar in Cartesian2D)
- axis range does not include your data (common when Value axis range is locked manually)
### What to do
1. In the Inspector, find `series` and expand a Serie
2. Check:
- whether `visible` is true
- whether `seriesData` has any elements
3. Check the coordinate system:
- Radar -> `coordinateSystem = Polar2D`
- Line/Bar/Scatter/Heatmap -> `coordinateSystem = Cartesian2D`
4. If you are using Value axes:
- first disable any "fixed min/max" range settings
- enable both `autoRangeMin/autoRangeMax`, confirm it renders, then lock step-by-step
---
## 2. Category axis has labels, but points/bars are not on labels
### Typical symptoms
- bars appear between two labels
- line points do not align to A/B/C
### Quick conclusion
- With a Category axis, `x` (or `y`) should usually be the **category index** (0/1/2/...), not an arbitrary value.
### What to do
- Check your data points:
- `labels[0]` corresponds to `x=0`
- `labels[1]` corresponds to `x=1`
- If you are making a bar chart:
- set `LabelPlacement` to `CellCenter`
---
## 3. Value axis range is weird (too large/too small)
### Possible causes
- Value axis range is locked (min/max)
- only one side is locked but the other side has extreme values
- rounding/unit snapped the range to an unsuitable unit
### What to do
1. First, revert to full auto range and confirm it renders
2. Then gradually add your constraints:
- common for bar charts: `minValue=0` + `autoRangeMax=true`
3. If you see lots of weird decimal ticks:
- set `labelFormat` first
---
## 4. Line is broken / nothing renders
### Most common cause
- NaN / Infinity exists in your data
### What to do
- Filter at the data source:
- `float.IsNaN(x/y/z)`
- `float.IsInfinity(x/y/z)`
---
## 5. Bar chart and labels do not align
### Quick conclusion
- 99% of the time, `LabelPlacement` is not the right one
### What to do
- Bar: prefer `LabelPlacement = CellCenter`
- Line/Scatter: prefer `LabelPlacement = Tick`
---
## 6. Heatmap is all one color / looks flat
### Possible causes
- `autoRange=false` but `minValue/maxValue` are unreasonable
- `clamp=false` and extreme values stretch the color range
- all data points have the same `value` (or all are 0)
### What to do
1. Enable `autoRange`
2. Check whether data point `value` varies
3. If you need a fixed range:
- set `minValue/maxValue` reasonably
---
## 7. Radar labels are missing/messy
### Common cause
- dimension label sources are inconsistent
### Recommended approach
- For each Radar point:
- `x = dimension index`
- `value = numeric value`
- `name = dimension name`
Also ensure Radar does not rely on Cartesian axis configuration to obtain labels.
---
## 8. tooltip/hover/selection points to the wrong item or state is unstable
### Common cause
- new point identifiers are generated on every refresh
### What to do
- keep each point `SeriesData.id` stable
- avoid clearing and generating a completely new set of points with `Guid.NewGuid()` on every refresh
---
## 9. I don't know which chapter to read
- If you are in the workflow stage (create/clone/preview/export): see `01_01-EditorWorkflow.md`
- If you are dealing with axes/range/alignment/unit/format: see section 7 of `00_02-WorkflowAndLibrary.md`
- If you need the data conventions for a specific chart (SeriesData.x/y/z): see section 8 of `00_02-WorkflowAndLibrary.md`
- If you just want copy-ready templates: see `04_08-CommonRecipes.md`
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 6d348b4bd3671b346ab70ccd28bc9abe
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/04_09-FAQ.md
uploadId: 857482
@@ -0,0 +1,172 @@
# Roadmap / Update Plan
This chapter describes the overall direction and planned items for future EasyChart updates.
- This file is **not split by version phases** (more detailed planning can be added inside each chart type chapter later)
- This file is organized by "capability categories" (you can treat it as a roadmap table of contents)
## Free / Pro split (release strategy)
### Free (standalone package)
- Positioning: cover the most common AssetStore use cases, forming a full loop of "configurable + previewable + runtime data injection".
- Includes: existing basic 2D chart types, runtime injection (`ChartFeed` / `ApplyJson`), editor workflow such as `EasyChartLibraryWindow`.
### Pro (standalone package, includes all Free)
- Positioning: provide clear differentiated capabilities and a long-term expansion path on top of Free.
- Includes: everything in Free + Pro incremental features (advanced effects / new chart types / 3D / tooling, etc.).
### Compatibility strategy
- When Free encounters Pro-only assets/configurations: it is allowed to fail with a direct error (no downgrade compatibility required).
### Pro initial selling points priority
- A: new chart types
- B: 3D charts
- C: advanced 2D visual effects (e.g. texture UV animation, special rendering effects)
---
## Appendix: version plan (tentative timeline)
> Note: the following is a tentative monthly/quarterly cadence. Specific dates can be refined after team capacity and release window are confirmed.
### 2026 Q1 (JanMar): stabilization + complete Free loop
- 2026-01 (Free v1.0.x):
- Fix/finalize: stability of JSON Injection panel and example generation/parsing (based on current TODO)
- Docs & samples: align with the latest data structures and panel capabilities
- 2026-02 (Free v1.1.0):
- 2D UX improvements (Free scope): Bar rounded corners, hover effects (if not implemented yet, land in this version)
- Editor UX: small workflow improvements in LibraryWindow (no Pro dependencies)
- 2026-03 (Free v1.1.x):
- Regression fixes + performance/GC optimization (large data refresh, tooltip/interaction stability)
### 2026 Q2 (AprJun): Pro v1.0 (new chart types first)
Each series type adds an animation component collection, allowing effects such as Point blinking and TextureFill UV animation.
- 2026-04 (Pro v1.0.0):
- Finalize Pro package structure and release workflow (Pro includes all Free)
- New chart types (batch 1): Gauge / Funnel (one or both depending on complexity)
- 2026-05 (Pro v1.0.x):
- New chart types (batch 2): BoxPlot / Candlestick (implement one with higher priority)
- Improve Pro-only error hints and readable Editor-side error messages
- 2026-06 (Free v1.2.0 + Pro v1.1.0):
- Free: continue filling common 2D capabilities and stability
- Pro: expand new chart types (Treemap / Sunburst research or first version)
### 2026 H2 (JulDec): 3D roadmap and effects
- 2026 Q3 (JulSep) (Pro v2.0 or v1.2+):
- 3D charts (batch 1): 3D Bar / 3D Scatter (prioritize one to complete an end-to-end workflow)
- 3D rendering pipeline and interaction foundations (iterate by minimum viable slices)
- 2026 Q4 (OctDec):
- 3D Surface (research/experimental)
- Advanced 2D visual effects (Pro): texture UV animation (and more complex effects later)
- Tooling improvements: Theme / direct networking / automated tests (pick one as the main quality track)
---
## 1. Chart type expansion plan (Chart Types)
### 1.1 2D charts (enhancements to existing system)
- Goal: without adding too many `SerieType`, fill common expressions via settings/variants.
- Candidate directions (examples):
- Line: more line types/fills/annotations (richer markers/threshold lines, etc.), texture UV animation (Pro)
- Bar: more stacking modes, percent stacking, waterfall modes, rounded bar caps (Free), hover effects (Free), texture UV animation (Pro)
- Scatter: more mapping dimensions (size/color), density expressions (aggregation/gridding)
- Pie: more layout/aggregation strategies, label strategies, interactions
### 1.2 New chart types (may add new `SerieType`)
- Goal: support more common standalone chart categories in AssetStore.
- Candidate directions (examples):
- Gauge
- Funnel
- BoxPlot
- Candlestick (OHLC)
- Treemap / Sunburst (hierarchical visualization)
- Sankey / Graph (more complex structural charts; later)
### 1.3 3D charts (3D Charts)
- Goal: provide a 3D chart capability set (possibly a separate rendering pipeline).
- Candidate directions (examples):
- 3D Bar / 3D Column
- 3D Scatter
- 3D Surface (higher complexity; later)
---
## 2. Multi-axis & coordinate systems
- Goal: enhance multi-axis scenarios while keeping semantics clear.
- Directions:
- more axis combinations (dual Y axes, top/bottom X, mixed left/right Y)
- clearer axis binding strategy (which axis a Serie binds to, which axis tooltip/label formats with)
- constraints and hints for switching/mixing coordinate systems (avoid confusing configs)
---
## 3. Font & text system
- Goal: unify text rendering look and configurable options, reducing UI Toolkit cross-platform differences.
- Directions:
- more complete text styles (font, size, weight, color, outline/shadow, etc.)
- text layout strategies (wrap, truncate, ellipsis, alignment, anchors)
- enhanced number formatting (thousands separator, units, percent, scientific notation, etc.)
---
## 4. Time axis & log axis
- Goal: improve expression for time series and wide-range values.
- Directions:
- time axis: ticks, formatting, interval strategies (day/week/month/year)
- log axis: log10/log2 ticks and labels
- integration with data injection (how to feed time data, handle missing points)
---
## 5. Theme / palette system
- Goal: abstract "colors/fonts/default styles" from individual Profiles into reusable themes.
- Directions:
- Theme assets (Palette + fonts + default styles)
- override strategy between Profile and Theme (theme defaults vs Profile overrides)
- theme preview, switching, theme library
---
## 6. Direct networking / data binding
- Goal: reduce integration cost from network API to chart.
- Directions:
- standard input protocol based on `ChartFeed`
- optional API Envelope support (e.g. `{code,message,data}`)
- samples: HTTP fetch -> parse -> Apply
- caching, throttling, error hints, fallback strategies
---
## 7. Automated tests & QA
- Goal: reduce iteration risk and make refactors safer.
- Directions:
- data migration tests (serialization compatibility)
- rendering regression tests (screenshot diff/pixel tolerance, or key mesh assertions)
- interaction tests (tooltip/hit test stability)
- performance benchmarks (large data refresh, GC, frame time)
---
## 8. Editor workflow & tooling
- Goal: make configuration, preview, injection, and reuse smoother.
- Directions:
- LibraryWindow: templates/copy/import-export/batch operations
- JSON Injection: stronger protocol compatibility, better error localization, better example generation
- clearer manual and sample project
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 84f6d1c5ac835fb409a6d70824b41c75
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Docs/Manual/en/05_01-UpdatePlan.md
uploadId: 857482