mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-22 00:20:18 +00:00
3.0 - unitypackage
This commit is contained in:
160
Runtime/Component/Mark/MarkArea.cs
Normal file
160
Runtime/Component/Mark/MarkArea.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// 标域类型
|
||||
/// </summary>
|
||||
public enum MarkAreaType
|
||||
{
|
||||
None,
|
||||
/// <summary>
|
||||
/// 最小值。
|
||||
/// </summary>
|
||||
Min,
|
||||
/// <summary>
|
||||
/// 最大值。
|
||||
/// </summary>
|
||||
Max,
|
||||
/// <summary>
|
||||
/// 平均值。
|
||||
/// </summary>
|
||||
Average,
|
||||
/// <summary>
|
||||
/// 中位数。
|
||||
/// </summary>
|
||||
Median
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
[ComponentHandler(typeof(MarkAreaHandler), true)]
|
||||
public class MarkArea : MainComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private string m_Text = "";
|
||||
[SerializeField] private int m_SerieIndex = 0;
|
||||
[SerializeField] private MarkAreaData m_Start = new MarkAreaData();
|
||||
[SerializeField] private MarkAreaData m_End = new MarkAreaData();
|
||||
[SerializeField] private ItemStyle m_ItemStyle = new ItemStyle();
|
||||
[SerializeField] private LabelStyle m_Label = new LabelStyle();
|
||||
public ChartLabel runtimeLabel { get; internal set; }
|
||||
public Vector3 runtimeLabelPosition { get; internal set; }
|
||||
public Rect runtimeRect { get; internal set; }
|
||||
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
|
||||
}
|
||||
public string text
|
||||
{
|
||||
get { return m_Text; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Text, value)) SetComponentDirty(); }
|
||||
}
|
||||
public int serieIndex
|
||||
{
|
||||
get { return m_SerieIndex; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_SerieIndex, value)) SetVerticesDirty(); }
|
||||
}
|
||||
public MarkAreaData start
|
||||
{
|
||||
get { return m_Start; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Start, value)) SetVerticesDirty(); }
|
||||
}
|
||||
public MarkAreaData end
|
||||
{
|
||||
get { return m_End; }
|
||||
set { if (PropertyUtil.SetClass(ref m_End, value)) SetVerticesDirty(); }
|
||||
}
|
||||
public ItemStyle itemStyle
|
||||
{
|
||||
get { return m_ItemStyle; }
|
||||
set { if (PropertyUtil.SetClass(ref m_ItemStyle, value)) SetVerticesDirty(); }
|
||||
}
|
||||
public LabelStyle label
|
||||
{
|
||||
get { return m_Label; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Label, value)) SetComponentDirty(); }
|
||||
}
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_ItemStyle = new ItemStyle();
|
||||
m_ItemStyle.opacity = 0.6f;
|
||||
m_Label = new LabelStyle();
|
||||
m_Label.show = true;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class MarkAreaData : ChildComponent
|
||||
{
|
||||
[SerializeField] private MarkAreaType m_Type = MarkAreaType.None;
|
||||
[SerializeField] private string m_Name;
|
||||
[SerializeField] private int m_Dimension = 1;
|
||||
[SerializeField] private float m_XPosition;
|
||||
[SerializeField] private float m_YPosition;
|
||||
[SerializeField] private double m_XValue;
|
||||
[SerializeField] private double m_YValue;
|
||||
public double runtimeValue { get; internal set; }
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Name, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Special markArea types, are used to label maximum value, minimum value and so on.
|
||||
/// 特殊的标域类型,用于标注最大值最小值等。
|
||||
/// </summary>
|
||||
public MarkAreaType type
|
||||
{
|
||||
get { return m_Type; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// From which dimension of data to calculate the maximum and minimum value and so on.
|
||||
/// 从哪个维度的数据计算最大最小值等。
|
||||
/// </summary>
|
||||
public int dimension
|
||||
{
|
||||
get { return m_Dimension; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Dimension, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The x coordinate relative to the origin, in pixels.
|
||||
/// 相对原点的 x 坐标,单位像素。当type为None时有效。
|
||||
/// </summary>
|
||||
public float xPosition
|
||||
{
|
||||
get { return m_XPosition; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_XPosition, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The y coordinate relative to the origin, in pixels.
|
||||
/// 相对原点的 y 坐标,单位像素。当type为None时有效。
|
||||
/// </summary>
|
||||
public float yPosition
|
||||
{
|
||||
get { return m_YPosition; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_YPosition, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The value specified on the X-axis. A value specified when the X-axis is the category axis represents the index of the category axis data, otherwise a specific value.
|
||||
/// X轴上的指定值。当X轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。
|
||||
/// </summary>
|
||||
public double xValue
|
||||
{
|
||||
get { return m_XValue; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_XValue, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// That's the value on the Y-axis. The value specified when the Y axis is the category axis represents the index of the category axis data, otherwise the specific value.
|
||||
/// Y轴上的指定值。当Y轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。
|
||||
/// </summary>
|
||||
public double yValue
|
||||
{
|
||||
get { return m_YValue; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_YValue, value)) SetVerticesDirty(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Mark/MarkArea.cs.meta
Normal file
11
Runtime/Component/Mark/MarkArea.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c7f98347a0d54e1c82866b041a473ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
204
Runtime/Component/Mark/MarkAreaHandler.cs
Normal file
204
Runtime/Component/Mark/MarkAreaHandler.cs
Normal file
@@ -0,0 +1,204 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class MarkAreaHandler : MainComponentHandler<MarkArea>
|
||||
{
|
||||
private GameObject m_MarkLineLabelRoot;
|
||||
private bool m_LabelShow;
|
||||
private bool m_NeedUpdateLabelPosition;
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
m_MarkLineLabelRoot = ChartHelper.AddObject("markarea" + component.index, chart.transform, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
m_MarkLineLabelRoot.hideFlags = chart.chartHideFlags;
|
||||
ChartHelper.HideAllObject(m_MarkLineLabelRoot);
|
||||
InitMarkArea(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawMarkArea(vh, component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (m_NeedUpdateLabelPosition)
|
||||
{
|
||||
m_NeedUpdateLabelPosition = false;
|
||||
if (component.runtimeLabel != null)
|
||||
{
|
||||
component.runtimeLabel.SetPosition(component.runtimeLabelPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitMarkArea(MarkArea markArea)
|
||||
{
|
||||
m_LabelShow = markArea.label.show && !string.IsNullOrEmpty(component.text);
|
||||
markArea.painter = chart.m_PainterTop;
|
||||
markArea.refreshComponent = delegate ()
|
||||
{
|
||||
var label = markArea.label;
|
||||
var color = !ChartHelper.IsClearColor(label.textStyle.color) ? label.textStyle.color : chart.theme.axis.textColor;
|
||||
var element = ChartHelper.AddSerieLabel("label", m_MarkLineLabelRoot.transform, label.backgroundWidth,
|
||||
label.backgroundHeight, color, label.textStyle, chart.theme);
|
||||
var isAutoSize = label.backgroundWidth == 0 || label.backgroundHeight == 0;
|
||||
var item = ChartHelper.GetOrAddComponent<ChartLabel>(element);
|
||||
UpdateRuntimeData(component);
|
||||
item.SetLabel(element, isAutoSize, label.paddingLeftRight, label.paddingTopBottom);
|
||||
item.SetIconActive(false);
|
||||
item.SetActive(m_LabelShow);
|
||||
item.SetPosition(component.runtimeLabelPosition);
|
||||
item.SetText(component.text);
|
||||
markArea.runtimeLabel = item;
|
||||
};
|
||||
markArea.refreshComponent();
|
||||
}
|
||||
|
||||
private void DrawMarkArea(VertexHelper vh, MarkArea markArea)
|
||||
{
|
||||
if (!markArea.show) return;
|
||||
var serie = chart.GetSerie(markArea.serieIndex);
|
||||
if (serie == null || !serie.show || !markArea.show) return;
|
||||
|
||||
UpdateRuntimeData(markArea);
|
||||
|
||||
var colorIndex = chart.GetLegendRealShowNameIndex(serie.serieName);
|
||||
var serieColor = SerieHelper.GetLineColor(serie, chart.theme, colorIndex, false);
|
||||
var areaColor = markArea.itemStyle.GetColor(serieColor);
|
||||
UGL.DrawRectangle(vh, markArea.runtimeRect, areaColor, areaColor);
|
||||
}
|
||||
|
||||
private void UpdateRuntimeData(MarkArea markArea)
|
||||
{
|
||||
var serie = chart.GetSerie(markArea.serieIndex);
|
||||
if (serie == null || !serie.show || !markArea.show) return;
|
||||
var yAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex);
|
||||
var xAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex);
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
var dataZoom = chart.GetDataZoomOfAxis(xAxis);
|
||||
var showData = serie.GetDataList(dataZoom);
|
||||
|
||||
var lt = GetPosition(markArea.start, serie, dataZoom, xAxis, yAxis, grid, showData, true);
|
||||
var rb = GetPosition(markArea.end, serie, dataZoom, xAxis, yAxis, grid, showData, false);
|
||||
var lb = new Vector3(lt.x, rb.y);
|
||||
|
||||
markArea.runtimeRect = new Rect(lb.x, lb.y, rb.x - lb.x, lt.y - lb.y);
|
||||
UpdateLabelPosition(markArea);
|
||||
}
|
||||
|
||||
private void UpdateLabelPosition(MarkArea markArea)
|
||||
{
|
||||
if (!m_LabelShow) return;
|
||||
m_NeedUpdateLabelPosition = true;
|
||||
var rect = markArea.runtimeRect;
|
||||
switch (markArea.label.position)
|
||||
{
|
||||
case LabelStyle.Position.Center:
|
||||
markArea.runtimeLabelPosition = rect.center;
|
||||
break;
|
||||
case LabelStyle.Position.Left:
|
||||
markArea.runtimeLabelPosition = rect.center + new Vector2(rect.width / 2, 0);
|
||||
break;
|
||||
case LabelStyle.Position.Right:
|
||||
markArea.runtimeLabelPosition = rect.center - new Vector2(rect.width / 2, 0);
|
||||
break;
|
||||
case LabelStyle.Position.Top:
|
||||
markArea.runtimeLabelPosition = rect.center + new Vector2(0, rect.height / 2);
|
||||
break;
|
||||
case LabelStyle.Position.Bottom:
|
||||
markArea.runtimeLabelPosition = rect.center - new Vector2(0, rect.height / 2);
|
||||
break;
|
||||
default:
|
||||
markArea.runtimeLabelPosition = rect.center + new Vector2(0, rect.height / 2);
|
||||
break;
|
||||
}
|
||||
markArea.runtimeLabelPosition += markArea.label.offset + markArea.label.textStyle.offsetv3;
|
||||
}
|
||||
|
||||
private Vector3 GetPosition(MarkAreaData data, Serie serie, DataZoom dataZoom, XAxis xAxis, YAxis yAxis,
|
||||
GridCoord grid, List<SerieData> showData, bool start)
|
||||
{
|
||||
var pos = Vector3.zero;
|
||||
switch (data.type)
|
||||
{
|
||||
case MarkAreaType.Min:
|
||||
data.runtimeValue = SerieHelper.GetMinData(serie, data.dimension, dataZoom);
|
||||
return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start);
|
||||
case MarkAreaType.Max:
|
||||
data.runtimeValue = SerieHelper.GetMaxData(serie, data.dimension, dataZoom);
|
||||
return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start);
|
||||
case MarkAreaType.Average:
|
||||
data.runtimeValue = SerieHelper.GetAverageData(serie, data.dimension, dataZoom);
|
||||
return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start);
|
||||
case MarkAreaType.Median:
|
||||
data.runtimeValue = SerieHelper.GetMedianData(serie, data.dimension, dataZoom);
|
||||
return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start);
|
||||
case MarkAreaType.None:
|
||||
if (data.xPosition != 0 || data.yPosition != 0)
|
||||
{
|
||||
var pX = grid.context.x + data.xPosition;
|
||||
var pY = grid.context.y + data.yPosition;
|
||||
return new Vector3(pX, pY);
|
||||
}
|
||||
else if (data.yValue != 0)
|
||||
{
|
||||
data.runtimeValue = data.yValue;
|
||||
if (yAxis.IsCategory())
|
||||
{
|
||||
var pY = AxisHelper.GetAxisPosition(grid, yAxis, data.yValue, showData.Count, dataZoom);
|
||||
return start ?
|
||||
new Vector3(grid.context.x, pY) :
|
||||
new Vector3(grid.context.x + grid.context.width, pY);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data.runtimeValue = data.xValue;
|
||||
if (xAxis.IsCategory())
|
||||
{
|
||||
var pX = AxisHelper.GetAxisPosition(grid, xAxis, data.xValue, showData.Count, dataZoom);
|
||||
return start ? new Vector3(pX, grid.context.y + grid.context.height) :
|
||||
new Vector3(pX, grid.context.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetPosition(xAxis, yAxis, grid, data.xValue, start);
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
private Vector3 GetPosition(Axis xAxis, Axis yAxis, GridCoord grid, double value, bool start)
|
||||
{
|
||||
if (yAxis.IsCategory())
|
||||
{
|
||||
var pX = AxisHelper.GetAxisPosition(grid, xAxis, value);
|
||||
return start ?
|
||||
new Vector3(pX, grid.context.y + grid.context.height) :
|
||||
new Vector3(pX, grid.context.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
var pY = AxisHelper.GetAxisPosition(grid, yAxis, value);
|
||||
return start ?
|
||||
new Vector3(grid.context.x, pY + grid.context.height) :
|
||||
new Vector3(grid.context.x + grid.context.width, pY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Mark/MarkAreaHandler.cs.meta
Normal file
11
Runtime/Component/Mark/MarkAreaHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5ffb2d23b0574e6eb5805a2f3783081
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
252
Runtime/Component/Mark/MarkLine.cs
Normal file
252
Runtime/Component/Mark/MarkLine.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// 标线类型
|
||||
/// </summary>
|
||||
public enum MarkLineType
|
||||
{
|
||||
None,
|
||||
/// <summary>
|
||||
/// 最小值。
|
||||
/// </summary>
|
||||
Min,
|
||||
/// <summary>
|
||||
/// 最大值。
|
||||
/// </summary>
|
||||
Max,
|
||||
/// <summary>
|
||||
/// 平均值。
|
||||
/// </summary>
|
||||
Average,
|
||||
/// <summary>
|
||||
/// 中位数。
|
||||
/// </summary>
|
||||
Median
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Use a line in the chart to illustrate.
|
||||
/// 图表标线。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[ComponentHandler(typeof(MarkLineHandler), true)]
|
||||
public class MarkLine : MainComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private int m_SerieIndex = 0;
|
||||
[SerializeField] private AnimationStyle m_Animation = new AnimationStyle();
|
||||
[SerializeField] private List<MarkLineData> m_Data = new List<MarkLineData>();
|
||||
|
||||
/// <summary>
|
||||
/// Whether to display the marking line.
|
||||
/// 是否显示标线。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
|
||||
}
|
||||
public int serieIndex
|
||||
{
|
||||
get { return m_SerieIndex; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_SerieIndex, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The animation of markline.
|
||||
/// 标线的动画样式。
|
||||
/// </summary>
|
||||
public AnimationStyle animation
|
||||
{
|
||||
get { return m_Animation; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Animation, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// A list of marked data. When the group of data item is 0, each data item represents a line;
|
||||
/// When the group is not 0, two data items of the same group represent the starting point and
|
||||
/// the ending point of the line respectively to form a line. In this case, the relevant style
|
||||
/// parameters of the line are the parameters of the starting point.
|
||||
/// 标线的数据列表。当数据项的group为0时,每个数据项表示一条标线;当group不为0时,相同group的两个数据项分别表
|
||||
/// 示标线的起始点和终止点来组成一条标线,此时标线的相关样式参数取起始点的参数。
|
||||
/// </summary>
|
||||
public List<MarkLineData> data
|
||||
{
|
||||
get { return m_Data; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Data, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
data.Clear();
|
||||
var item = new MarkLineData();
|
||||
item.name = "average";
|
||||
item.type = MarkLineType.Average;
|
||||
item.lineStyle.type = LineStyle.Type.Dashed;
|
||||
item.lineStyle.color = Color.blue;
|
||||
item.startSymbol.show = true;
|
||||
item.startSymbol.type = SymbolType.Circle;
|
||||
item.endSymbol.show = true;
|
||||
item.endSymbol.type = SymbolType.Arrow;
|
||||
item.label.show = true;
|
||||
item.label.numericFormatter = "f1";
|
||||
item.label.formatter = "{c}";
|
||||
data.Add(item);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Data of marking line.
|
||||
/// 图表标线的数据。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class MarkLineData : ChildComponent
|
||||
{
|
||||
[SerializeField] private MarkLineType m_Type = MarkLineType.None;
|
||||
[SerializeField] private string m_Name;
|
||||
[SerializeField] private int m_Dimension = 1;
|
||||
[SerializeField] private float m_XPosition;
|
||||
[SerializeField] private float m_YPosition;
|
||||
[SerializeField] private double m_XValue;
|
||||
[SerializeField] private double m_YValue;
|
||||
[SerializeField] private int m_Group = 0;
|
||||
[SerializeField] private bool m_ZeroPosition = false;
|
||||
|
||||
[SerializeField] private SymbolStyle m_StartSymbol = new SymbolStyle();
|
||||
[SerializeField] private SymbolStyle m_EndSymbol = new SymbolStyle();
|
||||
[SerializeField] private LineStyle m_LineStyle = new LineStyle();
|
||||
[SerializeField] private LabelStyle m_Label = new LabelStyle();
|
||||
//[SerializeField] private Emphasis m_Emphasis = new Emphasis();
|
||||
|
||||
public Vector3 runtimeStartPosition { get; internal set; }
|
||||
public Vector3 runtimeEndPosition { get; internal set; }
|
||||
public Vector3 runtimeCurrentEndPosition { get; internal set; }
|
||||
public ChartLabel runtimeLabel { get; internal set; }
|
||||
public double runtimeValue { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the marker, which will display as a label.
|
||||
/// 标线名称,将会作为文字显示。label的formatter可通过{b}显示名称,通过{c}显示数值。
|
||||
/// </summary>
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Name, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Special label types, are used to label maximum value, minimum value and so on.
|
||||
/// 特殊的标线类型,用于标注最大值最小值等。
|
||||
/// </summary>
|
||||
public MarkLineType type
|
||||
{
|
||||
get { return m_Type; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// From which dimension of data to calculate the maximum and minimum value and so on.
|
||||
/// 从哪个维度的数据计算最大最小值等。
|
||||
/// </summary>
|
||||
public int dimension
|
||||
{
|
||||
get { return m_Dimension; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Dimension, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The x coordinate relative to the origin, in pixels.
|
||||
/// 相对原点的 x 坐标,单位像素。当type为None时有效。
|
||||
/// </summary>
|
||||
public float xPosition
|
||||
{
|
||||
get { return m_XPosition; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_XPosition, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The y coordinate relative to the origin, in pixels.
|
||||
/// 相对原点的 y 坐标,单位像素。当type为None时有效。
|
||||
/// </summary>
|
||||
public float yPosition
|
||||
{
|
||||
get { return m_YPosition; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_YPosition, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The value specified on the X-axis. A value specified when the X-axis is the category axis represents the index of the category axis data, otherwise a specific value.
|
||||
/// X轴上的指定值。当X轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。
|
||||
/// </summary>
|
||||
public double xValue
|
||||
{
|
||||
get { return m_XValue; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_XValue, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// That's the value on the Y-axis. The value specified when the Y axis is the category axis represents the index of the category axis data, otherwise the specific value.
|
||||
/// Y轴上的指定值。当Y轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。
|
||||
/// </summary>
|
||||
public double yValue
|
||||
{
|
||||
get { return m_YValue; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_YValue, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Grouping. When the group is not 0, it means that this data is the starting point or end point of the marking line. Data consistent with the group form a marking line.
|
||||
/// 分组。当group不为0时,表示这个data是标线的起点或终点,group一致的data组成一条标线。
|
||||
/// </summary>
|
||||
public int group
|
||||
{
|
||||
get { return m_Group; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Group, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Is the origin of the coordinate system.
|
||||
/// 是否为坐标系原点。
|
||||
/// </summary>
|
||||
public bool zeroPosition
|
||||
{
|
||||
get { return m_ZeroPosition; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ZeroPosition, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The symbol of the start point of markline.
|
||||
/// 起始点的图形标记。
|
||||
/// </summary>
|
||||
public SymbolStyle startSymbol
|
||||
{
|
||||
get { return m_StartSymbol; }
|
||||
set { if (PropertyUtil.SetClass(ref m_StartSymbol, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The symbol of the end point of markline.
|
||||
/// 结束点的图形标记。
|
||||
/// </summary>
|
||||
public SymbolStyle endSymbol
|
||||
{
|
||||
get { return m_EndSymbol; }
|
||||
set { if (PropertyUtil.SetClass(ref m_EndSymbol, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The line style of markline.
|
||||
/// 标线样式。
|
||||
/// </summary>
|
||||
public LineStyle lineStyle
|
||||
{
|
||||
get { return m_LineStyle; }
|
||||
set { if (PropertyUtil.SetClass(ref m_LineStyle, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Text styles of label. You can set position to Start, Middle, and End to display text in different locations.
|
||||
/// 文本样式。可设置position为Start、Middle和End在不同的位置显示文本。
|
||||
/// </summary>
|
||||
public LabelStyle label
|
||||
{
|
||||
get { return m_Label; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Label, value)) SetVerticesDirty(); }
|
||||
}
|
||||
// public Emphasis emphasis
|
||||
// {
|
||||
// get { return m_Emphasis; }
|
||||
// set { if (PropertyUtil.SetClass(ref m_Emphasis, value)) SetVerticesDirty(); }
|
||||
// }
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Mark/MarkLine.cs.meta
Normal file
11
Runtime/Component/Mark/MarkLine.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e728b47a96c74b3f986d9abe3b03934
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
313
Runtime/Component/Mark/MarkLineHandler.cs
Normal file
313
Runtime/Component/Mark/MarkLineHandler.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class MarkLineHandler : MainComponentHandler<MarkLine>
|
||||
{
|
||||
private GameObject m_MarkLineLabelRoot;
|
||||
private bool m_RefreshLabel = false;
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
m_MarkLineLabelRoot = ChartHelper.AddObject("markline", chart.transform, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
m_MarkLineLabelRoot.hideFlags = chart.chartHideFlags;
|
||||
ChartHelper.HideAllObject(m_MarkLineLabelRoot);
|
||||
InitMarkLine(component);
|
||||
}
|
||||
|
||||
public override void DrawTop(VertexHelper vh)
|
||||
{
|
||||
DrawMarkLine(vh, component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (m_RefreshLabel)
|
||||
{
|
||||
m_RefreshLabel = false;
|
||||
var serie = chart.GetSerie(component.serieIndex);
|
||||
if (!serie.show || !component.show) return;
|
||||
foreach (var data in component.data)
|
||||
{
|
||||
if (data.runtimeLabel != null)
|
||||
{
|
||||
data.runtimeLabel.SetPosition(MarkLineHelper.GetLabelPosition(data));
|
||||
data.runtimeLabel.SetText(MarkLineHelper.GetFormatterContent(serie, data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitMarkLine(MarkLine markLine)
|
||||
{
|
||||
var serie = chart.GetSerie(markLine.serieIndex);
|
||||
if (!serie.show || !markLine.show) return;
|
||||
ResetTempMarkLineGroupData(markLine);
|
||||
var serieColor = (Color)chart.theme.GetColor(chart.GetLegendRealShowNameIndex(serie.serieName));
|
||||
if (m_TempGroupData.Count > 0)
|
||||
{
|
||||
foreach (var kv in m_TempGroupData)
|
||||
{
|
||||
if (kv.Value.Count >= 2)
|
||||
{
|
||||
var data = kv.Value[0];
|
||||
InitMarkLineLabel(serie, data, serieColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var data in markLine.data)
|
||||
{
|
||||
if (data.group != 0) continue;
|
||||
InitMarkLineLabel(serie, data, serieColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitMarkLineLabel(Serie serie, MarkLineData data, Color serieColor)
|
||||
{
|
||||
data.painter = chart.m_PainterTop;
|
||||
data.refreshComponent = delegate ()
|
||||
{
|
||||
var label = data.label;
|
||||
var textName = string.Format("markLine_{0}_{1}", serie.index, data.index);
|
||||
var color = !ChartHelper.IsClearColor(label.textStyle.color) ? label.textStyle.color : chart.theme.axis.textColor;
|
||||
var element = ChartHelper.AddSerieLabel(textName, m_MarkLineLabelRoot.transform, label.backgroundWidth,
|
||||
label.backgroundHeight, color, label.textStyle, chart.theme);
|
||||
var isAutoSize = label.backgroundWidth == 0 || label.backgroundHeight == 0;
|
||||
var item = ChartHelper.GetOrAddComponent<ChartLabel>(element);
|
||||
item.SetLabel(element, isAutoSize, label.paddingLeftRight, label.paddingTopBottom);
|
||||
item.SetIconActive(false);
|
||||
item.SetActive(data.label.show);
|
||||
item.SetPosition(MarkLineHelper.GetLabelPosition(data));
|
||||
item.SetText(MarkLineHelper.GetFormatterContent(serie, data));
|
||||
data.runtimeLabel = item;
|
||||
};
|
||||
data.refreshComponent();
|
||||
}
|
||||
|
||||
private Dictionary<int, List<MarkLineData>> m_TempGroupData = new Dictionary<int, List<MarkLineData>>();
|
||||
private void DrawMarkLine(VertexHelper vh, MarkLine markLine)
|
||||
{
|
||||
var serie = chart.GetSerie(markLine.serieIndex);
|
||||
if (!serie.show || !markLine.show) return;
|
||||
if (markLine.data.Count == 0) return;
|
||||
var yAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex);
|
||||
var xAxis = chart.GetChartComponent<XAxis>(serie.yAxisIndex);
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
var dataZoom = chart.GetDataZoomOfAxis(xAxis);
|
||||
var animation = markLine.animation;
|
||||
var showData = serie.GetDataList(dataZoom);
|
||||
var sp = Vector3.zero;
|
||||
var ep = Vector3.zero;
|
||||
var colorIndex = chart.GetLegendRealShowNameIndex(serie.serieName);
|
||||
var serieColor = SerieHelper.GetLineColor(serie, chart.theme, colorIndex, false);
|
||||
animation.InitProgress(0, 1f);
|
||||
ResetTempMarkLineGroupData(markLine);
|
||||
if (m_TempGroupData.Count > 0)
|
||||
{
|
||||
foreach (var kv in m_TempGroupData)
|
||||
{
|
||||
if (kv.Value.Count >= 2)
|
||||
{
|
||||
sp = GetSinglePos(xAxis, yAxis, grid, serie, dataZoom, kv.Value[0], showData.Count);
|
||||
ep = GetSinglePos(xAxis, yAxis, grid, serie, dataZoom, kv.Value[1], showData.Count);
|
||||
kv.Value[0].runtimeStartPosition = sp;
|
||||
kv.Value[1].runtimeEndPosition = ep;
|
||||
DrawMakLineData(vh, kv.Value[0], animation, serie, grid, serieColor, sp, ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var data in markLine.data)
|
||||
{
|
||||
if (data.group != 0) continue;
|
||||
switch (data.type)
|
||||
{
|
||||
case MarkLineType.Min:
|
||||
data.runtimeValue = SerieHelper.GetMinData(serie, data.dimension, dataZoom);
|
||||
GetStartEndPos(xAxis, yAxis, grid, data.runtimeValue, ref sp, ref ep);
|
||||
break;
|
||||
case MarkLineType.Max:
|
||||
data.runtimeValue = SerieHelper.GetMaxData(serie, data.dimension, dataZoom);
|
||||
GetStartEndPos(xAxis, yAxis, grid, data.runtimeValue, ref sp, ref ep);
|
||||
break;
|
||||
case MarkLineType.Average:
|
||||
data.runtimeValue = SerieHelper.GetAverageData(serie, data.dimension, dataZoom);
|
||||
GetStartEndPos(xAxis, yAxis, grid, data.runtimeValue, ref sp, ref ep);
|
||||
break;
|
||||
case MarkLineType.Median:
|
||||
data.runtimeValue = SerieHelper.GetMedianData(serie, data.dimension, dataZoom);
|
||||
GetStartEndPos(xAxis, yAxis, grid, data.runtimeValue, ref sp, ref ep);
|
||||
break;
|
||||
case MarkLineType.None:
|
||||
if (data.xPosition != 0)
|
||||
{
|
||||
data.runtimeValue = data.xPosition;
|
||||
var pX = grid.context.x + data.xPosition;
|
||||
sp = new Vector3(pX, grid.context.y);
|
||||
ep = new Vector3(pX, grid.context.y + grid.context.height);
|
||||
}
|
||||
else if (data.yPosition != 0)
|
||||
{
|
||||
data.runtimeValue = data.yPosition;
|
||||
var pY = grid.context.y + data.yPosition;
|
||||
sp = new Vector3(grid.context.x, pY);
|
||||
ep = new Vector3(grid.context.x + grid.context.width, pY);
|
||||
}
|
||||
else if (data.yValue != 0)
|
||||
{
|
||||
data.runtimeValue = data.yValue;
|
||||
if (yAxis.IsCategory())
|
||||
{
|
||||
var pY = AxisHelper.GetAxisPosition(grid, yAxis, data.yValue, showData.Count, dataZoom);
|
||||
sp = new Vector3(grid.context.x, pY);
|
||||
ep = new Vector3(grid.context.x + grid.context.width, pY);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetStartEndPos(xAxis, yAxis, grid, data.yValue, ref sp, ref ep);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data.runtimeValue = data.xValue;
|
||||
if (xAxis.IsCategory())
|
||||
{
|
||||
var pX = AxisHelper.GetAxisPosition(grid, xAxis, data.xValue, showData.Count, dataZoom);
|
||||
sp = new Vector3(pX, grid.context.y);
|
||||
ep = new Vector3(pX, grid.context.y + grid.context.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetStartEndPos(xAxis, yAxis, grid, data.xValue, ref sp, ref ep);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data.runtimeStartPosition = sp;
|
||||
data.runtimeEndPosition = ep;
|
||||
DrawMakLineData(vh, data, animation, serie, grid, serieColor, sp, ep);
|
||||
}
|
||||
if (!animation.IsFinish())
|
||||
{
|
||||
animation.CheckProgress(1f);
|
||||
chart.RefreshTopPainter();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetTempMarkLineGroupData(MarkLine markLine)
|
||||
{
|
||||
m_TempGroupData.Clear();
|
||||
for (int i = 0; i < markLine.data.Count; i++)
|
||||
{
|
||||
var data = markLine.data[i];
|
||||
data.index = i;
|
||||
if (data.group == 0) continue;
|
||||
if (!m_TempGroupData.ContainsKey(data.group))
|
||||
{
|
||||
m_TempGroupData[data.group] = new List<MarkLineData>();
|
||||
}
|
||||
m_TempGroupData[data.group].Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMakLineData(VertexHelper vh, MarkLineData data, AnimationStyle animation, Serie serie,
|
||||
GridCoord grid, Color32 serieColor, Vector3 sp, Vector3 ep)
|
||||
{
|
||||
if (!animation.IsFinish())
|
||||
ep = Vector3.Lerp(sp, ep, animation.GetCurrDetail());
|
||||
data.runtimeCurrentEndPosition = ep;
|
||||
if (sp != Vector3.zero || ep != Vector3.zero)
|
||||
{
|
||||
m_RefreshLabel = true;
|
||||
chart.ClampInChart(ref sp);
|
||||
chart.ClampInChart(ref ep);
|
||||
var theme = chart.theme.axis;
|
||||
var lineColor = ChartHelper.IsClearColor(data.lineStyle.color) ? serieColor : data.lineStyle.color;
|
||||
var lineWidth = data.lineStyle.width == 0 ? theme.lineWidth : data.lineStyle.width;
|
||||
ChartDrawer.DrawLineStyle(vh, data.lineStyle, sp, ep, lineWidth, LineStyle.Type.Dashed, lineColor, lineColor);
|
||||
if (data.startSymbol != null && data.startSymbol.show)
|
||||
{
|
||||
DrawMarkLineSymbol(vh, data.startSymbol, serie, grid, chart.theme, sp, sp, lineColor);
|
||||
}
|
||||
if (data.endSymbol != null && data.endSymbol.show)
|
||||
{
|
||||
DrawMarkLineSymbol(vh, data.endSymbol, serie, grid, chart.theme, ep, sp, lineColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMarkLineSymbol(VertexHelper vh, SymbolStyle symbol, Serie serie, GridCoord grid, ThemeStyle theme,
|
||||
Vector3 pos, Vector3 startPos, Color32 lineColor)
|
||||
{
|
||||
var symbolSize = symbol.GetSize(null, theme.serie.lineSymbolSize);
|
||||
var tickness = SerieHelper.GetSymbolBorder(serie, null, theme, false);
|
||||
var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, null, false);
|
||||
chart.DrawClipSymbol(vh, symbol.type, symbolSize, tickness, pos, lineColor, lineColor,
|
||||
ColorUtil.clearColor32, symbol.gap, true, cornerRadius, grid, startPos);
|
||||
}
|
||||
|
||||
private void GetStartEndPos(Axis xAxis, Axis yAxis, GridCoord grid, double value, ref Vector3 sp, ref Vector3 ep)
|
||||
{
|
||||
if (xAxis.IsCategory())
|
||||
{
|
||||
var pY = AxisHelper.GetAxisPosition(grid, yAxis, value);
|
||||
sp = new Vector3(grid.context.x, pY);
|
||||
ep = new Vector3(grid.context.x + grid.context.width, pY);
|
||||
}
|
||||
else
|
||||
{
|
||||
var pX = AxisHelper.GetAxisPosition(grid, xAxis, value);
|
||||
sp = new Vector3(pX, grid.context.y);
|
||||
ep = new Vector3(pX, grid.context.y + grid.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetAxisPosition(GridCoord grid, Axis axis, DataZoom dataZoom, int dataCount, double value)
|
||||
{
|
||||
return AxisHelper.GetAxisPosition(grid, axis, value, dataCount, dataZoom);
|
||||
}
|
||||
|
||||
private Vector3 GetSinglePos(Axis xAxis, Axis yAxis, GridCoord grid, Serie serie, DataZoom dataZoom, MarkLineData data,
|
||||
int serieDataCount)
|
||||
{
|
||||
switch (data.type)
|
||||
{
|
||||
case MarkLineType.Min:
|
||||
var serieData = SerieHelper.GetMinSerieData(serie, data.dimension, dataZoom);
|
||||
data.runtimeValue = serieData.GetData(data.dimension);
|
||||
var pX = GetAxisPosition(grid, xAxis, dataZoom, serieDataCount, serieData.index);
|
||||
var pY = GetAxisPosition(grid, yAxis, dataZoom, serieDataCount, data.runtimeValue);
|
||||
return new Vector3(pX, pY);
|
||||
case MarkLineType.Max:
|
||||
serieData = SerieHelper.GetMaxSerieData(serie, data.dimension, dataZoom);
|
||||
data.runtimeValue = serieData.GetData(data.dimension);
|
||||
pX = GetAxisPosition(grid, xAxis, dataZoom, serieDataCount, serieData.index);
|
||||
pY = GetAxisPosition(grid, yAxis, dataZoom, serieDataCount, data.runtimeValue);
|
||||
return new Vector3(pX, pY);
|
||||
case MarkLineType.None:
|
||||
if (data.zeroPosition)
|
||||
{
|
||||
data.runtimeValue = 0;
|
||||
return grid.context.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
pX = data.xPosition != 0 ? grid.context.x + data.xPosition :
|
||||
GetAxisPosition(grid, xAxis, dataZoom, serieDataCount, data.xValue);
|
||||
pY = data.yPosition != 0 ? grid.context.y + data.yPosition :
|
||||
GetAxisPosition(grid, yAxis, dataZoom, serieDataCount, data.yValue);
|
||||
data.runtimeValue = data.yValue;
|
||||
return new Vector3(pX, pY);
|
||||
}
|
||||
default:
|
||||
return grid.context.position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Mark/MarkLineHandler.cs.meta
Normal file
11
Runtime/Component/Mark/MarkLineHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: faa35bab8fc6e42d5b5d19731c1a20a0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
49
Runtime/Component/Mark/MarkLineHelper.cs
Normal file
49
Runtime/Component/Mark/MarkLineHelper.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
internal static class MarkLineHelper
|
||||
{
|
||||
public static string GetFormatterContent(Serie serie, MarkLineData data)
|
||||
{
|
||||
var serieLabel = data.label;
|
||||
var numericFormatter = serieLabel.numericFormatter;
|
||||
if (serieLabel.formatterFunction != null)
|
||||
{
|
||||
return serieLabel.formatterFunction(data.index, data.runtimeValue);
|
||||
}
|
||||
if (string.IsNullOrEmpty(serieLabel.formatter))
|
||||
return ChartCached.NumberToStr(data.runtimeValue, numericFormatter);
|
||||
else
|
||||
{
|
||||
var content = serieLabel.formatter;
|
||||
FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, data.runtimeValue,
|
||||
0, serie.serieName, data.name, data.name, Color.clear);
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector3 GetLabelPosition(MarkLineData data)
|
||||
{
|
||||
if (!data.label.show) return Vector3.zero;
|
||||
var dir = (data.runtimeEndPosition - data.runtimeStartPosition).normalized;
|
||||
var horizontal = Mathf.Abs(Vector3.Dot(dir, Vector3.right)) == 1;
|
||||
var labelWidth = data.runtimeLabel == null ? 50 : data.runtimeLabel.GetLabelWidth();
|
||||
var labelHeight = data.runtimeLabel == null ? 20 : data.runtimeLabel.GetLabelHeight();
|
||||
switch (data.label.position)
|
||||
{
|
||||
case LabelStyle.Position.Start:
|
||||
if (horizontal) return data.runtimeStartPosition + data.label.offset + labelWidth / 2 * Vector3.left;
|
||||
else return data.runtimeStartPosition + data.label.offset + labelHeight / 2 * Vector3.down;
|
||||
case LabelStyle.Position.Middle:
|
||||
var center = (data.runtimeStartPosition + data.runtimeCurrentEndPosition) / 2;
|
||||
if (horizontal) return center + data.label.offset + labelHeight / 2 * Vector3.up;
|
||||
else return center + data.label.offset + labelWidth / 2 * Vector3.right;
|
||||
default:
|
||||
if (horizontal) return data.runtimeCurrentEndPosition + data.label.offset + labelWidth / 2 * Vector3.right;
|
||||
else return data.runtimeCurrentEndPosition + data.label.offset + labelHeight / 2 * Vector3.up;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Mark/MarkLineHelper.cs.meta
Normal file
11
Runtime/Component/Mark/MarkLineHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b472a7e4755b74fb6a3ec2c410650833
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user