拼ui 一些业务逻辑x实现
This commit is contained in:
@@ -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 (3–8) 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 > 8–12 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 (Jan–Mar): 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 (Apr–Jun): 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 (Jul–Dec): 3D roadmap and effects
|
||||
|
||||
- 2026 Q3 (Jul–Sep) (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 (Oct–Dec):
|
||||
- 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
|
||||
Reference in New Issue
Block a user