From 34dd3d1c4e6cb78bd31d72648d402d4db97c88fa Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Thu, 25 Aug 2022 08:37:17 +0800 Subject: [PATCH 01/38] [improve][MarkLine] improve label --- CHANGELOG.md | 3 +++ Runtime/Component/Mark/MarkLineHandler.cs | 14 +++++++------- Runtime/Component/Mark/MarkLineHelper.cs | 3 +++ Runtime/Serie/Scatter/BaseScatterHandler.cs | 1 + 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f0bc2cc..d4c366bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,9 @@ ## master +* (2022.08.24) 修复`ScatterChart`的`label`不刷新的问题 +* (2022.08.24) 修复`MarkLine`的`label`某些情况下显示异常的问题 + ## v3.2.0 ### 版本要点 diff --git a/Runtime/Component/Mark/MarkLineHandler.cs b/Runtime/Component/Mark/MarkLineHandler.cs index 55d211df..6ac01410 100644 --- a/Runtime/Component/Mark/MarkLineHandler.cs +++ b/Runtime/Component/Mark/MarkLineHandler.cs @@ -35,8 +35,9 @@ public override void Update() { if (data.runtimeLabel != null) { - data.runtimeLabel.SetActive(data.label.show); - data.runtimeLabel.SetPosition(MarkLineHelper.GetLabelPosition(data)); + var pos = MarkLineHelper.GetLabelPosition(data); + data.runtimeLabel.SetActive(data.label.show && pos != Vector3.zero); + data.runtimeLabel.SetPosition(pos); data.runtimeLabel.SetText(MarkLineHelper.GetFormatterContent(serie, data)); } } @@ -76,10 +77,10 @@ private void InitMarkLineLabel(Serie serie, MarkLineData data, Color serieColor) var content = MarkLineHelper.GetFormatterContent(serie, data); var label = ChartHelper.AddChartLabel(textName, m_MarkLineLabelRoot.transform, data.label, chart.theme.axis, content, Color.clear, TextAnchor.MiddleCenter); - + var pos = MarkLineHelper.GetLabelPosition(data); label.SetIconActive(false); - label.SetActive(data.label.show); - label.SetPosition(MarkLineHelper.GetLabelPosition(data)); + label.SetActive(data.label.show && pos != Vector3.zero); + label.SetPosition(pos); data.runtimeLabel = label; }; data.refreshComponent(); @@ -202,8 +203,7 @@ private void ResetTempMarkLineGroupData(MarkLine markLine) for (int i = 0; i < markLine.data.Count; i++) { var data = markLine.data[i]; - // data.index = i; - data.index = markLine.index; + data.index = i; if (data.group == 0) continue; if (!m_TempGroupData.ContainsKey(data.group)) { diff --git a/Runtime/Component/Mark/MarkLineHelper.cs b/Runtime/Component/Mark/MarkLineHelper.cs index 55304ff4..4a1c5dcd 100644 --- a/Runtime/Component/Mark/MarkLineHelper.cs +++ b/Runtime/Component/Mark/MarkLineHelper.cs @@ -34,13 +34,16 @@ public static Vector3 GetLabelPosition(MarkLineData data) switch (data.label.position) { case LabelStyle.Position.Start: + if (data.runtimeStartPosition == Vector3.zero) return Vector3.zero; if (horizontal) return data.runtimeStartPosition + data.label.offset + labelWidth / 2 * Vector3.left; else return data.runtimeStartPosition + data.label.offset + labelHeight / 2 * Vector3.down; case LabelStyle.Position.Middle: + if (data.runtimeCurrentEndPosition == Vector3.zero) return Vector3.zero; var center = (data.runtimeStartPosition + data.runtimeCurrentEndPosition) / 2; if (horizontal) return center + data.label.offset + labelHeight / 2 * Vector3.up; else return center + data.label.offset + labelWidth / 2 * Vector3.right; default: + if (data.runtimeCurrentEndPosition == Vector3.zero) return Vector3.zero; if (horizontal) return data.runtimeCurrentEndPosition + data.label.offset + labelWidth / 2 * Vector3.right; else return data.runtimeCurrentEndPosition + data.label.offset + labelHeight / 2 * Vector3.up; } diff --git a/Runtime/Serie/Scatter/BaseScatterHandler.cs b/Runtime/Serie/Scatter/BaseScatterHandler.cs index 0d9be98f..8d8f0220 100644 --- a/Runtime/Serie/Scatter/BaseScatterHandler.cs +++ b/Runtime/Serie/Scatter/BaseScatterHandler.cs @@ -12,6 +12,7 @@ internal class BaseScatterHandler : SerieHandler where T : BaseScatter public override void Update() { + base.Update(); UpdateSerieContext(); } From 9552e877ce7d75fd60f5a0c56a7b40f322866d63 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Thu, 25 Aug 2022 13:37:36 +0800 Subject: [PATCH 02/38] [feature][formatter] support {d3} --- CHANGELOG.md | 1 + Runtime/Component/Tooltip/Tooltip.cs | 1 + Runtime/Helper/FormatterHelper.cs | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4c366bb..d12b4bfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.08.25) 增加`formatter`对`{d3}`指定维度数据百分比的支持 * (2022.08.24) 修复`ScatterChart`的`label`不刷新的问题 * (2022.08.24) 修复`MarkLine`的`label`某些情况下显示异常的问题 diff --git a/Runtime/Component/Tooltip/Tooltip.cs b/Runtime/Component/Tooltip/Tooltip.cs index 418c679a..948e06f6 100644 --- a/Runtime/Component/Tooltip/Tooltip.cs +++ b/Runtime/Component/Tooltip/Tooltip.cs @@ -189,6 +189,7 @@ public Trigger trigger /// {g}为当前所指示的serie的数据总个数。
/// {c0}表示当前数据项维度为0的数据。
/// {c1}表示当前数据项维度为1的数据。
+ /// {d3}表示维度3的数据的百分比。它的分母是默认维度(一般是1维度)数据。
/// |表示多个列的分隔。
/// 示例:"{i}", "{.}|{a}|{c}", "{.}|{b}|{c2:f2}" /// diff --git a/Runtime/Helper/FormatterHelper.cs b/Runtime/Helper/FormatterHelper.cs index 6cb3a659..02ddaea8 100644 --- a/Runtime/Helper/FormatterHelper.cs +++ b/Runtime/Helper/FormatterHelper.cs @@ -205,7 +205,9 @@ public static void ReplaceSerieLabelContent(ref string content, string numericFo } else if (p == 'd' || p == 'D') { - var rate = total == 0 ? 0 : value / total * 100; + var rate = pIndex >= 0 && serieData != null ? + (value == 0 ? 0 : serieData.GetData(pIndex) / value * 100) : + (total == 0 ? 0 : value / total * 100); content = content.Replace(old, ChartCached.NumberToStr(rate, numericFormatter)); } else if (p == 'c' || p == 'C') From 442a51abc1656809935a8c89599ef679c47bb68a Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Thu, 25 Aug 2022 21:38:25 +0800 Subject: [PATCH 03/38] [improve][label] improve emphasis label --- CHANGELOG.md | 1 + Runtime/Serie/SerieHandler.cs | 6 +++--- Runtime/Serie/SerieHelper.cs | 10 +++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d12b4bfc..4f1b8834 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.08.25) 优化`EmphasisStyle`对`label`的支持 * (2022.08.25) 增加`formatter`对`{d3}`指定维度数据百分比的支持 * (2022.08.24) 修复`ScatterChart`的`label`不刷新的问题 * (2022.08.24) 修复`MarkLine`的`label`某些情况下显示异常的问题 diff --git a/Runtime/Serie/SerieHandler.cs b/Runtime/Serie/SerieHandler.cs index 520fe7c6..62d0e05e 100644 --- a/Runtime/Serie/SerieHandler.cs +++ b/Runtime/Serie/SerieHandler.cs @@ -239,7 +239,7 @@ protected bool AddSerieLabel(GameObject serieLabelRoot, SerieData serieData, ref if (count == -1) count = serie.dataCount; var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); - if (serieLabel == null || !serieLabel.show) + if (serieLabel == null) { return false; } @@ -401,7 +401,7 @@ public override void RefreshLabelInternal() SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, currLabel, color); var offset = GetSerieDataLabelOffset(serieData, currLabel); - labelObject.SetActive(!isIgnore); + labelObject.SetActive(currLabel.show && !isIgnore); labelObject.SetText(content); labelObject.SetPosition(serieData.context.dataPoints[i] + offset); labelObject.UpdateIcon(currLabel.icon); @@ -422,7 +422,7 @@ public override void RefreshLabelInternal() ChartCached.NumberToStr(value, currLabel.numericFormatter) : SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, currLabel, color); - serieData.SetLabelActive(!isIgnore); + serieData.SetLabelActive(currLabel.show && !isIgnore); serieData.labelObject.UpdateIcon(currLabel.icon); serieData.labelObject.SetText(content); UpdateLabelPosition(serieData, currLabel); diff --git a/Runtime/Serie/SerieHelper.cs b/Runtime/Serie/SerieHelper.cs index ea5cff22..e9e77d9c 100644 --- a/Runtime/Serie/SerieHelper.cs +++ b/Runtime/Serie/SerieHelper.cs @@ -433,7 +433,7 @@ public static ItemStyle GetItemStyle(Serie serie, SerieData serieData, SerieStat else { var stateStyle = GetStateStyle(serie, serieData, state); - return stateStyle == null?serie.itemStyle : stateStyle.itemStyle; + return stateStyle == null || !stateStyle.show ? serie.itemStyle : stateStyle.itemStyle; } } @@ -447,7 +447,7 @@ public static LabelStyle GetSerieLabel(Serie serie, SerieData serieData, SerieSt else { var stateStyle = GetStateStyle(serie, serieData, state); - return stateStyle == null?serie.label : stateStyle.label; + return stateStyle == null || !stateStyle.show ? serie.label : stateStyle.label; } } @@ -461,7 +461,7 @@ public static LabelLine GetSerieLabelLine(Serie serie, SerieData serieData, Seri else { var stateStyle = GetStateStyle(serie, serieData, state); - return stateStyle == null?serie.labelLine : stateStyle.labelLine; + return stateStyle == null || !stateStyle.show ? serie.labelLine : stateStyle.labelLine; } } @@ -475,7 +475,7 @@ public static SerieSymbol GetSerieSymbol(Serie serie, SerieData serieData, Serie else { var stateStyle = GetStateStyle(serie, serieData, state); - return stateStyle == null?serie.symbol : stateStyle.symbol; + return stateStyle == null || !stateStyle.show ? serie.symbol : stateStyle.symbol; } } @@ -533,7 +533,7 @@ public static bool GetAreaColor(out Color32 color, out Color32 toColor, Serie serie, SerieData serieData, ThemeStyle theme, int index) { bool fill; - return GetAreaColor(out color, out toColor, out fill,serie, serieData, theme, index); + return GetAreaColor(out color, out toColor, out fill, serie, serieData, theme, index); } public static bool GetAreaColor(out Color32 color, out Color32 toColor, out bool innerFill, From b2f1fd00b14ad2d3e4071dda0425008eda088cd6 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Fri, 26 Aug 2022 07:50:48 +0800 Subject: [PATCH 04/38] [feature][Tooltip] support `position` --- CHANGELOG.md | 2 + Documentation/XChartsConfiguration-EN.md | 5 +- Documentation/XChartsConfiguration-ZH.md | 5 +- Editor/MainComponents/TooltipEditor.cs | 9 +-- Runtime/Component/Tooltip/Tooltip.cs | 85 ++++++++++++++++------ Runtime/Component/Tooltip/TooltipHelper.cs | 2 +- 6 files changed, 72 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f1b8834..d7afcae5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,8 @@ ## master +* (2022.08.25) 增加`Tooltip`的`position`参数支持设置移动平台不同的显示位置 +* (2022.08.25) 删除`Tooltip`的`fixedXEnable`和`fixedYEnable`参数 * (2022.08.25) 优化`EmphasisStyle`对`label`的支持 * (2022.08.25) 增加`formatter`对`{d3}`指定维度数据百分比的支持 * (2022.08.24) 修复`ScatterChart`的`label`不刷新的问题 diff --git a/Documentation/XChartsConfiguration-EN.md b/Documentation/XChartsConfiguration-EN.md index ed930332..7a696b8a 100644 --- a/Documentation/XChartsConfiguration-EN.md +++ b/Documentation/XChartsConfiguration-EN.md @@ -1422,6 +1422,7 @@ Tooltip component. |`show`|true||Whether to show the tooltip component. |`type`|||Indicator type.
`Tooltip.Type`:
- `Line`: line indicator.
- `Shadow`: shadow crosshair indicator.
- `None`: no indicator displayed.
- `Corss`: crosshair indicator, which is actually the shortcut of enable two axisPointers of two orthometric axes.
| |`trigger`|||Type of triggering.
`Tooltip.Trigger`:
- `Item`: Triggered by data item, which is mainly used for charts that don't have a category axis like scatter charts or pie charts.
- `Axis`: Triggered by axes, which is mainly used for charts that have category axes, like bar charts or line charts.
- `None`: Trigger nothing.
| +|`position`||v3.3.0|Type of position.
`Tooltip.Position`:
- `Auto`: Auto. The mobile platform is displayed at the top, and the non-mobile platform follows the mouse position.
- `Custom`: Custom. Fully customize display position (x,y).
- `FixedX`: Just fix the coordinate X. Y follows the mouse position.
- `FixedY`:
| |`itemFormatter`|||a string template formatter for a single Serie or data item content. Support for wrapping lines with \n. Template variables are {.}, {a}, {b}, {c}, {d}.
{.} is the dot of the corresponding color of a Serie that is currently indicated or whose index is 0.
{a} is the series name of the serie that is currently indicated or whose index is 0.
{b} is the name of the data item serieData that is currently indicated or whose index is 0, or a category value (such as the X-axis of a line chart).
{c} is the value of a Y-dimension (dimesion is 1) from a Serie that is currently indicated or whose index is 0.
{d} is the percentage value of Y-dimensions (dimesion is 1) from serie that is currently indicated or whose index is 0, with no % sign.
{e} is the name of the data item serieData that is currently indicated or whose index is 0.
{f} is sum of data.
{.1} represents a dot from serie corresponding color that specifies index as 1.
1 in {a1}, {b1}, {c1} represents a serie that specifies an index of 1.
{c1:2} represents the third data from serie's current indication data item indexed to 1 (a data item has multiple data, index 2 represents the third data).
{c1:2-2} represents the third data item from serie's third data item indexed to 1 (i.e., which data item must be specified to specify).
{d1:2: F2} indicates that a formatted string with a value specified separately is F2 (numericFormatter is used when numericFormatter is not specified).
{d:0.##} indicates that a formatted string with a value specified separately is 0.## (used for percentage, reserved 2 valid digits while avoiding the situation similar to "100.00%" when using f2 ).
Example: "{a}, {c}", "{a1}, {c1: f1}", "{a1}, {c1:0: f1}", "{a1} : {c1:1-1: f1}"
|`titleFormatter`|||The string template formatter for the tooltip title content. Support for wrapping lines with \n. The placeholder {I} can be set separately to indicate that the title is ignored and not displayed. Template see itemFormatter. |`marker`|||the marker of serie. @@ -1441,10 +1442,8 @@ Tooltip component. |`backgroundType`|||The background type of tooltip. |`backgroundColor`|||The background color of tooltip. |`borderWidth`|2f||the width of tooltip border. -|`fixedXEnable`|false||enable fixedX. |`fixedX`|0f||the x positionn of fixedX. -|`fixedYEnable`|false||enable fixedY. -|`fixedY`|0f||the y position of fixedY. +|`fixedY`|0.7f||the y position of fixedY. |`titleHeight`|25f||height of title text. |`itemHeight`|25f||height of content text. |`borderColor`|Color32(230, 230, 230, 255)||the color of tooltip border. diff --git a/Documentation/XChartsConfiguration-ZH.md b/Documentation/XChartsConfiguration-ZH.md index fbeed47d..effc6b6b 100644 --- a/Documentation/XChartsConfiguration-ZH.md +++ b/Documentation/XChartsConfiguration-ZH.md @@ -1422,6 +1422,7 @@ Inherits or Implemented: [MainComponent](#MainComponent) |`show`|true||是否显示提示框组件。 |`type`|||提示框指示器类型。
`Tooltip.Type`:
- `Line`: 直线指示器
- `Shadow`: 阴影指示器
- `None`: 无指示器
- `Corss`: 十字准星指示器。坐标轴显示Label和交叉线。
| |`trigger`|||触发类型。
`Tooltip.Trigger`:
- `Item`: 数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。
- `Axis`: 坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。
- `None`: 什么都不触发。
| +|`position`||v3.3.0|显示位置类型。
`Tooltip.Position`:
- `Auto`: 自适应。移动平台靠顶部显示,非移动平台跟随鼠标位置。
- `Custom`: 自定义。完全自定义显示位置(x,y)。
- `FixedX`: 只固定坐标X。Y跟随鼠标位置。
- `FixedY`:
| |`itemFormatter`|||提示框单个serie或数据项内容的字符串模版格式器。支持用 \n 换行。用 |`titleFormatter`|||提示框标题内容的字符串模版格式器。支持用 \n 换行。可以单独设置占位符{i}表示忽略不显示title。 模板变量有{.}、{a}、{b}、{c}、{d}、{e}、{f}、{g}。
{.}为当前所指示或index为0的serie的对应颜色的圆点。
{a}为当前所指示或index为0的serie的系列名name。
{b}为当前所指示或index为0的serie的数据项serieData的name,或者类目值(如折线图的X轴)。
{c}为当前所指示或index为0的serie的y维(dimesion为1)的数值。
{d}为当前所指示或index为0的serie的y维(dimesion为1)百分比值,注意不带%号。
{e}为当前所指示或index为0的serie的数据项serieData的name。
{f}为数据总和。
{g}为数据总个数。
{.1}表示指定index为1的serie对应颜色的圆点。
{a1}、{b1}、{c1}中的1表示指定index为1的serie。
{c1:2}表示索引为1的serie的当前指示数据项的第3个数据(一个数据项有多个数据,index为2表示第3个数据)。
{c1:2-2}表示索引为1的serie的第3个数据项的第3个数据(也就是要指定第几个数据项时必须要指定第几个数据)。
{d1:2:f2}表示单独指定了数值的格式化字符串为f2(不指定时用numericFormatter)。
{d:0.##} 表示单独指定了数值的格式化字符串为 0.## (用于百分比,保留2位有效数同时又能避免使用 f2 而出现的类似于"100.00%"的情况 )。
示例:"{a}:{c}"、"{a1}:{c1:f1}"、"{a1}:{c1:0:f1}"、"{a1}:{c1:1-1:f1}" |`marker`|||serie的符号标志。 @@ -1441,10 +1442,8 @@ Inherits or Implemented: [MainComponent](#MainComponent) |`backgroundType`|||提示框的背景图片显示类型。 |`backgroundColor`|||提示框的背景颜色。 |`borderWidth`|2f||边框线宽。 -|`fixedXEnable`|false||是否固定X位置。 |`fixedX`|0f||固定X位置的坐标。 -|`fixedYEnable`|false||是否固定Y位置。 -|`fixedY`|0f||固定Y位置的坐标。 +|`fixedY`|0.7f||固定Y位置的坐标。 |`titleHeight`|25f||标题文本的高。 |`itemHeight`|25f||数据项文本的高。 |`borderColor`|Color32(230, 230, 230, 255)||边框颜色。 diff --git a/Editor/MainComponents/TooltipEditor.cs b/Editor/MainComponents/TooltipEditor.cs index af7b4344..c657d8fe 100644 --- a/Editor/MainComponents/TooltipEditor.cs +++ b/Editor/MainComponents/TooltipEditor.cs @@ -11,6 +11,10 @@ public override void OnInspectorGUI() ++EditorGUI.indentLevel; PropertyField("m_Type"); PropertyField("m_Trigger"); + PropertyField("m_Position"); + PropertyField("m_FixedX"); + PropertyField("m_FixedY"); + PropertyField("m_Offset"); PropertyField("m_ShowContent"); PropertyField("m_AlwayShowContent"); PropertyField("m_TitleFormatter"); @@ -33,11 +37,6 @@ public override void OnInspectorGUI() PropertyField("m_MinWidth"); PropertyField("m_MinHeight"); PropertyField("m_IgnoreDataDefaultContent"); - PropertyField("m_Offset"); - PropertyField("m_FixedXEnable"); - PropertyField("m_FixedX"); - PropertyField("m_FixedYEnable"); - PropertyField("m_FixedY"); }); PropertyField("m_LineStyle"); PropertyField("m_IndicatorLabelStyle"); diff --git a/Runtime/Component/Tooltip/Tooltip.cs b/Runtime/Component/Tooltip/Tooltip.cs index 948e06f6..b882e057 100644 --- a/Runtime/Component/Tooltip/Tooltip.cs +++ b/Runtime/Component/Tooltip/Tooltip.cs @@ -42,6 +42,10 @@ public enum Type Corss } + /// + /// Trigger strategy. + /// |触发类型。 + /// public enum Trigger { /// @@ -60,10 +64,37 @@ public enum Trigger /// None } + /// + /// Position type. + /// |坐标类型。 + /// + public enum Position + { + /// + /// Auto. The mobile platform is displayed at the top, and the non-mobile platform follows the mouse position. + /// |自适应。移动平台靠顶部显示,非移动平台跟随鼠标位置。 + /// + Auto, + /// + /// Custom. Fully customize display position (x,y). + /// |自定义。完全自定义显示位置(x,y)。 + /// + Custom, + /// + /// Just fix the coordinate X. Y follows the mouse position. + /// |只固定坐标X。Y跟随鼠标位置。 + /// + FixedX, + /// + /// Just fix the coordinate Y. X follows the mouse position. + /// |只固定坐标Y。X跟随鼠标位置。 + FixedY + } [SerializeField] private bool m_Show = true; [SerializeField] private Type m_Type; [SerializeField] private Trigger m_Trigger = Trigger.Item; + [SerializeField][Since("v3.3.0")] private Position m_Position = Position.Auto; [SerializeField] private string m_ItemFormatter; [SerializeField] private string m_TitleFormatter; [SerializeField] private string m_Marker = "●"; @@ -83,10 +114,8 @@ public enum Trigger [SerializeField] private Image.Type m_BackgroundType = Image.Type.Simple; [SerializeField] private Color m_BackgroundColor; [SerializeField] private float m_BorderWidth = 2f; - [SerializeField] private bool m_FixedXEnable = false; [SerializeField] private float m_FixedX = 0f; - [SerializeField] private bool m_FixedYEnable = false; - [SerializeField] private float m_FixedY = 0f; + [SerializeField] private float m_FixedY = 0.7f; [SerializeField] private float m_TitleHeight = 25f; [SerializeField] private float m_ItemHeight = 25f; [SerializeField] private Color32 m_BorderColor = new Color32(230, 230, 230, 255); @@ -136,6 +165,15 @@ public Trigger trigger set { if (PropertyUtil.SetStruct(ref m_Trigger, value)) SetAllDirty(); } } /// + /// Type of position. + /// |显示位置类型。 + /// + public Position position + { + get { return m_Position; } + set { if (PropertyUtil.SetStruct(ref m_Position, value)) SetAllDirty(); } + } + /// /// The string template formatter for the tooltip title content. Support for wrapping lines with \n. /// The placeholder {I} can be set separately to indicate that the title is ignored and not displayed. /// Template see itemFormatter. @@ -304,15 +342,6 @@ public Color32 borderColor set { if (PropertyUtil.SetColor(ref m_BorderColor, value)) SetVerticesDirty(); } } /// - /// enable fixedX. - /// |是否固定X位置。 - /// - public bool fixedXEnable - { - get { return m_FixedXEnable; } - set { if (PropertyUtil.SetStruct(ref m_FixedXEnable, value)) SetVerticesDirty(); } - } - /// /// the x positionn of fixedX. /// |固定X位置的坐标。 /// @@ -322,15 +351,6 @@ public float fixedX set { if (PropertyUtil.SetStruct(ref m_FixedX, value)) SetVerticesDirty(); } } /// - /// enable fixedY. - /// |是否固定Y位置。 - /// - public bool fixedYEnable - { - get { return m_FixedYEnable; } - set { if (PropertyUtil.SetStruct(ref m_FixedYEnable, value)) SetVerticesDirty(); } - } - /// /// the y position of fixedY. /// |固定Y位置的坐标。 /// @@ -468,12 +488,29 @@ public void SetActive(bool flag) /// 更新文本框位置 /// /// - public void UpdateContentPos(Vector2 pos) + public void UpdateContentPos(Vector2 pos, float width, float height) { if (view != null) { - if (fixedXEnable) pos.x = fixedX; - if (fixedYEnable) pos.y = fixedY; + switch (m_Position) + { + case Position.Auto: +#if UNITY_ANDROID || UNITY_IOS + if (m_FixedY == 0) pos.y = ChartHelper.GetActualValue(0.7f, height); + else pos.y = ChartHelper.GetActualValue(m_FixedY, height); +#endif + break; + case Position.Custom: + pos.x = ChartHelper.GetActualValue(m_FixedX, width); + pos.y = ChartHelper.GetActualValue(m_FixedY, height); + break; + case Position.FixedX: + pos.x = ChartHelper.GetActualValue(m_FixedX, width); + break; + case Position.FixedY: + pos.y = ChartHelper.GetActualValue(m_FixedY, height); + break; + } view.UpdatePosition(pos); } } diff --git a/Runtime/Component/Tooltip/TooltipHelper.cs b/Runtime/Component/Tooltip/TooltipHelper.cs index f0dd53d6..8f9d729d 100644 --- a/Runtime/Component/Tooltip/TooltipHelper.cs +++ b/Runtime/Component/Tooltip/TooltipHelper.cs @@ -77,7 +77,7 @@ public static void LimitInRect(Tooltip tooltip, Rect chartRect) } if (pos.y > chartRect.y + chartRect.height) pos.y = chartRect.y + chartRect.height; - tooltip.UpdateContentPos(pos); + tooltip.UpdateContentPos(pos, chartRect.width / 2, chartRect.height / 2); } public static string GetItemNumericFormatter(Tooltip tooltip, Serie serie, SerieData serieData) From a1d8f3472036294a631eb6bbaa82adcbfa658024 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Fri, 26 Aug 2022 07:52:40 +0800 Subject: [PATCH 05/38] v3.3.0 --- Runtime/Internal/XChartsMgr.cs | 4 ++-- package.json | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Runtime/Internal/XChartsMgr.cs b/Runtime/Internal/XChartsMgr.cs index a9d29535..d789c75b 100644 --- a/Runtime/Internal/XChartsMgr.cs +++ b/Runtime/Internal/XChartsMgr.cs @@ -20,8 +20,8 @@ class XChartsVersion [ExecuteInEditMode] public static class XChartsMgr { - public static readonly string version = "3.2.0"; - public static readonly int versionDate = 20220815; + public static readonly string version = "3.3.0"; + public static readonly int versionDate = 20220915; public static string fullVersion { get { return version + "-" + versionDate; } } internal static List chartList = new List(); diff --git a/package.json b/package.json index b484585f..e8601711 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "com.monitor1394.xcharts", "displayName": "XCharts", - "version": "3.2.0", - "date": "20220815", - "checkdate": "20220815", + "version": "3.3.0", + "date": "20220915", + "checkdate": "20220915", "desc": "如果 XCharts 对您有帮助,希望您能在 Github 上点 Star 支持,非常感谢!", "unity": "2018.3", "description": "A charting and data visualization library for Unity.", From a885be625ed940d7490c813710868255018ba0be Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Fri, 26 Aug 2022 23:17:54 +0800 Subject: [PATCH 06/38] [improve][Candlestick] improve CandlestickChart --- CHANGELOG.md | 5 +++-- Editor/Series/CandlestickEditor.cs | 1 + Examples/Example90_Candlestick.cs | 2 +- Runtime/Internal/BaseChart.Serie.cs | 8 ++++---- Runtime/Serie/Candlestick/Candlestick.cs | 2 +- Runtime/Serie/Candlestick/CandlestickHandler.cs | 11 ++++++----- Runtime/Serie/Candlestick/SimplifiedCandlestick.cs | 2 +- .../Serie/Candlestick/SimplifiedCandlestickHandler.cs | 11 ++++++----- Runtime/Serie/Serie.cs | 5 +++-- 9 files changed, 26 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7afcae5..337b06be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,8 +58,9 @@ ## master -* (2022.08.25) 增加`Tooltip`的`position`参数支持设置移动平台不同的显示位置 -* (2022.08.25) 删除`Tooltip`的`fixedXEnable`和`fixedYEnable`参数 +* (2022.08.26) 优化`CandlestickChart`表现,调整相关的`AddData()`接口参数 +* (2022.08.26) 增加`Tooltip`的`position`参数支持设置移动平台不同的显示位置 +* (2022.08.26) 删除`Tooltip`的`fixedXEnable`和`fixedYEnable`参数 * (2022.08.25) 优化`EmphasisStyle`对`label`的支持 * (2022.08.25) 增加`formatter`对`{d3}`指定维度数据百分比的支持 * (2022.08.24) 修复`ScatterChart`的`label`不刷新的问题 diff --git a/Editor/Series/CandlestickEditor.cs b/Editor/Series/CandlestickEditor.cs index ff77a8db..06fff6ff 100644 --- a/Editor/Series/CandlestickEditor.cs +++ b/Editor/Series/CandlestickEditor.cs @@ -7,6 +7,7 @@ public class CandlestickEditor : SerieEditor { public override void OnCustomInspectorGUI() { + PropertyField("m_ColorBy"); PropertyField("m_XAxisIndex"); PropertyField("m_YAxisIndex"); PropertyFieldLimitMin("m_MinShow", 0); diff --git a/Examples/Example90_Candlestick.cs b/Examples/Example90_Candlestick.cs index 895e305d..7218b6b9 100644 --- a/Examples/Example90_Candlestick.cs +++ b/Examples/Example90_Candlestick.cs @@ -61,7 +61,7 @@ void GenerateOHLC(int count) var heighest = boxVals[3]; chart.AddXAxisData(i.ToString()); - chart.AddData(0, open, close, lowest, heighest); + chart.AddData(0, i, open, close, lowest, heighest); } } } diff --git a/Runtime/Internal/BaseChart.Serie.cs b/Runtime/Internal/BaseChart.Serie.cs index 4b0a3cec..a87dfd89 100644 --- a/Runtime/Internal/BaseChart.Serie.cs +++ b/Runtime/Internal/BaseChart.Serie.cs @@ -377,23 +377,23 @@ public SerieData AddData(int serieIndex, DateTime time, double yValue, string da return AddData(serieIndex, xValue, yValue, dataName, dataId); } - public SerieData AddData(int serieIndex, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null) + public SerieData AddData(int serieIndex, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null) { var serie = GetSerie(serieIndex); if (serie != null) { - var serieData = serie.AddData(open, close, lowest, heighest, dataName, dataId); + var serieData = serie.AddData(indexOrTimestamp, open, close, lowest, heighest, dataName, dataId); RefreshPainter(serie.painter); return serieData; } return null; } - public SerieData AddData(string serieName, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null) + public SerieData AddData(string serieName, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null) { var serie = GetSerie(serieName); if (serie != null) { - var serieData = serie.AddData(open, close, lowest, heighest, dataName, dataId); + var serieData = serie.AddData(indexOrTimestamp, open, close, lowest, heighest, dataName, dataId); RefreshPainter(serie.painter); return serieData; } diff --git a/Runtime/Serie/Candlestick/Candlestick.cs b/Runtime/Serie/Candlestick/Candlestick.cs index 16da2b14..08ff439c 100644 --- a/Runtime/Serie/Candlestick/Candlestick.cs +++ b/Runtime/Serie/Candlestick/Candlestick.cs @@ -22,7 +22,7 @@ public static Serie AddDefaultSerie(BaseChart chart, string serieName) var close = Random.Range(40, 90); var lowest = Random.Range(0, 50); var heighest = Random.Range(50, 100); - chart.AddData(serie.index, open, close, lowest, heighest); + chart.AddData(serie.index, i, open, close, lowest, heighest); } return serie; } diff --git a/Runtime/Serie/Candlestick/CandlestickHandler.cs b/Runtime/Serie/Candlestick/CandlestickHandler.cs index dcbf690c..3fe8b247 100644 --- a/Runtime/Serie/Candlestick/CandlestickHandler.cs +++ b/Runtime/Serie/Candlestick/CandlestickHandler.cs @@ -108,7 +108,7 @@ private void DrawCandlestickSerie(VertexHelper vh, Candlestick serie) for (int i = serie.minShow; i < maxCount; i++) { var serieData = showData[i]; - if (serie.IsIgnoreValue(serieData)) + if (!serieData.show || serie.IsIgnoreValue(serieData)) { serie.context.dataPoints.Add(Vector3.zero); serie.context.dataIndexs.Add(serieData.index); @@ -116,10 +116,11 @@ private void DrawCandlestickSerie(VertexHelper vh, Candlestick serie) } var state = SerieHelper.GetSerieState(serie, serieData); var itemStyle = SerieHelper.GetItemStyle(serie, serieData, state); - var open = serieData.GetCurrData(0, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var close = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var lowest = serieData.GetCurrData(2, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var heighest = serieData.GetCurrData(3, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); + var startDataIndex = serieData.data.Count > 4 ? 1 : 0; + var open = serieData.GetCurrData(startDataIndex, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); + var close = serieData.GetCurrData(startDataIndex + 1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); + var lowest = serieData.GetCurrData(startDataIndex + 2, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); + var heighest = serieData.GetCurrData(startDataIndex + 3, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); var isRise = yAxis.inverse ? close open; var borderWidth = open == 0 ? 0f : (itemStyle.runtimeBorderWidth == 0 ? theme.serie.candlestickBorderWidth : diff --git a/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs b/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs index 820b00a5..4a8ca1a2 100644 --- a/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs +++ b/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs @@ -25,7 +25,7 @@ public static Serie AddDefaultSerie(BaseChart chart, string serieName) var close = lastValue + Random.Range(-5, 10); var lowest = lastValue + Random.Range(-15, -10); var heighest = lastValue + Random.Range(10, 20); - chart.AddData(serie.index, open, close, lowest, heighest); + chart.AddData(serie.index, i, open, close, lowest, heighest); } return serie; } diff --git a/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs b/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs index 8266c6be..c10380b7 100644 --- a/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs +++ b/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs @@ -110,16 +110,17 @@ private void DrawCandlestickSerie(VertexHelper vh, SimplifiedCandlestick serie) for (int i = serie.minShow; i < maxCount; i++) { var serieData = showData[i]; - if (serie.IsIgnoreValue(serieData)) + if (!serieData.show || serie.IsIgnoreValue(serieData)) { serie.context.dataPoints.Add(Vector3.zero); serie.context.dataIndexs.Add(serieData.index); continue; } - var open = serieData.GetCurrData(0, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var close = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var lowest = serieData.GetCurrData(2, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var heighest = serieData.GetCurrData(3, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); + var startDataIndex = serieData.data.Count > 4 ? 1 : 0; + var open = serieData.GetCurrData(startDataIndex, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); + var close = serieData.GetCurrData(startDataIndex + 1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); + var lowest = serieData.GetCurrData(startDataIndex + 2, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); + var heighest = serieData.GetCurrData(startDataIndex + 3, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); var isRise = yAxis.inverse ? close open; var borderWidth = open == 0 ? 0f : (itemStyle.runtimeBorderWidth == 0 ? theme.serie.candlestickBorderWidth : diff --git a/Runtime/Serie/Serie.cs b/Runtime/Serie/Serie.cs index 151e9fb9..695d68f6 100644 --- a/Runtime/Serie/Serie.cs +++ b/Runtime/Serie/Serie.cs @@ -1296,11 +1296,12 @@ public SerieData AddXYData(double xValue, double yValue, string dataName = null, /// /// the unique id of data /// - public SerieData AddData(double open, double close, double lowest, double heighest, string dataName = null, string dataId = null) + public SerieData AddData(double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null) { CheckMaxCache(); var serieData = SerieDataPool.Get(); serieData.data.Clear(); + serieData.data.Add(indexOrTimestamp); serieData.data.Add(open); serieData.data.Add(close); serieData.data.Add(lowest); @@ -1309,7 +1310,7 @@ public SerieData AddData(double open, double close, double lowest, double heighe serieData.index = m_Data.Count; serieData.id = dataId; AddSerieData(serieData); - m_ShowDataDimension = 4; + m_ShowDataDimension = 5; SetVerticesDirty(); CheckDataName(dataName); labelDirty = true; From 48686e865cb5db387e6a100c5de8213dc2621318 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Fri, 26 Aug 2022 23:18:35 +0800 Subject: [PATCH 07/38] [feature][legend] add new icon type:candlestick --- CHANGELOG.md | 1 + Runtime/Component/Legend/Legend.cs | 4 ++ Runtime/Component/Legend/LegendHandler.cs | 55 +++++++++++++---------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 337b06be..22c48741 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.08.26) 增加`Legend`新图标类型`Candlestick` * (2022.08.26) 优化`CandlestickChart`表现,调整相关的`AddData()`接口参数 * (2022.08.26) 增加`Tooltip`的`position`参数支持设置移动平台不同的显示位置 * (2022.08.26) 删除`Tooltip`的`fixedXEnable`和`fixedYEnable`参数 diff --git a/Runtime/Component/Legend/Legend.cs b/Runtime/Component/Legend/Legend.cs index df3e5b46..9b8e53b4 100644 --- a/Runtime/Component/Legend/Legend.cs +++ b/Runtime/Component/Legend/Legend.cs @@ -43,6 +43,10 @@ public enum Type /// 菱形。 /// Diamond, + /// + /// 烛台(可用于K线图)。 + /// + Candlestick, } /// /// Selected mode of legend, which controls whether series can be toggled displaying by clicking legends. diff --git a/Runtime/Component/Legend/LegendHandler.cs b/Runtime/Component/Legend/LegendHandler.cs index 724d5d06..ab3df818 100644 --- a/Runtime/Component/Legend/LegendHandler.cs +++ b/Runtime/Component/Legend/LegendHandler.cs @@ -196,31 +196,34 @@ private void DrawLegend(VertexHelper vh) if (legend.iconType == Legend.Type.Auto) { var serie = chart.GetSerie(item.legendName); - if (serie != null && serie is Line) + if (serie != null) { - var sp = new Vector3(rect.center.x - rect.width / 2, rect.center.y); - var ep = new Vector3(rect.center.x + rect.width / 2, rect.center.y); - UGL.DrawLine(vh, sp, ep, chart.settings.legendIconLineWidth, color); - if (!serie.symbol.show) continue; - switch (serie.symbol.type) + if (serie is Line || serie is SimplifiedLine) { - case SymbolType.None: - continue; - case SymbolType.Circle: - iconType = Legend.Type.Circle; - break; - case SymbolType.Diamond: - iconType = Legend.Type.Diamond; - break; - case SymbolType.EmptyCircle: - iconType = Legend.Type.EmptyCircle; - break; - case SymbolType.Rect: - iconType = Legend.Type.Rect; - break; - case SymbolType.Triangle: - iconType = Legend.Type.Triangle; - break; + var sp = new Vector3(rect.center.x - rect.width / 2, rect.center.y); + var ep = new Vector3(rect.center.x + rect.width / 2, rect.center.y); + UGL.DrawLine(vh, sp, ep, chart.settings.legendIconLineWidth, color); + if (!serie.symbol.show) continue; + switch (serie.symbol.type) + { + case SymbolType.None: + continue; + case SymbolType.Circle: + iconType = Legend.Type.Circle; + break; + case SymbolType.Diamond: + iconType = Legend.Type.Diamond; + break; + case SymbolType.EmptyCircle: + iconType = Legend.Type.EmptyCircle; + break; + case SymbolType.Rect: + iconType = Legend.Type.Rect; + break; + case SymbolType.Triangle: + iconType = Legend.Type.Triangle; + break; + } } } else @@ -249,6 +252,12 @@ private void DrawLegend(VertexHelper vh) case Legend.Type.Triangle: UGL.DrawTriangle(vh, rect.center, 1.2f * radius, color); break; + case Legend.Type.Candlestick: + UGL.DrawRoundRectangle(vh, rect.center, rect.width / 2, rect.height / 2, color, color, + 0, null, false, 0.5f); + UGL.DrawLine(vh, new Vector3(rect.center.x, rect.center.y - rect.height / 2), + new Vector3(rect.center.x, rect.center.y + rect.height / 2), 1, color); + break; } } } From 6ae4468aa26958254591bace121c0c3782df7391 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Sun, 28 Aug 2022 17:34:22 +0800 Subject: [PATCH 08/38] [bug][line] fix linechart error when stack and custom y range. --- CHANGELOG.md | 1 + Runtime/Serie/Line/LineHandler.GridCoord.cs | 13 +++---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22c48741..653c567b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.08.28) 修复`LineChart`在堆叠和自定义Y轴范围的情况下显示不正常的问题 * (2022.08.26) 增加`Legend`新图标类型`Candlestick` * (2022.08.26) 优化`CandlestickChart`表现,调整相关的`AddData()`接口参数 * (2022.08.26) 增加`Tooltip`的`position`参数支持设置移动平台不同的显示位置 diff --git a/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Runtime/Serie/Line/LineHandler.GridCoord.cs index c3760d1c..b5cf3c92 100644 --- a/Runtime/Serie/Line/LineHandler.GridCoord.cs +++ b/Runtime/Serie/Line/LineHandler.GridCoord.cs @@ -372,14 +372,12 @@ private float GetDataPoint(bool isY, Axis axis, Axis relativedAxis, GridCoord gr float xPos, yPos; var gridXY = isY ? grid.context.x : grid.context.y; var valueHig = 0f; + valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue); + valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig); if (isY) { - valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue); - valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig); - xPos = gridXY + valueHig; yPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue); - if (isStack) { for (int n = 0; n < m_StackSerieData.Count - 1; n++) @@ -388,13 +386,8 @@ private float GetDataPoint(bool isY, Axis axis, Axis relativedAxis, GridCoord gr } else { - - valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue); - valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig); - yPos = gridXY + valueHig; xPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue); - if (isStack) { for (int n = 0; n < m_StackSerieData.Count - 1; n++) @@ -402,7 +395,7 @@ private float GetDataPoint(bool isY, Axis axis, Axis relativedAxis, GridCoord gr } } np = new Vector3(xPos, yPos); - return valueHig; + return AxisHelper.GetAxisValueLength(grid, relativedAxis, scaleWid, yValue); } } } \ No newline at end of file From b01c2e4338a453ebd8ab96e6e311795bb88bdfd6 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 29 Aug 2022 21:09:27 +0800 Subject: [PATCH 09/38] [improve][CandlestickChart] improve large data rendering --- CHANGELOG.md | 1 + .../Serie/Candlestick/CandlestickHandler.cs | 58 +++++++++++-------- .../SimplifiedCandlestickHandler.cs | 48 ++++++++------- Runtime/Serie/SerieData.cs | 17 ++++++ Runtime/Serie/SeriesHelper.cs | 15 ++--- 5 files changed, 86 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 653c567b..5a53a262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.08.29) 优化`CandlestickChart`大量数据绘制 * (2022.08.28) 修复`LineChart`在堆叠和自定义Y轴范围的情况下显示不正常的问题 * (2022.08.26) 增加`Legend`新图标类型`Candlestick` * (2022.08.26) 优化`CandlestickChart`表现,调整相关的`AddData()`接口参数 diff --git a/Runtime/Serie/Candlestick/CandlestickHandler.cs b/Runtime/Serie/Candlestick/CandlestickHandler.cs index 3fe8b247..9c98e21b 100644 --- a/Runtime/Serie/Candlestick/CandlestickHandler.cs +++ b/Runtime/Serie/Candlestick/CandlestickHandler.cs @@ -105,6 +105,7 @@ private void DrawCandlestickSerie(VertexHelper vh, Candlestick serie) var isYAxis = false; serie.containerIndex = grid.index; serie.containterInstanceId = grid.instanceId; + var intensive = grid.context.width / (maxCount - serie.minShow) < 0.6f; for (int i = serie.minShow; i < maxCount; i++) { var serieData = showData[i]; @@ -170,37 +171,44 @@ private void DrawCandlestickSerie(VertexHelper vh, Candlestick serie) var heighPos = new Vector3(center.x, zeroY + (float) ((heighest - minCut) / valueTotal * grid.context.height)); var openCenterPos = new Vector3(center.x, prb.y); var closeCenterPos = new Vector3(center.x, prt.y); - if (barWidth > 2f * borderWidth) + if (intensive) { - if (itemWidth > 0 && itemHeight > 0) + UGL.DrawLine(vh, lowPos, heighPos, borderWidth, borderColor); + } + else + { + if (barWidth > 2f * borderWidth) { - if (itemStyle.IsNeedCorner()) + if (itemWidth > 0 && itemHeight > 0) { - UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, + if (itemStyle.IsNeedCorner()) + { + UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, + itemStyle.cornerRadius, isYAxis, 0.5f); + } + else + { + chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, + serie.clip, grid); + } + UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, itemStyle.cornerRadius, isYAxis, 0.5f); } - else - { - chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, - serie.clip, grid); - } - UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, - itemStyle.cornerRadius, isYAxis, 0.5f); } - } - else - { - UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); - } - if (isRise) - { - UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); - } - else - { - UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); + else + { + UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); + } + if (isRise) + { + UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); + UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); + } + else + { + UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); + UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); + } } } if (!serie.animation.IsFinish()) diff --git a/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs b/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs index c10380b7..c6066a42 100644 --- a/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs +++ b/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs @@ -106,7 +106,7 @@ private void DrawCandlestickSerie(VertexHelper vh, SimplifiedCandlestick serie) var itemStyle = serie.itemStyle; serie.containerIndex = grid.index; serie.containterInstanceId = grid.instanceId; - + var intensive = grid.context.width / (maxCount - serie.minShow) < 0.6f; for (int i = serie.minShow; i < maxCount; i++) { var serieData = showData[i]; @@ -170,39 +170,45 @@ private void DrawCandlestickSerie(VertexHelper vh, SimplifiedCandlestick serie) var heighPos = new Vector3(center.x, zeroY + (float) ((heighest - minCut) / valueTotal * grid.context.height)); var openCenterPos = new Vector3(center.x, prb.y); var closeCenterPos = new Vector3(center.x, prt.y); - if (barWidth > 2f * borderWidth) + if (intensive) + { + UGL.DrawLine(vh, lowPos, heighPos, borderWidth, borderColor); + } + else { - if (itemWidth > 0 && itemHeight > 0) + if (barWidth > 2f * borderWidth) { - if (itemStyle.IsNeedCorner()) + if (itemWidth > 0 && itemHeight > 0) { - UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, + if (itemStyle.IsNeedCorner()) + { + UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, + itemStyle.cornerRadius, isYAxis, 0.5f); + } + else + { + chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, + serie.clip, grid); + } + UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, itemStyle.cornerRadius, isYAxis, 0.5f); } + if (isRise) + { + UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); + UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); + } else { - chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, - serie.clip, grid); + UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); + UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); } - UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, - itemStyle.cornerRadius, isYAxis, 0.5f); - } - if (isRise) - { - UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); } else { - UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); + UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); } } - else - { - UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); - } - } if (!serie.animation.IsFinish()) { diff --git a/Runtime/Serie/SerieData.cs b/Runtime/Serie/SerieData.cs index bd43a936..0b0e10bd 100644 --- a/Runtime/Serie/SerieData.cs +++ b/Runtime/Serie/SerieData.cs @@ -478,6 +478,23 @@ public double GetMinData(bool inverse = false) return temp; } + public void GetMinMaxData(int startDimensionIndex, bool inverse, out double min, out double max) + { + if (m_Data.Count == 0) + { + min = 0; + max = 0; + } + min = double.MaxValue; + max = double.MinValue; + for (int i = startDimensionIndex; i < m_Data.Count; i++) + { + var value = GetData(i, inverse); + if (value < min) min = value; + if (value > max) max = value; + } + } + public double GetTotalData() { var total = 0d; diff --git a/Runtime/Serie/SeriesHelper.cs b/Runtime/Serie/SeriesHelper.cs index a4fd0e6e..3e969355 100644 --- a/Runtime/Serie/SeriesHelper.cs +++ b/Runtime/Serie/SeriesHelper.cs @@ -344,19 +344,20 @@ public static void GetMinMaxValue(List series, DataZoom dataZoom, int axi else { var showData = serie.GetDataList(dataZoom); - foreach (var data in showData) + if (serie is Candlestick || serie is SimplifiedCandlestick) { - - if (serie is Candlestick) + foreach (var data in showData) { - var dataMin = data.GetMinData(inverse); - var dataMax = data.GetMaxData(inverse); + double dataMin, dataMax; + data.GetMinMaxData(1, inverse, out dataMin, out dataMax); if (dataMax > max) max = dataMax; if (dataMin < min) min = dataMin; } - else + } + else + { + foreach (var data in showData) { - //var currData = data.GetData(yValue ? 1 : 0, inverse); var currData = data.GetCurrData(yValue ? 1 : 0, updateDuration, inverse); if (!serie.IsIgnoreValue(currData)) { From de16bfad014d24a5b36c3d189a9d252ab85a6293 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 29 Aug 2022 23:00:11 +0800 Subject: [PATCH 10/38] [bug][candlestick] fix tooltip error --- Runtime/Serie/Candlestick/CandlestickHandler.cs | 4 ++-- Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Runtime/Serie/Candlestick/CandlestickHandler.cs b/Runtime/Serie/Candlestick/CandlestickHandler.cs index 9c98e21b..ab401a92 100644 --- a/Runtime/Serie/Candlestick/CandlestickHandler.cs +++ b/Runtime/Serie/Candlestick/CandlestickHandler.cs @@ -54,7 +54,7 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, param.columns.Add(string.Empty); paramList.Add(param); - for (int i = 0; i < 4; i++) + for (int i = 1; i < 5; i++) { param = new SerieParams(); param.serieName = serie.serieName; @@ -71,7 +71,7 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, param.columns.Clear(); param.columns.Add(param.marker); - param.columns.Add(XCSettings.lang.GetCandlestickDimensionName(i)); + param.columns.Add(XCSettings.lang.GetCandlestickDimensionName(i-1)); param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter)); paramList.Add(param); diff --git a/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs b/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs index c6066a42..7362e142 100644 --- a/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs +++ b/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs @@ -54,7 +54,7 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, param.columns.Add(string.Empty); paramList.Add(param); - for (int i = 0; i < 4; i++) + for (int i = 1; i < 5; i++) { param = new SerieParams(); param.serieName = serie.serieName; @@ -71,7 +71,7 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, param.columns.Clear(); param.columns.Add(param.marker); - param.columns.Add(XCSettings.lang.GetCandlestickDimensionName(i)); + param.columns.Add(XCSettings.lang.GetCandlestickDimensionName(i - 1)); param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter)); paramList.Add(param); From 6710a5295070edaaeadd2fff3236fa96f69ff7bd Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 29 Aug 2022 23:00:54 +0800 Subject: [PATCH 11/38] [feature][barchart] bar width --- Runtime/Serie/Serie.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Runtime/Serie/Serie.cs b/Runtime/Serie/Serie.cs index 695d68f6..c5e193ad 100644 --- a/Runtime/Serie/Serie.cs +++ b/Runtime/Serie/Serie.cs @@ -1684,6 +1684,7 @@ public void SetHighlight(int index, bool flag) public float GetBarWidth(float categoryWidth, int barCount = 0) { + if (categoryWidth < 2) return categoryWidth; if (m_BarWidth == 0) { var width = ChartHelper.GetActualValue(0.6f, categoryWidth); From 5f16685b649692b4457e67ce4732ecd532000453 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 29 Aug 2022 23:02:03 +0800 Subject: [PATCH 12/38] [improve][serie] improve min-max data range --- CHANGELOG.md | 2 ++ .../Axis/AngleAxis/AngleAxisHandler.cs | 2 +- .../Axis/RadiusAxis/RadiusAxisHandler.cs | 2 +- Runtime/Component/DataZoom/DataZoomHandler.cs | 4 ++-- Runtime/Internal/BaseChart.Component.cs | 16 +++++++++++++ Runtime/Internal/BaseChart.Custom.cs | 9 ++++---- Runtime/Serie/SeriesHelper.cs | 23 +++++++++++-------- 7 files changed, 39 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a53a262..6f794c70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,8 @@ ## master +* (2022.08.29) 优化`BarChart`在数据过密时的默认表现 +* (2022.08.29) 优化`DataZoom`下Y轴的最大最小值计算 * (2022.08.29) 优化`CandlestickChart`大量数据绘制 * (2022.08.28) 修复`LineChart`在堆叠和自定义Y轴范围的情况下显示不正常的问题 * (2022.08.26) 增加`Legend`新图标类型`Candlestick` diff --git a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs index b57b5a4d..b2c02b48 100644 --- a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs +++ b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs @@ -29,7 +29,7 @@ private void UpdateAxisMinMaxValue(AngleAxis axis, bool updateChart = true) if (axis.IsCategory() || !axis.show) return; double tempMinValue = 0; double tempMaxValue = 0; - SeriesHelper.GetYMinMaxValue(chart.series, null, axis.polarIndex, true, axis.inverse, out tempMinValue, + SeriesHelper.GetYMinMaxValue(chart, axis.polarIndex, true, axis.inverse, out tempMinValue, out tempMaxValue, true); AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue) diff --git a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs index 4e295923..4ea89808 100644 --- a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs +++ b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs @@ -50,7 +50,7 @@ private void UpdateAxisMinMaxValue(RadiusAxis axis, bool updateChart = true) if (axis.IsCategory() || !axis.show) return; double tempMinValue = 0; double tempMaxValue = 0; - SeriesHelper.GetXMinMaxValue(chart.series, null, axis.polarIndex, true, axis.inverse, out tempMinValue, + SeriesHelper.GetXMinMaxValue(chart, axis.polarIndex, true, axis.inverse, out tempMinValue, out tempMaxValue, true); AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue) diff --git a/Runtime/Component/DataZoom/DataZoomHandler.cs b/Runtime/Component/DataZoom/DataZoomHandler.cs index aa9e7644..be6854ad 100644 --- a/Runtime/Component/DataZoom/DataZoomHandler.cs +++ b/Runtime/Component/DataZoom/DataZoomHandler.cs @@ -464,7 +464,7 @@ private void DrawHorizonalDataZoomSlider(VertexHelper vh, DataZoom dataZoom) Vector3 np = Vector3.zero; double minValue = 0; double maxValue = 0; - SeriesHelper.GetYMinMaxValue(chart.series, null, 0, chart.IsAllAxisValue(), axis.inverse, out minValue, out maxValue); + SeriesHelper.GetYMinMaxValue(chart, 0, chart.IsAllAxisValue(), axis.inverse, out minValue, out maxValue, false, false); AxisHelper.AdjustMinMaxValue(axis, ref minValue, ref maxValue, true); int rate = 1; @@ -553,7 +553,7 @@ private void DrawVerticalDataZoomSlider(VertexHelper vh, DataZoom dataZoom) Vector3 np = Vector3.zero; double minValue = 0; double maxValue = 0; - SeriesHelper.GetYMinMaxValue(chart.series, null, 0, chart.IsAllAxisValue(), axis.inverse, out minValue, out maxValue); + SeriesHelper.GetYMinMaxValue(chart, 0, chart.IsAllAxisValue(), axis.inverse, out minValue, out maxValue); AxisHelper.AdjustMinMaxValue(axis, ref minValue, ref maxValue, true); int rate = 1; diff --git a/Runtime/Internal/BaseChart.Component.cs b/Runtime/Internal/BaseChart.Component.cs index 8e19c4d5..fdf14c28 100644 --- a/Runtime/Internal/BaseChart.Component.cs +++ b/Runtime/Internal/BaseChart.Component.cs @@ -349,6 +349,22 @@ public void GetDataZoomOfSerie(Serie serie, out DataZoom xDataZoom, out DataZoom } } + public DataZoom GetXDataZoomOfSerie(Serie serie) + { + if (serie == null) return null; + foreach (var component in m_Components) + { + if (component is DataZoom) + { + var dataZoom = component as DataZoom; + if (!dataZoom.enable) continue; + if (dataZoom.IsContainsXAxis(serie.xAxisIndex)) + return dataZoom; + } + } + return null; + } + /// /// reutrn true when all the show axis is `Value` type. /// |纯数值坐标轴(数值轴或对数轴)。 diff --git a/Runtime/Internal/BaseChart.Custom.cs b/Runtime/Internal/BaseChart.Custom.cs index cbd04dad..f9c110fb 100644 --- a/Runtime/Internal/BaseChart.Custom.cs +++ b/Runtime/Internal/BaseChart.Custom.cs @@ -6,8 +6,7 @@ namespace XCharts.Runtime { public partial class BaseChart { - public virtual void InitAxisRuntimeData(Axis axis) - { } + public virtual void InitAxisRuntimeData(Axis axis) { } public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue) { @@ -15,16 +14,16 @@ public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double te { if (axis is XAxis) { - SeriesHelper.GetXMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue); + SeriesHelper.GetXMinMaxValue(this, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue); } else { - SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue); + SeriesHelper.GetYMinMaxValue(this, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue); } } else { - SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, false, axis.inverse, out tempMinValue, out tempMaxValue); + SeriesHelper.GetYMinMaxValue(this, axisIndex, false, axis.inverse, out tempMinValue, out tempMaxValue); } AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); } diff --git a/Runtime/Serie/SeriesHelper.cs b/Runtime/Serie/SeriesHelper.cs index 3e969355..c2bb721f 100644 --- a/Runtime/Serie/SeriesHelper.cs +++ b/Runtime/Serie/SeriesHelper.cs @@ -300,10 +300,10 @@ public static void UpdateStackDataList(List series, Serie currSerie, Data /// /// /// - public static void GetXMinMaxValue(List series, DataZoom dataZoom, int axisIndex, bool isValueAxis, - bool inverse, out double minVaule, out double maxValue, bool isPolar = false) + public static void GetXMinMaxValue(BaseChart chart, int axisIndex, bool isValueAxis, + bool inverse, out double minVaule, out double maxValue, bool isPolar = false, bool filterByDataZoom = true) { - GetMinMaxValue(series, dataZoom, axisIndex, isValueAxis, inverse, false, out minVaule, out maxValue, isPolar); + GetMinMaxValue(chart, axisIndex, isValueAxis, inverse, false, out minVaule, out maxValue, isPolar, filterByDataZoom); } /// @@ -313,19 +313,22 @@ public static void GetXMinMaxValue(List series, DataZoom dataZoom, int ax /// /// /// - public static void GetYMinMaxValue(List series, DataZoom dataZoom, int axisIndex, bool isValueAxis, - bool inverse, out double minVaule, out double maxValue, bool isPolar = false) + public static void GetYMinMaxValue(BaseChart chart, int axisIndex, bool isValueAxis, + bool inverse, out double minVaule, out double maxValue, bool isPolar = false, bool filterByDataZoom = true) { - GetMinMaxValue(series, dataZoom, axisIndex, isValueAxis, inverse, true, out minVaule, out maxValue, isPolar); + GetMinMaxValue(chart, axisIndex, isValueAxis, inverse, true, out minVaule, out maxValue, isPolar, filterByDataZoom); } private static Dictionary> _stackSeriesForMinMax = new Dictionary>(); private static Dictionary _serieTotalValueForMinMax = new Dictionary(); - public static void GetMinMaxValue(List series, DataZoom dataZoom, int axisIndex, bool isValueAxis, - bool inverse, bool yValue, out double minVaule, out double maxValue, bool isPolar = false) + private static DataZoom xDataZoom, yDataZoom; + public static void GetMinMaxValue(BaseChart chart, int axisIndex, bool isValueAxis, + bool inverse, bool yValue, out double minVaule, out double maxValue, bool isPolar = false, + bool filterByDataZoom = true) { double min = double.MaxValue; double max = double.MinValue; + var series = chart.series; var isPercentStack = SeriesHelper.IsPercentStack(series); if (!SeriesHelper.IsStack(series) || (isValueAxis && !yValue)) { @@ -343,7 +346,7 @@ public static void GetMinMaxValue(List series, DataZoom dataZoom, int axi } else { - var showData = serie.GetDataList(dataZoom); + var showData = serie.GetDataList(filterByDataZoom?chart.GetXDataZoomOfSerie(serie) : null); if (serie is Candlestick || serie is SimplifiedCandlestick) { foreach (var data in showData) @@ -381,7 +384,7 @@ public static void GetMinMaxValue(List series, DataZoom dataZoom, int axi if ((isPolar && serie.polarIndex != axisIndex) || (!isPolar && serie.yAxisIndex != axisIndex) || !serie.show) continue; - var showData = serie.GetDataList(dataZoom); + var showData = serie.GetDataList(filterByDataZoom?chart.GetXDataZoomOfSerie(serie) : null); if (SeriesHelper.IsPercentStack(series, serie.stack)) { for (int j = 0; j < showData.Count; j++) From 027f5f260cb66bb414fb3a86a933e5c46afd7805 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Tue, 30 Aug 2022 08:04:18 +0800 Subject: [PATCH 13/38] [bug][datazoom] fix datazoom range error (#221) --- CHANGELOG.md | 3 ++- Runtime/Component/Axis/AxisContext.cs | 8 ++++---- Runtime/Serie/SerieHelper.cs | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f794c70..b7d156c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,8 +58,9 @@ ## master +* (2022.08.30) 修复`DataZoom`某些情况下计算范围不准确的问题 (#221) * (2022.08.29) 优化`BarChart`在数据过密时的默认表现 -* (2022.08.29) 优化`DataZoom`下Y轴的最大最小值计算 +* (2022.08.29) 优化`YAxis`在开启`DataZoom`时的最大最小值计算 * (2022.08.29) 优化`CandlestickChart`大量数据绘制 * (2022.08.28) 修复`LineChart`在堆叠和自定义Y轴范围的情况下显示不正常的问题 * (2022.08.26) 增加`Legend`新图标类型`Candlestick` diff --git a/Runtime/Component/Axis/AxisContext.cs b/Runtime/Component/Axis/AxisContext.cs index 5a50c1e4..fcc5a768 100644 --- a/Runtime/Component/Axis/AxisContext.cs +++ b/Runtime/Component/Axis/AxisContext.cs @@ -92,13 +92,13 @@ internal void UpdateFilterData(List data, DataZoom dataZoom) if (dataZoom.context.invert) { - end = Mathf.CeilToInt(data.Count * dataZoom.end / 100); + end = Mathf.RoundToInt(data.Count * dataZoom.end / 100); start = end - range; if (start < 0) start = 0; } else { - start = Mathf.FloorToInt(data.Count * dataZoom.start / 100); + start = Mathf.RoundToInt(data.Count * dataZoom.start / 100); end = start + range; if (end > data.Count) end = data.Count; } @@ -122,8 +122,8 @@ internal void UpdateFilterData(List data, DataZoom dataZoom) else range = dataZoom.minShowNum; } - if (range > data.Count - start - 1) - start = data.Count - range - 1; + if (range > data.Count - start) + start = data.Count - range; if (start >= 0) { dataZoomStartIndex = start; diff --git a/Runtime/Serie/SerieHelper.cs b/Runtime/Serie/SerieHelper.cs index e9e77d9c..7e7491f8 100644 --- a/Runtime/Serie/SerieHelper.cs +++ b/Runtime/Serie/SerieHelper.cs @@ -821,13 +821,13 @@ private static void UpdateFilterData_Category(Serie serie, DataZoom dataZoom) int start = 0, end = 0; if (dataZoom.context.invert) { - end = Mathf.CeilToInt(data.Count * dataZoom.end / 100); + end = Mathf.RoundToInt(data.Count * dataZoom.end / 100); start = end - range; if (start < 0) start = 0; } else { - start = Mathf.FloorToInt(data.Count * dataZoom.start / 100); + start = Mathf.RoundToInt(data.Count * dataZoom.start / 100); end = start + range; if (end > data.Count) end = data.Count; } @@ -845,8 +845,8 @@ private static void UpdateFilterData_Category(Serie serie, DataZoom dataZoom) if (dataZoom.minShowNum > data.Count) range = data.Count; else range = dataZoom.minShowNum; } - if (range > data.Count - start - 1) - start = data.Count - range - 1; + if (range > data.Count - start) + start = data.Count - range; if (start >= 0) { serie.context.dataZoomStartIndex = start; From 061ac4967040e8a19722b441e61095eaff5cd02f Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Wed, 31 Aug 2022 22:03:51 +0800 Subject: [PATCH 14/38] [improve][radar]improve radar chart --- CHANGELOG.md | 3 ++- Runtime/Component/Radar/RadarCoord.cs | 11 +++++++++-- Runtime/Component/Radar/RadarCoordHandler.cs | 1 + Runtime/Serie/Radar/Radar.cs | 2 +- Runtime/Serie/Radar/RadarHandler.cs | 1 - 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7d156c8..7a9b2fcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,8 @@ ## master -* (2022.08.30) 修复`DataZoom`某些情况下计算范围不准确的问题 (#221) +* (2022.08.30) 优化`RadarChart` +* (2022.08.30) 修复`DataZoom`在某些情况下计算范围不准确的问题 (#221) * (2022.08.29) 优化`BarChart`在数据过密时的默认表现 * (2022.08.29) 优化`YAxis`在开启`DataZoom`时的最大最小值计算 * (2022.08.29) 优化`CandlestickChart`大量数据绘制 diff --git a/Runtime/Component/Radar/RadarCoord.cs b/Runtime/Component/Radar/RadarCoord.cs index 5b0cb039..0af7d4be 100644 --- a/Runtime/Component/Radar/RadarCoord.cs +++ b/Runtime/Component/Radar/RadarCoord.cs @@ -385,7 +385,7 @@ public void AddIndicator(RadarCoord.Indicator indicator) SetAllDirty(); } - public RadarCoord.Indicator AddIndicator(string name, float min, float max) + public RadarCoord.Indicator AddIndicator(string name, double min, double max) { var indicator = new RadarCoord.Indicator(); indicator.name = name; @@ -396,7 +396,14 @@ public RadarCoord.Indicator AddIndicator(string name, float min, float max) return indicator; } - public bool UpdateIndicator(int indicatorIndex, string name, float min, float max) + [Since("v3.3.0")] + public void AddIndicatorList(List nameList, double min = 0, double max = 0) + { + foreach (var name in nameList) + AddIndicator(name, min, max); + } + + public bool UpdateIndicator(int indicatorIndex, string name, double min, double max) { var indicator = GetIndicator(indicatorIndex); if (indicator == null) return false; diff --git a/Runtime/Component/Radar/RadarCoordHandler.cs b/Runtime/Component/Radar/RadarCoordHandler.cs index 4c72ccb8..18adea9b 100644 --- a/Runtime/Component/Radar/RadarCoordHandler.cs +++ b/Runtime/Component/Radar/RadarCoordHandler.cs @@ -87,6 +87,7 @@ private void DrawCricleRadar(VertexHelper vh, RadarCoord radar) var lineType = radar.axisLine.GetType(chart.theme.axis.lineType); var splitLineColor = radar.splitLine.GetColor(chart.theme.axis.splitLineColor); var splitLineWidth = radar.splitLine.GetWidth(chart.theme.axis.splitLineWidth); + splitLineWidth *= 2f; for (int i = 0; i < radar.splitNumber; i++) { var color = radar.splitArea.GetColor(i, chart.theme.axis); diff --git a/Runtime/Serie/Radar/Radar.cs b/Runtime/Serie/Radar/Radar.cs index 924669e4..4aa23261 100644 --- a/Runtime/Serie/Radar/Radar.cs +++ b/Runtime/Serie/Radar/Radar.cs @@ -25,7 +25,7 @@ public bool smooth public int containerIndex { get; internal set; } public int containterInstanceId { get; internal set; } - public override SerieColorBy defaultColorBy { get { return radarType == RadarType.Multiple?SerieColorBy.Serie : SerieColorBy.Data; } } + public override SerieColorBy defaultColorBy { get { return radarType == RadarType.Multiple?SerieColorBy.Data : SerieColorBy.Serie; } } public override bool multiDimensionLabel { get { return radarType == RadarType.Multiple; } } public static Serie AddDefaultSerie(BaseChart chart, string serieName) diff --git a/Runtime/Serie/Radar/RadarHandler.cs b/Runtime/Serie/Radar/RadarHandler.cs index c01e80bf..73ad790f 100644 --- a/Runtime/Serie/Radar/RadarHandler.cs +++ b/Runtime/Serie/Radar/RadarHandler.cs @@ -320,7 +320,6 @@ private void DrawMutipleRadar(VertexHelper vh) serieData.interact.SetValue(ref interacting, symbolSize); symbolSize = serie.animation.GetSysmbolSize(symbolSize); } - colorIndex = serie.colorByData ? m : colorIndex; SerieHelper.GetItemColor(out symbolColor, out symbolToColor, out symbolEmptyColor, serie, serieData, chart.theme, colorIndex, serieState); SerieHelper.GetSymbolInfo(out borderColor, out symbolBorder, out cornerRadius, serie, serieData, chart.theme, serieState); chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, point, symbolColor, From 8bd0c23e193c7d5db74e3bfd119bbb64a136bdb7 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Fri, 2 Sep 2022 08:12:57 +0800 Subject: [PATCH 15/38] [improve][heatmap] improve heatmap chart --- CHANGELOG.md | 1 + Runtime/Chart/HeatmapChart.cs | 9 ++----- Runtime/Component/Tooltip/TooltipHandler.cs | 26 +++++++++++++++++-- Runtime/Component/VisualMap/VisualMap.cs | 8 +++--- .../Component/VisualMap/VisualMapContext.cs | 2 ++ .../Component/VisualMap/VisualMapHelper.cs | 12 ++++----- Runtime/Serie/Heatmap/Heatmap.cs | 6 ----- Runtime/Serie/Heatmap/HeatmapHandler.cs | 23 ++++++++++------ 8 files changed, 54 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a9b2fcf..5b3ea8f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.02) 优化`HeatmapChart` * (2022.08.30) 优化`RadarChart` * (2022.08.30) 修复`DataZoom`在某些情况下计算范围不准确的问题 (#221) * (2022.08.29) 优化`BarChart`在数据过密时的默认表现 diff --git a/Runtime/Chart/HeatmapChart.cs b/Runtime/Chart/HeatmapChart.cs index 421ae09e..f1df5f11 100644 --- a/Runtime/Chart/HeatmapChart.cs +++ b/Runtime/Chart/HeatmapChart.cs @@ -36,9 +36,7 @@ protected override void DefaultChart() Heatmap.AddDefaultSerie(this, GenerateDefaultSerieName()); var visualMap = GetOrAddChartComponent(); - visualMap.max = 10; - visualMap.range[0] = 0f; - visualMap.range[1] = 10f; + visualMap.autoMinMax = true; visualMap.orient = Orient.Vertical; visualMap.calculable = true; visualMap.location.align = Location.Align.BottomLeft; @@ -71,10 +69,7 @@ protected override void DefaultChart() { for (int j = 0; j < ySplitNumber; j++) { - var value = 0f; - var rate = Random.Range(0, 101); - if (rate > 70) value = Random.Range(8f, 10f); - else value = Random.Range(1f, 8f); + var value = Random.Range(0, 150); var list = new List { i, j, value }; AddData(0, list); } diff --git a/Runtime/Component/Tooltip/TooltipHandler.cs b/Runtime/Component/Tooltip/TooltipHandler.cs index a03205a6..ba6b4526 100644 --- a/Runtime/Component/Tooltip/TooltipHandler.cs +++ b/Runtime/Component/Tooltip/TooltipHandler.cs @@ -241,7 +241,11 @@ private ISerieContainer GetPointerContainerAndSeries(Tooltip tooltip, List series) { var serie = series[i]; serie.context.isTriggerByAxis = isTriggerByAxis; - if (isTriggerByAxis && dataIndex >= 0) + if (isTriggerByAxis && dataIndex >= 0 && serie.context.pointerItemDataIndex < 0) serie.context.pointerItemDataIndex = dataIndex; serie.handler.UpdateTooltipSerieParams(dataIndex, showCategory, category, tooltip.marker, tooltip.itemFormatter, tooltip.numericFormatter, diff --git a/Runtime/Component/VisualMap/VisualMap.cs b/Runtime/Component/VisualMap/VisualMap.cs index 165aa809..69a0a786 100644 --- a/Runtime/Component/VisualMap/VisualMap.cs +++ b/Runtime/Component/VisualMap/VisualMap.cs @@ -81,9 +81,9 @@ public enum SelectedMode [SerializeField] private SelectedMode m_SelectedMode = SelectedMode.Multiple; [SerializeField] private int m_SerieIndex = 0; [SerializeField] private double m_Min = 0; - [SerializeField] private double m_Max = 100; + [SerializeField] private double m_Max = 0; - [SerializeField] private double[] m_Range = new double[2] { 0, 100 }; + [SerializeField] private double[] m_Range = new double[2] { 0, 0 }; [SerializeField] private string[] m_Text = new string[2] { "", "" }; [SerializeField] private float[] m_TextGap = new float[2] { 10f, 10f }; [SerializeField] private int m_SplitNumber = 5; @@ -364,7 +364,8 @@ public double rangeMin { get { - if (m_Range[0] < min || m_Range[0] > max) return min; + if (m_Range[0] == 0 && m_Range[1] == 0) return min; + else if (m_Range[0] < min || m_Range[0] > max) return min; else return m_Range[0]; } set @@ -377,6 +378,7 @@ public double rangeMax { get { + if (m_Range[0] == 0 && m_Range[1] == 0) return max; if (m_Range[1] >= m_Range[0] && m_Range[1] < max) return m_Range[1]; else return max; } diff --git a/Runtime/Component/VisualMap/VisualMapContext.cs b/Runtime/Component/VisualMap/VisualMapContext.cs index 730b537d..afba42a2 100644 --- a/Runtime/Component/VisualMap/VisualMapContext.cs +++ b/Runtime/Component/VisualMap/VisualMapContext.cs @@ -12,6 +12,8 @@ public class VisualMapContext : MainComponentContext public double pointerValue { get; set; } public bool minDrag { get; internal set; } public bool maxDrag { get; internal set; } + public double min { get; set; } + public double max { get; set; } internal List inRangeColors = new List(); diff --git a/Runtime/Component/VisualMap/VisualMapHelper.cs b/Runtime/Component/VisualMap/VisualMapHelper.cs index 6351dea4..406b2bf5 100644 --- a/Runtime/Component/VisualMap/VisualMapHelper.cs +++ b/Runtime/Component/VisualMap/VisualMapHelper.cs @@ -177,15 +177,13 @@ public static bool IsNeedAreaGradient(VisualMap visualMap) return true; } - public static int GetDimension(VisualMap visualMap, int serieDataCount) + public static int GetDimension(VisualMap visualMap, int defaultDimension) { - var dimension = visualMap != null && visualMap.dimension >= 0 ? - visualMap.dimension : serieDataCount - 1; + if (visualMap == null || !visualMap.show) + return defaultDimension; - if (dimension > serieDataCount - 1) - dimension = serieDataCount - 1; - - return dimension; + return visualMap != null && visualMap.dimension >= 0 ? + visualMap.dimension : defaultDimension; } } } \ No newline at end of file diff --git a/Runtime/Serie/Heatmap/Heatmap.cs b/Runtime/Serie/Heatmap/Heatmap.cs index ea1ccd72..ec4fc180 100644 --- a/Runtime/Serie/Heatmap/Heatmap.cs +++ b/Runtime/Serie/Heatmap/Heatmap.cs @@ -19,12 +19,6 @@ public static Serie AddDefaultSerie(BaseChart chart, string serieName) serie.itemStyle.show = true; serie.itemStyle.borderWidth = 1; serie.itemStyle.borderColor = Color.clear; - - var emphasis = serie.AddExtraComponent(); - emphasis.show = true; - emphasis.itemStyle.show = true; - emphasis.itemStyle.borderWidth = 1; - emphasis.itemStyle.borderColor = Color.black; return serie; } } diff --git a/Runtime/Serie/Heatmap/HeatmapHandler.cs b/Runtime/Serie/Heatmap/HeatmapHandler.cs index 806908b2..7f69c9cc 100644 --- a/Runtime/Serie/Heatmap/HeatmapHandler.cs +++ b/Runtime/Serie/Heatmap/HeatmapHandler.cs @@ -34,6 +34,8 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, var serieData = serie.GetSerieData(dataIndex); if (serieData == null) return; + var visualMap = chart.GetVisualMapOfSerie(serie); + var dimension = VisualMapHelper.GetDimension(visualMap, defaultDimension); if (string.IsNullOrEmpty(category)) { @@ -41,13 +43,12 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, if (xAxis != null) category = xAxis.GetData((int) serieData.GetData(0)); } - title = serie.serieName; var param = serie.context.param; param.serieName = serie.serieName; param.serieIndex = serie.index; - param.dimension = defaultDimension; + param.dimension = dimension; param.dataCount = serie.dataCount; param.serieData = serieData; param.color = serieData.context.color; @@ -58,7 +59,7 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, param.columns.Add(param.marker); param.columns.Add(category); - param.columns.Add(ChartCached.NumberToStr(serieData.GetData(defaultDimension), param.numericFormatter)); + param.columns.Add(ChartCached.NumberToStr(serieData.GetData(dimension), param.numericFormatter)); paramList.Add(param); } @@ -121,7 +122,7 @@ private void UpdateSerieContext() private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie) { - if (serie.animation.HasFadeOut()) return; + if (!serie.show || serie.animation.HasFadeOut()) return; XAxis xAxis; YAxis yAxis; if (!chart.TryGetChartComponent(out xAxis, serie.xAxisIndex)) return; @@ -138,8 +139,6 @@ private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie) var zeroX = m_SerieGrid.context.x; var zeroY = m_SerieGrid.context.y; - var rangeMin = visualMap.rangeMin; - var rangeMax = visualMap.rangeMax; var color = chart.theme.GetColor(serie.index); var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0; var rectWid = xWidth - 2 * borderWidth; @@ -161,12 +160,21 @@ private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie) var dataChanging = false; serie.containerIndex = m_SerieGrid.index; serie.containterInstanceId = m_SerieGrid.instanceId; + + var dimension = VisualMapHelper.GetDimension(visualMap, defaultDimension); + if (visualMap.autoMinMax) + { + double maxValue, minValue; + SerieHelper.GetMinMaxData(serie, dimension, out minValue, out maxValue); + VisualMapHelper.SetMinMax(visualMap, minValue, maxValue); + } + var rangeMin = visualMap.rangeMin; + var rangeMax = visualMap.rangeMax; for (int n = 0; n < serie.dataCount; n++) { var serieData = serie.data[n]; var i = (int) serieData.GetData(0); var j = (int) serieData.GetData(1); - var dimension = VisualMapHelper.GetDimension(visualMap, serieData.data.Count); if (serie.IsIgnoreValue(serieData, dimension)) { serie.context.dataPoints.Add(Vector3.zero); @@ -184,7 +192,6 @@ private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie) serieData.context.canShowLabel = false; serieData.context.rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); - if (value == 0) continue; if ((value < rangeMin && rangeMin != visualMap.min) || (value > rangeMax && rangeMax != visualMap.max)) { From a44eca0f9139373c23c64e7ca7ba2ca46123a5af Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Fri, 2 Sep 2022 08:33:34 +0800 Subject: [PATCH 16/38] [feature][pie] support `onPointerEnterPie` --- CHANGELOG.md | 1 + Runtime/Internal/BaseChart.API.cs | 8 +++++++- Runtime/Internal/BaseChart.cs | 1 + Runtime/Serie/Pie/PieHandler.cs | 15 ++++++++++++++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b3ea8f1..ea92c446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.02) 增加`onPointerEnterPie`回调支持 * (2022.09.02) 优化`HeatmapChart` * (2022.08.30) 优化`RadarChart` * (2022.08.30) 修复`DataZoom`在某些情况下计算范围不准确的问题 (#221) diff --git a/Runtime/Internal/BaseChart.API.cs b/Runtime/Internal/BaseChart.API.cs index c0034efb..db3b70f9 100644 --- a/Runtime/Internal/BaseChart.API.cs +++ b/Runtime/Internal/BaseChart.API.cs @@ -96,11 +96,17 @@ public string chartName /// public CustomDrawGaugePointerFunction customDrawGaugePointerFunction { set { m_CustomDrawGaugePointerFunction = value; } get { return m_CustomDrawGaugePointerFunction; } } /// - /// the callback function of click pie area. + /// the callback function of pointer click pie area. /// |点击饼图区域回调。参数:PointerEventData,SerieIndex,SerieDataIndex /// public Action onPointerClickPie { set { m_OnPointerClickPie = value; m_ForceOpenRaycastTarget = true; } get { return m_OnPointerClickPie; } } /// + /// the callback function of pointer enter pie area. + /// |鼠标进入和离开饼图区域回调,SerieDataIndex为-1时表示离开。参数:PointerEventData,SerieIndex,SerieDataIndex + /// + [Since("v3.3.0")] + public Action onPointerEnterPie { set { m_OnPointerEnterPie = value; m_ForceOpenRaycastTarget = true; } get { return m_OnPointerEnterPie; } } + /// /// the callback function of click bar. /// |点击柱形图柱条回调。参数:eventData, dataIndex /// diff --git a/Runtime/Internal/BaseChart.cs b/Runtime/Internal/BaseChart.cs index fdbf414e..3aa80d66 100644 --- a/Runtime/Internal/BaseChart.cs +++ b/Runtime/Internal/BaseChart.cs @@ -86,6 +86,7 @@ public partial class BaseChart : BaseGraph, ISerializationCallbackReceiver protected Action m_OnDrawSerieBefore; protected Action m_OnDrawSerieAfter; protected Action m_OnPointerClickPie; + protected Action m_OnPointerEnterPie; protected Action m_OnPointerClickBar; protected Action m_OnAxisPointerValueChanged; protected Action m_OnLegendClick; diff --git a/Runtime/Serie/Pie/PieHandler.cs b/Runtime/Serie/Pie/PieHandler.cs index 966ebe01..3be3b1c9 100644 --- a/Runtime/Serie/Pie/PieHandler.cs +++ b/Runtime/Serie/Pie/PieHandler.cs @@ -123,6 +123,10 @@ private void UpdateSerieContext() serieData.context.highlight = false; serieData.interact.SetValueAndColor(ref needInteract, serieData.context.outsideRadius, color, toColor); } + if (chart.onPointerEnterPie != null) + { + chart.onPointerEnterPie(serie.index, serie.context.pointerItemDataIndex); + } if (needInteract) { chart.RefreshPainter(serie); @@ -131,8 +135,9 @@ private void UpdateSerieContext() return; } m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; + var lastPointerItemDataIndex = serie.context.pointerItemDataIndex; var dataIndex = GetPiePosIndex(serie, chart.pointerPos); + serie.context.pointerItemDataIndex = -1; for (int i = 0; i < serie.dataCount; i++) { var serieData = serie.data[i]; @@ -154,6 +159,14 @@ private void UpdateSerieContext() serieData.interact.SetValueAndColor(ref needInteract, serieData.context.outsideRadius, color, toColor); } } + if (lastPointerItemDataIndex != serie.context.pointerItemDataIndex) + { + needInteract = true; + if (chart.onPointerEnterPie != null) + { + chart.onPointerEnterPie(serie.index, serie.context.pointerItemDataIndex); + } + } if (needInteract) { chart.RefreshPainter(serie); From ce702fd1e3d60e5aee02784c9e2b53d5028a2635 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 5 Sep 2022 13:18:00 +0800 Subject: [PATCH 17/38] [improve][tooltip] improve tooltip for heatmap --- CHANGELOG.md | 1 + Runtime/Component/Axis/Axis.cs | 2 + Runtime/Component/Axis/AxisHelper.cs | 50 +++++++++++++++++++-- Runtime/Component/Tooltip/TooltipHandler.cs | 10 ++--- Runtime/Serie/Heatmap/HeatmapHandler.cs | 15 ++++--- Runtime/Serie/SerieHelper.cs | 10 +++++ 6 files changed, 73 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea92c446..762e3cdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.05) 优化`Tooltip`在热力图为数值轴时的指示 * (2022.09.02) 增加`onPointerEnterPie`回调支持 * (2022.09.02) 优化`HeatmapChart` * (2022.08.30) 优化`RadarChart` diff --git a/Runtime/Component/Axis/Axis.cs b/Runtime/Component/Axis/Axis.cs index 46bbb8e5..1a988b1f 100644 --- a/Runtime/Component/Axis/Axis.cs +++ b/Runtime/Component/Axis/Axis.cs @@ -719,6 +719,8 @@ public float GetValueLength(double value, float axisLength) } } + + /// /// 获得指定区域缩放的类目数据列表 /// diff --git a/Runtime/Component/Axis/AxisHelper.cs b/Runtime/Component/Axis/AxisHelper.cs index e24be302..73c96f5d 100644 --- a/Runtime/Component/Axis/AxisHelper.cs +++ b/Runtime/Component/Axis/AxisHelper.cs @@ -19,6 +19,24 @@ public static float GetAxisLineArrowOffset(Axis axis) return 0; } + /// + /// 获得分割网格个数,包含次刻度 + /// + /// + /// + public static int GetTotalSplitGridNum(Axis axis) + { + if (axis.IsCategory()) + return axis.data.Count; + else + { + var splitNum = axis.splitNumber <= 0 ? GetSplitNumber(axis, 0, null) : axis.splitNumber; + return axis.minorTick.show ? + splitNum * axis.minorTick.splitNumber : + splitNum; + } + } + /// /// 获得分割段数 /// @@ -519,6 +537,34 @@ public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWid return GetAxisPositionInternal(grid, axis, scaleWidth, value, false, true); } + /// + /// 获得数值value在坐标轴上对应的split索引 + /// + /// + /// + /// + public static int GetAxisValueSplitIndex(Axis axis, double value, int totalSplitNumber = -1) + { + if (axis.IsCategory()) + { + return (int) value; + } + else + { + if (value == axis.context.minValue) + return 0; + else + { + if (totalSplitNumber == -1) + totalSplitNumber = GetTotalSplitGridNum(axis); + if (axis.minMaxType == Axis.AxisMinMaxType.Custom) + return Mathf.CeilToInt(((float) ((value - axis.min) / axis.max) * totalSplitNumber) - 1); + else + return Mathf.CeilToInt(((float) ((value - axis.context.minValue) / axis.context.minMaxRange) * totalSplitNumber) - 1); + } + } + } + private static float GetAxisPositionInternal(GridCoord grid, Axis axis, float scaleWidth, double value, bool includeGridXY, bool realLength) { var isY = axis is YAxis; @@ -589,9 +635,5 @@ public static float GetYAxisXOrY(GridCoord grid, Axis yAxis, Axis relativedAxis) startX += relativedAxis.context.offset; return startX; } - - public static void UpdateAxisOffset(){ - - } } } \ No newline at end of file diff --git a/Runtime/Component/Tooltip/TooltipHandler.cs b/Runtime/Component/Tooltip/TooltipHandler.cs index ba6b4526..2520cd79 100644 --- a/Runtime/Component/Tooltip/TooltipHandler.cs +++ b/Runtime/Component/Tooltip/TooltipHandler.cs @@ -241,7 +241,7 @@ private ISerieContainer GetPointerContainerAndSeries(Tooltip tooltip, List @@ -180,6 +185,11 @@ public static void GetMinMaxData(Serie serie, out double min, out double max, Da } } } + if (min == double.MaxValue && max == double.MinValue) + { + min = 0; + max = 0; + } } /// From ccc5110e8e983082d0715b5fa4d896e0514dd6b2 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Tue, 6 Sep 2022 07:22:04 +0800 Subject: [PATCH 18/38] [feature][heatmap] support `heatmapType` --- CHANGELOG.md | 1 + Documentation/XChartsAPI-EN.md | 10 +- Documentation/XChartsAPI-ZH.md | 10 +- Documentation/XChartsConfiguration-EN.md | 7 +- Documentation/XChartsConfiguration-ZH.md | 7 +- Editor/Series/HeatmapEditor.cs | 1 + Runtime/Component/Axis/AxisHelper.cs | 4 +- Runtime/Component/Tooltip/TooltipHandler.cs | 14 +- Runtime/Serie/Heatmap/Heatmap.cs | 30 +++ Runtime/Serie/Heatmap/HeatmapHandler.cs | 246 +++++++++++++++++--- 10 files changed, 281 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 762e3cdb..c8d2b236 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.05) 增加`Heatmap`的`heatmapType`支持设置`Data`和`Count`两种不同映射方式的热力图 * (2022.09.05) 优化`Tooltip`在热力图为数值轴时的指示 * (2022.09.02) 增加`onPointerEnterPie`回调支持 * (2022.09.02) 优化`HeatmapChart` diff --git a/Documentation/XChartsAPI-EN.md b/Documentation/XChartsAPI-EN.md index f09576c8..931cd18f 100644 --- a/Documentation/XChartsAPI-EN.md +++ b/Documentation/XChartsAPI-EN.md @@ -130,12 +130,14 @@ Inherits or Implemented: [MainComponentHandler](#MainComponentHandler) | `GetAxisValueDistance()` |public static float GetAxisValueDistance(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上相对起点的距离 | | `GetAxisValueLength()` |public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上对应的长度 | | `GetAxisValuePosition()` |public static float GetAxisValuePosition(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上的坐标位置 | +| `GetAxisValueSplitIndex()` |public static int GetAxisValueSplitIndex(Axis axis, double value, int totalSplitNumber = -1)
获得数值value在坐标轴上对应的split索引 | | `GetAxisXOrY()` |public static float GetAxisXOrY(GridCoord grid, Axis axis, Axis relativedAxis)
| | `GetDataWidth()` |public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)
获得一个类目数据在坐标系中代表的宽度 | | `GetEachWidth()` |public static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
| | `GetScaleNumber()` |public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
获得分割线条数 | | `GetScaleWidth()` |public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)
获得分割段宽度 | | `GetSplitNumber()` |public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)
获得分割段数 | +| `GetTotalSplitGridNum()` |public static int GetTotalSplitGridNum(Axis axis)
获得分割网格个数,包含次刻度 | | `GetXAxisXOrY()` |public static float GetXAxisXOrY(GridCoord grid, Axis xAxis, Axis relativedAxis)
| | `GetYAxisXOrY()` |public static float GetYAxisXOrY(GridCoord grid, Axis yAxis, Axis relativedAxis)
| | `NeedShowSplit()` |public static bool NeedShowSplit(Axis axis)
| @@ -153,12 +155,12 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `AddChartComponent()` |public MainComponent AddChartComponent(Type type)
| | `AddData()` |public SerieData AddData(int serieIndex, DateTime time, double yValue, string dataName = null, string dataId = null)
Add a (time,y) data to serie. | | `AddData()` |public SerieData AddData(int serieIndex, double data, string dataName = null, string dataId = null)
Add a data to serie. | -| `AddData()` |public SerieData AddData(int serieIndex, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| +| `AddData()` |public SerieData AddData(int serieIndex, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| | `AddData()` |public SerieData AddData(int serieIndex, double xValue, double yValue, string dataName = null, string dataId = null)
Add a (x,y) data to serie. | | `AddData()` |public SerieData AddData(int serieIndex, List multidimensionalData, string dataName = null, string dataId = null)
Add an arbitray dimension data to serie,such as (x,y,z,...). | | `AddData()` |public SerieData AddData(string serieName, DateTime time, double yValue, string dataName = null, string dataId = null)
Add a (time,y) data to serie. | | `AddData()` |public SerieData AddData(string serieName, double data, string dataName = null, string dataId = null)
Add a data to serie. | -| `AddData()` |public SerieData AddData(string serieName, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| +| `AddData()` |public SerieData AddData(string serieName, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| | `AddData()` |public SerieData AddData(string serieName, double xValue, double yValue, string dataName = null, string dataId = null)
Add a (x,y) data to serie. | | `AddData()` |public SerieData AddData(string serieName, List multidimensionalData, string dataName = null, string dataId = null)
Add an arbitray dimension data to serie,such as (x,y,z,...). | | `AddXAxisData()` |public void AddXAxisData(string category, int xAxisIndex = 0)
Add a category data to xAxis. | @@ -201,13 +203,13 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `GetSeriesMinMaxValue()` |public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue)
| | `GetTitlePosition()` |public Vector3 GetTitlePosition(Title title)
| | `GetVisualMapOfSerie()` |public VisualMap GetVisualMapOfSerie(Serie serie)
| +| `GetXDataZoomOfSerie()` |public DataZoom GetXDataZoomOfSerie(Serie serie)
| | `GetXLerpColor()` |public Color32 GetXLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)
| | `GetYLerpColor()` |public Color32 GetYLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)
| | `HasChartComponent()` |public bool HasChartComponent(Type type)
| | `HasChartComponent()` |public bool HasChartComponent()
| | `HasSerie()` |public bool HasSerie(Type type)
| | `Init()` |public void Init(bool defaultChart = true)
| -| `InitAxisRuntimeData()` |public virtual void InitAxisRuntimeData(Axis axis)
| | `InsertSerie()` |public void InsertSerie(Serie serie, int index = -1, bool addToHead = false)
| | `Internal_CheckAnimation()` |public void Internal_CheckAnimation()
| | `IsActiveByLegend()` |public virtual bool IsActiveByLegend(string legendName)
Whether serie is activated. | @@ -1038,7 +1040,7 @@ Inherits or Implemented: [MainComponentContext](#MainComponentContext) |public method|description| |--|--| | `AutoSetLineMinMax()` |public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, bool isY, Axis axis, Axis relativedAxis)
| -| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int serieDataCount)
| +| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int defaultDimension)
| | `IsNeedAreaGradient()` |public static bool IsNeedAreaGradient(VisualMap visualMap)
| | `IsNeedGradient()` |public static bool IsNeedGradient(VisualMap visualMap)
| | `IsNeedLineGradient()` |public static bool IsNeedLineGradient(VisualMap visualMap)
| diff --git a/Documentation/XChartsAPI-ZH.md b/Documentation/XChartsAPI-ZH.md index e2994473..878e8c08 100644 --- a/Documentation/XChartsAPI-ZH.md +++ b/Documentation/XChartsAPI-ZH.md @@ -130,12 +130,14 @@ Inherits or Implemented: [MainComponentHandler](#MainComponentHandler) | `GetAxisValueDistance()` |public static float GetAxisValueDistance(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上相对起点的距离 | | `GetAxisValueLength()` |public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上对应的长度 | | `GetAxisValuePosition()` |public static float GetAxisValuePosition(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上的坐标位置 | +| `GetAxisValueSplitIndex()` |public static int GetAxisValueSplitIndex(Axis axis, double value, int totalSplitNumber = -1)
获得数值value在坐标轴上对应的split索引 | | `GetAxisXOrY()` |public static float GetAxisXOrY(GridCoord grid, Axis axis, Axis relativedAxis)
| | `GetDataWidth()` |public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)
获得一个类目数据在坐标系中代表的宽度 | | `GetEachWidth()` |public static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
| | `GetScaleNumber()` |public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
获得分割线条数 | | `GetScaleWidth()` |public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)
获得分割段宽度 | | `GetSplitNumber()` |public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)
获得分割段数 | +| `GetTotalSplitGridNum()` |public static int GetTotalSplitGridNum(Axis axis)
获得分割网格个数,包含次刻度 | | `GetXAxisXOrY()` |public static float GetXAxisXOrY(GridCoord grid, Axis xAxis, Axis relativedAxis)
| | `GetYAxisXOrY()` |public static float GetYAxisXOrY(GridCoord grid, Axis yAxis, Axis relativedAxis)
| | `NeedShowSplit()` |public static bool NeedShowSplit(Axis axis)
| @@ -153,12 +155,12 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `AddChartComponent()` |public MainComponent AddChartComponent(Type type)
| | `AddData()` |public SerieData AddData(int serieIndex, DateTime time, double yValue, string dataName = null, string dataId = null)
添加(time,y)数据到指定的系列中。 | | `AddData()` |public SerieData AddData(int serieIndex, double data, string dataName = null, string dataId = null)
添加一个数据到指定的系列中。 | -| `AddData()` |public SerieData AddData(int serieIndex, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| +| `AddData()` |public SerieData AddData(int serieIndex, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| | `AddData()` |public SerieData AddData(int serieIndex, double xValue, double yValue, string dataName = null, string dataId = null)
添加(x,y)数据到指定系列中。 | | `AddData()` |public SerieData AddData(int serieIndex, List multidimensionalData, string dataName = null, string dataId = null)
添加多维数据(x,y,z...)到指定的系列中。 | | `AddData()` |public SerieData AddData(string serieName, DateTime time, double yValue, string dataName = null, string dataId = null)
添加(time,y)数据到指定的系列中。 | | `AddData()` |public SerieData AddData(string serieName, double data, string dataName = null, string dataId = null)
If serieName doesn't exist in legend,will be add to legend. | -| `AddData()` |public SerieData AddData(string serieName, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| +| `AddData()` |public SerieData AddData(string serieName, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| | `AddData()` |public SerieData AddData(string serieName, double xValue, double yValue, string dataName = null, string dataId = null)
添加(x,y)数据到指定系列中。 | | `AddData()` |public SerieData AddData(string serieName, List multidimensionalData, string dataName = null, string dataId = null)
添加多维数据(x,y,z...)到指定的系列中。 | | `AddXAxisData()` |public void AddXAxisData(string category, int xAxisIndex = 0)
添加一个类目数据到指定的x轴。 | @@ -201,13 +203,13 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `GetSeriesMinMaxValue()` |public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue)
| | `GetTitlePosition()` |public Vector3 GetTitlePosition(Title title)
| | `GetVisualMapOfSerie()` |public VisualMap GetVisualMapOfSerie(Serie serie)
| +| `GetXDataZoomOfSerie()` |public DataZoom GetXDataZoomOfSerie(Serie serie)
| | `GetXLerpColor()` |public Color32 GetXLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)
| | `GetYLerpColor()` |public Color32 GetYLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)
| | `HasChartComponent()` |public bool HasChartComponent(Type type)
| | `HasChartComponent()` |public bool HasChartComponent()
| | `HasSerie()` |public bool HasSerie(Type type)
| | `Init()` |public void Init(bool defaultChart = true)
| -| `InitAxisRuntimeData()` |public virtual void InitAxisRuntimeData(Axis axis)
| | `InsertSerie()` |public void InsertSerie(Serie serie, int index = -1, bool addToHead = false)
| | `Internal_CheckAnimation()` |public void Internal_CheckAnimation()
| | `IsActiveByLegend()` |public virtual bool IsActiveByLegend(string legendName)
获得指定图例名字的系列是否显示。 | @@ -1038,7 +1040,7 @@ Inherits or Implemented: [MainComponentContext](#MainComponentContext) |public method|description| |--|--| | `AutoSetLineMinMax()` |public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, bool isY, Axis axis, Axis relativedAxis)
| -| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int serieDataCount)
| +| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int defaultDimension)
| | `IsNeedAreaGradient()` |public static bool IsNeedAreaGradient(VisualMap visualMap)
| | `IsNeedGradient()` |public static bool IsNeedGradient(VisualMap visualMap)
| | `IsNeedLineGradient()` |public static bool IsNeedLineGradient(VisualMap visualMap)
| diff --git a/Documentation/XChartsConfiguration-EN.md b/Documentation/XChartsConfiguration-EN.md index 7a696b8a..abfef096 100644 --- a/Documentation/XChartsConfiguration-EN.md +++ b/Documentation/XChartsConfiguration-EN.md @@ -628,6 +628,9 @@ Grid component. Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) +|field|default|since|comment| +|--|--|--|--| +|`heatmapType`||3.3.0|The mapping type of heatmap.
`HeatmapType`:
- `Data`: Data mapping type.By default, the second dimension data is used as the color map.
- `Count`: Number mapping type.The number of occurrences of a statistic in a divided grid, as a color map.
| ## `IconStyle` @@ -781,7 +784,7 @@ Legend component.The legend component shows different sets of tags, colors, and |field|default|since|comment| |--|--|--|--| |`show`|true||Whether to show legend component. -|`iconType`|||Type of legend.
`Legend.Type`:
- `Auto`: 自动匹配。
- `Custom`: 自定义图标。
- `EmptyCircle`: 空心圆。
- `Circle`: 圆形。
- `Rect`: 正方形。可通过Setting的legendIconCornerRadius参数调整圆角。
- `Triangle`: 三角形。
- `Diamond`: 菱形。
| +|`iconType`|||Type of legend.
`Legend.Type`:
- `Auto`: 自动匹配。
- `Custom`: 自定义图标。
- `EmptyCircle`: 空心圆。
- `Circle`: 圆形。
- `Rect`: 正方形。可通过Setting的legendIconCornerRadius参数调整圆角。
- `Triangle`: 三角形。
- `Diamond`: 菱形。
- `Candlestick`: 烛台(可用于K线图)。
| |`selectedMode`|||Selected mode of legend, which controls whether series can be toggled displaying by clicking legends.
`Legend.SelectedMode`:
- `Multiple`: 多选。
- `Single`: 单选。
- `None`: 无法选择。
| |`orient`|||Specify whether the layout of legend component is horizontal or vertical.
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| |`location`|||The location of legend. [Location](#Location)| @@ -1479,7 +1482,7 @@ VisualMap component. Mapping data to visual elements such as colors. |`selectedMode`|||the selected mode for Piecewise visualMap.
`VisualMap.SelectedMode`:
- `Multiple`: 多选。
- `Single`: 单选。
| |`serieIndex`|0||the serie index of visualMap. |`min`|0||范围最小值 -|`max`|100||范围最大值 +|`max`|0||范围最大值 |`range`|||Specifies the position of the numeric value corresponding to the handle. Range should be within the range of [min,max]. |`text`|||Text on both ends. |`textGap`|||The distance between the two text bodies. diff --git a/Documentation/XChartsConfiguration-ZH.md b/Documentation/XChartsConfiguration-ZH.md index effc6b6b..f0c24a82 100644 --- a/Documentation/XChartsConfiguration-ZH.md +++ b/Documentation/XChartsConfiguration-ZH.md @@ -628,6 +628,9 @@ Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) +|field|default|since|comment| +|--|--|--|--| +|`heatmapType`||3.3.0|热力图类型。通过颜色映射划分。
`HeatmapType`:
- `Data`: 数据映射型。默认用第2维数据作为颜色映射。要求数据至少有3个维度数据。
- `Count`: 个数映射型。统计数据在划分的格子中出现的次数,作为颜色映射。要求数据至少有2个维度数据。
| ## `IconStyle` @@ -781,7 +784,7 @@ Inherits or Implemented: [MainComponent](#MainComponent),[IPropertyChanged](#IPr |field|default|since|comment| |--|--|--|--| |`show`|true||是否显示图例组件。 -|`iconType`|||图例类型。
`Legend.Type`:
- `Auto`: 自动匹配。
- `Custom`: 自定义图标。
- `EmptyCircle`: 空心圆。
- `Circle`: 圆形。
- `Rect`: 正方形。可通过Setting的legendIconCornerRadius参数调整圆角。
- `Triangle`: 三角形。
- `Diamond`: 菱形。
| +|`iconType`|||图例类型。
`Legend.Type`:
- `Auto`: 自动匹配。
- `Custom`: 自定义图标。
- `EmptyCircle`: 空心圆。
- `Circle`: 圆形。
- `Rect`: 正方形。可通过Setting的legendIconCornerRadius参数调整圆角。
- `Triangle`: 三角形。
- `Diamond`: 菱形。
- `Candlestick`: 烛台(可用于K线图)。
| |`selectedMode`|||选择模式。控制是否可以通过点击图例改变系列的显示状态。默认开启图例选择,可以设成 None 关闭。
`Legend.SelectedMode`:
- `Multiple`: 多选。
- `Single`: 单选。
- `None`: 无法选择。
| |`orient`|||布局方式是横还是竖。
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| |`location`|||图例显示的位置。 [Location](#Location)| @@ -1479,7 +1482,7 @@ Inherits or Implemented: [MainComponent](#MainComponent) |`selectedMode`|||选择模式。
`VisualMap.SelectedMode`:
- `Multiple`: 多选。
- `Single`: 单选。
| |`serieIndex`|0||影响的serie索引。 |`min`|0||范围最小值 -|`max`|100||范围最大值 +|`max`|0||范围最大值 |`range`|||指定手柄对应数值的位置。range 应在[min,max]范围内。 |`text`|||两端的文本,如 ['High', 'Low']。 |`textGap`|||两端文字主体之间的距离,单位为px。 diff --git a/Editor/Series/HeatmapEditor.cs b/Editor/Series/HeatmapEditor.cs index 739952ba..60e3caed 100644 --- a/Editor/Series/HeatmapEditor.cs +++ b/Editor/Series/HeatmapEditor.cs @@ -7,6 +7,7 @@ public class HeatmapEditor : SerieEditor { public override void OnCustomInspectorGUI() { + PropertyField("m_HeatmapType"); PropertyField("m_Ignore"); PropertyField("m_IgnoreValue"); diff --git a/Runtime/Component/Axis/AxisHelper.cs b/Runtime/Component/Axis/AxisHelper.cs index 73c96f5d..249f5e92 100644 --- a/Runtime/Component/Axis/AxisHelper.cs +++ b/Runtime/Component/Axis/AxisHelper.cs @@ -31,9 +31,7 @@ public static int GetTotalSplitGridNum(Axis axis) else { var splitNum = axis.splitNumber <= 0 ? GetSplitNumber(axis, 0, null) : axis.splitNumber; - return axis.minorTick.show ? - splitNum * axis.minorTick.splitNumber : - splitNum; + return splitNum * axis.minorTick.splitNumber; } } diff --git a/Runtime/Component/Tooltip/TooltipHandler.cs b/Runtime/Component/Tooltip/TooltipHandler.cs index 2520cd79..05a356de 100644 --- a/Runtime/Component/Tooltip/TooltipHandler.cs +++ b/Runtime/Component/Tooltip/TooltipHandler.cs @@ -286,11 +286,19 @@ private void GetSerieDataByXYAxis(Serie serie, Axis xAxis, Axis yAxis) var xAxisIndex = AxisHelper.GetAxisValueSplitIndex(xAxis, xAxis.context.pointerValue); var yAxisIndex = AxisHelper.GetAxisValueSplitIndex(yAxis, yAxis.context.pointerValue); serie.context.pointerItemDataIndex = -1; - + if (serie is Heatmap) + { + var heatmap = serie as Heatmap; + if (heatmap.heatmapType == HeatmapType.Count) + { + serie.context.pointerItemDataIndex = HeatmapHandler.GetGridKey(xAxisIndex, yAxisIndex); + return; + } + } foreach (var serieData in serie.data) { - var x = AxisHelper.GetAxisValueSplitIndex(xAxis,serieData.GetData(0)); - var y = AxisHelper.GetAxisValueSplitIndex(yAxis,serieData.GetData(1)); + var x = AxisHelper.GetAxisValueSplitIndex(xAxis, serieData.GetData(0)); + var y = AxisHelper.GetAxisValueSplitIndex(yAxis, serieData.GetData(1)); if (xAxisIndex == x && y == yAxisIndex) { serie.context.pointerItemDataIndex = serieData.index; diff --git a/Runtime/Serie/Heatmap/Heatmap.cs b/Runtime/Serie/Heatmap/Heatmap.cs index ec4fc180..a40b745d 100644 --- a/Runtime/Serie/Heatmap/Heatmap.cs +++ b/Runtime/Serie/Heatmap/Heatmap.cs @@ -2,6 +2,24 @@ namespace XCharts.Runtime { + /// + /// The mapping type of heatmap. + /// |热力图类型。通过颜色映射划分。 + /// + public enum HeatmapType + { + /// + /// Data mapping type.By default, the second dimension data is used as the color map. + /// |数据映射型。默认用第2维数据作为颜色映射。要求数据至少有3个维度数据。 + /// + Data, + /// + /// Number mapping type.The number of occurrences of a statistic in a divided grid, as a color map. + /// |个数映射型。统计数据在划分的格子中出现的次数,作为颜色映射。要求数据至少有2个维度数据。 + /// + Count + } + [System.Serializable] [SerieHandler(typeof(HeatmapHandler), true)] [DefaultAnimation(AnimationType.LeftToRight)] @@ -11,8 +29,20 @@ namespace XCharts.Runtime [SerieDataExtraField()] public class Heatmap : Serie, INeedSerieContainer { + [SerializeField][Since("3.3.0")] private HeatmapType m_HeatmapType = HeatmapType.Data; + + /// + /// The mapping type of heatmap. + /// |热力图类型。通过颜色映射划分。 + /// + public HeatmapType heatmapType + { + get { return m_HeatmapType; } + set { if (PropertyUtil.SetStruct(ref m_HeatmapType, value)) { SetVerticesDirty(); } } + } public int containerIndex { get; internal set; } public int containterInstanceId { get; internal set; } + public static Serie AddDefaultSerie(BaseChart chart, string serieName) { var serie = chart.AddSerie(serieName); diff --git a/Runtime/Serie/Heatmap/HeatmapHandler.cs b/Runtime/Serie/Heatmap/HeatmapHandler.cs index 0edd024d..c5c3295e 100644 --- a/Runtime/Serie/Heatmap/HeatmapHandler.cs +++ b/Runtime/Serie/Heatmap/HeatmapHandler.cs @@ -9,9 +9,21 @@ namespace XCharts.Runtime internal sealed class HeatmapHandler : SerieHandler { private GridCoord m_SerieGrid; + private Dictionary m_CountDict = new Dictionary(); public override int defaultDimension { get { return 2; } } + public static int GetGridKey(int x, int y) + { + return x * 100000 + y; + } + + public static void GetGridXYByKey(int key, out int x, out int y) + { + x = key / 100000; + y = key % 100000; + } + public override void Update() { base.Update(); @@ -20,7 +32,10 @@ public override void Update() public override void DrawSerie(VertexHelper vh) { - DrawHeatmapSerie(vh, serie); + if (serie.heatmapType == HeatmapType.Count) + DrawCountHeatmapSerie(vh, serie); + else + DrawDataHeatmapSerie(vh, serie); } public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, @@ -28,40 +43,70 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, ref List paramList, ref string title) { dataIndex = serie.context.pointerItemDataIndex; - if (dataIndex < 0) - return; + if (serie.heatmapType == HeatmapType.Count) + { + int value; + if (!m_CountDict.TryGetValue(dataIndex, out value)) return; + var visualMap = chart.GetVisualMapOfSerie(serie); + var dimension = VisualMapHelper.GetDimension(visualMap, defaultDimension); - var serieData = serie.GetSerieData(dataIndex); - if (serieData == null) - return; - var visualMap = chart.GetVisualMapOfSerie(serie); - var dimension = VisualMapHelper.GetDimension(visualMap, defaultDimension); + title = serie.serieName; - if (string.IsNullOrEmpty(category)) - { - var xAxis = chart.GetChartComponent(serie.xAxisIndex); - if (xAxis != null) - category = xAxis.GetData((int) serieData.GetData(0)); + var param = serie.context.param; + param.serieName = serie.serieName; + param.serieIndex = serie.index; + param.dimension = dimension; + param.dataCount = serie.dataCount; + param.serieData = null; + param.color = visualMap.GetColor(value); + param.marker = SerieHelper.GetItemMarker(serie, null, marker); + param.itemFormatter = SerieHelper.GetItemFormatter(serie, null, itemFormatter); + param.numericFormatter = SerieHelper.GetNumericFormatter(serie, null, numericFormatter); + param.columns.Clear(); + + param.columns.Add(param.marker); + param.columns.Add("count"); + param.columns.Add(ChartCached.NumberToStr(value, param.numericFormatter)); + + paramList.Add(param); } - title = serie.serieName; + else + { + if (dataIndex < 0) + return; - var param = serie.context.param; - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.dimension = dimension; - param.dataCount = serie.dataCount; - param.serieData = serieData; - param.color = serieData.context.color; - param.marker = SerieHelper.GetItemMarker(serie, serieData, marker); - param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); - param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); - param.columns.Clear(); + var serieData = serie.GetSerieData(dataIndex); + if (serieData == null) + return; + var visualMap = chart.GetVisualMapOfSerie(serie); + var dimension = VisualMapHelper.GetDimension(visualMap, defaultDimension); - param.columns.Add(param.marker); - param.columns.Add(category); - param.columns.Add(ChartCached.NumberToStr(serieData.GetData(dimension), param.numericFormatter)); + if (string.IsNullOrEmpty(category)) + { + var xAxis = chart.GetChartComponent(serie.xAxisIndex); + if (xAxis != null) + category = xAxis.GetData((int) serieData.GetData(0)); + } + title = serie.serieName; + + var param = serie.context.param; + param.serieName = serie.serieName; + param.serieIndex = serie.index; + param.dimension = dimension; + param.dataCount = serie.dataCount; + param.serieData = serieData; + param.color = serieData.context.color; + param.marker = SerieHelper.GetItemMarker(serie, serieData, marker); + param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); + param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); + param.columns.Clear(); + + param.columns.Add(param.marker); + param.columns.Add(category); + param.columns.Add(ChartCached.NumberToStr(serieData.GetData(dimension), param.numericFormatter)); - paramList.Add(param); + paramList.Add(param); + } } private void UpdateSerieContext() @@ -86,6 +131,8 @@ private void UpdateSerieContext() } return; } + if (serie.heatmapType == HeatmapType.Count) + return; m_LastCheckContextFlag = needCheck; if (m_LegendEnter) { @@ -120,7 +167,7 @@ private void UpdateSerieContext() } } - private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie) + private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie) { if (!serie.show || serie.animation.HasFadeOut()) return; XAxis xAxis; @@ -212,7 +259,6 @@ private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie) var highlight = (serieData.context.highlight) || visualMap.context.pointerIndex > 0; - //UGL.DrawRectangle(vh, pos, rectWid / 2, rectHig / 2, color); UGL.DrawRectangle(vh, serieData.context.rect, color); if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) @@ -243,5 +289,143 @@ private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie) chart.RefreshPainter(serie); } } + + private void DrawCountHeatmapSerie(VertexHelper vh, Heatmap serie) + { + if (!serie.show || serie.animation.HasFadeOut()) return; + XAxis xAxis; + YAxis yAxis; + if (!chart.TryGetChartComponent(out xAxis, serie.xAxisIndex)) return; + if (!chart.TryGetChartComponent(out yAxis, serie.yAxisIndex)) return; + m_SerieGrid = chart.GetChartComponent(xAxis.gridIndex); + xAxis.boundaryGap = true; + yAxis.boundaryGap = true; + var visualMap = chart.GetVisualMapOfSerie(serie); + var emphasisStyle = serie.emphasisStyle; + var xCount = AxisHelper.GetTotalSplitGridNum(xAxis); + var yCount = AxisHelper.GetTotalSplitGridNum(yAxis); + var xWidth = m_SerieGrid.context.width / xCount; + var yWidth = m_SerieGrid.context.height / yCount; + + var zeroX = m_SerieGrid.context.x; + var zeroY = m_SerieGrid.context.y; + var color = chart.theme.GetColor(serie.index); + var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0; + var rectWid = xWidth - 2 * borderWidth; + var rectHig = yWidth - 2 * borderWidth; + + var borderColor = serie.itemStyle.opacity > 0 ? + serie.itemStyle.borderColor : + ChartConst.clearColor32; + borderColor.a = (byte) (borderColor.a * serie.itemStyle.opacity); + + var borderToColor = serie.itemStyle.opacity > 0 ? + serie.itemStyle.borderToColor : + ChartConst.clearColor32; + borderToColor.a = (byte) (borderToColor.a * serie.itemStyle.opacity); + + serie.animation.InitProgress(0, xCount); + var animationIndex = serie.animation.GetCurrIndex(); + var dataChanging = false; + serie.containerIndex = m_SerieGrid.index; + serie.containterInstanceId = m_SerieGrid.instanceId; + + m_CountDict.Clear(); + double minCount = 0, maxCount = 0; + foreach (var serieData in serie.data) + { + var xValue = serieData.GetData(0); + var yValue = serieData.GetData(1); + var i = AxisHelper.GetAxisValueSplitIndex(xAxis, xValue, xCount); + var j = AxisHelper.GetAxisValueSplitIndex(yAxis, yValue, yCount); + var key = GetGridKey(i, j); + var count = 0; + + if (!m_CountDict.TryGetValue(key, out count)) + count = 1; + else + count++; + if (count > maxCount) + maxCount = count; + m_CountDict[key] = count; + } + + if (visualMap.autoMinMax) + { + VisualMapHelper.SetMinMax(visualMap, minCount, maxCount); + } + var rangeMin = visualMap.rangeMin; + var rangeMax = visualMap.rangeMax; + + int highlightX = -1; + int highlightY = -1; + if (serie.context.pointerItemDataIndex > 0) + { + if (m_CountDict.ContainsKey(serie.context.pointerItemDataIndex)) + { + GetGridXYByKey(serie.context.pointerItemDataIndex, out highlightX, out highlightY); + } + } + + foreach (var kv in m_CountDict) + { + int i, j; + GetGridXYByKey(kv.Key, out i, out j); + var value = kv.Value; + + if (serie.IsIgnoreValue(value)) + { + continue; + } + + if ((value < rangeMin && rangeMin != visualMap.min) || + (value > rangeMax && rangeMax != visualMap.max)) + { + continue; + } + if (!visualMap.IsInSelectedValue(value)) + continue; + if (animationIndex >= 0 && i > animationIndex) + continue; + + var highlight = i == highlightX && j == highlightY; + + color = visualMap.GetColor(value); + if (highlight) + color = ChartHelper.GetHighlightColor(color); + + var pos = new Vector3(zeroX + (i + 0.5f) * xWidth, + zeroY + (j + 0.5f) * yWidth); + var rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); + UGL.DrawRectangle(vh, rect, color); + + if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) + { + UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderToColor); + } + if (visualMap.hoverLink && highlight && emphasisStyle != null && + emphasisStyle.itemStyle.borderWidth > 0) + { + var emphasisItemStyle = emphasisStyle.itemStyle; + var emphasisBorderWidth = emphasisItemStyle.borderWidth; + var emphasisBorderColor = emphasisItemStyle.opacity > 0 ? + emphasisItemStyle.borderColor : ChartConst.clearColor32; + var emphasisBorderToColor = emphasisItemStyle.opacity > 0 ? + emphasisItemStyle.borderToColor : ChartConst.clearColor32; + UGL.DrawBorder(vh, pos, rectWid, rectHig, emphasisBorderWidth, emphasisBorderColor, + emphasisBorderToColor); + } + + } + if (!serie.animation.IsFinish()) + { + serie.animation.CheckProgress(xCount); + chart.RefreshPainter(serie); + } + if (dataChanging) + { + chart.RefreshPainter(serie); + } + } } } \ No newline at end of file From 83744777c5872f36ffd2082d406e189a2d6b2c5c Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Tue, 6 Sep 2022 13:12:50 +0800 Subject: [PATCH 19/38] [feature][heatmap] support symbol --- CHANGELOG.md | 1 + Editor/Series/HeatmapEditor.cs | 1 + Runtime/Internal/BaseChart.Serie.cs | 5 ++ Runtime/Serie/Heatmap/HeatmapHandler.cs | 76 +++++++++++++++---------- Runtime/Serie/SerieHelper.cs | 4 +- 5 files changed, 55 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8d2b236..6567d579 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.06) 增加`Heatmap`通过`symbol`设置不同的图案的支持 * (2022.09.05) 增加`Heatmap`的`heatmapType`支持设置`Data`和`Count`两种不同映射方式的热力图 * (2022.09.05) 优化`Tooltip`在热力图为数值轴时的指示 * (2022.09.02) 增加`onPointerEnterPie`回调支持 diff --git a/Editor/Series/HeatmapEditor.cs b/Editor/Series/HeatmapEditor.cs index 60e3caed..f525541e 100644 --- a/Editor/Series/HeatmapEditor.cs +++ b/Editor/Series/HeatmapEditor.cs @@ -11,6 +11,7 @@ public override void OnCustomInspectorGUI() PropertyField("m_Ignore"); PropertyField("m_IgnoreValue"); + PropertyField("m_Symbol"); PropertyField("m_ItemStyle"); PropertyField("m_Animation"); } diff --git a/Runtime/Internal/BaseChart.Serie.cs b/Runtime/Internal/BaseChart.Serie.cs index a87dfd89..e3a302c8 100644 --- a/Runtime/Internal/BaseChart.Serie.cs +++ b/Runtime/Internal/BaseChart.Serie.cs @@ -966,6 +966,11 @@ private Serie InsertSerie(int index, Type type, string serieName, bool show = tr serie.symbol.show = true; serie.symbol.type = SymbolType.EmptyCircle; } + else if (type == typeof(Heatmap)) + { + serie.symbol.show = true; + serie.symbol.type = SymbolType.Rect; + } else { serie.symbol.show = false; diff --git a/Runtime/Serie/Heatmap/HeatmapHandler.cs b/Runtime/Serie/Heatmap/HeatmapHandler.cs index c5c3295e..83a553ef 100644 --- a/Runtime/Serie/Heatmap/HeatmapHandler.cs +++ b/Runtime/Serie/Heatmap/HeatmapHandler.cs @@ -186,20 +186,10 @@ private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie) var zeroX = m_SerieGrid.context.x; var zeroY = m_SerieGrid.context.y; - var color = chart.theme.GetColor(serie.index); var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0; var rectWid = xWidth - 2 * borderWidth; var rectHig = yWidth - 2 * borderWidth; - - var borderColor = serie.itemStyle.opacity > 0 ? - serie.itemStyle.borderColor : - ChartConst.clearColor32; - borderColor.a = (byte) (borderColor.a * serie.itemStyle.opacity); - - var borderToColor = serie.itemStyle.opacity > 0 ? - serie.itemStyle.borderToColor : - ChartConst.clearColor32; - borderToColor.a = (byte) (borderToColor.a * serie.itemStyle.opacity); + var defaultSymbolSize = Mathf.Min(rectWid, rectHig) * 0.25f; serie.animation.InitProgress(0, xCount); var animationIndex = serie.animation.GetCurrIndex(); @@ -217,6 +207,10 @@ private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie) } var rangeMin = visualMap.rangeMin; var rangeMax = visualMap.rangeMax; + var color = chart.theme.GetColor(serie.index); + float symbolBorder = 0f; + float[] cornerRadius = null; + Color32 borderColor; for (int n = 0; n < serie.dataCount; n++) { var serieData = serie.data[n]; @@ -231,6 +225,10 @@ private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie) serie.context.dataIndexs.Add(serieData.index); continue; } + var state = SerieHelper.GetSerieState(serie, serieData, true); + var symbol = SerieHelper.GetSerieSymbol(serie, serieData, state); + var isRectSymbol = symbol.type == SymbolType.Rect; + SerieHelper.GetSymbolInfo(out borderColor, out symbolBorder, out cornerRadius, serie, serieData, chart.theme, state); var value = serieData.GetCurrData(dimension, dataChangeDuration, yAxis.inverse, yAxis.context.minValue, yAxis.context.maxValue); if (serieData.IsDataChanged()) dataChanging = true; @@ -259,12 +257,23 @@ private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie) var highlight = (serieData.context.highlight) || visualMap.context.pointerIndex > 0; - UGL.DrawRectangle(vh, serieData.context.rect, color); + if (isRectSymbol) + { + UGL.DrawRectangle(vh, serieData.context.rect, color); - if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) + if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) + { + UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderColor); + } + } + else { - UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderToColor); + var symbolSize = SerieHelper.GetSysmbolSize(serie, serieData, chart.theme, defaultSymbolSize, state); + var emptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, serie.context.colorIndex, state); + chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, + color, color, emptyColor, borderColor, symbol.gap, cornerRadius); } + if (visualMap.hoverLink && highlight && emphasisStyle != null && emphasisStyle.itemStyle.borderWidth > 0) { @@ -309,20 +318,10 @@ private void DrawCountHeatmapSerie(VertexHelper vh, Heatmap serie) var zeroX = m_SerieGrid.context.x; var zeroY = m_SerieGrid.context.y; - var color = chart.theme.GetColor(serie.index); var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0; var rectWid = xWidth - 2 * borderWidth; var rectHig = yWidth - 2 * borderWidth; - - var borderColor = serie.itemStyle.opacity > 0 ? - serie.itemStyle.borderColor : - ChartConst.clearColor32; - borderColor.a = (byte) (borderColor.a * serie.itemStyle.opacity); - - var borderToColor = serie.itemStyle.opacity > 0 ? - serie.itemStyle.borderToColor : - ChartConst.clearColor32; - borderToColor.a = (byte) (borderToColor.a * serie.itemStyle.opacity); + var defaultSymbolSize = Mathf.Min(rectWid, rectHig) * 0.25f; serie.animation.InitProgress(0, xCount); var animationIndex = serie.animation.GetCurrIndex(); @@ -366,7 +365,15 @@ private void DrawCountHeatmapSerie(VertexHelper vh, Heatmap serie) GetGridXYByKey(serie.context.pointerItemDataIndex, out highlightX, out highlightY); } } - + var state = SerieHelper.GetSerieState(serie, null, true); + var symbol = SerieHelper.GetSerieSymbol(serie, null, state); + var symbolSize = SerieHelper.GetSysmbolSize(serie, null, chart.theme, defaultSymbolSize, state); + var isRectSymbol = symbol.type == SymbolType.Rect; + float symbolBorder = 0f; + float[] cornerRadius = null; + Color32 color, toColor, emptyColor, borderColor; + SerieHelper.GetItemColor(out color, out toColor, out emptyColor, serie, null, chart.theme, serie.context.colorIndex, state); + SerieHelper.GetSymbolInfo(out borderColor, out symbolBorder, out cornerRadius, serie, null, chart.theme, state); foreach (var kv in m_CountDict) { int i, j; @@ -377,7 +384,7 @@ private void DrawCountHeatmapSerie(VertexHelper vh, Heatmap serie) { continue; } - + if ((value < rangeMin && rangeMin != visualMap.min) || (value > rangeMax && rangeMax != visualMap.max)) { @@ -397,12 +404,21 @@ private void DrawCountHeatmapSerie(VertexHelper vh, Heatmap serie) var pos = new Vector3(zeroX + (i + 0.5f) * xWidth, zeroY + (j + 0.5f) * yWidth); var rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); - UGL.DrawRectangle(vh, rect, color); + if (isRectSymbol) + { + UGL.DrawRectangle(vh, rect, color); - if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) + if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) + { + UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderColor); + } + } + else { - UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderToColor); + chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, + color, color, emptyColor, borderColor, symbol.gap, cornerRadius); } + if (visualMap.hoverLink && highlight && emphasisStyle != null && emphasisStyle.itemStyle.borderWidth > 0) { diff --git a/Runtime/Serie/SerieHelper.cs b/Runtime/Serie/SerieHelper.cs index 95e04f70..3e4e52c5 100644 --- a/Runtime/Serie/SerieHelper.cs +++ b/Runtime/Serie/SerieHelper.cs @@ -679,7 +679,7 @@ public static float GetSysmbolSize(Serie serie, SerieData serieData, ThemeStyle if (stateStyle == null) { var symbol = GetSerieSymbol(serie, serieData, SerieState.Normal); - size = symbol.GetSize(serieData.data, defaultSize); + size = symbol.GetSize(serieData == null? null : serieData.data, defaultSize); switch (state) { case SerieState.Emphasis: @@ -693,7 +693,7 @@ public static float GetSysmbolSize(Serie serie, SerieData serieData, ThemeStyle else { var symbol = stateStyle.symbol; - size = symbol.GetSize(serieData.data, defaultSize); + size = symbol.GetSize(serieData == null? null : serieData.data, defaultSize); } return size; } From 16d055abc0a1ff622ac9b35f6ddbb286a745ee6d Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Tue, 6 Sep 2022 22:54:40 +0800 Subject: [PATCH 20/38] [feature][axis] add `showStartLine` and `showEndLine` for AxisSplitLine --- CHANGELOG.md | 1 + Documentation/XChartsConfiguration-EN.md | 2 ++ Documentation/XChartsConfiguration-ZH.md | 2 ++ Editor/ChildComponents/LineDrawer.cs | 2 ++ Runtime/Component/Axis/AxisHandler.cs | 6 ++-- Runtime/Component/Axis/AxisSplitLine.cs | 32 ++++++++++++++++++-- Runtime/Component/Radar/RadarCoordHandler.cs | 2 +- 7 files changed, 41 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6567d579..0fce9944 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.06) 增加`AxisSplitLine`的`showStartLine`和`showEndLine`参数 * (2022.09.06) 增加`Heatmap`通过`symbol`设置不同的图案的支持 * (2022.09.05) 增加`Heatmap`的`heatmapType`支持设置`Data`和`Count`两种不同映射方式的热力图 * (2022.09.05) 优化`Tooltip`在热力图为数值轴时的指示 diff --git a/Documentation/XChartsConfiguration-EN.md b/Documentation/XChartsConfiguration-EN.md index abfef096..ab523e2d 100644 --- a/Documentation/XChartsConfiguration-EN.md +++ b/Documentation/XChartsConfiguration-EN.md @@ -357,6 +357,8 @@ Split line of axis in grid area. |`interval`|||Interval of Axis splitLine. |`distance`|||The distance between the split line and axis line. |`autoColor`|||auto color. +|`showStartLine`|true|v3.3.0|Whether to show the first split line. +|`showEndLine`|true|v3.3.0|Whether to show the last split line. ## `AxisTheme` diff --git a/Documentation/XChartsConfiguration-ZH.md b/Documentation/XChartsConfiguration-ZH.md index f0c24a82..7fe54734 100644 --- a/Documentation/XChartsConfiguration-ZH.md +++ b/Documentation/XChartsConfiguration-ZH.md @@ -357,6 +357,8 @@ Inherits or Implemented: [BaseLine](#BaseLine) |`interval`|||坐标轴分隔线的显示间隔。 |`distance`|||刻度线与轴线的距离。 |`autoColor`|||自动设置颜色。 +|`showStartLine`|true|v3.3.0|是否显示第一条分割线。 +|`showEndLine`|true|v3.3.0|是否显示最后一条分割线。 ## `AxisTheme` diff --git a/Editor/ChildComponents/LineDrawer.cs b/Editor/ChildComponents/LineDrawer.cs index 002d520c..f3519bb1 100644 --- a/Editor/ChildComponents/LineDrawer.cs +++ b/Editor/ChildComponents/LineDrawer.cs @@ -44,6 +44,8 @@ protected override void DrawExtendeds(SerializedProperty prop) PropertyField(prop, "m_Interval"); PropertyField(prop, "m_Distance"); PropertyField(prop, "m_AutoColor"); + PropertyField(prop, "m_ShowStartLine"); + PropertyField(prop, "m_ShowEndLine"); } } diff --git a/Runtime/Component/Axis/AxisHandler.cs b/Runtime/Component/Axis/AxisHandler.cs index 0a86e596..47fc3c5e 100644 --- a/Runtime/Component/Axis/AxisHandler.cs +++ b/Runtime/Component/Axis/AxisHandler.cs @@ -817,11 +817,11 @@ protected void DrawAxisSplit(VertexHelper vh, AxisTheme theme, DataZoom dataZoom } if (axis.splitLine.show) { - if (axis.splitLine.NeedShow(i)) + if (axis.splitLine.NeedShow(i, size)) { if (orient == Orient.Horizonal) { - if (relativedAxis == null || !MathUtil.Approximately(current, relativedAxis.context.x)) + if (relativedAxis == null || !relativedAxis.axisLine.show || !MathUtil.Approximately(current, relativedAxis.context.x)) { ChartDrawer.DrawLineStyle(vh, lineType, @@ -885,7 +885,7 @@ protected void DrawAxisSplit(VertexHelper vh, AxisTheme theme, DataZoom dataZoom } else { - if (relativedAxis == null || !MathUtil.Approximately(current, relativedAxis.context.y)) + if (relativedAxis == null || !relativedAxis.axisLine.show || !MathUtil.Approximately(current, relativedAxis.context.y)) { ChartDrawer.DrawLineStyle(vh, lineType, diff --git a/Runtime/Component/Axis/AxisSplitLine.cs b/Runtime/Component/Axis/AxisSplitLine.cs index 8e345272..a9785e3c 100644 --- a/Runtime/Component/Axis/AxisSplitLine.cs +++ b/Runtime/Component/Axis/AxisSplitLine.cs @@ -13,6 +13,8 @@ public class AxisSplitLine : BaseLine [SerializeField] private int m_Interval; [SerializeField] private float m_Distance; [SerializeField] private bool m_AutoColor; + [SerializeField][Since("v3.3.0")] private bool m_ShowStartLine = true; + [SerializeField][Since("v3.3.0")] private bool m_ShowEndLine = true; /// /// The distance between the split line and axis line. @@ -33,6 +35,24 @@ public int interval get { return m_Interval; } set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetVerticesDirty(); } } + /// + /// Whether to show the first split line. + /// |是否显示第一条分割线。 + /// + public bool showStartLine + { + get { return m_ShowStartLine; } + set { if (PropertyUtil.SetStruct(ref m_ShowStartLine, value)) SetVerticesDirty(); } + } + /// + /// Whether to show the last split line. + /// |是否显示最后一条分割线。 + /// + public bool showEndLine + { + get { return m_ShowEndLine; } + set { if (PropertyUtil.SetStruct(ref m_ShowEndLine, value)) SetVerticesDirty(); } + } public override bool vertsDirty { get { return m_VertsDirty || m_LineStyle.anyDirty; } } public override void ClearVerticesDirty() @@ -56,6 +76,8 @@ public AxisSplitLine Clone() var axisSplitLine = new AxisSplitLine(); axisSplitLine.show = show; axisSplitLine.interval = interval; + axisSplitLine.showStartLine = showStartLine; + axisSplitLine.showEndLine = showEndLine; axisSplitLine.lineStyle = lineStyle.Clone(); return axisSplitLine; } @@ -64,11 +86,17 @@ public void Copy(AxisSplitLine splitLine) { base.Copy(splitLine); interval = splitLine.interval; + showStartLine = splitLine.showStartLine; + showEndLine = splitLine.showEndLine; } - internal bool NeedShow(int index) + internal bool NeedShow(int index, int total) { - return show && (interval == 0 || index % (interval + 1) == 0); + if (!show) return false; + if (interval != 0 && index % (interval + 1) != 0) return false; + if (!showStartLine && index == 0) return false; + if (!showEndLine && index == total - 1) return false; + return true; } } } \ No newline at end of file diff --git a/Runtime/Component/Radar/RadarCoordHandler.cs b/Runtime/Component/Radar/RadarCoordHandler.cs index 18adea9b..3ffdf003 100644 --- a/Runtime/Component/Radar/RadarCoordHandler.cs +++ b/Runtime/Component/Radar/RadarCoordHandler.cs @@ -147,7 +147,7 @@ private void DrawPolygonRadar(VertexHelper vh, RadarCoord radar) { UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, color); } - if (radar.splitLine.NeedShow(i)) + if (radar.splitLine.NeedShow(i, radar.splitNumber)) { ChartDrawer.DrawLineStyle(vh, splitLineType, splitLineWidth, p2, p3, splitLineColor); } From a5e13794e805f7df1d2d4cc488e1b913c3bdc778 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Wed, 7 Sep 2022 07:14:22 +0800 Subject: [PATCH 21/38] [feature][symbol] add `minSize` and `maxSize` for SerieSymbol --- CHANGELOG.md | 3 +- Documentation/XChartsConfiguration-EN.md | 2 + Documentation/XChartsConfiguration-ZH.md | 2 + Editor/ChildComponents/SerieSymbolDrawer.cs | 2 + Runtime/Component/Child/SerieSymbl.cs | 28 ++++++++++++- Runtime/Serie/Heatmap/HeatmapHandler.cs | 46 ++++++++++++++++----- 6 files changed, 71 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fce9944..21e7e268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,8 @@ ## master -* (2022.09.06) 增加`AxisSplitLine`的`showStartLine`和`showEndLine`参数 +* (2022.09.06) 增加`SerieSymbol`的`minSize`和`maxSize`参数设置最大最小尺寸的支持 +* (2022.09.06) 增加`AxisSplitLine`的`showStartLine`和`showEndLine`参数设置是否显示首位分割线的支持 * (2022.09.06) 增加`Heatmap`通过`symbol`设置不同的图案的支持 * (2022.09.05) 增加`Heatmap`的`heatmapType`支持设置`Data`和`Count`两种不同映射方式的热力图 * (2022.09.05) 优化`Tooltip`在热力图为数值轴时的指示 diff --git a/Documentation/XChartsConfiguration-EN.md b/Documentation/XChartsConfiguration-EN.md index ab523e2d..676e15dd 100644 --- a/Documentation/XChartsConfiguration-EN.md +++ b/Documentation/XChartsConfiguration-EN.md @@ -1174,6 +1174,8 @@ Inherits or Implemented: [SymbolStyle](#SymbolStyle),[ISerieDataComponent](#ISer |`interval`|||the interval of show symbol. |`forceShowLast`|false||whether to show the last symbol. |`repeat`|false||图形是否重复。 +|`minSize`|0f|v3.3.0|Minimum symbol size. +|`maxSize`|0f|v3.3.0|Maximum symbol size. ## `SerieTheme` diff --git a/Documentation/XChartsConfiguration-ZH.md b/Documentation/XChartsConfiguration-ZH.md index 7fe54734..8abb88b2 100644 --- a/Documentation/XChartsConfiguration-ZH.md +++ b/Documentation/XChartsConfiguration-ZH.md @@ -1174,6 +1174,8 @@ Inherits or Implemented: [SymbolStyle](#SymbolStyle),[ISerieDataComponent](#ISer |`interval`|||显示图形标记的间隔。0表示显示所有标签,1表示隔一个隔显示一个标签,以此类推。 |`forceShowLast`|false||是否强制显示最后一个图形标记。 |`repeat`|false||图形是否重复。 +|`minSize`|0f|v3.3.0|图形最小尺寸。只在sizeType为SymbolSizeType.FromData时有效。 +|`maxSize`|0f|v3.3.0|图形最大尺寸。只在sizeType为SymbolSizeType.FromData时有效。 ## `SerieTheme` diff --git a/Editor/ChildComponents/SerieSymbolDrawer.cs b/Editor/ChildComponents/SerieSymbolDrawer.cs index 23639c5b..31a132e4 100644 --- a/Editor/ChildComponents/SerieSymbolDrawer.cs +++ b/Editor/ChildComponents/SerieSymbolDrawer.cs @@ -35,6 +35,8 @@ public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) case SymbolSizeType.FromData: PropertyField(prop, "m_DataIndex"); PropertyField(prop, "m_DataScale"); + PropertyField(prop, "m_MinSize"); + PropertyField(prop, "m_MaxSize"); break; case SymbolSizeType.Function: break; diff --git a/Runtime/Component/Child/SerieSymbl.cs b/Runtime/Component/Child/SerieSymbl.cs index 7cdc1013..c31c5bd5 100644 --- a/Runtime/Component/Child/SerieSymbl.cs +++ b/Runtime/Component/Child/SerieSymbl.cs @@ -41,6 +41,8 @@ public class SerieSymbol : SymbolStyle, ISerieDataComponent [SerializeField] private int m_Interval; [SerializeField] private bool m_ForceShowLast = false; [SerializeField] private bool m_Repeat = false; + [SerializeField][Since("v3.3.0")] private float m_MinSize = 0f; + [SerializeField][Since("v3.3.0")] private float m_MaxSize = 0f; public override void Reset() { @@ -53,6 +55,8 @@ public override void Reset() m_Interval = 0; m_ForceShowLast = false; m_Repeat = false; + m_MinSize = 0f; + m_MaxSize = 0f; } /// @@ -126,6 +130,25 @@ public bool repeat get { return m_Repeat; } set { if (PropertyUtil.SetStruct(ref m_Repeat, value)) SetAllDirty(); } } + /// + /// Minimum symbol size. + /// |图形最小尺寸。只在sizeType为SymbolSizeType.FromData时有效。 + /// + public float minSize + { + get { return m_MinSize; } + set { if (PropertyUtil.SetStruct(ref m_MinSize, value)) SetVerticesDirty(); } + } + /// + /// Maximum symbol size. + /// |图形最大尺寸。只在sizeType为SymbolSizeType.FromData时有效。 + /// + public float maxSize + { + get { return m_MaxSize; } + set { if (PropertyUtil.SetStruct(ref m_MaxSize, value)) SetVerticesDirty(); } + } + /// /// 根据指定的sizeType获得标记的大小 /// @@ -140,7 +163,10 @@ public float GetSize(List data, float themeSize) case SymbolSizeType.FromData: if (data != null && dataIndex >= 0 && dataIndex < data.Count) { - return (float) data[dataIndex] * m_DataScale; + var value = (float) data[dataIndex] * m_DataScale; + if (m_MinSize != 0 && value < m_MinSize) value = m_MinSize; + if (m_MaxSize != 0 && value > m_MaxSize) value = m_MaxSize; + return value; } else { diff --git a/Runtime/Serie/Heatmap/HeatmapHandler.cs b/Runtime/Serie/Heatmap/HeatmapHandler.cs index 83a553ef..648b37e1 100644 --- a/Runtime/Serie/Heatmap/HeatmapHandler.cs +++ b/Runtime/Serie/Heatmap/HeatmapHandler.cs @@ -187,9 +187,9 @@ private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie) var zeroX = m_SerieGrid.context.x; var zeroY = m_SerieGrid.context.y; var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0; - var rectWid = xWidth - 2 * borderWidth; - var rectHig = yWidth - 2 * borderWidth; - var defaultSymbolSize = Mathf.Min(rectWid, rectHig) * 0.25f; + var splitWid = xWidth - 2 * borderWidth; + var splitHig = yWidth - 2 * borderWidth; + var defaultSymbolSize = Mathf.Min(splitWid, splitHig) * 0.25f; serie.animation.InitProgress(0, xCount); var animationIndex = serie.animation.GetCurrIndex(); @@ -237,9 +237,8 @@ private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie) serie.context.dataPoints.Add(pos); serie.context.dataIndexs.Add(serieData.index); serieData.context.position = pos; - serieData.context.canShowLabel = false; - serieData.context.rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); + if ((value < rangeMin && rangeMin != visualMap.min) || (value > rangeMax && rangeMax != visualMap.max)) { @@ -256,9 +255,22 @@ private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie) var highlight = (serieData.context.highlight) || visualMap.context.pointerIndex > 0; - + var rectWid = 0f; + var rectHig = 0f; if (isRectSymbol) { + if (symbol.size == 0 && symbol.sizeType == SymbolSizeType.Custom) + { + rectWid = splitWid; + rectHig = splitHig; + } + else + { + var symbolSize = SerieHelper.GetSysmbolSize(serie, serieData, chart.theme, defaultSymbolSize, state); + rectWid = symbolSize; + rectHig = symbolSize; + } + serieData.context.rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); UGL.DrawRectangle(vh, serieData.context.rect, color); if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) @@ -270,6 +282,7 @@ private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie) { var symbolSize = SerieHelper.GetSysmbolSize(serie, serieData, chart.theme, defaultSymbolSize, state); var emptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, serie.context.colorIndex, state); + serieData.context.rect = new Rect(pos.x - symbolSize / 2, pos.y - symbolSize / 2, symbolSize, symbolSize); chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, color, color, emptyColor, borderColor, symbol.gap, cornerRadius); } @@ -319,9 +332,9 @@ private void DrawCountHeatmapSerie(VertexHelper vh, Heatmap serie) var zeroX = m_SerieGrid.context.x; var zeroY = m_SerieGrid.context.y; var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0; - var rectWid = xWidth - 2 * borderWidth; - var rectHig = yWidth - 2 * borderWidth; - var defaultSymbolSize = Mathf.Min(rectWid, rectHig) * 0.25f; + var splitWid = xWidth - 2 * borderWidth; + var splitHig = yWidth - 2 * borderWidth; + var defaultSymbolSize = Mathf.Min(splitWid, splitHig) * 0.25f; serie.animation.InitProgress(0, xCount); var animationIndex = serie.animation.GetCurrIndex(); @@ -403,9 +416,22 @@ private void DrawCountHeatmapSerie(VertexHelper vh, Heatmap serie) var pos = new Vector3(zeroX + (i + 0.5f) * xWidth, zeroY + (j + 0.5f) * yWidth); - var rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); + + var rectWid = 0f; + var rectHig = 0f; if (isRectSymbol) { + if (symbol.size == 0 && symbol.sizeType == SymbolSizeType.Custom) + { + rectWid = splitWid; + rectHig = splitHig; + } + else + { + rectWid = symbolSize; + rectHig = symbolSize; + } + var rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); UGL.DrawRectangle(vh, rect, color); if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) From dd6833d32295f5c39d553292abe978425867301a Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Thu, 8 Sep 2022 08:00:13 +0800 Subject: [PATCH 22/38] [feature][ring] support `LabelLine` --- CHANGELOG.md | 1 + Editor/ChildComponents/SymbolStyleDrawer.cs | 2 +- Runtime/Component/Label/LabelLine.cs | 10 ++ Runtime/Serie/Ring/Ring.cs | 4 +- Runtime/Serie/Ring/RingHandler.cs | 114 ++++++++++++++++++-- Runtime/Serie/SerieDataContext.cs | 1 + 6 files changed, 122 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21e7e268..9a6fc189 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.06) 增加`RingChart`可设置`LabelLine`引导线的支持 * (2022.09.06) 增加`SerieSymbol`的`minSize`和`maxSize`参数设置最大最小尺寸的支持 * (2022.09.06) 增加`AxisSplitLine`的`showStartLine`和`showEndLine`参数设置是否显示首位分割线的支持 * (2022.09.06) 增加`Heatmap`通过`symbol`设置不同的图案的支持 diff --git a/Editor/ChildComponents/SymbolStyleDrawer.cs b/Editor/ChildComponents/SymbolStyleDrawer.cs index d30ac905..1ae59e29 100644 --- a/Editor/ChildComponents/SymbolStyleDrawer.cs +++ b/Editor/ChildComponents/SymbolStyleDrawer.cs @@ -23,11 +23,11 @@ public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) PropertyField(prop, "m_ImageType"); PropertyField(prop, "m_Width"); PropertyField(prop, "m_Height"); - // PropertyField(prop, "m_Offset"); } PropertyField(prop, "m_Color"); PropertyField(prop, "m_Size"); PropertyField(prop, "m_Gap"); + PropertyField(prop, "m_Offset"); --EditorGUI.indentLevel; } } diff --git a/Runtime/Component/Label/LabelLine.cs b/Runtime/Component/Label/LabelLine.cs index a0b1c2c6..d092af18 100644 --- a/Runtime/Component/Label/LabelLine.cs +++ b/Runtime/Component/Label/LabelLine.cs @@ -141,5 +141,15 @@ public SymbolStyle endSymbol get { return m_EndSymbol; } set { if (PropertyUtil.SetClass(ref m_EndSymbol, value)) SetVerticesDirty(); } } + + public Vector3 GetStartSymbolOffset() + { + return m_StartSymbol != null && m_StartSymbol.show? m_StartSymbol.offset3 : Vector3.zero; + } + + public Vector3 GetEndSymbolOffset() + { + return m_EndSymbol != null && m_EndSymbol.show? m_EndSymbol.offset3 : Vector3.zero; + } } } \ No newline at end of file diff --git a/Runtime/Serie/Ring/Ring.cs b/Runtime/Serie/Ring/Ring.cs index 658bd596..6610cdd2 100644 --- a/Runtime/Serie/Ring/Ring.cs +++ b/Runtime/Serie/Ring/Ring.cs @@ -4,8 +4,8 @@ namespace XCharts.Runtime { [System.Serializable] [SerieHandler(typeof(RingHandler), true)] - [SerieExtraComponent(typeof(LabelStyle), typeof(TitleStyle), typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(TitleStyle), typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] + [SerieExtraComponent(typeof(LabelStyle), typeof(LabelLine), typeof(TitleStyle), typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] + [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(LabelLine), typeof(TitleStyle), typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] [SerieDataExtraField()] public class Ring : Serie { diff --git a/Runtime/Serie/Ring/RingHandler.cs b/Runtime/Serie/Ring/RingHandler.cs index c4a87e25..c90a7db3 100644 --- a/Runtime/Serie/Ring/RingHandler.cs +++ b/Runtime/Serie/Ring/RingHandler.cs @@ -113,6 +113,7 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label) { + var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData); var centerRadius = (serieData.context.outsideRadius + serieData.context.insideRadius) / 2; var startAngle = serieData.context.startAngle; var toAngle = serieData.context.toAngle; @@ -123,7 +124,17 @@ public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyl var px1 = Mathf.Sin(startAngle * Mathf.Deg2Rad) * centerRadius; var py1 = Mathf.Cos(startAngle * Mathf.Deg2Rad) * centerRadius; var xDiff = serie.clockwise ? -label.distance : label.distance; - serieData.context.labelPosition = serie.context.center + new Vector3(px1 + xDiff, py1); + + if (labelLine != null && labelLine.show) + { + serieData.context.labelLinePosition = serie.context.center + new Vector3(px1, py1) + labelLine.GetStartSymbolOffset(); + serieData.context.labelPosition = GetLabelLineEndPosition(serie, serieData, labelLine) + new Vector3(xDiff, 0); + } + else + { + serieData.context.labelLinePosition = serie.context.center + new Vector3(px1 + xDiff, py1); + serieData.context.labelPosition = serieData.context.labelLinePosition; + } break; case LabelStyle.Position.Top: case LabelStyle.Position.End: @@ -131,15 +142,39 @@ public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyl toAngle += serie.clockwise ? label.distance : -label.distance; var px2 = Mathf.Sin(toAngle * Mathf.Deg2Rad) * centerRadius; var py2 = Mathf.Cos(toAngle * Mathf.Deg2Rad) * centerRadius; - serieData.context.labelPosition = serie.context.center + new Vector3(px2, py2); + + if (labelLine != null && labelLine.show) + { + serieData.context.labelLinePosition = serie.context.center + new Vector3(px2, py2) + labelLine.GetStartSymbolOffset(); + serieData.context.labelPosition = GetLabelLineEndPosition(serie, serieData, labelLine); + } + else + { + serieData.context.labelLinePosition = serie.context.center + new Vector3(px2, py2); + serieData.context.labelPosition = serieData.context.labelLinePosition; + } break; default: //LabelStyle.Position.Center - serieData.context.labelPosition = serie.context.center + label.offset; + serieData.context.labelLinePosition = serie.context.center + label.offset; + serieData.context.labelPosition = serieData.context.labelLinePosition; break; } return serieData.context.labelPosition; } + private Vector3 GetLabelLineEndPosition(Serie serie, SerieData serieData, LabelLine labelLine) + { + var isRight = !serie.clockwise; + var dire = isRight ? Vector3.right : Vector3.left; + var rad = Mathf.Deg2Rad * (isRight ? labelLine.lineAngle : 180 - labelLine.lineAngle); + var lineLength1 = ChartHelper.GetActualValue(labelLine.lineLength1, serie.context.outsideRadius); + var lineLength2 = ChartHelper.GetActualValue(labelLine.lineLength2, serie.context.outsideRadius); + var pos1 = serieData.context.labelLinePosition; + var pos2 = pos1 + new Vector3(Mathf.Cos(rad) * lineLength1, Mathf.Sin(rad) * lineLength1); + var pos5 = pos2 + dire * lineLength2; + return pos5 + labelLine.GetEndSymbolOffset(); + } + public override void DrawSerie(VertexHelper vh) { if (!serie.show || serie.animation.HasFadeOut()) return; @@ -169,8 +204,8 @@ public override void DrawSerie(VertexHelper vh) var borderColor = itemStyle.borderColor; var roundCap = serie.roundCap && insideRadius > 0; - serieData.context.startAngle = serie.clockwise ? startDegree : toDegree; - serieData.context.toAngle = serie.clockwise ? toDegree : startDegree; + serieData.context.startAngle = startDegree; + serieData.context.toAngle = toDegree; serieData.context.insideRadius = insideRadius; serieData.context.outsideRadius = serieData.radius > 0 ? serieData.radius : outsideRadius; DrawBackground(vh, serie, serieData, j, insideRadius, outsideRadius); @@ -178,6 +213,12 @@ public override void DrawSerie(VertexHelper vh) Color.clear, startDegree, toDegree, borderWidth, borderColor, 0, chart.settings.cicleSmoothness, roundCap, serie.clockwise); DrawCenter(vh, serie, serieData, insideRadius, j == data.Count - 1); + + var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); + if (SerieLabelHelper.CanShowLabel(serie, serieData, serieLabel, 0)) + { + DrawRingLabelLine(vh, serie, serieData, itemColor); + } } if (!serie.animation.IsFinish()) { @@ -304,8 +345,7 @@ private int GetRingIndex(Vector2 local) var serieData = serie.data[i]; if (dist >= serieData.context.insideRadius && dist <= serieData.context.outsideRadius && - angle >= serieData.context.startAngle && - angle <= serieData.context.toAngle) + IsInAngle(serieData, angle, serie.clockwise)) { return i; } @@ -313,6 +353,14 @@ private int GetRingIndex(Vector2 local) return -1; } + private bool IsInAngle(SerieData serieData, float angle, bool clockwise) + { + if (clockwise) + return angle >= serieData.context.startAngle && angle <= serieData.context.toAngle; + else + return angle >= serieData.context.toAngle && angle <= serieData.context.startAngle; + } + private float VectorAngle(Vector2 from, Vector2 to) { float angle; @@ -323,5 +371,57 @@ private float VectorAngle(Vector2 from, Vector2 to) angle = (angle + 360) % 360; return angle; } + + private void DrawRingLabelLine(VertexHelper vh, Serie serie, SerieData serieData, Color32 defaltColor) + { + var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); + var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData); + if (serieLabel != null && serieLabel.show && + labelLine != null && labelLine.show) + { + var color = ChartHelper.IsClearColor(labelLine.lineColor) ? + ChartHelper.GetHighlightColor(defaltColor, 0.9f) : + labelLine.lineColor; + var isRight = !serie.clockwise; + var dire = isRight ? Vector3.right : Vector3.left; + var rad = Mathf.Deg2Rad * (isRight ? labelLine.lineAngle : 180 - labelLine.lineAngle); + var lineLength1 = ChartHelper.GetActualValue(labelLine.lineLength1, serie.context.outsideRadius); + var lineLength2 = ChartHelper.GetActualValue(labelLine.lineLength2, serie.context.outsideRadius); + var pos1 = serieData.context.labelLinePosition; + var pos2 = pos1 + new Vector3(Mathf.Cos(rad) * lineLength1, Mathf.Sin(rad) * lineLength1); + var pos5 = pos2 + dire * lineLength2 + labelLine.GetEndSymbolOffset(); + serieData.context.labelPosition = pos5; + switch (labelLine.lineType) + { + case LabelLine.LineType.BrokenLine: + UGL.DrawLine(vh, pos1, pos2, pos5, labelLine.lineWidth, color); + break; + case LabelLine.LineType.Curves: + UGL.DrawCurves(vh, pos1, pos5, pos1, pos2, labelLine.lineWidth, color, + chart.settings.lineSmoothness, UGL.Direction.XAxis); + break; + case LabelLine.LineType.HorizontalLine: + pos5 = pos1 + dire * (lineLength1 + lineLength2); + serieData.context.labelPosition = pos5; + UGL.DrawLine(vh, pos1, pos5, labelLine.lineWidth, color); + break; + } + if (labelLine.startSymbol != null && labelLine.startSymbol.show) + { + DrawSymbol(vh, labelLine.startSymbol, pos1, color); + } + if (labelLine.endSymbol != null && labelLine.endSymbol.show) + { + DrawSymbol(vh, labelLine.endSymbol, pos5, color); + } + } + } + + private void DrawSymbol(VertexHelper vh, SymbolStyle symbol, Vector3 pos, Color32 defaultColor) + { + var color = symbol.GetColor(defaultColor); + chart.DrawSymbol(vh, symbol.type, symbol.size, 1, pos, + color, color, ColorUtil.clearColor32, color, symbol.gap, null); + } } } \ No newline at end of file diff --git a/Runtime/Serie/SerieDataContext.cs b/Runtime/Serie/SerieDataContext.cs index d2bdf499..f549c9f9 100644 --- a/Runtime/Serie/SerieDataContext.cs +++ b/Runtime/Serie/SerieDataContext.cs @@ -7,6 +7,7 @@ namespace XCharts.Runtime public class SerieDataContext { public Vector3 labelPosition; + public Vector3 labelLinePosition; /// /// 开始角度 /// From ac7628ce68813903a7159deaabb0163aff3c4956 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Fri, 9 Sep 2022 13:19:22 +0800 Subject: [PATCH 23/38] [bug] fix editor auto refresh bug --- CHANGELOG.md | 3 ++- Runtime/Internal/BaseChart.API.cs | 5 +++++ Runtime/Internal/BaseGraph.API.cs | 2 +- Runtime/Internal/BaseGraph.cs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a6fc189..1e6e135a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,8 @@ ## master -* (2022.09.06) 增加`RingChart`可设置`LabelLine`引导线的支持 +* (2022.09.09) 修复`Editor`下编辑参数部分组件可能不会实时刷新的问题 +* (2022.09.08) 增加`RingChart`可设置`LabelLine`引导线的支持 * (2022.09.06) 增加`SerieSymbol`的`minSize`和`maxSize`参数设置最大最小尺寸的支持 * (2022.09.06) 增加`AxisSplitLine`的`showStartLine`和`showEndLine`参数设置是否显示首位分割线的支持 * (2022.09.06) 增加`Heatmap`通过`symbol`设置不同的图案的支持 diff --git a/Runtime/Internal/BaseChart.API.cs b/Runtime/Internal/BaseChart.API.cs index db3b70f9..765355c1 100644 --- a/Runtime/Internal/BaseChart.API.cs +++ b/Runtime/Internal/BaseChart.API.cs @@ -157,6 +157,11 @@ public void RefreshChart() if (m_PainterTop) m_PainterTop.Refresh(); } + public override void RefreshGraph() + { + RefreshChart(); + } + /// /// Redraw chart serie in next frame. /// |在下一帧刷新图表的指定serie。 diff --git a/Runtime/Internal/BaseGraph.API.cs b/Runtime/Internal/BaseGraph.API.cs index a9290229..f2c9c945 100644 --- a/Runtime/Internal/BaseGraph.API.cs +++ b/Runtime/Internal/BaseGraph.API.cs @@ -120,7 +120,7 @@ public void SetPainterDirty() /// Redraw graph in next frame. /// |在下一帧刷新图形。 /// - public void RefreshGraph() + public virtual void RefreshGraph() { m_RefreshChart = true; } diff --git a/Runtime/Internal/BaseGraph.cs b/Runtime/Internal/BaseGraph.cs index 28b212dc..f5e52e10 100644 --- a/Runtime/Internal/BaseGraph.cs +++ b/Runtime/Internal/BaseGraph.cs @@ -80,9 +80,9 @@ protected virtual void Update() if (m_IsOnValidate) { m_IsOnValidate = false; - m_RefreshChart = true; CheckTextMeshPro(); InitComponent(); + RefreshGraph(); } else { From afbfa20fd9bbe5dad5b34ee14bdae25f8cd14029 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Wed, 14 Sep 2022 07:13:45 +0800 Subject: [PATCH 24/38] [feature][polar] support circular polar --- CHANGELOG.md | 1 + Editor/MainComponents/PolarCoordEditor.cs | 2 +- .../Axis/AngleAxis/AngleAxisHandler.cs | 6 +++--- .../Axis/RadiusAxis/RadiusAxisHandler.cs | 12 +++++++----- Runtime/Component/Radar/RadarCoordHandler.cs | 1 + Runtime/Component/Tooltip/TooltipHandler.cs | 2 +- Runtime/Coord/Polar/PolarCoord.cs | 11 ++++++----- Runtime/Coord/Polar/PolarCoordContext.cs | 10 ++++++++-- Runtime/Coord/Polar/PolarCoordHandler.cs | 18 ++++++++++++++++-- Runtime/Coord/Polar/PolarHelper.cs | 17 +++++------------ Runtime/Serie/Line/LineHandler.PolarCoord.cs | 2 +- 11 files changed, 50 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e6e135a..7a266932 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.14) 增加`PolarCoord`可通过`radius`设置环形极坐标的支持 * (2022.09.09) 修复`Editor`下编辑参数部分组件可能不会实时刷新的问题 * (2022.09.08) 增加`RingChart`可设置`LabelLine`引导线的支持 * (2022.09.06) 增加`SerieSymbol`的`minSize`和`maxSize`参数设置最大最小尺寸的支持 diff --git a/Editor/MainComponents/PolarCoordEditor.cs b/Editor/MainComponents/PolarCoordEditor.cs index 8d359e74..28d867a6 100644 --- a/Editor/MainComponents/PolarCoordEditor.cs +++ b/Editor/MainComponents/PolarCoordEditor.cs @@ -10,7 +10,7 @@ public override void OnInspectorGUI() { ++EditorGUI.indentLevel; PropertyTwoFiled("m_Center"); - PropertyField("m_Radius"); + PropertyTwoFiled("m_Radius"); PropertyField("m_BackgroundColor"); --EditorGUI.indentLevel; } diff --git a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs index b2c02b48..e29dfb79 100644 --- a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs +++ b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs @@ -61,7 +61,7 @@ private void InitAngleAxis(AngleAxis axis) var polar = chart.GetChartComponent(axis.polarIndex); if (polar == null) return; PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight); - var radius = polar.context.radius; + var radius = polar.context.outsideRadius; axis.context.labelObjectList.Clear(); axis.context.startAngle = 90 - axis.startAngle; @@ -103,7 +103,7 @@ private void InitAngleAxis(AngleAxis axis) private void DrawAngleAxis(VertexHelper vh, AngleAxis angleAxis) { var polar = chart.GetChartComponent(angleAxis.polarIndex); - var radius = polar.context.radius; + var radius = polar.context.outsideRadius; var cenPos = polar.context.center; var total = 360; var size = AxisHelper.GetScaleNumber(angleAxis, total, null); @@ -158,7 +158,7 @@ protected override void UpdatePointerValue(Axis axis) var dir = (chart.pointerPos - new Vector2(polar.context.center.x, polar.context.center.y)).normalized; var angle = ChartHelper.GetAngle360(Vector2.up, dir); axis.context.pointerValue = (angle - component.context.startAngle + 360) % 360; - axis.context.pointerLabelPosition = polar.context.center + new Vector3(dir.x, dir.y) * (polar.context.radius + 25); + axis.context.pointerLabelPosition = polar.context.center + new Vector3(dir.x, dir.y) * (polar.context.outsideRadius + 25); } } } \ No newline at end of file diff --git a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs index 4ea89808..bf840307 100644 --- a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs +++ b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs @@ -74,7 +74,9 @@ internal void UpdateAxisLabelText(RadiusAxis axis) if (axis.context.labelObjectList.Count <= 0) InitRadiusAxis(axis); else + { axis.UpdateLabelText(polar.context.radius, null, false); + } } private void InitRadiusAxis(RadiusAxis axis) @@ -89,7 +91,7 @@ private void InitRadiusAxis(RadiusAxis axis) PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight); axis.context.labelObjectList.Clear(); - var radius = polar.context.radius; + var radius = polar.context.outsideRadius - polar.context.insideRadius; var objName = component.GetType().Name + axis.index; var axisObj = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor, chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); @@ -99,7 +101,7 @@ private void InitRadiusAxis(RadiusAxis axis) ChartHelper.HideAllObject(axisObj); var textStyle = axis.axisLabel.textStyle; var splitNumber = AxisHelper.GetScaleNumber(axis, radius, null); - var totalWidth = 0f; + var totalWidth = polar.context.insideRadius; var txtHig = textStyle.GetFontSize(chart.theme.axis) + 2; for (int i = 0; i < splitNumber; i++) { @@ -150,7 +152,7 @@ private void DrawRadiusAxis(VertexHelper vh, RadiusAxis radiusAxis) var radius = polar.context.radius; var cenPos = polar.context.center; var size = AxisHelper.GetScaleNumber(radiusAxis, radius, null); - var totalWidth = 0f; + var totalWidth = polar.context.insideRadius; var dire = ChartHelper.GetDire(startAngle, true).normalized; var tickWidth = radiusAxis.axisTick.GetWidth(chart.theme.axis.tickWidth); var tickLength = radiusAxis.axisTick.GetLength(chart.theme.axis.tickLength); @@ -178,8 +180,8 @@ private void DrawRadiusAxis(VertexHelper vh, RadiusAxis radiusAxis) } if (radiusAxis.show && radiusAxis.axisLine.show) { - var lineStartPos = polar.context.center - dire * tickWidth; - var lineEndPos = polar.context.center + dire * (radius + tickWidth); + var lineStartPos = polar.context.center + dire * polar.context.insideRadius; + var lineEndPos = polar.context.center + dire * (polar.context.outsideRadius + 2 * tickWidth); var lineWidth = radiusAxis.axisLine.GetWidth(chart.theme.axis.lineWidth); UGL.DrawLine(vh, lineStartPos, lineEndPos, lineWidth, chart.theme.axis.lineColor); } diff --git a/Runtime/Component/Radar/RadarCoordHandler.cs b/Runtime/Component/Radar/RadarCoordHandler.cs index 3ffdf003..add4ada8 100644 --- a/Runtime/Component/Radar/RadarCoordHandler.cs +++ b/Runtime/Component/Radar/RadarCoordHandler.cs @@ -17,6 +17,7 @@ public override void InitComponent() public override void Update() { + base.Update(); if (!chart.isPointerInChart) { component.context.isPointerEnter = false; diff --git a/Runtime/Component/Tooltip/TooltipHandler.cs b/Runtime/Component/Tooltip/TooltipHandler.cs index 05a356de..372305d9 100644 --- a/Runtime/Component/Tooltip/TooltipHandler.cs +++ b/Runtime/Component/Tooltip/TooltipHandler.cs @@ -646,7 +646,7 @@ private void DrawPolarIndicator(VertexHelper vh, Tooltip tooltip, PolarCoord m_P var lineType = tooltip.lineStyle.GetType(theme.tooltip.lineType); var lineWidth = tooltip.lineStyle.GetWidth(theme.tooltip.lineWidth); var cenPos = m_Polar.context.center; - var radius = m_Polar.context.radius; + var radius = m_Polar.context.outsideRadius; var sp = m_Polar.context.center; var tooltipAngle = m_AngleAxis.GetValueAngle(tooltip.context.angle); diff --git a/Runtime/Coord/Polar/PolarCoord.cs b/Runtime/Coord/Polar/PolarCoord.cs index b251c932..a68ea39c 100644 --- a/Runtime/Coord/Polar/PolarCoord.cs +++ b/Runtime/Coord/Polar/PolarCoord.cs @@ -14,7 +14,7 @@ public class PolarCoord : CoordSystem, ISerieContainer { [SerializeField] private bool m_Show = true; [SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.45f }; - [SerializeField] private float m_Radius = 0.35f; + [SerializeField] private float[] m_Radius = new float[2] { 0, 0.35f }; [SerializeField] private Color m_BackgroundColor; public PolarCoordContext context = new PolarCoordContext(); @@ -41,12 +41,12 @@ public float[] center } /// /// the radius of polar. - /// |极坐标的半径。 + /// |半径。radius[0]表示内径,radius[1]表示外径。 /// - public float radius + public float[] radius { get { return m_Radius; } - set { if (PropertyUtil.SetStruct(ref m_Radius, value)) SetAllDirty(); } + set { if (value != null && value.Length == 2) { m_Radius = value; SetAllDirty(); } } } /// /// Background color of polar, which is transparent by default. @@ -65,7 +65,8 @@ public bool IsPointerEnter() public bool Contains(Vector3 pos) { - return Vector3.Distance(pos, context.center) < context.radius; + var dist = Vector3.Distance(pos, context.center); + return dist >= context.insideRadius && dist <= context.outsideRadius; } } } \ No newline at end of file diff --git a/Runtime/Coord/Polar/PolarCoordContext.cs b/Runtime/Coord/Polar/PolarCoordContext.cs index 035c2ca9..f2909b6f 100644 --- a/Runtime/Coord/Polar/PolarCoordContext.cs +++ b/Runtime/Coord/Polar/PolarCoordContext.cs @@ -10,11 +10,17 @@ public class PolarCoordContext : MainComponentContext /// |极坐标在容器中的具体中心点。 /// public Vector3 center; + public float radius; /// /// the true radius of polar. - /// |极坐标的运行时实际半径。 + /// |极坐标的运行时实际内半径。 /// - public float radius; + public float insideRadius; + /// + /// the true radius of polar. + /// |极坐标的运行时实际外半径。 + /// + public float outsideRadius; public bool isPointerEnter; } } \ No newline at end of file diff --git a/Runtime/Coord/Polar/PolarCoordHandler.cs b/Runtime/Coord/Polar/PolarCoordHandler.cs index 7c176a87..182c8be7 100644 --- a/Runtime/Coord/Polar/PolarCoordHandler.cs +++ b/Runtime/Coord/Polar/PolarCoordHandler.cs @@ -10,6 +10,7 @@ internal sealed class PolarCoordHandler : MainComponentHandler { public override void Update() { + base.Update(); PolarHelper.UpdatePolarCenter(component, chart.chartPosition, chart.chartWidth, chart.chartHeight); if (chart.isPointerInChart) @@ -26,9 +27,22 @@ public override void DrawBase(VertexHelper vh) private void DrawPolar(VertexHelper vh, PolarCoord polar) { PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight); - if (!ChartHelper.IsClearColor(polar.backgroundColor)) + if (polar.show && !ChartHelper.IsClearColor(polar.backgroundColor)) { - UGL.DrawCricle(vh, polar.context.center, polar.context.radius, polar.backgroundColor); + if (polar.context.insideRadius > 0) + { + UGL.DrawDoughnut(vh, polar.context.center, + polar.context.insideRadius, + polar.context.outsideRadius, + polar.backgroundColor, + ColorUtil.clearColor32); + } + else + { + UGL.DrawCricle(vh, polar.context.center, + polar.context.outsideRadius, + polar.backgroundColor); + } } } } diff --git a/Runtime/Coord/Polar/PolarHelper.cs b/Runtime/Coord/Polar/PolarHelper.cs index fa51a52a..72260e41 100644 --- a/Runtime/Coord/Polar/PolarHelper.cs +++ b/Runtime/Coord/Polar/PolarHelper.cs @@ -9,19 +9,12 @@ public static void UpdatePolarCenter(PolarCoord polar, Vector3 chartPosition, fl if (polar.center.Length < 2) return; var centerX = polar.center[0] <= 1 ? chartWidth * polar.center[0] : polar.center[0]; var centerY = polar.center[1] <= 1 ? chartHeight * polar.center[1] : polar.center[1]; + var minWidth = Mathf.Min(chartWidth, chartHeight); + polar.context.center = chartPosition + new Vector3(centerX, centerY); - if (polar.radius <= 0) - { - polar.context.radius = 0; - } - else if (polar.radius <= 1) - { - polar.context.radius = Mathf.Min(chartWidth, chartHeight) * polar.radius; - } - else - { - polar.context.radius = polar.radius; - } + polar.context.insideRadius = polar.radius[0] <= 1 ? minWidth * polar.radius[0] : polar.radius[0]; + polar.context.outsideRadius = polar.radius[1] <= 1 ? minWidth * polar.radius[1] : polar.radius[1]; + polar.context.radius = polar.context.outsideRadius - polar.context.insideRadius; } } } \ No newline at end of file diff --git a/Runtime/Serie/Line/LineHandler.PolarCoord.cs b/Runtime/Serie/Line/LineHandler.PolarCoord.cs index 9b1c5ae9..600dfe7e 100644 --- a/Runtime/Serie/Line/LineHandler.PolarCoord.cs +++ b/Runtime/Serie/Line/LineHandler.PolarCoord.cs @@ -111,7 +111,7 @@ private void DrawPolarLine(VertexHelper vh, Serie serie) return; var startAngle = m_AngleAxis.startAngle; - var radius = m_SeriePolar.context.radius; + var radius = m_SeriePolar.context.outsideRadius; var min = m_RadiusAxis.context.minValue; var max = m_RadiusAxis.context.maxValue; From ba9faa8bc618e8dd0b1ef11299cb1615071fd83a Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Fri, 16 Sep 2022 08:03:14 +0800 Subject: [PATCH 25/38] [feature][polar] support bar and ring polar --- CHANGELOG.md | 1 + Runtime/Component/Axis/AngleAxis/AngleAxis.cs | 5 + .../Axis/AngleAxis/AngleAxisHandler.cs | 8 +- .../Axis/RadiusAxis/RadiusAxisHandler.cs | 25 ++- Runtime/Coord/Polar/PolarHelper.cs | 13 ++ Runtime/Internal/BaseChart.Component.cs | 6 + Runtime/Internal/BaseChart.cs | 34 ++-- Runtime/Serie/Bar/Bar.cs | 2 +- Runtime/Serie/Bar/BarHandler.PolarCoord.cs | 183 ++++++++++++++++++ .../Serie/Bar/BarHandler.PolarCoord.cs.meta | 11 ++ Runtime/Serie/Bar/BarHandler.cs | 20 +- Runtime/Serie/Line/LineHandler.GridCoord.cs | 2 - Runtime/Serie/Line/LineHandler.PolarCoord.cs | 34 +--- 13 files changed, 283 insertions(+), 61 deletions(-) create mode 100644 Runtime/Serie/Bar/BarHandler.PolarCoord.cs create mode 100644 Runtime/Serie/Bar/BarHandler.PolarCoord.cs.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a266932..a7d201d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.16) 增加`PolarChart`对`Bar`柱图的支持 * (2022.09.14) 增加`PolarCoord`可通过`radius`设置环形极坐标的支持 * (2022.09.09) 修复`Editor`下编辑参数部分组件可能不会实时刷新的问题 * (2022.09.08) 增加`RingChart`可设置`LabelLine`引导线的支持 diff --git a/Runtime/Component/Axis/AngleAxis/AngleAxis.cs b/Runtime/Component/Axis/AngleAxis/AngleAxis.cs index 46909d73..51436a3c 100644 --- a/Runtime/Component/Axis/AngleAxis/AngleAxis.cs +++ b/Runtime/Component/Axis/AngleAxis/AngleAxis.cs @@ -29,6 +29,11 @@ public float GetValueAngle(float value) return (value + context.startAngle + 360) % 360; } + public float GetValueAngle(double value) + { + return (float) (value + context.startAngle + 360) % 360; + } + public override void SetDefaultValue() { m_Show = true; diff --git a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs index e29dfb79..c464b8c0 100644 --- a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs +++ b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs @@ -139,7 +139,13 @@ private void DrawAngleAxis(VertexHelper vh, AngleAxis angleAxis) { var lineWidth = angleAxis.axisLine.GetWidth(chart.theme.axis.lineWidth); var outsideRaidus = radius + lineWidth * 2; - UGL.DrawDoughnut(vh, cenPos, radius, outsideRaidus, lineColor, Color.clear); + UGL.DrawDoughnut(vh, cenPos, radius, outsideRaidus, lineColor, ColorUtil.clearColor32); + if (polar.context.insideRadius > 0) + { + radius = polar.context.insideRadius; + outsideRaidus = radius + lineWidth * 2; + UGL.DrawDoughnut(vh, cenPos, radius, outsideRaidus, lineColor, ColorUtil.clearColor32); + } } } diff --git a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs index bf840307..2eb27023 100644 --- a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs +++ b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs @@ -157,15 +157,18 @@ private void DrawRadiusAxis(VertexHelper vh, RadiusAxis radiusAxis) var tickWidth = radiusAxis.axisTick.GetWidth(chart.theme.axis.tickWidth); var tickLength = radiusAxis.axisTick.GetLength(chart.theme.axis.tickLength); var tickVetor = ChartHelper.GetVertialDire(dire) * tickLength; - for (int i = 0; i <= size; i++) + for (int i = 0; i < size; i++) { - var scaleWidth = AxisHelper.GetScaleWidth(radiusAxis, radius, i); + var scaleWidth = AxisHelper.GetScaleWidth(radiusAxis, radius, i + 1); var pos = ChartHelper.GetPos(cenPos, totalWidth + tickWidth, startAngle, true); if (radiusAxis.show && radiusAxis.splitLine.show) { - var outsideRaidus = totalWidth + radiusAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth) * 2; - var splitLineColor = radiusAxis.splitLine.GetColor(chart.theme.axis.splitLineColor); - UGL.DrawDoughnut(vh, cenPos, totalWidth, outsideRaidus, splitLineColor, Color.clear); + if (CanDrawSplitLine(angleAxis, i, size)) + { + var outsideRaidus = totalWidth + radiusAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth) * 2; + var splitLineColor = radiusAxis.splitLine.GetColor(chart.theme.axis.splitLineColor); + UGL.DrawDoughnut(vh, cenPos, totalWidth, outsideRaidus, splitLineColor, Color.clear); + } } if (radiusAxis.show && radiusAxis.axisTick.show) { @@ -186,5 +189,17 @@ private void DrawRadiusAxis(VertexHelper vh, RadiusAxis radiusAxis) UGL.DrawLine(vh, lineStartPos, lineEndPos, lineWidth, chart.theme.axis.lineColor); } } + + private bool CanDrawSplitLine(AngleAxis angleAxis, int i, int size) + { + if (angleAxis.axisLine.show) + { + return i != size - 1 && i != 0; + } + else + { + return true; + } + } } } \ No newline at end of file diff --git a/Runtime/Coord/Polar/PolarHelper.cs b/Runtime/Coord/Polar/PolarHelper.cs index 72260e41..8cfc7196 100644 --- a/Runtime/Coord/Polar/PolarHelper.cs +++ b/Runtime/Coord/Polar/PolarHelper.cs @@ -16,5 +16,18 @@ public static void UpdatePolarCenter(PolarCoord polar, Vector3 chartPosition, fl polar.context.outsideRadius = polar.radius[1] <= 1 ? minWidth * polar.radius[1] : polar.radius[1]; polar.context.radius = polar.context.outsideRadius - polar.context.insideRadius; } + + public static Vector3 UpdatePolarAngleAndPos(PolarCoord polar, AngleAxis angleAxis, RadiusAxis radiusAxis, SerieData serieData) + { + var value = serieData.GetData(0); + var angle = angleAxis.GetValueAngle(serieData.GetData(1)); + var radius = polar.context.insideRadius + radiusAxis.GetValueLength(value, polar.context.radius); + + angle = (angle + 360) % 360; + serieData.context.angle = angle; + serieData.context.position = ChartHelper.GetPos(polar.context.center, radius, angle, true); + + return serieData.context.position; + } } } \ No newline at end of file diff --git a/Runtime/Internal/BaseChart.Component.cs b/Runtime/Internal/BaseChart.Component.cs index fdf14c28..b989f2d9 100644 --- a/Runtime/Internal/BaseChart.Component.cs +++ b/Runtime/Internal/BaseChart.Component.cs @@ -443,6 +443,12 @@ internal string GetTooltipCategory(int dataIndex, Serie serie, DataZoom dataZoom internal bool GetSerieGridCoordAxis(Serie serie, out Axis axis, out Axis relativedAxis) { var yAxis = GetChartComponent(serie.yAxisIndex); + if (yAxis == null) + { + axis = null; + relativedAxis = null; + return false; + } var isY = yAxis.IsCategory(); if (isY) { diff --git a/Runtime/Internal/BaseChart.cs b/Runtime/Internal/BaseChart.cs index 3aa80d66..23cbca1e 100644 --- a/Runtime/Internal/BaseChart.cs +++ b/Runtime/Internal/BaseChart.cs @@ -579,23 +579,25 @@ protected virtual void OnDrawPainterSerie(VertexHelper vh, Painter painter) serie.context.dataIndexs.Clear(); serie.context.dataIgnores.Clear(); serie.animation.context.isAllItemAnimationEnd = true; - if (!serie.context.pointerEnter) - serie.ResetInteract(); - - if (m_OnDrawSerieBefore != null) - { - m_OnDrawSerieBefore.Invoke(vh, serie); - } - DrawPainterSerie(vh, serie); - if (i >= 0 && i < m_SerieHandlers.Count) + if (serie.show && !serie.animation.HasFadeOut()) { - var handler = m_SerieHandlers[i]; - handler.DrawSerie(vh); - handler.RefreshLabelNextFrame(); - } - if (m_OnDrawSerieAfter != null) - { - m_OnDrawSerieAfter(vh, serie); + if (!serie.context.pointerEnter) + serie.ResetInteract(); + if (m_OnDrawSerieBefore != null) + { + m_OnDrawSerieBefore.Invoke(vh, serie); + } + DrawPainterSerie(vh, serie); + if (i >= 0 && i < m_SerieHandlers.Count) + { + var handler = m_SerieHandlers[i]; + handler.DrawSerie(vh); + handler.RefreshLabelNextFrame(); + } + if (m_OnDrawSerieAfter != null) + { + m_OnDrawSerieAfter(vh, serie); + } } serie.context.vertCount = vh.currentVertCount; } diff --git a/Runtime/Serie/Bar/Bar.cs b/Runtime/Serie/Bar/Bar.cs index c02e83cb..bd3c1031 100644 --- a/Runtime/Serie/Bar/Bar.cs +++ b/Runtime/Serie/Bar/Bar.cs @@ -3,7 +3,7 @@ namespace XCharts.Runtime [System.Serializable] [SerieHandler(typeof(BarHandler), true)] [SerieConvert(typeof(Line), typeof(Pie))] - [RequireChartComponent(typeof(GridCoord))] + [CoordOptions(typeof(GridCoord), typeof(PolarCoord))] [DefaultAnimation(AnimationType.BottomToTop)] [SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] diff --git a/Runtime/Serie/Bar/BarHandler.PolarCoord.cs b/Runtime/Serie/Bar/BarHandler.PolarCoord.cs new file mode 100644 index 00000000..f44f0ee4 --- /dev/null +++ b/Runtime/Serie/Bar/BarHandler.PolarCoord.cs @@ -0,0 +1,183 @@ +using UnityEngine; +using UnityEngine.UI; +using XUGL; + +namespace XCharts.Runtime +{ + /// + /// For polar coord + /// + internal sealed partial class BarHandler + { + private PolarCoord m_SeriePolar; + + private void UpdateSeriePolarContext() + { + if (m_SeriePolar == null) + return; + + var needCheck = (chart.isPointerInChart && m_SeriePolar.IsPointerEnter()) || m_LegendEnter; + var lineWidth = 0f; + if (!needCheck) + { + if (m_LastCheckContextFlag != needCheck) + { + var needAnimation1 = false; + lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); + m_LastCheckContextFlag = needCheck; + serie.context.pointerItemDataIndex = -1; + serie.context.pointerEnter = false; + serie.interact.SetValue(ref needAnimation1, lineWidth, false); + foreach (var serieData in serie.data) + { + var symbol = SerieHelper.GetSerieSymbol(serie, serieData); + var symbolSize = symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); + serieData.context.highlight = false; + serieData.interact.SetValue(ref needAnimation1, symbolSize); + } + if (needAnimation1) + { + if (SeriesHelper.IsStack(chart.series)) + chart.RefreshTopPainter(); + else + chart.RefreshPainter(serie); + } + } + return; + } + m_LastCheckContextFlag = needCheck; + var themeSymbolSize = chart.theme.serie.lineSymbolSize; + lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); + + var needInteract = false; + if (m_LegendEnter) + { + serie.context.pointerEnter = true; + serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate); + for (int i = 0; i < serie.dataCount; i++) + { + var serieData = serie.data[i]; + var size = SerieHelper.GetSysmbolSize(serie, serieData, chart.theme, themeSymbolSize, SerieState.Emphasis); + serieData.context.highlight = true; + serieData.interact.SetValue(ref needInteract, size); + } + } + else + { + serie.context.pointerItemDataIndex = -1; + serie.context.pointerEnter = false; + var dir = chart.pointerPos - new Vector2(m_SeriePolar.context.center.x, m_SeriePolar.context.center.y); + var pointerAngle = ChartHelper.GetAngle360(Vector2.up, dir); + var pointerRadius = Vector2.Distance(chart.pointerPos, m_SeriePolar.context.center); + Color32 color, toColor; + for (int i = 0; i < serie.dataCount; i++) + { + var serieData = serie.data[i]; + if (pointerAngle >= serieData.context.startAngle && + pointerAngle < serieData.context.toAngle && + pointerRadius >= serieData.context.insideRadius && + pointerRadius < serieData.context.outsideRadius) + { + serie.context.pointerItemDataIndex = i; + serie.context.pointerEnter = true; + serieData.context.highlight = true; + } + else + { + serieData.context.highlight = false; + } + var state = SerieHelper.GetSerieState(serie, serieData, true); + SerieHelper.GetItemColor(out color, out toColor, serie, serieData, chart.theme, state); + serieData.interact.SetColor(ref needInteract, color, toColor); + } + } + if (needInteract) + { + if (SeriesHelper.IsStack(chart.series)) + chart.RefreshTopPainter(); + else + chart.RefreshPainter(serie); + } + } + + private void DrawPolarBar(VertexHelper vh, Serie serie) + { + var datas = serie.data; + if (datas.Count <= 0) + return; + + m_SeriePolar = chart.GetChartComponent(serie.polarIndex); + if (m_SeriePolar == null) + return; + + var m_AngleAxis = ComponentHelper.GetAngleAxis(chart.components, m_SeriePolar.index); + var m_RadiusAxis = ComponentHelper.GetRadiusAxis(chart.components, m_SeriePolar.index); + if (m_AngleAxis == null || m_RadiusAxis == null) + return; + + var startAngle = m_AngleAxis.context.startAngle; + var currDetailProgress = 0f; + var totalDetailProgress = datas.Count; + + serie.animation.InitProgress(currDetailProgress, totalDetailProgress); + + var isStack = SeriesHelper.IsStack(chart.series, serie.stack); + if (isStack) + SeriesHelper.UpdateStackDataList(chart.series, serie, null, m_StackSerieData); + + var barCount = chart.GetSerieBarRealCount(); + float categoryWidth = AxisHelper.GetDataWidth(m_AngleAxis, 360, datas.Count, null); + float barGap = chart.GetSerieBarGap(); + float totalBarWidth = chart.GetSerieTotalWidth(categoryWidth, barGap, barCount); + float barWidth = serie.GetBarWidth(categoryWidth, barCount); + float offset = (categoryWidth - totalBarWidth) * 0.5f; + //var serieReadIndex = chart.GetSerieIndexIfStack(serie); + //float gap = serie.barGap == -1 ? offset : offset + chart.GetSerieTotalGap(categoryWidth, barGap, serieReadIndex); + + var areaColor = ColorUtil.clearColor32; + var areaToColor = ColorUtil.clearColor32; + var interacting = false; + + for (int i = 0; i < datas.Count; i++) + { + if (serie.animation.CheckDetailBreak(i)) + break; + var serieData = datas[i]; + var value = serieData.GetData(1); + var start = startAngle + categoryWidth * i + offset; + var end = start + barWidth; + var itemStyle = SerieHelper.GetItemStyle(serie, serieData); + var borderWidth = itemStyle.borderWidth; + var borderColor = itemStyle.borderColor; + + serieData.context.startAngle = start; + serieData.context.toAngle = end; + + if (!serieData.interact.TryGetColor(ref areaColor, ref areaToColor, ref interacting)) + { + SerieHelper.GetItemColor(out areaColor, out areaToColor, serie, serieData, chart.theme); + serieData.interact.SetColor(ref interacting, areaColor, areaToColor); + } + + var inside = m_SeriePolar.context.insideRadius; + var outside = inside + m_RadiusAxis.GetValueLength(value, m_SeriePolar.context.radius); + var needRoundCap = serie.roundCap && inside > 0; + + serieData.context.insideRadius = inside; + serieData.context.outsideRadius = outside; + serieData.context.position = ChartHelper.GetPosition(m_SeriePolar.context.center, (inside + outside) / 2, outside); + + UGL.DrawDoughnut(vh, m_SeriePolar.context.center, inside, outside, areaColor, areaToColor, + ColorUtil.clearColor32, start, end, borderWidth, borderColor, serie.gap / 2, chart.settings.cicleSmoothness, + needRoundCap, true); + } + + if (!serie.animation.IsFinish()) + { + serie.animation.CheckProgress(totalDetailProgress); + serie.animation.CheckSymbol(serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize)); + chart.RefreshChart(); + } + } + } +} \ No newline at end of file diff --git a/Runtime/Serie/Bar/BarHandler.PolarCoord.cs.meta b/Runtime/Serie/Bar/BarHandler.PolarCoord.cs.meta new file mode 100644 index 00000000..30d890fb --- /dev/null +++ b/Runtime/Serie/Bar/BarHandler.PolarCoord.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 152848d4f7ed84b0491d277fd55b64ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Serie/Bar/BarHandler.cs b/Runtime/Serie/Bar/BarHandler.cs index 5b4558ff..8537a821 100644 --- a/Runtime/Serie/Bar/BarHandler.cs +++ b/Runtime/Serie/Bar/BarHandler.cs @@ -7,7 +7,7 @@ namespace XCharts.Runtime { [UnityEngine.Scripting.Preserve] - internal sealed class BarHandler : SerieHandler + internal sealed partial class BarHandler : SerieHandler { List> m_StackSerieData = new List>(); private GridCoord m_SerieGrid; @@ -16,7 +16,10 @@ internal sealed class BarHandler : SerieHandler public override void Update() { base.Update(); - UpdateSerieContext(); + if (serie.IsUseCoord()) + UpdateSerieGridContext(); + else if (serie.IsUseCoord()) + UpdateSeriePolarContext(); } public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, @@ -29,7 +32,14 @@ public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, public override void DrawSerie(VertexHelper vh) { - DrawBarSerie(vh, serie, serie.context.colorIndex); + if (serie.IsUseCoord()) + { + DrawPolarBar(vh, serie); + } + else if (serie.IsUseCoord()) + { + DrawBarSerie(vh, serie); + } } public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label) @@ -57,7 +67,7 @@ public override void OnPointerDown(PointerEventData eventData) } } - private void UpdateSerieContext() + private void UpdateSerieGridContext() { if (m_SerieGrid == null) return; @@ -119,7 +129,7 @@ private void UpdateSerieContext() } } - private void DrawBarSerie(VertexHelper vh, Bar serie, int colorIndex) + private void DrawBarSerie(VertexHelper vh, Bar serie) { if (!serie.show || serie.animation.HasFadeOut()) return; diff --git a/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Runtime/Serie/Line/LineHandler.GridCoord.cs index b5cf3c92..8d7f76e0 100644 --- a/Runtime/Serie/Line/LineHandler.GridCoord.cs +++ b/Runtime/Serie/Line/LineHandler.GridCoord.cs @@ -248,8 +248,6 @@ private void DrawLineArrow(VertexHelper vh, Serie serie) private void DrawLineSerie(VertexHelper vh, Line serie) { - if (!serie.show) - return; if (serie.animation.HasFadeOut()) return; diff --git a/Runtime/Serie/Line/LineHandler.PolarCoord.cs b/Runtime/Serie/Line/LineHandler.PolarCoord.cs index 600dfe7e..3dedb776 100644 --- a/Runtime/Serie/Line/LineHandler.PolarCoord.cs +++ b/Runtime/Serie/Line/LineHandler.PolarCoord.cs @@ -111,12 +111,8 @@ private void DrawPolarLine(VertexHelper vh, Serie serie) return; var startAngle = m_AngleAxis.startAngle; - var radius = m_SeriePolar.context.outsideRadius; - - var min = m_RadiusAxis.context.minValue; - var max = m_RadiusAxis.context.maxValue; var firstSerieData = datas[0]; - var lp = GetPolarPos(m_SeriePolar, m_AngleAxis, firstSerieData, min, max, radius); + var lp = PolarHelper.UpdatePolarAngleAndPos(m_SeriePolar, m_AngleAxis, m_RadiusAxis, firstSerieData); var cp = Vector3.zero; var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.index); var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); @@ -141,9 +137,9 @@ private void DrawPolarLine(VertexHelper vh, Serie serie) var serieData = datas[i]; - cp = GetPolarPos(m_SeriePolar, m_AngleAxis, datas[i], min, max, radius); + cp = PolarHelper.UpdatePolarAngleAndPos(m_SeriePolar, m_AngleAxis, m_RadiusAxis, datas[i]); var np = i == datas.Count - 1 ? cp : - GetPolarPos(m_SeriePolar, m_AngleAxis, datas[i + 1], min, max, radius); + PolarHelper.UpdatePolarAngleAndPos(m_SeriePolar, m_AngleAxis, m_RadiusAxis, datas[i + 1]); UGLHelper.GetLinePoints(lp, cp, np, lineWidth, ref ltp, ref lbp, @@ -227,29 +223,5 @@ private void DrawPolarLineSymbol(VertexHelper vh) } } } - - private Vector3 GetPolarPos(PolarCoord m_Polar, AngleAxis m_AngleAxis, SerieData serieData, double min, - double max, float polarRadius) - { - var angle = 0f; - - if (!m_AngleAxis.clockwise) - { - angle = m_AngleAxis.GetValueAngle((float) serieData.GetData(1)); - } - else - { - angle = m_AngleAxis.GetValueAngle((float) serieData.GetData(1)); - } - - var value = serieData.GetData(0); - var radius = (float) ((value - min) / (max - min) * polarRadius); - - angle = (angle + 360) % 360; - serieData.context.angle = angle; - serieData.context.position = ChartHelper.GetPos(m_Polar.context.center, radius, angle, true); - - return serieData.context.position; - } } } \ No newline at end of file From 4e05759c3ce68c964411786acb9700f10e94f731 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 19 Sep 2022 13:20:34 +0800 Subject: [PATCH 26/38] [feature][polar] support multiple bar and stack bar in polar --- CHANGELOG.md | 1 + .../Axis/AngleAxis/AngleAxisHandler.cs | 7 ++- .../Axis/RadiusAxis/RadiusAxisHandler.cs | 4 ++ Runtime/Component/Tooltip/TooltipHandler.cs | 4 +- Runtime/Coord/Polar/PolarHelper.cs | 12 +++- Runtime/Serie/Bar/BarHandler.PolarCoord.cs | 56 ++++++++++++++----- Runtime/Serie/Bar/BarHandler.cs | 44 +++++++++++---- Runtime/Serie/SeriesHelper.cs | 2 +- 8 files changed, 98 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7d201d6..6c4407c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.19) 增加`PolarChart`对多柱图和堆叠柱图的支持 * (2022.09.16) 增加`PolarChart`对`Bar`柱图的支持 * (2022.09.14) 增加`PolarCoord`可通过`radius`设置环形极坐标的支持 * (2022.09.09) 修复`Editor`下编辑参数部分组件可能不会实时刷新的问题 diff --git a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs index c464b8c0..b3006ba8 100644 --- a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs +++ b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs @@ -116,11 +116,12 @@ private void DrawAngleAxis(VertexHelper vh, AngleAxis angleAxis) for (int i = 1; i < size; i++) { var scaleWidth = AxisHelper.GetScaleWidth(angleAxis, total, i); - var pos = ChartHelper.GetPos(cenPos, radius, currAngle, true); + var pos1 = ChartHelper.GetPos(cenPos, polar.context.insideRadius, currAngle, true); + var pos2 = ChartHelper.GetPos(cenPos, polar.context.outsideRadius, currAngle, true); if (angleAxis.show && angleAxis.splitLine.show) { var lineWidth = angleAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth); - UGL.DrawLine(vh, cenPos, pos, lineWidth, splitLineColor); + UGL.DrawLine(vh, pos1, pos2, lineWidth, splitLineColor); } if (angleAxis.show && angleAxis.axisTick.show) { @@ -130,7 +131,7 @@ private void DrawAngleAxis(VertexHelper vh, AngleAxis angleAxis) { var tickY = radius + tickLength; var tickPos = ChartHelper.GetPos(cenPos, tickY, currAngle, true); - UGL.DrawLine(vh, pos, tickPos, tickWidth, tickColor); + UGL.DrawLine(vh, pos2, tickPos, tickWidth, tickColor); } } currAngle += scaleWidth; diff --git a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs index 2eb27023..8c227a20 100644 --- a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs +++ b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs @@ -135,6 +135,10 @@ private Vector3 GetLabelPosition(PolarCoord polar, Axis axis, float startAngle, var tickLength = axis.axisTick.GetLength(chart.theme.axis.tickLength); var tickVector = ChartHelper.GetVertialDire(dire) * (tickLength + axis.axisLabel.distance); + if (axis.IsCategory()) + { + totalWidth += polar.context.radius / axis.data.Count / 2; + } return ChartHelper.GetPos(cenPos, totalWidth, startAngle, true) + tickVector; } diff --git a/Runtime/Component/Tooltip/TooltipHandler.cs b/Runtime/Component/Tooltip/TooltipHandler.cs index 372305d9..1572b9f2 100644 --- a/Runtime/Component/Tooltip/TooltipHandler.cs +++ b/Runtime/Component/Tooltip/TooltipHandler.cs @@ -647,10 +647,10 @@ private void DrawPolarIndicator(VertexHelper vh, Tooltip tooltip, PolarCoord m_P var lineWidth = tooltip.lineStyle.GetWidth(theme.tooltip.lineWidth); var cenPos = m_Polar.context.center; var radius = m_Polar.context.outsideRadius; - var sp = m_Polar.context.center; var tooltipAngle = m_AngleAxis.GetValueAngle(tooltip.context.angle); - var ep = ChartHelper.GetPos(sp, radius, tooltipAngle, true); + var sp = ChartHelper.GetPos(m_Polar.context.center, m_Polar.context.insideRadius, tooltipAngle, true); + var ep = ChartHelper.GetPos(m_Polar.context.center, m_Polar.context.outsideRadius, tooltipAngle, true); switch (tooltip.type) { diff --git a/Runtime/Coord/Polar/PolarHelper.cs b/Runtime/Coord/Polar/PolarHelper.cs index 8cfc7196..f80f5216 100644 --- a/Runtime/Coord/Polar/PolarHelper.cs +++ b/Runtime/Coord/Polar/PolarHelper.cs @@ -12,8 +12,16 @@ public static void UpdatePolarCenter(PolarCoord polar, Vector3 chartPosition, fl var minWidth = Mathf.Min(chartWidth, chartHeight); polar.context.center = chartPosition + new Vector3(centerX, centerY); - polar.context.insideRadius = polar.radius[0] <= 1 ? minWidth * polar.radius[0] : polar.radius[0]; - polar.context.outsideRadius = polar.radius[1] <= 1 ? minWidth * polar.radius[1] : polar.radius[1]; + polar.context.insideRadius = polar.context.outsideRadius = 0; + if (polar.radius.Length >= 2) + { + polar.context.insideRadius = ChartHelper.GetActualValue(polar.radius[0], minWidth, 1); + polar.context.outsideRadius = ChartHelper.GetActualValue(polar.radius[1], minWidth, 1); + } + else if (polar.radius.Length >= 1) + { + polar.context.outsideRadius = ChartHelper.GetActualValue(polar.radius[0], minWidth, 1); + } polar.context.radius = polar.context.outsideRadius - polar.context.insideRadius; } diff --git a/Runtime/Serie/Bar/BarHandler.PolarCoord.cs b/Runtime/Serie/Bar/BarHandler.PolarCoord.cs index f44f0ee4..f4688f57 100644 --- a/Runtime/Serie/Bar/BarHandler.PolarCoord.cs +++ b/Runtime/Serie/Bar/BarHandler.PolarCoord.cs @@ -126,32 +126,63 @@ private void DrawPolarBar(VertexHelper vh, Serie serie) SeriesHelper.UpdateStackDataList(chart.series, serie, null, m_StackSerieData); var barCount = chart.GetSerieBarRealCount(); - float categoryWidth = AxisHelper.GetDataWidth(m_AngleAxis, 360, datas.Count, null); - float barGap = chart.GetSerieBarGap(); - float totalBarWidth = chart.GetSerieTotalWidth(categoryWidth, barGap, barCount); - float barWidth = serie.GetBarWidth(categoryWidth, barCount); - float offset = (categoryWidth - totalBarWidth) * 0.5f; - //var serieReadIndex = chart.GetSerieIndexIfStack(serie); - //float gap = serie.barGap == -1 ? offset : offset + chart.GetSerieTotalGap(categoryWidth, barGap, serieReadIndex); + var categoryWidth = m_AngleAxis.IsCategory() ? + AxisHelper.GetDataWidth(m_AngleAxis, 360, datas.Count, null) : + AxisHelper.GetDataWidth(m_RadiusAxis, m_SeriePolar.context.radius, datas.Count, null); + var barGap = chart.GetSerieBarGap(); + var totalBarWidth = chart.GetSerieTotalWidth(categoryWidth, barGap, barCount); + var barWidth = serie.GetBarWidth(categoryWidth, barCount); + var offset = (categoryWidth - totalBarWidth) * 0.5f; + var serieReadIndex = chart.GetSerieIndexIfStack(serie); + float gap = serie.barGap == -1 ? offset : offset + chart.GetSerieTotalGap(categoryWidth, barGap, serieReadIndex); var areaColor = ColorUtil.clearColor32; var areaToColor = ColorUtil.clearColor32; var interacting = false; + float start, end; + float inside, outside; + double radiusValue, angleValue; for (int i = 0; i < datas.Count; i++) { if (serie.animation.CheckDetailBreak(i)) break; var serieData = datas[i]; - var value = serieData.GetData(1); - var start = startAngle + categoryWidth * i + offset; - var end = start + barWidth; var itemStyle = SerieHelper.GetItemStyle(serie, serieData); var borderWidth = itemStyle.borderWidth; var borderColor = itemStyle.borderColor; + radiusValue = serieData.GetData(0); + angleValue = serieData.GetData(1); + if (m_AngleAxis.IsCategory()) + { + start = (float) (startAngle + categoryWidth * angleValue + gap); + end = start + barWidth; + inside = m_SeriePolar.context.insideRadius; + if (isStack) + { + for (int n = 0; n < m_StackSerieData.Count - 1; n++) + inside += m_StackSerieData[n][i].context.stackHeight; + } + outside = inside + m_RadiusAxis.GetValueLength(radiusValue, m_SeriePolar.context.radius); + serieData.context.stackHeight = outside - inside; + } + else + { + start = startAngle; + if (isStack) + { + for (int n = 0; n < m_StackSerieData.Count - 1; n++) + start += m_StackSerieData[n][i].context.stackHeight; + } + end = startAngle + m_AngleAxis.GetValueLength(angleValue, 360); + serieData.context.stackHeight = end - start; + inside = m_SeriePolar.context.insideRadius + categoryWidth * (float) radiusValue + gap; + outside = inside + barWidth; + } serieData.context.startAngle = start; serieData.context.toAngle = end; + serieData.context.halfAngle = (start + end) / 2; if (!serieData.interact.TryGetColor(ref areaColor, ref areaToColor, ref interacting)) { @@ -159,13 +190,12 @@ private void DrawPolarBar(VertexHelper vh, Serie serie) serieData.interact.SetColor(ref interacting, areaColor, areaToColor); } - var inside = m_SeriePolar.context.insideRadius; - var outside = inside + m_RadiusAxis.GetValueLength(value, m_SeriePolar.context.radius); var needRoundCap = serie.roundCap && inside > 0; serieData.context.insideRadius = inside; serieData.context.outsideRadius = outside; - serieData.context.position = ChartHelper.GetPosition(m_SeriePolar.context.center, (inside + outside) / 2, outside); + serieData.context.areaCenter = m_SeriePolar.context.center; + serieData.context.position = ChartHelper.GetPosition(m_SeriePolar.context.center, (start + end) / 2, (inside + outside) / 2); UGL.DrawDoughnut(vh, m_SeriePolar.context.center, inside, outside, areaColor, areaToColor, ColorUtil.clearColor32, start, end, borderWidth, borderColor, serie.gap / 2, chart.settings.cicleSmoothness, diff --git a/Runtime/Serie/Bar/BarHandler.cs b/Runtime/Serie/Bar/BarHandler.cs index 8537a821..c3c70c0f 100644 --- a/Runtime/Serie/Bar/BarHandler.cs +++ b/Runtime/Serie/Bar/BarHandler.cs @@ -44,16 +44,37 @@ public override void DrawSerie(VertexHelper vh) public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label) { - switch (label.position) + if (serie.IsUseCoord()) { - case LabelStyle.Position.Bottom: - var center = serieData.context.rect.center; - return new Vector3(center.x, center.y - serieData.context.rect.height / 2); - case LabelStyle.Position.Center: - case LabelStyle.Position.Inside: - return serieData.context.rect.center; - default: - return serieData.context.position; + switch (label.position) + { + case LabelStyle.Position.Bottom: + var center = serieData.context.areaCenter; + var angle = serieData.context.halfAngle; + var radius = serieData.context.insideRadius; + return ChartHelper.GetPosition(center, angle, radius); + case LabelStyle.Position.Top: + center = serieData.context.areaCenter; + angle = serieData.context.halfAngle; + radius = serieData.context.outsideRadius; + return ChartHelper.GetPosition(center, angle, radius); + default: + return serieData.context.position; + } + } + else + { + switch (label.position) + { + case LabelStyle.Position.Bottom: + var center = serieData.context.rect.center; + return new Vector3(center.x, center.y - serieData.context.rect.height / 2); + case LabelStyle.Position.Center: + case LabelStyle.Position.Inside: + return serieData.context.rect.center; + default: + return serieData.context.position; + } } } @@ -137,14 +158,15 @@ private void DrawBarSerie(VertexHelper vh, Bar serie) Axis axis; Axis relativedAxis; var isY = chart.GetSerieGridCoordAxis(serie, out axis, out relativedAxis); - m_SerieGrid = chart.GetChartComponent(axis.gridIndex); - if (axis == null) return; if (relativedAxis == null) return; + + m_SerieGrid = chart.GetChartComponent(axis.gridIndex); if (m_SerieGrid == null) return; + var dataZoom = chart.GetDataZoomOfAxis(axis); var showData = serie.GetDataList(dataZoom); diff --git a/Runtime/Serie/SeriesHelper.cs b/Runtime/Serie/SeriesHelper.cs index c2bb721f..4055b8f1 100644 --- a/Runtime/Serie/SeriesHelper.cs +++ b/Runtime/Serie/SeriesHelper.cs @@ -330,7 +330,7 @@ public static void GetMinMaxValue(BaseChart chart, int axisIndex, bool isValueAx double max = double.MinValue; var series = chart.series; var isPercentStack = SeriesHelper.IsPercentStack(series); - if (!SeriesHelper.IsStack(series) || (isValueAxis && !yValue)) + if (!SeriesHelper.IsStack(series)) { for (int i = 0; i < series.Count; i++) { From ae35a4d7e65dfe049ce7d95a2b614da110ee4377 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Tue, 20 Sep 2022 13:16:22 +0800 Subject: [PATCH 27/38] [feature][polar] support heatmap in polar --- CHANGELOG.md | 1 + Editor/Series/BarEditor.cs | 15 +- Editor/Series/HeatmapEditor.cs | 9 + Runtime/Component/Legend/LegendHandler.cs | 4 + Runtime/Serie/Bar/BarHandler.PolarCoord.cs | 2 +- Runtime/Serie/Heatmap/Heatmap.cs | 1 + .../Heatmap/HeatmapHandler.PolarCoord.cs | 202 ++++++++++++++++++ .../Heatmap/HeatmapHandler.PolarCoord.cs.meta | 11 + Runtime/Serie/Heatmap/HeatmapHandler.cs | 20 +- 9 files changed, 256 insertions(+), 9 deletions(-) create mode 100644 Runtime/Serie/Heatmap/HeatmapHandler.PolarCoord.cs create mode 100644 Runtime/Serie/Heatmap/HeatmapHandler.PolarCoord.cs.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c4407c1..50d5b749 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.20) 增加`PolarChart`对`Heatmap`热力图的支持 * (2022.09.19) 增加`PolarChart`对多柱图和堆叠柱图的支持 * (2022.09.16) 增加`PolarChart`对`Bar`柱图的支持 * (2022.09.14) 增加`PolarCoord`可通过`radius`设置环形极坐标的支持 diff --git a/Editor/Series/BarEditor.cs b/Editor/Series/BarEditor.cs index beb6ecea..1a078531 100644 --- a/Editor/Series/BarEditor.cs +++ b/Editor/Series/BarEditor.cs @@ -19,13 +19,20 @@ public override void OnCustomInspectorGUI() PropertyField("m_YAxisIndex"); } PropertyField("m_BarType"); - PropertyField("m_BarPercentStack"); PropertyField("m_BarWidth"); PropertyField("m_BarGap"); - if (serie.barType == BarType.Zebra) + if (serie.IsUseCoord()) + { + PropertyField("m_RoundCap"); + } + else { - PropertyField("m_BarZebraWidth"); - PropertyField("m_BarZebraGap"); + PropertyField("m_BarPercentStack"); + if (serie.barType == BarType.Zebra) + { + PropertyField("m_BarZebraWidth"); + PropertyField("m_BarZebraGap"); + } } PropertyField("m_Clip"); PropertyFiledMore(() => diff --git a/Editor/Series/HeatmapEditor.cs b/Editor/Series/HeatmapEditor.cs index f525541e..c4eaa9cb 100644 --- a/Editor/Series/HeatmapEditor.cs +++ b/Editor/Series/HeatmapEditor.cs @@ -7,6 +7,15 @@ public class HeatmapEditor : SerieEditor { public override void OnCustomInspectorGUI() { + if (serie.IsUseCoord()) + { + PropertyField("m_PolarIndex"); + } + else + { + PropertyField("m_XAxisIndex"); + PropertyField("m_YAxisIndex"); + } PropertyField("m_HeatmapType"); PropertyField("m_Ignore"); PropertyField("m_IgnoreValue"); diff --git a/Runtime/Component/Legend/LegendHandler.cs b/Runtime/Component/Legend/LegendHandler.cs index ab3df818..52951bd8 100644 --- a/Runtime/Component/Legend/LegendHandler.cs +++ b/Runtime/Component/Legend/LegendHandler.cs @@ -225,6 +225,10 @@ private void DrawLegend(VertexHelper vh) break; } } + else + { + iconType = Legend.Type.Rect; + } } else { diff --git a/Runtime/Serie/Bar/BarHandler.PolarCoord.cs b/Runtime/Serie/Bar/BarHandler.PolarCoord.cs index f4688f57..f2c860ec 100644 --- a/Runtime/Serie/Bar/BarHandler.PolarCoord.cs +++ b/Runtime/Serie/Bar/BarHandler.PolarCoord.cs @@ -175,7 +175,7 @@ private void DrawPolarBar(VertexHelper vh, Serie serie) for (int n = 0; n < m_StackSerieData.Count - 1; n++) start += m_StackSerieData[n][i].context.stackHeight; } - end = startAngle + m_AngleAxis.GetValueLength(angleValue, 360); + end = start + m_AngleAxis.GetValueLength(angleValue, 360); serieData.context.stackHeight = end - start; inside = m_SeriePolar.context.insideRadius + categoryWidth * (float) radiusValue + gap; outside = inside + barWidth; diff --git a/Runtime/Serie/Heatmap/Heatmap.cs b/Runtime/Serie/Heatmap/Heatmap.cs index a40b745d..91b79855 100644 --- a/Runtime/Serie/Heatmap/Heatmap.cs +++ b/Runtime/Serie/Heatmap/Heatmap.cs @@ -24,6 +24,7 @@ public enum HeatmapType [SerieHandler(typeof(HeatmapHandler), true)] [DefaultAnimation(AnimationType.LeftToRight)] [RequireChartComponent(typeof(VisualMap))] + [CoordOptions(typeof(GridCoord), typeof(PolarCoord))] [SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] [SerieDataExtraField()] diff --git a/Runtime/Serie/Heatmap/HeatmapHandler.PolarCoord.cs b/Runtime/Serie/Heatmap/HeatmapHandler.PolarCoord.cs new file mode 100644 index 00000000..c2ed3ffc --- /dev/null +++ b/Runtime/Serie/Heatmap/HeatmapHandler.PolarCoord.cs @@ -0,0 +1,202 @@ +using UnityEngine; +using UnityEngine.UI; +using XUGL; + +namespace XCharts.Runtime +{ + /// + /// For polar coord + /// + internal sealed partial class HeatmapHandler + { + private PolarCoord m_SeriePolar; + + private void UpdateSeriePolarContext() + { + if (m_SeriePolar == null) + return; + + var needCheck = (chart.isPointerInChart && m_SeriePolar.IsPointerEnter()) || m_LegendEnter; + var lineWidth = 0f; + if (!needCheck) + { + if (m_LastCheckContextFlag != needCheck) + { + var needAnimation1 = false; + lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); + m_LastCheckContextFlag = needCheck; + serie.context.pointerItemDataIndex = -1; + serie.context.pointerEnter = false; + serie.interact.SetValue(ref needAnimation1, lineWidth, false); + foreach (var serieData in serie.data) + { + var symbol = SerieHelper.GetSerieSymbol(serie, serieData); + var symbolSize = symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); + serieData.context.highlight = false; + serieData.interact.SetValue(ref needAnimation1, symbolSize); + } + if (needAnimation1) + { + if (SeriesHelper.IsStack(chart.series)) + chart.RefreshTopPainter(); + else + chart.RefreshPainter(serie); + } + } + return; + } + m_LastCheckContextFlag = needCheck; + var themeSymbolSize = chart.theme.serie.lineSymbolSize; + lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); + + var needInteract = false; + if (m_LegendEnter) + { + serie.context.pointerEnter = true; + serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate); + for (int i = 0; i < serie.dataCount; i++) + { + var serieData = serie.data[i]; + var size = SerieHelper.GetSysmbolSize(serie, serieData, chart.theme, themeSymbolSize, SerieState.Emphasis); + serieData.context.highlight = true; + serieData.interact.SetValue(ref needInteract, size); + } + } + else + { + serie.context.pointerItemDataIndex = -1; + serie.context.pointerEnter = false; + var dir = chart.pointerPos - new Vector2(m_SeriePolar.context.center.x, m_SeriePolar.context.center.y); + var pointerAngle = ChartHelper.GetAngle360(Vector2.up, dir); + var pointerRadius = Vector2.Distance(chart.pointerPos, m_SeriePolar.context.center); + Color32 color, toColor; + for (int i = 0; i < serie.dataCount; i++) + { + var serieData = serie.data[i]; + if (pointerAngle >= serieData.context.startAngle && + pointerAngle < serieData.context.toAngle && + pointerRadius >= serieData.context.insideRadius && + pointerRadius < serieData.context.outsideRadius) + { + serie.context.pointerItemDataIndex = i; + serie.context.pointerEnter = true; + serieData.context.highlight = true; + } + else + { + serieData.context.highlight = false; + } + var state = SerieHelper.GetSerieState(serie, serieData, true); + SerieHelper.GetItemColor(out color, out toColor, serie, serieData, chart.theme, state); + serieData.interact.SetColor(ref needInteract, color, toColor); + } + } + if (needInteract) + { + if (SeriesHelper.IsStack(chart.series)) + chart.RefreshTopPainter(); + else + chart.RefreshPainter(serie); + } + } + + private void DrawPolarHeatmap(VertexHelper vh, Serie serie) + { + var datas = serie.data; + if (datas.Count <= 0) + return; + + m_SeriePolar = chart.GetChartComponent(serie.polarIndex); + if (m_SeriePolar == null) + return; + + var m_AngleAxis = ComponentHelper.GetAngleAxis(chart.components, m_SeriePolar.index); + var m_RadiusAxis = ComponentHelper.GetRadiusAxis(chart.components, m_SeriePolar.index); + if (m_AngleAxis == null || m_RadiusAxis == null) + return; + var visualMap = chart.GetVisualMapOfSerie(serie); + + var startAngle = m_AngleAxis.context.startAngle; + var currDetailProgress = 0f; + var totalDetailProgress = datas.Count; + + var xCount = AxisHelper.GetTotalSplitGridNum(m_RadiusAxis); + var yCount = AxisHelper.GetTotalSplitGridNum(m_AngleAxis); + var xWidth = m_SeriePolar.context.radius / xCount; + var yWidth = 360 / yCount; + + serie.animation.InitProgress(currDetailProgress, totalDetailProgress); + + var dimension = VisualMapHelper.GetDimension(visualMap, defaultDimension); + if (visualMap.autoMinMax) + { + double maxValue, minValue; + SerieHelper.GetMinMaxData(serie, dimension, out minValue, out maxValue); + VisualMapHelper.SetMinMax(visualMap, minValue, maxValue); + } + var rangeMin = visualMap.rangeMin; + var rangeMax = visualMap.rangeMax; + var color = chart.theme.GetColor(serie.index); + + float start, end; + float inside, outside; + double value, radiusValue, angleValue; + for (int i = 0; i < datas.Count; i++) + { + if (serie.animation.CheckDetailBreak(i)) + break; + var serieData = datas[i]; + var itemStyle = SerieHelper.GetItemStyle(serie, serieData); + var borderWidth = itemStyle.borderWidth; + var borderColor = itemStyle.borderColor; + + radiusValue = serieData.GetData(0); + angleValue = serieData.GetData(1); + value = serieData.GetData(2); + + var xIndex = AxisHelper.GetAxisValueSplitIndex(m_RadiusAxis, radiusValue, xCount); + var yIndex = AxisHelper.GetAxisValueSplitIndex(m_AngleAxis, angleValue, yCount); + + start = startAngle + yIndex * yWidth; + end = start + yWidth; + + inside = m_SeriePolar.context.insideRadius + xIndex * xWidth; + outside = inside + xWidth; + + serieData.context.startAngle = start; + serieData.context.toAngle = end; + serieData.context.halfAngle = (start + end) / 2; + serieData.context.insideRadius = inside; + serieData.context.outsideRadius = outside; + + if ((value < rangeMin && rangeMin != visualMap.min) || + (value > rangeMax && rangeMax != visualMap.max)) + { + continue; + } + if (!visualMap.IsInSelectedValue(value)) continue; + color = visualMap.GetColor(value); + if (serieData.context.highlight) + color = ChartHelper.GetHighlightColor(color); + + var needRoundCap = serie.roundCap && inside > 0; + + serieData.context.insideRadius = inside; + serieData.context.outsideRadius = outside; + serieData.context.areaCenter = m_SeriePolar.context.center; + serieData.context.position = ChartHelper.GetPosition(m_SeriePolar.context.center, (start + end) / 2, (inside + outside) / 2); + + UGL.DrawDoughnut(vh, m_SeriePolar.context.center, inside, outside, color, color, + ColorUtil.clearColor32, start, end, borderWidth, borderColor, serie.gap / 2, chart.settings.cicleSmoothness, + needRoundCap, true); + } + + if (!serie.animation.IsFinish()) + { + serie.animation.CheckProgress(totalDetailProgress); + serie.animation.CheckSymbol(serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize)); + chart.RefreshChart(); + } + } + } +} \ No newline at end of file diff --git a/Runtime/Serie/Heatmap/HeatmapHandler.PolarCoord.cs.meta b/Runtime/Serie/Heatmap/HeatmapHandler.PolarCoord.cs.meta new file mode 100644 index 00000000..e9f8a398 --- /dev/null +++ b/Runtime/Serie/Heatmap/HeatmapHandler.PolarCoord.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: baaa1d070b88a4b9bb7d1eed341041e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Serie/Heatmap/HeatmapHandler.cs b/Runtime/Serie/Heatmap/HeatmapHandler.cs index 648b37e1..b3bf9ba4 100644 --- a/Runtime/Serie/Heatmap/HeatmapHandler.cs +++ b/Runtime/Serie/Heatmap/HeatmapHandler.cs @@ -6,7 +6,7 @@ namespace XCharts.Runtime { [UnityEngine.Scripting.Preserve] - internal sealed class HeatmapHandler : SerieHandler + internal sealed partial class HeatmapHandler : SerieHandler { private GridCoord m_SerieGrid; private Dictionary m_CountDict = new Dictionary(); @@ -27,7 +27,10 @@ public static void GetGridXYByKey(int key, out int x, out int y) public override void Update() { base.Update(); - UpdateSerieContext(); + if (serie.IsUseCoord()) + UpdateSerieContext(); + else if (serie.IsUseCoord()) + UpdateSeriePolarContext(); } public override void DrawSerie(VertexHelper vh) @@ -35,7 +38,16 @@ public override void DrawSerie(VertexHelper vh) if (serie.heatmapType == HeatmapType.Count) DrawCountHeatmapSerie(vh, serie); else - DrawDataHeatmapSerie(vh, serie); + { + if (serie.IsUseCoord()) + { + DrawPolarHeatmap(vh, serie); + } + else if (serie.IsUseCoord()) + { + DrawDataHeatmapSerie(vh, serie); + } + } } public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, @@ -416,7 +428,7 @@ private void DrawCountHeatmapSerie(VertexHelper vh, Heatmap serie) var pos = new Vector3(zeroX + (i + 0.5f) * xWidth, zeroY + (j + 0.5f) * yWidth); - + var rectWid = 0f; var rectHig = 0f; if (isRectSymbol) From f0d6316c207fd25ee817d8efbe2ca64131ecbd71 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Wed, 21 Sep 2022 06:59:34 +0800 Subject: [PATCH 28/38] [improve][axis] support `showStartLine` and `showEndLine` in AngleAxis and RadiusAxis --- Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs | 7 +++++-- Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs index b3006ba8..5ac345e7 100644 --- a/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs +++ b/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs @@ -120,8 +120,11 @@ private void DrawAngleAxis(VertexHelper vh, AngleAxis angleAxis) var pos2 = ChartHelper.GetPos(cenPos, polar.context.outsideRadius, currAngle, true); if (angleAxis.show && angleAxis.splitLine.show) { - var lineWidth = angleAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth); - UGL.DrawLine(vh, pos1, pos2, lineWidth, splitLineColor); + if (angleAxis.splitLine.NeedShow(i - 1, size - 1)) + { + var lineWidth = angleAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth); + UGL.DrawLine(vh, pos1, pos2, lineWidth, splitLineColor); + } } if (angleAxis.show && angleAxis.axisTick.show) { diff --git a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs index 8c227a20..60382f55 100644 --- a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs +++ b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs @@ -167,7 +167,7 @@ private void DrawRadiusAxis(VertexHelper vh, RadiusAxis radiusAxis) var pos = ChartHelper.GetPos(cenPos, totalWidth + tickWidth, startAngle, true); if (radiusAxis.show && radiusAxis.splitLine.show) { - if (CanDrawSplitLine(angleAxis, i, size)) + if (CanDrawSplitLine(angleAxis, i, size) && radiusAxis.splitLine.NeedShow(i, size)) { var outsideRaidus = totalWidth + radiusAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth) * 2; var splitLineColor = radiusAxis.splitLine.GetColor(chart.theme.axis.splitLineColor); From 4b8ca2e5e14b877211c071d1e7ddc449dbd3a393 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Wed, 21 Sep 2022 06:59:57 +0800 Subject: [PATCH 29/38] [improve][line] improve line in polar --- CHANGELOG.md | 1 + Runtime/Serie/Line/LineHandler.GridCoord.cs | 4 +- Runtime/Serie/Line/LineHandler.PolarCoord.cs | 128 +++++++++++++------ Runtime/Serie/Line/LineHandler.cs | 1 + 4 files changed, 96 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50d5b749..3c131de8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.21) 优化`PolarChart`对`Line`热力图的支持 * (2022.09.20) 增加`PolarChart`对`Heatmap`热力图的支持 * (2022.09.19) 增加`PolarChart`对多柱图和堆叠柱图的支持 * (2022.09.16) 增加`PolarChart`对`Bar`柱图的支持 diff --git a/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Runtime/Serie/Line/LineHandler.GridCoord.cs index 8d7f76e0..d5364dc5 100644 --- a/Runtime/Serie/Line/LineHandler.GridCoord.cs +++ b/Runtime/Serie/Line/LineHandler.GridCoord.cs @@ -185,7 +185,7 @@ private void DrawLinePoint(VertexHelper vh, Serie serie) float symbolBorder = 0f; float[] cornerRadius = null; Color32 symbolColor, symbolToColor, symbolEmptyColor, borderColor; - SerieHelper.GetItemColor(out symbolColor, out symbolToColor, out symbolEmptyColor, serie, serieData, theme, serie.index); + SerieHelper.GetItemColor(out symbolColor, out symbolToColor, out symbolEmptyColor, serie, serieData, theme, serie.context.colorIndex); SerieHelper.GetSymbolInfo(out borderColor, out symbolBorder, out cornerRadius, serie, null, chart.theme, state); if (isVisualMapGradient) { @@ -213,7 +213,7 @@ private void DrawLineArrow(VertexHelper vh, Serie serie) if (serie.context.dataPoints.Count < 2) return; - var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.index); + var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.context.colorIndex); var startPos = Vector3.zero; var arrowPos = Vector3.zero; var lineArrow = serie.lineArrow.arrow; diff --git a/Runtime/Serie/Line/LineHandler.PolarCoord.cs b/Runtime/Serie/Line/LineHandler.PolarCoord.cs index 3dedb776..1c34e96a 100644 --- a/Runtime/Serie/Line/LineHandler.PolarCoord.cs +++ b/Runtime/Serie/Line/LineHandler.PolarCoord.cs @@ -114,7 +114,7 @@ private void DrawPolarLine(VertexHelper vh, Serie serie) var firstSerieData = datas[0]; var lp = PolarHelper.UpdatePolarAngleAndPos(m_SeriePolar, m_AngleAxis, m_RadiusAxis, firstSerieData); var cp = Vector3.zero; - var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.index); + var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.context.colorIndex); var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); var currDetailProgress = 0f; var totalDetailProgress = datas.Count; @@ -130,53 +130,69 @@ private void DrawPolarLine(VertexHelper vh, Serie serie) var clp = Vector3.zero; var crp = Vector3.zero; bool bitp = true, bibp = true; - for (int i = 1; i < datas.Count; i++) + if (datas.Count <= 2) { - if (serie.animation.CheckDetailBreak(i)) - break; - - var serieData = datas[i]; + for (int i = 0; i < datas.Count; i++) + { + var serieData = datas[i]; + cp = PolarHelper.UpdatePolarAngleAndPos(m_SeriePolar, m_AngleAxis, m_RadiusAxis, datas[i]); + serieData.context.position = cp; + serie.context.dataPoints.Add(cp); + } + UGL.DrawLine(vh, serie.context.dataPoints, lineWidth, lineColor, false, false); + } + else + { + for (int i = 1; i < datas.Count; i++) + { + if (serie.animation.CheckDetailBreak(i)) + break; - cp = PolarHelper.UpdatePolarAngleAndPos(m_SeriePolar, m_AngleAxis, m_RadiusAxis, datas[i]); - var np = i == datas.Count - 1 ? cp : - PolarHelper.UpdatePolarAngleAndPos(m_SeriePolar, m_AngleAxis, m_RadiusAxis, datas[i + 1]); + var serieData = datas[i]; + cp = PolarHelper.UpdatePolarAngleAndPos(m_SeriePolar, m_AngleAxis, m_RadiusAxis, datas[i]); + serieData.context.position = cp; + serie.context.dataPoints.Add(cp); - UGLHelper.GetLinePoints(lp, cp, np, lineWidth, - ref ltp, ref lbp, - ref ntp, ref nbp, - ref itp, ref ibp, - ref clp, ref crp, - ref bitp, ref bibp, i); + var np = i == datas.Count - 1 ? cp : + PolarHelper.UpdatePolarAngleAndPos(m_SeriePolar, m_AngleAxis, m_RadiusAxis, datas[i + 1]); - if (i == 1) - { - UGL.AddVertToVertexHelper(vh, ltp, lbp, lineColor, false); - } + UGLHelper.GetLinePoints(lp, cp, np, lineWidth, + ref ltp, ref lbp, + ref ntp, ref nbp, + ref itp, ref ibp, + ref clp, ref crp, + ref bitp, ref bibp, i); - if (bitp == bibp) - { - if (bitp) - UGL.AddVertToVertexHelper(vh, itp, ibp, lineColor, true); - else + if (i == 1) { - UGL.AddVertToVertexHelper(vh, ltp, clp, lineColor, true); - UGL.AddVertToVertexHelper(vh, ltp, crp, lineColor, true); + UGL.AddVertToVertexHelper(vh, ltp, lbp, lineColor, false); } - } - else - { - if (bitp) + + if (bitp == bibp) { - UGL.AddVertToVertexHelper(vh, itp, clp, lineColor, true); - UGL.AddVertToVertexHelper(vh, itp, crp, lineColor, true); + if (bitp) + UGL.AddVertToVertexHelper(vh, itp, ibp, lineColor, true); + else + { + UGL.AddVertToVertexHelper(vh, ltp, clp, lineColor, true); + UGL.AddVertToVertexHelper(vh, ltp, crp, lineColor, true); + } } - else if (bibp) + else { - UGL.AddVertToVertexHelper(vh, clp, ibp, lineColor, true); - UGL.AddVertToVertexHelper(vh, crp, ibp, lineColor, true); + if (bitp) + { + UGL.AddVertToVertexHelper(vh, itp, clp, lineColor, true); + UGL.AddVertToVertexHelper(vh, itp, crp, lineColor, true); + } + else if (bibp) + { + UGL.AddVertToVertexHelper(vh, clp, ibp, lineColor, true); + UGL.AddVertToVertexHelper(vh, crp, ibp, lineColor, true); + } } + lp = cp; } - lp = cp; } if (!serie.animation.IsFinish()) @@ -187,6 +203,46 @@ private void DrawPolarLine(VertexHelper vh, Serie serie) } } + private void DrawPolarLineArrow(VertexHelper vh, Serie serie) + { + if (!serie.show || serie.lineArrow == null || !serie.lineArrow.show) + return; + + if (serie.context.dataPoints.Count < 2) + return; + + var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.context.colorIndex); + var startPos = Vector3.zero; + var arrowPos = Vector3.zero; + var lineArrow = serie.lineArrow.arrow; + var dataPoints = serie.context.dataPoints; + switch (serie.lineArrow.position) + { + case LineArrow.Position.End: + if (dataPoints.Count < 3) + { + startPos = dataPoints[dataPoints.Count - 2]; + arrowPos = dataPoints[dataPoints.Count - 1]; + } + else + { + startPos = dataPoints[dataPoints.Count - 3]; + arrowPos = dataPoints[dataPoints.Count - 2]; + } + UGL.DrawArrow(vh, startPos, arrowPos, lineArrow.width, lineArrow.height, + lineArrow.offset, lineArrow.dent, lineArrow.GetColor(lineColor)); + + break; + + case LineArrow.Position.Start: + startPos = dataPoints[1]; + arrowPos = dataPoints[0]; + UGL.DrawArrow(vh, startPos, arrowPos, lineArrow.width, lineArrow.height, + lineArrow.offset, lineArrow.dent, lineArrow.GetColor(lineColor)); + break; + } + } + private void DrawPolarLineSymbol(VertexHelper vh) { for (int n = 0; n < chart.series.Count; n++) diff --git a/Runtime/Serie/Line/LineHandler.cs b/Runtime/Serie/Line/LineHandler.cs index 9d9efa1a..10a5c5be 100644 --- a/Runtime/Serie/Line/LineHandler.cs +++ b/Runtime/Serie/Line/LineHandler.cs @@ -35,6 +35,7 @@ public override void DrawSerie(VertexHelper vh) { DrawPolarLine(vh, serie); DrawPolarLineSymbol(vh); + DrawPolarLineArrow(vh, serie); } else if (serie.IsUseCoord()) { From 95c0bcdb7539c202dedad53e55b711d4d962392a Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Wed, 21 Sep 2022 07:12:59 +0800 Subject: [PATCH 30/38] [fix] fix InsertSerie() --- CHANGELOG.md | 1 + Runtime/Internal/BaseChart.Serie.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c131de8..29588113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.21) 修复`InsertSerie()`接口不刷新图表的问题 * (2022.09.21) 优化`PolarChart`对`Line`热力图的支持 * (2022.09.20) 增加`PolarChart`对`Heatmap`热力图的支持 * (2022.09.19) 增加`PolarChart`对多柱图和堆叠柱图的支持 diff --git a/Runtime/Internal/BaseChart.Serie.cs b/Runtime/Internal/BaseChart.Serie.cs index e3a302c8..9867b5db 100644 --- a/Runtime/Internal/BaseChart.Serie.cs +++ b/Runtime/Internal/BaseChart.Serie.cs @@ -30,7 +30,9 @@ public void InsertSerie(Serie serie, int index = -1, bool addToHead = false) else if (index >= 0) m_Series.Insert(index, serie); else m_Series.Add(serie); ResetSeriesIndex(); + InitSerieHandlers(); SeriesHelper.UpdateSerieNameList(this, ref m_LegendRealShowName); + RefreshChart(); } public bool MoveUpSerie(int serieIndex) From eba8986f18ee3182ef4f59cb0e079ed489a35bb8 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Wed, 21 Sep 2022 07:18:54 +0800 Subject: [PATCH 31/38] [fix] fix InsertSerie() --- Examples/Example_Test.cs | 12 +++--------- Runtime/Internal/BaseChart.Serie.cs | 6 +++--- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Examples/Example_Test.cs b/Examples/Example_Test.cs index f105bc79..e51b0ac9 100644 --- a/Examples/Example_Test.cs +++ b/Examples/Example_Test.cs @@ -51,15 +51,9 @@ void OnTestBtn() void AddData() { - chart.ClearData(); - int count = Random.Range(5, 100); - for (int i = 0; i < count; i++) - { - chart.AddXAxisData("x" + i); - if (Random.Range(1, 3) == 2) - chart.AddData(0, Random.Range(-110, 200)); - else - chart.AddData(0, Random.Range(-100, 100)); + var serie = chart.InsertSerie(0); + for(int i=0;i<5;i++){ + chart.AddData(serie.index, Random.Range(10,90)); } } } diff --git a/Runtime/Internal/BaseChart.Serie.cs b/Runtime/Internal/BaseChart.Serie.cs index 9867b5db..48f753ce 100644 --- a/Runtime/Internal/BaseChart.Serie.cs +++ b/Runtime/Internal/BaseChart.Serie.cs @@ -19,7 +19,9 @@ public T AddSerie(string serieName = null, bool show = true, bool addToHead = public T InsertSerie(int index, string serieName = null, bool show = true) where T : Serie { if (!CanAddSerie()) return null; - return InsertSerie(index, typeof(T), serieName, show) as T; + var serie = InsertSerie(index, typeof(T), serieName, show) as T; + InitSerieHandlers(); + return serie; } public void InsertSerie(Serie serie, int index = -1, bool addToHead = false) @@ -30,9 +32,7 @@ public void InsertSerie(Serie serie, int index = -1, bool addToHead = false) else if (index >= 0) m_Series.Insert(index, serie); else m_Series.Add(serie); ResetSeriesIndex(); - InitSerieHandlers(); SeriesHelper.UpdateSerieNameList(this, ref m_LegendRealShowName); - RefreshChart(); } public bool MoveUpSerie(int serieIndex) From bd9a0df52b6fd7d4267d18902a1d1a8df1bdc770 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Thu, 22 Sep 2022 08:37:56 +0800 Subject: [PATCH 32/38] [feature][API] add SaveAsImage() --- CHANGELOG.md | 1 + Editor/Charts/BaseChartEditor.cs | 5 ++ Plugins.meta | 8 ++++ Plugins/Download.jslib | 24 ++++++++++ Plugins/Download.jslib.meta | 34 +++++++++++++ Runtime/Internal/BaseChart.API.cs | 10 ++++ Runtime/Internal/BaseChart.cs | 7 +++ Runtime/Internal/Utilities/ChartHelper.cs | 58 +++++++++++++++++++++++ 8 files changed, 147 insertions(+) create mode 100644 Plugins.meta create mode 100644 Plugins/Download.jslib create mode 100644 Plugins/Download.jslib.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index 29588113..2922f202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.22) 增加`SaveAsImage()`接口保存图表到图片 * (2022.09.21) 修复`InsertSerie()`接口不刷新图表的问题 * (2022.09.21) 优化`PolarChart`对`Line`热力图的支持 * (2022.09.20) 增加`PolarChart`对`Heatmap`热力图的支持 diff --git a/Editor/Charts/BaseChartEditor.cs b/Editor/Charts/BaseChartEditor.cs index 617d12ef..fc9f39d7 100644 --- a/Editor/Charts/BaseChartEditor.cs +++ b/Editor/Charts/BaseChartEditor.cs @@ -16,6 +16,7 @@ class Styles public static readonly GUIContent btnAddComponent = new GUIContent("Add Main Component", ""); public static readonly GUIContent btnCovertXYAxis = new GUIContent("Covert XY Axis", ""); public static readonly GUIContent btnRebuildChartObject = new GUIContent("Rebuild Chart Object", ""); + public static readonly GUIContent btnSaveAsImage = new GUIContent("Save As Image", ""); public static readonly GUIContent btnCheckWarning = new GUIContent("Check Warning", ""); public static readonly GUIContent btnHideWarning = new GUIContent("Hide Warning", ""); } @@ -279,6 +280,10 @@ private void CheckWarning() { m_Chart.RebuildChartObject(); } + if (GUILayout.Button(Styles.btnSaveAsImage)) + { + m_Chart.SaveAsImage(); + } if (m_CheckWarning) { EditorGUILayout.BeginHorizontal(); diff --git a/Plugins.meta b/Plugins.meta new file mode 100644 index 00000000..a60003bb --- /dev/null +++ b/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6558d1464a47441d18df18c4a403b2f2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/Download.jslib b/Plugins/Download.jslib new file mode 100644 index 00000000..cc5b8886 --- /dev/null +++ b/Plugins/Download.jslib @@ -0,0 +1,24 @@ +mergeInto(LibraryManager.library, { + Download: function (str, fn) { + var msg = UTF8ToString(str); + var fname = UTF8ToString(fn); + function fixBinary(bin) { + var length = bin.length; + var buf = new ArrayBuffer(length); + var arr = new Uint8Array(buf); + for (var i = 0; i < length; i++) { + arr[i] = bin.charCodeAt(i); + } + return buf; + } + var binary = fixBinary(atob(msg)); + var data = new Blob([binary]); + var link = document.createElement('a'); + link.download = fname; + link.href = URL.createObjectURL(data); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } +}); + diff --git a/Plugins/Download.jslib.meta b/Plugins/Download.jslib.meta new file mode 100644 index 00000000..c2c8647a --- /dev/null +++ b/Plugins/Download.jslib.meta @@ -0,0 +1,34 @@ +fileFormatVersion: 2 +guid: 821b9cd60f13648a396c76481da2191c +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Facebook: WebGL + second: + enabled: 1 + settings: {} + - first: + WebGL: WebGL + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Internal/BaseChart.API.cs b/Runtime/Internal/BaseChart.API.cs index 765355c1..68c279cc 100644 --- a/Runtime/Internal/BaseChart.API.cs +++ b/Runtime/Internal/BaseChart.API.cs @@ -588,5 +588,15 @@ public Color32 GetItemColor(Serie serie) SerieHelper.GetItemColor(out color, out toColor, serie, null, m_Theme); return color; } + + /// + /// 保存图表为图片。 + /// + /// type of image: png, jpg, exr + /// save path + public void SaveAsImage(string imageType = "png", string savePath = "") + { + StartCoroutine(SaveAsImageSync(imageType, savePath)); + } } } \ No newline at end of file diff --git a/Runtime/Internal/BaseChart.cs b/Runtime/Internal/BaseChart.cs index 23cbca1e..f9ea93c1 100644 --- a/Runtime/Internal/BaseChart.cs +++ b/Runtime/Internal/BaseChart.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Reflection; using UnityEngine; @@ -741,5 +742,11 @@ public void OnAfterDeserialize() InitComponentHandlers(); InitSerieHandlers(); } + + private IEnumerator SaveAsImageSync(string imageType, string path) + { + yield return new WaitForEndOfFrame(); + ChartHelper.SaveAsImage(rectTransform, canvas, imageType, path); + } } } \ No newline at end of file diff --git a/Runtime/Internal/Utilities/ChartHelper.cs b/Runtime/Internal/Utilities/ChartHelper.cs index be19f64a..63025ade 100644 --- a/Runtime/Internal/Utilities/ChartHelper.cs +++ b/Runtime/Internal/Utilities/ChartHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using UnityEngine; @@ -896,5 +897,62 @@ public static float GetActualValue(float valueOrRate, float total, float maxRate if (valueOrRate >= -maxRate && valueOrRate <= maxRate) return valueOrRate * total; else return valueOrRate; } + + [DllImport("__Internal")] + private static extern void Download(string base64str, string fileName); + + public static Texture2D SaveAsImage(RectTransform rectTransform, Canvas canvas, string imageType = "png", string path = "") + { + var cam = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera; + var pos = RectTransformUtility.WorldToScreenPoint(cam, rectTransform.position); + var width = rectTransform.rect.width * canvas.scaleFactor; + var height = rectTransform.rect.height * canvas.scaleFactor; + var posX = pos.x + rectTransform.rect.xMin * canvas.scaleFactor; + var posY = pos.y + rectTransform.rect.yMin * canvas.scaleFactor; + var rect = new Rect(posX, posY, width, height); + var tex = new Texture2D((int) width, (int) height, TextureFormat.RGBA32, false); + tex.ReadPixels(rect, 0, 0); + tex.Apply(); + byte[] bytes; + switch (imageType) + { + case "png": + bytes = tex.EncodeToPNG(); + break; + case "jpg": + bytes = tex.EncodeToJPG(); + break; + case "exr": + bytes = tex.EncodeToEXR(); + break; + default: + Debug.LogError("SaveAsImage ERROR: not support image type:" + imageType); + return null; + } + var fileName = rectTransform.name + "." + imageType; +#if UNITY_WEBGL + string base64str = Convert.ToBase64String(bytes); + Download(base64str, fileName); + Debug.Log("SaveAsImage: download by brower:" + fileName); + return tex; +#endif + if (string.IsNullOrEmpty(path)) + { + var dir = Application.persistentDataPath + "/SavedImage"; +#if UNITY_EDITOR + dir = Application.dataPath + "/../SavedImage"; +#else + dir = Application.persistentDataPath + "/SavedImage"; +#endif + if (!System.IO.Directory.Exists(dir)) + { + System.IO.Directory.CreateDirectory(dir); + } + path = dir + "/" + fileName; + } + System.IO.File.WriteAllBytes(path, bytes); + Debug.Log("SaveAsImage:" + path); + return tex; + } } } \ No newline at end of file From 4c89bda4b974bfc59b09c570f7d964ea4e4adf7e Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Fri, 23 Sep 2022 08:38:56 +0800 Subject: [PATCH 33/38] [improve][Parallel] improve ParallelChart --- CHANGELOG.md | 1 + Editor/Series/ParallelEditor.cs | 1 + .../Axis/ParallelAxis/ParallelAxis.cs | 1 + .../Axis/ParallelAxis/ParallelAxisHander.cs | 2 +- Runtime/Serie/Parallel/Parallel.cs | 3 +- Runtime/Serie/Parallel/ParallelHandler.cs | 28 +++++++++---------- Runtime/Serie/SerieHandler.cs | 2 +- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2922f202..ecf624b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.09.23) 优化`ParallelChart` * (2022.09.22) 增加`SaveAsImage()`接口保存图表到图片 * (2022.09.21) 修复`InsertSerie()`接口不刷新图表的问题 * (2022.09.21) 优化`PolarChart`对`Line`热力图的支持 diff --git a/Editor/Series/ParallelEditor.cs b/Editor/Series/ParallelEditor.cs index c0d7b2c5..c29aff68 100644 --- a/Editor/Series/ParallelEditor.cs +++ b/Editor/Series/ParallelEditor.cs @@ -7,6 +7,7 @@ public class ParallelEditor : SerieEditor { public override void OnCustomInspectorGUI() { + PropertyField("m_ColorBy"); PropertyField("m_ParallelIndex"); PropertyField("m_LineType"); PropertyField("m_LineStyle"); diff --git a/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs b/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs index 18f86050..7fac3ab5 100644 --- a/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs +++ b/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs @@ -23,6 +23,7 @@ public override void SetDefaultValue() splitLine.show = false; splitLine.lineStyle.type = LineStyle.Type.None; axisLabel.textLimit.enable = true; + axisName.labelStyle.offset = new Vector3(0, 25, 0); } } diff --git a/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs b/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs index 0ae6185c..f1e8d57a 100644 --- a/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs +++ b/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs @@ -160,7 +160,7 @@ private void DrawParallelAxisLine(VertexHelper vh, ParallelAxis axis) internal override float GetAxisLineXOrY() { - return component.context.y; + return component.context.x; } } } \ No newline at end of file diff --git a/Runtime/Serie/Parallel/Parallel.cs b/Runtime/Serie/Parallel/Parallel.cs index 721f9f91..09b65279 100644 --- a/Runtime/Serie/Parallel/Parallel.cs +++ b/Runtime/Serie/Parallel/Parallel.cs @@ -6,7 +6,8 @@ namespace XCharts.Runtime [System.Serializable] [SerieHandler(typeof(ParallelHandler), true)] [RequireChartComponent(typeof(ParallelCoord))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] + [SerieExtraComponent(typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] + [SerieDataExtraComponent(typeof(EmphasisStyle), typeof(BlurStyle), typeof(SelectStyle))] [SerieDataExtraField()] public class Parallel : Serie, INeedSerieContainer { diff --git a/Runtime/Serie/Parallel/ParallelHandler.cs b/Runtime/Serie/Parallel/ParallelHandler.cs index c126f576..26a5be3b 100644 --- a/Runtime/Serie/Parallel/ParallelHandler.cs +++ b/Runtime/Serie/Parallel/ParallelHandler.cs @@ -8,8 +8,6 @@ namespace XCharts.Runtime [UnityEngine.Scripting.Preserve] internal sealed class ParallelHandler : SerieHandler { - private List m_Points = new List(); - public override void Update() { base.Update(); @@ -38,7 +36,7 @@ private void DrawParallelSerie(VertexHelper vh, Parallel serie) var animationIndex = serie.animation.GetCurrIndex(); var isHorizonal = parallel.orient == Orient.Horizonal; - var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.context.colorIndex); + var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); float currDetailProgress = !isHorizonal ? @@ -58,9 +56,11 @@ private void DrawParallelSerie(VertexHelper vh, Parallel serie) var isSmooth = serie.lineType == LineType.Smooth; foreach (var serieData in serie.data) { - m_Points.Clear(); var count = Mathf.Min(axisCount, serieData.data.Count); var lp = Vector3.zero; + var colorIndex = serie.colorByData?serieData.index : serie.context.colorIndex; + var lineColor = SerieHelper.GetLineColor(serie, serieData, chart.theme, colorIndex); + serieData.context.dataPoints.Clear(); for (int i = 0; i < count; i++) { if (animationIndex >= 0 && i > animationIndex) continue; @@ -69,11 +69,11 @@ private void DrawParallelSerie(VertexHelper vh, Parallel serie) { if (isSmooth) { - m_Points.Add(pos); + serieData.context.dataPoints.Add(pos); } else if (pos.x <= currProgress) { - m_Points.Add(pos); + serieData.context.dataPoints.Add(pos); } else { @@ -82,9 +82,9 @@ private void DrawParallelSerie(VertexHelper vh, Parallel serie) var intersectionPos = Vector3.zero; if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos)) - m_Points.Add(intersectionPos); + serieData.context.dataPoints.Add(intersectionPos); else - m_Points.Add(pos); + serieData.context.dataPoints.Add(pos); break; } } @@ -92,11 +92,11 @@ private void DrawParallelSerie(VertexHelper vh, Parallel serie) { if (isSmooth) { - m_Points.Add(pos); + serieData.context.dataPoints.Add(pos); } else if (pos.y <= currProgress) { - m_Points.Add(pos); + serieData.context.dataPoints.Add(pos); } else { @@ -105,21 +105,21 @@ private void DrawParallelSerie(VertexHelper vh, Parallel serie) var intersectionPos = Vector3.zero; if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos)) - m_Points.Add(intersectionPos); + serieData.context.dataPoints.Add(intersectionPos); else - m_Points.Add(pos); + serieData.context.dataPoints.Add(pos); break; } } lp = pos; } if (isSmooth) - UGL.DrawCurves(vh, m_Points, lineWidth, lineColor, + UGL.DrawCurves(vh, serieData.context.dataPoints, lineWidth, lineColor, chart.settings.lineSmoothStyle, chart.settings.lineSmoothness, UGL.Direction.XAxis, currProgress, isHorizonal); else - UGL.DrawLine(vh, m_Points, lineWidth, lineColor, isSmooth); + UGL.DrawLine(vh, serieData.context.dataPoints, lineWidth, lineColor, isSmooth); } if (!serie.animation.IsFinish()) { diff --git a/Runtime/Serie/SerieHandler.cs b/Runtime/Serie/SerieHandler.cs index 62d0e05e..0b8a53fb 100644 --- a/Runtime/Serie/SerieHandler.cs +++ b/Runtime/Serie/SerieHandler.cs @@ -448,7 +448,7 @@ public virtual void RefreshEndLabelInternal() var endLabelStyle = serie.endLabel; if (endLabelStyle == null) return; - var dataCount = serie.context.drawPoints.Count; + var dataCount = serie.context.dataPoints.Count; var active = endLabelStyle.show && dataCount > 0; m_EndLabel.SetActive(active); if (active) From 7f27325ce1adb31c3fa54f4b41c96f30d115d93e Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Sun, 25 Sep 2022 22:40:30 +0800 Subject: [PATCH 34/38] [refactor]remove warning --- Runtime/Internal/Utilities/ChartHelper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Runtime/Internal/Utilities/ChartHelper.cs b/Runtime/Internal/Utilities/ChartHelper.cs index 63025ade..d1c5f7a9 100644 --- a/Runtime/Internal/Utilities/ChartHelper.cs +++ b/Runtime/Internal/Utilities/ChartHelper.cs @@ -935,7 +935,7 @@ public static Texture2D SaveAsImage(RectTransform rectTransform, Canvas canvas, Download(base64str, fileName); Debug.Log("SaveAsImage: download by brower:" + fileName); return tex; -#endif +#else if (string.IsNullOrEmpty(path)) { var dir = Application.persistentDataPath + "/SavedImage"; @@ -953,6 +953,7 @@ public static Texture2D SaveAsImage(RectTransform rectTransform, Canvas canvas, System.IO.File.WriteAllBytes(path, bytes); Debug.Log("SaveAsImage:" + path); return tex; +#endif } } } \ No newline at end of file From a9fe1f53b12e49007a029d3ed9c143a7f9f29859 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Sun, 25 Sep 2022 22:41:13 +0800 Subject: [PATCH 35/38] [doc] update doc --- CHANGELOG.md | 2 + Documentation/XChartsAPI-EN.md | 88 +++++++++++++++++++++++- Documentation/XChartsAPI-ZH.md | 88 +++++++++++++++++++++++- Documentation/XChartsConfiguration-EN.md | 2 +- Documentation/XChartsConfiguration-ZH.md | 2 +- 5 files changed, 178 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf624b2..2d5a34f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,8 @@ ## master +* (2022.09.25) 修复`API`文档中部分接口没有导出的问题 +* (2022.09.24) 优化`FunnelChart` * (2022.09.23) 优化`ParallelChart` * (2022.09.22) 增加`SaveAsImage()`接口保存图表到图片 * (2022.09.21) 修复`InsertSerie()`接口不刷新图表的问题 diff --git a/Documentation/XChartsAPI-EN.md b/Documentation/XChartsAPI-EN.md index 931cd18f..dc8d9f4f 100644 --- a/Documentation/XChartsAPI-EN.md +++ b/Documentation/XChartsAPI-EN.md @@ -153,6 +153,8 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver |public method|description| |--|--| | `AddChartComponent()` |public MainComponent AddChartComponent(Type type)
| +| `AddChartComponent()` |public T AddChartComponent() where T : MainComponent
| +| `AddChartComponentWhenNoExist()` |public T AddChartComponentWhenNoExist() where T : MainComponent
| | `AddData()` |public SerieData AddData(int serieIndex, DateTime time, double yValue, string dataName = null, string dataId = null)
Add a (time,y) data to serie. | | `AddData()` |public SerieData AddData(int serieIndex, double data, string dataName = null, string dataId = null)
Add a data to serie. | | `AddData()` |public SerieData AddData(int serieIndex, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| @@ -163,6 +165,7 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `AddData()` |public SerieData AddData(string serieName, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| | `AddData()` |public SerieData AddData(string serieName, double xValue, double yValue, string dataName = null, string dataId = null)
Add a (x,y) data to serie. | | `AddData()` |public SerieData AddData(string serieName, List multidimensionalData, string dataName = null, string dataId = null)
Add an arbitray dimension data to serie,such as (x,y,z,...). | +| `AddSerie()` |public T AddSerie(string serieName = null, bool show = true, bool addToHead = false) where T : Serie
| | `AddXAxisData()` |public void AddXAxisData(string category, int xAxisIndex = 0)
Add a category data to xAxis. | | `AddXAxisIcon()` |public void AddXAxisIcon(Sprite icon, int xAxisIndex = 0)
Add an icon to xAxis. | | `AddYAxisData()` |public void AddYAxisData(string category, int yAxisIndex = 0)
Add a category data to yAxis. | @@ -175,17 +178,22 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `AnimationResume()` |public void AnimationResume()
Stop play animation. | | `CanAddChartComponent()` |public bool CanAddChartComponent(Type type)
| | `CanAddSerie()` |public bool CanAddSerie(Type type)
| +| `CanAddSerie()` |public bool CanAddSerie() where T : Serie
| | `CanMultipleComponent()` |public bool CanMultipleComponent(Type type)
| | `ClampInChart()` |public void ClampInChart(ref Vector3 pos)
| | `ClampInGrid()` |public Vector3 ClampInGrid(GridCoord grid, Vector3 pos)
| | `ClearData()` |public virtual void ClearData()
Clear all components and series data. Note: serie only empties the data and does not remove serie. | | `ClickLegendButton()` |public void ClickLegendButton(int legendIndex, string legendName, bool show)
点击图例按钮 | | `CovertSerie()` |public bool CovertSerie(Serie serie, Type type)
| +| `CovertSerie()` |public bool CovertSerie(Serie serie) where T : Serie
| | `CovertXYAxis()` |public void CovertXYAxis(int index)
转换X轴和Y轴的配置 | | `GenerateDefaultSerieName()` |public string GenerateDefaultSerieName()
| | `GetAllSerieDataCount()` |public int GetAllSerieDataCount()
| | `GetChartBackgroundColor()` |public Color32 GetChartBackgroundColor()
| +| `GetChartComponent()` |public T GetChartComponent(int index = 0) where T : MainComponent
| | `GetChartComponentNum()` |public int GetChartComponentNum(Type type)
| +| `GetChartComponentNum()` |public int GetChartComponentNum() where T : MainComponent
| +| `GetChartComponents()` |public List GetChartComponents() where T : MainComponent
| | `GetData()` |public double GetData(int serieIndex, int dataIndex, int dimension = 1)
| | `GetData()` |public double GetData(string serieName, int dataIndex, int dimension = 1)
| | `GetDataZoomOfAxis()` |public DataZoom GetDataZoomOfAxis(Axis axis)
| @@ -197,10 +205,19 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `GetItemColor()` |public Color32 GetItemColor(Serie serie, SerieData serieData, int colorIndex)
| | `GetLegendRealShowNameColor()` |public Color32 GetLegendRealShowNameColor(string name)
| | `GetLegendRealShowNameIndex()` |public int GetLegendRealShowNameIndex(string name)
| +| `GetOrAddChartComponent()` |public T GetOrAddChartComponent() where T : MainComponent
| | `GetPainter()` |public Painter GetPainter(int index)
| | `GetSerie()` |public Serie GetSerie(int serieIndex)
| | `GetSerie()` |public Serie GetSerie(string serieName)
| +| `GetSerie()` |public T GetSerie() where T : Serie
| +| `GetSerie()` |public T GetSerie(int serieIndex) where T : Serie
| +| `GetSerieBarGap()` |public float GetSerieBarGap() where T : Serie
| +| `GetSerieBarRealCount()` |public int GetSerieBarRealCount() where T : Serie
| +| `GetSerieIndexIfStack()` |public int GetSerieIndexIfStack(Serie currSerie) where T : Serie
| +| `GetSerieSameStackTotalValue()` |public double GetSerieSameStackTotalValue(string stack, int dataIndex) where T : Serie
| | `GetSeriesMinMaxValue()` |public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue)
| +| `GetSerieTotalGap()` |public float GetSerieTotalGap(float categoryWidth, float gap, int index) where T : Serie
| +| `GetSerieTotalWidth()` |public float GetSerieTotalWidth(float categoryWidth, float gap, int realBarCount) where T : Serie
| | `GetTitlePosition()` |public Vector3 GetTitlePosition(Title title)
| | `GetVisualMapOfSerie()` |public VisualMap GetVisualMapOfSerie(Serie serie)
| | `GetXDataZoomOfSerie()` |public DataZoom GetXDataZoomOfSerie(Serie serie)
| @@ -209,8 +226,11 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `HasChartComponent()` |public bool HasChartComponent(Type type)
| | `HasChartComponent()` |public bool HasChartComponent()
| | `HasSerie()` |public bool HasSerie(Type type)
| +| `HasSerie()` |public bool HasSerie() where T : Serie
| | `Init()` |public void Init(bool defaultChart = true)
| +| `InitAxisRuntimeData()` |public virtual void InitAxisRuntimeData(Axis axis) { }
| | `InsertSerie()` |public void InsertSerie(Serie serie, int index = -1, bool addToHead = false)
| +| `InsertSerie()` |public T InsertSerie(int index, string serieName = null, bool show = true) where T : Serie
| | `Internal_CheckAnimation()` |public void Internal_CheckAnimation()
| | `IsActiveByLegend()` |public virtual bool IsActiveByLegend(string legendName)
Whether serie is activated. | | `IsAllAxisCategory()` |public bool IsAllAxisCategory()
纯类目轴。 | @@ -241,6 +261,7 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `RefreshChart()` |public void RefreshChart(int serieIndex)
Redraw chart serie in next frame. | | `RefreshChart()` |public void RefreshChart(Serie serie)
Redraw chart serie in next frame. | | `RefreshDataZoom()` |public void RefreshDataZoom()
在下一帧刷新DataZoom | +| `RefreshGraph()` |public override void RefreshGraph()
| | `RefreshPainter()` |public void RefreshPainter(int index)
| | `RefreshPainter()` |public void RefreshPainter(Serie serie)
| | `RefreshTopPainter()` |public void RefreshTopPainter()
| @@ -257,8 +278,10 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `RemoveSerie()` |public void RemoveSerie(int serieIndex)
| | `RemoveSerie()` |public void RemoveSerie(Serie serie)
| | `RemoveSerie()` |public void RemoveSerie(string serieName)
| +| `RemoveSerie()` |public void RemoveSerie() where T : Serie
| | `ReplaceSerie()` |public bool ReplaceSerie(Serie oldSerie, Serie newSerie)
| | `ResetDataIndex()` |public bool ResetDataIndex(int serieIndex)
重置serie的数据项索引。避免数据项索引异常。 | +| `SaveAsImage()` |public void SaveAsImage(string imageType = "png", string savePath = "")
保存图表为图片。 | | `SetBasePainterMaterial()` |public void SetBasePainterMaterial(Material material)
设置Base Painter的材质球 | | `SetMaxCache()` |public void SetMaxCache(int maxCache)
设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。 | | `SetPainterActive()` |public void SetPainterActive(int index, bool flag)
| @@ -269,6 +292,8 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `SetTopPainterMaterial()` |public void SetTopPainterMaterial(Material material)
设置Top Painter的材质球 | | `SetUpperPainterMaterial()` |public void SetUpperPainterMaterial(Material material)
设置Upper Painter的材质球 | | `TryAddChartComponent()` |public bool TryAddChartComponent(Type type)
| +| `TryAddChartComponent()` |public bool TryAddChartComponent() where T : MainComponent
| +| `TryAddChartComponent()` |public bool TryAddChartComponent(out T component) where T : MainComponent
| | `TryGetChartComponent()` |public bool TryGetChartComponent(out T component, int index = 0)
| | `UdpateXAxisIcon()` |public void UdpateXAxisIcon(int index, Sprite icon, int xAxisIndex = 0)
Update xAxis icon. | | `UpdateData()` |public bool UpdateData(int serieIndex, int dataIndex, double value)
Update serie data by serie index. | @@ -304,7 +329,7 @@ Inherits or Implemented: [MaskableGraphic](#MaskableGraphic),[IPointerDownHandle | `OnScroll()` |public virtual void OnScroll(PointerEventData eventData)
| | `RebuildChartObject()` |public void RebuildChartObject()
移除并重新创建所有图表的Object。 | | `RefreshAllComponent()` |public void RefreshAllComponent()
| -| `RefreshGraph()` |public void RefreshGraph()
Redraw graph in next frame. | +| `RefreshGraph()` |public virtual void RefreshGraph()
Redraw graph in next frame. | | `ScreenPointToChartPoint()` |public bool ScreenPointToChartPoint(Vector2 screenPoint, out Vector2 chartPoint)
| | `SetPainterDirty()` |public void SetPainterDirty()
重新初始化Painter | | `SetSize()` |public virtual void SetSize(float width, float height)
设置图形的宽高(在非stretch pivot下才有效,其他情况需要自己调整RectTransform) | @@ -356,6 +381,8 @@ Inherits or Implemented: [BaseChart](#BaseChart) | `GetMaxLogValue()` |public static double GetMaxLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber)
| | `GetMinDivisibleValue()` |public static double GetMinDivisibleValue(double min, double ceilRate)
| | `GetMinLogValue()` |public static double GetMinLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber)
| +| `GetOrAddComponent()` |public static T GetOrAddComponent(GameObject gameObject) where T : Component
| +| `GetOrAddComponent()` |public static T GetOrAddComponent(Transform transform) where T : Component
| | `GetPointList()` |public static void GetPointList(ref List posList, Vector3 sp, Vector3 ep, float k = 30f)
| | `GetPos()` |public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false)
| | `GetPosition()` |public static Vector3 GetPosition(Vector3 center, float angle, float radius)
| @@ -382,6 +409,7 @@ Inherits or Implemented: [BaseChart](#BaseChart) | `ParseStringFromString()` |public static List ParseStringFromString(string jsonData)
| | `RemoveComponent()` |public static void RemoveComponent(GameObject gameObject)
| | `RotateRound()` |public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
| +| `SaveAsImage()` |public static Texture2D SaveAsImage(RectTransform rectTransform, Canvas canvas, string imageType = "png", string path = "")
| | `SetActive()` |public static void SetActive(GameObject gameObject, bool active)
| | `SetActive()` |public static void SetActive(Image image, bool active)
| | `SetActive()` |public static void SetActive(Text text, bool active)
| @@ -460,6 +488,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| +| `Contains()` |public bool Contains() where T : CoordSystem
| | `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord)
| | `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2)
| | `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2, Type coord3)
| @@ -474,6 +503,7 @@ Inherits or Implemented: [MainComponentContext](#MainComponentContext) |public method|description| |--|--| | `UpdateDataZoomRuntimeStartEndValue()` |public static void UpdateDataZoomRuntimeStartEndValue(DataZoom dataZoom, Serie serie)
| +| `UpdateDataZoomRuntimeStartEndValue()` |public static void UpdateDataZoomRuntimeStartEndValue(BaseChart chart) where T : Serie
| ## `DateTimeUtil` @@ -617,6 +647,26 @@ Inherits or Implemented: [ListFor](#ListFor) ## `MainComponentHandler` +|public method|description| +|--|--| +| `CheckComponent()` |public virtual void CheckComponent(StringBuilder sb) { }
| +| `DrawBase()` |public virtual void DrawBase(VertexHelper vh) { }
| +| `DrawTop()` |public virtual void DrawTop(VertexHelper vh) { }
| +| `DrawUpper()` |public virtual void DrawUpper(VertexHelper vh) { }
| +| `InitComponent()` |public virtual void InitComponent() { }
| +| `OnBeginDrag()` |public virtual void OnBeginDrag(PointerEventData eventData) { }
| +| `OnDrag()` |public virtual void OnDrag(PointerEventData eventData) { }
| +| `OnEndDrag()` |public virtual void OnEndDrag(PointerEventData eventData) { }
| +| `OnPointerClick()` |public virtual void OnPointerClick(PointerEventData eventData) { }
| +| `OnPointerDown()` |public virtual void OnPointerDown(PointerEventData eventData) { }
| +| `OnPointerEnter()` |public virtual void OnPointerEnter(PointerEventData eventData) { }
| +| `OnPointerExit()` |public virtual void OnPointerExit(PointerEventData eventData) { }
| +| `OnPointerUp()` |public virtual void OnPointerUp(PointerEventData eventData) { }
| +| `OnScroll()` |public virtual void OnScroll(PointerEventData eventData) { }
| +| `OnSerieDataUpdate()` |public virtual void OnSerieDataUpdate(int serieIndex) { }
| +| `RemoveComponent()` |public virtual void RemoveComponent() { }
| +| `Update()` |public virtual void Update() { }
| + ## `MainComponentHandler` Inherits or Implemented: [MainComponentHandler](#MainComponentHandler) @@ -681,8 +731,10 @@ Inherits or Implemented: [BaseChart](#BaseChart) |public method|description| |--|--| +| `SetClass()` |public static bool SetClass(ref T currentValue, T newValue, bool notNull = false) where T : class
| | `SetColor()` |public static bool SetColor(ref Color currentValue, Color newValue)
| | `SetColor()` |public static bool SetColor(ref Color32 currentValue, Color32 newValue)
| +| `SetStruct()` |public static bool SetStruct(ref T currentValue, T newValue) where T : struct
| ## `RadarChart` @@ -724,6 +776,8 @@ Inherits or Implemented: [BaseChart](#BaseChart) | `GetAllAssemblyTypes()` |public static IEnumerable GetAllAssemblyTypes()
| | `GetAllTypesDerivedFrom()` |public static IEnumerable GetAllTypesDerivedFrom(Type type)
| | `GetAllTypesDerivedFrom()` |public static IEnumerable GetAllTypesDerivedFrom()
| +| `GetAttribute()` |public static T GetAttribute(this MemberInfo type, bool check = true) where T : Attribute
| +| `GetAttribute()` |public static T GetAttribute(this Type type, bool check = true) where T : Attribute
| | `HasSubclass()` |public static bool HasSubclass(Type type)
| ## `ScatterChart` @@ -739,6 +793,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| | `Contains()` |public bool Contains(Type type)
| +| `Contains()` |public bool Contains() where T : Serie
| | `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie)
| | `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2)
| | `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2, Type serie3)
| @@ -757,6 +812,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| | `Contains()` |public bool Contains(Type type)
| +| `Contains()` |public bool Contains() where T : ISerieExtraComponent
| | `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute()
| | `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1)
| | `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2)
| @@ -789,6 +845,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| | `Contains()` |public bool Contains(Type type)
| +| `Contains()` |public bool Contains() where T : ISerieExtraComponent
| | `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute()
| | `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1)
| | `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2)
| @@ -800,6 +857,31 @@ Inherits or Implemented: [Attribute](#Attribute) ## `SerieHandler` +|public method|description| +|--|--| +| `CheckComponent()` |public virtual void CheckComponent(StringBuilder sb) { }
| +| `DrawBase()` |public virtual void DrawBase(VertexHelper vh) { }
| +| `DrawSerie()` |public virtual void DrawSerie(VertexHelper vh) { }
| +| `DrawTop()` |public virtual void DrawTop(VertexHelper vh) { }
| +| `DrawUpper()` |public virtual void DrawUpper(VertexHelper vh) { }
| +| `InitComponent()` |public virtual void InitComponent() { }
| +| `OnBeginDrag()` |public virtual void OnBeginDrag(PointerEventData eventData) { }
| +| `OnDrag()` |public virtual void OnDrag(PointerEventData eventData) { }
| +| `OnEndDrag()` |public virtual void OnEndDrag(PointerEventData eventData) { }
| +| `OnLegendButtonClick()` |public virtual void OnLegendButtonClick(int index, string legendName, bool show) { }
| +| `OnLegendButtonEnter()` |public virtual void OnLegendButtonEnter(int index, string legendName) { }
| +| `OnLegendButtonExit()` |public virtual void OnLegendButtonExit(int index, string legendName) { }
| +| `OnPointerClick()` |public virtual void OnPointerClick(PointerEventData eventData) { }
| +| `OnPointerDown()` |public virtual void OnPointerDown(PointerEventData eventData) { }
| +| `OnPointerEnter()` |public virtual void OnPointerEnter(PointerEventData eventData) { }
| +| `OnPointerExit()` |public virtual void OnPointerExit(PointerEventData eventData) { }
| +| `OnPointerUp()` |public virtual void OnPointerUp(PointerEventData eventData) { }
| +| `OnScroll()` |public virtual void OnScroll(PointerEventData eventData) { }
| +| `RefreshLabelInternal()` |public virtual void RefreshLabelInternal() { }
| +| `RefreshLabelNextFrame()` |public virtual void RefreshLabelNextFrame() { }
| +| `RemoveComponent()` |public virtual void RemoveComponent() { }
| +| `Update()` |public virtual void Update() { }
| + ## `SerieHandler` Inherits or Implemented: [SerieHandler where T](#SerieHandler where T),[Serie](#Serie) @@ -833,6 +915,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| +| `CloneSerie()` |public static T CloneSerie(Serie serie) where T : Serie
| | `CopySerie()` |public static void CopySerie(Serie oldSerie, Serie newSerie)
| | `GetAllMinMaxData()` |public static void GetAllMinMaxData(Serie serie, double ceilRate = 0, DataZoom dataZoom = null)
| | `GetAreaStyle()` |public static AreaStyle GetAreaStyle(Serie serie, SerieData serieData)
| @@ -902,7 +985,10 @@ Inherits or Implemented: [Attribute](#Attribute) | `GetStackSeries()` |public static void GetStackSeries(List series, ref Dictionary> stackSeries)
获得堆叠系列列表 | | `IsAnyClipSerie()` |public static bool IsAnyClipSerie(List series)
是否有需裁剪的serie。 | | `IsLegalLegendName()` |public static bool IsLegalLegendName(string name)
| +| `IsPercentStack()` |public static bool IsPercentStack(List series) where T : Serie
是否时百分比堆叠 | +| `IsPercentStack()` |public static bool IsPercentStack(List series, string stackName) where T : Serie
是否时百分比堆叠 | | `IsStack()` |public static bool IsStack(List series)
是否由数据堆叠 | +| `IsStack()` |public static bool IsStack(List series, string stackName) where T : Serie
是否堆叠 | | `UpdateSerieNameList()` |public static void UpdateSerieNameList(BaseChart chart, ref List serieNameList)
获得所有系列名,不包含空名字。 | | `UpdateStackDataList()` |public static void UpdateStackDataList(List series, Serie currSerie, DataZoom dataZoom, List> dataList)
| diff --git a/Documentation/XChartsAPI-ZH.md b/Documentation/XChartsAPI-ZH.md index 878e8c08..d4b73194 100644 --- a/Documentation/XChartsAPI-ZH.md +++ b/Documentation/XChartsAPI-ZH.md @@ -153,6 +153,8 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver |public method|description| |--|--| | `AddChartComponent()` |public MainComponent AddChartComponent(Type type)
| +| `AddChartComponent()` |public T AddChartComponent() where T : MainComponent
| +| `AddChartComponentWhenNoExist()` |public T AddChartComponentWhenNoExist() where T : MainComponent
| | `AddData()` |public SerieData AddData(int serieIndex, DateTime time, double yValue, string dataName = null, string dataId = null)
添加(time,y)数据到指定的系列中。 | | `AddData()` |public SerieData AddData(int serieIndex, double data, string dataName = null, string dataId = null)
添加一个数据到指定的系列中。 | | `AddData()` |public SerieData AddData(int serieIndex, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| @@ -163,6 +165,7 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `AddData()` |public SerieData AddData(string serieName, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| | `AddData()` |public SerieData AddData(string serieName, double xValue, double yValue, string dataName = null, string dataId = null)
添加(x,y)数据到指定系列中。 | | `AddData()` |public SerieData AddData(string serieName, List multidimensionalData, string dataName = null, string dataId = null)
添加多维数据(x,y,z...)到指定的系列中。 | +| `AddSerie()` |public T AddSerie(string serieName = null, bool show = true, bool addToHead = false) where T : Serie
| | `AddXAxisData()` |public void AddXAxisData(string category, int xAxisIndex = 0)
添加一个类目数据到指定的x轴。 | | `AddXAxisIcon()` |public void AddXAxisIcon(Sprite icon, int xAxisIndex = 0)
添加一个图标到指定的x轴。 | | `AddYAxisData()` |public void AddYAxisData(string category, int yAxisIndex = 0)
添加一个类目数据到指定的y轴。 | @@ -175,17 +178,22 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `AnimationResume()` |public void AnimationResume()
继续动画。 | | `CanAddChartComponent()` |public bool CanAddChartComponent(Type type)
| | `CanAddSerie()` |public bool CanAddSerie(Type type)
| +| `CanAddSerie()` |public bool CanAddSerie() where T : Serie
| | `CanMultipleComponent()` |public bool CanMultipleComponent(Type type)
| | `ClampInChart()` |public void ClampInChart(ref Vector3 pos)
| | `ClampInGrid()` |public Vector3 ClampInGrid(GridCoord grid, Vector3 pos)
| | `ClearData()` |public virtual void ClearData()
清空所有组件和Serie的数据。注意:Serie只是清空数据,不会移除Serie。 | | `ClickLegendButton()` |public void ClickLegendButton(int legendIndex, string legendName, bool show)
点击图例按钮 | | `CovertSerie()` |public bool CovertSerie(Serie serie, Type type)
| +| `CovertSerie()` |public bool CovertSerie(Serie serie) where T : Serie
| | `CovertXYAxis()` |public void CovertXYAxis(int index)
转换X轴和Y轴的配置 | | `GenerateDefaultSerieName()` |public string GenerateDefaultSerieName()
| | `GetAllSerieDataCount()` |public int GetAllSerieDataCount()
| | `GetChartBackgroundColor()` |public Color32 GetChartBackgroundColor()
| +| `GetChartComponent()` |public T GetChartComponent(int index = 0) where T : MainComponent
| | `GetChartComponentNum()` |public int GetChartComponentNum(Type type)
| +| `GetChartComponentNum()` |public int GetChartComponentNum() where T : MainComponent
| +| `GetChartComponents()` |public List GetChartComponents() where T : MainComponent
| | `GetData()` |public double GetData(int serieIndex, int dataIndex, int dimension = 1)
| | `GetData()` |public double GetData(string serieName, int dataIndex, int dimension = 1)
| | `GetDataZoomOfAxis()` |public DataZoom GetDataZoomOfAxis(Axis axis)
| @@ -197,10 +205,19 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `GetItemColor()` |public Color32 GetItemColor(Serie serie, SerieData serieData, int colorIndex)
| | `GetLegendRealShowNameColor()` |public Color32 GetLegendRealShowNameColor(string name)
| | `GetLegendRealShowNameIndex()` |public int GetLegendRealShowNameIndex(string name)
| +| `GetOrAddChartComponent()` |public T GetOrAddChartComponent() where T : MainComponent
| | `GetPainter()` |public Painter GetPainter(int index)
| | `GetSerie()` |public Serie GetSerie(int serieIndex)
| | `GetSerie()` |public Serie GetSerie(string serieName)
| +| `GetSerie()` |public T GetSerie() where T : Serie
| +| `GetSerie()` |public T GetSerie(int serieIndex) where T : Serie
| +| `GetSerieBarGap()` |public float GetSerieBarGap() where T : Serie
| +| `GetSerieBarRealCount()` |public int GetSerieBarRealCount() where T : Serie
| +| `GetSerieIndexIfStack()` |public int GetSerieIndexIfStack(Serie currSerie) where T : Serie
| +| `GetSerieSameStackTotalValue()` |public double GetSerieSameStackTotalValue(string stack, int dataIndex) where T : Serie
| | `GetSeriesMinMaxValue()` |public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue)
| +| `GetSerieTotalGap()` |public float GetSerieTotalGap(float categoryWidth, float gap, int index) where T : Serie
| +| `GetSerieTotalWidth()` |public float GetSerieTotalWidth(float categoryWidth, float gap, int realBarCount) where T : Serie
| | `GetTitlePosition()` |public Vector3 GetTitlePosition(Title title)
| | `GetVisualMapOfSerie()` |public VisualMap GetVisualMapOfSerie(Serie serie)
| | `GetXDataZoomOfSerie()` |public DataZoom GetXDataZoomOfSerie(Serie serie)
| @@ -209,8 +226,11 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `HasChartComponent()` |public bool HasChartComponent(Type type)
| | `HasChartComponent()` |public bool HasChartComponent()
| | `HasSerie()` |public bool HasSerie(Type type)
| +| `HasSerie()` |public bool HasSerie() where T : Serie
| | `Init()` |public void Init(bool defaultChart = true)
| +| `InitAxisRuntimeData()` |public virtual void InitAxisRuntimeData(Axis axis) { }
| | `InsertSerie()` |public void InsertSerie(Serie serie, int index = -1, bool addToHead = false)
| +| `InsertSerie()` |public T InsertSerie(int index, string serieName = null, bool show = true) where T : Serie
| | `Internal_CheckAnimation()` |public void Internal_CheckAnimation()
| | `IsActiveByLegend()` |public virtual bool IsActiveByLegend(string legendName)
获得指定图例名字的系列是否显示。 | | `IsAllAxisCategory()` |public bool IsAllAxisCategory()
纯类目轴。 | @@ -241,6 +261,7 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `RefreshChart()` |public void RefreshChart(int serieIndex)
在下一帧刷新图表的指定serie。 | | `RefreshChart()` |public void RefreshChart(Serie serie)
在下一帧刷新图表的指定serie。 | | `RefreshDataZoom()` |public void RefreshDataZoom()
在下一帧刷新DataZoom | +| `RefreshGraph()` |public override void RefreshGraph()
| | `RefreshPainter()` |public void RefreshPainter(int index)
| | `RefreshPainter()` |public void RefreshPainter(Serie serie)
| | `RefreshTopPainter()` |public void RefreshTopPainter()
| @@ -257,8 +278,10 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `RemoveSerie()` |public void RemoveSerie(int serieIndex)
| | `RemoveSerie()` |public void RemoveSerie(Serie serie)
| | `RemoveSerie()` |public void RemoveSerie(string serieName)
| +| `RemoveSerie()` |public void RemoveSerie() where T : Serie
| | `ReplaceSerie()` |public bool ReplaceSerie(Serie oldSerie, Serie newSerie)
| | `ResetDataIndex()` |public bool ResetDataIndex(int serieIndex)
重置serie的数据项索引。避免数据项索引异常。 | +| `SaveAsImage()` |public void SaveAsImage(string imageType = "png", string savePath = "")
保存图表为图片。 | | `SetBasePainterMaterial()` |public void SetBasePainterMaterial(Material material)
设置Base Painter的材质球 | | `SetMaxCache()` |public void SetMaxCache(int maxCache)
设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。 | | `SetPainterActive()` |public void SetPainterActive(int index, bool flag)
| @@ -269,6 +292,8 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver | `SetTopPainterMaterial()` |public void SetTopPainterMaterial(Material material)
设置Top Painter的材质球 | | `SetUpperPainterMaterial()` |public void SetUpperPainterMaterial(Material material)
设置Upper Painter的材质球 | | `TryAddChartComponent()` |public bool TryAddChartComponent(Type type)
| +| `TryAddChartComponent()` |public bool TryAddChartComponent() where T : MainComponent
| +| `TryAddChartComponent()` |public bool TryAddChartComponent(out T component) where T : MainComponent
| | `TryGetChartComponent()` |public bool TryGetChartComponent(out T component, int index = 0)
| | `UdpateXAxisIcon()` |public void UdpateXAxisIcon(int index, Sprite icon, int xAxisIndex = 0)
更新X轴图标。 | | `UpdateData()` |public bool UpdateData(int serieIndex, int dataIndex, double value)
更新指定系列中的指定索引数据。 | @@ -304,7 +329,7 @@ Inherits or Implemented: [MaskableGraphic](#MaskableGraphic),[IPointerDownHandle | `OnScroll()` |public virtual void OnScroll(PointerEventData eventData)
| | `RebuildChartObject()` |public void RebuildChartObject()
移除并重新创建所有图表的Object。 | | `RefreshAllComponent()` |public void RefreshAllComponent()
| -| `RefreshGraph()` |public void RefreshGraph()
在下一帧刷新图形。 | +| `RefreshGraph()` |public virtual void RefreshGraph()
在下一帧刷新图形。 | | `ScreenPointToChartPoint()` |public bool ScreenPointToChartPoint(Vector2 screenPoint, out Vector2 chartPoint)
| | `SetPainterDirty()` |public void SetPainterDirty()
重新初始化Painter | | `SetSize()` |public virtual void SetSize(float width, float height)
设置图形的宽高(在非stretch pivot下才有效,其他情况需要自己调整RectTransform) | @@ -356,6 +381,8 @@ Inherits or Implemented: [BaseChart](#BaseChart) | `GetMaxLogValue()` |public static double GetMaxLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber)
| | `GetMinDivisibleValue()` |public static double GetMinDivisibleValue(double min, double ceilRate)
| | `GetMinLogValue()` |public static double GetMinLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber)
| +| `GetOrAddComponent()` |public static T GetOrAddComponent(GameObject gameObject) where T : Component
| +| `GetOrAddComponent()` |public static T GetOrAddComponent(Transform transform) where T : Component
| | `GetPointList()` |public static void GetPointList(ref List posList, Vector3 sp, Vector3 ep, float k = 30f)
| | `GetPos()` |public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false)
| | `GetPosition()` |public static Vector3 GetPosition(Vector3 center, float angle, float radius)
| @@ -382,6 +409,7 @@ Inherits or Implemented: [BaseChart](#BaseChart) | `ParseStringFromString()` |public static List ParseStringFromString(string jsonData)
| | `RemoveComponent()` |public static void RemoveComponent(GameObject gameObject)
| | `RotateRound()` |public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
| +| `SaveAsImage()` |public static Texture2D SaveAsImage(RectTransform rectTransform, Canvas canvas, string imageType = "png", string path = "")
| | `SetActive()` |public static void SetActive(GameObject gameObject, bool active)
| | `SetActive()` |public static void SetActive(Image image, bool active)
| | `SetActive()` |public static void SetActive(Text text, bool active)
| @@ -460,6 +488,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| +| `Contains()` |public bool Contains() where T : CoordSystem
| | `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord)
| | `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2)
| | `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2, Type coord3)
| @@ -474,6 +503,7 @@ Inherits or Implemented: [MainComponentContext](#MainComponentContext) |public method|description| |--|--| | `UpdateDataZoomRuntimeStartEndValue()` |public static void UpdateDataZoomRuntimeStartEndValue(DataZoom dataZoom, Serie serie)
| +| `UpdateDataZoomRuntimeStartEndValue()` |public static void UpdateDataZoomRuntimeStartEndValue(BaseChart chart) where T : Serie
| ## `DateTimeUtil` @@ -617,6 +647,26 @@ Inherits or Implemented: [ListFor](#ListFor) ## `MainComponentHandler` +|public method|description| +|--|--| +| `CheckComponent()` |public virtual void CheckComponent(StringBuilder sb) { }
| +| `DrawBase()` |public virtual void DrawBase(VertexHelper vh) { }
| +| `DrawTop()` |public virtual void DrawTop(VertexHelper vh) { }
| +| `DrawUpper()` |public virtual void DrawUpper(VertexHelper vh) { }
| +| `InitComponent()` |public virtual void InitComponent() { }
| +| `OnBeginDrag()` |public virtual void OnBeginDrag(PointerEventData eventData) { }
| +| `OnDrag()` |public virtual void OnDrag(PointerEventData eventData) { }
| +| `OnEndDrag()` |public virtual void OnEndDrag(PointerEventData eventData) { }
| +| `OnPointerClick()` |public virtual void OnPointerClick(PointerEventData eventData) { }
| +| `OnPointerDown()` |public virtual void OnPointerDown(PointerEventData eventData) { }
| +| `OnPointerEnter()` |public virtual void OnPointerEnter(PointerEventData eventData) { }
| +| `OnPointerExit()` |public virtual void OnPointerExit(PointerEventData eventData) { }
| +| `OnPointerUp()` |public virtual void OnPointerUp(PointerEventData eventData) { }
| +| `OnScroll()` |public virtual void OnScroll(PointerEventData eventData) { }
| +| `OnSerieDataUpdate()` |public virtual void OnSerieDataUpdate(int serieIndex) { }
| +| `RemoveComponent()` |public virtual void RemoveComponent() { }
| +| `Update()` |public virtual void Update() { }
| + ## `MainComponentHandler` Inherits or Implemented: [MainComponentHandler](#MainComponentHandler) @@ -681,8 +731,10 @@ Inherits or Implemented: [BaseChart](#BaseChart) |public method|description| |--|--| +| `SetClass()` |public static bool SetClass(ref T currentValue, T newValue, bool notNull = false) where T : class
| | `SetColor()` |public static bool SetColor(ref Color currentValue, Color newValue)
| | `SetColor()` |public static bool SetColor(ref Color32 currentValue, Color32 newValue)
| +| `SetStruct()` |public static bool SetStruct(ref T currentValue, T newValue) where T : struct
| ## `RadarChart` @@ -724,6 +776,8 @@ Inherits or Implemented: [BaseChart](#BaseChart) | `GetAllAssemblyTypes()` |public static IEnumerable GetAllAssemblyTypes()
| | `GetAllTypesDerivedFrom()` |public static IEnumerable GetAllTypesDerivedFrom(Type type)
| | `GetAllTypesDerivedFrom()` |public static IEnumerable GetAllTypesDerivedFrom()
| +| `GetAttribute()` |public static T GetAttribute(this MemberInfo type, bool check = true) where T : Attribute
| +| `GetAttribute()` |public static T GetAttribute(this Type type, bool check = true) where T : Attribute
| | `HasSubclass()` |public static bool HasSubclass(Type type)
| ## `ScatterChart` @@ -739,6 +793,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| | `Contains()` |public bool Contains(Type type)
| +| `Contains()` |public bool Contains() where T : Serie
| | `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie)
| | `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2)
| | `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2, Type serie3)
| @@ -757,6 +812,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| | `Contains()` |public bool Contains(Type type)
| +| `Contains()` |public bool Contains() where T : ISerieExtraComponent
| | `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute()
| | `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1)
| | `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2)
| @@ -789,6 +845,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| | `Contains()` |public bool Contains(Type type)
| +| `Contains()` |public bool Contains() where T : ISerieExtraComponent
| | `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute()
| | `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1)
| | `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2)
| @@ -800,6 +857,31 @@ Inherits or Implemented: [Attribute](#Attribute) ## `SerieHandler` +|public method|description| +|--|--| +| `CheckComponent()` |public virtual void CheckComponent(StringBuilder sb) { }
| +| `DrawBase()` |public virtual void DrawBase(VertexHelper vh) { }
| +| `DrawSerie()` |public virtual void DrawSerie(VertexHelper vh) { }
| +| `DrawTop()` |public virtual void DrawTop(VertexHelper vh) { }
| +| `DrawUpper()` |public virtual void DrawUpper(VertexHelper vh) { }
| +| `InitComponent()` |public virtual void InitComponent() { }
| +| `OnBeginDrag()` |public virtual void OnBeginDrag(PointerEventData eventData) { }
| +| `OnDrag()` |public virtual void OnDrag(PointerEventData eventData) { }
| +| `OnEndDrag()` |public virtual void OnEndDrag(PointerEventData eventData) { }
| +| `OnLegendButtonClick()` |public virtual void OnLegendButtonClick(int index, string legendName, bool show) { }
| +| `OnLegendButtonEnter()` |public virtual void OnLegendButtonEnter(int index, string legendName) { }
| +| `OnLegendButtonExit()` |public virtual void OnLegendButtonExit(int index, string legendName) { }
| +| `OnPointerClick()` |public virtual void OnPointerClick(PointerEventData eventData) { }
| +| `OnPointerDown()` |public virtual void OnPointerDown(PointerEventData eventData) { }
| +| `OnPointerEnter()` |public virtual void OnPointerEnter(PointerEventData eventData) { }
| +| `OnPointerExit()` |public virtual void OnPointerExit(PointerEventData eventData) { }
| +| `OnPointerUp()` |public virtual void OnPointerUp(PointerEventData eventData) { }
| +| `OnScroll()` |public virtual void OnScroll(PointerEventData eventData) { }
| +| `RefreshLabelInternal()` |public virtual void RefreshLabelInternal() { }
| +| `RefreshLabelNextFrame()` |public virtual void RefreshLabelNextFrame() { }
| +| `RemoveComponent()` |public virtual void RemoveComponent() { }
| +| `Update()` |public virtual void Update() { }
| + ## `SerieHandler` Inherits or Implemented: [SerieHandler where T](#SerieHandler where T),[Serie](#Serie) @@ -833,6 +915,7 @@ Inherits or Implemented: [Attribute](#Attribute) |public method|description| |--|--| +| `CloneSerie()` |public static T CloneSerie(Serie serie) where T : Serie
| | `CopySerie()` |public static void CopySerie(Serie oldSerie, Serie newSerie)
| | `GetAllMinMaxData()` |public static void GetAllMinMaxData(Serie serie, double ceilRate = 0, DataZoom dataZoom = null)
| | `GetAreaStyle()` |public static AreaStyle GetAreaStyle(Serie serie, SerieData serieData)
| @@ -902,7 +985,10 @@ Inherits or Implemented: [Attribute](#Attribute) | `GetStackSeries()` |public static void GetStackSeries(List series, ref Dictionary> stackSeries)
获得堆叠系列列表 | | `IsAnyClipSerie()` |public static bool IsAnyClipSerie(List series)
是否有需裁剪的serie。 | | `IsLegalLegendName()` |public static bool IsLegalLegendName(string name)
| +| `IsPercentStack()` |public static bool IsPercentStack(List series) where T : Serie
是否时百分比堆叠 | +| `IsPercentStack()` |public static bool IsPercentStack(List series, string stackName) where T : Serie
是否时百分比堆叠 | | `IsStack()` |public static bool IsStack(List series)
是否由数据堆叠 | +| `IsStack()` |public static bool IsStack(List series, string stackName) where T : Serie
是否堆叠 | | `UpdateSerieNameList()` |public static void UpdateSerieNameList(BaseChart chart, ref List serieNameList)
获得所有系列名,不包含空名字。 | | `UpdateStackDataList()` |public static void UpdateStackDataList(List series, Serie currSerie, DataZoom dataZoom, List> dataList)
| diff --git a/Documentation/XChartsConfiguration-EN.md b/Documentation/XChartsConfiguration-EN.md index 676e15dd..d43693a8 100644 --- a/Documentation/XChartsConfiguration-EN.md +++ b/Documentation/XChartsConfiguration-EN.md @@ -1009,7 +1009,7 @@ Polar coordinate can be used in scatter and line chart. Every polar coordinate h |--|--|--|--| |`show`|true||Whether to show the polor component. |`center`|||The center of ploar. The center[0] is the x-coordinate, and the center[1] is the y-coordinate. When value between 0 and 1 represents a percentage relative to the chart. -|`radius`|0.35f||the radius of polar. +|`radius`|||the radius of polar. |`backgroundColor`|||Background color of polar, which is transparent by default. ## `Radar` diff --git a/Documentation/XChartsConfiguration-ZH.md b/Documentation/XChartsConfiguration-ZH.md index 8abb88b2..af9a78cd 100644 --- a/Documentation/XChartsConfiguration-ZH.md +++ b/Documentation/XChartsConfiguration-ZH.md @@ -1009,7 +1009,7 @@ Inherits or Implemented: [CoordSystem](#CoordSystem),[ISerieContainer](#ISerieCo |--|--|--|--| |`show`|true||是否显示极坐标。 |`center`|||极坐标的中心点。数组的第一项是横坐标,第二项是纵坐标。 当值为0-1之间时表示百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度。 -|`radius`|0.35f||极坐标的半径。 +|`radius`|||半径。radius[0]表示内径,radius[1]表示外径。 |`backgroundColor`|||极坐标的背景色,默认透明。 ## `Radar` From 1141208407754daf8b6b6f809bf5f19ea66a2763 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 26 Sep 2022 08:38:33 +0800 Subject: [PATCH 36/38] v3.3.0 --- CHANGELOG.md | 11 +++++++++++ Documentation/XChartsTutorial01-EN.md | 9 +++++---- README.md | 8 ++++++-- Runtime/Internal/XChartsMgr.cs | 2 +- package.json | 4 ++-- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d5a34f6..9fc892e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ # 更新日志 [master](#master) +[v3.3.0](#v3.3.0) [v3.2.0](#v3.2.0) [v3.1.0](#v3.1.0) [v3.0.1](#v3.0.1) @@ -58,6 +59,16 @@ ## master +## v3.3.0 + +### 版本要点 + +* 优化图表细节,支持更多功能 +* 增加大量的Demo示例 +* 完善Editor下的操作,完善文档 + +### 日志详情 + * (2022.09.25) 修复`API`文档中部分接口没有导出的问题 * (2022.09.24) 优化`FunnelChart` * (2022.09.23) 优化`ParallelChart` diff --git a/Documentation/XChartsTutorial01-EN.md b/Documentation/XChartsTutorial01-EN.md index 216e3e89..e4013745 100644 --- a/Documentation/XChartsTutorial01-EN.md +++ b/Documentation/XChartsTutorial01-EN.md @@ -11,7 +11,7 @@ XCharts可通过以下任意一种方式导入到项目: - 直接将XCharts源码到项目 - 下载好XCharts源码后,直接将XCharts目录拷贝到Unity项目工程的Assets目录下。 + 下载好XCharts源码后,直接将XCharts目录拷贝到Unity项目工程的Assets目录或Packages目录下,编译通过后即可使用。 - 通过`Assets/Import Package`导入XCharts @@ -50,7 +50,7 @@ XCharts可通过以下任意一种方式导入到项目: ## 添加Serie组件 -Serie只自带了几个常见的组件,其他组件按需额外添加。比如,需要给折线图区域填充颜色,可单独给`Serie`添加`AreaStyle`组件: +Serie只自带了几个常见的组件,其他组件要根据需求额外添加,不同的Serie支持不同的额外组件。比如,需要给折线图区域填充颜色,可单独给`Serie`添加`AreaStyle`组件: ![op_addseriecomponent](res/op_addseriecomponent.png) ![linechart3](res/linechart3.png) @@ -80,7 +80,7 @@ Serie只自带了几个常见的组件,其他组件按需额外添加。比如 2. 如果`Serie`的`ItemStyle`配置有非`0000`颜色值,则优先用这个颜色值。 3. 否则颜色值取自主题`Theme`的`Color Palette`。 -通常颜色值为0000时表示用主题默认颜色,配置为0或null时表示用主题默认配置。 +通常配置的颜色值为0000时表示用主题默认颜色;配置参数的值为0或null时表示用主题默认配置。 ## 用代码添加折线图 @@ -94,6 +94,7 @@ if (chart == null) chart.Init(); } ``` +用代码生成的Chart需要调用一次Init()。 调整大小: @@ -170,7 +171,7 @@ for (int i = 0; i < 10; i++) XCharts内部有自动刷新机制,但也是在一定条件下。如果自己调用了内部组件的接口,碰到组件没有刷新,确实找不到原因的话,可以用以下两个接口强制刷新: -1. `chart.RefreshAllComponent()`:刷新图表组件,会重新初始化所有组件,不建议频繁待用。 +1. `chart.RefreshAllComponent()`:刷新图表组件,会重新初始化所有组件,不建议频繁使用。 2. `chart.RefreshChart()`:刷新图表绘制,只刷新绘制部分,不会刷新组件文本,位置等部分。 ## 使用TextMeshPro diff --git a/README.md b/README.md index 22371843..747b61ed 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ 更多教程请看:[XCharts教程:5分钟上手教程](Documentation/XChartsTutorial01-ZH.md) -首次使用,建议认真看一遍教程。 +首次使用,建议先认真看一遍教程。 ## FAQ @@ -125,11 +125,15 @@ 答:`XCharts`使用`MIT`协议,可以免费使用。也可以订阅`VIP`享受更多增值服务。 2. `XCharts`支持代码动态添加和修改数据吗?支持从`Excel`或数据库中获取数据吗? - 答:支持代码动态添加和修改数据,但数据需要自己解析或获取,再调用`XCharts`的接口添加到`XCharts`。 + 答:`XCharts`提供了各种数据操作的接口,支持代码动态添加和修改数据,但数据需要自己解析或获取,再调用`XCharts`的接口添加到`XCharts`。 3. 这个插件除了用在`Unity`,还能用在其他平台(如`Winform`或`WPF`)吗? 答:目前只支持在`Unity`平台使用。理论上任何支持`UGUI`的`Unity`版本都能运行`XCharts`。 +4. 锯齿怎么解决?支持多大量级的数据? + 答:`XCharts`是基于`UGUI`实现的,所以`UGUI`中碰到的问题,在`XCharts`中也会存在。比如锯齿问题,比如`Mesh`顶点数超`65535`的问题。这两个问题的解决可参考`问答16`和`问答27`。 + 由于`Mesh`的`65535`顶点数的限制,目前`XCharts`的单条`Line`大概支持`2万`左右的数据量,当然开采样可以支持更多数据,但可能会更消耗CPU。 + ## Licenses [MIT License](LICENSE.md) diff --git a/Runtime/Internal/XChartsMgr.cs b/Runtime/Internal/XChartsMgr.cs index d789c75b..ad454b56 100644 --- a/Runtime/Internal/XChartsMgr.cs +++ b/Runtime/Internal/XChartsMgr.cs @@ -21,7 +21,7 @@ class XChartsVersion public static class XChartsMgr { public static readonly string version = "3.3.0"; - public static readonly int versionDate = 20220915; + public static readonly int versionDate = 20220928; public static string fullVersion { get { return version + "-" + versionDate; } } internal static List chartList = new List(); diff --git a/package.json b/package.json index e8601711..6ad69cde 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "name": "com.monitor1394.xcharts", "displayName": "XCharts", "version": "3.3.0", - "date": "20220915", - "checkdate": "20220915", + "date": "20220928", + "checkdate": "20220928", "desc": "如果 XCharts 对您有帮助,希望您能在 Github 上点 Star 支持,非常感谢!", "unity": "2018.3", "description": "A charting and data visualization library for Unity.", From aec3e59aca185502983bc08752b3cf7f411b1835 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 26 Sep 2022 22:15:49 +0800 Subject: [PATCH 37/38] [improve][Axis] improve default split number --- CHANGELOG.md | 1 + Runtime/Component/Axis/AxisHelper.cs | 13 ++++--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fc892e5..a35c789a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,7 @@ ### 日志详情 +* (2022.09.26) 优化`Axis`在类目轴时的默认分割段数 * (2022.09.25) 修复`API`文档中部分接口没有导出的问题 * (2022.09.24) 优化`FunnelChart` * (2022.09.23) 优化`ParallelChart` diff --git a/Runtime/Component/Axis/AxisHelper.cs b/Runtime/Component/Axis/AxisHelper.cs index 249f5e92..86490bd2 100644 --- a/Runtime/Component/Axis/AxisHelper.cs +++ b/Runtime/Component/Axis/AxisHelper.cs @@ -64,15 +64,10 @@ public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZo if (axis.splitNumber <= 0) { - if (dataCount <= 10) return dataCount; - else - { - for (int i = 4; i < 6; i++) - { - if (dataCount % i == 0) return i; - } - return 5; - } + var eachWid = coordinateWid / dataCount; + if (eachWid > 40) return dataCount; + for (int i = 2; i < dataCount / 2; i++) + if (eachWid * i > 40) return dataCount / i; } else { From 75bf6e0e6cb930070862e423ce844d9a2e84fea3 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Wed, 28 Sep 2022 08:20:10 +0800 Subject: [PATCH 38/38] v3.3.0 --- CHANGELOG.md | 5 ++- Documentation/CHANGELOG.md | 49 +++++++++++++++++++++++++++ Runtime/Component/Axis/AxisHandler.cs | 4 --- Runtime/Component/Axis/AxisHelper.cs | 14 ++++---- Runtime/Serie/SeriesHelper.cs | 4 ++- 5 files changed, 62 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a35c789a..9885877d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,7 +65,10 @@ * 优化图表细节,支持更多功能 * 增加大量的Demo示例 -* 完善Editor下的操作,完善文档 +* 完善文档,修复若干问题 +* 新增PolarChart对Bar、Heatmap的支持 +* 新增HeatmapChart热力图类型 +* 完善Tooltip显示 ### 日志详情 diff --git a/Documentation/CHANGELOG.md b/Documentation/CHANGELOG.md index 8e94df40..e20f04a6 100644 --- a/Documentation/CHANGELOG.md +++ b/Documentation/CHANGELOG.md @@ -2,6 +2,7 @@ # 更新日志 [master](#master) +[v3.3.0](#v3.3.0) [v3.2.0](#v3.2.0) [v3.1.0](#v3.1.0) [v3.0.1](#v3.0.1) @@ -58,6 +59,54 @@ ## master +## v3.3.0 + +### Main points + +* Optimized chart details to support more functions +* Add lots of Demo examples +* Improved documentation and fixed several issues +* Added PolarChart support for Bar and Heatmap +* Added a HeatmapChart type +* Improved Tooltip display + +### Log details + +* (2022.09.26) Optimizes the default number of segments for `Axis` at the category Axis +* (2022.09.25) Fixed the problem that some interfaces in the `API` document were not exported +* (2022.09.24) optimize `FunnelChart` +* (2022.09.23) Optimizes `ParallelChart` +* (2022.09.22) Added `SaveAsImage()` interface to save charts to images +* (2022.09.21) Fixed an issue where the `InsertSerie()` interface did not refresh the graph +* (2022.09.21) Optimized `PolarChart` for `Line` thermal map support +* (2022.09.20) Added `PolarChart` support for `Heatmap` +* (2022.09.19) Added `PolarChart` support for multi-bar graphs and stacked bar graphs +* (2022.09.16) Added `PolarChart` support for `Bar` histogram +* (2022.09.14) Added support for `PolarCoord` to set ring polar coordinates via `Radius` +* (2022.09.09) Fixed an issue where some components of edit parameters in `Editor` might not refresh in real time +* (2022.09.08) Added support for `RingChart` settable `LabelLine` bootline +* (2022.09.06) Added support for `SerieSymbol` `minSize` and `maxSize` parameters to set maximum and minimum sizes +* (2022.09.06) Added support for `showStartLine` and `showEndLine` parameters for `AxisSplitLine` to set whether to display the first splitter +* (2022.09.06) Added `Heatmap` support for different patterns via `symbol` +* (2022.09.05) added `Heatmap` `heatmapType` support for setting `Data` and `Count` two different mapping methods of Heatmap +* (2022.09.05) Optimizes `Tooltip` when indicating numerical axis in thermograph +* (2022.09.02) Added `onPointerEnterPie` callback support +* (2022.09.02) Optimize the HeatmapChart ` +* (2022.08.30) optimizes` RadarChart ` +* (2022.08.30) Fixed `DataZoom` calculation range inaccuracies in some cases (#221) +* (2022.08.29) optimizes the default behavior of `BarChart` when data is too dense +* (2022.08.29) optimizes `YAxis` Max/min calculations when `DataZoom` is enabled +* (2022.08.29) optimized `CandlestickChart` massive data rendering +* (2022.08.28) fixed an issue where `LineChart` does not appear properly in the case of stacking and custom Y-axis range +* (2022.08.26) added `Legend` new icon type `Candlestick` +* (2022.08.26) optimizes` CandlestickChart `performance and adjusts related` AddData() `interface parameters +* (2022.08.26) Added support for setting different display positions in Tooltip's `position` parameter +* (2022.08.26) Delete the `fixedXEnable` and `fixedYEnable` arguments of Tooltip +* (2022.08.25) EmphasisStyle `EmphasisStyle` has emphasised the support for `label` +* (2022.08.25) Added support for `formatter` for `{d3}` specified percentage of dimension data +* (2022.08.24) fixed the `label` of the `ScatterChart` not refreshing +* (2022.08.24) fixed abnormal display of `label` of `MarkLine` in some cases + ## v3.2.0 ### Main points diff --git a/Runtime/Component/Axis/AxisHandler.cs b/Runtime/Component/Axis/AxisHandler.cs index 47fc3c5e..22863c28 100644 --- a/Runtime/Component/Axis/AxisHandler.cs +++ b/Runtime/Component/Axis/AxisHandler.cs @@ -368,10 +368,6 @@ protected void InitAxis(Axis relativedAxis, Orient orient, ((inside && axis.IsLeft()) || (!inside && axis.IsRight()) ? TextAnchor.MiddleLeft : TextAnchor.MiddleRight); - - if (axis.IsCategory() && axis.boundaryGap) - splitNumber -= 1; - for (int i = 0; i < splitNumber; i++) { var labelWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom); diff --git a/Runtime/Component/Axis/AxisHelper.cs b/Runtime/Component/Axis/AxisHelper.cs index 86490bd2..7171e826 100644 --- a/Runtime/Component/Axis/AxisHelper.cs +++ b/Runtime/Component/Axis/AxisHelper.cs @@ -65,9 +65,9 @@ public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZo if (axis.splitNumber <= 0) { var eachWid = coordinateWid / dataCount; - if (eachWid > 40) return dataCount; - for (int i = 2; i < dataCount / 2; i++) - if (eachWid * i > 40) return dataCount / i; + if (eachWid > 80) return dataCount; + var tick = Mathf.CeilToInt(80 / eachWid); + return (int) (dataCount / tick); } else { @@ -191,7 +191,8 @@ public static string GetLabelName(Axis axis, float coordinateWidth, int index, d } else { - if (axis.boundaryGap && coordinateWidth / dataCount > 5) + var diff = newIndex - dataCount; + if (axis.boundaryGap && ((diff > 0 && diff / rate < 0.4f) || dataCount >= axis.data.Count)) return string.Empty; else return axis.axisLabel.GetFormatterContent(dataCount - 1, showData[dataCount - 1]); @@ -223,10 +224,7 @@ public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom data } else { - if (dataCount < splitNum) scaleNum = splitNum; - else scaleNum = dataCount > 2 && dataCount % splitNum == 0 ? - splitNum : - splitNum + 1; + scaleNum = splitNum + 1; } return scaleNum; } diff --git a/Runtime/Serie/SeriesHelper.cs b/Runtime/Serie/SeriesHelper.cs index 4055b8f1..d3e9c244 100644 --- a/Runtime/Serie/SeriesHelper.cs +++ b/Runtime/Serie/SeriesHelper.cs @@ -359,9 +359,11 @@ public static void GetMinMaxValue(BaseChart chart, int axisIndex, bool isValueAx } else { + var performanceMode = serie.IsPerformanceMode(); foreach (var data in showData) { - var currData = data.GetCurrData(yValue ? 1 : 0, updateDuration, inverse); + var currData = performanceMode? data.GetData(yValue?1 : 0, inverse): + data.GetCurrData(yValue ? 1 : 0, updateDuration, inverse); if (!serie.IsIgnoreValue(currData)) { if (currData > max) max = currData;