2019-10-22 04:09:04 +08:00
|
|
|
|
/******************************************/
|
|
|
|
|
|
/* */
|
|
|
|
|
|
/* Copyright (c) 2018 monitor1394 */
|
|
|
|
|
|
/* https://github.com/monitor1394 */
|
|
|
|
|
|
/* */
|
|
|
|
|
|
/******************************************/
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using UnityEngine;
|
2019-07-13 16:38:38 +08:00
|
|
|
|
using UnityEngine.UI;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
|
|
|
|
|
|
namespace XCharts
|
|
|
|
|
|
{
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The axis in rectangular coordinate.
|
|
|
|
|
|
/// 直角坐标系的坐标轴组件。
|
|
|
|
|
|
/// </summary>
|
2019-05-11 04:33:54 +08:00
|
|
|
|
[System.Serializable]
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public class Axis : MainComponent
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// the type of axis.
|
|
|
|
|
|
/// 坐标轴类型。
|
|
|
|
|
|
/// </summary>
|
2019-05-11 04:33:54 +08:00
|
|
|
|
public enum AxisType
|
|
|
|
|
|
{
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Numerical axis, suitable for continuous data.
|
2020-01-15 19:41:21 +08:00
|
|
|
|
/// 数值轴。适用于连续数据。
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// </summary>
|
2019-05-11 04:33:54 +08:00
|
|
|
|
Value,
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <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 设置类目数据。
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// </summary>
|
2020-01-15 19:41:21 +08:00
|
|
|
|
Category,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Log axis, suitable for log data.
|
|
|
|
|
|
/// 对数轴。适用于对数数据。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
Log
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// the type of axis min and max value.
|
|
|
|
|
|
/// 坐标轴最大最小刻度显示类型。
|
|
|
|
|
|
/// </summary>
|
2019-05-16 09:39:58 +08:00
|
|
|
|
public enum AxisMinMaxType
|
|
|
|
|
|
{
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 0 - maximum.
|
|
|
|
|
|
/// 0-最大值。
|
|
|
|
|
|
/// </summary>
|
2019-05-16 09:39:58 +08:00
|
|
|
|
Default,
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// minimum - maximum.
|
|
|
|
|
|
/// 最小值-最大值。
|
|
|
|
|
|
/// </summary>
|
2019-05-16 09:39:58 +08:00
|
|
|
|
MinMax,
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Customize the minimum and maximum.
|
|
|
|
|
|
/// 自定义最小值最大值。
|
|
|
|
|
|
/// </summary>
|
2019-05-16 09:39:58 +08:00
|
|
|
|
Custom
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-11 04:33:54 +08:00
|
|
|
|
[SerializeField] protected bool m_Show = true;
|
|
|
|
|
|
[SerializeField] protected AxisType m_Type;
|
2019-05-16 09:39:58 +08:00
|
|
|
|
[SerializeField] protected AxisMinMaxType m_MinMaxType;
|
2019-10-26 05:00:26 +08:00
|
|
|
|
[SerializeField] protected float m_Min;
|
|
|
|
|
|
[SerializeField] protected float m_Max;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
[SerializeField] protected int m_SplitNumber = 5;
|
2019-09-17 18:30:45 +08:00
|
|
|
|
[SerializeField] protected float m_Interval = 0;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
[SerializeField] protected bool m_BoundaryGap = true;
|
2019-09-29 07:37:53 +08:00
|
|
|
|
[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;
|
2020-03-29 15:46:01 +08:00
|
|
|
|
[SerializeField] protected int m_CeilRate = 0;
|
2020-04-18 08:19:17 +08:00
|
|
|
|
[SerializeField] protected bool m_Inverse = false;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
[SerializeField] protected List<string> m_Data = new List<string>();
|
2019-07-09 22:20:50 +08:00
|
|
|
|
[SerializeField] protected AxisLine m_AxisLine = AxisLine.defaultAxisLine;
|
2019-06-29 07:22:57 +08:00
|
|
|
|
[SerializeField] protected AxisName m_AxisName = AxisName.defaultAxisName;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
[SerializeField] protected AxisTick m_AxisTick = AxisTick.defaultTick;
|
2019-07-03 18:45:48 +08:00
|
|
|
|
[SerializeField] protected AxisLabel m_AxisLabel = AxisLabel.defaultAxisLabel;
|
2020-02-11 20:37:34 +08:00
|
|
|
|
[SerializeField] protected AxisSplitLine m_SplitLine = AxisSplitLine.defaultSplitLine;
|
2019-07-13 16:38:38 +08:00
|
|
|
|
[SerializeField] protected AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
|
2019-09-17 18:30:45 +08:00
|
|
|
|
[NonSerialized] private float m_ValueRange;
|
2019-10-09 02:37:05 +08:00
|
|
|
|
[NonSerialized] private bool m_NeedUpdateFilterData;
|
2019-09-17 18:30:45 +08:00
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Set this to false to prevent the axis from showing.
|
|
|
|
|
|
/// 是否显示坐标轴。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public bool show
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_Show; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_Show, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// the type of axis.
|
|
|
|
|
|
/// 坐标轴类型。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public AxisType type
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_Type; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_Type, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// the type of axis minmax.
|
|
|
|
|
|
/// 坐标轴刻度最大最小值显示类型。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public AxisMinMaxType minMaxType
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_MinMaxType; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_MinMaxType, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The minimun value of axis.
|
|
|
|
|
|
/// 设定的坐标轴刻度最小值,当minMaxType为Custom时有效。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public float min
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_Min; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_Min, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The maximum value of axis.
|
|
|
|
|
|
/// 设定的坐标轴刻度最大值,当minMaxType为Custom时有效。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public float max
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_Max; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_Max, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Number of segments that the axis is split into.
|
|
|
|
|
|
/// 坐标轴的分割段数。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public int splitNumber
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_SplitNumber; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
2019-09-17 18:30:45 +08:00
|
|
|
|
/// 强制设置坐标轴分割间隔。无法在类目轴中使用。
|
|
|
|
|
|
/// Compulsively set segmentation interval for axis.This is unavailable for category axis.
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public float interval
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_Interval; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_Interval, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2019-09-17 18:30:45 +08:00
|
|
|
|
/// <summary>
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// The boundary gap on both sides of a coordinate axis.
|
|
|
|
|
|
/// 坐标轴两边是否留白。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public bool boundaryGap
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_BoundaryGap; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_BoundaryGap, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <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>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public float logBase
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_LogBase; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_LogBase, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2020-01-15 19:41:21 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 对数轴是否以自然数 e 为底数,为 true 时 logBase 失效。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public bool logBaseE
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_LogBaseE; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_LogBaseE, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2020-01-15 19:41:21 +08:00
|
|
|
|
/// <summary>
|
2019-09-29 07:37:53 +08:00
|
|
|
|
/// 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>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public int maxCache
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_MaxCache; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_MaxCache, value < 0 ? 0 : value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
2019-09-29 07:37:53 +08:00
|
|
|
|
/// <summary>
|
2020-03-29 15:46:01 +08:00
|
|
|
|
/// 最大最小值向上取整的倍率。默认为0时自动计算。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int ceilRate
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_CeilRate; }
|
|
|
|
|
|
set { if (PropertyUtility.SetStruct(ref m_CeilRate, value < 0 ? 0 : value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
2020-04-18 08:19:17 +08:00
|
|
|
|
/// Whether the axis are reversed or not. Invalid in `Category` axis.
|
|
|
|
|
|
/// 是否反向坐标轴。在类目轴中无效。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool inverse
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_Inverse; }
|
|
|
|
|
|
set { if (m_Type == AxisType.Value && PropertyUtility.SetStruct(ref m_Inverse, value)) SetAllDirty(); }
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// Category data, available in type: 'Category' axis.
|
|
|
|
|
|
/// 类目数据,在类目轴(type: 'category')中有效。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public List<string> data
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_Data; }
|
|
|
|
|
|
set { if (value != null) { m_Data = value; SetAllDirty(); } }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// axis Line.
|
|
|
|
|
|
/// 坐标轴轴线。
|
2020-03-05 20:25:19 +08:00
|
|
|
|
/// /// </summary>
|
|
|
|
|
|
public AxisLine axisLine
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_AxisLine; }
|
|
|
|
|
|
set { if (value != null) { m_AxisLine = value; SetVerticesDirty(); } }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// axis name.
|
|
|
|
|
|
/// 坐标轴名称。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public AxisName axisName
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_AxisName; }
|
|
|
|
|
|
set { if (value != null) { m_AxisName = value; SetComponentDirty(); } }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// axis tick.
|
|
|
|
|
|
/// 坐标轴刻度。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public AxisTick axisTick
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_AxisTick; }
|
|
|
|
|
|
set { if (value != null) { m_AxisTick = value; SetVerticesDirty(); } }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// axis label.
|
|
|
|
|
|
/// 坐标轴刻度标签。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public AxisLabel axisLabel
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_AxisLabel; }
|
|
|
|
|
|
set { if (value != null) { m_AxisLabel = value; SetComponentDirty(); } }
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
2020-02-11 20:37:34 +08:00
|
|
|
|
/// axis split line.
|
|
|
|
|
|
/// 坐标轴分割线。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
public AxisSplitLine splitLine
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return m_SplitLine; }
|
|
|
|
|
|
set { if (value != null) { m_SplitLine = value; SetVerticesDirty(); } }
|
|
|
|
|
|
}
|
2020-02-11 20:37:34 +08:00
|
|
|
|
/// <summary>
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// axis split area.
|
|
|
|
|
|
/// 坐标轴分割区域。
|
|
|
|
|
|
/// </summary>
|
2020-03-05 20:25:19 +08:00
|
|
|
|
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();
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// the axis label text list.
|
|
|
|
|
|
/// 坐标轴刻度标签的Text列表。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public List<Text> 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
|
|
|
|
|
|
{
|
2020-02-23 11:06:16 +08:00
|
|
|
|
m_RuntimeMinValue = value;
|
|
|
|
|
|
m_RuntimeLastMinValue = value;
|
|
|
|
|
|
m_RuntimeMinValueUpdateTime = Time.time;
|
|
|
|
|
|
m_RuntimeMinValueChanged = true;
|
2019-11-30 21:24:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +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
|
|
|
|
|
|
{
|
2020-02-23 11:06:16 +08:00
|
|
|
|
m_RuntimeMaxValue = value;
|
|
|
|
|
|
m_RuntimeLastMaxValue = value;
|
|
|
|
|
|
m_RuntimeMaxValueUpdateTime = Time.time;
|
|
|
|
|
|
m_RuntimeMaxValueChanged = false;
|
2019-11-30 21:24:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// the x offset of zero position.
|
|
|
|
|
|
/// 坐标轴原点在X轴的偏移。
|
|
|
|
|
|
/// </summary>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
public float runtimeZeroXOffset { get; internal set; }
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// the y offset of zero position.
|
|
|
|
|
|
/// 坐标轴原点在Y轴的偏移。
|
|
|
|
|
|
/// </summary>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
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); } }
|
2020-04-18 08:19:17 +08:00
|
|
|
|
internal bool runtimeLastCheckInverse { get; set; }
|
2019-08-01 23:49:30 +08:00
|
|
|
|
private int filterStart;
|
|
|
|
|
|
private int filterEnd;
|
2019-12-21 20:00:58 +08:00
|
|
|
|
private int filterMinShow;
|
2019-08-01 23:49:30 +08:00
|
|
|
|
private List<string> filterData;
|
|
|
|
|
|
private List<Text> m_AxisLabelTextList = new List<Text>();
|
2019-07-13 16:38:38 +08:00
|
|
|
|
private GameObject m_TooltipLabel;
|
|
|
|
|
|
private Text m_TooltipLabelText;
|
|
|
|
|
|
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
|
|
|
|
|
2020-04-18 12:31:21 +08:00
|
|
|
|
public Axis Clone()
|
|
|
|
|
|
{
|
|
|
|
|
|
var axis = new Axis();
|
|
|
|
|
|
axis.show = show;
|
|
|
|
|
|
axis.type = type;
|
|
|
|
|
|
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;
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 清空类目数据
|
|
|
|
|
|
/// </summary>
|
2019-05-11 04:33:54 +08:00
|
|
|
|
public void ClearData()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_Data.Clear();
|
2020-03-05 20:25:19 +08:00
|
|
|
|
SetAllDirty();
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
2020-01-15 19:41:21 +08:00
|
|
|
|
/// 是否为类目轴。
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
2019-07-13 16:38:38 +08:00
|
|
|
|
public bool IsCategory()
|
|
|
|
|
|
{
|
|
|
|
|
|
return type == AxisType.Category;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
2020-01-15 19:41:21 +08:00
|
|
|
|
/// 是否为数值轴。
|
2019-08-01 23:49:30 +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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 添加一个类目到类目数据列表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="category"></param>
|
2019-09-29 07:37:53 +08:00
|
|
|
|
public void AddData(string category)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-09-29 07:37:53 +08:00
|
|
|
|
if (maxCache > 0)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-10-09 02:37:05 +08:00
|
|
|
|
while (m_Data.Count > maxCache)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_NeedUpdateFilterData = true;
|
|
|
|
|
|
m_Data.RemoveAt(0);
|
|
|
|
|
|
}
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
m_Data.Add(category);
|
2020-03-05 20:25:19 +08:00
|
|
|
|
SetAllDirty();
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获得在dataZoom范围内指定索引的类目数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="index">类目数据索引</param>
|
|
|
|
|
|
/// <param name="dataZoom">区域缩放</param>
|
|
|
|
|
|
/// <returns></returns>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal string GetData(int index, DataZoom dataZoom)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
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];
|
2019-05-11 04:33:54 +08:00
|
|
|
|
else
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获得指定区域缩放的类目数据列表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dataZoom">区域缩放</param>
|
|
|
|
|
|
/// <returns></returns>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal List<string> GetDataList(DataZoom dataZoom)
|
2019-06-13 09:53:03 +08:00
|
|
|
|
{
|
2019-10-09 02:37:05 +08:00
|
|
|
|
if (dataZoom != null && dataZoom.enable)
|
2019-06-13 09:53:03 +08:00
|
|
|
|
{
|
2019-10-09 02:37:05 +08:00
|
|
|
|
UpdateFilterData(dataZoom);
|
2019-06-13 09:53:03 +08:00
|
|
|
|
return filterData;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_Data;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-09 02:37:05 +08:00
|
|
|
|
private List<string> emptyFliter = new List<string>();
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 更新dataZoom对应的类目数据列表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dataZoom"></param>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal void UpdateFilterData(DataZoom dataZoom)
|
2019-06-13 09:53:03 +08:00
|
|
|
|
{
|
2019-10-09 02:37:05 +08:00
|
|
|
|
if (dataZoom != null && dataZoom.enable)
|
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);
|
2020-01-09 19:30:15 +08:00
|
|
|
|
if (endIndex < startIndex) endIndex = startIndex;
|
2019-12-21 20:00:58 +08:00
|
|
|
|
if (startIndex != filterStart || endIndex != filterEnd || dataZoom.minShowNum != filterMinShow || m_NeedUpdateFilterData)
|
2019-06-13 09:53:03 +08:00
|
|
|
|
{
|
|
|
|
|
|
filterStart = startIndex;
|
|
|
|
|
|
filterEnd = endIndex;
|
2019-12-21 20:00:58 +08:00
|
|
|
|
filterMinShow = dataZoom.minShowNum;
|
2019-10-09 02:37:05 +08:00
|
|
|
|
m_NeedUpdateFilterData = false;
|
2019-06-13 09:53:03 +08:00
|
|
|
|
if (m_Data.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
|
2020-01-09 19:30:15 +08:00
|
|
|
|
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
|
|
|
|
{
|
2019-10-09 02:37:05 +08:00
|
|
|
|
filterData = emptyFliter;
|
2019-06-13 09:53:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获得分割段数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dataZoom"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal int GetSplitNumber(float coordinateWid, DataZoom dataZoom)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-09-17 18:30:45 +08:00
|
|
|
|
if (type == AxisType.Value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_Interval > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (coordinateWid <= 0) return 0;
|
|
|
|
|
|
int num = Mathf.CeilToInt(m_ValueRange / m_Interval) + 1;
|
|
|
|
|
|
int maxNum = Mathf.CeilToInt(coordinateWid / 15);
|
|
|
|
|
|
if (num > maxNum)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_Interval = m_ValueRange / (maxNum - 1);
|
|
|
|
|
|
num = Mathf.CeilToInt(m_ValueRange / m_Interval) + 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
return num;
|
|
|
|
|
|
}
|
|
|
|
|
|
else return m_SplitNumber;
|
|
|
|
|
|
}
|
2020-01-15 19:41:21 +08:00
|
|
|
|
else if (type == AxisType.Log)
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_SplitNumber;
|
|
|
|
|
|
}
|
2019-07-15 00:24:04 +08:00
|
|
|
|
int dataCount = GetDataList(dataZoom).Count;
|
2019-09-27 19:17:11 +08:00
|
|
|
|
if (m_SplitNumber <= 0) return dataCount;
|
2019-06-13 09:53:03 +08:00
|
|
|
|
if (dataCount > 2 * m_SplitNumber || dataCount <= 0)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
return m_SplitNumber;
|
|
|
|
|
|
else
|
2019-06-13 09:53:03 +08:00
|
|
|
|
return dataCount;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获得分割段的宽度
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="coordinateWidth"></param>
|
|
|
|
|
|
/// <param name="dataZoom"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal float GetSplitWidth(float coordinateWidth, DataZoom dataZoom)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-09-17 18:30:45 +08:00
|
|
|
|
int split = GetSplitNumber(coordinateWidth, dataZoom);
|
2019-09-18 19:10:43 +08:00
|
|
|
|
int segment = (m_BoundaryGap ? split : split - 1);
|
|
|
|
|
|
segment = segment <= 0 ? 1 : segment;
|
|
|
|
|
|
return coordinateWidth / segment;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获得类目数据个数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dataZoom"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal int GetDataNumber(DataZoom dataZoom)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-07-15 00:24:04 +08:00
|
|
|
|
return GetDataList(dataZoom).Count;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获得一个类目数据在坐标系中代表的宽度
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="coordinateWidth"></param>
|
|
|
|
|
|
/// <param name="dataZoom"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal float GetDataWidth(float coordinateWidth, int dataCount, DataZoom dataZoom)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-10-26 05:26:55 +08:00
|
|
|
|
if (dataCount < 1) dataCount = 1;
|
|
|
|
|
|
var categoryCount = GetDataNumber(dataZoom);
|
|
|
|
|
|
int segment = (m_BoundaryGap ? categoryCount : categoryCount - 1);
|
|
|
|
|
|
segment = segment <= 0 ? dataCount : segment;
|
2019-09-18 19:10:43 +08:00
|
|
|
|
return coordinateWidth / segment;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获得标签显示的名称
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="index"></param>
|
|
|
|
|
|
/// <param name="minValue"></param>
|
|
|
|
|
|
/// <param name="maxValue"></param>
|
|
|
|
|
|
/// <param name="dataZoom"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal string GetLabelName(float coordinateWidth, int index, float minValue, float maxValue,
|
2019-10-18 06:48:24 +08:00
|
|
|
|
DataZoom dataZoom, bool forcePercent)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-09-17 18:30:45 +08:00
|
|
|
|
int split = GetSplitNumber(coordinateWidth, dataZoom);
|
2019-05-11 04:33:54 +08:00
|
|
|
|
if (m_Type == AxisType.Value)
|
|
|
|
|
|
{
|
2019-12-11 02:14:37 +08:00
|
|
|
|
if (minValue == 0 && maxValue == 0) return string.Empty;
|
2019-09-17 18:30:45 +08:00
|
|
|
|
float value = 0;
|
2019-10-18 06:48:24 +08:00
|
|
|
|
if (forcePercent) maxValue = 100;
|
2019-09-17 18:30:45 +08:00
|
|
|
|
if (m_Interval > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (index == split - 1) value = maxValue;
|
|
|
|
|
|
else value = minValue + index * m_Interval;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
value = (minValue + (maxValue - minValue) * index / (split - 1));
|
|
|
|
|
|
}
|
2020-04-18 08:19:17 +08:00
|
|
|
|
if (inverse)
|
|
|
|
|
|
{
|
|
|
|
|
|
value = -value;
|
|
|
|
|
|
minValue = -minValue;
|
|
|
|
|
|
maxValue = -maxValue;
|
|
|
|
|
|
}
|
2019-10-18 06:48:24 +08:00
|
|
|
|
if (forcePercent) return string.Format("{0}%", (int)value);
|
2019-10-26 05:00:26 +08:00
|
|
|
|
else return m_AxisLabel.GetFormatterContent(value, minValue, maxValue);
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
2020-01-15 19:41:21 +08:00
|
|
|
|
else if (m_Type == AxisType.Log)
|
|
|
|
|
|
{
|
|
|
|
|
|
float value = m_LogBaseE ? Mathf.Exp(runtimeMinLogIndex + index) :
|
|
|
|
|
|
Mathf.Pow(m_LogBase, runtimeMinLogIndex + index);
|
2020-04-18 08:19:17 +08:00
|
|
|
|
if (inverse)
|
|
|
|
|
|
{
|
|
|
|
|
|
value = -value;
|
|
|
|
|
|
minValue = -minValue;
|
|
|
|
|
|
maxValue = -maxValue;
|
|
|
|
|
|
}
|
2020-01-15 19:41:21 +08:00
|
|
|
|
return m_AxisLabel.GetFormatterContent(value, minValue, maxValue, true);
|
|
|
|
|
|
}
|
2019-07-15 00:24:04 +08:00
|
|
|
|
var showData = GetDataList(dataZoom);
|
2019-06-13 09:53:03 +08:00
|
|
|
|
int dataCount = showData.Count;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
if (dataCount <= 0) return "";
|
2019-06-13 09:53:03 +08:00
|
|
|
|
|
2019-09-17 18:30:45 +08:00
|
|
|
|
if (index == split - 1 && !m_BoundaryGap)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-09-23 19:09:56 +08:00
|
|
|
|
return m_AxisLabel.GetFormatterContent(showData[dataCount - 1]);
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2019-09-17 18:30:45 +08:00
|
|
|
|
float rate = dataCount / split;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
if (rate < 1) rate = 1;
|
|
|
|
|
|
int offset = m_BoundaryGap ? (int)(rate / 2) : 0;
|
2019-06-13 09:53:03 +08:00
|
|
|
|
int newIndex = (int)(index * rate >= dataCount - 1 ?
|
|
|
|
|
|
dataCount - 1 : offset + index * rate);
|
2019-09-23 19:09:56 +08:00
|
|
|
|
return m_AxisLabel.GetFormatterContent(showData[newIndex]);
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获得分割线条数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dataZoom"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal int GetScaleNumber(float coordinateWidth, DataZoom dataZoom)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2020-01-15 19:41:21 +08:00
|
|
|
|
if (type == AxisType.Value || type == AxisType.Log)
|
2019-05-14 05:24:13 +08:00
|
|
|
|
{
|
2019-09-17 18:30:45 +08:00
|
|
|
|
int splitNum = GetSplitNumber(coordinateWidth, dataZoom);
|
|
|
|
|
|
return m_BoundaryGap ? splitNum + 1 : splitNum;
|
2019-05-14 05:24:13 +08:00
|
|
|
|
}
|
2019-05-11 04:33:54 +08:00
|
|
|
|
else
|
2019-06-13 09:53:03 +08:00
|
|
|
|
{
|
2019-07-15 00:24:04 +08:00
|
|
|
|
var showData = GetDataList(dataZoom);
|
2019-06-13 09:53:03 +08:00
|
|
|
|
int dataCount = showData.Count;
|
2019-09-27 19:17:11 +08:00
|
|
|
|
if (m_SplitNumber <= 0) return m_BoundaryGap ? dataCount + 1 : dataCount;
|
2019-06-13 09:53:03 +08:00
|
|
|
|
if (dataCount > 2 * splitNumber || dataCount <= 0)
|
|
|
|
|
|
return m_BoundaryGap ? m_SplitNumber + 1 : m_SplitNumber;
|
|
|
|
|
|
else
|
|
|
|
|
|
return m_BoundaryGap ? dataCount + 1 : dataCount;
|
|
|
|
|
|
}
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获得分割段宽度
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="coordinateWidth"></param>
|
|
|
|
|
|
/// <param name="dataZoom"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal float GetScaleWidth(float coordinateWidth, int index, DataZoom dataZoom)
|
2019-05-11 04:33:54 +08:00
|
|
|
|
{
|
2019-09-17 18:30:45 +08:00
|
|
|
|
int num = GetScaleNumber(coordinateWidth, dataZoom) - 1;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
if (num <= 0) num = 1;
|
2019-09-17 18:30:45 +08:00
|
|
|
|
if (type == AxisType.Value && m_Interval > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (index == num - 1) return coordinateWidth - (num - 1) * m_Interval * coordinateWidth / m_ValueRange;
|
|
|
|
|
|
else return m_Interval * coordinateWidth / m_ValueRange;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return coordinateWidth / num;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-11 04:33:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <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)
|
|
|
|
|
|
{
|
2019-11-30 21:24:04 +08:00
|
|
|
|
axisLabelTextList[i].text = GetLabelName(coordinateWidth, i, minValue, maxValue, dataZoom, forcePercent);
|
2019-07-15 00:24:04 +08:00
|
|
|
|
}
|
2019-07-13 16:38:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal void SetTooltipLabel(GameObject label)
|
2019-07-13 16:38:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
m_TooltipLabel = label;
|
|
|
|
|
|
m_TooltipLabelRect = label.GetComponent<RectTransform>();
|
|
|
|
|
|
m_TooltipLabelText = label.GetComponentInChildren<Text>();
|
|
|
|
|
|
m_TooltipLabel.SetActive(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal void SetTooltipLabelColor(Color bgColor, Color textColor)
|
2019-07-13 16:38:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
m_TooltipLabel.GetComponent<Image>().color = bgColor;
|
|
|
|
|
|
m_TooltipLabelText.color = textColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal void SetTooltipLabelActive(bool flag)
|
2019-07-13 16:38:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (m_TooltipLabel && m_TooltipLabel.activeInHierarchy != flag)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_TooltipLabel.SetActive(flag);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal void UpdateTooptipLabelText(string text)
|
2019-07-13 16:38:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (m_TooltipLabelText)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_TooltipLabelText.text = text;
|
|
|
|
|
|
m_TooltipLabelRect.sizeDelta = new Vector2(m_TooltipLabelText.preferredWidth + 8,
|
|
|
|
|
|
m_TooltipLabelText.preferredHeight + 8);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-02 08:24:37 +08:00
|
|
|
|
internal void UpdateTooltipLabelPos(Vector2 pos)
|
2019-07-13 16:38:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (m_TooltipLabel)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_TooltipLabel.transform.localPosition = pos;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-26 05:26:55 +08:00
|
|
|
|
internal bool NeedShowSplit()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!show) return false;
|
|
|
|
|
|
if (IsCategory() && data.Count <= 0) return false;
|
2019-12-11 02:14:37 +08:00
|
|
|
|
else if (IsValue() && m_RuntimeMinValue == 0 && m_RuntimeMaxValue == 0) return false;
|
2019-10-26 05:26:55 +08:00
|
|
|
|
else return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 调整最大最小值
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="minValue"></param>
|
|
|
|
|
|
/// <param name="maxValue"></param>
|
2019-11-30 21:24:04 +08:00
|
|
|
|
internal void AdjustMinMaxValue(ref float minValue, ref float maxValue, bool needFormat)
|
2019-07-13 16:38:38 +08:00
|
|
|
|
{
|
2020-01-15 19:41:21 +08:00
|
|
|
|
if (m_Type == AxisType.Log)
|
|
|
|
|
|
{
|
|
|
|
|
|
int minSplit = 0;
|
|
|
|
|
|
int maxSplit = 0;
|
|
|
|
|
|
maxValue = ChartHelper.GetMaxLogValue(maxValue, m_LogBase, m_LogBaseE, out maxSplit);
|
|
|
|
|
|
minValue = ChartHelper.GetMinLogValue(minValue, m_LogBase, m_LogBaseE, out minSplit);
|
|
|
|
|
|
splitNumber = (minSplit > 0 && maxSplit > 0) ? (maxSplit + minSplit - 1) : (maxSplit + minSplit);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2019-07-13 16:38:38 +08:00
|
|
|
|
if (minMaxType == Axis.AxisMinMaxType.Custom)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (min != 0 || max != 0)
|
|
|
|
|
|
{
|
2020-04-18 08:19:17 +08:00
|
|
|
|
if (inverse)
|
|
|
|
|
|
{
|
|
|
|
|
|
minValue = -max;
|
|
|
|
|
|
maxValue = -min;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
minValue = min;
|
|
|
|
|
|
maxValue = max;
|
|
|
|
|
|
}
|
2019-07-13 16:38:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (minMaxType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Axis.AxisMinMaxType.Default:
|
2019-12-11 02:14:37 +08:00
|
|
|
|
if (minValue == 0 && maxValue == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (minValue > 0 && maxValue > 0)
|
2019-07-13 16:38:38 +08:00
|
|
|
|
{
|
2019-07-14 14:34:18 +08:00
|
|
|
|
minValue = 0;
|
2020-04-18 08:19:17 +08:00
|
|
|
|
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, m_CeilRate) : maxValue;
|
2019-07-13 16:38:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
else if (minValue < 0 && maxValue < 0)
|
|
|
|
|
|
{
|
2020-04-18 08:19:17 +08:00
|
|
|
|
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, m_CeilRate) : minValue;
|
2019-07-14 14:34:18 +08:00
|
|
|
|
maxValue = 0;
|
2019-07-13 16:38:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2020-04-18 08:19:17 +08:00
|
|
|
|
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, m_CeilRate) : minValue;
|
|
|
|
|
|
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, m_CeilRate) : maxValue;
|
2019-07-13 16:38:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case Axis.AxisMinMaxType.MinMax:
|
2020-04-18 08:19:17 +08:00
|
|
|
|
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, m_CeilRate) : minValue;
|
|
|
|
|
|
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, m_CeilRate) : maxValue;
|
2019-07-13 16:38:38 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-09-17 18:30:45 +08:00
|
|
|
|
m_ValueRange = maxValue - minValue;
|
2019-07-13 16:38:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-02-23 11:06:16 +08:00
|
|
|
|
internal void UpdateMinValue(float value, bool check)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (value != m_RuntimeMaxValue)
|
|
|
|
|
|
{
|
2020-03-05 20:25:19 +08:00
|
|
|
|
if (check && Application.isPlaying)
|
2020-02-23 11:06:16 +08:00
|
|
|
|
{
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2020-03-05 20:25:19 +08:00
|
|
|
|
if (check && Application.isPlaying)
|
2020-02-23 11:06:16 +08:00
|
|
|
|
{
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2020-03-05 20:25:19 +08:00
|
|
|
|
if (!Application.isPlaying) return m_RuntimeMinValue;
|
2019-12-11 02:14:37 +08:00
|
|
|
|
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;
|
2020-03-11 08:41:42 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2020-03-05 20:25:19 +08:00
|
|
|
|
if (!Application.isPlaying) return m_RuntimeMaxValue;
|
2019-12-11 02:14:37 +08:00
|
|
|
|
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;
|
2020-03-11 08:41:42 +08:00
|
|
|
|
if (time == 0) return m_RuntimeMaxValue;
|
2019-11-30 21:24:04 +08:00
|
|
|
|
var total = duration / 1000;
|
2020-03-11 08:41:42 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2020-03-05 20:25:19 +08:00
|
|
|
|
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) return 0;
|
|
|
|
|
|
return logBaseE ? Mathf.Log(value) : Mathf.Log(value, logBase);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-11 04:33:54 +08:00
|
|
|
|
public override void ParseJsonData(string jsonData)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(jsonData) || !m_DataFromJson) return;
|
|
|
|
|
|
m_Data = ChartHelper.ParseStringFromString(jsonData);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <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>
|
2019-05-11 04:33:54 +08:00
|
|
|
|
[System.Serializable]
|
|
|
|
|
|
public class XAxis : Axis
|
|
|
|
|
|
{
|
|
|
|
|
|
public static XAxis defaultXAxis
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
var axis = new XAxis
|
|
|
|
|
|
{
|
|
|
|
|
|
m_Show = true,
|
|
|
|
|
|
m_Type = AxisType.Category,
|
2019-05-16 09:39:58 +08:00
|
|
|
|
m_Min = 0,
|
|
|
|
|
|
m_Max = 0,
|
2019-05-11 04:33:54 +08:00
|
|
|
|
m_SplitNumber = 5,
|
|
|
|
|
|
m_BoundaryGap = true,
|
|
|
|
|
|
m_Data = new List<string>()
|
|
|
|
|
|
{
|
|
|
|
|
|
"x1","x2","x3","x4","x5"
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2020-02-11 20:37:34 +08:00
|
|
|
|
axis.splitLine.show = false;
|
|
|
|
|
|
axis.splitLine.lineStyle.type = LineStyle.Type.Dashed;
|
2020-01-26 22:34:57 +08:00
|
|
|
|
axis.axisLabel.textLimit.enable = true;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
return axis;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-01 23:49:30 +08:00
|
|
|
|
/// <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>
|
2019-05-11 04:33:54 +08:00
|
|
|
|
[System.Serializable]
|
|
|
|
|
|
public class YAxis : Axis
|
|
|
|
|
|
{
|
|
|
|
|
|
public static YAxis defaultYAxis
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
var axis = new YAxis
|
|
|
|
|
|
{
|
|
|
|
|
|
m_Show = true,
|
|
|
|
|
|
m_Type = AxisType.Value,
|
2019-05-16 09:39:58 +08:00
|
|
|
|
m_Min = 0,
|
|
|
|
|
|
m_Max = 0,
|
2019-05-11 04:33:54 +08:00
|
|
|
|
m_SplitNumber = 5,
|
|
|
|
|
|
m_BoundaryGap = false,
|
|
|
|
|
|
m_Data = new List<string>(5),
|
|
|
|
|
|
};
|
2020-02-11 20:37:34 +08:00
|
|
|
|
axis.splitLine.show = true;
|
|
|
|
|
|
axis.splitLine.lineStyle.type = LineStyle.Type.Dashed;
|
2020-01-26 22:34:57 +08:00
|
|
|
|
axis.axisLabel.textLimit.enable = false;
|
2019-05-11 04:33:54 +08:00
|
|
|
|
return axis;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|