From b040f27b2c06a9164f884b95a49d107145f8ee33 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Tue, 26 May 2026 08:46:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0`DataZoom`=E7=9A=84`filterAxi?= =?UTF-8?q?sRange`=E8=AE=BE=E7=BD=AE=E5=9D=90=E6=A0=87=E8=BD=B4=E7=9A=84?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E8=AE=A1=E7=AE=97=E6=98=AF=E5=90=A6=E5=8F=97?= =?UTF-8?q?`DataZoom`=E7=9A=84=E5=BD=B1=E5=93=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Documentation~/zh/changelog.md | 1 + Editor/MainComponents/DataZoomEditor.cs | 3 +- Runtime/Component/DataZoom/DataZoom.cs | 11 +++++ Runtime/Component/DataZoom/DataZoomHandler.cs | 9 ++-- Runtime/Internal/BaseChart.Custom.cs | 6 +-- Runtime/Serie/SerieHelper.cs | 8 ++-- Runtime/Serie/SeriesHelper.cs | 47 ++++++++++--------- 7 files changed, 50 insertions(+), 35 deletions(-) diff --git a/Documentation~/zh/changelog.md b/Documentation~/zh/changelog.md index e39b53ee..ff9bad75 100644 --- a/Documentation~/zh/changelog.md +++ b/Documentation~/zh/changelog.md @@ -81,6 +81,7 @@ slug: /changelog ## master +* (2026.05.23) 增加`DataZoom`的`filterAxisRange`设置坐标轴的范围计算是否受`DataZoom`的影响 * (2026.05.23) 优化`DataZoom`的`Marquee`框选功能 * (2026.05.23) 修复`DataZoom`内绘制的折线图可能会超出范围的问题 * (2026.05.23) 修复`Axis`的`inverse`没能正确反转的问题 diff --git a/Editor/MainComponents/DataZoomEditor.cs b/Editor/MainComponents/DataZoomEditor.cs index 5dad19bf..27aa06a5 100644 --- a/Editor/MainComponents/DataZoomEditor.cs +++ b/Editor/MainComponents/DataZoomEditor.cs @@ -28,10 +28,11 @@ namespace XCharts.Editor PropertyField("m_ScrollSensitivity"); PropertyField("m_RangeMode"); PropertyField(m_Start); - PropertyField(m_End); PropertyField("m_StartLock"); + PropertyField(m_End); PropertyField("m_EndLock"); PropertyField(m_MinZoomRatio); + PropertyField("m_FilterAxisRange"); if (m_Start.floatValue < 0) m_Start.floatValue = 0; if (m_End.floatValue > 100) m_End.floatValue = 100; if (m_MinZoomRatio.floatValue < 0) m_MinZoomRatio.floatValue = 0; diff --git a/Runtime/Component/DataZoom/DataZoom.cs b/Runtime/Component/DataZoom/DataZoom.cs index 1fa0b940..b2f1bb31 100644 --- a/Runtime/Component/DataZoom/DataZoom.cs +++ b/Runtime/Component/DataZoom/DataZoom.cs @@ -92,6 +92,7 @@ namespace XCharts.Runtime [SerializeField][Since("v3.5.0")] private MarqueeStyle m_MarqueeStyle = new MarqueeStyle(); [SerializeField][Since("v3.6.0")] private bool m_StartLock; [SerializeField][Since("v3.6.0")] private bool m_EndLock; + [SerializeField][Since("v3.12.0")] private bool m_FilterAxisRange = true; public DataZoomContext context = new DataZoomContext(); private CustomDataZoomStartEndFunction m_StartEndFunction; @@ -325,6 +326,16 @@ namespace XCharts.Runtime set { if (PropertyUtil.SetStruct(ref m_EndLock, value)) SetVerticesDirty(); } } /// + /// Whether dataZoom filters the axis min/max range. When true, the axis scale adapts to the current zoom window. + /// When false, the axis always shows the full data range regardless of the zoom position. + /// ||是否根据DataZoom的缩放窗口过滤坐标轴的最大最小值范围。为true时坐标轴范围随缩放窗口变化;为false时坐标轴始终显示全部数据范围。 + /// + public bool filterAxisRange + { + get { return m_FilterAxisRange; } + set { if (PropertyUtil.SetStruct(ref m_FilterAxisRange, value)) SetVerticesDirty(); } + } + /// /// The end percentage of the window out of the data extent, in the range of 0 ~ 100. /// ||数据窗口范围的结束百分比。范围是:0 ~ 100。 /// diff --git a/Runtime/Component/DataZoom/DataZoomHandler.cs b/Runtime/Component/DataZoom/DataZoomHandler.cs index 62f48474..d31eeb18 100644 --- a/Runtime/Component/DataZoom/DataZoomHandler.cs +++ b/Runtime/Component/DataZoom/DataZoomHandler.cs @@ -591,9 +591,9 @@ namespace XCharts.Runtime float scaleWid = showData.Count > 1 ? dataZoom.context.width / (showData.Count - 1) : dataZoom.context.width; Vector3 lp = Vector3.zero; Vector3 np = Vector3.zero; - double minValue; - double maxValue; - SeriesHelper.GetYMinMaxValue(chart, 0, axis.inverse, out minValue, out maxValue, false, false); + // shadow always shows the full data range, independent of DataZoom window + double minValue = SerieHelper.GetMinData(serie, 1, null, axis.inverse); + double maxValue = SerieHelper.GetMaxData(serie, 1, null, axis.inverse); minValue = ChartHelper.GetMinDivisibleValue(minValue, 0); maxValue = ChartHelper.GetMaxDivisibleValue(maxValue, 0); double xMinValue = 0; @@ -603,7 +603,8 @@ namespace XCharts.Runtime var xAxis = chart.GetChartComponent(xAxisIndex); if (xAxis != null && (xAxis.IsValue() || xAxis.IsTime())) { - SeriesHelper.GetXMinMaxValue(chart, xAxisIndex, xAxis.inverse, out xMinValue, out xMaxValue, false, false); + xMinValue = SerieHelper.GetMinData(serie, 0, null, xAxis.inverse); + xMaxValue = SerieHelper.GetMaxData(serie, 0, null, xAxis.inverse); AxisHelper.AdjustMinMaxValue(xAxis, ref xMinValue, ref xMaxValue, true); useXValueForShadow = (xMaxValue - xMinValue) > 0; } diff --git a/Runtime/Internal/BaseChart.Custom.cs b/Runtime/Internal/BaseChart.Custom.cs index c0a4b671..84c5b6cb 100644 --- a/Runtime/Internal/BaseChart.Custom.cs +++ b/Runtime/Internal/BaseChart.Custom.cs @@ -56,15 +56,15 @@ namespace XCharts.Runtime } if (isX) { - SeriesHelper.GetXMinMaxValue(this, axisIndex, axis.inverse, out tempMinValue, out tempMaxValue, false, false, needAnimationData); + SeriesHelper.GetXMinMaxValue(this, axisIndex, axis.inverse, out tempMinValue, out tempMaxValue, false, needAnimationData); } else if (isY) { - SeriesHelper.GetYMinMaxValue(this, axisIndex, axis.inverse, out tempMinValue, out tempMaxValue, false, false, needAnimationData); + SeriesHelper.GetYMinMaxValue(this, axisIndex, axis.inverse, out tempMinValue, out tempMaxValue, false, needAnimationData); } else if(isZ) { - SeriesHelper.GetZMinMaxValue(this, axisIndex, axis.inverse, out tempMinValue, out tempMaxValue, false, false, needAnimationData); + SeriesHelper.GetZMinMaxValue(this, axisIndex, axis.inverse, out tempMinValue, out tempMaxValue, false, needAnimationData); } AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); } diff --git a/Runtime/Serie/SerieHelper.cs b/Runtime/Serie/SerieHelper.cs index 1ace341b..b19a781d 100644 --- a/Runtime/Serie/SerieHelper.cs +++ b/Runtime/Serie/SerieHelper.cs @@ -7,7 +7,7 @@ namespace XCharts.Runtime { public static partial class SerieHelper { - public static double GetMinData(Serie serie, int dimension = 1, DataZoom dataZoom = null) + public static double GetMinData(Serie serie, int dimension = 1, DataZoom dataZoom = null, bool inverse = false) { double min = double.MaxValue; var dataList = serie.GetDataList(dataZoom); @@ -16,7 +16,7 @@ namespace XCharts.Runtime var serieData = dataList[i]; if (serieData.show && serieData.data.Count > dimension) { - var value = serieData.data[dimension]; + var value = serieData.GetData(dimension, inverse); if (value < min && !serie.IsIgnoreValue(serieData, value)) min = value; } } @@ -42,7 +42,7 @@ namespace XCharts.Runtime } return minData; } - public static double GetMaxData(Serie serie, int dimension = 1, DataZoom dataZoom = null) + public static double GetMaxData(Serie serie, int dimension = 1, DataZoom dataZoom = null, bool inverse = false) { double max = double.MinValue; var dataList = serie.GetDataList(dataZoom); @@ -51,7 +51,7 @@ namespace XCharts.Runtime var serieData = dataList[i]; if (serieData.show && serieData.data.Count > dimension) { - var value = serieData.data[dimension]; + var value = serieData.GetData(dimension, inverse); if (value > max && !serie.IsIgnoreValue(serieData, value)) max = value; } } diff --git a/Runtime/Serie/SeriesHelper.cs b/Runtime/Serie/SeriesHelper.cs index 1797592f..22a628f1 100644 --- a/Runtime/Serie/SeriesHelper.cs +++ b/Runtime/Serie/SeriesHelper.cs @@ -324,9 +324,9 @@ namespace XCharts.Runtime /// /// public static void GetXMinMaxValue(BaseChart chart, int axisIndex, bool inverse, out double minValue, - out double maxValue, bool isPolar = false, bool filterByDataZoom = true, bool needAnimation = false) + out double maxValue, bool isPolar = false, bool needAnimation = false) { - GetMinMaxValue(chart, axisIndex, inverse, 0, out minValue, out maxValue, isPolar, filterByDataZoom, needAnimation); + GetMinMaxValue(chart, axisIndex, inverse, 0, out minValue, out maxValue, isPolar, needAnimation); } /// @@ -337,9 +337,9 @@ namespace XCharts.Runtime /// /// public static void GetYMinMaxValue(BaseChart chart, int axisIndex, bool inverse, out double minValue, - out double maxValue, bool isPolar = false, bool filterByDataZoom = true, bool needAnimation = false) + out double maxValue, bool isPolar = false, bool needAnimation = false) { - GetMinMaxValue(chart, axisIndex, inverse, 1, out minValue, out maxValue, isPolar, filterByDataZoom, needAnimation); + GetMinMaxValue(chart, axisIndex, inverse, 1, out minValue, out maxValue, isPolar, needAnimation); } /// @@ -350,16 +350,16 @@ namespace XCharts.Runtime /// /// public static void GetZMinMaxValue(BaseChart chart, int axisIndex, bool inverse, out double minValue, - out double maxValue, bool isPolar = false, bool filterByDataZoom = true, bool needAnimation = false) + out double maxValue, bool isPolar = false, bool needAnimation = false) { - GetMinMaxValue(chart, axisIndex, inverse, 2, out minValue, out maxValue, isPolar, filterByDataZoom, needAnimation); + GetMinMaxValue(chart, axisIndex, inverse, 2, out minValue, out maxValue, isPolar, needAnimation); } private static Dictionary> _stackSeriesForMinMax = new Dictionary>(); private static Dictionary _serieTotalValueForMinMax = new Dictionary(); public static void GetMinMaxValue(BaseChart chart, int axisIndex, bool inverse, int dimension, out double minValue, out double maxValue, bool isPolar = false, - bool filterByDataZoom = true, bool needAnimation = false) + bool needAnimation = false) { double min = double.MaxValue; double max = double.MinValue; @@ -377,8 +377,12 @@ namespace XCharts.Runtime var dataAddDuration = needAnimation ? serie.animation.GetAdditionDuration() : 0; var unscaledTime = serie.animation.unscaledTime; + // determine whether DataZoom filtering applies for this serie + var dz = chart.GetXDataZoomOfSerie(serie); + bool useDataZoomFilter = dz != null && dz.enable && dz.filterAxisRange; + // try per-serie cache when not filtering by dataZoom and not in animation mode - if (!filterByDataZoom && !needAnimation) + if (!useDataZoomFilter && !needAnimation) { double cmin, cmax; if (serie.context.TryGetCachedMinMax(dimension, out cmin, out cmax)) @@ -391,7 +395,6 @@ namespace XCharts.Runtime double smin = double.MaxValue; double smax = double.MinValue; - DataZoom dz = null; if (isPercentStack && SeriesHelper.IsPercentStack(series, serie.serieName)) { @@ -401,21 +404,17 @@ namespace XCharts.Runtime } else { - if (filterByDataZoom) + if (useDataZoomFilter) { - dz = chart.GetXDataZoomOfSerie(serie); - if (dz != null && dz.enable) + var key = string.Format("dz:{0:F3}:{1:F3}:{2}", dz.start, dz.end, dz.filterMode); + double cmin, cmax; + if (serie.context.TryGetDataZoomCachedMinMax(key, dimension, out cmin, out cmax)) { - var key = string.Format("dz:{0:F3}:{1:F3}:{2}", dz.start, dz.end, dz.filterMode); - double cmin, cmax; - if (serie.context.TryGetDataZoomCachedMinMax(key, dimension, out cmin, out cmax)) - { - smin = cmin; - smax = cmax; - } + smin = cmin; + smax = cmax; } } - var showData = serie.GetDataList(dz != null && dz.enable ? dz : (filterByDataZoom ? chart.GetXDataZoomOfSerie(serie) : null)); + var showData = serie.GetDataList(useDataZoomFilter ? dz : null); if (dimension > 0 && (serie is Candlestick || serie is SimplifiedCandlestick)) { foreach (var data in showData) @@ -449,12 +448,12 @@ namespace XCharts.Runtime // cache per-serie result for future calls if (!needAnimation) { - if (filterByDataZoom && dz != null && dz.enable) + if (useDataZoomFilter) { var key = string.Format("dz:{0:F3}:{1:F3}:{2}", dz.start, dz.end, dz.filterMode); serie.context.SetDataZoomCachedMinMax(key, dimension, smin == double.MaxValue ? 0 : smin, smax == double.MinValue ? 0 : smax); } - else if (!filterByDataZoom) + else { serie.context.SetCachedMinMax(dimension, smin == double.MaxValue ? 0 : smin, smax == double.MinValue ? 0 : smax); } @@ -476,7 +475,9 @@ namespace XCharts.Runtime if ((isPolar && serie.polarIndex != axisIndex) || (!isPolar && serie.yAxisIndex != axisIndex) || !serie.show) continue; - var showData = serie.GetDataList(filterByDataZoom ? chart.GetXDataZoomOfSerie(serie) : null); + var stackDz = chart.GetXDataZoomOfSerie(serie); + if (stackDz != null && (!stackDz.filterAxisRange || !stackDz.enable)) stackDz = null; + var showData = serie.GetDataList(stackDz); if (SeriesHelper.IsPercentStack(series, serie.stack)) { for (int j = 0; j < showData.Count; j++)