Files
XCharts/Runtime/Component/Main/Axis.cs

965 lines
34 KiB
C#
Raw Normal View History

2021-01-11 08:54:28 +08:00
/************************************************/
/* */
/* Copyright (c) 2018 - 2021 monitor1394 */
/* https://github.com/monitor1394 */
/* */
/************************************************/
using System;
using System.Collections.Generic;
using UnityEngine;
2019-07-13 16:38:38 +08:00
using UnityEngine.UI;
namespace XCharts
{
/// <summary>
/// The axis in rectangular coordinate.
/// 直角坐标系的坐标轴组件。
/// </summary>
[System.Serializable]
public class Axis : MainComponent
{
/// <summary>
/// the type of axis.
/// 坐标轴类型。
/// </summary>
public enum AxisType
{
/// <summary>
/// Numerical axis, suitable for continuous data.
2020-01-15 19:41:21 +08:00
/// 数值轴。适用于连续数据。
/// </summary>
Value,
/// <summary>
/// Category axis, suitable for discrete category data. Data should only be set via data for this type.
2020-01-15 19:41:21 +08:00
/// 类目轴。适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。
/// </summary>
2020-01-15 19:41:21 +08:00
Category,
/// <summary>
/// Log axis, suitable for log data.
/// 对数轴。适用于对数数据。
/// </summary>
Log
}
/// <summary>
/// the type of axis min and max value.
/// 坐标轴最大最小刻度显示类型。
/// </summary>
public enum AxisMinMaxType
{
/// <summary>
/// 0 - maximum.
/// 0-最大值。
/// </summary>
Default,
/// <summary>
/// minimum - maximum.
/// 最小值-最大值。
/// </summary>
MinMax,
/// <summary>
/// Customize the minimum and maximum.
/// 自定义最小值最大值。
/// </summary>
Custom
}
2021-01-11 08:54:28 +08:00
/// <summary>
/// the position of axis in grid.
/// 坐标轴在Grid中的位置
/// </summary>
public enum AxisPosition
{
Left,
Right,
Bottom,
Top
}
[SerializeField] protected bool m_Show = true;
[SerializeField] protected AxisType m_Type;
[SerializeField] protected AxisMinMaxType m_MinMaxType;
2021-01-11 08:54:28 +08:00
[SerializeField] protected int m_GridIndex;
[SerializeField] protected int m_PolarIndex;
[SerializeField] protected AxisPosition m_Position;
[SerializeField] protected float m_Offset;
[SerializeField] protected float m_Min;
[SerializeField] protected float m_Max;
[SerializeField] protected int m_SplitNumber = 5;
[SerializeField] protected float m_Interval = 0;
[SerializeField] protected bool m_BoundaryGap = true;
[SerializeField] protected int m_MaxCache = 0;
2020-01-15 19:41:21 +08:00
[SerializeField] protected float m_LogBase = 10;
[SerializeField] protected bool m_LogBaseE = false;
[SerializeField] protected int m_CeilRate = 0;
[SerializeField] protected bool m_Inverse = false;
[SerializeField] private bool m_Clockwise = true;
[SerializeField] protected List<string> m_Data = new List<string>();
[SerializeField] protected AxisLine m_AxisLine = AxisLine.defaultAxisLine;
2019-06-29 07:22:57 +08:00
[SerializeField] protected AxisName m_AxisName = AxisName.defaultAxisName;
[SerializeField] protected AxisTick m_AxisTick = AxisTick.defaultTick;
[SerializeField] protected AxisLabel m_AxisLabel = AxisLabel.defaultAxisLabel;
[SerializeField] protected AxisSplitLine m_SplitLine = AxisSplitLine.defaultSplitLine;
2019-07-13 16:38:38 +08:00
[SerializeField] protected AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea;
2020-05-17 20:36:14 +08:00
[NonSerialized] private float m_MinMaxValueRange;
[NonSerialized] private bool m_NeedUpdateFilterData;
/// <summary>
2020-07-17 08:52:32 +08:00
/// Whether to show axis.
/// 是否显示坐标轴。
/// </summary>
public bool show
{
get { return m_Show; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetAllDirty(); }
}
/// <summary>
/// the type of axis.
/// 坐标轴类型。
/// </summary>
public AxisType type
{
get { return m_Type; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetAllDirty(); }
}
/// <summary>
/// the type of axis minmax.
/// 坐标轴刻度最大最小值显示类型。
/// </summary>
public AxisMinMaxType minMaxType
{
get { return m_MinMaxType; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_MinMaxType, value)) SetAllDirty(); }
}
/// <summary>
/// The index of the grid on which the axis are located, by default, is in the first grid.
/// 坐标轴所在的 grid 的索引,默认位于第一个 grid。
/// </summary>
public int gridIndex
{
get { return m_GridIndex; }
set { if (PropertyUtil.SetStruct(ref m_GridIndex, value)) SetAllDirty(); }
}
/// <summary>
/// The index of the polar on which the axis are located, by default, is in the first polar.
/// 坐标轴所在的 ploar 的索引,默认位于第一个 polar。
/// </summary>
public int polarIndex
{
get { return m_PolarIndex; }
set { if (PropertyUtil.SetStruct(ref m_PolarIndex, value)) SetAllDirty(); }
}
/// <summary>
/// the position of axis in grid.
/// 坐标轴在Grid中的位置。
/// </summary>
public AxisPosition position
{
get { return m_Position; }
set { if (PropertyUtil.SetStruct(ref m_Position, value)) SetAllDirty(); }
}
/// <summary>
/// the offset of axis from the default position. Useful when the same position has multiple axes.
/// 坐标轴相对默认位置的偏移。在相同position有多个坐标轴时有用。
/// </summary>
public float offset
{
get { return m_Offset; }
set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetAllDirty(); }
}
/// <summary>
2020-07-17 08:52:32 +08:00
/// The minimun value of axis.Valid when `minMaxType` is `Custom`
/// 设定的坐标轴刻度最小值当minMaxType为Custom时有效。
/// </summary>
public float min
{
get { return m_Min; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_Min, value)) SetAllDirty(); }
}
/// <summary>
2020-07-17 08:52:32 +08:00
/// The maximum value of axis.Valid when `minMaxType` is `Custom`
/// 设定的坐标轴刻度最大值当minMaxType为Custom时有效。
/// </summary>
public float max
{
get { return m_Max; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_Max, value)) SetAllDirty(); }
}
/// <summary>
/// Number of segments that the axis is split into.
/// 坐标轴的分割段数。
/// </summary>
public int splitNumber
{
get { return m_SplitNumber; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); }
}
/// <summary>
/// Compulsively set segmentation interval for axis.This is unavailable for category axis.
2020-07-17 08:52:32 +08:00
/// 强制设置坐标轴分割间隔。无法在类目轴中使用。
/// </summary>
public float interval
{
get { return m_Interval; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetAllDirty(); }
}
/// <summary>
2020-09-13 20:17:11 +08:00
/// The boundary gap on both sides of a coordinate axis, which is valid only for category axis with type: 'Category'.
/// 坐标轴两边是否留白。只对类目轴有效。
/// </summary>
public bool boundaryGap
{
2020-09-13 20:17:11 +08:00
get { return IsCategory() ? m_BoundaryGap : false; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_BoundaryGap, value)) SetAllDirty(); }
}
/// <summary>
2020-01-15 19:41:21 +08:00
/// Base of logarithm, which is valid only for numeric axes with type: 'Log'.
/// 对数轴的底数只在对数轴type:'Log')中有效。
/// </summary>
public float logBase
{
get { return m_LogBase; }
set
{
if (value <= 0 || value == 1) value = 10;
2021-01-11 08:54:28 +08:00
if (PropertyUtil.SetStruct(ref m_LogBase, value)) SetAllDirty();
}
}
2020-01-15 19:41:21 +08:00
/// <summary>
2020-07-17 08:52:32 +08:00
/// On the log axis, if base e is the natural number, and is true, logBase fails.
2020-01-15 19:41:21 +08:00
/// 对数轴是否以自然数 e 为底数,为 true 时 logBase 失效。
/// </summary>
public bool logBaseE
{
get { return m_LogBaseE; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_LogBaseE, value)) SetAllDirty(); }
}
2020-01-15 19:41:21 +08:00
/// <summary>
/// The max number of axis data cache.
/// The first data will be remove when the size of axis data is larger then maxCache.
/// 可缓存的最大数据量。默认为0没有限制大于0时超过指定值会移除旧数据再插入新数据。
/// </summary>
public int maxCache
{
get { return m_MaxCache; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_MaxCache, value < 0 ? 0 : value)) SetAllDirty(); }
}
/// <summary>
2020-07-17 08:52:32 +08:00
/// The ratio of maximum and minimum values rounded upward. The default is 0, which is automatically calculated.
/// 最大最小值向上取整的倍率。默认为0时自动计算。
/// </summary>
public int ceilRate
{
get { return m_CeilRate; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_CeilRate, value < 0 ? 0 : value)) SetAllDirty(); }
}
/// <summary>
/// Whether the axis are reversed or not. Invalid in `Category` axis.
/// 是否反向坐标轴。在类目轴中无效。
/// </summary>
public bool inverse
{
get { return m_Inverse; }
2021-01-11 08:54:28 +08:00
set { if (m_Type == AxisType.Value && PropertyUtil.SetStruct(ref m_Inverse, value)) SetAllDirty(); }
}
/// <summary>
/// Whether the positive position of axis is in clockwise. True for clockwise by default.
/// 刻度增长是否按顺时针,默认顺时针。
/// </summary>
public bool clockwise
{
get { return m_Clockwise; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_Clockwise, value)) SetAllDirty(); }
}
/// <summary>
/// Category data, available in type: 'Category' axis.
/// 类目数据在类目轴type: 'category')中有效。
/// </summary>
public List<string> data
{
get { return m_Data; }
set { if (value != null) { m_Data = value; SetAllDirty(); } }
}
/// <summary>
/// axis Line.
/// 坐标轴轴线。
/// /// </summary>
public AxisLine axisLine
{
get { return m_AxisLine; }
set { if (value != null) { m_AxisLine = value; SetVerticesDirty(); } }
}
/// <summary>
/// axis name.
/// 坐标轴名称。
/// </summary>
public AxisName axisName
{
get { return m_AxisName; }
set { if (value != null) { m_AxisName = value; SetComponentDirty(); } }
}
/// <summary>
/// axis tick.
/// 坐标轴刻度。
/// </summary>
public AxisTick axisTick
{
get { return m_AxisTick; }
set { if (value != null) { m_AxisTick = value; SetVerticesDirty(); } }
}
/// <summary>
/// axis label.
/// 坐标轴刻度标签。
/// </summary>
public AxisLabel axisLabel
{
get { return m_AxisLabel; }
set { if (value != null) { m_AxisLabel = value; SetComponentDirty(); } }
}
/// <summary>
/// axis split line.
/// 坐标轴分割线。
/// </summary>
public AxisSplitLine splitLine
{
get { return m_SplitLine; }
set { if (value != null) { m_SplitLine = value; SetVerticesDirty(); } }
}
/// <summary>
/// axis split area.
/// 坐标轴分割区域。
/// </summary>
public AxisSplitArea splitArea
{
get { return m_SplitArea; }
set { if (value != null) { m_SplitArea = value; SetVerticesDirty(); } }
}
public override bool vertsDirty
{
get { return m_VertsDirty || axisLine.anyDirty || axisTick.anyDirty || splitLine.anyDirty || splitArea.anyDirty; }
}
public override bool componentDirty
{
get { return m_ComponentDirty || axisName.anyDirty || axisLabel.anyDirty; }
}
internal override void ClearComponentDirty()
{
base.ClearComponentDirty();
axisName.ClearComponentDirty();
axisLabel.ClearComponentDirty();
}
internal override void ClearVerticesDirty()
{
base.ClearVerticesDirty();
axisLine.ClearVerticesDirty();
axisTick.ClearVerticesDirty();
splitLine.ClearVerticesDirty();
splitArea.ClearVerticesDirty();
}
public int index { get; internal set; }
/// <summary>
/// the axis label text list.
/// 坐标轴刻度标签的Text列表。
/// </summary>
2021-01-11 08:54:28 +08:00
public List<ChartText> axisLabelTextList { get { return m_AxisLabelTextList; } set { m_AxisLabelTextList = value; } }
/// <summary>
/// the current minimun value.
/// 当前最小值。
/// </summary>
2019-11-30 21:24:04 +08:00
public float runtimeMinValue
{
get { return m_RuntimeMinValue; }
internal set
{
m_RuntimeMinValue = value;
m_RuntimeLastMinValue = value;
m_RuntimeMinValueUpdateTime = Time.time;
m_RuntimeMinValueChanged = true;
2019-11-30 21:24:04 +08:00
}
}
/// <summary>
/// the current maximum value.
/// 当前最大值。
/// </summary>
2019-11-30 21:24:04 +08:00
public float runtimeMaxValue
{
get { return m_RuntimeMaxValue; }
internal set
{
m_RuntimeMaxValue = value;
m_RuntimeLastMaxValue = value;
m_RuntimeMaxValueUpdateTime = Time.time;
m_RuntimeMaxValueChanged = false;
2019-11-30 21:24:04 +08:00
}
}
/// <summary>
/// the x offset of zero position.
/// 坐标轴原点在X轴的偏移。
/// </summary>
public float runtimeZeroXOffset { get; internal set; }
/// <summary>
/// the y offset of zero position.
/// 坐标轴原点在Y轴的偏移。
/// </summary>
public float runtimeZeroYOffset { get; internal set; }
2020-01-15 19:41:21 +08:00
public int runtimeMinLogIndex { get { return logBaseE ? (int)Mathf.Log(runtimeMinValue) : (int)Mathf.Log(runtimeMinValue, logBase); } }
public int runtimeMaxLogIndex { get { return logBaseE ? (int)Mathf.Log(runtimeMaxValue) : (int)Mathf.Log(runtimeMaxValue, logBase); } }
internal bool runtimeLastCheckInverse { get; set; }
2020-05-17 20:36:14 +08:00
internal float runtimeMinMaxRange { get { return m_MinMaxValueRange; } set { m_MinMaxValueRange = value; } }
private int filterStart;
private int filterEnd;
private int filterMinShow;
private List<string> filterData;
2021-01-11 08:54:28 +08:00
private List<ChartText> m_AxisLabelTextList = new List<ChartText>();
2019-07-13 16:38:38 +08:00
private GameObject m_TooltipLabel;
2021-01-11 08:54:28 +08:00
private ChartText m_TooltipLabelText;
2019-07-13 16:38:38 +08:00
private RectTransform m_TooltipLabelRect;
2019-11-30 21:24:04 +08:00
private float m_RuntimeMinValue;
private float m_RuntimeLastMinValue;
private bool m_RuntimeMinValueChanged;
private float m_RuntimeMinValueUpdateTime;
private float m_RuntimeMaxValue;
private float m_RuntimeLastMaxValue;
private bool m_RuntimeMaxValueChanged;
private float m_RuntimeMaxValueUpdateTime;
private bool m_RuntimeMinValueFirstChanged = true;
private bool m_RuntimeMaxValueFirstChanged = true;
2019-07-13 16:38:38 +08:00
public Axis Clone()
{
var axis = new Axis();
axis.show = show;
axis.type = type;
2021-01-11 08:54:28 +08:00
axis.gridIndex = 0;
axis.minMaxType = minMaxType;
axis.min = min;
axis.max = max;
axis.splitNumber = splitNumber;
axis.interval = interval;
axis.boundaryGap = boundaryGap;
axis.maxCache = maxCache;
axis.logBase = logBase;
axis.logBaseE = logBaseE;
axis.ceilRate = ceilRate;
axis.axisLine = axisLine.Clone();
axis.axisName = axisName.Clone();
axis.axisTick = axisTick.Clone();
axis.axisLabel = axisLabel.Clone();
axis.splitLine = splitLine.Clone();
axis.splitArea = splitArea.Clone();
axis.data = new List<string>();
ChartHelper.CopyList(axis.data, data);
return axis;
}
public void Copy(Axis axis)
{
show = axis.show;
type = axis.type;
minMaxType = axis.minMaxType;
2021-01-11 08:54:28 +08:00
gridIndex = axis.gridIndex;
min = axis.min;
max = axis.max;
splitNumber = axis.splitNumber;
interval = axis.interval;
boundaryGap = axis.boundaryGap;
maxCache = axis.maxCache;
logBase = axis.logBase;
logBaseE = axis.logBaseE;
ceilRate = axis.ceilRate;
axisLine.Copy(axis.axisLine);
axisName.Copy(axis.axisName);
axisTick.Copy(axis.axisTick);
axisLabel.Copy(axis.axisLabel);
splitLine.Copy(axis.splitLine);
splitArea.Copy(axis.splitArea);
ChartHelper.CopyList(data, axis.data);
}
/// <summary>
/// 清空类目数据
/// </summary>
public void ClearData()
{
m_Data.Clear();
SetAllDirty();
}
/// <summary>
2020-01-15 19:41:21 +08:00
/// 是否为类目轴。
/// </summary>
/// <returns></returns>
2019-07-13 16:38:38 +08:00
public bool IsCategory()
{
return type == AxisType.Category;
}
/// <summary>
2020-01-15 19:41:21 +08:00
/// 是否为数值轴。
/// </summary>
/// <returns></returns>
2019-07-13 16:38:38 +08:00
public bool IsValue()
{
return type == AxisType.Value;
}
2020-01-15 19:41:21 +08:00
/// <summary>
/// 是否为对数轴。
/// </summary>
/// <returns></returns>
public bool IsLog()
{
return type == AxisType.Log;
}
/// <summary>
/// 添加一个类目到类目数据列表
/// </summary>
/// <param name="category"></param>
public void AddData(string category)
{
if (maxCache > 0)
{
while (m_Data.Count > maxCache)
{
m_NeedUpdateFilterData = true;
m_Data.RemoveAt(0);
}
}
m_Data.Add(category);
SetAllDirty();
}
2020-05-17 20:36:14 +08:00
/// <summary>
/// 获得指定索引的类目数据
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public string GetData(int index)
{
if (index >= 0 && index < m_Data.Count)
return m_Data[index];
else
return null;
}
/// <summary>
/// 获得在dataZoom范围内指定索引的类目数据
/// </summary>
/// <param name="index">类目数据索引</param>
/// <param name="dataZoom">区域缩放</param>
/// <returns></returns>
2020-05-17 20:36:14 +08:00
public string GetData(int index, DataZoom dataZoom)
{
2019-07-15 00:24:04 +08:00
var showData = GetDataList(dataZoom);
2019-06-13 09:53:03 +08:00
if (index >= 0 && index < showData.Count)
return showData[index];
else
return "";
}
/// <summary>
/// 获得指定区域缩放的类目数据列表
/// </summary>
/// <param name="dataZoom">区域缩放</param>
/// <returns></returns>
internal List<string> GetDataList(DataZoom dataZoom)
2019-06-13 09:53:03 +08:00
{
2021-01-11 08:54:28 +08:00
if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxisIndex(index))
2019-06-13 09:53:03 +08:00
{
UpdateFilterData(dataZoom);
2019-06-13 09:53:03 +08:00
return filterData;
}
else
{
return m_Data;
}
}
private List<string> emptyFliter = new List<string>();
/// <summary>
/// 更新dataZoom对应的类目数据列表
/// </summary>
/// <param name="dataZoom"></param>
internal void UpdateFilterData(DataZoom dataZoom)
2019-06-13 09:53:03 +08:00
{
2021-01-11 08:54:28 +08:00
if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxisIndex(index))
2019-06-13 09:53:03 +08:00
{
var startIndex = (int)((data.Count - 1) * dataZoom.start / 100);
var endIndex = (int)((data.Count - 1) * dataZoom.end / 100);
if (endIndex < startIndex) endIndex = startIndex;
if (startIndex != filterStart || endIndex != filterEnd || dataZoom.minShowNum != filterMinShow || m_NeedUpdateFilterData)
2019-06-13 09:53:03 +08:00
{
filterStart = startIndex;
filterEnd = endIndex;
filterMinShow = dataZoom.minShowNum;
m_NeedUpdateFilterData = false;
2019-06-13 09:53:03 +08:00
if (m_Data.Count > 0)
{
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
if (count < dataZoom.minShowNum)
{
if (dataZoom.minShowNum > m_Data.Count) count = m_Data.Count;
else count = dataZoom.minShowNum;
}
if (startIndex + count > m_Data.Count)
{
int start = endIndex - count;
filterData = m_Data.GetRange(start < 0 ? 0 : start, count);
}
else filterData = m_Data.GetRange(startIndex, count);
2019-06-13 09:53:03 +08:00
}
else
{
filterData = m_Data;
}
}
2019-06-21 09:34:33 +08:00
else if (endIndex == 0)
2019-06-13 09:53:03 +08:00
{
filterData = emptyFliter;
2019-06-13 09:53:03 +08:00
}
}
}
/// <summary>
/// 获得类目数据个数
/// </summary>
/// <param name="dataZoom"></param>
/// <returns></returns>
internal int GetDataNumber(DataZoom dataZoom)
{
2019-07-15 00:24:04 +08:00
return GetDataList(dataZoom).Count;
}
/// <summary>
/// 更新刻度标签文字
/// </summary>
/// <param name="dataZoom"></param>
2019-11-30 21:24:04 +08:00
internal void UpdateLabelText(float coordinateWidth, DataZoom dataZoom, bool forcePercent, float duration)
2019-07-13 16:38:38 +08:00
{
2019-11-30 21:24:04 +08:00
var minValue = GetCurrMinValue(duration);
var maxValue = GetCurrMaxValue(duration);
2019-07-13 16:38:38 +08:00
for (int i = 0; i < axisLabelTextList.Count; i++)
{
2019-07-15 00:24:04 +08:00
if (axisLabelTextList[i] != null)
{
2020-05-17 20:36:14 +08:00
var text = AxisHelper.GetLabelName(this, coordinateWidth, i, minValue, maxValue, dataZoom, forcePercent);
2021-01-11 08:54:28 +08:00
axisLabelTextList[i].SetText(text);
2019-07-15 00:24:04 +08:00
}
2019-07-13 16:38:38 +08:00
}
}
internal void SetTooltipLabel(GameObject label)
2019-07-13 16:38:38 +08:00
{
m_TooltipLabel = label;
m_TooltipLabelRect = label.GetComponent<RectTransform>();
2021-01-11 08:54:28 +08:00
m_TooltipLabelText = new ChartText(label);
2020-05-09 09:42:41 +08:00
ChartHelper.SetActive(m_TooltipLabel, true);
2019-07-13 16:38:38 +08:00
}
internal void SetTooltipLabelColor(Color bgColor, Color textColor)
2019-07-13 16:38:38 +08:00
{
m_TooltipLabel.GetComponent<Image>().color = bgColor;
2021-01-11 08:54:28 +08:00
m_TooltipLabelText.SetColor(textColor);
2019-07-13 16:38:38 +08:00
}
internal void SetTooltipLabelActive(bool flag)
2019-07-13 16:38:38 +08:00
{
2021-01-11 08:54:28 +08:00
ChartHelper.SetActive(m_TooltipLabel, flag);
2019-07-13 16:38:38 +08:00
}
internal void UpdateTooptipLabelText(string text)
2019-07-13 16:38:38 +08:00
{
2021-01-11 08:54:28 +08:00
if (m_TooltipLabelText != null)
2019-07-13 16:38:38 +08:00
{
2021-01-11 08:54:28 +08:00
m_TooltipLabelText.SetText(text);
m_TooltipLabelRect.sizeDelta = new Vector2(m_TooltipLabelText.GetPreferredWidth() + 8,
m_TooltipLabelText.GetPreferredHeight() + 8);
2019-07-13 16:38:38 +08:00
}
}
internal void UpdateTooltipLabelPos(Vector2 pos)
2019-07-13 16:38:38 +08:00
{
if (m_TooltipLabel)
{
m_TooltipLabel.transform.localPosition = pos;
}
}
internal void UpdateMinValue(float value, bool check)
{
if (value != m_RuntimeMaxValue)
{
if (check && Application.isPlaying)
{
if (m_RuntimeMinValueFirstChanged)
{
m_RuntimeMinValueFirstChanged = false;
}
else
{
m_RuntimeLastMinValue = m_RuntimeMinValue;
m_RuntimeMinValueChanged = true;
m_RuntimeMinValueUpdateTime = Time.time;
}
m_RuntimeMinValue = value;
}
else
{
m_RuntimeMinValue = value;
m_RuntimeLastMinValue = value;
m_RuntimeMinValueUpdateTime = Time.time;
m_RuntimeMinValueChanged = true;
}
}
}
internal void UpdateMaxValue(float value, bool check)
{
if (value != m_RuntimeMaxValue)
{
if (check && Application.isPlaying)
{
if (m_RuntimeMaxValueFirstChanged)
{
m_RuntimeMaxValueFirstChanged = false;
}
else
{
m_RuntimeLastMaxValue = m_RuntimeMaxValue;
m_RuntimeMaxValueChanged = true;
m_RuntimeMaxValueUpdateTime = Time.time;
}
m_RuntimeMaxValue = value;
}
else
{
m_RuntimeMaxValue = value;
m_RuntimeLastMaxValue = value;
m_RuntimeMaxValueUpdateTime = Time.time;
m_RuntimeMaxValueChanged = false;
}
}
}
2019-11-30 21:24:04 +08:00
internal float GetCurrMinValue(float duration)
{
if (!Application.isPlaying) return m_RuntimeMinValue;
if (m_RuntimeMinValue == 0 && m_RuntimeMaxValue == 0) return 0;
2019-11-30 21:24:04 +08:00
if (!m_RuntimeMinValueChanged) return m_RuntimeMinValue;
var time = Time.time - m_RuntimeMinValueUpdateTime;
if (time == 0) return m_RuntimeMinValue;
2019-11-30 21:24:04 +08:00
var total = duration / 1000;
if (duration > 0 && time <= total)
{
var curr = Mathf.Lerp(m_RuntimeLastMinValue, m_RuntimeMinValue, time / total);
return curr;
}
else
{
m_RuntimeMinValueChanged = false;
return m_RuntimeMinValue;
}
}
internal float GetCurrMaxValue(float duration)
{
if (!Application.isPlaying) return m_RuntimeMaxValue;
if (m_RuntimeMinValue == 0 && m_RuntimeMaxValue == 0) return 0;
2019-11-30 21:24:04 +08:00
if (!m_RuntimeMaxValueChanged) return m_RuntimeMaxValue;
var time = Time.time - m_RuntimeMaxValueUpdateTime;
if (time == 0) return m_RuntimeMaxValue;
2019-11-30 21:24:04 +08:00
var total = duration / 1000;
if (duration > 0 && time < total)
2019-11-30 21:24:04 +08:00
{
var curr = Mathf.Lerp(m_RuntimeLastMaxValue, m_RuntimeMaxValue, time / total);
return curr;
}
else
{
m_RuntimeMaxValueChanged = false;
return m_RuntimeMaxValue;
}
}
public bool IsValueChanging(float duration)
{
if (!Application.isPlaying) return false;
2019-11-30 21:24:04 +08:00
if (GetCurrMinValue(duration) != m_RuntimeMinValue || GetCurrMaxValue(duration) != m_RuntimeMaxValue)
{
return true;
}
else
{
return false;
}
}
2020-01-15 19:41:21 +08:00
public float GetLogValue(float value)
{
if (value <= 0 || value == 1) return 0;
2020-01-15 19:41:21 +08:00
return logBaseE ? Mathf.Log(value) : Mathf.Log(value, logBase);
}
2021-01-11 08:54:28 +08:00
public bool IsLeft()
{
return position == AxisPosition.Left;
}
public bool IsRight()
{
return position == AxisPosition.Right;
}
public bool IsTop()
{
return position == AxisPosition.Top;
}
public bool IsBottom()
{
2021-01-11 08:54:28 +08:00
return position == AxisPosition.Bottom;
}
}
/// <summary>
/// The x axis in cartesian(rectangular) coordinate. a grid component can place at most 2 x axis,
/// one on the bottom and another on the top.
/// <para>直角坐标系 grid 中的 x 轴,单个 grid 组件最多只能放上下两个 x 轴。</para>
/// </summary>
[System.Serializable]
public class XAxis : Axis
{
public static XAxis defaultXAxis
{
get
{
var axis = new XAxis
{
m_Show = true,
m_Type = AxisType.Category,
m_Min = 0,
m_Max = 0,
m_SplitNumber = 5,
m_BoundaryGap = true,
2021-01-11 08:54:28 +08:00
m_Position = AxisPosition.Bottom,
m_Offset = 0,
m_Data = new List<string>()
{
"x1","x2","x3","x4","x5"
}
};
axis.splitLine.show = false;
2021-01-11 08:54:28 +08:00
axis.splitLine.lineStyle.type = LineStyle.Type.None;
axis.axisLabel.textLimit.enable = true;
return axis;
}
}
}
/// <summary>
/// The x axis in cartesian(rectangular) coordinate. a grid component can place at most 2 x axis,
/// one on the bottom and another on the top.
/// <para>直角坐标系 grid 中的 y 轴,单个 grid 组件最多只能放左右两个 y 轴</para>
/// </summary>
[System.Serializable]
public class YAxis : Axis
{
public static YAxis defaultYAxis
{
get
{
var axis = new YAxis
{
m_Show = true,
m_Type = AxisType.Value,
m_Min = 0,
m_Max = 0,
m_SplitNumber = 5,
m_BoundaryGap = false,
2021-01-11 08:54:28 +08:00
m_Position = AxisPosition.Left,
m_Data = new List<string>(5),
};
axis.splitLine.show = true;
2021-01-11 08:54:28 +08:00
axis.splitLine.lineStyle.type = LineStyle.Type.None;
axis.axisLabel.textLimit.enable = false;
return axis;
}
}
}
2020-07-01 09:38:00 +08:00
/// <summary>
/// Radial axis of polar coordinate.
/// 极坐标系的径向轴。
/// </summary>
[System.Serializable]
public class RadiusAxis : Axis
{
public static RadiusAxis defaultRadiusAxis
{
get
{
var axis = new RadiusAxis
{
m_Show = true,
m_Type = AxisType.Value,
m_Min = 0,
m_Max = 0,
m_SplitNumber = 5,
m_BoundaryGap = false,
m_Data = new List<string>(5),
};
axis.splitLine.show = true;
axis.splitLine.lineStyle.type = LineStyle.Type.Solid;
axis.axisLabel.textLimit.enable = false;
return axis;
}
}
}
/// <summary>
/// Angle axis of Polar Coordinate.
/// 极坐标系的角度轴。
/// </summary>
[System.Serializable]
public class AngleAxis : Axis
{
[SerializeField] private float m_StartAngle = 90;
2020-07-02 09:44:25 +08:00
2020-07-01 09:38:00 +08:00
/// <summary>
/// Starting angle of axis. 90 degrees by default, standing for top position of center. 0 degree stands for right position of center.
/// 起始刻度的角度,默认为 90 度即圆心的正上方。0 度为圆心的正右方。
/// </summary>
public float startAngle
{
get { return m_StartAngle; }
2021-01-11 08:54:28 +08:00
set { if (PropertyUtil.SetStruct(ref m_StartAngle, value)) SetAllDirty(); }
2020-07-01 09:38:00 +08:00
}
2020-07-02 09:44:25 +08:00
2020-07-01 09:38:00 +08:00
public float runtimeStartAngle { get; set; }
public static AngleAxis defaultAngleAxis
{
get
{
var axis = new AngleAxis
{
m_Show = true,
m_Type = AxisType.Value,
2021-01-11 08:54:28 +08:00
m_SplitNumber = 12,
2020-07-01 09:38:00 +08:00
m_BoundaryGap = false,
2021-01-11 08:54:28 +08:00
m_Data = new List<string>(12),
2020-07-01 09:38:00 +08:00
};
axis.splitLine.show = true;
axis.splitLine.lineStyle.type = LineStyle.Type.Solid;
axis.axisLabel.textLimit.enable = false;
axis.minMaxType = AxisMinMaxType.Custom;
axis.min = 0;
axis.max = 360;
return axis;
}
}
}
}