diff --git a/Editor/ChildComponents/LabelStyleDrawer.cs b/Editor/ChildComponents/LabelStyleDrawer.cs
index f2724cd2..bd933807 100644
--- a/Editor/ChildComponents/LabelStyleDrawer.cs
+++ b/Editor/ChildComponents/LabelStyleDrawer.cs
@@ -30,4 +30,10 @@ namespace XCharts.Editor
}
}
}
+
+ [CustomPropertyDrawer(typeof(EndLabelStyle), true)]
+ public class EndLabelStyleDrawer : LabelStyleDrawer
+ {
+ public override string ClassName { get { return "EndLabel"; } }
+ }
}
\ No newline at end of file
diff --git a/Runtime/Component/Axis/AxisHelper.cs b/Runtime/Component/Axis/AxisHelper.cs
index 4bddf213..5e9b1570 100644
--- a/Runtime/Component/Axis/AxisHelper.cs
+++ b/Runtime/Component/Axis/AxisHelper.cs
@@ -490,6 +490,22 @@ namespace XCharts.Runtime
}
}
+ public static double GetAxisPositionValue(GridCoord grid, Axis axis, Vector3 pos)
+ {
+ if (axis is YAxis)
+ return GetAxisPositionValue(pos.y, grid.context.height, axis.context.minMaxRange, grid.context.y, axis.context.offset);
+ else if (axis is XAxis)
+ return GetAxisPositionValue(pos.x, grid.context.width, axis.context.minMaxRange, grid.context.x, axis.context.offset);
+ else
+ return 0;
+ }
+
+ public static double GetAxisPositionValue(float xy, float axisLength, double axisRange, float axisStart, float axisOffset)
+ {
+ var yRate = axisRange / axisLength;
+ return yRate * (xy - axisStart - axisOffset);
+ }
+
///
/// 获得数值value在坐标轴上的坐标位置
///
diff --git a/Runtime/Component/Child/EndLabelStyle.cs b/Runtime/Component/Child/EndLabelStyle.cs
index 7653775e..2f22c1b5 100644
--- a/Runtime/Component/Child/EndLabelStyle.cs
+++ b/Runtime/Component/Child/EndLabelStyle.cs
@@ -7,5 +7,12 @@ namespace XCharts.Runtime
[System.Serializable]
public class EndLabelStyle : LabelStyle
{
+ public EndLabelStyle()
+ {
+ m_Offset = new Vector3(5, 0, 0);
+ m_TextStyle.alignment = TextAnchor.MiddleLeft;
+ m_NumericFormatter = "f0";
+ m_Formatter = "{a}:{c}";
+ }
}
}
\ No newline at end of file
diff --git a/Runtime/Component/Child/LabelStyle.cs b/Runtime/Component/Child/LabelStyle.cs
index fb23053a..86513731 100644
--- a/Runtime/Component/Child/LabelStyle.cs
+++ b/Runtime/Component/Child/LabelStyle.cs
@@ -67,20 +67,20 @@ namespace XCharts.Runtime
End
}
- [SerializeField] private bool m_Show = true;
+ [SerializeField] protected bool m_Show = true;
[SerializeField] Position m_Position = Position.Outside;
- [SerializeField] private Vector3 m_Offset;
- [SerializeField] private float m_Distance;
- [SerializeField] private string m_Formatter;
- [SerializeField] private float m_PaddingLeftRight = 2f;
- [SerializeField] private float m_PaddingTopBottom = 2f;
- [SerializeField] private float m_BackgroundWidth = 0;
- [SerializeField] private float m_BackgroundHeight = 0;
- [SerializeField] private string m_NumericFormatter = "";
- [SerializeField] private bool m_AutoOffset = false;
+ [SerializeField] protected Vector3 m_Offset;
+ [SerializeField] protected float m_Distance;
+ [SerializeField] protected string m_Formatter;
+ [SerializeField] protected float m_PaddingLeftRight = 2f;
+ [SerializeField] protected float m_PaddingTopBottom = 2f;
+ [SerializeField] protected float m_BackgroundWidth = 0;
+ [SerializeField] protected float m_BackgroundHeight = 0;
+ [SerializeField] protected string m_NumericFormatter = "";
+ [SerializeField] protected bool m_AutoOffset = false;
- [SerializeField] private TextStyle m_TextStyle = new TextStyle();
- private SerieLabelFormatterFunction m_FormatterFunction;
+ [SerializeField] protected TextStyle m_TextStyle = new TextStyle();
+ protected SerieLabelFormatterFunction m_FormatterFunction;
public void Reset()
{
diff --git a/Runtime/Coord/Grid/GridCoordContext.cs b/Runtime/Coord/Grid/GridCoordContext.cs
index 251766fa..961a3585 100644
--- a/Runtime/Coord/Grid/GridCoordContext.cs
+++ b/Runtime/Coord/Grid/GridCoordContext.cs
@@ -1,4 +1,5 @@
+using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
@@ -16,5 +17,6 @@ namespace XCharts.Runtime
public float bottom;
public float top;
public bool isPointerEnter;
+ public List endLabelList = new List();
}
}
\ No newline at end of file
diff --git a/Runtime/Internal/Object/ChartLabel.cs b/Runtime/Internal/Object/ChartLabel.cs
index 600e35a3..057a728a 100644
--- a/Runtime/Internal/Object/ChartLabel.cs
+++ b/Runtime/Internal/Object/ChartLabel.cs
@@ -7,7 +7,7 @@ namespace XCharts.Runtime
public class ChartLabel : Image
{
[SerializeField] private ChartText m_LabelText;
-
+
private bool m_AutoHideIconWhenLabelEmpty = false;
private bool m_LabelAutoSize = true;
private float m_LabelPaddingLeftRight = 3f;
@@ -43,6 +43,7 @@ namespace XCharts.Runtime
public bool autoHideIconWhenLabelEmpty { set { m_AutoHideIconWhenLabelEmpty = value; } }
public bool isIconActive { get; private set; }
+ public bool isAnimationEnd { get; internal set; }
protected override void Awake()
{
diff --git a/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Runtime/Serie/Line/LineHandler.GridCoord.cs
index 9e92026e..300733b2 100644
--- a/Runtime/Serie/Line/LineHandler.GridCoord.cs
+++ b/Runtime/Serie/Line/LineHandler.GridCoord.cs
@@ -266,6 +266,10 @@ namespace XCharts.Runtime
m_SerieGrid = chart.GetChartComponent(axis.gridIndex);
if (m_SerieGrid == null)
return;
+ if (m_EndLabel != null && !m_SerieGrid.context.endLabelList.Contains(m_EndLabel))
+ {
+ m_SerieGrid.context.endLabelList.Add(m_EndLabel);
+ }
var visualMap = chart.GetVisualMapOfSerie(serie);
var dataZoom = chart.GetDataZoomOfAxis(axis);
diff --git a/Runtime/Serie/Line/LineHandler.cs b/Runtime/Serie/Line/LineHandler.cs
index 9b0bdf05..b90bb341 100644
--- a/Runtime/Serie/Line/LineHandler.cs
+++ b/Runtime/Serie/Line/LineHandler.cs
@@ -60,5 +60,39 @@ namespace XCharts.Runtime
}
}
}
+
+ public override void RefreshEndLabelInternal()
+ {
+ base.RefreshEndLabelInternal();
+ if (m_SerieGrid == null) return;
+ if (!serie.animation.IsFinish()) return;
+ var endLabelList = m_SerieGrid.context.endLabelList;
+ if (endLabelList.Count <= 1) return;
+
+ endLabelList.Sort(delegate (ChartLabel a, ChartLabel b)
+ {
+ return b.transform.position.y.CompareTo(a.transform.position.y);
+ });
+ var lastY = float.NaN;
+ for (int i = 0; i < endLabelList.Count; i++)
+ {
+ var label = endLabelList[i];
+ if (!label.isAnimationEnd) continue;
+ var labelPosition = label.transform.localPosition;
+ if (float.IsNaN(lastY))
+ {
+ lastY = labelPosition.y;
+ }
+ else
+ {
+ var labelHeight = label.GetLabelHeight();
+ if (labelPosition.y + labelHeight > lastY)
+ {
+ label.SetPosition(new Vector3(labelPosition.x, lastY - labelHeight, labelPosition.z));
+ }
+ lastY = label.transform.localPosition.y;
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Runtime/Serie/Line/LineHelper.cs b/Runtime/Serie/Line/LineHelper.cs
index d35da898..ff1f71f6 100644
--- a/Runtime/Serie/Line/LineHelper.cs
+++ b/Runtime/Serie/Line/LineHelper.cs
@@ -295,6 +295,14 @@ namespace XCharts.Runtime
{
AddLineVertToVertexHelper(vh, ltp, lbp, lineColor, isVisualMapGradient, isLineStyleGradient,
visualMap, serie.lineStyle, grid, axis, relativedAxis, false, lastDataIsIgnore, isIgnore);
+ if (dataCount == 2 || isBreak)
+ {
+ AddLineVertToVertexHelper(vh, clp, crp, lineColor, isVisualMapGradient, isLineStyleGradient,
+ visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore);
+ serie.context.lineEndPostion = cp;
+ serie.context.lineEndValue = AxisHelper.GetAxisPositionValue(grid, relativedAxis, cp);
+ break;
+ }
}
if (bitp == bibp)
@@ -327,6 +335,8 @@ namespace XCharts.Runtime
visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore);
}
}
+ serie.context.lineEndPostion = cp;
+ serie.context.lineEndValue = AxisHelper.GetAxisPositionValue(grid, relativedAxis, cp);
lastDataIsIgnore = isIgnore;
if (isBreak)
break;
diff --git a/Runtime/Serie/SerieContext.cs b/Runtime/Serie/SerieContext.cs
index d549f635..1298be7b 100644
--- a/Runtime/Serie/SerieContext.cs
+++ b/Runtime/Serie/SerieContext.cs
@@ -37,6 +37,11 @@ namespace XCharts.Runtime
///
public Vector3 center;
///
+ /// 线段终点
+ ///
+ public Vector3 lineEndPostion;
+ public double lineEndValue;
+ ///
/// 内半径
///
public float insideRadius;
diff --git a/Runtime/Serie/SerieHandler.cs b/Runtime/Serie/SerieHandler.cs
index 13bc06cd..b46941c2 100644
--- a/Runtime/Serie/SerieHandler.cs
+++ b/Runtime/Serie/SerieHandler.cs
@@ -47,6 +47,7 @@ namespace XCharts.Runtime
private static readonly string s_SerieLabelObjectName = "label";
private static readonly string s_SerieTitleObjectName = "title";
private static readonly string s_SerieRootObjectName = "serie";
+ private static readonly string s_SerieEndLabelObjectName = "end_label";
protected GameObject m_SerieRoot;
protected GameObject m_SerieLabelRoot;
protected bool m_InitedLabel;
@@ -55,6 +56,7 @@ namespace XCharts.Runtime
protected bool m_LastCheckContextFlag = false;
protected bool m_LegendEnter = false;
protected int m_LegendEnterIndex;
+ protected ChartLabel m_EndLabel;
public T serie { get; internal set; }
public GameObject labelObject { get { return m_SerieLabelRoot; } }
@@ -77,8 +79,8 @@ namespace XCharts.Runtime
if (m_RefreshLabel)
{
m_RefreshLabel = false;
- if (m_InitedLabel)
- RefreshLabelInternal();
+ RefreshLabelInternal();
+ RefreshEndLabelInternal();
}
if (serie.dataDirty)
{
@@ -91,6 +93,12 @@ namespace XCharts.Runtime
serie.labelDirty = false;
serie.label.ClearComponentDirty();
InitSerieLabel();
+ InitSerieEndLabel();
+ }
+ if (serie.endLabel != null && serie.endLabel.componentDirty)
+ {
+ serie.endLabel.ClearComponentDirty();
+ InitSerieEndLabel();
}
if (serie.titleStyle != null && (serie.titleDirty || serie.titleStyle.componentDirty))
{
@@ -126,6 +134,7 @@ namespace XCharts.Runtime
InitRoot();
InitSerieLabel();
InitSerieTitle();
+ InitSerieEndLabel();
}
public override void RemoveComponent()
@@ -265,6 +274,46 @@ namespace XCharts.Runtime
return true;
}
+ private void InitSerieEndLabel()
+ {
+ if (serie.endLabel == null)
+ {
+ if (m_EndLabel != null)
+ {
+ m_EndLabel.SetActive(false);
+ m_EndLabel = null;
+ }
+ return;
+ }
+ if (m_SerieRoot == null)
+ InitRoot();
+ var serieLabel = serie.endLabel;
+ var textStyle = serieLabel.textStyle;
+ var dataAutoColor = (Color)chart.theme.GetColor(serie.index);
+
+ var color = serieLabel.textStyle.autoColor ? dataAutoColor : chart.theme.common.textColor;
+
+ var anchorMin = new Vector2(0f, 0.5f);
+ var anchorMax = new Vector2(0f, 0.5f);
+ var pivot = new Vector2(0f, 0.5f);
+ var sizeDelta = new Vector2(50, textStyle.GetFontSize(chart.theme.common) + 2);
+ var labelObj = ChartHelper.AddObject(s_SerieEndLabelObjectName, m_SerieRoot.transform, anchorMin, anchorMax, pivot, sizeDelta);
+ var txt = ChartHelper.AddTextObject("Text", labelObj.transform, anchorMin, anchorMax, pivot, sizeDelta, textStyle,
+ chart.theme.common);
+ txt.SetColor(color);
+ txt.SetAlignment(textStyle.alignment);
+ txt.SetText("Text");
+ txt.SetLocalPosition(new Vector2(0, 0));
+ txt.SetLocalEulerAngles(Vector3.zero);
+
+ var isAutoSize = serieLabel.backgroundWidth == 0 || serieLabel.backgroundHeight == 0;
+ m_EndLabel = ChartHelper.GetOrAddComponent(labelObj);
+ m_EndLabel.SetLabel(labelObj, isAutoSize, serieLabel.paddingLeftRight, serieLabel.paddingTopBottom);
+ m_EndLabel.SetIconActive(false);
+ m_EndLabel.SetActive(true);
+ RefreshEndLabelInternal();
+ }
+
private void InitSerieTitle()
{
if (m_SerieRoot == null)
@@ -367,6 +416,27 @@ namespace XCharts.Runtime
}
}
+ public virtual void RefreshEndLabelInternal()
+ {
+ if (m_EndLabel == null)
+ return;
+ var endLabelStyle = serie.endLabel;
+ if (endLabelStyle == null)
+ return;
+ var dataCount = serie.context.drawPoints.Count;
+ var active = endLabelStyle.show && dataCount > 0;
+ m_EndLabel.SetActive(active);
+ if (active)
+ {
+ var value = serie.context.lineEndValue;
+ var content = SerieLabelHelper.GetFormatterContent(serie, null, value, 0,
+ endLabelStyle, Color.clear);
+ m_EndLabel.SetText(content);
+ m_EndLabel.SetPosition(serie.context.lineEndPostion + endLabelStyle.offset);
+ }
+ m_EndLabel.isAnimationEnd = serie.animation.IsFinish();
+ }
+
private void UpdateLabelPosition(SerieData serieData, LabelStyle currLabel)
{
var isNeedInvertPositionSerie = serie is Line;
diff --git a/Runtime/XUGL/UGLHelper.cs b/Runtime/XUGL/UGLHelper.cs
index 650efed1..922783a3 100644
--- a/Runtime/XUGL/UGLHelper.cs
+++ b/Runtime/XUGL/UGLHelper.cs
@@ -289,20 +289,25 @@ namespace XUGL
ref Vector3 ntp, ref Vector3 nbp,
ref Vector3 itp, ref Vector3 ibp,
ref Vector3 clp, ref Vector3 crp,
- ref bool bitp, ref bool bibp, int debugIndex = 0
- )
+ ref bool bitp, ref bool bibp, int debugIndex = 0)
{
var dir1 = (cp - lp).normalized;
- var dir2 = (cp - np).normalized;
var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized * width;
- var dir2v = Vector3.Cross(dir2, Vector3.back).normalized * width;
-
ltp = lp - dir1v;
lbp = lp + dir1v;
+ if (debugIndex == 1 && cp == np)
+ {
+ ntp = np - dir1v;
+ nbp = np + dir1v;
+ clp = cp - dir1v;
+ crp = cp + dir1v;
+ return;
+ }
+ var dir2 = (cp - np).normalized;
+ var dir2v = Vector3.Cross(dir2, Vector3.back).normalized * width;
ntp = np - dir2v;
nbp = np + dir2v;
-
clp = cp - dir2v;
crp = cp + dir2v;