mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-28 12:08:46 +00:00
增加DataZoom的filterAxisRange设置坐标轴的范围计算是否受DataZoom的影响
This commit is contained in:
@@ -81,6 +81,7 @@ slug: /changelog
|
|||||||
|
|
||||||
## master
|
## master
|
||||||
|
|
||||||
|
* (2026.05.23) 增加`DataZoom`的`filterAxisRange`设置坐标轴的范围计算是否受`DataZoom`的影响
|
||||||
* (2026.05.23) 优化`DataZoom`的`Marquee`框选功能
|
* (2026.05.23) 优化`DataZoom`的`Marquee`框选功能
|
||||||
* (2026.05.23) 修复`DataZoom`内绘制的折线图可能会超出范围的问题
|
* (2026.05.23) 修复`DataZoom`内绘制的折线图可能会超出范围的问题
|
||||||
* (2026.05.23) 修复`Axis`的`inverse`没能正确反转的问题
|
* (2026.05.23) 修复`Axis`的`inverse`没能正确反转的问题
|
||||||
|
|||||||
@@ -28,10 +28,11 @@ namespace XCharts.Editor
|
|||||||
PropertyField("m_ScrollSensitivity");
|
PropertyField("m_ScrollSensitivity");
|
||||||
PropertyField("m_RangeMode");
|
PropertyField("m_RangeMode");
|
||||||
PropertyField(m_Start);
|
PropertyField(m_Start);
|
||||||
PropertyField(m_End);
|
|
||||||
PropertyField("m_StartLock");
|
PropertyField("m_StartLock");
|
||||||
|
PropertyField(m_End);
|
||||||
PropertyField("m_EndLock");
|
PropertyField("m_EndLock");
|
||||||
PropertyField(m_MinZoomRatio);
|
PropertyField(m_MinZoomRatio);
|
||||||
|
PropertyField("m_FilterAxisRange");
|
||||||
if (m_Start.floatValue < 0) m_Start.floatValue = 0;
|
if (m_Start.floatValue < 0) m_Start.floatValue = 0;
|
||||||
if (m_End.floatValue > 100) m_End.floatValue = 100;
|
if (m_End.floatValue > 100) m_End.floatValue = 100;
|
||||||
if (m_MinZoomRatio.floatValue < 0) m_MinZoomRatio.floatValue = 0;
|
if (m_MinZoomRatio.floatValue < 0) m_MinZoomRatio.floatValue = 0;
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ namespace XCharts.Runtime
|
|||||||
[SerializeField][Since("v3.5.0")] private MarqueeStyle m_MarqueeStyle = new MarqueeStyle();
|
[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_StartLock;
|
||||||
[SerializeField][Since("v3.6.0")] private bool m_EndLock;
|
[SerializeField][Since("v3.6.0")] private bool m_EndLock;
|
||||||
|
[SerializeField][Since("v3.12.0")] private bool m_FilterAxisRange = true;
|
||||||
|
|
||||||
public DataZoomContext context = new DataZoomContext();
|
public DataZoomContext context = new DataZoomContext();
|
||||||
private CustomDataZoomStartEndFunction m_StartEndFunction;
|
private CustomDataZoomStartEndFunction m_StartEndFunction;
|
||||||
@@ -325,6 +326,16 @@ namespace XCharts.Runtime
|
|||||||
set { if (PropertyUtil.SetStruct(ref m_EndLock, value)) SetVerticesDirty(); }
|
set { if (PropertyUtil.SetStruct(ref m_EndLock, value)) SetVerticesDirty(); }
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 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时坐标轴始终显示全部数据范围。
|
||||||
|
/// </summary>
|
||||||
|
public bool filterAxisRange
|
||||||
|
{
|
||||||
|
get { return m_FilterAxisRange; }
|
||||||
|
set { if (PropertyUtil.SetStruct(ref m_FilterAxisRange, value)) SetVerticesDirty(); }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
/// The end percentage of the window out of the data extent, in the range of 0 ~ 100.
|
/// The end percentage of the window out of the data extent, in the range of 0 ~ 100.
|
||||||
/// ||数据窗口范围的结束百分比。范围是:0 ~ 100。
|
/// ||数据窗口范围的结束百分比。范围是:0 ~ 100。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -591,9 +591,9 @@ namespace XCharts.Runtime
|
|||||||
float scaleWid = showData.Count > 1 ? dataZoom.context.width / (showData.Count - 1) : dataZoom.context.width;
|
float scaleWid = showData.Count > 1 ? dataZoom.context.width / (showData.Count - 1) : dataZoom.context.width;
|
||||||
Vector3 lp = Vector3.zero;
|
Vector3 lp = Vector3.zero;
|
||||||
Vector3 np = Vector3.zero;
|
Vector3 np = Vector3.zero;
|
||||||
double minValue;
|
// shadow always shows the full data range, independent of DataZoom window
|
||||||
double maxValue;
|
double minValue = SerieHelper.GetMinData(serie, 1, null, axis.inverse);
|
||||||
SeriesHelper.GetYMinMaxValue(chart, 0, axis.inverse, out minValue, out maxValue, false, false);
|
double maxValue = SerieHelper.GetMaxData(serie, 1, null, axis.inverse);
|
||||||
minValue = ChartHelper.GetMinDivisibleValue(minValue, 0);
|
minValue = ChartHelper.GetMinDivisibleValue(minValue, 0);
|
||||||
maxValue = ChartHelper.GetMaxDivisibleValue(maxValue, 0);
|
maxValue = ChartHelper.GetMaxDivisibleValue(maxValue, 0);
|
||||||
double xMinValue = 0;
|
double xMinValue = 0;
|
||||||
@@ -603,7 +603,8 @@ namespace XCharts.Runtime
|
|||||||
var xAxis = chart.GetChartComponent<XAxis>(xAxisIndex);
|
var xAxis = chart.GetChartComponent<XAxis>(xAxisIndex);
|
||||||
if (xAxis != null && (xAxis.IsValue() || xAxis.IsTime()))
|
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);
|
AxisHelper.AdjustMinMaxValue(xAxis, ref xMinValue, ref xMaxValue, true);
|
||||||
useXValueForShadow = (xMaxValue - xMinValue) > 0;
|
useXValueForShadow = (xMaxValue - xMinValue) > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,15 +56,15 @@ namespace XCharts.Runtime
|
|||||||
}
|
}
|
||||||
if (isX)
|
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)
|
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)
|
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);
|
AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace XCharts.Runtime
|
|||||||
{
|
{
|
||||||
public static partial class SerieHelper
|
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;
|
double min = double.MaxValue;
|
||||||
var dataList = serie.GetDataList(dataZoom);
|
var dataList = serie.GetDataList(dataZoom);
|
||||||
@@ -16,7 +16,7 @@ namespace XCharts.Runtime
|
|||||||
var serieData = dataList[i];
|
var serieData = dataList[i];
|
||||||
if (serieData.show && serieData.data.Count > dimension)
|
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;
|
if (value < min && !serie.IsIgnoreValue(serieData, value)) min = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ namespace XCharts.Runtime
|
|||||||
}
|
}
|
||||||
return minData;
|
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;
|
double max = double.MinValue;
|
||||||
var dataList = serie.GetDataList(dataZoom);
|
var dataList = serie.GetDataList(dataZoom);
|
||||||
@@ -51,7 +51,7 @@ namespace XCharts.Runtime
|
|||||||
var serieData = dataList[i];
|
var serieData = dataList[i];
|
||||||
if (serieData.show && serieData.data.Count > dimension)
|
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;
|
if (value > max && !serie.IsIgnoreValue(serieData, value)) max = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -324,9 +324,9 @@ namespace XCharts.Runtime
|
|||||||
/// <param name="minValue"></param>
|
/// <param name="minValue"></param>
|
||||||
/// <param name="maxValue"></param>
|
/// <param name="maxValue"></param>
|
||||||
public static void GetXMinMaxValue(BaseChart chart, int axisIndex, bool inverse, out double minValue,
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -337,9 +337,9 @@ namespace XCharts.Runtime
|
|||||||
/// <param name="minValue"></param>
|
/// <param name="minValue"></param>
|
||||||
/// <param name="maxValue"></param>
|
/// <param name="maxValue"></param>
|
||||||
public static void GetYMinMaxValue(BaseChart chart, int axisIndex, bool inverse, out double minValue,
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -350,16 +350,16 @@ namespace XCharts.Runtime
|
|||||||
/// <param name="minValue"></param>
|
/// <param name="minValue"></param>
|
||||||
/// <param name="maxValue"></param>
|
/// <param name="maxValue"></param>
|
||||||
public static void GetZMinMaxValue(BaseChart chart, int axisIndex, bool inverse, out double minValue,
|
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<int, List<Serie>> _stackSeriesForMinMax = new Dictionary<int, List<Serie>>();
|
private static Dictionary<int, List<Serie>> _stackSeriesForMinMax = new Dictionary<int, List<Serie>>();
|
||||||
private static Dictionary<int, double> _serieTotalValueForMinMax = new Dictionary<int, double>();
|
private static Dictionary<int, double> _serieTotalValueForMinMax = new Dictionary<int, double>();
|
||||||
public static void GetMinMaxValue(BaseChart chart, int axisIndex,
|
public static void GetMinMaxValue(BaseChart chart, int axisIndex,
|
||||||
bool inverse, int dimension, out double minValue, out double maxValue, bool isPolar = false,
|
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 min = double.MaxValue;
|
||||||
double max = double.MinValue;
|
double max = double.MinValue;
|
||||||
@@ -377,8 +377,12 @@ namespace XCharts.Runtime
|
|||||||
var dataAddDuration = needAnimation ? serie.animation.GetAdditionDuration() : 0;
|
var dataAddDuration = needAnimation ? serie.animation.GetAdditionDuration() : 0;
|
||||||
var unscaledTime = serie.animation.unscaledTime;
|
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
|
// try per-serie cache when not filtering by dataZoom and not in animation mode
|
||||||
if (!filterByDataZoom && !needAnimation)
|
if (!useDataZoomFilter && !needAnimation)
|
||||||
{
|
{
|
||||||
double cmin, cmax;
|
double cmin, cmax;
|
||||||
if (serie.context.TryGetCachedMinMax(dimension, out cmin, out cmax))
|
if (serie.context.TryGetCachedMinMax(dimension, out cmin, out cmax))
|
||||||
@@ -391,7 +395,6 @@ namespace XCharts.Runtime
|
|||||||
|
|
||||||
double smin = double.MaxValue;
|
double smin = double.MaxValue;
|
||||||
double smax = double.MinValue;
|
double smax = double.MinValue;
|
||||||
DataZoom dz = null;
|
|
||||||
|
|
||||||
if (isPercentStack && SeriesHelper.IsPercentStack<Bar>(series, serie.serieName))
|
if (isPercentStack && SeriesHelper.IsPercentStack<Bar>(series, serie.serieName))
|
||||||
{
|
{
|
||||||
@@ -401,21 +404,17 @@ namespace XCharts.Runtime
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (filterByDataZoom)
|
if (useDataZoomFilter)
|
||||||
{
|
{
|
||||||
dz = chart.GetXDataZoomOfSerie(serie);
|
var key = string.Format("dz:{0:F3}:{1:F3}:{2}", dz.start, dz.end, dz.filterMode);
|
||||||
if (dz != null && dz.enable)
|
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);
|
smin = cmin;
|
||||||
double cmin, cmax;
|
smax = cmax;
|
||||||
if (serie.context.TryGetDataZoomCachedMinMax(key, dimension, out cmin, out 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))
|
if (dimension > 0 && (serie is Candlestick || serie is SimplifiedCandlestick))
|
||||||
{
|
{
|
||||||
foreach (var data in showData)
|
foreach (var data in showData)
|
||||||
@@ -449,12 +448,12 @@ namespace XCharts.Runtime
|
|||||||
// cache per-serie result for future calls
|
// cache per-serie result for future calls
|
||||||
if (!needAnimation)
|
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);
|
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);
|
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);
|
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) ||
|
if ((isPolar && serie.polarIndex != axisIndex) ||
|
||||||
(!isPolar && serie.yAxisIndex != axisIndex) ||
|
(!isPolar && serie.yAxisIndex != axisIndex) ||
|
||||||
!serie.show) continue;
|
!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<Bar>(series, serie.stack))
|
if (SeriesHelper.IsPercentStack<Bar>(series, serie.stack))
|
||||||
{
|
{
|
||||||
for (int j = 0; j < showData.Count; j++)
|
for (int j = 0; j < showData.Count; j++)
|
||||||
|
|||||||
Reference in New Issue
Block a user