diff --git a/Documentation~/zh/changelog.md b/Documentation~/zh/changelog.md index 9eafac57..e01c7ea0 100644 --- a/Documentation~/zh/changelog.md +++ b/Documentation~/zh/changelog.md @@ -81,6 +81,7 @@ slug: /changelog ## master +* (2026.05.22) 增加`LabelStyle`的`minGap`可避免`label`过于密集 * (2026.05.17) 修复`DataZoom`点击时指示区域不准的问题 * (2026.05.17) 增加`Legend`的`Width`和`Height`可设置固定宽高 * (2026.05.17) 修复`Serie`的`EndLabel`在`Y`轴是`MinMax`类型时显示的数值不对的问题 diff --git a/Editor/ChildComponents/LabelStyleDrawer.cs b/Editor/ChildComponents/LabelStyleDrawer.cs index a6b760f3..1a6db5e6 100644 --- a/Editor/ChildComponents/LabelStyleDrawer.cs +++ b/Editor/ChildComponents/LabelStyleDrawer.cs @@ -26,6 +26,7 @@ namespace XCharts.Editor PropertyField(prop, "m_Height"); PropertyField(prop, "m_FixedX"); PropertyField(prop, "m_FixedY"); + PropertyField(prop, "m_MinGap"); PropertyField(prop, "m_Icon"); PropertyField(prop, "m_Background"); PropertyField(prop, "m_TextStyle"); diff --git a/Runtime/Component/Label/LabelStyle.cs b/Runtime/Component/Label/LabelStyle.cs index 563ad1ac..243aafa3 100644 --- a/Runtime/Component/Label/LabelStyle.cs +++ b/Runtime/Component/Label/LabelStyle.cs @@ -82,6 +82,7 @@ namespace XCharts.Runtime [SerializeField] protected float m_Height = 0; [SerializeField][Since("v3.15.0")] protected float m_FixedX = 0; [SerializeField][Since("v3.15.0")] protected float m_FixedY = 0; + [SerializeField][Since("v3.16.0")] protected float m_MinGap = 0; [SerializeField] protected IconStyle m_Icon = new IconStyle(); [SerializeField] protected ImageStyle m_Background = new ImageStyle(); @@ -308,6 +309,16 @@ namespace XCharts.Runtime set { if (PropertyUtil.SetStruct(ref m_FixedY, value)) SetComponentDirty(); } } /// + /// the gap between label and the previous label. When the distance to the previous label is less than this value, + /// the label with smaller y value will be hidden. Default is 0, which means this function is turned off. + /// 和上一个标签的最小间距。当和上一个标签的距离小于该值时,隐藏对应y值较小的标签。默认为0不开启该功能。 + /// + public float minGap + { + get { return m_MinGap; } + set { if (PropertyUtil.SetStruct(ref m_MinGap, value)) SetComponentDirty(); } + } + /// /// the sytle of background. /// ||背景图样式。 /// diff --git a/Runtime/Serie/SerieHandler.cs b/Runtime/Serie/SerieHandler.cs index e503068b..5209e311 100644 --- a/Runtime/Serie/SerieHandler.cs +++ b/Runtime/Serie/SerieHandler.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Text; using UnityEngine; @@ -507,6 +508,9 @@ namespace XCharts.Runtime var needCheck = serie.context.dataIndexs.Count > 0; var allLabelZeroPosition = true; var anyLabelActive = false; + SerieData lastActiveLabelSerieData = null; + var lastActiveLabelPos = Vector3.zero; + double lastActiveLabelValue = 0; foreach (var serieData in serie.data) { if (serieData.labelObject == null && serieData.context.dataLabels.Count <= 0) @@ -573,6 +577,37 @@ namespace XCharts.Runtime currLabel, color, chart); var labelPos = UpdateLabelPosition(serieData, currLabel); var active = currLabel.show && !isIgnore && !serie.IsMinShowLabelValue(value); + if (active && currLabel.minGap > 0 && lastActiveLabelSerieData != null) + { + var dist = Mathf.Abs(labelPos.x - lastActiveLabelPos.x); + if (dist < currLabel.minGap) + { + var currValue = serieData.GetData(1); + if (Math.Abs(currValue) >= Math.Abs(lastActiveLabelValue)) + { + lastActiveLabelSerieData.SetLabelActive(false); + lastActiveLabelSerieData = serieData; + lastActiveLabelPos = labelPos; + lastActiveLabelValue = currValue; + } + else + { + active = false; + } + } + else + { + lastActiveLabelSerieData = serieData; + lastActiveLabelPos = labelPos; + lastActiveLabelValue = serieData.GetData(1); + } + } + else if (active) + { + lastActiveLabelSerieData = serieData; + lastActiveLabelPos = labelPos; + lastActiveLabelValue = serieData.GetData(1); + } if (active) { anyLabelActive = true;