Merge branch 'master' into 3.0

This commit is contained in:
monitor1394
2024-09-30 18:35:24 +08:00
42 changed files with 25991 additions and 7279 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,9 @@
# 更新日志
[master](#master)
[v3.12.0](#v3120)
[v3.11.2](#v3112)
[v3.11.1](#v3111)
[v3.11.0](#v3110)
[v3.10.2](#v3102)
[v3.10.1](#v3101)
@@ -69,6 +72,48 @@
## master
## v3.12.0
Version Highlights:
* Added `radiusGradient` parameter for `Ring` to set the gradient direction
* Added support for `date` and `time` in `numericFormatter`
* Improved `origin` parameter setting for `AreaStyle` to define the starting position of area filling
* Adjusted and perfected the documentation
* Other optimizations and fixes
Log Details:
* (2024.09.30) Released version `v3.12.0`
* (2024.09.27) Improved the `5-minute tutorial`
* (2024.09.24) Improved support for multiple Series in `Legend`'s `formatter` (#332)
* (2024.09.22) Adjusted the display style of the `Documentation`
* (2024.09.09) Added support for `date` and `time` in `numericFormatter`
* (2024.09.03) Improved the setting of the `origin` parameter for `AreaStyle` to define the starting position of area filling
* (2024.09.01) Added `radiusGradient` parameter for `Ring` to set the gradient direction
* (2024.09.01) Optimized the position of the first Label when `Axis` is used as a time axis
## v3.11.2
* (2024.08.01) Release `v3.11.2`
* (2024.07.29) Fixed compatibility issue with `Tooltip` reporting error on wechat mini game platform (#326)
* (2024.07.27) Adjust the default position of `AxisName` for `Axis`
* (2024.07.22) Improved the behavior of `Pie`'s `Label` when `Tooltip` is triggered
* (2024.07.21) Fix to `Tooltip` indicating inaccurate content when opening `DataZoom`
* (2024.07.17) Fixed an issue where `Label` of `MarkLine` could flash during initialization
* (2024.07.16) Optimized the default effect of `Tooltip` when `Axis` is `Time` timeline
* (2024.07.15) Optimized segmentation when Axis is Time
* (2024.07.14) Improved movement performance when `Axis` is `Time`
* (2024.07.12) Optimized the initial display effect of `Label`
* (2024.07.06) Fix to `Chart` background not adaptive when dynamically created (#323)
## v3.11.1
* (2024.07.01) Release `v3.11.1`
* (2024.07.01) Fixed an issue where `Serie` has multiple abnormal colors
* (2024.06.23) Fixed an issue where `labels` would pile up during initialization
## v3.11.0
Release Highlights:

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,103 +1,143 @@
---
title: Introductory tutorial: Get started with XCharts 3.0 in 5 minutes
title: Tutorial: Getting Started with XCharts 3.0 in 5 Minutes
sidebar_position: 11
slug: /tutorial01
---
# Tutorial: Get started with XCharts 3.0 in 5 minutes
# Tutorial: Getting Started with XCharts 3.0 in 5 Minutes
> Note: This tutorial is for XCharts 3.x version only
## What do I need to know before using XCharts
> Note: This tutorial is only applicable to the XCharts 3.x version. For the 2.x version, please refer to [Tutorial: Mastering XCharts 2.0](https://github.com/XCharts-Team/XCharts/blob/2.0/Doc/Tutorial%3A5-Minute-Start-to-XCharts.md)
- Have used Unity, know the basic operation of Unity.
- Understand UGUI and can use UGUI.
- Understand MonoBehavior script usage in Unity, know how to hang scripts, manipulate scripts with code.
## Prerequisites for XCharts
## Get and import XCharts
XCharts is a Unity chart plugin, currently only available for use on the Unity platform.
XCharts can be imported into a project in any of the following ways:
Before using XCharts, you need to:
- Source XCharts directly into the project
- Have a basic understanding of how to use Unity.
- Understand the basic usage of UGUI for making UI.
- Know how to use Unity's MonoBehavior scripts, how to attach scripts, and how to manipulate scripts with code.
After downloading the XCharts source code, copy the XCharts directory directly to the Assets directory of the Unity project.
If you are new to Unity, it is recommended to learn some basic Unity tutorials before using XCharts.
- Import XCharts through `Assets/Import Package`
## Obtaining and Importing XCharts
After downloading the.unitypackage file for XCharts, open Unity and go to the menu bar Assets--> Import Package--> Select.unitypackage import to start using XCharts.
XCharts is primarily maintained and released through Github. You can download the source code and Package from the [Github Homepage](https://github.com/XCharts-Team).
- Import XCharts through the Package Manager
XCharts can be imported into your project in any of the following ways:
For Unity 2018.3 and later, XCharts can be imported through the Package Manager. After opening the Package Manager, run the `Add package form git URL...`, input XCharts dead simple URL: ` https://github.com/XCharts-Team/XCharts.git use XCharts after ` wait a moment.
### Copying the XCharts Source Code Directly into the Project
You can also add the package directly to the manifest.json file: Open the manifest.json file in the Packages directory and add it under dependencies:
After downloading the XCharts source code, simply copy the XCharts directory into the Assets directory of your Unity project. Once compiled, it is ready to use.
``` json
"com.monitor1394.xcharts" : "https://github.com/XCharts-Team/XCharts.git",
```
### Importing XCharts through Import Package
To update XCharts, remove com.monitor1394.xcharts from the manifest.json file under lock (some versions of Unity may be packages-lock.json) and re-download and compile.
After downloading the .unitypackage file of XCharts, open Unity, go to the menu bar Assets-->Import Package-->select the downloaded .unitypackage to import. After the import is complete and compiled, you can start using XCharts.
- Recommended daemon into XCharts (not required)
### Importing XCharts through Package Manager
[XCharts Daemon](https://github.com/XCharts-Team/XCharts-Daemon) can ensure update compilation is normal, when the local open TextMeshPro or NewInputSystem would be very useful. After importing Xchart-daemon into a project, when updating XCharts, the Daemon will automatically refresh asmdef according to the status of local TMP, etc., to ensure normal compilation and facilitate the execution of automated processes such as CI-CD.
For Unity versions above 2018.3, you can import XCharts through the Package Manager. Open the Package Manager, then use `Add package from git URL...`, enter the GitHub URL of XCharts: `https://github.com/XCharts-Team/XCharts.git`. After compiling, you can use XCharts.
## Add a simple chart
For some Unity versions, you can also directly add the package to the `manifest.json` file: Open the `manifest.json` file under the `Packages` directory, and add the following under `dependencies`:
Right-click in `Hierarchy` view or menu bar `GameObject` drop down and select `XCharts->LineChart`, can quickly create a default line chart out:
>"com.monitor1394.xcharts": "https://github.com/XCharts-Team/XCharts.git",
If you need to update `XCharts`, delete the relevant content of `com.monitor1394.xcharts` under the `lock` of the `manifest.json` file (some Unity versions may be the packages-lock.json file), and it will re-download and compile.
### Recommended Import of XCharts Daemon
The daemon [XCharts-Daemon](https://github.com/XCharts-Team/XCharts-Daemon) ensures that the compilation is normal when updating. It is very useful when TextMeshPro or NewInputSystem is turned on locally. After importing XCharts-Daemon into the project, the daemon will automatically refresh XCharts' asmdef according to the local situation of TMP when updating XCharts, ensuring that the compilation is normal without manual intervention, which is convenient for automated processes such as CI/CD.
The import method of XCharts-Daemon can refer to the previous import method of XCharts. It can be imported into the project through source code or Package. The GitHub URL of XCharts-Daemon: https://github.com/XCharts-Team/XCharts-Daemon.git
## Basic Usage of XCharts
After importing XCharts and compiling, the XCharts menu will appear in the Unity editor's menu bar, and you can start using XCharts.
>Note: The XCharts menu in the Unity menu bar indicates that XCharts is available.
### Adding a Simple Chart
In the `Hierarchy` view, right-click `UI->XCharts->LineChart` or select `LineChart` from the menu bar `XCharts` to quickly create a default line chart:
![linechart1](img/tutorial01_linechart1.png)
## Add multiple Seire
If you need to create a chart under a certain node, you can select the node and right-click `UI->XCharts->LineChart` to create a chart under the node.
In the Inspector view, locate LineChart's panel, and with the `Add Serie` button, you can add a second Line line:
### Modifying Chart Data
For the newly created chart, its data can be modified on the Inspector panel.
For X-axis data, you can add, delete, and modify by expanding: `XAxis->Data`:
![op_axisdata](img/tutorial01_axisdata.png)
For Serie data, you can add, delete, and modify by expanding: `Serie->Data`:
![op_seriedata](img/tutorial01_seriedata.png)
Serie supports multi-dimensional data, and generally, a line chart only uses two-dimensional data: the first dimension represents the ID of the X-axis category data, and the second dimension represents the corresponding value.
### Adding Multiple Series
In the `Inspector` view, find the `LineChart` panel, and click the `Add Serie` button to add a second `Line` line:
![op_addserie](img/tutorial01_addserie.png)
![linechart2](img/tutorial01_linechart2.png)
## Add other components
>Note: Series are added through the `Add Serie` button. Different types of Series can be added. [What kinds of Series does XCharts have?](https://xcharts-team.github.io/docs/configuration#serie-系列)
The default chart does not have a `Legend`, and a `Legend` Component can be added via the `Add Component` button:
### Adding Other Main Components
By default, the chart does not have a `Legend`. If you need a `Legend` component, you can add it through the `Add Component` button:
![op_addcomponent](img/tutorial01_addcomponent.png)
## Add Serie components
>Note: Main components are added through the `Add Component` button. [What main components does XCharts have?](https://xcharts-team.github.io/docs/configuration/#maincomponent-主组件)
Serie comes with only a few common components, and others are added as needed. For example, if you need to fill a line chart area with color, you can add a separate `AreaStyle` component to Serie:
### Adding Serie Components
Serie only comes with a few common components, and other components need to be added when used. For example, if you need to fill the area color for the line chart, you can add an `AreaStyle` component to `Serie` separately:
![op_addseriecomponent](img/tutorial01_addseriecomponent.png)
![linechart3](img/tutorial01_linechart3.png)
## Add the SerieData component
>Note: Serie components are added through the button on the right side of Serie. [What components can be added to Serie in XCharts?](https://xcharts-team.github.io/docs/configuration/#iseriecomponent-可添加到serie的组件)
If you need to personalize the configuration of each data item, you can add a Component to each SerieData separately. For example, we give the second data of the line chart a separate display `Label`:
### Adding SerieData Components
If you need to customize the configuration of each data item individually, you can add components to each `SerieData` separately. For example, we can display `Label` for the second data of the line chart individually:
![op_addseriedatacomponent](img/tutorial01_addseriedatacomponent.png)
![linechart4](img/tutorial01_linechart4.png)
## More components and configuration parameters
>Note: SerieData components are added through the button on the right side of SerieData after expanding. [What components can be added to SerieData in XCharts?](https://xcharts-team.github.io/docs/configuration/#iseriedatacomponent-可添加到seriedata的组件)
XCharts has been iteratively optimized and now has dozens of main and sub-components, each with a few to dozens of configurable parameters to support a variety of flexible and complex functions.
### More Components and Configuration Parameters
Using XCharts for the first time, you can add various charts in the `Inspector` view, add or adjust the components in the chart, and the `Game` view gives real-time feedback on the effects of adjustments to familiarize yourself with the use of various components. Detailed parameter descriptions of each component can be found in the [XCharts Configuration](Configuration.md).
XCharts has been continuously iterated and optimized, and now has dozens of main components and sub-components, each with several to dozens of configurable parameters to support a variety of functions.
## How to adjust parameters quickly
When using XCharts for the first time, it is recommended to personally test the actual effects of each chart, each component. The `Inspector` view can directly add various charts, components, and adjust various configuration parameters, and the `Game` view will provide real-time feedback on the adjustments. A detailed description of each component's parameters can be found in the [XCharts Configuration Manual](configuration.md).
XCharts is configuration and data driven. Want what effect, only need to adjust the configuration parameters under the corresponding component can be, do not need to change the nodes under the `Hierarchy` view, because those nodes are generated by the `XCharts` internal according to the configuration and data, even if changed will be restored in the refresh.
### How to Quickly Adjust Parameters
How to quickly locate the component corresponding to the effect you want to change requires a certain understanding of the component. For example, if we want to show an arrow at the end of the X-axis, how do we position it? First, position the X-axis to `XAxis0`; Second, locate the axis to `AxisLine`; Finally, check to see if there are any parameters in the AxisLine component that can achieve this effect, and check [XCharts configuration](Configuration.md) for uncertain parameters.
XCharts is driven by data and parameters. To achieve the desired effect, simply adjust the configuration parameters under the corresponding component. Do not modify the nodes under the `Hierarchy` view, as those nodes are generated by XCharts internally based on configuration and data, and will be restored upon refresh.
`XCharts` provides a full range of parameter configuration from the global` Theme `, series` Serie `, and single data item `SerieData`. The priority in descending order is: `SerieData` -> `Serie` -> `Theme`. Take the color of `ItemStyle` for example:
To quickly locate the component corresponding to the effect you want to change, you need to have a certain understanding of the components. For example, we want to display an arrow at the end of the X-axis line. How to locate it? The first step, the X-axis is located at `XAxis0`; the second step, the axis line is located at `AxisLine`; finally, check if there is such a parameter under the `AxisLine` component to achieve this effect. If you are not sure about the parameters, you can refer to the [XCharts Configuration Manual](configuration.md).
1. If the `ItemStyle` of `SerieData` has a color value other than `0000`, this color value is preferred.
2. If the ItemStyle of `Serie` is configured with a color value other than `0000`, this color value takes precedence.
3. Otherwise, the Color value is taken from the Color Palette of the Theme.
`XCharts` provides comprehensive parameter configuration from the global `Theme`, series `Serie`, and individual data items `SerieData`. The priority order from high to low is: `SerieData`->`Serie`->`Theme`. Take the color of `ItemStyle` as
an example:
Usually, `0000` indicates the theme default color, and 0 or null indicates the theme default.
1. If the `ItemStyle` of `SerieData` has a color value other than `0000`, this color value is used first.
2. If the `ItemStyle` of `Serie` has a color value other than `0000`, this color value is used.
3. Otherwise, the color value is taken from the `Color Palette` of the theme `Theme`.
## Add line charts with code
>Note: The color value is usually `0000` when using the default color of the theme; other parameters are `0` or null when using the default configuration of the theme; pay attention to transparency when setting colors.
Attach the `LineChart` script to the gameObject:
### Adding a Line Chart with Code
Attach the `LineChart` script to `gameObject`:
```csharp
var chart = gameObject.GetComponent<LineChart>();
@@ -108,10 +148,10 @@ if (chart == null)
}
```
Resize:
Adjust the size:
```csharp
chart.SetSize(580, 300);//代码动态设置尺寸或直接操作chart.rectTransform或直接在Inspector上改
chart.SetSize(580, 300);//Dynamically set the size with code, or directly operate chart.rectTransform, or directly change it in the Inspector
```
Set the title:
@@ -121,7 +161,7 @@ var title = chart.EnsureChartComponent<Title>();
title.text = "Simple Line";
```
Set whether prompt boxes and legends are displayed:
Set whether to display the tooltip and legend:
```csharp
var tooltip = chart.EnsureChartComponent<Tooltip>();
@@ -131,7 +171,7 @@ var legend = chart.EnsureChartComponent<Legend>();
legend.show = false;
```
Set axes:
Set the coordinate axis:
```csharp
var xAxis = chart.EnsureChartComponent<XAxis>();
@@ -143,14 +183,22 @@ var yAxis = chart.EnsureChartComponent<YAxis>();
yAxis.type = Axis.AxisType.Value;
```
Clear default data and add `Line` type `Serie` for receiving data:
Clear all default data (including Series), add a `Line` type `Serie` to receive data:
```csharp
chart.RemoveData();
chart.AddSerie<Line>("line");
```
Add 10 data:
If the Serie is fixed, it is recommended to only clear the data, not to remove the Serie:
```csharp
chart.ClearData();
```
This way, you can set the configuration parameters of Serie in the UI in advance.
Add 10 data points:
```csharp
for (int i = 0; i < 10; i++)
@@ -160,59 +208,74 @@ for (int i = 0; i < 10; i++)
}
```
So a simple line chart comes out:
Now, a simple line chart is ready:
![tutorial01_linechart_simple](img/tutorial01_linechart_simple.png)
If there are multiple series in a Chart, the data of Axis only needs to be added once, rather than repeated in multiple cycles. Remember: the number of data in Axis should be the same as the number in Serie.
If there are multiple series in a Chart, the data of Axis only needs to be added once, and should not be repeated in multiple loops.
See `Examples`: `Example13_LineSimple.cs` for the complete code
>Remember: The number of Axis data should be consistent with the number of Serie data.
You can also use code to control more parameters, there are more Examples under `Examples`, all the configurable parameters seen in the `Inspector` can be set by code. All parameters in [XCharts configuration](Configuration.md) can be controlled by code.
For the complete code, please refer to `Examples`: `Example13_LineSimple.cs`
In addition, unless customized, it is recommended to call the `public` interface provided under `Chart`, especially in the data-related operations section. These interfaces do some associated processing inside, such as refreshing charts. Common interfaces are:
You can also control more parameters with code. There are more examples in `Examples`. All parameters that can be configured in the `Inspector` can be set with code. All parameters in the [XCharts Configuration Manual](configuration.md) can be controlled by code.
1. `Chart.ClearData()` : Clear chart data (without removing Series)
2. `Chart.RemoveData()` : Clear chart data (will remove all Serie)
3. `chart.AddSerie()` : AddSerie
4. `chart.AddXAxisData()` : Add X-axis data
5. `chart.AddData()` : Adds Serie data
6. `chart.UpdateData()` : Updates Serie data
7. `chart.UpdateXAxisData()` : Updates the X-axis data
8. `chart.UpdateDataName()` : Updates the Serie data name
### Setting the Default Font
XCharts has an automatic refresh mechanism inside, but it only triggers under certain conditions. If you call the interface of the internal component, encounter the component did not refresh, and indeed can not find the reason, you can use the following two interfaces to force refresh:
The default font used by XCharts is Unity's default font `Arial`, which may not display Chinese characters on the WebGL platform. When using XCharts in your project, it is recommended to set the font first:
1. `chart.RefreshAllComponent()` : refresh chart component, to initialize all of the components, often is not recommended.
2. `chart.RefreshChart()` : refreshes the chart drawing, only the drawing part is refreshed, and the component text, position, etc., is not refreshed.
3. Individual components can also refresh only themselves by `SetAllDirty()`.
- Find the `XCharts/Resources/XCSetting.asset` resource and modify the `Font` inside and save.
- Find the `XCharts/Resources/XCTheme-Default.asset` and `XCharts/Resources/XCTheme-Dark.asset` font configurations, and click the `Sync Font from Setting` and `Sync Font to Sub Theme` buttons to synchronize the font to the theme configuration files.
## Use TextMeshPro
After the font is set, newly created charts will use the newly set font. For old charts, you can click the `Rebuild Chart Object` button to refresh.
XCharts supports TextMeshPro, but it is disabled by default and needs to be switched manually. It can be turned on and off in the following ways:
>Note: It is recommended to set the font before using XCharts; when updating XCharts, pay attention to the potential restoration of the set font.
### Using TextMeshPro
XCharts supports TextMeshPro, but it is not enabled by default and needs to be switched on manually. It can be turned on and off in the following ways:
![textmeshpro1](img/tutorial01_textmeshpro.png)
After opening, you need to set the global font used by TextMeshPro, or you can set it separately in the Theme:
After turning it on, you need to set the global font to be used by TextMeshPro, and it can also be set individually in the Theme:
![textmeshpro-font](img/tutorial01_textmeshpro_font.png)
It is recommended to plan whether to use TextMeshPro at the beginning of the project and set the font. When switching TMP with many existing charts, some charts may not refresh automatically. You can manually click the `Rebuild Chart Object` button to rebuild the chart, which can be initialized normally.
It is recommended to plan whether to use TextMeshPro at the beginning of the project and set the font accordingly. When switching to TMP in a project with many charts, some charts may not refresh automatically, and you can manually click the `Rebuild Chart Object` button to rebuild the chart, which will initialize normally.
When updating XCharts for TMP projects, you may encounter problems with missing TMP references and failing to compile. These problems can be solved in one of two ways:
If you have enabled TMP in your project, you may encounter compilation failures due to lost TMP references when updating XCharts. This can be solved in the following two ways:
1. Find `XCharts.Runtime.asmdef` and `XCharts.Editor.asmdef` and manually add references to `TextMeshPro`
2. Remove the `dUI_TextMeshPro` macro for Scripting Define Symbols in PlayerSetting
1. Find `XCharts.Runtime.asmdef` and `XCharts.Editor.asmdef`, and manually add references to `TextMeshPro`.
2. Remove the `dUI_TextMeshPro` macro from the `Scripting Define Symbols` in `PlayerSetting`.
Version `3.8.0` after adding daemon[XCharts - Daemon](https://github.com/XCharts-Team/XCharts-Daemon), will be XCharts-Daemon import project, When updating XCharts, the daemon automatically refreshes the asmdef based on the locally enabled TMP to ensure proper compilation.
After the `3.8.0` version, the [XCharts-Daemon](https://github.com/XCharts-Team/XCharts-Daemon) daemon was added. After importing XCharts-Daemon into the project, the daemon will automatically refresh the asmdef based on the local situation of the enabled TMP when updating XCharts, ensuring normal compilation.
## Change chart parameters with code
## XCharts Code Control
All parameters seen on Inspector can be modified with code, the key is to identify whether the parameters you want to change are on the component, on the Serie, or on the specific data item SerieData.
All parameters seen in the `Inspector` can be modified with code. The key is to locate the parameter you want to change, whether it is on the component, the Serie, or the specific data item SerieData.
### Change the parameters on the main component
In addition, unless customized, it is recommended to call the `public` interfaces provided under `Chart`, especially for data-related and list operations. These interfaces will do some associated processing internally, such as refreshing the chart. Common interfaces include:
You need to obtain the component first, and then modify the parameters in it:
1. `chart.ClearData()`: Clear chart data (does not remove Series)
2. `chart.RemoveData()`: Clear chart data (will remove all Series)
3. `chart.AddSerie()`: Add Serie
4. `chart.AddXAxisData()`: Add X-axis data
5. `chart.AddData()`: Add Serie data
6. `chart.UpdateData()`: Update Serie data
7. `chart.UpdateXAxisData()`: Update X-axis data
8. `chart.UpdateDataName()`: Update the name of Serie data
XCharts has an automatic refresh mechanism, but it is also triggered under certain conditions. If you have called the internal component interfaces and encountered components that have not been refreshed, and you cannot find the reason, you can use the following two interfaces to force a refresh:
1. `chart.RefreshAllComponent()`: Refresh chart components, which will re-initialize all components. It is not recommended to use it frequently.
2. `chart.RefreshChart()`: Refresh chart rendering, which only refreshes the rendering part and will not refresh component text, position, etc.
3. Each component can also refresh itself by calling `SetAllDirty()`.
>Note: Use APIs to manipulate data and various lists, not directly access the list for processing.
### Changing Parameters on Main Components
You need to obtain the component first, then modify its parameters:
```csharp
var title = chart.EnsureChartComponent<Title>();
@@ -225,11 +288,11 @@ xAxis.boundaryGap = true;
xAxis.type = Axis.AxisType.Category;
```
> Note: When the earlier version does not have the EnsureChartComponent() interface, GetOrAddChartComponent() is used.
> Note: In older versions without the `EnsureChartComponent()` interface, use `GetOrAddChartComponent()`
### Change Serie parameters
### Changing Serie Parameters
For newly added Serie:
For newly added Series:
```csharp
var serie = chart.AddSerie<Pie>();
@@ -241,7 +304,7 @@ serie.animation.dataChangeEnable = true;
serie.roundCap = true;
```
For existing Serie:
For existing Series:
```csharp
var serie = chart.GetSerie<Pie>();
@@ -253,7 +316,7 @@ serie.animation.dataChangeEnable = true;
serie.roundCap = true;
```
Add additional components to Serie:
Adding additional components to Serie:
```csharp
serie.EnsureComponent<AreaStyle>();
@@ -262,14 +325,14 @@ var label = serie1.EnsureComponent<LabelStyle>();
label.offset = new Vector3(0,20,0);
```
### Change the parameter on the data item SerieData
### Changing Parameters on Data Item SerieData
```csharp
var serieData = chart.AddData(0, 20);
//var serieData = serie.GetSerieData(0); //从已有数据中获取
//var serieData = serie.GetSerieData(0); //To get from existing data
serieData.radius = 10;
var itemStyle = serieData.EnsureComponent<ItemStyle>(); //给数据项添加ItemStyle组件
var itemStyle = serieData.EnsureComponent<ItemStyle>(); //Add ItemStyle component to the data item
itemStyle.color = Color.blue;
```
```

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,9 @@ slug: /changelog
# 更新日志
[master](#master)
[v3.12.0](#v3120)
[v3.11.2](#v3112)
[v3.11.1](#v3111)
[v3.11.0](#v3110)
[v3.10.2](#v3102)
[v3.10.1](#v3101)
@@ -74,6 +77,47 @@ slug: /changelog
## master
## v3.12.0
版本要点:
* 增加`Ring``radiusGradient`参数设置渐变方向
* 增加`numericFormatter``date``time`的支持
* 完善`AreaStyle``origin`参数设置区域填充起始位置
* 调整和完善文档
* 其他优化和修复
日志详情:
* (2024.09.30) 发布`v3.12.0`版本
* (2024.09.27) 完善`5分钟教程`
* (2024.09.24) 完善`Legend``formatter`对多Serie的支持 (#332)
* (2024.09.22) 调整`Documentation`文档显示样式
* (2024.09.09) 增加`numericFormatter``date``time`的支持
* (2024.09.03) 完善`AreaStyle``origin`参数设置区域填充起始位置
* (2024.09.01) 增加`Ring``radiusGradient`参数设置渐变方向
* (2024.09.01) 优化`Axis`为时间轴时首个Label的位置
## v3.11.2
* (2024.08.01) 发布`v3.11.2`版本
* (2024.07.29) 修复`Tooltip`在微信小游戏平台上报错的兼容问题 (#326)
* (2024.07.27) 调整`Axis``AxisName`的默认位置
* (2024.07.22) 优化`Pie``Label``Tooltip`触发时的表现
* (2024.07.21) 修复`Tooltip`在开启`DataZoom`时指示内容不准确的问题
* (2024.07.17) 修复`MarkLine``Label`在初始化时可能会闪烁的问题
* (2024.07.16) 优化`Axis``Time`时间轴时的`Tooltip`默认效果
* (2024.07.15) 优化`Axis``Time`时间轴时的分割效果
* (2024.07.14) 优化`Axis``Time`时间轴时的移动表现
* (2024.07.12) 优化`Label`的初始化显示效果
* (2024.07.06) 修复`Chart`在动态创建时背景没有自适应的问题 (#323)
## v3.11.1
* (2024.07.01) 发布`v3.11.1`版本
* (2024.07.01) 修复`Serie`有多个时颜色异常的问题
* (2024.06.23) 修复`Label`在初始化时会堆积的问题
## v3.11.0
版本要点:

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -6,84 +6,122 @@ slug: /tutorial01
# 教程5分钟上手 XCharts 3.0
> 本教程适用XCharts 3.x版本2.x版本请看 [教程5分钟上手XCharts 2.0](https://github.com/XCharts-Team/XCharts/blob/2.0/Doc/教程5分钟上手XCharts.md)
> Note:本教程适用XCharts 3.x版本2.x版本请看 [教程5分钟上手XCharts 2.0](https://github.com/XCharts-Team/XCharts/blob/2.0/Doc/教程5分钟上手XCharts.md)
## 使用 XCharts 前需要掌握什么
## XCharts的前提条件
- 会简单使用Unity
- 了解UGUI会使用UGUI
- 了解Unity的MonoBehavior脚本用法知道怎么挂脚本用代码操作脚本
XCharts是一个Unity图表插件目前只能在Unity平台使用。
## 获取和导入 XCharts
使用XCharts前,你需要:
XCharts可通过以下任意一种方式导入到项目
- 掌握Unity的基本用法。
- 掌握UGUI制作UI的基本用法。
- 了解Unity的MonoBehavior脚本用法知道怎么挂脚本和用代码操作脚本。
- 直接将XCharts源码到项目
如果你刚接触Unity建议先学习Unity相关的基础教程再使用XCharts
下载好XCharts源码后直接将XCharts目录拷贝到Unity项目工程的Assets目录下。
## XCharts的获取和导入
- 通过`Assets/Import Package`导入XCharts
XCharts主要通过Github来维护更新和发布可以到【Github主页】(https://github.com/XCharts-Team)进行下载获取源码和Pacakge对于无Github访问条件的用户可以访问[【国内镜像】](https://gitee.com/monitor1394/unity-ugui-XCharts)进行下载。国内镜像的版本更新可能会相对滞后。
下载好XCharts的.unitypackage文件后打开Unity菜单栏 Assets-->Import Package-->选中.unitypackage导入即可开始使用XCharts。
XCharts可通过以下任意一种方式导入到你的项目:
- 通过`Package Manager`导入XCharts
### 直接将XCharts源码拷贝到项目
对于Unity 2018.3以上版本,可通过 Package Manager来导入XCharts打开Package Manager后通过 `Add package form git URL...`输入XCharts3.0的GitHub URL: `https://github.com/XCharts-Team/XCharts.git#3.0` 稍等片刻后即可使用XCharts
下载好XCharts源码后直接将XCharts目录拷贝到Unity项目工程的Assets目录下。编译通过后即可使用
也可以直接将package加入到`manifest.json`文件:打开`Packages`目录下的`manifest.json`文件,在`dependencies`下加入:
### 通过Import Package导入XCharts
``` json
"com.monitor1394.xcharts": "https://github.com/XCharts-Team/XCharts.git#3.0",
```
下载好XCharts的.unitypackage文件后打开Unity菜单栏 Assets-->Import Package-->选中下载好的.unitypackage进行导入。导入完成并通过编译后即可开始使用XCharts。
如需更新`XCharts`,删除`manifest.json`文件部分Unity版本可能是packages-lock.json文件的`lock`下的`com.monitor1394.xcharts`相关内容即会重新下载编译。
### 通过Package Manager导入XCharts
- 建议先导入XCharts的守护程序非必须
对于2018.3以上的Unity版本可通过Package Manager来导入XCharts打开Package Manager后通过 `Add package form git URL...`输入XCharts的GitHub URL: `https://github.com/XCharts-Team/XCharts.git` 编译通过后即可使用XCharts。
守护程序[XCharts-Daemon](https://github.com/XCharts-Team/XCharts-Daemon)可以确保更新时编译正常当本地开启TextMeshPro或NewInputSystem时将会非常有用。将XCharts-Daemon导入项目后在更新XCharts时守护程序会自动根据本地TMP等的开启情况刷新asmdef确保编译正常不用手动去解决方便CI-CD等自动化流程执行。
对于部分Unity版本也可以直接将package加入到`manifest.json`文件:打开`Packages`目录下的`manifest.json`文件,在`dependencies`下加入:
## 添加一个简单图表
>"com.monitor1394.xcharts": "https://github.com/XCharts-Team/XCharts.git",
在`Hierarchy`视图下右键`UI->XCharts->LineChart`或菜单栏`GameObject`下拉选择`XCharts->LineChart`,即可快速创建一个默认的折线图出来:
如需更新`XCharts`,删除`manifest.json`文件部分Unity版本可能是packages-lock.json文件`lock`下的`com.monitor1394.xcharts`相关内容即会重新下载编译。
### 建议导入XCharts的守护程序
守护程序[XCharts-Daemon](https://github.com/XCharts-Team/XCharts-Daemon)可以确保更新时编译正常当本地开启TextMeshPro或NewInputSystem时将会非常有用。将XCharts-Daemon导入项目后在更新XCharts时守护程序会自动根据本地TMP等的开启情况刷新XCharts的asmdef确保编译正常不用手动去解决方便CI/CD等自动化流程执行。
XCharts-Daemon的导入方式可参考刚才的XCharts导入方式。可以通过源码或Package的方式导入项目XCharts-Daemon的Github URLhttps://github.com/XCharts-Team/XCharts-Daemon.git
## XCharts的基本使用
导入XCharts并编译通过后Unity编辑器的菜单栏会显示XCharts这时可以开始使用XCharts了。
>NoteUnity的菜单栏出现XCharts菜单时才表示XCharts可用。
### 添加一个简单图表
`Hierarchy`视图下右键`UI->XCharts->LineChart`或菜单栏`XCharts`下拉选择`LineChart`,即可快速创建一个默认的折线图:
![linechart1](img/tutorial01_linechart1.png)
## 添加多个Seire
如需在某个节点下创建图表,可以选中节点右键`UI->XCharts->LineChart`即可在节点下创建图表。
### 修改图表数据
刚创建的图表它的数据可以在Inspector视图面板上进行修改。
对于X轴数据可通过`XAxis->Data`展开后进行增删和修改:
![op_axisdata](img/tutorial01_axisdata.png)
对于Serie数据可通过`Serie->Data`展开后进行增删和修改:
![op_seriedata](img/tutorial01_seriedata.png)
Serie支持多维数据一般折线图只用到二维数据第一维表示X轴类目数据的编号第二维表示对应的数值。
### 添加多个Seire
`Inspector`视图,找到`LineChart`的面板,通过`Add Serie`按钮,可以添加第二条`Line`折线:
![op_addserie](img/tutorial01_addserie.png)
![linechart2](img/tutorial01_linechart2.png)
## 添加其他组件
>NoteSerie通过`Add Serie`按钮添加。可添加不同类型的Serie。[XCharts有哪些Serie](https://xcharts-team.github.io/docs/configuration#serie-系列)
### 添加其他主组件
默认图表没有`Legend`,需要`Legend`组件可通过`Add Component`按钮添加:
![op_addcomponent](img/tutorial01_addcomponent.png)
## 添加Serie组件
>Note主组件通过`Add Component`按钮添加。[XCharts有哪些主组件](https://xcharts-team.github.io/docs/configuration/#maincomponent-主组件)
Serie只自带了几个常见的组件其他组件按需额外添加。比如需要给折线图区域填充颜色可单独给`Serie`添加`AreaStyle`组件
### 添加Serie组件
Serie只自带了几个常见的组件其他组件用到时需额外添加。比如需要给折线图进行区域填充颜色可单独给`Serie`添加`AreaStyle`组件:
![op_addseriecomponent](img/tutorial01_addseriecomponent.png)
![linechart3](img/tutorial01_linechart3.png)
## 添加SerieData组件
>NoteSerie组件通过Serie右边的按钮添加。[XCharts有哪些Serie组件](https://xcharts-team.github.io/docs/configuration/#iseriecomponent-可添加到serie的组件)
如果需要个性化定制每个数据项的配置,可以单独给每个`SerieData`添加`Component`。比如我们给折线图的第二个数据单独显示`Label`
### 添加SerieData组件
如果需要个性化定制每个数据项的配置,可以单独给每个`SerieData`添加组件。比如我们给折线图的第二个数据单独显示`Label`
![op_addseriedatacomponent](img/tutorial01_addseriedatacomponent.png)
![linechart4](img/tutorial01_linechart4.png)
## 更多组件和配置参数
>NoteSerieData组件通过展开SerieData后Component右边的按钮添加。[XCharts有哪些SerieData组件](https://xcharts-team.github.io/docs/configuration/#iseriedatacomponent-可添加到seriedata的组件)
XCharts经过不断的迭代优化目前已有多达几十种的主组件和子组件每个组件有几个至几十个不等的可配置参数以支持各种灵活而复杂的功能。
### 更多组件和配置参数
首次使用XCharts,可在 `Inspector` 视图添加各种图表,给图表添加或调整里面组件,`Game` 视图会实时反馈调整后的效果,以熟悉各种组件的使用。各个组件的详细参数说明可查阅[XCharts配置项手册](configuration.md)
XCharts经过不断的迭代优化,目前已有多达几十种的主组件和子组件,每个组件有几个到几十个的可配置参数,用来支持多样化的功能
## 如何快速调整参数
首次使用XCharts建议亲自去测试下各个图表各个组件的实际效果。`Inspector` 视图可以直接添加各种图表,各种组件以及调整各个配置参数,`Game` 视图会实时反馈调整后的效果。各个组件的详细参数说明可查阅[XCharts配置项手册](configuration.md)。
`XCharts`是配置和数据来驱动的。想要什么效果,只需要去调整对应组件下的配置参数就可以,不需要去改`Hierarchy`视图下的节点,因为那些节点是由`XCharts`内部根据配置和数据生成的,即使改了也会在刷新时还原回来。
### 如何快速调整参数
XCharts是数据和参数驱动的。想要什么效果只需要去调整对应组件下的配置参数就可以不能去改`Hierarchy`视图下的节点因为那些节点是由XCharts内部根据配置和数据生成的即使改了也会在刷新时被还原掉。
如何快速定位你想要改的效果所对应的组件这就需要对组件有一定的了解。比如我们想要让X轴的轴线末端显示箭头如何定位第一步X轴定位到`XAxis0`;第二步,轴线定位到`AxisLine`;最后,再去看`AxisLine`组件下有没有这样的参数可以实现这个效果,对于不太确定的参数可以查阅[XCharts配置项手册](configuration.md)。
@@ -93,9 +131,9 @@ XCharts经过不断的迭代优化目前已有多达几十种的主组件和
2. 如果`Serie``ItemStyle`配置有非`0000`颜色值,则优先用这个颜色值。
3. 否则颜色值取自主题`Theme``Color Palette`
通常颜色值为0000时表示用主题默认颜色,配置为0或null时表示用主题默认配置。
>Note通常颜色值为0000时表示用主题默认颜色;其他参数为0或null时表示用主题默认配置;设置颜色时注意透明度
## 用代码添加折线图
### 用代码添加折线图
`gameObject`挂上`LineChart`脚本:
@@ -143,13 +181,21 @@ var yAxis = chart.EnsureChartComponent<YAxis>();
yAxis.type = Axis.AxisType.Value;
```
清空默认数据,添加`Line`类型的`Serie`用于接收数据:
清空所有默认数据包含Serie,添加`Line`类型的`Serie`用于接收数据:
```csharp
chart.RemoveData();
chart.AddSerie<Line>("line");
```
如果Serie是固定的建议只是清空数据不用把Serie也清掉
```csharp
chart.ClearData();
```
这样可以提前在UI上设置好Serie的配置参数。
添加10个数据
```csharp
@@ -164,30 +210,26 @@ for (int i = 0; i < 10; i++)
![tutorial01_linechart_simple](img/tutorial01_linechart_simple.png)
如果一个Chart里面有多个系列时则Axis的data只需要加一次不要多个循环加重复了。记住Axis的数据个数要和Serie的数据个数一致。
如果一个Chart里面有多个系列时则Axis的data只需要加一次不要多个循环加重复了。
>记住Axis的数据个数要和Serie的数据个数一致。
完整代码请查阅`Examples``Example13_LineSimple.cs`
你还可以用代码控制更多的参数,`Examples`下还有更多的其他例子,凡是`Inspector`上看到的可配置的参数,都可以通过代码来设置。[XCharts配置项手册](configuration.md)里面的所有参数都是可以通过代码控制的。
另外,除非定制,建议调用`Chart`下提供的`public`接口,特别是数据相关操作部分。这些接口内部会做一些关联处理,比如刷新图表等。常见的接口有:
### 设置默认字体
1. `chart.ClearData()`清空图表数据不移除Series
2. `chart.RemoveData()`清除图表数据会移除所有Serie
3. `chart.AddSerie()`添加Serie
4. `chart.AddXAxisData()`添加X轴数据
5. `chart.AddData()`添加Serie数据
6. `chart.UpdateData()`更新Serie数据
7. `chart.UpdateXAxisData()`更新X轴数据
8. `chart.UpdateDataName()`更新Serie数据的名字
XCharts默认使用的是Unity默认字体`Arial`在WebGL平台上可能无法显示中文。在将XCharts用在你的项目时建议先设置好字体
XCharts内部有自动刷新机制但也是在一定条件才会触发。如果自己调用了内部组件的接口碰到组件没有刷新确实找不到原因的话可以用以下两个接口强制刷新
- 找到`XCharts/Resources/XCSetting.asset`资源,修改里面的`Font`并保存。
- 找到`XCharts/Resources/XCTheme-Default.asset``XCharts/Resources/XCTheme-Default.asset`两个字体配置,点击`Sync Font from Setting``Sync Font to Sub Theme`按钮将字体同步到主题配置文件上。
1. `chart.RefreshAllComponent()`:刷新图表组件,会重新初始化所有组件,不建议频繁待用
2. `chart.RefreshChart()`:刷新图表绘制,只刷新绘制部分,不会刷新组件文本,位置等部分。
3. 各个组件也可以通过`SetAllDirty()`只刷新自己。
字体设置好后,新创建的图表就会用新设置的字体了。对于旧图表,可以点击`Rebuild Chart Object`进行刷新
## 使用TextMeshPro
>Note使用XCharts前建议先设置好字体更新XCharts时注意设置的字体可能被还原的问题。
### 使用TextMeshPro
XCharts支持TextMeshPro但默认是不开启的需要自己手动切换。可通过以下方式开启和关闭
@@ -206,10 +248,29 @@ XCharts支持TextMeshPro但默认是不开启的需要自己手动切换
`3.8.0`版本后增加[XCharts-Daemon](https://github.com/XCharts-Team/XCharts-Daemon)守护程序将XCharts-Daemon导入项目后在更新XCharts时守护程序会自动根据本地开启的TMP情况刷新asmdef确保编译正常。
## 用代码改图表参数
## XCharts的代码控制
`Inspector`上看到的所有参数都可以用代码来修改关键是要定位好你要改的参数是在组件上、还是Serie上、还是在具体的数据项SerieData上。
另外,除非定制,建议调用`Chart`下提供的`public`接口,特别是数据相关和列表的操作。这些接口内部会做一些关联处理,比如刷新图表等。常见的接口有:
1. `chart.ClearData()`清空图表数据不移除Series
2. `chart.RemoveData()`清除图表数据会移除所有Serie
3. `chart.AddSerie()`添加Serie
4. `chart.AddXAxisData()`添加X轴数据
5. `chart.AddData()`添加Serie数据
6. `chart.UpdateData()`更新Serie数据
7. `chart.UpdateXAxisData()`更新X轴数据
8. `chart.UpdateDataName()`更新Serie数据的名字
XCharts内部有自动刷新机制但也是在一定条件才会触发。如果自己调用了内部组件的接口碰到组件没有刷新确实找不到原因的话可以用以下两个接口强制刷新
1. `chart.RefreshAllComponent()`:刷新图表组件,会重新初始化所有组件,不建议频繁待用。
2. `chart.RefreshChart()`:刷新图表绘制,只刷新绘制部分,不会刷新组件文本,位置等部分。
3. 各个组件也可以通过`SetAllDirty()`只刷新自己。
>Note用API去操作数据和各种list而不是直接访问list进行处理
### 改主组件上的参数
需要先获取组件,再修改里面的参数:

View File

@@ -16,6 +16,7 @@ namespace XCharts.Editor
PropertyField("m_RoundCap");
PropertyField("m_Clockwise");
PropertyField("m_AvoidLabelOverlap");
PropertyField("m_RadiusGradient");
PropertyField("m_ItemStyle");
PropertyField("m_Animation");

View File

@@ -139,7 +139,7 @@ namespace XCharts
}
}
internal void UpdateAxisMinMaxValue(int axisIndex, Axis axis, bool updateChart = true)
internal void UpdateAxisMinMaxValue(int axisIndex, Axis axis, bool cancelAnimation = false)
{
if (!axis.show)
return;
@@ -173,7 +173,7 @@ namespace XCharts
{
m_LastSplitNumber = axis.splitNumber;
m_LastInterval = axis.interval;
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, axis.context.needAnimation);
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, !cancelAnimation && axis.context.needAnimation);
axis.context.offset = 0;
axis.context.lastCheckInverse = axis.inverse;
UpdateAxisTickValueList(axis);
@@ -191,14 +191,11 @@ namespace XCharts
}
}
if (updateChart)
{
UpdateAxisLabelText(axis);
chart.RefreshChart();
}
UpdateAxisLabelText(axis);
chart.RefreshChart();
}
if (axis.context.needAnimation && (axis.context.minValue != axis.context.destMinValue || axis.context.maxValue != axis.context.destMaxValue))
if (!cancelAnimation && axis.context.needAnimation && (axis.context.minValue != axis.context.destMinValue || axis.context.maxValue != axis.context.destMaxValue))
{
var duration = axis.animation.duration == 0
? SeriesHelper.GetMinAnimationDuration(chart.series) / 1000f
@@ -455,7 +452,7 @@ namespace XCharts
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetActive(axis.axisName.labelStyle.show, true);
label.SetPosition(axis.context.start + offset);
break;
@@ -463,7 +460,7 @@ namespace XCharts
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetActive(axis.axisName.labelStyle.show, true);
label.SetPosition((axis.context.start + axis.context.end) / 2 + offset);
break;
@@ -471,11 +468,12 @@ namespace XCharts
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetActive(axis.axisName.labelStyle.show, true);
label.SetPosition(axis.context.end + offset);
break;
}
}
UpdateAxisMinMaxValue(axis.index, axis, true);
}
protected void InitAxis(Axis relativedAxis, Orient orient,
@@ -574,7 +572,7 @@ namespace XCharts
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleRight);
label.SetActive(axis.axisName.labelStyle.show);
label.SetActive(axis.axisName.labelStyle.show, true);
label.SetPosition(axis.position == Axis.AxisPosition.Top ?
new Vector2(zeroPos.x - offset.x, axisStartY + relativedLength + offset.y + axis.offset) :
new Vector2(zeroPos.x - offset.x, posY + offset.y));
@@ -584,7 +582,7 @@ namespace XCharts
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetActive(axis.axisName.labelStyle.show, true);
label.SetPosition(axis.position == Axis.AxisPosition.Top ?
new Vector2(axisStartX + axisLength / 2 + offset.x, axisStartY + relativedLength - offset.y + axis.offset) :
new Vector2(axisStartX + axisLength / 2 + offset.x, posY + offset.y));
@@ -594,7 +592,7 @@ namespace XCharts
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleLeft);
label.SetActive(axis.axisName.labelStyle.show);
label.SetActive(axis.axisName.labelStyle.show, true);
label.SetPosition(axis.position == Axis.AxisPosition.Top ?
new Vector2(axisStartX + axisLength + offset.x, axisStartY + relativedLength + offset.y + axis.offset) :
new Vector2(axisStartX + axisLength + offset.x, posY + offset.y));
@@ -611,7 +609,7 @@ namespace XCharts
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetActive(axis.axisName.labelStyle.show, true);
label.SetPosition(axis.position == Axis.AxisPosition.Right ?
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY - offset.y) :
new Vector2(posX + offset.x, axisStartY - offset.y));
@@ -621,7 +619,7 @@ namespace XCharts
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetActive(axis.axisName.labelStyle.show, true);
label.SetPosition(axis.position == Axis.AxisPosition.Right ?
new Vector2(axisStartX + relativedLength - offset.x + axis.offset, axisStartY + axisLength / 2 + offset.y) :
new Vector2(posX + offset.x, axisStartY + axisLength / 2 + offset.y));
@@ -631,7 +629,7 @@ namespace XCharts
//LabelStyle.Position
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetActive(axis.axisName.labelStyle.show, true);
label.SetPosition(axis.position == Axis.AxisPosition.Right ?
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY + axisLength + offset.y) :
new Vector2(posX + offset.x, axisStartY + axisLength + offset.y));
@@ -639,6 +637,7 @@ namespace XCharts
}
}
}
UpdateAxisMinMaxValue(axis.index, axis, true);
}
internal static Vector3 GetLabelPosition(int i, Orient orient, Axis axis, Axis relativedAxis, AxisTheme theme,
@@ -720,12 +719,6 @@ namespace XCharts
if (AxisHelper.NeedShowSplit(axis))
{
var size = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
if (axis.IsTime())
{
size += 1;
if (!ChartHelper.IsEquals(axis.GetLastLabelValue(), axis.context.maxValue))
size += 1;
}
var tickWidth = axis.axisTick.GetWidth(theme.tickWidth);
var tickColor = axis.axisTick.GetColor(theme.tickColor);
var current = orient == Orient.Horizonal ? startX : startY;

View File

@@ -124,7 +124,7 @@ namespace XCharts.Runtime
label.text.SetAlignment(textStyle.GetAlignment(TextAnchor.MiddleCenter));
label.SetText(labelName);
label.SetPosition(GetLabelPosition(polar, axis, angleAxis.context.startAngle, totalWidth));
label.SetActive(true);
label.SetActive(true, true);
label.SetTextActive(true);
axis.context.labelObjectList.Add(label);

View File

@@ -28,6 +28,7 @@ namespace XCharts.Runtime
splitLine.show = false;
splitLine.lineStyle.type = LineStyle.Type.None;
axisLabel.textLimit.enable = true;
axisName.labelStyle.offset = new Vector3(5, 0, 0);
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
@@ -25,6 +26,7 @@ namespace XCharts.Runtime
splitLine.lineStyle.type = LineStyle.Type.None;
axisLabel.textLimit.enable = false;
axisTick.showStartTick = true;
axisName.labelStyle.offset = new Vector3(0, 22, 0);
}
}
}

View File

@@ -50,7 +50,7 @@ namespace XCharts.Runtime
var borderColor = component.borderStyle.GetRuntimeBorderColor();
var cornerRadius = component.borderStyle.GetRuntimeCornerRadius();
UGL.DrawRoundRectangleWithBorder(vh, chart.chartRect, backgroundColor, backgroundColor, cornerRadius,
borderWidth, borderColor);
borderWidth, borderColor, 0, 1f);
}
}
}

View File

@@ -209,10 +209,29 @@ namespace XCharts.Runtime
set { if (PropertyUtil.SetClass(ref m_ItemMarker, value)) SetVerticesDirty(); }
}
/// <summary>
/// Standard numeric format strings.
/// ||标准数字格式字符串。用于将数值格式化显示为字符串。
/// 使用Axx的形式A是格式说明符的单字符支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明从0-99。
/// 参考https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings
/// Standard number and date format string. Used to format a Double value or a DateTime date as a string.
/// numericFormatter is used as an argument to either `Double.ToString ()` or `DateTime.ToString()`. <br />
/// The number format uses the Axx format: A is a single-character format specifier that supports C currency,
/// D decimal, E exponent, F fixed-point number, G regular, N digit, P percentage, R round trip, and X hexadecimal.
/// xx is precision specification, from 0-99. E.g. F1, E2<br />
/// Date format: Starts with `date`, which is used to format DateTime. Common date formats are:
/// yyyy year, MM month, dd day, HH hour, mm minute, ss second, fff millisecond. For example: date:yyyy-MM-dd HH:mm:ss<br />
/// Time format: Starts with `time`, which is used to format TimeSpan. Common time formats are:
/// d day, HH hour, mm minute, ss second, fffffff fractional part.
/// Only the version of Unity2018 or later can support formatting, and the characters inside should be escaped.
/// For example: time:HH\:mm\:ss<br />
/// number format reference: https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings<br/>
/// date format reference: https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings<br/>
/// Note: The date and time formats are only supported by 'v3.12.0' or later.<br/>
/// ||标准数字和日期格式字符串。用于将Double数值或DateTime日期格式化显示为字符串。numericFormatter用来作为Double.ToString()或DateTime.ToString()的参数。<br/>
/// 数字格式使用Axx的形式A是格式说明符的单字符支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明从0-99。如F1, E2<br/>
/// 日期格式:以`date`开头用来格式化DateTime常见格式有yyyy年MM月dd日HH时mm分ss秒fff毫秒。如date:yyyy-MM-dd HH:mm:ss<br/>
/// 时间格式:以`time`开头用来格式化TimeSpan常见格式有d日HH时mm分ss秒fffffff小数部分。
/// 需要Unity2018以上版本才支持格式化并且里面的字符要转义。如time:d\.HH\:mm\:ss<br/>
/// 数值格式化参考https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings <br/>
/// 日期格式化参考https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/standard-date-and-time-format-strings <br/>
/// 时间格式化参考https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/standard-timespan-format-strings <br/>
/// 注意date和time格式需要`v3.12.0`以上版本才支持。
/// </summary>
public string numericFormatter
{

View File

@@ -34,7 +34,7 @@ namespace XCharts.Runtime
var labelPos = chart.chartPosition + item.location.GetPosition(chart.chartWidth, chart.chartHeight);
var label = ChartHelper.AddChartLabel(s_CommentObjectName + i, commentObj.transform, labelStyle, chart.theme.common,
GetContent(item), Color.clear, TextAnchor.MiddleCenter);
label.SetActive(comment.show && item.show);
label.SetActive(comment.show && item.show, true);
label.SetPosition(labelPos);
label.text.SetLocalPosition(labelStyle.offset);
}

View File

@@ -184,16 +184,29 @@ namespace XCharts.Runtime
set { if (PropertyUtil.SetClass(ref m_Formatter, value)) SetComponentDirty(); }
}
/// <summary>
/// Standard number and date format string. Used to format a Double value or a DateTime date as a string. numericFormatter is used as an argument to either `Double.ToString ()` or `DateTime.ToString()`. <br />
/// The number format uses the Axx format: A is a single-character format specifier that supports C currency, D decimal, E exponent, F fixed-point number, G regular, N digit, P percentage, R round trip, and X hexadecimal. xx is precision specification, from 0-99. E.g. F1, E2<br />
/// Date format Common date formats are: yyyy year, MM month, dd day, HH hour, mm minute, ss second, fff millisecond. For example: yyyy-MM-dd HH:mm:ss<br />
/// Standard number and date format string. Used to format a Double value or a DateTime date as a string.
/// numericFormatter is used as an argument to either `Double.ToString ()` or `DateTime.ToString()`. <br />
/// The number format uses the Axx format: A is a single-character format specifier that supports C currency,
/// D decimal, E exponent, F fixed-point number, G regular, N digit, P percentage, R round trip, and X hexadecimal.
/// xx is precision specification, from 0-99. E.g. F1, E2<br />
/// Date format: Starts with `date`, which is used to format DateTime. Common date formats are:
/// yyyy year, MM month, dd day, HH hour, mm minute, ss second, fff millisecond. For example: date:yyyy-MM-dd HH:mm:ss<br />
/// Time format: Starts with `time`, which is used to format TimeSpan. Common time formats are:
/// d day, HH hour, mm minute, ss second, fffffff fractional part.
/// Only the version of Unity2018 or later can support formatting, and the characters inside should be escaped.
/// For example: time:HH\:mm\:ss<br />
/// number format reference: https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings<br/>
/// date format reference: https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings<br/>
/// Note: The date and time formats are only supported by 'v3.12.0' or later.<br/>
/// ||标准数字和日期格式字符串。用于将Double数值或DateTime日期格式化显示为字符串。numericFormatter用来作为Double.ToString()或DateTime.ToString()的参数。<br/>
/// 数字格式使用Axx的形式A是格式说明符的单字符支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明从0-99。如F1, E2<br/>
/// 日期格式常见格式yyyy年MM月dd日HH时mm分ss秒fff毫秒。如yyyy-MM-dd HH:mm:ss<br/>
/// 日期格式:以`date`开头用来格式化DateTime常见格式yyyy年MM月dd日HH时mm分ss秒fff毫秒。如date:yyyy-MM-dd HH:mm:ss<br/>
/// 时间格式:以`time`开头用来格式化TimeSpan常见格式有d日HH时mm分ss秒fffffff小数部分。
/// 需要Unity2018以上版本才支持格式化并且里面的字符要转义。如time:d\.HH\:mm\:ss<br/>
/// 数值格式化参考https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings <br/>
/// 日期格式化参考https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/standard-date-and-time-format-strings
/// 日期格式化参考https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/standard-date-and-time-format-strings <br/>
/// 时间格式化参考https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/standard-timespan-format-strings <br/>
/// 注意date和time格式需要`v3.12.0`以上版本才支持。
/// </summary>
public string numericFormatter
{
@@ -405,7 +418,7 @@ namespace XCharts.Runtime
public virtual string GetFormatterContent(int labelIndex, double value, double minValue, double maxValue, bool isLog = false)
{
var newNumericFormatter = numericFormatter;
if (value == 0)
if (value == 0 && !DateTimeUtil.IsDateOrTimeRegex(newNumericFormatter))
{
newNumericFormatter = "f0";
}
@@ -444,6 +457,8 @@ namespace XCharts.Runtime
}
}
private static bool isDateFormatter = false;
private static string newFormatter = null;
public string GetFormatterDateTime(int labelIndex, double value, double minValue, double maxValue)
{
var timestamp = (int)value;
@@ -457,7 +472,17 @@ namespace XCharts.Runtime
{
try
{
dateString = dateTime.ToString(numericFormatter);
if(DateTimeUtil.IsDateOrTimeRegex(numericFormatter, ref isDateFormatter, ref newFormatter))
{
if(isDateFormatter)
dateString = ChartCached.NumberToDateStr(timestamp, newFormatter);
else
dateString = ChartCached.NumberToTimeStr(timestamp, newFormatter);
}
else
{
dateString = dateTime.ToString(numericFormatter);
}
}
catch
{

View File

@@ -87,11 +87,14 @@ namespace XCharts.Runtime
ChartHelper.HideAllObject(legendObject);
if (!legend.show) return;
var textLimitInitFlag = false;
var isAnySerieColorByData = SeriesHelper.IsAnyColorByDataSerie(chart.series);
for (int i = 0; i < datas.Count; i++)
{
if (!SeriesHelper.IsLegalLegendName(datas[i])) continue;
string legendName = datas[i];
var legendContent = GetFormatterContent(legend, i, datas[i]);
var serieIndex = isAnySerieColorByData ? 0 : i;
var dataIndex = isAnySerieColorByData ? i : 0;
var legendContent = GetFormatterContent(legend, dataIndex, datas[i], serieIndex);
if (legend.textLimit.enable)
legendContent = legend.textLimit.GetLimitContent(legendContent);
var readIndex = chart.m_LegendRealShowName.IndexOf(datas[i]);
@@ -158,7 +161,7 @@ namespace XCharts.Runtime
legend.refreshComponent();
}
private string GetFormatterContent(Legend legend, int dataIndex, string category)
private string GetFormatterContent(Legend legend, int dataIndex, string category, int serieIndex)
{
#pragma warning disable 0618
if (string.IsNullOrEmpty(legend.formatter) && string.IsNullOrEmpty(legend.labelStyle.formatter))
@@ -168,7 +171,7 @@ namespace XCharts.Runtime
var formatter = string.IsNullOrEmpty(legend.labelStyle.formatter) ? legend.formatter : legend.labelStyle.formatter;
var content = formatter.Replace("{name}", category);
content = content.Replace("{value}", category);
var serie = chart.GetSerie(0);
var serie = chart.GetSerie(serieIndex);
FormatterHelper.ReplaceContent(ref content, dataIndex, legend.labelStyle.numericFormatter, serie, chart, category);
return content;
}

View File

@@ -58,7 +58,7 @@ namespace XCharts.Runtime
var label = ChartHelper.AddChartLabel("content", btnObj.transform, legend.labelStyle, theme.legend,
content, contentColor, TextAnchor.MiddleLeft);
label.SetActive(true);
label.SetActive(true, true);
var item = new LegendItem();
item.index = i;

View File

@@ -45,7 +45,7 @@ namespace XCharts.Runtime
var label = ChartHelper.AddChartLabel("label", m_MarkLineLabelRoot.transform, markArea.label, chart.theme.axis,
component.text, Color.clear, TextAnchor.MiddleCenter);
UpdateRuntimeData(component);
label.SetActive(markArea.label.show);
label.SetActive(markArea.label.show, true);
label.SetPosition(component.runtimeLabelPosition);
label.SetText(component.text);
markArea.runtimeLabel = label;

View File

@@ -86,7 +86,7 @@ namespace XCharts.Runtime
content, Color.clear, TextAnchor.MiddleCenter);
var pos = MarkLineHelper.GetLabelPosition(data);
label.SetIconActive(false);
label.SetActive(data.label.show && data.runtimeInGrid);
label.SetActive(false, true);
label.SetPosition(pos);
data.runtimeLabel = label;
};

View File

@@ -53,7 +53,7 @@ namespace XCharts.Runtime
var label = ChartHelper.AddChartLabel(objName, radarObject.transform, radar.axisName.labelStyle,
chart.theme.common, radar.GetFormatterIndicatorContent(i), Color.clear, TextAnchor.MiddleCenter);
label.SetActive(radar.axisName.show && radar.indicator && radar.axisName.labelStyle.show);
label.SetActive(radar.axisName.show && radar.indicator && radar.axisName.labelStyle.show, true);
AxisHelper.AdjustCircleLabelPos(label, pos, radar.context.center, txtHig, radar.axisName.labelStyle.offset);
}
chart.RefreshBasePainter();

View File

@@ -293,16 +293,29 @@ namespace XCharts.Runtime
/// </summary>
public string itemFormatter { get { return m_ItemFormatter; } set { m_ItemFormatter = value; } }
/// <summary>
/// Standard number and date format string. Used to format a Double value or a DateTime date as a string. numericFormatter is used as an argument to either `Double.ToString ()` or `DateTime.ToString()`. <br />
/// The number format uses the Axx format: A is a single-character format specifier that supports C currency, D decimal, E exponent, F fixed-point number, G regular, N digit, P percentage, R round trip, and X hexadecimal. xx is precision specification, from 0-99. E.g. F1, E2<br />
/// Date format Common date formats are: yyyy year, MM month, dd day, HH hour, mm minute, ss second, fff millisecond. For example: yyyy-MM-dd HH:mm:ss<br />
/// Standard number and date format string. Used to format a Double value or a DateTime date as a string.
/// numericFormatter is used as an argument to either `Double.ToString ()` or `DateTime.ToString()`. <br />
/// The number format uses the Axx format: A is a single-character format specifier that supports C currency,
/// D decimal, E exponent, F fixed-point number, G regular, N digit, P percentage, R round trip, and X hexadecimal.
/// xx is precision specification, from 0-99. E.g. F1, E2<br />
/// Date format: Starts with `date`, which is used to format DateTime. Common date formats are:
/// yyyy year, MM month, dd day, HH hour, mm minute, ss second, fff millisecond. For example: date:yyyy-MM-dd HH:mm:ss<br />
/// Time format: Starts with `time`, which is used to format TimeSpan. Common time formats are:
/// d day, HH hour, mm minute, ss second, fffffff fractional part.
/// Only the version of Unity2018 or later can support formatting, and the characters inside should be escaped.
/// For example: time:HH\:mm\:ss<br />
/// number format reference: https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings<br/>
/// date format reference: https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings<br/>
/// Note: The date and time formats are only supported by 'v3.12.0' or later.<br/>
/// ||标准数字和日期格式字符串。用于将Double数值或DateTime日期格式化显示为字符串。numericFormatter用来作为Double.ToString()或DateTime.ToString()的参数。<br/>
/// 数字格式使用Axx的形式A是格式说明符的单字符支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明从0-99。如F1, E2<br/>
/// 日期格式常见格式yyyy年MM月dd日HH时mm分ss秒fff毫秒。如yyyy-MM-dd HH:mm:ss<br/>
/// 日期格式:以`date`开头用来格式化DateTime常见格式yyyy年MM月dd日HH时mm分ss秒fff毫秒。如date:yyyy-MM-dd HH:mm:ss<br/>
/// 时间格式:以`time`开头用来格式化TimeSpan常见格式有d日HH时mm分ss秒fffffff小数部分。
/// 需要Unity2018以上版本才支持格式化并且里面的字符要转义。如time:d\.HH\:mm\:ss<br/>
/// 数值格式化参考https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings <br/>
/// 日期格式化参考https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/standard-date-and-time-format-strings
/// 日期格式化参考https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/standard-date-and-time-format-strings <br/>
/// 时间格式化参考https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/standard-timespan-format-strings <br/>
/// 注意date和time格式需要`v3.12.0`以上版本才支持。
/// </summary>
public string numericFormatter
{

View File

@@ -255,7 +255,7 @@ namespace XCharts.Runtime
{
if (label == null) return;
if (double.IsNaN(axis.context.pointerValue)) return;
label.SetActive(true);
label.SetActive(true, true);
label.SetTextActive(true);
label.SetPosition(axis.context.pointerLabelPosition + axis.indicatorLabel.offset);
@@ -359,7 +359,7 @@ namespace XCharts.Runtime
serie.context.pointerEnter = true;
serie.context.pointerAxisDataIndexs.Add(index);
serie.context.pointerItemDataIndex = index;
yAxis.context.axisTooltipValue = yAxis.context.pointerValue;
yAxis.context.axisTooltipValue = index;
}
}
else if (yAxis.IsTime())
@@ -571,11 +571,13 @@ namespace XCharts.Runtime
var isTriggerByAxis = false;
var isTriggerByItem = tooltip.context.trigger == Tooltip.Trigger.Item;
var dataIndex = -1;
var timestamp = -1;
double axisRange = 0;
tooltip.context.data.param.Clear();
tooltip.context.pointer = GetTooltipPointerPos();
if (m_PointerContainer is GridCoord)
{
GetAxisCategory(m_PointerContainer.index, ref dataIndex, ref category);
GetAxisCategory(m_PointerContainer.index, ref dataIndex, ref category, ref timestamp, ref axisRange);
if (tooltip.context.trigger == Tooltip.Trigger.Axis)
{
isTriggerByAxis = true;
@@ -585,7 +587,9 @@ namespace XCharts.Runtime
tooltip.context.data.title = series[0].serieName;
}
else
{
tooltip.context.data.title = category;
}
}
else if (tooltip.context.trigger == Tooltip.Trigger.Item)
{
@@ -604,6 +608,15 @@ namespace XCharts.Runtime
serie.context.isTriggerByAxis = isTriggerByAxis;
if (isTriggerByAxis && dataIndex >= 0 && serie.context.pointerItemDataIndex < 0)
serie.context.pointerItemDataIndex = dataIndex;
if (timestamp >= 0)
{
showCategory = false;
var serieData = serie.GetSerieData(serie.context.pointerItemDataIndex);
if (serieData != null)
{
tooltip.context.data.title = DateTimeUtil.GetDefaultDateTimeString((int)serieData.GetData(0), axisRange);
}
}
serie.handler.UpdateTooltipSerieParams(dataIndex, showCategory, category,
tooltip.marker, tooltip.itemFormatter, tooltip.numericFormatter,
tooltip.ignoreDataDefaultContent,
@@ -626,20 +639,28 @@ namespace XCharts.Runtime
return false;
}
private bool GetAxisCategory(int gridIndex, ref int dataIndex, ref string category)
private bool GetAxisCategory(int gridIndex, ref int dataIndex, ref string category, ref int timestamp, ref double axisRange)
{
foreach (var component in chart.components)
{
if (component is Axis)
{
var axis = component as Axis;
if (axis.gridIndex == gridIndex && axis.IsCategory())
if (axis.gridIndex == gridIndex)
{
dataIndex = double.IsNaN(axis.context.pointerValue)
? axis.context.dataZoomStartIndex
: axis.context.dataZoomStartIndex + (int)axis.context.axisTooltipValue;
category = axis.GetData(dataIndex);
return true;
if (axis.IsCategory())
{
dataIndex = double.IsNaN(axis.context.pointerValue)
? axis.context.dataZoomStartIndex
: (int)axis.context.axisTooltipValue;
category = axis.GetData(dataIndex);
return true;
}
else if (axis.IsTime())
{
timestamp = (int)axis.context.pointerValue;
axisRange = axis.context.minMaxRange;
}
}
}
}

View File

@@ -175,6 +175,7 @@ namespace XCharts.Runtime
m_ChartWidth = m_GraphWidth;
m_ChartHeight = m_GraphHeight;
rectTransform.sizeDelta = new Vector2(m_ChartWidth, m_ChartHeight);
UpdateSize();
}
ChartHelper.HideAllObject(transform);
m_ChartInited = true;

View File

@@ -56,7 +56,7 @@ namespace XCharts.Runtime
protected override void Awake()
{
raycastTarget = false;
SetActive(true);
m_Active = ChartHelper.IsActiveByScale(gameObject);
}
public void SetTextPadding(TextPadding padding)
@@ -200,10 +200,13 @@ namespace XCharts.Runtime
return m_Active;
}
public void SetActive(bool flag)
public void SetActive(bool flag, bool force = false)
{
m_Active = flag;
ChartHelper.SetActive(gameObject, flag);
if (m_Active == flag && !force) return;
if (ChartHelper.SetActive(gameObject, flag))
{
m_Active = flag;
}
}
public void SetTextActive(bool flag)
@@ -247,7 +250,7 @@ namespace XCharts.Runtime
AdjustIconPos();
if (m_HideIconIfTextEmpty && isIconActive)
{
ChartHelper.SetActive(m_IconImage.gameObject, !string.IsNullOrEmpty(text));
SetIconActive(!string.IsNullOrEmpty(text));
}
}
return false;

View File

@@ -67,7 +67,7 @@ namespace XCharts.Runtime
{
var label = ChartHelper.AddChartLabel(name, parent, labelStyle, theme.common,
"", color, TextAnchor.MiddleCenter);
label.SetActive(labelStyle.show);
label.SetActive(labelStyle.show, true);
return label.gameObject;
}
}

View File

@@ -12,7 +12,7 @@ namespace XCharts.Runtime
private const string NUMERIC_FORMATTER_X = "X";
private const string NUMERIC_FORMATTER_x = "x";
private static readonly string s_DefaultAxis = "axis_";
private static CultureInfo ci = new CultureInfo("en-us"); // "en-us", "zh-cn", "ar-iq", "de-de"
private static CultureInfo ci = GetDefaultCultureInfo(); // "en-us", "zh-cn", "ar-iq", "de-de"
private static Dictionary<Color, string> s_ColorToStr = new Dictionary<Color, string>(100);
private static Dictionary<int, string> s_SerieLabelName = new Dictionary<int, string>(1000);
private static Dictionary<Color, string> s_ColorDotStr = new Dictionary<Color, string>(100);
@@ -23,6 +23,20 @@ namespace XCharts.Runtime
private static Dictionary<double, Dictionary<string, string>> s_NumberToStr = new Dictionary<double, Dictionary<string, string>>();
private static Dictionary<int, Dictionary<string, string>> s_PrecisionToStr = new Dictionary<int, Dictionary<string, string>>();
private static Dictionary<string, Dictionary<int, string>> s_StringIntDict = new Dictionary<string, Dictionary<int, string>>();
private static Dictionary<double, DateTime> s_TimestampToDateTimeDict = new Dictionary<double, DateTime>();
private static Dictionary<double, TimeSpan> s_NumberToTimeSpanDict = new Dictionary<double, TimeSpan>();
private static CultureInfo GetDefaultCultureInfo()
{
try
{
return new CultureInfo("en-us");
}
catch (Exception)
{
return CultureInfo.InvariantCulture;
}
}
public static string FloatToStr(double value, string numericFormatter = "F", int precision = 0)
{
@@ -52,10 +66,19 @@ namespace XCharts.Runtime
}
if (!s_NumberToStr[value].ContainsKey(formatter))
{
bool isDateFormatter = false;
string newFormatter = null;
if (string.IsNullOrEmpty(formatter))
{
s_NumberToStr[value][formatter] = value.ToString();
}
else if (DateTimeUtil.IsDateOrTimeRegex(formatter,ref isDateFormatter, ref newFormatter))
{
if(isDateFormatter)
s_NumberToStr[value][formatter] = NumberToDateStr(value, newFormatter);
else
s_NumberToStr[value][formatter] = NumberToTimeStr(value, newFormatter);
}
else if (formatter.StartsWith(NUMERIC_FORMATTER_D) ||
formatter.StartsWith(NUMERIC_FORMATTER_d) ||
formatter.StartsWith(NUMERIC_FORMATTER_X) ||
@@ -77,6 +100,56 @@ namespace XCharts.Runtime
return NumberToStr(value, numericFormatter);
}
public static string NumberToDateStr(double timestamp, string formatter)
{
var dt = NumberToDateTime(timestamp);
try
{
return dt.ToString(formatter, ci);
}
catch (Exception)
{
XLog.LogError("Not support DateTime format: " + formatter);
return timestamp.ToString();
}
}
public static string NumberToTimeStr(double timestamp, string formatter)
{
try
{
var ts = NumberToTimeSpan(timestamp);
#if UNITY_2018_3_OR_NEWER
return ts.ToString(formatter, ci);
#else
return ts.ToString();
#endif
}
catch (Exception)
{
XLog.LogError("Not support TimeSpan format: " + formatter);
return timestamp.ToString();
}
}
public static DateTime NumberToDateTime(double timestamp)
{
if (!s_TimestampToDateTimeDict.ContainsKey(timestamp))
{
s_TimestampToDateTimeDict[timestamp] = DateTimeUtil.GetDateTime(timestamp);
}
return s_TimestampToDateTimeDict[timestamp];
}
public static TimeSpan NumberToTimeSpan(double timestamp)
{
if(!s_NumberToTimeSpanDict.ContainsKey(timestamp))
{
s_NumberToTimeSpanDict[timestamp] = TimeSpan.FromSeconds(timestamp);
}
return s_NumberToTimeSpanDict[timestamp];
}
public static string ColorToStr(Color color)
{
if (s_ColorToStr.ContainsKey(color))

View File

@@ -41,22 +41,39 @@ namespace XCharts.Runtime
return s_Builder.ToString();
}
public static void SetActive(GameObject gameObject, bool active)
public static bool IsActiveByScale(GameObject gameObject)
{
if (gameObject == null) return;
SetActive(gameObject.transform, active);
if (gameObject == null) return false;
return IsActiveByScale(gameObject.transform);
}
public static void SetActive(Image image, bool active)
public static bool IsActiveByScale(Image image)
{
if (image == null) return;
SetActive(image.gameObject, active);
if (image == null) return false;
return IsActiveByScale(image.gameObject);
}
public static void SetActive(Text text, bool active)
public static bool IsActiveByScale(Transform transform)
{
if (text == null) return;
SetActive(text.gameObject, active);
return transform.localScale != Vector3.zero;
}
public static bool SetActive(GameObject gameObject, bool active)
{
if (gameObject == null) return false;
return SetActive(gameObject.transform, active);
}
public static bool SetActive(Image image, bool active)
{
if (image == null) return false;
return SetActive(image.gameObject, active);
}
public static bool SetActive(Text text, bool active)
{
if (text == null) return false;
return SetActive(text.gameObject, active);
}
/// <summary>
@@ -64,12 +81,14 @@ namespace XCharts.Runtime
/// </summary>
/// <param name="transform"></param>
/// <param name="active"></param>
public static void SetActive(Transform transform, bool active)
public static bool SetActive(Transform transform, bool active)
{
if (transform == null) return;
if (transform == null) return false;
if (active) transform.localScale = Vector3.one;
else transform.localScale = Vector3.zero;
return true;
}
public static void HideAllObject(GameObject obj, string match = null)
{
if (obj == null) return;
@@ -460,7 +479,7 @@ namespace XCharts.Runtime
label.color = (!labelStyle.background.autoColor || autoColor == Color.clear) ?
labelStyle.background.color : autoColor;
label.sprite = labelStyle.background.sprite;
if(label.type != labelStyle.background.type)
if (label.type != labelStyle.background.type)
label.type = labelStyle.background.type;
}
else
@@ -536,7 +555,7 @@ namespace XCharts.Runtime
{
var label = ChartHelper.AddChartLabel(name, parent, labelStyle, theme.tooltip,
"", Color.clear, alignment);
label.SetActive(tooltip.show && labelStyle.show);
label.SetActive(tooltip.show && labelStyle.show, true);
return label;
}

View File

@@ -21,8 +21,8 @@ namespace XCharts.Runtime
[ExecuteInEditMode]
public static class XChartsMgr
{
public static readonly string version = "3.11.0";
public static readonly int versionDate = 20240616;
public static readonly string version = "3.12.0";
public static readonly int versionDate = 20240930;
public static string fullVersion { get { return version + "-" + versionDate; } }
internal static List<BaseChart> chartList = new List<BaseChart>();

View File

@@ -35,12 +35,27 @@ namespace XCharts.Runtime
return;
}
var gridXY = (isY ? grid.context.x : grid.context.y);
var min = gridXY;
var max = gridXY + (isY ? grid.context.width : grid.context.height);
var start = 0f;
switch(serie.areaStyle.origin)
{
case AreaStyle.AreaOrigin.Start:
start = min;
break;
case AreaStyle.AreaOrigin.End:
start = max;
break;
default:
start = gridXY + relativedAxis.context.offset;
break;
}
if (lastStackSerie == null)
{
DrawSerieLineNormalArea(vh, serie, isY,
gridXY + relativedAxis.context.offset,
gridXY,
gridXY + (isY ? grid.context.width : grid.context.height),
start,
min,
max,
areaColor,
areaToColor,
visualMap,
@@ -52,9 +67,9 @@ namespace XCharts.Runtime
else
{
DrawSerieLineStackArea(vh, serie, lastStackSerie, isY,
gridXY + relativedAxis.context.offset,
gridXY,
gridXY + (isY ? grid.context.width : grid.context.height),
start,
min,
max,
areaColor,
areaToColor,
visualMap,

View File

@@ -470,7 +470,7 @@ namespace XCharts.Runtime
var rad = Mathf.Deg2Rad * serieData.context.halfAngle;
var lineLength1 = ChartHelper.GetActualValue(labelLine.lineLength1, serie.context.outsideRadius);
var lineLength2 = ChartHelper.GetActualValue(labelLine.lineLength2, serie.context.outsideRadius);
var radius = lineLength1 + serie.context.outsideRadius - serieData.context.outsideRadius;
var radius = lineLength1;
var pos1 = startPosition;
var pos2 = pos1 + new Vector3(Mathf.Sin(rad) * radius, Mathf.Cos(rad) * radius);
var pos5 = labelLine.lineType == LabelLine.LineType.HorizontalLine

View File

@@ -9,7 +9,20 @@ namespace XCharts.Runtime
[SerieDataExtraField()]
public class Ring : Serie
{
[SerializeField][Since("v3.12.0")] private bool m_RadiusGradient = false;
/// <summary>
/// Whether to use gradient color in pie chart.
/// || 是否开启半径方向的渐变效果。
/// </summary>
public bool radiusGradient
{
get { return m_RadiusGradient; }
set { if (PropertyUtil.SetStruct(ref m_RadiusGradient, value)) { SetVerticesDirty(); } }
}
public override SerieColorBy defaultColorBy { get { return SerieColorBy.Data; } }
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
{
var serie = chart.AddSerie<Ring>(serieName);

View File

@@ -162,7 +162,7 @@ namespace XCharts.Runtime
DrawBackground(vh, serie, serieData, j, insideRadius, outsideRadius);
UGL.DrawDoughnut(vh, serie.context.center, insideRadius, outsideRadius, itemColor, itemToColor,
Color.clear, startDegree, toDegree, borderWidth, borderColor, 0, chart.settings.cicleSmoothness,
roundCap, serie.clockwise);
roundCap, serie.clockwise, serie.radiusGradient);
DrawCenter(vh, serie, serieData, insideRadius, j == data.Count - 1);
}

View File

@@ -155,6 +155,7 @@ namespace XCharts.Runtime
{
Color32 color1, toColor1;
bool needInteract = false;
serie.context.colorIndex = chart.GetLegendRealShowNameIndex(serie.legendName);
foreach (var serieData in serie.data)
{
var state = SerieHelper.GetSerieState(serie, serieData, true);
@@ -367,7 +368,7 @@ namespace XCharts.Runtime
var textName = string.Format("{0}_{1}_{2}_{3}", s_SerieLabelObjectName, serie.index, serieData.index, i);
var label = ChartHelper.AddChartLabel(textName, serieLabelRoot.transform, serieLabel, chart.theme.common,
"", dataAutoColor, TextAnchor.MiddleCenter);
label.SetActive(serieLabel.show);
label.SetActive(false, true);
serieData.context.dataLabels.Add(label);
}
}
@@ -376,7 +377,7 @@ namespace XCharts.Runtime
var textName = ChartCached.GetSerieLabelName(s_SerieLabelObjectName, serie.index, serieData.index);
var label = ChartHelper.AddChartLabel(textName, serieLabelRoot.transform, serieLabel, chart.theme.common,
"", dataAutoColor, TextAnchor.MiddleCenter);
label.SetActive(serieLabel.show);
label.SetActive(false, true);
serieData.labelObject = label;
}
@@ -440,7 +441,7 @@ namespace XCharts.Runtime
var label = ChartHelper.AddChartLabel("title_" + 0, serieTitleRoot.transform, titleStyle, chart.theme.common,
content, color, TextAnchor.MiddleCenter);
serie.context.titleObject = label;
label.SetActive(titleStyle.show);
label.SetActive(titleStyle.show, true);
var labelPosition = GetSerieDataTitlePosition(null, titleStyle);
var offset = titleStyle.GetOffset(serie.context.insideRadius);
label.SetPosition(labelPosition + offset);
@@ -467,7 +468,7 @@ namespace XCharts.Runtime
var label = ChartHelper.AddChartLabel("title_" + i, serieTitleRoot.transform, titleStyle, chart.theme.common,
content, color, TextAnchor.MiddleCenter);
serieData.titleObject = label;
label.SetActive(titleStyle.show);
label.SetActive(titleStyle.show, true);
var labelPosition = GetSerieDataTitlePosition(serieData, titleStyle);
var offset = titleStyle.GetOffset(serie.context.insideRadius);
label.SetPosition(labelPosition + offset);
@@ -484,6 +485,8 @@ namespace XCharts.Runtime
var dataAddDuration = serie.animation.GetAdditionDuration();
var unscaledTime = serie.animation.unscaledTime;
var needCheck = serie.context.dataIndexs.Count > 0;
var allLabelZeroPosition = true;
var anyLabelActive = false;
foreach (var serieData in serie.data)
{
if (serieData.labelObject == null && serieData.context.dataLabels.Count <= 0)
@@ -518,7 +521,16 @@ namespace XCharts.Runtime
SerieLabelHelper.GetFormatterContent(serie, serieData, value, total,
currLabel, color, chart);
var offset = GetSerieDataLabelOffset(serieData, currLabel);
labelObject.SetActive(currLabel.show && !isIgnore && !serie.IsMinShowLabelValue(value));
var active = currLabel.show && !isIgnore && !serie.IsMinShowLabelValue(value);
if (active)
{
anyLabelActive = true;
if (!ChartHelper.IsZeroVector(serieData.context.dataPoints[i]))
{
allLabelZeroPosition = false;
}
}
labelObject.SetActive(active);
labelObject.SetText(content);
labelObject.SetPosition(serieData.context.dataPoints[i] + offset);
labelObject.UpdateIcon(currLabel.icon);
@@ -539,10 +551,19 @@ namespace XCharts.Runtime
ChartCached.NumberToStr(value, currLabel.numericFormatter) :
SerieLabelHelper.GetFormatterContent(serie, serieData, value, total,
currLabel, color, chart);
serieData.SetLabelActive(currLabel.show && !isIgnore && !serie.IsMinShowLabelValue(value));
var labelPos = UpdateLabelPosition(serieData, currLabel);
var active = currLabel.show && !isIgnore && !serie.IsMinShowLabelValue(value);
if (active)
{
anyLabelActive = true;
if (!ChartHelper.IsZeroVector(labelPos))
{
allLabelZeroPosition = false;
}
}
serieData.SetLabelActive(active);
serieData.labelObject.UpdateIcon(currLabel.icon);
serieData.labelObject.SetText(content);
UpdateLabelPosition(serieData, currLabel);
if (currLabel.textStyle.autoColor)
{
var dataAutoColor = GetSerieDataAutoColor(serieData);
@@ -556,6 +577,13 @@ namespace XCharts.Runtime
serieData.SetLabelActive(false);
}
}
if (anyLabelActive && allLabelZeroPosition)
{
foreach (var serieData in serie.data)
{
serieData.SetLabelActive(false);
}
}
}
public virtual void RefreshEndLabelInternal()
@@ -579,7 +607,7 @@ namespace XCharts.Runtime
m_EndLabel.isAnimationEnd = serie.animation.IsFinish();
}
protected void UpdateLabelPosition(SerieData serieData, LabelStyle currLabel)
protected Vector3 UpdateLabelPosition(SerieData serieData, LabelStyle currLabel)
{
var labelPosition = GetSerieDataLabelPosition(serieData, currLabel);
var offset = GetSerieDataLabelOffset(serieData, currLabel);
@@ -591,6 +619,7 @@ namespace XCharts.Runtime
else
serieData.labelObject.SetRotate(-serieData.context.angle + currLabel.rotate);
}
return labelPosition;
}
public virtual Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label)

View File

@@ -132,6 +132,21 @@ namespace XCharts.Runtime
return false;
}
/// <summary>
/// check if series has any serie which is color by data.
/// || 是否有任何一个系列是按数据颜色的。
/// </summary>
/// <param name="series"></param>
/// <returns></returns>
public static bool IsAnyColorByDataSerie(List<Serie> series)
{
foreach (var serie in series)
{
if (serie.defaultColorBy == SerieColorBy.Data) return true;
}
return false;
}
/// <summary>
/// 获得上一个同堆叠且显示的serie。
/// </summary>

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
namespace XCharts.Runtime
@@ -7,10 +8,11 @@ namespace XCharts.Runtime
public static class DateTimeUtil
{
#if UNITY_2018_3_OR_NEWER
private static readonly DateTime k_DateTime1970 = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1), TimeZoneInfo.Local);
private static readonly DateTime k_LocalDateTime1970 = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1), TimeZoneInfo.Local);
#else
private static readonly DateTime k_DateTime1970 = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
private static readonly DateTime k_LocalDateTime1970 = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
#endif
private static readonly DateTime k_DateTime1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static readonly int ONE_SECOND = 1;
public static readonly int ONE_MINUTE = ONE_SECOND * 60;
public static readonly int ONE_HOUR = ONE_MINUTE * 60;
@@ -26,22 +28,54 @@ namespace XCharts.Runtime
//private static string s_MinuteDateFormatter = "mm:ss";
private static string s_SecondDateFormatter = "HH:mm:ss";
//private static string s_FullDateFormatter = "yyyy-MM-dd HH:mm:ss";
private static Regex s_DateOrTimeRegex = new Regex(@"^(date|time)\s*[:\s]+(.*)", RegexOptions.IgnoreCase);
public static bool IsDateOrTimeRegex(string regex)
{
return regex.StartsWith("date") || regex.StartsWith("time");
}
public static bool IsDateOrTimeRegex(string regex, ref bool date, ref string formatter)
{
if(IsDateOrTimeRegex(regex))
{
if(regex == "date" || regex == "time")
{
date = regex == "date";
formatter = "";
return true;
}
var mc = s_DateOrTimeRegex.Matches(regex);
date = mc[0].Groups[1].Value == "date";
formatter = mc[0].Groups[2].Value;
return true;
}
return false;
}
public static int GetTimestamp()
{
return (int)(DateTime.Now - k_DateTime1970).TotalSeconds;
return (int)(DateTime.Now - k_LocalDateTime1970).TotalSeconds;
}
public static int GetTimestamp(DateTime time)
public static int GetTimestamp(DateTime time, bool local = false)
{
return (int)(time - k_DateTime1970).TotalSeconds;
if (local)
{
return (int)(time - k_LocalDateTime1970).TotalSeconds;
}
else
{
return (int)(time - k_DateTime1970).TotalSeconds;
}
}
public static int GetTimestamp(string dateTime)
public static int GetTimestamp(string dateTime, bool local = false)
{
try
{
return GetTimestamp(DateTime.Parse(dateTime));
return GetTimestamp(DateTime.Parse(dateTime), local);
}
catch (Exception e)
{
@@ -49,9 +83,24 @@ namespace XCharts.Runtime
}
}
public static DateTime GetDateTime(int timestamp)
public static DateTime GetDateTime(double timestamp, bool local = true)
{
return k_DateTime1970.AddSeconds(timestamp);
return local ? k_LocalDateTime1970.AddSeconds(timestamp) : k_DateTime1970.AddSeconds(timestamp);
}
public static string GetDefaultDateTimeString(int timestamp, double range = 0)
{
var dateString = String.Empty;
var dateTime = GetDateTime(timestamp);
if (range <= 0 || range >= DateTimeUtil.ONE_DAY)
{
dateString = dateTime.ToString("yyyy-MM-dd");
}
else
{
dateString = dateTime.ToString(s_SecondDateFormatter);
}
return dateString;
}
internal static string GetDateTimeFormatString(DateTime dateTime, double range)
@@ -97,17 +146,20 @@ namespace XCharts.Runtime
/// <param name="splitNumber"></param>
internal static float UpdateTimeAxisDateTimeList(List<double> list, int minTimestamp, int maxTimestamp, int splitNumber)
{
var firstValue = list.Count > 0 ? list[0] : 0;
var secondValue = list.Count > 1 ? list[1] : 0;
list.Clear();
var range = maxTimestamp - minTimestamp;
if (range <= 0) return 0;
if (splitNumber <= 0) splitNumber = 1;
var dtMin = DateTimeUtil.GetDateTime(minTimestamp);
var dtMax = DateTimeUtil.GetDateTime(maxTimestamp);
int tick = 0;
if (range >= ONE_YEAR * MIN_TIME_SPLIT_NUMBER)
{
var num = Math.Max(range / (splitNumber * ONE_YEAR), 1);
var dtStart = new DateTime(dtMin.Year + 1, 1, 1);
var num = splitNumber <= 0 ? GetSplitNumber(range, ONE_YEAR) : Math.Max(range / (splitNumber * ONE_YEAR), 1);
var dtStart = (firstValue == 0 || secondValue == 0 || (minTimestamp > firstValue && minTimestamp > secondValue))
? (new DateTime(dtMin.Year, dtMin.Month, 1).AddMonths(1))
: (minTimestamp > firstValue ? DateTimeUtil.GetDateTime(secondValue) : DateTimeUtil.GetDateTime(firstValue));
tick = num * 365 * 24 * 3600;
while (dtStart.Ticks < dtMax.Ticks)
{
@@ -117,8 +169,10 @@ namespace XCharts.Runtime
}
else if (range >= ONE_MONTH * MIN_TIME_SPLIT_NUMBER)
{
var num = Math.Max(range / (splitNumber * ONE_MONTH), 1);
var dtStart = new DateTime(dtMin.Year, dtMin.Month, 1).AddMonths(1);
var num = splitNumber <= 0 ? GetSplitNumber(range, ONE_MONTH) : Math.Max(range / (splitNumber * ONE_MONTH), 1);
var dtStart = (firstValue == 0 || secondValue == 0 || (minTimestamp > firstValue && minTimestamp > secondValue))
? (new DateTime(dtMin.Year, dtMin.Month, 1).AddMonths(1))
: (minTimestamp > firstValue ? DateTimeUtil.GetDateTime(secondValue) : DateTimeUtil.GetDateTime(firstValue));
tick = num * 30 * 24 * 3600;
while (dtStart.Ticks < dtMax.Ticks)
{
@@ -129,30 +183,44 @@ namespace XCharts.Runtime
else if (range >= ONE_DAY * MIN_TIME_SPLIT_NUMBER)
{
tick = GetTickSecond(range, splitNumber, ONE_DAY);
var startTimestamp = (minTimestamp - minTimestamp % tick) + tick;
var let = minTimestamp % tick;
var startTimestamp = let == 0 ? minTimestamp : (minTimestamp - let) + tick;
AddTickTimestamp(list, startTimestamp, maxTimestamp, tick);
}
else if (range >= ONE_HOUR * MIN_TIME_SPLIT_NUMBER)
{
tick = GetTickSecond(range, splitNumber, ONE_HOUR);
var startTimestamp = (minTimestamp - minTimestamp % tick) + tick;
var let = minTimestamp % tick;
var startTimestamp = let == 0 ? minTimestamp : (minTimestamp - let) + tick;
AddTickTimestamp(list, startTimestamp, maxTimestamp, tick);
}
else if (range >= ONE_MINUTE * MIN_TIME_SPLIT_NUMBER)
{
tick = GetTickSecond(range, splitNumber, ONE_MINUTE);
var startTimestamp = (minTimestamp - minTimestamp % tick) + tick;
var let = minTimestamp % tick;
var startTimestamp = let == 0 ? minTimestamp : (minTimestamp - let) + tick;
AddTickTimestamp(list, startTimestamp, maxTimestamp, tick);
}
else
{
tick = GetTickSecond(range, splitNumber, ONE_SECOND);
var startTimestamp = (minTimestamp - minTimestamp % tick) + tick;
var let = minTimestamp % tick;
var startTimestamp = let == 0 ? minTimestamp : (minTimestamp - let) + tick;
AddTickTimestamp(list, startTimestamp, maxTimestamp, tick);
}
return tick;
}
private static int GetSplitNumber(int range, int tickSecond)
{
var num = 1;
while (range / (num * tickSecond) > 8)
{
num++;
}
return num;
}
private static int GetTickSecond(int range, int splitNumber, int tickSecond)
{
var num = 0;

View File

@@ -3,9 +3,9 @@
"displayName": "XCharts",
"author": "monitor1394",
"license": "MIT",
"version": "3.11.0",
"date": "20240616",
"checkdate": "20240616",
"version": "3.12.0",
"date": "20240930",
"checkdate": "20240930",
"unity": "2018.3",
"description": "A charting and data visualization library for Unity. Support line chart, bar chart, pie chart, radar chart, scatter chart, heatmap chart, ring chart, candlestick chart, polar chart and parallel coordinates.",
"keywords": [