[enhancement][line] line support end label

This commit is contained in:
monitor1394
2022-04-14 21:32:44 +08:00
parent 84cf39df4d
commit 80e4475f65
12 changed files with 181 additions and 21 deletions

View File

@@ -30,4 +30,10 @@ namespace XCharts.Editor
} }
} }
} }
[CustomPropertyDrawer(typeof(EndLabelStyle), true)]
public class EndLabelStyleDrawer : LabelStyleDrawer
{
public override string ClassName { get { return "EndLabel"; } }
}
} }

View File

@@ -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);
}
/// <summary> /// <summary>
/// 获得数值value在坐标轴上的坐标位置 /// 获得数值value在坐标轴上的坐标位置
/// </summary> /// </summary>

View File

@@ -7,5 +7,12 @@ namespace XCharts.Runtime
[System.Serializable] [System.Serializable]
public class EndLabelStyle : LabelStyle 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}";
}
} }
} }

View File

@@ -67,20 +67,20 @@ namespace XCharts.Runtime
End End
} }
[SerializeField] private bool m_Show = true; [SerializeField] protected bool m_Show = true;
[SerializeField] Position m_Position = Position.Outside; [SerializeField] Position m_Position = Position.Outside;
[SerializeField] private Vector3 m_Offset; [SerializeField] protected Vector3 m_Offset;
[SerializeField] private float m_Distance; [SerializeField] protected float m_Distance;
[SerializeField] private string m_Formatter; [SerializeField] protected string m_Formatter;
[SerializeField] private float m_PaddingLeftRight = 2f; [SerializeField] protected float m_PaddingLeftRight = 2f;
[SerializeField] private float m_PaddingTopBottom = 2f; [SerializeField] protected float m_PaddingTopBottom = 2f;
[SerializeField] private float m_BackgroundWidth = 0; [SerializeField] protected float m_BackgroundWidth = 0;
[SerializeField] private float m_BackgroundHeight = 0; [SerializeField] protected float m_BackgroundHeight = 0;
[SerializeField] private string m_NumericFormatter = ""; [SerializeField] protected string m_NumericFormatter = "";
[SerializeField] private bool m_AutoOffset = false; [SerializeField] protected bool m_AutoOffset = false;
[SerializeField] private TextStyle m_TextStyle = new TextStyle(); [SerializeField] protected TextStyle m_TextStyle = new TextStyle();
private SerieLabelFormatterFunction m_FormatterFunction; protected SerieLabelFormatterFunction m_FormatterFunction;
public void Reset() public void Reset()
{ {

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
namespace XCharts.Runtime namespace XCharts.Runtime
@@ -16,5 +17,6 @@ namespace XCharts.Runtime
public float bottom; public float bottom;
public float top; public float top;
public bool isPointerEnter; public bool isPointerEnter;
public List<ChartLabel> endLabelList = new List<ChartLabel>();
} }
} }

View File

@@ -7,7 +7,7 @@ namespace XCharts.Runtime
public class ChartLabel : Image public class ChartLabel : Image
{ {
[SerializeField] private ChartText m_LabelText; [SerializeField] private ChartText m_LabelText;
private bool m_AutoHideIconWhenLabelEmpty = false; private bool m_AutoHideIconWhenLabelEmpty = false;
private bool m_LabelAutoSize = true; private bool m_LabelAutoSize = true;
private float m_LabelPaddingLeftRight = 3f; private float m_LabelPaddingLeftRight = 3f;
@@ -43,6 +43,7 @@ namespace XCharts.Runtime
public bool autoHideIconWhenLabelEmpty { set { m_AutoHideIconWhenLabelEmpty = value; } } public bool autoHideIconWhenLabelEmpty { set { m_AutoHideIconWhenLabelEmpty = value; } }
public bool isIconActive { get; private set; } public bool isIconActive { get; private set; }
public bool isAnimationEnd { get; internal set; }
protected override void Awake() protected override void Awake()
{ {

View File

@@ -266,6 +266,10 @@ namespace XCharts.Runtime
m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex); m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
if (m_SerieGrid == null) if (m_SerieGrid == null)
return; 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 visualMap = chart.GetVisualMapOfSerie(serie);
var dataZoom = chart.GetDataZoomOfAxis(axis); var dataZoom = chart.GetDataZoomOfAxis(axis);

View File

@@ -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;
}
}
}
} }
} }

View File

@@ -295,6 +295,14 @@ namespace XCharts.Runtime
{ {
AddLineVertToVertexHelper(vh, ltp, lbp, lineColor, isVisualMapGradient, isLineStyleGradient, AddLineVertToVertexHelper(vh, ltp, lbp, lineColor, isVisualMapGradient, isLineStyleGradient,
visualMap, serie.lineStyle, grid, axis, relativedAxis, false, lastDataIsIgnore, isIgnore); 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) if (bitp == bibp)
@@ -327,6 +335,8 @@ namespace XCharts.Runtime
visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore);
} }
} }
serie.context.lineEndPostion = cp;
serie.context.lineEndValue = AxisHelper.GetAxisPositionValue(grid, relativedAxis, cp);
lastDataIsIgnore = isIgnore; lastDataIsIgnore = isIgnore;
if (isBreak) if (isBreak)
break; break;

View File

@@ -37,6 +37,11 @@ namespace XCharts.Runtime
/// </summary> /// </summary>
public Vector3 center; public Vector3 center;
/// <summary> /// <summary>
/// 线段终点
/// </summary>
public Vector3 lineEndPostion;
public double lineEndValue;
/// <summary>
/// 内半径 /// 内半径
/// </summary> /// </summary>
public float insideRadius; public float insideRadius;

View File

@@ -47,6 +47,7 @@ namespace XCharts.Runtime
private static readonly string s_SerieLabelObjectName = "label"; private static readonly string s_SerieLabelObjectName = "label";
private static readonly string s_SerieTitleObjectName = "title"; private static readonly string s_SerieTitleObjectName = "title";
private static readonly string s_SerieRootObjectName = "serie"; private static readonly string s_SerieRootObjectName = "serie";
private static readonly string s_SerieEndLabelObjectName = "end_label";
protected GameObject m_SerieRoot; protected GameObject m_SerieRoot;
protected GameObject m_SerieLabelRoot; protected GameObject m_SerieLabelRoot;
protected bool m_InitedLabel; protected bool m_InitedLabel;
@@ -55,6 +56,7 @@ namespace XCharts.Runtime
protected bool m_LastCheckContextFlag = false; protected bool m_LastCheckContextFlag = false;
protected bool m_LegendEnter = false; protected bool m_LegendEnter = false;
protected int m_LegendEnterIndex; protected int m_LegendEnterIndex;
protected ChartLabel m_EndLabel;
public T serie { get; internal set; } public T serie { get; internal set; }
public GameObject labelObject { get { return m_SerieLabelRoot; } } public GameObject labelObject { get { return m_SerieLabelRoot; } }
@@ -77,8 +79,8 @@ namespace XCharts.Runtime
if (m_RefreshLabel) if (m_RefreshLabel)
{ {
m_RefreshLabel = false; m_RefreshLabel = false;
if (m_InitedLabel) RefreshLabelInternal();
RefreshLabelInternal(); RefreshEndLabelInternal();
} }
if (serie.dataDirty) if (serie.dataDirty)
{ {
@@ -91,6 +93,12 @@ namespace XCharts.Runtime
serie.labelDirty = false; serie.labelDirty = false;
serie.label.ClearComponentDirty(); serie.label.ClearComponentDirty();
InitSerieLabel(); InitSerieLabel();
InitSerieEndLabel();
}
if (serie.endLabel != null && serie.endLabel.componentDirty)
{
serie.endLabel.ClearComponentDirty();
InitSerieEndLabel();
} }
if (serie.titleStyle != null && (serie.titleDirty || serie.titleStyle.componentDirty)) if (serie.titleStyle != null && (serie.titleDirty || serie.titleStyle.componentDirty))
{ {
@@ -126,6 +134,7 @@ namespace XCharts.Runtime
InitRoot(); InitRoot();
InitSerieLabel(); InitSerieLabel();
InitSerieTitle(); InitSerieTitle();
InitSerieEndLabel();
} }
public override void RemoveComponent() public override void RemoveComponent()
@@ -265,6 +274,46 @@ namespace XCharts.Runtime
return true; 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<ChartLabel>(labelObj);
m_EndLabel.SetLabel(labelObj, isAutoSize, serieLabel.paddingLeftRight, serieLabel.paddingTopBottom);
m_EndLabel.SetIconActive(false);
m_EndLabel.SetActive(true);
RefreshEndLabelInternal();
}
private void InitSerieTitle() private void InitSerieTitle()
{ {
if (m_SerieRoot == null) 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) private void UpdateLabelPosition(SerieData serieData, LabelStyle currLabel)
{ {
var isNeedInvertPositionSerie = serie is Line; var isNeedInvertPositionSerie = serie is Line;

View File

@@ -289,20 +289,25 @@ namespace XUGL
ref Vector3 ntp, ref Vector3 nbp, ref Vector3 ntp, ref Vector3 nbp,
ref Vector3 itp, ref Vector3 ibp, ref Vector3 itp, ref Vector3 ibp,
ref Vector3 clp, ref Vector3 crp, 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 dir1 = (cp - lp).normalized;
var dir2 = (cp - np).normalized;
var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized * width; var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized * width;
var dir2v = Vector3.Cross(dir2, Vector3.back).normalized * width;
ltp = lp - dir1v; ltp = lp - dir1v;
lbp = 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; ntp = np - dir2v;
nbp = np + dir2v; nbp = np + dir2v;
clp = cp - dir2v; clp = cp - dir2v;
crp = cp + dir2v; crp = cp + dir2v;