diff --git a/Documentation~/zh/changelog.md b/Documentation~/zh/changelog.md index c8d5f5cc..bea460d3 100644 --- a/Documentation~/zh/changelog.md +++ b/Documentation~/zh/changelog.md @@ -80,6 +80,7 @@ slug: /changelog ## master +* (2026.01.08) 增加`DataZoom`的`minZoomRatio`替换旧的`minShowNum` (#350) * (2025.11.05) 修复`Axis`的`indicatorLabel`无法隐藏的问题 * (2025.11.03) 增加`Tooltip`的`Title`可通过`TitleLabelStyle`的`numericFormatter`格式化时间显示 (#353) * (2025.10.30) 增加`Chart`的`useUtc`参数设置显示时间是否用UTC时间 diff --git a/Editor/MainComponents/DataZoomEditor.cs b/Editor/MainComponents/DataZoomEditor.cs index 10f0fdba..5dad19bf 100644 --- a/Editor/MainComponents/DataZoomEditor.cs +++ b/Editor/MainComponents/DataZoomEditor.cs @@ -13,7 +13,7 @@ namespace XCharts.Editor var m_SupportMarquee = baseProperty.FindPropertyRelative("m_SupportMarquee"); var m_Start = baseProperty.FindPropertyRelative("m_Start"); var m_End = baseProperty.FindPropertyRelative("m_End"); - var m_MinShowNum = baseProperty.FindPropertyRelative("m_MinShowNum"); + var m_MinZoomRatio = baseProperty.FindPropertyRelative("m_MinZoomRatio"); ++EditorGUI.indentLevel; PropertyField("m_Orient"); PropertyField("m_SupportInside"); @@ -31,10 +31,11 @@ namespace XCharts.Editor PropertyField(m_End); PropertyField("m_StartLock"); PropertyField("m_EndLock"); - PropertyField(m_MinShowNum); + PropertyField(m_MinZoomRatio); if (m_Start.floatValue < 0) m_Start.floatValue = 0; if (m_End.floatValue > 100) m_End.floatValue = 100; - if (m_MinShowNum.intValue < 0) m_MinShowNum.intValue = 0; + if (m_MinZoomRatio.floatValue < 0) m_MinZoomRatio.floatValue = 0; + if (m_MinZoomRatio.floatValue > 1) m_MinZoomRatio.floatValue = 1; if (m_SupportSlider.boolValue) { PropertyField("m_ShowDataShadow"); diff --git a/Runtime/Component/Axis/AxisContext.cs b/Runtime/Component/Axis/AxisContext.cs index 11e4e36f..89df8e66 100644 --- a/Runtime/Component/Axis/AxisContext.cs +++ b/Runtime/Component/Axis/AxisContext.cs @@ -120,24 +120,25 @@ namespace XCharts.Runtime if (end > data.Count) end = data.Count; } + var minZoomRatio = (int)(data.Count * dataZoom.minZoomRatio); if (start != filterStart || end != filterEnd || - dataZoom.minShowNum != filterMinShow || + minZoomRatio != filterMinShow || isNeedUpdateFilterData) { filterStart = start; filterEnd = end; - filterMinShow = dataZoom.minShowNum; + filterMinShow = minZoomRatio; isNeedUpdateFilterData = false; if (data.Count > 0) { - if (range < dataZoom.minShowNum) + if (range < minZoomRatio) { - if (dataZoom.minShowNum > data.Count) + if (dataZoom.minZoomRatio > data.Count) range = data.Count; else - range = dataZoom.minShowNum; + range = minZoomRatio; } if (range > data.Count - start) start = data.Count - range; diff --git a/Runtime/Component/DataZoom/DataZoom.cs b/Runtime/Component/DataZoom/DataZoom.cs index fd2f60fe..26edaa43 100644 --- a/Runtime/Component/DataZoom/DataZoom.cs +++ b/Runtime/Component/DataZoom/DataZoom.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using UnityEngine; @@ -81,7 +82,7 @@ namespace XCharts.Runtime [SerializeField] private RangeMode m_RangeMode; [SerializeField] private float m_Start; [SerializeField] private float m_End; - [SerializeField] private int m_MinShowNum = 2; + [SerializeField] private float m_MinZoomRatio = 0.2f; [Range(1f, 20f)] [SerializeField] private float m_ScrollSensitivity = 1.1f; [SerializeField] private Orient m_Orient = Orient.Horizonal; @@ -336,10 +337,19 @@ namespace XCharts.Runtime /// Minimum number of display data. Minimum number of data displayed when DataZoom is enlarged to maximum. /// ||最小显示数据个数。当DataZoom放大到最大时,最小显示的数据个数。 /// - public int minShowNum + [Obsolete("Use \"minZoomRatio\" instead", true)] + public float minShowNum { - get { return m_MinShowNum; } - set { if (PropertyUtil.SetStruct(ref m_MinShowNum, value)) SetVerticesDirty(); } + set;get; + } + /// + /// The minimum zoom ratio of dataZoom. Range 0f-1f. + /// ||缩放区域组件的最小缩放比例,范围0f-1f。 + /// + public float minZoomRatio + { + get { return m_MinZoomRatio; } + set { if (PropertyUtil.SetStruct(ref m_MinZoomRatio, value)) SetVerticesDirty(); } } /// /// The sensitivity of dataZoom scroll. diff --git a/Runtime/Component/DataZoom/DataZoomHandler.cs b/Runtime/Component/DataZoom/DataZoomHandler.cs index 14b78906..ec621a58 100644 --- a/Runtime/Component/DataZoom/DataZoomHandler.cs +++ b/Runtime/Component/DataZoom/DataZoomHandler.cs @@ -215,7 +215,7 @@ namespace XCharts.Runtime var grid = chart.GetGridOfDataZoom(dataZoom); var start = (dataZoom.context.marqueeRect.x - grid.context.x) / grid.context.width * 100; var end = (dataZoom.context.marqueeRect.x - grid.context.x + dataZoom.context.marqueeRect.width) / grid.context.width * 100; - UpdateDataZoomRange(dataZoom, start, end); + UpdateDataZoomRange(dataZoom, start, end, grid); } if (dataZoom.marqueeStyle.onEnd != null) { @@ -271,7 +271,7 @@ namespace XCharts.Runtime } var start = (startX - grid.context.x) / grid.context.width * 100; var end = (endX - grid.context.x) / grid.context.width * 100; - UpdateDataZoomRange(dataZoom, start, end); + UpdateDataZoomRange(dataZoom, start, end, grid); } } @@ -294,7 +294,7 @@ namespace XCharts.Runtime if ((dataZoom.supportInside && dataZoom.supportInsideScroll && grid.Contains(pos)) || dataZoom.IsInZoom(pos)) { - ScaleDataZoom(dataZoom, eventData.scrollDelta.y * dataZoom.scrollSensitivity); + ScaleDataZoom(dataZoom, eventData.scrollDelta.y * dataZoom.scrollSensitivity, grid); } } @@ -375,25 +375,27 @@ namespace XCharts.Runtime } } - private void ScaleDataZoom(DataZoom dataZoom, float delta) + private void ScaleDataZoom(DataZoom dataZoom, float delta, GridCoord grid = null) { - var grid = chart.GetGridOfDataZoom(dataZoom); - var deltaPercent = dataZoom.orient == Orient.Horizonal ? - Mathf.Abs(delta / grid.context.width * 100) : - Mathf.Abs(delta / grid.context.height * 100); + if (grid == null) grid = chart.GetGridOfDataZoom(dataZoom); + var range = dataZoom.orient == Orient.Horizonal ? grid.context.width : grid.context.height; + var deltaPercent = Mathf.Abs(delta / range * 100); + float start, end; if (delta > 0) { - if (dataZoom.end <= dataZoom.start) - return; - UpdateDataZoomRange(dataZoom, dataZoom.start + deltaPercent, dataZoom.end - deltaPercent); + if (dataZoom.end <= dataZoom.start) return; + start = dataZoom.start + deltaPercent; + end = dataZoom.end - deltaPercent; } else { - UpdateDataZoomRange(dataZoom, dataZoom.start - deltaPercent, dataZoom.end + deltaPercent); + start = dataZoom.start - deltaPercent; + end = dataZoom.end + deltaPercent; } + UpdateDataZoomRange(dataZoom, start, end, grid); } - public void UpdateDataZoomRange(DataZoom dataZoom, float start, float end) + public void UpdateDataZoomRange(DataZoom dataZoom, float start, float end, GridCoord grid = null) { if (end > 100) end = 100; @@ -403,13 +405,26 @@ namespace XCharts.Runtime if (end < start) end = start; - if (dataZoom.startEndFunction != null) - dataZoom.startEndFunction(ref start, ref end); + + if(dataZoom.minZoomRatio > 0) + { + if(grid == null) grid = chart.GetGridOfDataZoom(dataZoom); + var range = dataZoom.orient == Orient.Horizonal ? grid.context.width : grid.context.height; + var minRange = dataZoom.minZoomRatio * range; + if (end - start < minRange / range * 100) + { + return; + } + } if (!dataZoom.startLock) dataZoom.start = start; if (!dataZoom.endLock) dataZoom.end = end; + + if (dataZoom.startEndFunction != null) + dataZoom.startEndFunction(ref start, ref end); + m_LastStart = dataZoom.start; m_LastEnd = dataZoom.end; if (dataZoom.realtime) @@ -444,7 +459,7 @@ namespace XCharts.Runtime var tempPos1 = touch1.position; var currDist = Vector2.Distance(tempPos0, tempPos1); var lastDist = Vector2.Distance(m_LastTouchPos0, m_LastTouchPos1); - var delta = (currDist - lastDist); + var delta = currDist - lastDist; ScaleDataZoom(dataZoom, delta / dataZoom.scrollSensitivity); m_LastTouchPos0 = tempPos0; m_LastTouchPos1 = tempPos1; @@ -492,7 +507,6 @@ namespace XCharts.Runtime } else if (xAxis.IsTime()) { - //TODO: dataZoom.SetStartLabelText(""); dataZoom.SetEndLabelText(""); } diff --git a/Runtime/Serie/SerieHelper.cs b/Runtime/Serie/SerieHelper.cs index eb560218..1ace341b 100644 --- a/Runtime/Serie/SerieHelper.cs +++ b/Runtime/Serie/SerieHelper.cs @@ -833,13 +833,14 @@ namespace XCharts.Runtime var data = serie.data; var startValue = min; var endValue = max; + var minZoomRatio = (int)((max-min) * dataZoom.minZoomRatio); if (endValue < startValue) endValue = startValue; if (startValue != serie.m_FilterStartValue || endValue != serie.m_FilterEndValue || - dataZoom.minShowNum != serie.m_FilterMinShow || serie.m_NeedUpdateFilterData) + dataZoom.minZoomRatio != serie.m_FilterMinShow || serie.m_NeedUpdateFilterData) { serie.m_FilterStartValue = startValue; serie.m_FilterEndValue = endValue; - serie.m_FilterMinShow = dataZoom.minShowNum; + serie.m_FilterMinShow = minZoomRatio; serie.m_NeedUpdateFilterData = false; if (ReferenceEquals(serie.m_FilterData, data)) @@ -883,19 +884,20 @@ namespace XCharts.Runtime end = start + range; if (end > data.Count) end = data.Count; } + var minZoomRatio = (int)(data.Count * dataZoom.minZoomRatio); if (start != serie.m_FilterStart || end != serie.m_FilterEnd || - dataZoom.minShowNum != serie.m_FilterMinShow || serie.m_NeedUpdateFilterData) + minZoomRatio != serie.m_FilterMinShow || serie.m_NeedUpdateFilterData) { serie.m_FilterStart = start; serie.m_FilterEnd = end; - serie.m_FilterMinShow = dataZoom.minShowNum; + serie.m_FilterMinShow = minZoomRatio; serie.m_NeedUpdateFilterData = false; if (data.Count > 0) { - if (range < dataZoom.minShowNum) + if (range < minZoomRatio) { - if (dataZoom.minShowNum > data.Count) range = data.Count; - else range = dataZoom.minShowNum; + if (minZoomRatio > data.Count) range = data.Count; + else range = minZoomRatio; } if (range > data.Count - start) start = data.Count - range;