mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-23 09:20:08 +00:00
3.0 - unitypackage
This commit is contained in:
8
Runtime/Chart.meta
Normal file
8
Runtime/Chart.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 900b05585ba864df1aa05dcdb36b324b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
33
Runtime/Chart/BarChart.cs
Normal file
33
Runtime/Chart/BarChart.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/BarChart", 14)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public partial class BarChart : BaseChart
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Shadow;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
Bar.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/BarChart.cs.meta
Normal file
11
Runtime/Chart/BarChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 535d2697503c2a94a887354e22a5414d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
460
Runtime/Chart/BaseChart_API.cs
Normal file
460
Runtime/Chart/BaseChart_API.cs
Normal file
@@ -0,0 +1,460 @@
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class of all charts.
|
||||
/// 所有Chart的基类。
|
||||
/// </summary>
|
||||
public partial class BaseChart
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of chart.
|
||||
/// </summary>
|
||||
public string chartName
|
||||
{
|
||||
get { return m_ChartName; }
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value) && XChartsMgr.ContainsChart(value))
|
||||
{
|
||||
Debug.LogError("chartName repeated:" + value);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ChartName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The theme.
|
||||
/// </summary>
|
||||
public ThemeStyle theme { get { return m_Theme; } set { m_Theme = value; } }
|
||||
/// <summary>
|
||||
/// Global parameter setting component.
|
||||
/// 全局设置组件。
|
||||
/// </summary>
|
||||
public Settings settings { get { return m_Settings; } }
|
||||
/// <summary>
|
||||
/// The x of chart.
|
||||
/// 图表的X
|
||||
/// </summary>
|
||||
public float chartX { get { return m_ChartX; } }
|
||||
/// <summary>
|
||||
/// The y of chart.
|
||||
/// 图表的Y
|
||||
/// </summary>
|
||||
public float chartY { get { return m_ChartY; } }
|
||||
/// <summary>
|
||||
/// The width of chart.
|
||||
/// 图表的宽
|
||||
/// </summary>
|
||||
public float chartWidth { get { return m_ChartWidth; } }
|
||||
/// <summary>
|
||||
/// The height of chart.
|
||||
/// 图表的高
|
||||
/// </summary>
|
||||
public float chartHeight { get { return m_ChartHeight; } }
|
||||
public Vector2 chartMinAnchor { get { return m_ChartMinAnchor; } }
|
||||
public Vector2 chartMaxAnchor { get { return m_ChartMaxAnchor; } }
|
||||
public Vector2 chartPivot { get { return m_ChartPivot; } }
|
||||
public Vector2 chartSizeDelta { get { return m_ChartSizeDelta; } }
|
||||
/// <summary>
|
||||
/// The position of chart.
|
||||
/// 图表的左下角起始坐标。
|
||||
/// </summary>
|
||||
public Vector3 chartPosition { get { return m_ChartPosition; } }
|
||||
public Rect chartRect { get { return m_ChartRect; } }
|
||||
/// <summary>
|
||||
/// 自定义绘制回调。在绘制Serie前调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper> onCustomDraw { set { m_OnCustomDrawBaseCallback = value; } }
|
||||
/// <summary>
|
||||
/// 自定义Serie绘制回调。在每个Serie绘制完前调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper, Serie> onCustomDrawBeforeSerie { set { m_OnCustomDrawSerieBeforeCallback = value; } }
|
||||
/// <summary>
|
||||
/// 自定义Serie绘制回调。在每个Serie绘制完后调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper, Serie> onCustomDrawAfterSerie { set { m_OnCustomDrawSerieAfterCallback = value; } }
|
||||
/// <summary>
|
||||
/// 自定义Top绘制回调。在绘制Tooltip前调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper> onCustomDrawTop { set { m_OnCustomDrawTopCallback = value; } }
|
||||
/// <summary>
|
||||
/// the callback function of click pie area.
|
||||
/// 点击饼图区域回调。参数:PointerEventData,SerieIndex,SerieDataIndex
|
||||
/// </summary>
|
||||
public Action<PointerEventData, int, int> onPointerClickPie { set { m_OnPointerClickPie = value; m_ForceOpenRaycastTarget = true; } get { return m_OnPointerClickPie; } }
|
||||
/// <summary>
|
||||
/// the callback function of click bar.
|
||||
/// 点击柱形图柱条回调。参数:eventData, dataIndex
|
||||
/// </summary>
|
||||
public Action<PointerEventData, int> onPointerClickBar { set { m_OnPointerClickBar = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// Redraw chart in next frame.
|
||||
/// 在下一帧刷新图表。
|
||||
/// </summary>
|
||||
public void RefreshChart()
|
||||
{
|
||||
m_RefreshChart = true;
|
||||
if (m_Painter) m_Painter.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all series and legend data.
|
||||
/// It just emptying all of serie's data without emptying the list of series.
|
||||
/// 清除所有数据,系列中只是移除数据,列表会保留。
|
||||
/// </summary>
|
||||
public virtual void ClearData()
|
||||
{
|
||||
foreach(var serie in m_Series)
|
||||
serie.ClearData();
|
||||
foreach (var component in m_Components)
|
||||
component.ClearData();
|
||||
m_CheckAnimation = false;
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all data from series and legend.
|
||||
/// The series list is also cleared.
|
||||
/// 清除所有系列和图例数据,系列的列表也会被清除。
|
||||
/// </summary>
|
||||
public virtual void RemoveData()
|
||||
{
|
||||
foreach (var component in m_Components)
|
||||
component.ClearData();
|
||||
m_Series.Clear();
|
||||
m_CheckAnimation = false;
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove legend and serie by name.
|
||||
/// 清除指定系列名称的数据。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
public virtual void RemoveData(string serieName)
|
||||
{
|
||||
RemoveSerie(serieName);
|
||||
foreach (var component in m_Components)
|
||||
{
|
||||
if (component is Legend)
|
||||
{
|
||||
var legend = component as Legend;
|
||||
legend.RemoveData(serieName);
|
||||
}
|
||||
}
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
public virtual void UpdateLegendColor(string legendName, bool active)
|
||||
{
|
||||
var legendIndex = m_LegendRealShowName.IndexOf(legendName);
|
||||
if (legendIndex >= 0)
|
||||
{
|
||||
foreach (var component in m_Components)
|
||||
{
|
||||
if (component is Legend)
|
||||
{
|
||||
var legend = component as Legend;
|
||||
var iconColor = LegendHelper.GetIconColor(this, legend, legendIndex, legendName, active);
|
||||
var contentColor = LegendHelper.GetContentColor(legendIndex, legend, m_Theme, active);
|
||||
legend.UpdateButtonColor(legendName, iconColor);
|
||||
legend.UpdateContentColor(legendName, contentColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether serie is activated.
|
||||
/// 获得指定图例名字的系列是否显示。
|
||||
/// </summary>
|
||||
/// <param name="legendName"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool IsActiveByLegend(string legendName)
|
||||
{
|
||||
foreach (var serie in m_Series)
|
||||
{
|
||||
if (serie.show && legendName.Equals(serie.serieName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (serieData.show && legendName.Equals(serieData.name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update chart theme.
|
||||
/// 切换内置主题。
|
||||
/// </summary>
|
||||
/// <param name="theme">theme</param>
|
||||
public bool UpdateTheme(ThemeType theme)
|
||||
{
|
||||
if (theme == ThemeType.Custom)
|
||||
{
|
||||
Debug.LogError("UpdateTheme: not support switch to Custom theme.");
|
||||
return false;
|
||||
}
|
||||
m_Theme.sharedTheme.CopyTheme(theme);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update chart theme info.
|
||||
/// 切换图表主题。
|
||||
/// </summary>
|
||||
/// <param name="theme">theme</param>
|
||||
public void UpdateTheme(Theme theme)
|
||||
{
|
||||
m_Theme.sharedTheme = theme;
|
||||
SetAllComponentDirty();
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorUtility.SetDirty(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether series animation enabel.
|
||||
/// 启用或关闭起始动画。
|
||||
/// </summary>
|
||||
/// <param name="flag"></param>
|
||||
public void AnimationEnable(bool flag)
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationEnable(flag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// fadeIn animation.
|
||||
/// 开始渐入动画。
|
||||
/// </summary>
|
||||
public void AnimationFadeIn()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationFadeIn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// fadeIn animation.
|
||||
/// 开始渐出动画。
|
||||
/// </summary>
|
||||
public void AnimationFadeOut()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationFadeOut();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pause animation.
|
||||
/// 暂停动画。
|
||||
/// </summary>
|
||||
public void AnimationPause()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationPause();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop play animation.
|
||||
/// 继续动画。
|
||||
/// </summary>
|
||||
public void AnimationResume()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationResume();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset animation.
|
||||
/// 重置动画。
|
||||
/// </summary>
|
||||
public void AnimationReset()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationReset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点击图例按钮
|
||||
/// </summary>
|
||||
/// <param name="legendIndex">图例按钮索引</param>
|
||||
/// <param name="legendName">图例按钮名称</param>
|
||||
/// <param name="show">显示还是隐藏</param>
|
||||
public void ClickLegendButton(int legendIndex, string legendName, bool show)
|
||||
{
|
||||
OnLegendButtonClick(legendIndex, legendName, show);
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 坐标是否在图表范围内
|
||||
/// </summary>
|
||||
/// <param name="local"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsInChart(Vector2 local)
|
||||
{
|
||||
return IsInChart(local.x, local.y);
|
||||
}
|
||||
|
||||
public bool IsInChart(float x, float y)
|
||||
{
|
||||
if (x < m_ChartX || x > m_ChartX + m_ChartWidth ||
|
||||
y < m_ChartY || y > m_ChartY + m_ChartHeight)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ClampInChart(ref Vector3 pos)
|
||||
{
|
||||
if (!IsInChart(pos.x, pos.y))
|
||||
{
|
||||
if (pos.x < m_ChartX) pos.x = m_ChartX;
|
||||
if (pos.x > m_ChartX + m_ChartWidth) pos.x = m_ChartX + m_ChartWidth;
|
||||
if (pos.y < m_ChartY) pos.y = m_ChartY;
|
||||
if (pos.y > m_ChartY + m_ChartHeight) pos.y = m_ChartY + m_ChartHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 ClampInGrid(GridCoord grid, Vector3 pos)
|
||||
{
|
||||
if (grid.Contains(pos)) return pos;
|
||||
else
|
||||
{
|
||||
// var pos = new Vector3(pos.x, pos.y);
|
||||
if (pos.x < grid.context.x) pos.x = grid.context.x;
|
||||
if (pos.x > grid.context.x + grid.context.width) pos.x = grid.context.x + grid.context.width;
|
||||
if (pos.y < grid.context.y) pos.y = grid.context.y;
|
||||
if (pos.y > grid.context.y + grid.context.height) pos.y = grid.context.y + grid.context.height;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换X轴和Y轴的配置
|
||||
/// </summary>
|
||||
/// <param name="index">坐标轴索引,0或1</param>
|
||||
public void CovertXYAxis(int index)
|
||||
{
|
||||
List<MainComponent> m_XAxes;
|
||||
List<MainComponent> m_YAxes;
|
||||
m_ComponentMaps.TryGetValue(typeof(XAxis), out m_XAxes);
|
||||
m_ComponentMaps.TryGetValue(typeof(YAxis), out m_YAxes);
|
||||
if (index >= 0 && index <= 1)
|
||||
{
|
||||
var xAxis = m_XAxes[index] as XAxis;
|
||||
var yAxis = m_YAxes[index] as YAxis;
|
||||
var tempX = xAxis.Clone();
|
||||
xAxis.Copy(yAxis);
|
||||
yAxis.Copy(tempX);
|
||||
xAxis.context.offset = 0;
|
||||
yAxis.context.offset = 0;
|
||||
xAxis.context.minValue = 0;
|
||||
xAxis.context.maxValue = 0;
|
||||
yAxis.context.minValue = 0;
|
||||
yAxis.context.maxValue = 0;
|
||||
RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在下一帧刷新DataZoom
|
||||
/// </summary>
|
||||
public void RefreshDataZoom()
|
||||
{
|
||||
foreach (var handler in m_ComponentHandlers)
|
||||
{
|
||||
if (handler is DataZoomHandler)
|
||||
{
|
||||
(handler as DataZoomHandler).RefreshDataZoomLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。
|
||||
/// </summary>
|
||||
public void SetMaxCache(int maxCache)
|
||||
{
|
||||
foreach (var serie in m_Series)
|
||||
serie.maxCache = maxCache;
|
||||
foreach (var component in m_Components)
|
||||
{
|
||||
if (component is Axis)
|
||||
{
|
||||
(component as Axis).maxCache = maxCache;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 GetTitlePosition(Title title)
|
||||
{
|
||||
return chartPosition + title.location.GetPosition(chartWidth, chartHeight);
|
||||
}
|
||||
|
||||
public int GetLegendRealShowNameIndex(string name)
|
||||
{
|
||||
return m_LegendRealShowName.IndexOf(name);
|
||||
}
|
||||
|
||||
public Color32 GetLegendRealShowNameColor(string name)
|
||||
{
|
||||
var index = GetLegendRealShowNameIndex(name);
|
||||
return theme.GetColor(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Base Painter的材质球
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetBasePainterMaterial(Material material)
|
||||
{
|
||||
settings.basePainterMaterial = material;
|
||||
if (m_Painter != null)
|
||||
{
|
||||
m_Painter.material = material;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Serie Painter的材质球
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetSeriePainterMaterial(Material material)
|
||||
{
|
||||
settings.basePainterMaterial = material;
|
||||
if (m_PainterList != null)
|
||||
{
|
||||
foreach (var painter in m_PainterList)
|
||||
painter.material = material;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Top Painter的材质球
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetTopPainterMaterial(Material material)
|
||||
{
|
||||
settings.topPainterMaterial = material;
|
||||
if (m_PainterTop != null)
|
||||
{
|
||||
m_PainterTop.material = material;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/BaseChart_API.cs.meta
Normal file
11
Runtime/Chart/BaseChart_API.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1fc3767ca43f44f77a6d017fd55c8fec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
176
Runtime/Chart/BaseGraph_API.cs
Normal file
176
Runtime/Chart/BaseGraph_API.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class of all graphs or components.
|
||||
/// 所有图形的基类。
|
||||
/// </summary>
|
||||
public partial class BaseGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// The background component.
|
||||
/// 背景组件。
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
///public Background background { get { return m_Background; } }
|
||||
/// <summary>
|
||||
/// The x of graph.
|
||||
/// 图形的X
|
||||
/// </summary>
|
||||
public float graphX { get { return m_GraphX; } }
|
||||
/// <summary>
|
||||
/// The y of graph.
|
||||
/// 图形的Y
|
||||
/// </summary>
|
||||
public float graphY { get { return m_GraphY; } }
|
||||
/// <summary>
|
||||
/// The width of graph.
|
||||
/// 图形的宽
|
||||
/// </summary>
|
||||
public float graphWidth { get { return m_GraphWidth; } }
|
||||
/// <summary>
|
||||
/// The height of graph.
|
||||
/// 图形的高
|
||||
/// </summary>
|
||||
public float graphHeight { get { return m_GraphHeight; } }
|
||||
/// <summary>
|
||||
/// The position of graph.
|
||||
/// 图形的左下角起始坐标。
|
||||
/// </summary>
|
||||
public Vector3 graphPosition { get { return m_GraphPosition; } }
|
||||
public Rect graphRect { get { return m_GraphRect; } }
|
||||
/// <summary>
|
||||
/// The postion of pointer.
|
||||
/// 鼠标位置。
|
||||
/// </summary>
|
||||
public Vector2 pointerPos { get; protected set; }
|
||||
/// <summary>
|
||||
/// Whether the mouse pointer is in the chart.
|
||||
/// 鼠标是否在图表内。
|
||||
/// </summary>
|
||||
public bool isPointerInChart { get; protected set; }
|
||||
/// <summary>
|
||||
/// 警告信息。
|
||||
/// </summary>
|
||||
public string warningInfo { get; protected set; }
|
||||
/// <summary>
|
||||
/// 强制开启鼠标事件检测。
|
||||
/// </summary>
|
||||
public bool forceOpenRaycastTarget { get { return m_ForceOpenRaycastTarget; } set { m_ForceOpenRaycastTarget = value; } }
|
||||
/// <summary>
|
||||
/// 鼠标点击回调。
|
||||
/// </summary>
|
||||
public Action<PointerEventData, BaseGraph> onPointerClick { set { m_OnPointerClick = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// 鼠标按下回调。
|
||||
/// </summary>
|
||||
public Action<PointerEventData, BaseGraph> onPointerDown { set { m_OnPointerDown = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// 鼠标弹起回调。
|
||||
/// </summary>
|
||||
public Action<PointerEventData, BaseGraph> onPointerUp { set { m_OnPointerUp = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// 鼠标进入回调。
|
||||
/// </summary>
|
||||
public Action<PointerEventData, BaseGraph> onPointerEnter { set { m_OnPointerEnter = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// 鼠标退出回调。
|
||||
/// </summary>
|
||||
public Action<PointerEventData, BaseGraph> onPointerExit { set { m_OnPointerExit = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// 鼠标开始拖拽回调。
|
||||
/// </summary>
|
||||
public Action<PointerEventData, BaseGraph> onBeginDrag { set { m_OnBeginDrag = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// 鼠标拖拽回调。
|
||||
/// </summary>
|
||||
public Action<PointerEventData, BaseGraph> onDrag { set { m_OnDrag = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// 鼠标结束拖拽回调。
|
||||
/// </summary>
|
||||
public Action<PointerEventData, BaseGraph> onEndDrag { set { m_OnEndDrag = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// 鼠标滚动回调。
|
||||
/// </summary>
|
||||
public Action<PointerEventData, BaseGraph> onScroll { set { m_OnScroll = value; m_ForceOpenRaycastTarget = true; } }
|
||||
|
||||
/// <summary>
|
||||
/// 设置图形的宽高(在非stretch pivot下才有效,其他情况需要自己调整RectTransform)
|
||||
/// </summary>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
public virtual void SetSize(float width, float height)
|
||||
{
|
||||
if (LayerHelper.IsFixedWidthHeight(rectTransform))
|
||||
{
|
||||
rectTransform.sizeDelta = new Vector2(width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Can't set size on stretch pivot,you need to modify rectTransform by yourself.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新初始化Painter
|
||||
/// </summary>
|
||||
public void SetPainterDirty()
|
||||
{
|
||||
m_PainerDirty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redraw graph in next frame.
|
||||
/// 在下一帧刷新图形。
|
||||
/// </summary>
|
||||
public void RefreshGraph()
|
||||
{
|
||||
m_RefreshChart = true;
|
||||
}
|
||||
|
||||
public void RefreshAllComponent()
|
||||
{
|
||||
SetAllComponentDirty();
|
||||
RefreshGraph();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测警告信息。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string CheckWarning()
|
||||
{
|
||||
warningInfo = CheckHelper.CheckChart(this);
|
||||
return warningInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除所有图表子节点,会自动重新初始化。
|
||||
/// </summary>
|
||||
public void RemoveChartObject()
|
||||
{
|
||||
ChartHelper.DestroyAllChildren(transform);
|
||||
//SetAllComponentDirty();
|
||||
}
|
||||
|
||||
public bool ScreenPointToChartPoint(Vector2 screenPoint, out Vector2 chartPoint)
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX
|
||||
var relative = Display.RelativeMouseAt(screenPoint);
|
||||
if(relative != Vector3.zero)
|
||||
screenPoint = relative;
|
||||
#endif
|
||||
var cam = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera;
|
||||
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform,
|
||||
screenPoint, cam, out chartPoint))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/BaseGraph_API.cs.meta
Normal file
11
Runtime/Chart/BaseGraph_API.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec7d385a69cce42fda86960eb0b23c3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
35
Runtime/Chart/CandlestickChart.cs
Normal file
35
Runtime/Chart/CandlestickChart.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/CandlestickChart", 23)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class CandlestickChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Shadow;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
Candlestick.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < GetSerie(0).dataCount; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/CandlestickChart.cs.meta
Normal file
11
Runtime/Chart/CandlestickChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b64f0bb738cc4acfa72fff2c30212b4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
83
Runtime/Chart/HeatmapChart.cs
Normal file
83
Runtime/Chart/HeatmapChart.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/HeatmapChart", 18)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class HeatmapChart : BaseChart
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.None;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
var grid = GetOrAddChartComponent<GridCoord>();
|
||||
grid.left = 100;
|
||||
grid.right = 60;
|
||||
grid.bottom = 60;
|
||||
|
||||
var xAxis = GetOrAddChartComponent<XAxis>();
|
||||
xAxis.type = Axis.AxisType.Category;
|
||||
xAxis.boundaryGap = true;
|
||||
xAxis.splitNumber = 10;
|
||||
|
||||
var yAxis = GetOrAddChartComponent<YAxis>();
|
||||
yAxis.type = Axis.AxisType.Category;
|
||||
yAxis.boundaryGap = true;
|
||||
yAxis.splitNumber = 10;
|
||||
RemoveData();
|
||||
|
||||
var heatmapGridWid = 10f;
|
||||
int xSplitNumber = (int)(grid.context.width / heatmapGridWid);
|
||||
int ySplitNumber = (int)(grid.context.height / heatmapGridWid);
|
||||
|
||||
Heatmap.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
|
||||
var visualMap = GetOrAddChartComponent<VisualMap>();
|
||||
visualMap.max = 10;
|
||||
visualMap.range[0] = 0f;
|
||||
visualMap.range[1] = 10f;
|
||||
visualMap.orient = Orient.Vertical;
|
||||
visualMap.calculable = true;
|
||||
visualMap.location.align = Location.Align.BottomLeft;
|
||||
visualMap.location.bottom = 100;
|
||||
visualMap.location.left = 30;
|
||||
var colors = new List<string>{"#313695", "#4575b4", "#74add1", "#abd9e9", "#e0f3f8", "#ffffbf",
|
||||
"#fee090", "#fdae61", "#f46d43", "#d73027", "#a50026"};
|
||||
visualMap.inRange.Clear();
|
||||
foreach (var str in colors)
|
||||
{
|
||||
visualMap.inRange.Add(ThemeStyle.GetColor(str));
|
||||
}
|
||||
for (int i = 0; i < xSplitNumber; i++)
|
||||
{
|
||||
xAxis.data.Add((i + 1).ToString());
|
||||
}
|
||||
for (int i = 0; i < ySplitNumber; i++)
|
||||
{
|
||||
yAxis.data.Add((i + 1).ToString());
|
||||
}
|
||||
for (int i = 0; i < xSplitNumber; i++)
|
||||
{
|
||||
for (int j = 0; j < ySplitNumber; j++)
|
||||
{
|
||||
var value = 0f;
|
||||
var rate = Random.Range(0, 101);
|
||||
if (rate > 70) value = Random.Range(8f, 10f);
|
||||
else value = Random.Range(1f, 8f);
|
||||
var list = new List<double> { i, j, value };
|
||||
AddData(0, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/HeatmapChart.cs.meta
Normal file
11
Runtime/Chart/HeatmapChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31aa03cd4ce594c239ae746791b3b59f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
35
Runtime/Chart/LineChart.cs
Normal file
35
Runtime/Chart/LineChart.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/LineChart", 13)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class LineChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Line;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
Line.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/LineChart.cs.meta
Normal file
11
Runtime/Chart/LineChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4f38bd00b4648c448cabfc167538f7c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Runtime/Chart/LiquidChart.cs
Normal file
27
Runtime/Chart/LiquidChart.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// 水位图
|
||||
/// </summary>
|
||||
[AddComponentMenu("XCharts/LiquidChart", 22)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class LiquidChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
GetChartComponent<Tooltip>().type = Tooltip.Type.Line;
|
||||
RemoveData();
|
||||
|
||||
Liquid.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/LiquidChart.cs.meta
Normal file
11
Runtime/Chart/LiquidChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41f7e109291bd44de96fccf526e9c7f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Runtime/Chart/ParallelChart.cs
Normal file
34
Runtime/Chart/ParallelChart.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/ParallelChart", 25)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class ParallelChart : BaseChart
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
RemoveData();
|
||||
AddChartComponent<ParallelCoord>();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var valueAxis = AddChartComponent<ParallelAxis>();
|
||||
valueAxis.type = Axis.AxisType.Value;
|
||||
}
|
||||
var categoryAxis = AddChartComponent<ParallelAxis>();
|
||||
categoryAxis.type = Axis.AxisType.Category;
|
||||
categoryAxis.position = Axis.AxisPosition.Right;
|
||||
categoryAxis.data = new List<string>() { "x1", "x2", "x3", "x4", "x5" };
|
||||
|
||||
Parallel.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/ParallelChart.cs.meta
Normal file
11
Runtime/Chart/ParallelChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 161753d0d6ce541c89483f8c3a21343f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
Runtime/Chart/PieChart.cs
Normal file
24
Runtime/Chart/PieChart.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/PieChart", 15)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class PieChart : BaseChart
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
var legend = GetOrAddChartComponent<Legend>();
|
||||
legend.show = true;
|
||||
|
||||
RemoveData();
|
||||
Pie.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/PieChart.cs.meta
Normal file
11
Runtime/Chart/PieChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d44276ba809fd92408b296835f6f7658
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
28
Runtime/Chart/RadarChart.cs
Normal file
28
Runtime/Chart/RadarChart.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/RadarChart", 16)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class RadarChart : BaseChart
|
||||
{
|
||||
protected override void InitComponent()
|
||||
{
|
||||
base.InitComponent();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
RemoveData();
|
||||
RemoveChartComponents<RadarCoord>();
|
||||
AddChartComponent<RadarCoord>();
|
||||
Radar.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/RadarChart.cs.meta
Normal file
11
Runtime/Chart/RadarChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2231a0d3e3a5b043b074f6739be4a86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
Runtime/Chart/RingChart.cs
Normal file
24
Runtime/Chart/RingChart.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/RingChart", 20)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class RingChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
GetChartComponent<Tooltip>().type = Tooltip.Type.Line;
|
||||
RemoveData();
|
||||
Ring.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/RingChart.cs.meta
Normal file
11
Runtime/Chart/RingChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ad8949f652ee4376a4a4fe5cb32029f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
35
Runtime/Chart/ScatterChart.cs
Normal file
35
Runtime/Chart/ScatterChart.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/ScatterChart", 17)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class ScatterChart : BaseChart
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
|
||||
var tooltip = GetOrAddChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.None;
|
||||
tooltip.trigger = Tooltip.Trigger.Item;
|
||||
|
||||
var xAxis = GetOrAddChartComponent<XAxis>();
|
||||
xAxis.type = Axis.AxisType.Value;
|
||||
xAxis.boundaryGap = false;
|
||||
|
||||
var yAxis = GetOrAddChartComponent<YAxis>();
|
||||
yAxis.type = Axis.AxisType.Value;
|
||||
yAxis.boundaryGap = false;
|
||||
|
||||
RemoveData();
|
||||
Scatter.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/ScatterChart.cs.meta
Normal file
11
Runtime/Chart/ScatterChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf16aac0bd6c24a8da75846c34c5193e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
35
Runtime/Chart/SimplifiedBarChart.cs
Normal file
35
Runtime/Chart/SimplifiedBarChart.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/SimplifiedBarChart", 27)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class SimplifiedBarChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Line;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
SimplifiedBar.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < GetSerie(0).dataCount; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/SimplifiedBarChart.cs.meta
Normal file
11
Runtime/Chart/SimplifiedBarChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa86c3bbf8877409c9d45716fbaf92f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
35
Runtime/Chart/SimplifiedCandlestickChart.cs
Normal file
35
Runtime/Chart/SimplifiedCandlestickChart.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/SimplifiedCandlestickChart", 28)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class SimplifiedCandlestickChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Shadow;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
SimplifiedCandlestick.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < GetSerie(0).dataCount; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/SimplifiedCandlestickChart.cs.meta
Normal file
11
Runtime/Chart/SimplifiedCandlestickChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6dcc9bd1ca8344d938f386e6b32e8946
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
35
Runtime/Chart/SimplifiedLineChart.cs
Normal file
35
Runtime/Chart/SimplifiedLineChart.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/SimplifiedLineChart", 26)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class SimplifiedLineChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Line;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
SimplifiedLine.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < GetSerie(0).dataCount; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Runtime/Chart/SimplifiedLineChart.cs.meta
Normal file
11
Runtime/Chart/SimplifiedLineChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8233997c1b324ecd875a03af4d90972
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component.meta
Normal file
8
Runtime/Component.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3be5f1d3b129a47dd8e41cffe3b8e428
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Animation.meta
Normal file
8
Runtime/Component/Animation.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f827513754e8436bbc63e64c5b5e6c3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
631
Runtime/Component/Animation/AnimationStyle.cs
Normal file
631
Runtime/Component/Animation/AnimationStyle.cs
Normal file
@@ -0,0 +1,631 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public delegate float CustomAnimationDelay(int dataIndex);
|
||||
public delegate float CustomAnimationDuration(int dataIndex);
|
||||
|
||||
public enum AnimationType
|
||||
{
|
||||
/// <summary>
|
||||
/// he default. An animation playback mode will be selected according to the actual situation.
|
||||
/// 默认。内部会根据实际情况选择一种动画播放方式。
|
||||
/// </summary>
|
||||
Default,
|
||||
/// <summary>
|
||||
/// Play the animation from left to right.
|
||||
/// 从左往右播放动画。
|
||||
/// </summary>
|
||||
LeftToRight,
|
||||
/// <summary>
|
||||
/// Play the animation from bottom to top.
|
||||
/// 从下往上播放动画。
|
||||
/// </summary>
|
||||
BottomToTop,
|
||||
/// <summary>
|
||||
/// Play animations from the inside out.
|
||||
/// 由内到外播放动画。
|
||||
/// </summary>
|
||||
InsideOut,
|
||||
/// <summary>
|
||||
/// Play the animation along the path.
|
||||
/// 沿着路径播放动画。
|
||||
/// </summary>
|
||||
AlongPath,
|
||||
/// <summary>
|
||||
/// Play the animation clockwise.
|
||||
/// 顺时针播放动画。
|
||||
/// </summary>
|
||||
Clockwise,
|
||||
}
|
||||
|
||||
public enum AnimationEasing
|
||||
{
|
||||
Linear,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the animation of serie.
|
||||
/// 动画表现。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AnimationStyle : ChildComponent
|
||||
{
|
||||
[SerializeField] private bool m_Enable = true;
|
||||
[SerializeField] private AnimationType m_Type;
|
||||
[SerializeField] private AnimationEasing m_Easting;
|
||||
[SerializeField] private int m_Threshold = 2000;
|
||||
[SerializeField] private float m_FadeInDuration = 1000;
|
||||
[SerializeField] private float m_FadeInDelay = 0;
|
||||
[SerializeField] private float m_FadeOutDuration = 1000f;
|
||||
[SerializeField] private float m_FadeOutDelay = 0;
|
||||
[SerializeField] private bool m_DataChangeEnable = true;
|
||||
[SerializeField] private float m_DataChangeDuration = 500;
|
||||
[SerializeField] private float m_ActualDuration;
|
||||
[SerializeField] private bool m_AlongWithLinePath;
|
||||
/// <summary>
|
||||
/// 自定义渐入动画延时函数。返回ms值。
|
||||
/// </summary>
|
||||
public CustomAnimationDelay customFadeInDelay;
|
||||
/// <summary>
|
||||
/// 自定义渐入动画时长函数。返回ms值。
|
||||
/// </summary>
|
||||
public CustomAnimationDuration customFadeInDuration;
|
||||
/// <summary>
|
||||
/// 自定义渐出动画延时函数。返回ms值。
|
||||
/// </summary>
|
||||
public CustomAnimationDelay customFadeOutDelay;
|
||||
/// <summary>
|
||||
/// 自定义渐出动画时长函数。返回ms值。
|
||||
/// </summary>
|
||||
public CustomAnimationDuration customFadeOutDuration;
|
||||
public AnimationStyleContext context = new AnimationStyleContext();
|
||||
|
||||
/// <summary>
|
||||
/// Whether to enable animation.
|
||||
/// 是否开启动画效果。
|
||||
/// </summary>
|
||||
public bool enable { get { return m_Enable; } set { m_Enable = value; } }
|
||||
/// <summary>
|
||||
/// The type of animation.
|
||||
/// 动画类型。
|
||||
/// </summary>
|
||||
public AnimationType type { get { return m_Type; } set { m_Type = value; } }
|
||||
/// <summary>
|
||||
/// Easing method used for the first animation.
|
||||
/// 动画的缓动效果。
|
||||
/// </summary>
|
||||
//public Easing easing { get { return m_Easting; } set { m_Easting = value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds duration of the fadeIn animation.
|
||||
/// 设定的渐入动画时长(毫秒)。如果要设置单个数据项的渐入时长,可以用代码定制:customFadeInDuration。
|
||||
/// </summary>
|
||||
public float fadeInDuration { get { return m_FadeInDuration; } set { m_FadeInDuration = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds duration of the fadeOut animation.
|
||||
/// 设定的渐出动画时长(毫秒)。如果要设置单个数据项的渐出时长,可以用代码定制:customFadeOutDuration。
|
||||
/// </summary>
|
||||
public float fadeOutDuration { get { return m_FadeOutDuration; } set { m_FadeOutDuration = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds actual duration of the first animation.
|
||||
/// 实际的动画时长(毫秒)。
|
||||
/// </summary>
|
||||
public float actualDuration { get { return m_ActualDuration; } }
|
||||
/// <summary>
|
||||
/// Whether to set graphic number threshold to animation. Animation will be disabled when graphic number is larger than threshold.
|
||||
/// 是否开启动画的阈值,当单个系列显示的图形数量大于这个阈值时会关闭动画。
|
||||
/// </summary>
|
||||
public int threshold { get { return m_Threshold; } set { m_Threshold = value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds delay before updating the first animation.
|
||||
/// 渐入动画延时(毫秒)。如果要设置单个数据项的延时,可以用代码定制:customFadeInDelay。
|
||||
/// </summary>
|
||||
public float fadeInDelay { get { return m_FadeInDelay; } set { m_FadeInDelay = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// 渐出动画延时(毫秒)。如果要设置单个数据项的延时,可以用代码定制:customFadeOutDelay。
|
||||
/// </summary>
|
||||
public float fadeOutDelay { get { return m_FadeOutDelay; } set { m_FadeInDelay = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// 是否开启数据变更动画。
|
||||
/// </summary>
|
||||
public bool dataChangeEnable { get { return m_DataChangeEnable; } set { m_DataChangeEnable = value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds duration of the data change animation.
|
||||
/// 数据变更的动画时长(毫秒)。
|
||||
/// </summary>
|
||||
public float dataChangeDuration { get { return m_DataChangeDuration; } set { m_DataChangeDuration = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// 渐入动画完成回调
|
||||
/// </summary>
|
||||
public Action fadeInFinishCallback { get; set; }
|
||||
/// <summary>
|
||||
/// 渐出动画完成回调
|
||||
/// </summary>
|
||||
public Action fadeOutFinishCallback { get; set; }
|
||||
private Dictionary<int, float> m_ItemCurrProgress = new Dictionary<int, float>();
|
||||
private Dictionary<int, float> m_ItemDestProgress = new Dictionary<int, float>();
|
||||
private bool m_FadeIn = false;
|
||||
private bool m_IsEnd = true;
|
||||
private bool m_IsPause = false;
|
||||
private bool m_FadeOut = false;
|
||||
private bool m_FadeOuted = false;
|
||||
private bool m_IsInit = false;
|
||||
|
||||
private float startTime { get; set; }
|
||||
private float m_CurrDetailProgress;
|
||||
private float m_DestDetailProgress;
|
||||
private float m_TotalDetailProgress;
|
||||
private float m_CurrSymbolProgress;
|
||||
private Vector3 m_LinePathLastPos;
|
||||
|
||||
public void FadeIn()
|
||||
{
|
||||
if (m_FadeOut)
|
||||
return;
|
||||
|
||||
if (m_IsPause)
|
||||
{
|
||||
m_IsPause = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_FadeIn)
|
||||
return;
|
||||
|
||||
startTime = Time.time;
|
||||
m_FadeIn = true;
|
||||
m_IsEnd = false;
|
||||
m_IsInit = false;
|
||||
m_IsPause = false;
|
||||
m_FadeOuted = false;
|
||||
m_CurrDetailProgress = 0;
|
||||
m_DestDetailProgress = 1;
|
||||
m_CurrSymbolProgress = 0;
|
||||
m_ItemCurrProgress.Clear();
|
||||
m_ItemDestProgress.Clear();
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
Reset();
|
||||
FadeIn();
|
||||
}
|
||||
|
||||
public void FadeOut()
|
||||
{
|
||||
if (m_IsPause)
|
||||
{
|
||||
m_IsPause = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_FadeOut = true;
|
||||
startTime = Time.time;
|
||||
m_FadeIn = true;
|
||||
m_IsEnd = false;
|
||||
m_IsInit = false;
|
||||
m_IsPause = false;
|
||||
m_CurrDetailProgress = 0;
|
||||
m_DestDetailProgress = 1;
|
||||
m_CurrSymbolProgress = 0;
|
||||
m_ItemCurrProgress.Clear();
|
||||
m_ItemDestProgress.Clear();
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
if (!m_IsPause)
|
||||
{
|
||||
m_IsPause = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Resume()
|
||||
{
|
||||
if (m_IsPause)
|
||||
{
|
||||
m_IsPause = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void End()
|
||||
{
|
||||
if (m_IsEnd)
|
||||
return;
|
||||
|
||||
m_ActualDuration = (int)((Time.time - startTime) * 1000) - (m_FadeOut ? fadeOutDelay : fadeInDelay);
|
||||
m_IsEnd = true;
|
||||
m_IsInit = false;
|
||||
|
||||
if (m_FadeIn)
|
||||
{
|
||||
m_FadeIn = false;
|
||||
if (fadeInFinishCallback != null)
|
||||
{
|
||||
fadeInFinishCallback();
|
||||
}
|
||||
}
|
||||
if (m_FadeOut)
|
||||
{
|
||||
m_FadeOut = false;
|
||||
m_FadeOuted = true;
|
||||
if (fadeOutFinishCallback != null)
|
||||
{
|
||||
fadeOutFinishCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_FadeIn = false;
|
||||
m_IsEnd = true;
|
||||
m_IsInit = false;
|
||||
m_IsPause = false;
|
||||
m_FadeOut = false;
|
||||
m_FadeOuted = false;
|
||||
m_ItemCurrProgress.Clear();
|
||||
}
|
||||
|
||||
public void InitProgress(float curr, float dest)
|
||||
{
|
||||
if (m_IsInit || m_IsEnd)
|
||||
return;
|
||||
if (curr > dest)
|
||||
return;
|
||||
|
||||
m_IsInit = true;
|
||||
m_TotalDetailProgress = dest - curr;
|
||||
|
||||
if (m_FadeOut)
|
||||
{
|
||||
m_CurrDetailProgress = dest;
|
||||
m_DestDetailProgress = curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrDetailProgress = curr;
|
||||
m_DestDetailProgress = dest;
|
||||
}
|
||||
}
|
||||
|
||||
public void InitProgress(List<Vector3> paths, bool isY)
|
||||
{
|
||||
if (paths.Count < 1) return;
|
||||
var sp = paths[0];
|
||||
var ep = paths[paths.Count - 1];
|
||||
var currDetailProgress = isY ? sp.y : sp.x;
|
||||
var totalDetailProgress = isY ? ep.y : ep.x;
|
||||
if (context.type == AnimationType.AlongPath)
|
||||
{
|
||||
currDetailProgress = 0;
|
||||
totalDetailProgress = 0;
|
||||
var lp = sp;
|
||||
for (int i = 1; i < paths.Count; i++)
|
||||
{
|
||||
var np = paths[i];
|
||||
totalDetailProgress += Vector3.Distance(np, lp);
|
||||
lp = np;
|
||||
}
|
||||
m_LinePathLastPos = sp;
|
||||
context.currentPathDistance = 0;
|
||||
}
|
||||
InitProgress(currDetailProgress, totalDetailProgress);
|
||||
}
|
||||
|
||||
private void SetDataCurrProgress(int index, float state)
|
||||
{
|
||||
m_ItemCurrProgress[index] = state;
|
||||
}
|
||||
|
||||
private float GetDataCurrProgress(int index, float initValue, float destValue, ref bool isBarEnd)
|
||||
{
|
||||
if (IsInDelay())
|
||||
{
|
||||
isBarEnd = false;
|
||||
return initValue;
|
||||
}
|
||||
var c1 = !m_ItemCurrProgress.ContainsKey(index);
|
||||
var c2 = !m_ItemDestProgress.ContainsKey(index);
|
||||
if (c1 || c2)
|
||||
{
|
||||
if (c1)
|
||||
m_ItemCurrProgress.Add(index, initValue);
|
||||
|
||||
if (c2)
|
||||
m_ItemDestProgress.Add(index, destValue);
|
||||
|
||||
isBarEnd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
isBarEnd = m_ItemCurrProgress[index] == m_ItemDestProgress[index];
|
||||
}
|
||||
return m_ItemCurrProgress[index];
|
||||
}
|
||||
|
||||
public bool IsFinish()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return true;
|
||||
#endif
|
||||
if (!m_Enable || m_IsEnd)
|
||||
return true;
|
||||
|
||||
if (IsIndexAnimation())
|
||||
return m_CurrDetailProgress > m_DestDetailProgress;
|
||||
if (IsItemAnimation())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsInFadeOut()
|
||||
{
|
||||
return m_FadeOut;
|
||||
}
|
||||
|
||||
public bool IsInDelay()
|
||||
{
|
||||
if (m_FadeOut)
|
||||
return (fadeOutDelay > 0 && Time.time - startTime < fadeOutDelay / 1000);
|
||||
else
|
||||
return (fadeInDelay > 0 && Time.time - startTime < fadeInDelay / 1000);
|
||||
}
|
||||
|
||||
public bool IsItemAnimation()
|
||||
{
|
||||
return context.type == AnimationType.BottomToTop || context.type == AnimationType.InsideOut;
|
||||
}
|
||||
|
||||
public bool IsIndexAnimation()
|
||||
{
|
||||
return context.type == AnimationType.LeftToRight
|
||||
|| context.type == AnimationType.Clockwise
|
||||
|| context.type == AnimationType.AlongPath;
|
||||
}
|
||||
|
||||
public float GetIndexDelay(int dataIndex)
|
||||
{
|
||||
if (m_FadeOut && customFadeOutDelay != null)
|
||||
return customFadeOutDelay(dataIndex);
|
||||
else if (m_FadeIn && customFadeInDelay != null)
|
||||
return customFadeInDelay(dataIndex);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool IsInIndexDelay(int dataIndex)
|
||||
{
|
||||
return Time.time - startTime < GetIndexDelay(dataIndex) / 1000f;
|
||||
}
|
||||
|
||||
public bool IsAllOutDelay(int dataCount)
|
||||
{
|
||||
var nowTime = Time.time - startTime;
|
||||
for (int i = 0; i < dataCount; i++)
|
||||
{
|
||||
if (nowTime < GetIndexDelay(i) / 1000)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CheckDetailBreak(float detail)
|
||||
{
|
||||
if (!IsIndexAnimation())
|
||||
return false;
|
||||
return !IsFinish() && detail > m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
public bool CheckDetailBreak(Vector3 pos, bool isYAxis)
|
||||
{
|
||||
if (!IsIndexAnimation())
|
||||
return false;
|
||||
|
||||
if (IsFinish())
|
||||
return false;
|
||||
|
||||
if (context.type == AnimationType.AlongPath)
|
||||
{
|
||||
context.currentPathDistance += Vector3.Distance(pos, m_LinePathLastPos);
|
||||
m_LinePathLastPos = pos;
|
||||
return CheckDetailBreak(context.currentPathDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isYAxis)
|
||||
return pos.y > m_CurrDetailProgress;
|
||||
else
|
||||
return pos.x > m_CurrDetailProgress;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckProgress()
|
||||
{
|
||||
if (IsItemAnimation() && context.isAllItemAnimationEnd)
|
||||
{
|
||||
End();
|
||||
return;
|
||||
}
|
||||
CheckProgress(m_TotalDetailProgress);
|
||||
}
|
||||
|
||||
public void CheckProgress(double total)
|
||||
{
|
||||
if (IsFinish())
|
||||
return;
|
||||
|
||||
if (!m_IsInit || m_IsPause || m_IsEnd)
|
||||
return;
|
||||
|
||||
if (IsInDelay())
|
||||
return;
|
||||
|
||||
m_ActualDuration = (int)((Time.time - startTime) * 1000) - fadeInDelay;
|
||||
var duration = GetCurrAnimationDuration();
|
||||
var delta = (float)(total / duration * Time.deltaTime);
|
||||
if (m_FadeOut)
|
||||
{
|
||||
m_CurrDetailProgress -= delta;
|
||||
if (m_CurrDetailProgress <= m_DestDetailProgress)
|
||||
{
|
||||
m_CurrDetailProgress = m_DestDetailProgress;
|
||||
End();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrDetailProgress += delta;
|
||||
if (m_CurrDetailProgress >= m_DestDetailProgress)
|
||||
{
|
||||
m_CurrDetailProgress = m_DestDetailProgress;
|
||||
End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal float GetCurrAnimationDuration(int dataIndex = -1)
|
||||
{
|
||||
if (dataIndex >= 0)
|
||||
{
|
||||
if (m_FadeOut && customFadeOutDuration != null)
|
||||
return customFadeOutDuration(dataIndex) / 1000f;
|
||||
if (m_FadeIn && customFadeInDuration != null)
|
||||
return customFadeInDuration(dataIndex) / 1000f;
|
||||
}
|
||||
|
||||
if (m_FadeOut)
|
||||
return m_FadeOutDuration > 0 ? m_FadeOutDuration / 1000 : 1f;
|
||||
else
|
||||
return m_FadeInDuration > 0 ? m_FadeInDuration / 1000 : 1f;
|
||||
}
|
||||
|
||||
internal float CheckItemProgress(int dataIndex, float barHig, ref bool isEnd)
|
||||
{
|
||||
isEnd = false;
|
||||
var initHig = m_FadeOut ? barHig : 0;
|
||||
var destHig = m_FadeOut ? 0 : barHig;
|
||||
var currHig = GetDataCurrProgress(dataIndex, initHig, destHig, ref isEnd);
|
||||
if (isEnd || IsFinish())
|
||||
{
|
||||
return m_FadeOuted ? 0 : barHig;
|
||||
}
|
||||
else if (IsInDelay() || IsInIndexDelay(dataIndex))
|
||||
{
|
||||
return m_FadeOut ? barHig : 0;
|
||||
}
|
||||
else if (m_IsPause)
|
||||
{
|
||||
return currHig;
|
||||
}
|
||||
else
|
||||
{
|
||||
var duration = GetCurrAnimationDuration(dataIndex);
|
||||
var delta = barHig / duration * Time.deltaTime;
|
||||
currHig = currHig + (m_FadeOut ? -delta : delta);
|
||||
if (m_FadeOut)
|
||||
{
|
||||
if ((initHig > 0 && currHig <= 0) || (initHig < 0 && currHig >= 0))
|
||||
{
|
||||
currHig = 0;
|
||||
isEnd = true;
|
||||
}
|
||||
}
|
||||
else if (Mathf.Abs(currHig) >= Mathf.Abs(barHig))
|
||||
{
|
||||
currHig = barHig;
|
||||
isEnd = true;
|
||||
}
|
||||
SetDataCurrProgress(dataIndex, currHig);
|
||||
return currHig;
|
||||
}
|
||||
}
|
||||
|
||||
internal void CheckSymbol(float dest)
|
||||
{
|
||||
if (!enable || m_IsEnd || m_IsPause || !m_IsInit)
|
||||
return;
|
||||
|
||||
if (IsInDelay())
|
||||
return;
|
||||
|
||||
var duration = GetCurrAnimationDuration();
|
||||
var delta = dest / duration * Time.deltaTime;
|
||||
if (m_FadeOut)
|
||||
{
|
||||
m_CurrSymbolProgress -= delta;
|
||||
if (m_CurrSymbolProgress < 0)
|
||||
m_CurrSymbolProgress = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrSymbolProgress += delta;
|
||||
if (m_CurrSymbolProgress > dest)
|
||||
m_CurrSymbolProgress = dest;
|
||||
}
|
||||
}
|
||||
|
||||
public float GetSysmbolSize(float dest)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return dest;
|
||||
#endif
|
||||
if (!enable)
|
||||
return dest;
|
||||
|
||||
if (m_IsEnd)
|
||||
return m_FadeOut ? 0 : dest;
|
||||
|
||||
return m_CurrSymbolProgress;
|
||||
}
|
||||
|
||||
public float GetCurrDetail()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return m_DestDetailProgress;
|
||||
#endif
|
||||
return m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
public float GetCurrRate()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return 1;
|
||||
#endif
|
||||
if (!enable || m_IsEnd)
|
||||
return 1;
|
||||
return m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
public int GetCurrIndex()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return -1;
|
||||
#endif
|
||||
if (!enable || m_IsEnd)
|
||||
return -1;
|
||||
return (int)m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
public float GetUpdateAnimationDuration()
|
||||
{
|
||||
if (m_Enable && m_DataChangeEnable && IsFinish())
|
||||
return m_DataChangeDuration;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool HasFadeOut()
|
||||
{
|
||||
return enable && m_FadeOuted && m_IsEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Animation/AnimationStyle.cs.meta
Normal file
11
Runtime/Component/Animation/AnimationStyle.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e31c30f2ef61c48718a626f93307ce92
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Runtime/Component/Animation/AnimationStyleContext.cs
Normal file
14
Runtime/Component/Animation/AnimationStyleContext.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public struct AnimationStyleContext
|
||||
{
|
||||
public AnimationType type;
|
||||
internal float currentPathDistance;
|
||||
internal bool isAllItemAnimationEnd;
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Animation/AnimationStyleContext.cs.meta
Normal file
11
Runtime/Component/Animation/AnimationStyleContext.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3dc504960589413fa6a76267067775c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
66
Runtime/Component/Animation/AnimationStyleHelper.cs
Normal file
66
Runtime/Component/Animation/AnimationStyleHelper.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using UnityEngine;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public static class AnimationStyleHelper
|
||||
{
|
||||
public static float CheckDataAnimation(BaseChart chart, Serie serie, int dataIndex, float destProgress)
|
||||
{
|
||||
if (!serie.animation.IsItemAnimation())
|
||||
{
|
||||
serie.animation.context.isAllItemAnimationEnd = false;
|
||||
return destProgress;
|
||||
}
|
||||
if (serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.context.isAllItemAnimationEnd = false;
|
||||
return destProgress;
|
||||
}
|
||||
var isDataAnimationEnd = true;
|
||||
float currHig = serie.animation.CheckItemProgress(dataIndex, destProgress, ref isDataAnimationEnd);
|
||||
if (!isDataAnimationEnd)
|
||||
{
|
||||
serie.animation.context.isAllItemAnimationEnd = false;
|
||||
}
|
||||
return currHig;
|
||||
}
|
||||
|
||||
public static void UpdateSerieAnimation(Serie serie)
|
||||
{
|
||||
var serieType = serie.GetType();
|
||||
var animationType = AnimationType.LeftToRight;
|
||||
if (serieType.IsDefined(typeof(DefaultAnimationAttribute), false))
|
||||
{
|
||||
animationType = serieType.GetAttribute<DefaultAnimationAttribute>().type;
|
||||
}
|
||||
UpdateAnimationType(serie.animation, animationType);
|
||||
serie.animation.context.isAllItemAnimationEnd = true;
|
||||
}
|
||||
|
||||
public static void UpdateAnimationType(AnimationStyle animation, AnimationType defaultType)
|
||||
{
|
||||
animation.context.type = animation.type == AnimationType.Default
|
||||
? defaultType
|
||||
: animation.type;
|
||||
}
|
||||
|
||||
public static bool GetAnimationPosition(AnimationStyle animation, bool isY, Vector3 lp, Vector3 cp, float progress, ref Vector3 ip)
|
||||
{
|
||||
if (animation.context.type == AnimationType.AlongPath)
|
||||
{
|
||||
var dist = Vector3.Distance(lp, cp);
|
||||
var rate = (dist - animation.context.currentPathDistance + animation.GetCurrDetail()) / dist;
|
||||
ip = Vector3.Lerp(lp, cp, rate);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var startPos = isY ? new Vector3(-10000, progress) : new Vector3(progress, -10000);
|
||||
var endPos = isY ? new Vector3(10000, progress) : new Vector3(progress, 10000);
|
||||
|
||||
return UGLHelper.GetIntersection(lp, cp, startPos, endPos, ref ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Animation/AnimationStyleHelper.cs.meta
Normal file
11
Runtime/Component/Animation/AnimationStyleHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54cadaee0856b4f7085787fd450eec37
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Axis.meta
Normal file
8
Runtime/Component/Axis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 194a62edf7ec2484fa2eebbf5bde3e95
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Axis/AngleAxis.meta
Normal file
8
Runtime/Component/Axis/AngleAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28b88ca3453f04fbdb23a53b5bcb4bf7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
44
Runtime/Component/Axis/AngleAxis/AngleAxis.cs
Normal file
44
Runtime/Component/Axis/AngleAxis/AngleAxis.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Angle axis of Polar Coordinate.
|
||||
/// 极坐标系的角度轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[ComponentHandler(typeof(AngleAxisHandler), true)]
|
||||
public class AngleAxis : Axis
|
||||
{
|
||||
[SerializeField] private float m_StartAngle = 90;
|
||||
|
||||
/// <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; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_StartAngle, value)) SetAllDirty(); }
|
||||
}
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Value;
|
||||
m_SplitNumber = 12;
|
||||
m_StartAngle = 90;
|
||||
m_BoundaryGap = false;
|
||||
m_Data = new List<string>(12);
|
||||
splitLine.show = true;
|
||||
splitLine.lineStyle.type = LineStyle.Type.Solid;
|
||||
axisLabel.textLimit.enable = false;
|
||||
minMaxType = AxisMinMaxType.Custom;
|
||||
min = 0;
|
||||
max = 360;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AngleAxis/AngleAxis.cs.meta
Normal file
11
Runtime/Component/Axis/AngleAxis/AngleAxis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 787015be923a74e1da4000c7abc2dcdf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
134
Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs
Normal file
134
Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class AngleAxisHandler : MainComponentHandler<AngleAxis>
|
||||
{
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitAngleAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
component.startAngle = 90 - component.startAngle;
|
||||
UpdateAxisMinMaxValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawAngleAxis(vh, component);
|
||||
}
|
||||
|
||||
private void UpdateAxisMinMaxValue(AngleAxis axis, bool updateChart = true)
|
||||
{
|
||||
if (axis.IsCategory() || !axis.show) return;
|
||||
double tempMinValue = 0;
|
||||
double tempMaxValue = 0;
|
||||
SeriesHelper.GetYMinMaxValue(chart.series, null, axis.polarIndex, true, axis.inverse, out tempMinValue,
|
||||
out tempMaxValue, true);
|
||||
AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true);
|
||||
if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue)
|
||||
{
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.offset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
if (updateChart)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAxisLabelText(AngleAxis axis)
|
||||
{
|
||||
var runtimeWidth = 360;
|
||||
axis.UpdateLabelText(runtimeWidth, null, false);
|
||||
}
|
||||
|
||||
private void InitAngleAxis(AngleAxis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
|
||||
if (polar == null) return;
|
||||
PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight);
|
||||
var radius = polar.context.radius;
|
||||
axis.context.labelObjectList.Clear();
|
||||
|
||||
string objName = "axis_angle" + axis.index;
|
||||
var axisObj = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
axisObj.transform.localPosition = Vector3.zero;
|
||||
axisObj.SetActive(axis.show);
|
||||
axisObj.hideFlags = chart.chartHideFlags;
|
||||
ChartHelper.HideAllObject(axisObj);
|
||||
var splitNumber = AxisHelper.GetSplitNumber(axis, radius, null);
|
||||
var totalAngle = axis.startAngle;
|
||||
var total = 360;
|
||||
var cenPos = polar.context.center;
|
||||
var txtHig = axis.axisLabel.textStyle.GetFontSize(chart.theme.axis) + 2;
|
||||
var margin = axis.axisLabel.margin;
|
||||
var isCategory = axis.IsCategory();
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
for (int i = 0; i < splitNumber; i++)
|
||||
{
|
||||
float scaleAngle = AxisHelper.GetScaleWidth(axis, total, i, null);
|
||||
bool inside = axis.axisLabel.inside;
|
||||
var labelName = AxisHelper.GetLabelName(axis, total, i, axis.context.minValue, axis.context.maxValue,
|
||||
null, isPercentStack);
|
||||
var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform, new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(scaleAngle, txtHig), axis,
|
||||
chart.theme.axis, labelName);
|
||||
label.label.SetAlignment(axis.axisLabel.textStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
var pos = ChartHelper.GetPos(cenPos, radius + margin,
|
||||
isCategory ? (totalAngle + scaleAngle / 2) : totalAngle, true);
|
||||
AxisHelper.AdjustCircleLabelPos(label, pos, cenPos, txtHig, Vector3.zero);
|
||||
if (i == 0) axis.axisLabel.SetRelatedText(label.label, scaleAngle);
|
||||
axis.context.labelObjectList.Add(label);
|
||||
|
||||
totalAngle += scaleAngle;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAngleAxis(VertexHelper vh, AngleAxis angleAxis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(angleAxis.polarIndex);
|
||||
var radius = polar.context.radius;
|
||||
var cenPos = polar.context.center;
|
||||
var total = 360;
|
||||
var size = AxisHelper.GetScaleNumber(angleAxis, total, null);
|
||||
var currAngle = angleAxis.startAngle;
|
||||
var tickWidth = angleAxis.axisTick.GetWidth(chart.theme.axis.tickWidth);
|
||||
var tickLength = angleAxis.axisTick.GetLength(chart.theme.axis.tickLength);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var scaleWidth = AxisHelper.GetScaleWidth(angleAxis, total, i);
|
||||
var pos = ChartHelper.GetPos(cenPos, radius, currAngle, true);
|
||||
if (angleAxis.show && angleAxis.splitLine.show)
|
||||
{
|
||||
var splitLineColor = angleAxis.splitLine.GetColor(chart.theme.axis.splitLineColor);
|
||||
var lineWidth = angleAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth);
|
||||
UGL.DrawLine(vh, cenPos, pos, lineWidth, splitLineColor);
|
||||
}
|
||||
if (angleAxis.show && angleAxis.axisTick.show)
|
||||
{
|
||||
var tickY = radius + tickLength;
|
||||
var tickPos = ChartHelper.GetPos(cenPos, tickY, currAngle, true);
|
||||
UGL.DrawLine(vh, pos, tickPos, tickWidth, chart.theme.axis.lineColor);
|
||||
}
|
||||
currAngle += scaleWidth;
|
||||
}
|
||||
if (angleAxis.show && angleAxis.axisLine.show)
|
||||
{
|
||||
var lineWidth = angleAxis.axisLine.GetWidth(chart.theme.axis.lineWidth);
|
||||
var outsideRaidus = radius + lineWidth * 2;
|
||||
UGL.DrawDoughnut(vh, cenPos, radius, outsideRaidus, chart.theme.axis.lineColor, Color.clear);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs.meta
Normal file
11
Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83f228c42435c4619943a2f187c98e7b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
798
Runtime/Component/Axis/Axis.cs
Normal file
798
Runtime/Component/Axis/Axis.cs
Normal file
@@ -0,0 +1,798 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
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.
|
||||
/// 数值轴。适用于连续数据。
|
||||
/// </summary>
|
||||
Value,
|
||||
/// <summary>
|
||||
/// Category axis, suitable for discrete category data. Data should only be set via data for this type.
|
||||
/// 类目轴。适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。
|
||||
/// </summary>
|
||||
Category,
|
||||
/// <summary>
|
||||
/// Log axis, suitable for log data.
|
||||
/// 对数轴。适用于对数数据。
|
||||
/// </summary>
|
||||
Log,
|
||||
/// <summary>
|
||||
/// Time axis, suitable for continuous time series data.
|
||||
/// 时间轴。适用于连续的时序数据。
|
||||
/// </summary>
|
||||
Time
|
||||
}
|
||||
|
||||
/// <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
|
||||
}
|
||||
/// <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;
|
||||
[SerializeField] protected int m_GridIndex;
|
||||
[SerializeField] protected int m_PolarIndex;
|
||||
[SerializeField] protected int m_ParallelIndex;
|
||||
[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 = 0;
|
||||
[SerializeField] protected float m_Interval = 0;
|
||||
[SerializeField] protected bool m_BoundaryGap = true;
|
||||
[SerializeField] protected int m_MaxCache = 0;
|
||||
[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] private bool m_InsertDataToHead;
|
||||
[SerializeField] private IconStyle m_IconStyle = new IconStyle();
|
||||
[SerializeField] protected List<Sprite> m_Icons = new List<Sprite>();
|
||||
[SerializeField] protected List<string> m_Data = new List<string>();
|
||||
[SerializeField] protected AxisLine m_AxisLine = AxisLine.defaultAxisLine;
|
||||
[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;
|
||||
[SerializeField] protected AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea;
|
||||
|
||||
public AxisContext context = new AxisContext();
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show axis.
|
||||
/// 是否显示坐标轴。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the type of axis.
|
||||
/// 坐标轴类型。
|
||||
/// </summary>
|
||||
public AxisType type
|
||||
{
|
||||
get { return m_Type; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the type of axis minmax.
|
||||
/// 坐标轴刻度最大最小值显示类型。
|
||||
/// </summary>
|
||||
public AxisMinMaxType minMaxType
|
||||
{
|
||||
get { return m_MinMaxType; }
|
||||
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 index of the parallel on which the axis are located, by default, is in the first parallel.
|
||||
/// 坐标轴所在的 parallel 的索引,默认位于第一个 parallel。
|
||||
/// </summary>
|
||||
public int parallelIndex
|
||||
{
|
||||
get { return m_ParallelIndex; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ParallelIndex, 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>
|
||||
/// The minimun value of axis.Valid when `minMaxType` is `Custom`
|
||||
/// 设定的坐标轴刻度最小值,当minMaxType为Custom时有效。
|
||||
/// </summary>
|
||||
public float min
|
||||
{
|
||||
get { return m_Min; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Min, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The maximum value of axis.Valid when `minMaxType` is `Custom`
|
||||
/// 设定的坐标轴刻度最大值,当minMaxType为Custom时有效。
|
||||
/// </summary>
|
||||
public float max
|
||||
{
|
||||
get { return m_Max; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Max, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Number of segments that the axis is split into.
|
||||
/// 坐标轴的期望的分割段数。默认为0表示自动分割。
|
||||
/// </summary>
|
||||
public int splitNumber
|
||||
{
|
||||
get { return m_SplitNumber; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Compulsively set segmentation interval for axis.This is unavailable for category axis.
|
||||
/// 强制设置坐标轴分割间隔。无法在类目轴中使用。
|
||||
/// </summary>
|
||||
public float interval
|
||||
{
|
||||
get { return m_Interval; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The boundary gap on both sides of a coordinate axis, which is valid only for category axis with type: 'Category'.
|
||||
/// 坐标轴两边是否留白。只对类目轴有效。
|
||||
/// </summary>
|
||||
public bool boundaryGap
|
||||
{
|
||||
get { return IsCategory() ? m_BoundaryGap : false; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_BoundaryGap, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 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;
|
||||
if (PropertyUtil.SetStruct(ref m_LogBase, value)) SetAllDirty();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// On the log axis, if base e is the natural number, and is true, logBase fails.
|
||||
/// 对数轴是否以自然数 e 为底数,为 true 时 logBase 失效。
|
||||
/// </summary>
|
||||
public bool logBaseE
|
||||
{
|
||||
get { return m_LogBaseE; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_LogBaseE, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <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; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_MaxCache, value < 0 ? 0 : value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 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; }
|
||||
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; }
|
||||
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; }
|
||||
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>
|
||||
/// 类目数据对应的图标。
|
||||
/// </summary>
|
||||
public List<Sprite> icons
|
||||
{
|
||||
get { return m_Icons; }
|
||||
set { if (value != null) { m_Icons = 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(); } }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to add new data at the head or at the end of the list.
|
||||
/// 添加新数据时是在列表的头部还是尾部加入。
|
||||
/// </summary>
|
||||
public bool insertDataToHead
|
||||
{
|
||||
get { return m_InsertDataToHead; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_InsertDataToHead, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 图标样式。
|
||||
/// </summary>
|
||||
public IconStyle iconStyle
|
||||
{
|
||||
get { return m_IconStyle; }
|
||||
set { if (PropertyUtil.SetClass(ref m_IconStyle, value)) SetAllDirty(); }
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearComponentDirty()
|
||||
{
|
||||
base.ClearComponentDirty();
|
||||
axisName.ClearComponentDirty();
|
||||
axisLabel.ClearComponentDirty();
|
||||
}
|
||||
|
||||
public override void ClearVerticesDirty()
|
||||
{
|
||||
base.ClearVerticesDirty();
|
||||
axisLine.ClearVerticesDirty();
|
||||
axisTick.ClearVerticesDirty();
|
||||
splitLine.ClearVerticesDirty();
|
||||
splitArea.ClearVerticesDirty();
|
||||
}
|
||||
|
||||
public override void SetComponentDirty()
|
||||
{
|
||||
context.isNeedUpdateFilterData = true;
|
||||
base.SetComponentDirty();
|
||||
}
|
||||
|
||||
public Axis Clone()
|
||||
{
|
||||
var axis = new Axis();
|
||||
axis.show = show;
|
||||
axis.type = type;
|
||||
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.insertDataToHead = insertDataToHead;
|
||||
axis.iconStyle = iconStyle.Clone();
|
||||
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.icons = new List<Sprite>();
|
||||
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;
|
||||
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;
|
||||
insertDataToHead = axis.insertDataToHead;
|
||||
iconStyle.Copy(axis.iconStyle);
|
||||
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);
|
||||
ChartHelper.CopyList<Sprite>(icons, axis.icons);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空类目数据
|
||||
/// </summary>
|
||||
public override void ClearData()
|
||||
{
|
||||
m_Data.Clear();
|
||||
m_Icons.Clear();
|
||||
context.Clear();
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为类目轴。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsCategory()
|
||||
{
|
||||
return type == AxisType.Category;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为数值轴。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsValue()
|
||||
{
|
||||
return type == AxisType.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为对数轴。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsLog()
|
||||
{
|
||||
return type == AxisType.Log;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为时间轴。
|
||||
/// </summary>
|
||||
public bool IsTime()
|
||||
{
|
||||
return type == AxisType.Time;
|
||||
}
|
||||
|
||||
public bool IsLeft()
|
||||
{
|
||||
return position == AxisPosition.Left;
|
||||
}
|
||||
|
||||
public bool IsRight()
|
||||
{
|
||||
return position == AxisPosition.Right;
|
||||
}
|
||||
|
||||
public bool IsTop()
|
||||
{
|
||||
return position == AxisPosition.Top;
|
||||
}
|
||||
|
||||
public bool IsBottom()
|
||||
{
|
||||
return position == AxisPosition.Bottom;
|
||||
}
|
||||
|
||||
public void SetNeedUpdateFilterData()
|
||||
{
|
||||
context.isNeedUpdateFilterData = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加一个类目到类目数据列表
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
public void AddData(string category)
|
||||
{
|
||||
if (maxCache > 0)
|
||||
{
|
||||
while (m_Data.Count >= maxCache)
|
||||
{
|
||||
context.isNeedUpdateFilterData = true;
|
||||
m_Data.RemoveAt(m_InsertDataToHead ? m_Data.Count - 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_InsertDataToHead)
|
||||
m_Data.Insert(0, category);
|
||||
else
|
||||
m_Data.Add(category);
|
||||
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新类目数据
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="category"></param>
|
||||
public void UpdateData(int index, string category)
|
||||
{
|
||||
if (index >= 0 && index < m_Data.Count)
|
||||
{
|
||||
m_Data[index] = category;
|
||||
SetComponentDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加图标
|
||||
/// </summary>
|
||||
/// <param name="icon"></param>
|
||||
public void AddIcon(Sprite icon)
|
||||
{
|
||||
if (maxCache > 0)
|
||||
{
|
||||
while (m_Icons.Count > maxCache)
|
||||
{
|
||||
m_Icons.RemoveAt(m_InsertDataToHead ? m_Icons.Count - 1 : 0);
|
||||
}
|
||||
}
|
||||
if (m_InsertDataToHead) m_Icons.Insert(0, icon);
|
||||
else m_Icons.Add(icon);
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新图标
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="icon"></param>
|
||||
public void UpdateIcon(int index, Sprite icon)
|
||||
{
|
||||
if (index >= 0 && index < m_Icons.Count)
|
||||
{
|
||||
m_Icons[index] = icon;
|
||||
SetComponentDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <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>
|
||||
public string GetData(int index, DataZoom dataZoom)
|
||||
{
|
||||
var showData = GetDataList(dataZoom);
|
||||
if (index >= 0 && index < showData.Count)
|
||||
return showData[index];
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
public Sprite GetIcon(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_Icons.Count)
|
||||
return m_Icons[index];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得值在坐标轴上的距离
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="axisLength"></param>
|
||||
/// <returns></returns>
|
||||
public float GetDistance(double value, float axisLength)
|
||||
{
|
||||
if (context.minMaxRange == 0)
|
||||
return 0;
|
||||
|
||||
if (IsCategory() && boundaryGap)
|
||||
{
|
||||
var each = axisLength / data.Count;
|
||||
return (float)(each * (value + 0.5f));
|
||||
}
|
||||
else
|
||||
{
|
||||
return axisLength * (float)((value - context.minValue) / context.minMaxRange);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定区域缩放的类目数据列表
|
||||
/// </summary>
|
||||
/// <param name="dataZoom">区域缩放</param>
|
||||
/// <returns></returns>
|
||||
internal List<string> GetDataList(DataZoom dataZoom)
|
||||
{
|
||||
if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this))
|
||||
{
|
||||
UpdateFilterData(dataZoom);
|
||||
return context.filterData;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Data.Count > 0 ? m_Data : context.runtimeData;
|
||||
}
|
||||
}
|
||||
|
||||
internal List<string> GetDataList()
|
||||
{
|
||||
return m_Data.Count > 0 ? m_Data : context.runtimeData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新dataZoom对应的类目数据列表
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
internal void UpdateFilterData(DataZoom dataZoom)
|
||||
{
|
||||
if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this))
|
||||
{
|
||||
var data = GetDataList();
|
||||
context.UpdateFilterData(data, dataZoom);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得类目数据个数
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
internal int GetDataCount(DataZoom dataZoom)
|
||||
{
|
||||
return IsCategory() ? GetDataList(dataZoom).Count : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新刻度标签文字
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
internal void UpdateLabelText(float coordinateWidth, DataZoom dataZoom, bool forcePercent)
|
||||
{
|
||||
for (int i = 0; i < context.labelObjectList.Count; i++)
|
||||
{
|
||||
if (context.labelObjectList[i] != null)
|
||||
{
|
||||
var text = AxisHelper.GetLabelName(this, coordinateWidth, i, context.minValue, context.maxValue, dataZoom, forcePercent);
|
||||
context.labelObjectList[i].SetText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal Vector3 GetLabelObjectPosition(int index)
|
||||
{
|
||||
if (context.labelObjectList != null && index < context.labelObjectList.Count)
|
||||
return context.labelObjectList[index].GetPosition();
|
||||
else
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
internal void UpdateMinMaxValue(double minValue, double maxValue)
|
||||
{
|
||||
context.minValue = minValue;
|
||||
context.maxValue = maxValue;
|
||||
double tempRange = maxValue - minValue;
|
||||
if (context.minMaxRange != tempRange)
|
||||
{
|
||||
context.minMaxRange = tempRange;
|
||||
if (type == Axis.AxisType.Value && interval > 0)
|
||||
{
|
||||
SetComponentDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetLogValue(double value)
|
||||
{
|
||||
if (value <= 0 || value == 1)
|
||||
return 0;
|
||||
else
|
||||
return logBaseE ? (float)Math.Log(value) : (float)Math.Log(value, logBase);
|
||||
}
|
||||
|
||||
public int GetLogMinIndex()
|
||||
{
|
||||
return logBaseE
|
||||
? (int)Math.Log(context.minValue)
|
||||
: (int)Math.Log(context.minValue, logBase);
|
||||
}
|
||||
|
||||
public int GetLogMaxIndex()
|
||||
{
|
||||
return logBaseE
|
||||
? (int)Math.Log(context.maxValue)
|
||||
: (int)Math.Log(context.maxValue, logBase);
|
||||
}
|
||||
|
||||
public double GetLabelValue(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return context.minValue;
|
||||
else if (index > context.labelValueList.Count - 1)
|
||||
return context.maxValue;
|
||||
else
|
||||
return context.labelValueList[index];
|
||||
}
|
||||
|
||||
public double GetLastLabelValue()
|
||||
{
|
||||
if (context.labelValueList.Count > 0)
|
||||
return context.labelValueList[context.labelValueList.Count - 1];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/Axis.cs.meta
Normal file
11
Runtime/Component/Axis/Axis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5c29555575e04db98ee243c3b17f0ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
120
Runtime/Component/Axis/AxisContext.cs
Normal file
120
Runtime/Component/Axis/AxisContext.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class AxisContext : MainComponentContext
|
||||
{
|
||||
internal Orient orient { get; set; }
|
||||
public float x { get; internal set; }
|
||||
public float y { get; internal set; }
|
||||
public float width { get; internal set; }
|
||||
public float height { get; internal set; }
|
||||
public Vector3 position { get; internal set; }
|
||||
public float left { get; internal set; }
|
||||
public float right { get; internal set; }
|
||||
public float bottom { get; internal set; }
|
||||
public float top { get; internal set; }
|
||||
/// <summary>
|
||||
/// the current minimun value.
|
||||
/// 当前最小值。
|
||||
/// </summary>
|
||||
public double minValue { get; internal set; }
|
||||
/// <summary>
|
||||
/// the current maximum value.
|
||||
/// 当前最大值。
|
||||
/// </summary>
|
||||
public double maxValue { get; internal set; }
|
||||
/// <summary>
|
||||
/// the offset of zero position.
|
||||
/// 坐标轴原点在坐标轴的偏移。
|
||||
/// </summary>
|
||||
public float offset { get; internal set; }
|
||||
public double minMaxRange { get; internal set; }
|
||||
public float scaleWidth { get; internal set; }
|
||||
public float startAngle { get; set; }
|
||||
public double pointerValue { get; internal set; }
|
||||
public Vector3 pointerLabelPosition { get; internal set; }
|
||||
public double axisTooltipValue { get; internal set; }
|
||||
public List<string> runtimeData { get { return m_RuntimeData; } }
|
||||
public List<double> labelValueList { get { return m_LabelValueList; } }
|
||||
public List<ChartLabel> labelObjectList { get { return m_AxisLabelList; } }
|
||||
|
||||
internal List<string> filterData;
|
||||
internal bool lastCheckInverse { get; set; }
|
||||
internal bool isNeedUpdateFilterData;
|
||||
|
||||
private int filterStart;
|
||||
private int filterEnd;
|
||||
private int filterMinShow;
|
||||
|
||||
private List<ChartLabel> m_AxisLabelList = new List<ChartLabel>();
|
||||
private List<double> m_LabelValueList = new List<double>();
|
||||
private List<string> m_RuntimeData = new List<string>();
|
||||
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
m_RuntimeData.Clear();
|
||||
}
|
||||
|
||||
private List<string> m_EmptyFliter = new List<string>();
|
||||
/// <summary>
|
||||
/// 更新dataZoom对应的类目数据列表
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
internal void UpdateFilterData(List<string> data, DataZoom dataZoom)
|
||||
{
|
||||
int start = 0, end = 0;
|
||||
var range = Mathf.RoundToInt(data.Count * (dataZoom.end - dataZoom.start) / 100);
|
||||
if (range <= 0)
|
||||
range = 1;
|
||||
|
||||
if (dataZoom.context.invert)
|
||||
{
|
||||
end = Mathf.CeilToInt(data.Count * dataZoom.end / 100);
|
||||
start = end - range;
|
||||
if (start < 0) start = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = Mathf.FloorToInt(data.Count * dataZoom.start / 100);
|
||||
end = start + range;
|
||||
if (end > data.Count) end = data.Count;
|
||||
}
|
||||
|
||||
if (start != filterStart
|
||||
|| end != filterEnd
|
||||
|| dataZoom.minShowNum != filterMinShow
|
||||
|| isNeedUpdateFilterData)
|
||||
{
|
||||
filterStart = start;
|
||||
filterEnd = end;
|
||||
filterMinShow = dataZoom.minShowNum;
|
||||
isNeedUpdateFilterData = false;
|
||||
|
||||
if (data.Count > 0)
|
||||
{
|
||||
if (range < dataZoom.minShowNum)
|
||||
{
|
||||
if (dataZoom.minShowNum > data.Count)
|
||||
range = data.Count;
|
||||
else
|
||||
range = dataZoom.minShowNum;
|
||||
}
|
||||
filterData = data.GetRange(start, range);
|
||||
}
|
||||
else
|
||||
{
|
||||
filterData = data;
|
||||
}
|
||||
}
|
||||
else if (end == 0)
|
||||
{
|
||||
filterData = m_EmptyFliter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AxisContext.cs.meta
Normal file
11
Runtime/Component/Axis/AxisContext.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6525f065fa5d04663ab7026a3467f56e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
808
Runtime/Component/Axis/AxisHandler.cs
Normal file
808
Runtime/Component/Axis/AxisHandler.cs
Normal file
@@ -0,0 +1,808 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public abstract class AxisHandler<T> : MainComponentHandler
|
||||
where T : Axis
|
||||
{
|
||||
private static readonly string s_DefaultAxisName = "name";
|
||||
private double m_LastInterval = double.MinValue;
|
||||
private int m_LastSplitNumber = int.MinValue;
|
||||
public T component { get; internal set; }
|
||||
|
||||
internal override void SetComponent(MainComponent component)
|
||||
{
|
||||
this.component = (T)component;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
protected virtual Orient orient { get; }
|
||||
|
||||
protected void UpdatePointerValue(Axis axis)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
if (!grid.context.isPointerEnter)
|
||||
{
|
||||
axis.context.pointerValue = double.PositiveInfinity;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
var dataCount = chart.series.Count > 0 ? chart.series[0].GetDataList(dataZoom).Count : 0;
|
||||
var local = chart.pointerPos;
|
||||
|
||||
for (int j = 0; j < axis.GetDataCount(dataZoom); j++)
|
||||
{
|
||||
if (axis is YAxis)
|
||||
{
|
||||
float splitWid = AxisHelper.GetDataWidth(axis, grid.context.height, dataCount, dataZoom);
|
||||
float pY = grid.context.y + j * splitWid;
|
||||
if ((axis.boundaryGap && (local.y > pY && local.y <= pY + splitWid))
|
||||
|| (!axis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2)))
|
||||
{
|
||||
axis.context.pointerValue = j;
|
||||
axis.context.pointerLabelPosition = axis.GetLabelObjectPosition(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float splitWid = AxisHelper.GetDataWidth(axis, grid.context.width, dataCount, dataZoom);
|
||||
float pX = grid.context.x + j * splitWid;
|
||||
if ((axis.boundaryGap && (local.x > pX && local.x <= pX + splitWid))
|
||||
|| (!axis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2)))
|
||||
{
|
||||
axis.context.pointerValue = j;
|
||||
axis.context.pointerLabelPosition = axis.GetLabelObjectPosition(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis is YAxis)
|
||||
{
|
||||
var yRate = axis.context.minMaxRange / grid.context.height;
|
||||
|
||||
var yValue = yRate * (chart.pointerPos.y - grid.context.y - axis.context.offset);
|
||||
if (axis.context.minValue > 0)
|
||||
yValue += axis.context.minValue;
|
||||
|
||||
var labelX = axis.GetLabelObjectPosition(0).x;
|
||||
axis.context.pointerValue = yValue;
|
||||
axis.context.pointerLabelPosition = new Vector3(labelX, chart.pointerPos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
var xRate = axis.context.minMaxRange / grid.context.width;
|
||||
|
||||
var xValue = xRate * (chart.pointerPos.x - grid.context.x - axis.context.offset);
|
||||
if (axis.context.minValue > 0)
|
||||
xValue += axis.context.minValue;
|
||||
|
||||
var labelY = axis.GetLabelObjectPosition(0).y;
|
||||
axis.context.pointerValue = xValue;
|
||||
axis.context.pointerLabelPosition = new Vector3(chart.pointerPos.x, labelY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAxisMinMaxValue(int axisIndex, Axis axis, bool updateChart = true)
|
||||
{
|
||||
if (!axis.show)
|
||||
return;
|
||||
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
axis.context.minValue = 0;
|
||||
axis.context.maxValue = SeriesHelper.GetMaxSerieDataCount(chart.series) - 1;
|
||||
axis.context.minMaxRange = axis.context.maxValue;
|
||||
return;
|
||||
}
|
||||
|
||||
double tempMinValue = 0;
|
||||
double tempMaxValue = 0;
|
||||
chart.GetSeriesMinMaxValue(axis, axisIndex, out tempMinValue, out tempMaxValue);
|
||||
|
||||
if (tempMinValue != axis.context.minValue
|
||||
|| tempMaxValue != axis.context.maxValue
|
||||
|| m_LastInterval != axis.interval
|
||||
|| m_LastSplitNumber != axis.splitNumber)
|
||||
{
|
||||
m_LastSplitNumber = axis.splitNumber;
|
||||
m_LastInterval = axis.interval;
|
||||
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.offset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
|
||||
UpdateAxisTickValueList(axis);
|
||||
|
||||
if (tempMinValue != 0 || tempMaxValue != 0)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
if (grid != null && axis is XAxis && axis.IsValue())
|
||||
{
|
||||
axis.context.offset = axis.context.minValue > 0
|
||||
? 0
|
||||
: (axis.context.maxValue < 0
|
||||
? grid.context.width
|
||||
: (float)(Math.Abs(axis.context.minValue) * (grid.context.width
|
||||
/ (Math.Abs(axis.context.minValue) + Math.Abs(axis.context.maxValue))))
|
||||
);
|
||||
}
|
||||
if (grid != null && axis is YAxis && axis.IsValue())
|
||||
{
|
||||
axis.context.offset = axis.context.minValue > 0
|
||||
? 0
|
||||
: (axis.context.maxValue < 0
|
||||
? grid.context.height
|
||||
: (float)(Math.Abs(axis.context.minValue) * (grid.context.height
|
||||
/ (Math.Abs(axis.context.minValue) + Math.Abs(axis.context.maxValue))))
|
||||
);
|
||||
}
|
||||
}
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
if (dataZoom != null && dataZoom.enable)
|
||||
{
|
||||
if (axis is XAxis)
|
||||
dataZoom.SetXAxisIndexValueInfo(axisIndex, tempMinValue, tempMaxValue);
|
||||
else
|
||||
dataZoom.SetYAxisIndexValueInfo(axisIndex, tempMinValue, tempMaxValue);
|
||||
}
|
||||
if (updateChart)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
if (grid == null || axis == null)
|
||||
return;
|
||||
|
||||
float runtimeWidth = axis is XAxis ? grid.context.width : grid.context.height;
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
|
||||
axis.UpdateLabelText(runtimeWidth, dataZoom, isPercentStack);
|
||||
}
|
||||
|
||||
internal static void UpdateAxisTickValueList(Axis axis)
|
||||
{
|
||||
if (axis.IsTime())
|
||||
{
|
||||
var lastCount = axis.context.labelValueList.Count;
|
||||
DateTimeUtil.UpdateTimeAxisDateTimeList(axis.context.labelValueList, (int)axis.context.minValue,
|
||||
(int)axis.context.maxValue, axis.splitNumber);
|
||||
|
||||
if (axis.context.labelValueList.Count != lastCount)
|
||||
axis.SetAllDirty();
|
||||
}
|
||||
else if (axis.IsValue())
|
||||
{
|
||||
var list = axis.context.labelValueList;
|
||||
var lastCount = list.Count;
|
||||
list.Clear();
|
||||
|
||||
var range = axis.context.maxValue - axis.context.minValue;
|
||||
if (range <= 0)
|
||||
return;
|
||||
|
||||
double tick = axis.interval;
|
||||
|
||||
if (axis.interval == 0)
|
||||
{
|
||||
if (axis.splitNumber > 0)
|
||||
{
|
||||
tick = range / axis.splitNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
var each = GetTick(range);
|
||||
tick = each;
|
||||
if (range / tick > 8)
|
||||
tick = 2 * each;
|
||||
else if (range / tick < 4)
|
||||
tick = each / 2;
|
||||
}
|
||||
}
|
||||
var value = 0d;
|
||||
if (Mathf.Approximately((float)(axis.context.minValue % tick), 0))
|
||||
{
|
||||
value = axis.context.minValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(axis.context.minValue);
|
||||
value = Math.Ceiling(axis.context.minValue / tick) * tick;
|
||||
}
|
||||
while (value <= axis.context.maxValue)
|
||||
{
|
||||
list.Add(value);
|
||||
value += tick;
|
||||
|
||||
if (list.Count > 20)
|
||||
break;
|
||||
}
|
||||
if (!ChartHelper.IsEquals(axis.context.maxValue, list[list.Count - 1]))
|
||||
{
|
||||
list.Add(axis.context.maxValue);
|
||||
}
|
||||
if (lastCount != list.Count)
|
||||
{
|
||||
axis.SetAllDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static double GetTick(double max)
|
||||
{
|
||||
var bigger = Math.Ceiling(Math.Abs(max));
|
||||
int n = 1;
|
||||
while (bigger / (Mathf.Pow(10, n)) > 10)
|
||||
{
|
||||
n++;
|
||||
}
|
||||
return Math.Pow(10, n);
|
||||
}
|
||||
|
||||
internal void CheckValueLabelActive(Axis axis, int i, ChartLabel label, Vector3 pos)
|
||||
{
|
||||
if (axis.IsValue())
|
||||
{
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var dist = GetLabelPosition(0, 1).x - pos.x;
|
||||
label.SetLabelActive(dist > label.label.GetPreferredWidth());
|
||||
}
|
||||
else if (i == axis.context.labelValueList.Count - 1)
|
||||
{
|
||||
var dist = pos.x - GetLabelPosition(0, i - 1).x;
|
||||
label.SetLabelActive(dist > label.label.GetPreferredWidth());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var dist = GetLabelPosition(0, 1).y - pos.y;
|
||||
label.SetLabelActive(dist > label.label.GetPreferredHeight());
|
||||
}
|
||||
else if (i == axis.context.labelValueList.Count - 1)
|
||||
{
|
||||
var dist = pos.y - GetLabelPosition(0, i - 1).y;
|
||||
label.SetLabelActive(dist > label.label.GetPreferredHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void InitAxis(Axis axis, Axis relativedAxis, BaseChart chart, AxisHandler<T> handler,
|
||||
Orient orient, float axisStartX, float axisStartY, float axisLength, float relativedLength)
|
||||
{
|
||||
chart.InitAxisRuntimeData(axis);
|
||||
|
||||
var objName = ChartCached.GetComponentObjectName(axis);
|
||||
var axisObj = ChartHelper.AddObject(objName,
|
||||
chart.transform,
|
||||
chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor,
|
||||
chart.chartPivot,
|
||||
chart.chartSizeDelta);
|
||||
|
||||
axisObj.SetActive(axis.show);
|
||||
axisObj.hideFlags = chart.chartHideFlags;
|
||||
ChartHelper.HideAllObject(axisObj);
|
||||
|
||||
axis.gameObject = axisObj;
|
||||
axis.context.labelObjectList.Clear();
|
||||
|
||||
if (!axis.show)
|
||||
return;
|
||||
|
||||
var axisLabelTextStyle = axis.axisLabel.textStyle;
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
var splitNumber = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
|
||||
var totalWidth = 0f;
|
||||
var eachWidth = AxisHelper.GetEachWidth(axis, axisLength, dataZoom);
|
||||
var gapWidth = axis.boundaryGap ? eachWidth / 2 : 0;
|
||||
|
||||
var textWidth = axis.axisLabel.width > 0
|
||||
? axis.axisLabel.width
|
||||
: (orient == Orient.Horizonal
|
||||
? AxisHelper.GetScaleWidth(axis, axisLength, 0, dataZoom)
|
||||
: (axisStartX - chart.chartX)
|
||||
);
|
||||
|
||||
var textHeight = axis.axisLabel.height > 0
|
||||
? axis.axisLabel.height
|
||||
: 20f;
|
||||
|
||||
if (axis.IsCategory() && axis.boundaryGap)
|
||||
{
|
||||
splitNumber -= 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < splitNumber; i++)
|
||||
{
|
||||
ChartLabel label;
|
||||
|
||||
var labelWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom);
|
||||
var inside = axis.axisLabel.inside;
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
|
||||
var labelName = AxisHelper.GetLabelName(axis, axisLength, i,
|
||||
axis.context.minValue,
|
||||
axis.context.maxValue,
|
||||
dataZoom, isPercentStack);
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
label = ChartHelper.AddAxisLabelObject(splitNumber, i,
|
||||
ChartCached.GetAxisLabelName(i),
|
||||
axisObj.transform,
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(textWidth, textHeight),
|
||||
axis, chart.theme.axis, labelName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((inside && axis.IsLeft()) || (!inside && axis.IsRight()))
|
||||
{
|
||||
label = ChartHelper.AddAxisLabelObject(splitNumber, i,
|
||||
ChartCached.GetAxisLabelName(i),
|
||||
axisObj.transform,
|
||||
Vector2.zero,
|
||||
Vector2.zero,
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(textWidth, textHeight),
|
||||
axis, chart.theme.axis, labelName);
|
||||
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleLeft));
|
||||
}
|
||||
else
|
||||
{
|
||||
label = ChartHelper.AddAxisLabelObject(splitNumber, i,
|
||||
ChartCached.GetAxisLabelName(i),
|
||||
axisObj.transform,
|
||||
Vector2.zero,
|
||||
Vector2.zero,
|
||||
new Vector2(1, 0.5f),
|
||||
new Vector2(textWidth, textHeight),
|
||||
axis, chart.theme.axis, labelName);
|
||||
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleRight));
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
axis.axisLabel.SetRelatedText(label.label, labelWidth);
|
||||
|
||||
var pos = handler.GetLabelPosition(totalWidth + gapWidth, i);
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.IsRight())
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleLeft));
|
||||
else
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleRight));
|
||||
}
|
||||
|
||||
label.SetPosition(pos);
|
||||
handler.CheckValueLabelActive(axis, i, label, pos);
|
||||
|
||||
axis.context.labelObjectList.Add(label);
|
||||
|
||||
totalWidth += labelWidth;
|
||||
}
|
||||
if (axis.axisName.show)
|
||||
{
|
||||
ChartText axisName = null;
|
||||
|
||||
var axisNameTextStyle = axis.axisName.textStyle;
|
||||
var offset = axisNameTextStyle.offset;
|
||||
|
||||
var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.offset);
|
||||
var zeroPos = new Vector3(axisStartX, axisStartY + relativedDist);
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
switch (axis.axisName.location)
|
||||
{
|
||||
case AxisName.Location.Start:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform,
|
||||
new Vector2(1, 0.5f),
|
||||
new Vector2(1, 0.5f),
|
||||
new Vector2(1, 0.5f),
|
||||
new Vector2(100, 20),
|
||||
axisNameTextStyle, chart.theme.axis);
|
||||
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleRight));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Top
|
||||
? new Vector2(zeroPos.x - offset.x, axisStartY + relativedLength + offset.y + axis.offset)
|
||||
: new Vector2(zeroPos.x - offset.x, zeroPos.y + offset.y + axis.offset));
|
||||
break;
|
||||
|
||||
case AxisName.Location.Middle:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform,
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(100, 20),
|
||||
axisNameTextStyle, chart.theme.axis);
|
||||
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Top
|
||||
? new Vector2(axisStartX + axisLength / 2 + offset.x, axisStartY + relativedLength - offset.y + axis.offset)
|
||||
: new Vector2(axisStartX + axisLength / 2 + offset.x, axisStartY - offset.y + axis.offset));
|
||||
break;
|
||||
|
||||
case AxisName.Location.End:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform,
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(100, 20),
|
||||
axisNameTextStyle, chart.theme.axis);
|
||||
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleLeft));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Top
|
||||
? new Vector2(axisStartX + axisLength + offset.x, axisStartY + relativedLength + offset.y + axis.offset)
|
||||
: new Vector2(axisStartX + axisLength + offset.x, zeroPos.y + offset.y + axis.offset));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (axis.axisName.location)
|
||||
{
|
||||
case AxisName.Location.Start:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100, 20), axisNameTextStyle,
|
||||
chart.theme.axis);
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Right ?
|
||||
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY - offset.y) :
|
||||
new Vector2(zeroPos.x + offset.x + axis.offset, axisStartY - offset.y));
|
||||
break;
|
||||
|
||||
case AxisName.Location.Middle:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, new Vector2(1, 0.5f),
|
||||
new Vector2(1, 0.5f), new Vector2(1, 0.5f), new Vector2(100, 20), axisNameTextStyle,
|
||||
chart.theme.axis);
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleRight));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Right ?
|
||||
new Vector2(axisStartX + relativedLength - offset.x + axis.offset, axisStartY + axisLength / 2 + offset.y) :
|
||||
new Vector2(axisStartX - offset.x + axis.offset, axisStartY + axisLength / 2 + offset.y));
|
||||
break;
|
||||
|
||||
case AxisName.Location.End:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100, 20), axisNameTextStyle,
|
||||
chart.theme.axis);
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Right ?
|
||||
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY + axisLength + offset.y) :
|
||||
new Vector2(zeroPos.x + offset.x + axis.offset, axisStartY + axisLength + offset.y));
|
||||
break;
|
||||
}
|
||||
}
|
||||
axisName.SetText(axis.axisName.name);
|
||||
}
|
||||
}
|
||||
|
||||
internal static Vector3 GetLabelPosition(int i, Orient orient, Axis axis, Axis relativedAxis, AxisTheme theme,
|
||||
float scaleWid, float axisStartX, float axisStartY, float axisLength, float relativedLength)
|
||||
{
|
||||
var inside = axis.axisLabel.inside;
|
||||
var fontSize = axis.axisLabel.textStyle.GetFontSize(theme);
|
||||
var current = axis.offset;
|
||||
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
scaleWid = axis.context.minMaxRange != 0
|
||||
? axis.GetDistance(axis.GetLabelValue(i), axisLength)
|
||||
: 0;
|
||||
}
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
if (axis.axisLabel.onZero && relativedAxis != null)
|
||||
axisStartY += relativedAxis.context.offset;
|
||||
|
||||
if (axis.IsTop())
|
||||
axisStartY += relativedLength;
|
||||
|
||||
if ((inside && axis.IsBottom()) || (!inside && axis.IsTop()))
|
||||
current += axisStartY + axis.axisLabel.margin + fontSize / 2;
|
||||
else
|
||||
current += axisStartY - axis.axisLabel.margin - fontSize / 2;
|
||||
|
||||
return new Vector3(axisStartX + scaleWid, current) + axis.axisLabel.textStyle.offsetv3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.axisLabel.onZero && relativedAxis != null)
|
||||
axisStartX += relativedAxis.context.offset;
|
||||
|
||||
if (axis.IsRight())
|
||||
axisStartX += relativedLength;
|
||||
|
||||
if ((inside && axis.IsLeft()) || (!inside && axis.IsRight()))
|
||||
current += axisStartX + axis.axisLabel.margin;
|
||||
else
|
||||
current += axisStartX - axis.axisLabel.margin;
|
||||
|
||||
return new Vector3(current, axisStartY + scaleWid) + axis.axisLabel.textStyle.offsetv3;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DrawAxisLine(VertexHelper vh, Axis axis, AxisTheme theme, Orient orient,
|
||||
float startX, float startY, float axisLength)
|
||||
{
|
||||
var inverse = axis.IsValue() && axis.inverse;
|
||||
var offset = AxisHelper.GetAxisLineArrowOffset(axis);
|
||||
|
||||
var lineWidth = axis.axisLine.GetWidth(theme.lineWidth);
|
||||
var lineType = axis.axisLine.GetType(theme.lineType);
|
||||
var lineColor = axis.axisLine.GetColor(theme.lineColor);
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
var left = new Vector3(startX - lineWidth - (inverse ? offset : 0), startY);
|
||||
var right = new Vector3(startX + axisLength + lineWidth + (!inverse ? offset : 0), startY);
|
||||
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, left, right, lineColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
var bottom = new Vector3(startX, startY - lineWidth - (inverse ? offset : 0));
|
||||
var top = new Vector3(startX, startY + axisLength + lineWidth + (!inverse ? offset : 0));
|
||||
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, bottom, top, lineColor);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DrawAxisTick(VertexHelper vh, Axis axis, AxisTheme theme, DataZoom dataZoom,
|
||||
Orient orient, float startX, float startY, float axisLength)
|
||||
{
|
||||
var lineWidth = axis.axisLine.GetWidth(theme.lineWidth);
|
||||
var tickLength = axis.axisTick.GetLength(theme.tickLength);
|
||||
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
var size = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
|
||||
|
||||
var current = orient == Orient.Horizonal
|
||||
? startX
|
||||
: startY;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var scaleWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom);
|
||||
if (i == 0 && (!axis.axisTick.showStartTick || axis.axisTick.alignWithLabel))
|
||||
{
|
||||
current += scaleWidth;
|
||||
continue;
|
||||
}
|
||||
if (i == size - 1 && !axis.axisTick.showEndTick)
|
||||
{
|
||||
current += scaleWidth;
|
||||
continue;
|
||||
}
|
||||
if (axis.axisTick.show)
|
||||
{
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
float pX = axis.IsTime()
|
||||
? (startX + axis.GetDistance(axis.GetLabelValue(i), axisLength))
|
||||
: current;
|
||||
|
||||
if (axis.boundaryGap && axis.axisTick.alignWithLabel)
|
||||
pX -= scaleWidth / 2;
|
||||
|
||||
var sY = 0f;
|
||||
var eY = 0f;
|
||||
if ((axis.axisTick.inside && axis.IsBottom())
|
||||
|| (!axis.axisTick.inside && axis.IsTop()))
|
||||
{
|
||||
sY = startY + axis.offset + lineWidth;
|
||||
eY = sY + tickLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
sY = startY + axis.offset - lineWidth;
|
||||
eY = sY - tickLength;
|
||||
}
|
||||
|
||||
UGL.DrawLine(vh, new Vector3(pX, sY), new Vector3(pX, eY),
|
||||
axis.axisTick.GetWidth(theme.tickWidth),
|
||||
axis.axisTick.GetColor(theme.tickColor));
|
||||
}
|
||||
else
|
||||
{
|
||||
float pY = axis.IsTime()
|
||||
? (startY + axis.GetDistance(axis.GetLabelValue(i), axisLength))
|
||||
: current;
|
||||
|
||||
if (axis.boundaryGap && axis.axisTick.alignWithLabel)
|
||||
pY -= scaleWidth / 2;
|
||||
|
||||
var sX = 0f;
|
||||
var eX = 0f;
|
||||
if ((axis.axisTick.inside && axis.IsLeft())
|
||||
|| (!axis.axisTick.inside && axis.IsRight()))
|
||||
{
|
||||
sX = startX + axis.offset + lineWidth;
|
||||
eX = sX + tickLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
sX = startX + axis.offset - lineWidth;
|
||||
eX = sX - tickLength;
|
||||
}
|
||||
|
||||
UGL.DrawLine(vh, new Vector3(sX, pY), new Vector3(eX, pY),
|
||||
axis.axisTick.GetWidth(theme.tickWidth),
|
||||
axis.axisTick.GetColor(theme.tickColor));
|
||||
}
|
||||
}
|
||||
current += scaleWidth;
|
||||
}
|
||||
}
|
||||
if (axis.show && axis.axisLine.show && axis.axisLine.showArrow)
|
||||
{
|
||||
var lineY = startY + axis.offset;
|
||||
var inverse = axis.IsValue() && axis.inverse;
|
||||
var axisArrow = axis.axisLine.arrow;
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
if (inverse)
|
||||
{
|
||||
var startPos = new Vector3(startX + axisLength, lineY);
|
||||
var arrowPos = new Vector3(startX, lineY);
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
|
||||
axisArrow.offset, axisArrow.dent,
|
||||
axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var arrowPosX = startX + axisLength + lineWidth;
|
||||
var startPos = new Vector3(startX, lineY);
|
||||
var arrowPos = new Vector3(arrowPosX, lineY);
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
|
||||
axisArrow.offset, axisArrow.dent,
|
||||
axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inverse)
|
||||
{
|
||||
var startPos = new Vector3(startX, startY + axisLength);
|
||||
var arrowPos = new Vector3(startX, startY);
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
|
||||
axisArrow.offset, axisArrow.dent,
|
||||
axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var startPos = new Vector3(startX, startY);
|
||||
var arrowPos = new Vector3(startX, startY + axisLength + lineWidth);
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
|
||||
axisArrow.offset, axisArrow.dent,
|
||||
axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DrawAxisSplit(VertexHelper vh, Axis axis, AxisTheme theme, DataZoom dataZoom,
|
||||
Orient orient, float startX, float startY, float axisLength, float splitLength)
|
||||
{
|
||||
var lineColor = axis.splitLine.GetColor(theme.splitLineColor);
|
||||
var lineWidth = axis.splitLine.GetWidth(theme.lineWidth);
|
||||
var lineType = axis.splitLine.GetType(theme.splitLineType);
|
||||
|
||||
var size = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
|
||||
if (axis.IsTime())
|
||||
{
|
||||
size += 1;
|
||||
if (!ChartHelper.IsEquals(axis.GetLastLabelValue(), axis.context.maxValue))
|
||||
size += 1;
|
||||
}
|
||||
|
||||
var current = orient == Orient.Horizonal
|
||||
? startX
|
||||
: startY;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var scaleWidth = AxisHelper.GetScaleWidth(axis, axisLength, axis.IsTime() ? i : i + 1, dataZoom);
|
||||
|
||||
if (axis.boundaryGap && axis.axisTick.alignWithLabel)
|
||||
current -= scaleWidth / 2;
|
||||
|
||||
if (axis.splitArea.show && i <= size - 1)
|
||||
{
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
UGL.DrawQuadrilateral(vh,
|
||||
new Vector2(current, startY),
|
||||
new Vector2(current, startY + splitLength),
|
||||
new Vector2(current + scaleWidth, startY + splitLength),
|
||||
new Vector2(current + scaleWidth, startY),
|
||||
axis.splitArea.GetColor(i, theme));
|
||||
}
|
||||
else
|
||||
{
|
||||
UGL.DrawQuadrilateral(vh,
|
||||
new Vector2(startX, current),
|
||||
new Vector2(startX + splitLength, current),
|
||||
new Vector2(startX + splitLength, current + scaleWidth),
|
||||
new Vector2(startX, current + scaleWidth),
|
||||
axis.splitArea.GetColor(i, theme));
|
||||
}
|
||||
|
||||
}
|
||||
if (axis.splitLine.show)
|
||||
{
|
||||
if (axis.splitLine.NeedShow(i))
|
||||
{
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
ChartDrawer.DrawLineStyle(vh,
|
||||
lineType,
|
||||
lineWidth,
|
||||
new Vector3(current, startY),
|
||||
new Vector3(current, startY + splitLength),
|
||||
lineColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChartDrawer.DrawLineStyle(vh,
|
||||
lineType,
|
||||
lineWidth,
|
||||
new Vector3(startX, current),
|
||||
new Vector3(startX + splitLength, current),
|
||||
lineColor);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
current += scaleWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AxisHandler.cs.meta
Normal file
11
Runtime/Component/Axis/AxisHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0babef8a2708b4745bbb0a0648913a35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
532
Runtime/Component/Axis/AxisHelper.cs
Normal file
532
Runtime/Component/Axis/AxisHelper.cs
Normal file
@@ -0,0 +1,532 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public static class AxisHelper
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 包含箭头偏移的轴线长度
|
||||
/// </summary>
|
||||
/// <param name="axis"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetAxisLineArrowOffset(Axis axis)
|
||||
{
|
||||
if (axis.axisLine.show && axis.axisLine.showArrow && axis.axisLine.arrow.offset > 0)
|
||||
{
|
||||
return axis.axisLine.arrow.offset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得分割段数
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)
|
||||
{
|
||||
if (axis.type == Axis.AxisType.Value)
|
||||
{
|
||||
return axis.context.labelValueList.Count - 1;
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
return axis.context.labelValueList.Count;
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
return axis.splitNumber > 0 ? axis.splitNumber : 4;
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Category)
|
||||
{
|
||||
int dataCount = axis.GetDataList(dataZoom).Count;
|
||||
if (!axis.boundaryGap)
|
||||
dataCount -= 1;
|
||||
if (dataCount <= 0)
|
||||
dataCount = 1;
|
||||
|
||||
if (axis.splitNumber <= 0)
|
||||
{
|
||||
if (dataCount <= 10) return dataCount;
|
||||
else
|
||||
{
|
||||
for (int i = 4; i < 6; i++)
|
||||
{
|
||||
if (dataCount % i == 0) return i;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.splitNumber <= 0 || axis.splitNumber > dataCount)
|
||||
return dataCount;
|
||||
if (dataCount >= axis.splitNumber * 2)
|
||||
return axis.splitNumber;
|
||||
else
|
||||
return dataCount;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得一个类目数据在坐标系中代表的宽度
|
||||
/// </summary>
|
||||
/// <param name="coordinateWidth"></param>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)
|
||||
{
|
||||
if (dataCount < 1)
|
||||
dataCount = 1;
|
||||
var categoryCount = axis.GetDataCount(dataZoom);
|
||||
int segment = (axis.boundaryGap ? categoryCount : categoryCount - 1);
|
||||
segment = segment <= 0 ? dataCount : segment;
|
||||
if (segment <= 0)
|
||||
segment = 1;
|
||||
|
||||
return coordinateWidth / segment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得标签显示的名称
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="minValue"></param>
|
||||
/// <param name="maxValue"></param>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetLabelName(Axis axis, float coordinateWidth, int index, double minValue, double maxValue,
|
||||
DataZoom dataZoom, bool forcePercent)
|
||||
{
|
||||
int split = GetSplitNumber(axis, coordinateWidth, dataZoom);
|
||||
if (axis.type == Axis.AxisType.Value)
|
||||
{
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
maxValue = axis.max != 0 ? axis.max : 1;
|
||||
double value = 0;
|
||||
if (forcePercent)
|
||||
maxValue = 100;
|
||||
|
||||
value = axis.GetLabelValue(index);
|
||||
if (axis.inverse)
|
||||
{
|
||||
value = -value;
|
||||
minValue = -minValue;
|
||||
maxValue = -maxValue;
|
||||
}
|
||||
if (forcePercent)
|
||||
return string.Format("{0}%", (int)value);
|
||||
else
|
||||
return axis.axisLabel.GetFormatterContent(index, value, minValue, maxValue);
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
float value = axis.logBaseE
|
||||
? Mathf.Exp(axis.GetLogMinIndex() + index)
|
||||
: Mathf.Pow(axis.logBase, axis.GetLogMinIndex() + index);
|
||||
if (axis.inverse)
|
||||
{
|
||||
value = -value;
|
||||
minValue = -minValue;
|
||||
maxValue = -maxValue;
|
||||
}
|
||||
return axis.axisLabel.GetFormatterContent(index, value, minValue, maxValue, true);
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
return string.Empty;
|
||||
if (index > axis.context.labelValueList.Count - 1)
|
||||
return string.Empty;
|
||||
|
||||
var value = axis.GetLabelValue(index);
|
||||
return axis.axisLabel.GetFormatterDateTime(index, value, minValue, maxValue);
|
||||
}
|
||||
var showData = axis.GetDataList(dataZoom);
|
||||
int dataCount = showData.Count;
|
||||
if (dataCount <= 0)
|
||||
return "";
|
||||
int rate = axis.boundaryGap ? (dataCount / split) : (dataCount - 1) / split;
|
||||
if (rate == 0) rate = 1;
|
||||
if (axis.insertDataToHead)
|
||||
{
|
||||
if (index > 0)
|
||||
{
|
||||
var residue = (dataCount - 1) - split * rate;
|
||||
var newIndex = residue + (index - 1) * rate;
|
||||
if (newIndex < 0)
|
||||
newIndex = 0;
|
||||
return axis.axisLabel.GetFormatterContent(newIndex, showData[newIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.boundaryGap && coordinateWidth / dataCount > 5)
|
||||
return string.Empty;
|
||||
else
|
||||
return axis.axisLabel.GetFormatterContent(0, showData[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int newIndex = index * rate;
|
||||
if (newIndex < dataCount)
|
||||
{
|
||||
return axis.axisLabel.GetFormatterContent(newIndex, showData[newIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.boundaryGap && coordinateWidth / dataCount > 5)
|
||||
return string.Empty;
|
||||
else
|
||||
return axis.axisLabel.GetFormatterContent(dataCount - 1, showData[dataCount - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得分割线条数
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
|
||||
{
|
||||
int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom);
|
||||
if (splitNum == 0)
|
||||
return 0;
|
||||
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
var dataCount = axis.GetDataList(dataZoom).Count;
|
||||
var scaleNum = 0;
|
||||
|
||||
if (axis.boundaryGap)
|
||||
{
|
||||
scaleNum = dataCount > 2 && dataCount % splitNum == 0
|
||||
? splitNum + 1
|
||||
: splitNum + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dataCount < splitNum) scaleNum = splitNum;
|
||||
else scaleNum = dataCount > 2 && dataCount % splitNum == 0
|
||||
? splitNum
|
||||
: splitNum + 1;
|
||||
}
|
||||
return scaleNum;
|
||||
}
|
||||
else if (axis.IsTime())
|
||||
return splitNum;
|
||||
else
|
||||
return splitNum + 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得分割段宽度
|
||||
/// </summary>
|
||||
/// <param name="coordinateWidth"></param>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)
|
||||
{
|
||||
if (index < 0)
|
||||
return 0;
|
||||
|
||||
int num = GetScaleNumber(axis, coordinateWidth, dataZoom);
|
||||
int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom);
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
var value = axis.GetLabelValue(index);
|
||||
var lastValue = axis.GetLabelValue(index - 1);
|
||||
return axis.context.minMaxRange == 0
|
||||
? 0
|
||||
: (float)(coordinateWidth * (value - lastValue) / axis.context.minMaxRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = axis.GetDataList(dataZoom);
|
||||
if (axis.IsCategory() && data.Count > 0)
|
||||
{
|
||||
var count = axis.boundaryGap ? data.Count : data.Count - 1;
|
||||
int tick = count / splitNum;
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
var each = coordinateWidth / count;
|
||||
if (axis.insertDataToHead)
|
||||
{
|
||||
var max = axis.boundaryGap ? splitNum : splitNum - 1;
|
||||
if (index == 1)
|
||||
{
|
||||
if (axis.axisTick.alignWithLabel)
|
||||
return each * tick;
|
||||
else
|
||||
return coordinateWidth - each * tick * max;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count < splitNum)
|
||||
return each;
|
||||
else
|
||||
return each * (count / splitNum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var max = axis.boundaryGap ? num - 1 : num;
|
||||
if (index >= max)
|
||||
{
|
||||
if (axis.axisTick.alignWithLabel)
|
||||
return each * tick;
|
||||
else
|
||||
return coordinateWidth - each * tick * (index - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count < splitNum)
|
||||
return each;
|
||||
else
|
||||
return each * (count / splitNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (splitNum <= 0)
|
||||
return 0;
|
||||
else
|
||||
return coordinateWidth / splitNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
|
||||
{
|
||||
var data = axis.GetDataList(dataZoom);
|
||||
if (data.Count > 0)
|
||||
{
|
||||
var count = axis.boundaryGap ? data.Count : data.Count - 1;
|
||||
return count > 0 ? coordinateWidth / count : coordinateWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
int num = GetScaleNumber(axis, coordinateWidth, dataZoom) - 1;
|
||||
return num > 0 ? coordinateWidth / num : coordinateWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 调整最大最小值
|
||||
/// </summary>
|
||||
/// <param name="minValue"></param>
|
||||
/// <param name="maxValue"></param>
|
||||
public static void AdjustMinMaxValue(Axis axis, ref double minValue, ref double maxValue, bool needFormat, int ceilRate = 0)
|
||||
{
|
||||
if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
int minSplit = 0;
|
||||
int maxSplit = 0;
|
||||
maxValue = ChartHelper.GetMaxLogValue(maxValue, axis.logBase, axis.logBaseE, out maxSplit);
|
||||
minValue = ChartHelper.GetMinLogValue(minValue, axis.logBase, axis.logBaseE, out minSplit);
|
||||
axis.splitNumber = (minSplit > 0 && maxSplit > 0) ? (maxSplit + minSplit - 1) : (maxSplit + minSplit);
|
||||
return;
|
||||
}
|
||||
if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
}
|
||||
else if (axis.minMaxType == Axis.AxisMinMaxType.Custom)
|
||||
{
|
||||
if (axis.min != 0 || axis.max != 0)
|
||||
{
|
||||
if (axis.inverse)
|
||||
{
|
||||
minValue = -axis.max;
|
||||
maxValue = -axis.min;
|
||||
}
|
||||
else
|
||||
{
|
||||
minValue = axis.min;
|
||||
maxValue = axis.max;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ceilRate == 0) ceilRate = axis.ceilRate;
|
||||
switch (axis.minMaxType)
|
||||
{
|
||||
case Axis.AxisMinMaxType.Default:
|
||||
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
{
|
||||
}
|
||||
else if (minValue > 0 && maxValue > 0)
|
||||
{
|
||||
minValue = 0;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
}
|
||||
else if (minValue < 0 && maxValue < 0)
|
||||
{
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
}
|
||||
break;
|
||||
|
||||
case Axis.AxisMinMaxType.MinMax:
|
||||
|
||||
minValue = ceilRate != 0 ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = ceilRate != 0 ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool NeedShowSplit(Axis axis)
|
||||
{
|
||||
if (!axis.show)
|
||||
return false;
|
||||
if (axis.IsCategory() && axis.GetDataList().Count <= 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void AdjustCircleLabelPos(ChartText txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
|
||||
{
|
||||
var txtWidth = txt.GetPreferredWidth();
|
||||
var sizeDelta = new Vector2(txtWidth, txt.GetPreferredHeight());
|
||||
txt.SetSizeDelta(sizeDelta);
|
||||
var diff = pos.x - cenPos.x;
|
||||
if (diff < -1f) //left
|
||||
{
|
||||
pos = new Vector3(pos.x - txtWidth / 2, pos.y);
|
||||
}
|
||||
else if (diff > 1f) //right
|
||||
{
|
||||
pos = new Vector3(pos.x + txtWidth / 2, pos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
float y = pos.y > cenPos.y ? pos.y + txtHig / 2 : pos.y - txtHig / 2;
|
||||
pos = new Vector3(pos.x, y);
|
||||
}
|
||||
txt.SetLocalPosition(pos + offset);
|
||||
}
|
||||
|
||||
public static void AdjustCircleLabelPos(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
|
||||
{
|
||||
var txtWidth = txt.label.GetPreferredWidth();
|
||||
var sizeDelta = new Vector2(txtWidth, txt.label.GetPreferredHeight());
|
||||
txt.label.SetSizeDelta(sizeDelta);
|
||||
var diff = pos.x - cenPos.x;
|
||||
if (diff < -1f) //left
|
||||
{
|
||||
pos = new Vector3(pos.x - txtWidth / 2, pos.y);
|
||||
}
|
||||
else if (diff > 1f) //right
|
||||
{
|
||||
pos = new Vector3(pos.x + txtWidth / 2, pos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
float y = pos.y > cenPos.y ? pos.y + txtHig / 2 : pos.y - txtHig / 2;
|
||||
pos = new Vector3(pos.x, y);
|
||||
}
|
||||
txt.SetPosition(pos + offset);
|
||||
}
|
||||
|
||||
public static void AdjustRadiusAxisLabelPos(ChartText txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
|
||||
{
|
||||
var txtWidth = txt.GetPreferredWidth();
|
||||
var sizeDelta = new Vector2(txtWidth, txt.GetPreferredHeight());
|
||||
txt.SetSizeDelta(sizeDelta);
|
||||
var diff = pos.y - cenPos.y;
|
||||
if (diff > 20f) //left
|
||||
{
|
||||
pos = new Vector3(pos.x - txtWidth / 2, pos.y);
|
||||
}
|
||||
else if (diff < -20f) //right
|
||||
{
|
||||
pos = new Vector3(pos.x + txtWidth / 2, pos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
float y = pos.y > cenPos.y ? pos.y + txtHig / 2 : pos.y - txtHig / 2;
|
||||
pos = new Vector3(pos.x, y);
|
||||
}
|
||||
txt.SetLocalPosition(pos);
|
||||
}
|
||||
|
||||
public static float GetAxisPosition(GridCoord grid, Axis axis, double value, int dataCount = 0, DataZoom dataZoom = null)
|
||||
{
|
||||
var gridHeight = axis is YAxis ? grid.context.height : grid.context.width;
|
||||
var gridXY = axis is YAxis ? grid.context.y : grid.context.x;
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
if (dataCount == 0) dataCount = axis.data.Count;
|
||||
var categoryIndex = (int)value;
|
||||
var scaleWid = AxisHelper.GetDataWidth(axis, gridHeight, dataCount, dataZoom);
|
||||
float startY = gridXY + (axis.boundaryGap ? scaleWid / 2 : 0);
|
||||
return startY + scaleWid * categoryIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
var yDataHig = (axis.context.minMaxRange == 0) ? 0f :
|
||||
(float)((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight);
|
||||
return gridXY + yDataHig;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static float GetAxisPosition(GridCoord grid, Axis axis, float scaleWidth, double value)
|
||||
{
|
||||
return GetAxisPositionInternal(grid, axis, scaleWidth, value, true);
|
||||
}
|
||||
|
||||
public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value)
|
||||
{
|
||||
return GetAxisPositionInternal(grid, axis, scaleWidth, value, false);
|
||||
}
|
||||
|
||||
private static float GetAxisPositionInternal(GridCoord grid, Axis axis, float scaleWidth, double value, bool includeGridXY)
|
||||
{
|
||||
var isY = axis is YAxis;
|
||||
var gridHeight = isY ? grid.context.height : grid.context.width;
|
||||
var gridXY = isY ? grid.context.y : grid.context.x;
|
||||
|
||||
if (axis.IsLog())
|
||||
{
|
||||
int minIndex = axis.GetLogMinIndex();
|
||||
float nowIndex = axis.GetLogValue(value);
|
||||
return includeGridXY
|
||||
? gridXY + (nowIndex - minIndex) / axis.splitNumber * gridHeight
|
||||
: (nowIndex - minIndex) / axis.splitNumber * gridHeight;
|
||||
}
|
||||
else if (axis.IsCategory())
|
||||
{
|
||||
var categoryIndex = (int)value;
|
||||
return includeGridXY
|
||||
? gridXY + (axis.boundaryGap ? scaleWidth / 2 : 0) + scaleWidth * categoryIndex
|
||||
: (axis.boundaryGap ? scaleWidth / 2 : 0) + scaleWidth * categoryIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
var yDataHig = (axis.context.minMaxRange == 0) ? 0f :
|
||||
(float)((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight);
|
||||
return includeGridXY
|
||||
? gridXY + yDataHig
|
||||
: yDataHig;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AxisHelper.cs.meta
Normal file
11
Runtime/Component/Axis/AxisHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 566e3426780cc4339a1fb92d9604d21f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
311
Runtime/Component/Axis/AxisLabel.cs
Normal file
311
Runtime/Component/Axis/AxisLabel.cs
Normal file
@@ -0,0 +1,311 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings related to axis label.
|
||||
/// 坐标轴刻度标签的相关设置。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisLabel : ChildComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private string m_Formatter;
|
||||
[SerializeField] private int m_Interval = 0;
|
||||
[SerializeField] private bool m_Inside = false;
|
||||
[SerializeField] private float m_Margin;
|
||||
[SerializeField] private string m_NumericFormatter = "";
|
||||
[SerializeField] private bool m_ShowAsPositiveNumber = false;
|
||||
[SerializeField] private bool m_OnZero = false;
|
||||
[SerializeField] private float m_Width = 0f;
|
||||
[SerializeField] private float m_Height = 0f;
|
||||
[SerializeField] private bool m_ShowStartLabel = true;
|
||||
[SerializeField] private bool m_ShowEndLabel = true;
|
||||
[SerializeField] private TextLimit m_TextLimit = new TextLimit();
|
||||
[SerializeField] private TextStyle m_TextStyle = new TextStyle();
|
||||
private DelegateAxisLabelFormatter m_FormatterFunction;
|
||||
|
||||
/// <summary>
|
||||
/// Set this to false to prevent the axis label from appearing.
|
||||
/// 是否显示刻度标签。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The display interval of the axis label.
|
||||
/// 坐标轴刻度标签的显示间隔,在类目轴中有效。0表示显示所有标签,1表示隔一个隔显示一个标签,以此类推。
|
||||
/// </summary>
|
||||
public int interval
|
||||
{
|
||||
get { return m_Interval; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Set this to true so the axis labels face the inside direction.
|
||||
/// 刻度标签是否朝内,默认朝外。
|
||||
/// </summary>
|
||||
public bool inside
|
||||
{
|
||||
get { return m_Inside; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Inside, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The margin between the axis label and the axis line.
|
||||
/// 刻度标签与轴线之间的距离。
|
||||
/// </summary>
|
||||
public float margin
|
||||
{
|
||||
get { return m_Margin; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Margin, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 图例内容字符串模版格式器。支持用 \n 换行。
|
||||
/// 模板变量为图例名称 {value}。
|
||||
/// </summary>
|
||||
public string formatter
|
||||
{
|
||||
get { return m_Formatter; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Formatter, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Standard numeric format strings.
|
||||
/// 标准数字格式字符串。用于将数值格式化显示为字符串。
|
||||
/// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。
|
||||
/// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string numericFormatter
|
||||
{
|
||||
get { return m_NumericFormatter; }
|
||||
set { if (PropertyUtil.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show negative number as positive number.
|
||||
/// 将负数数值显示为正数。一般和`Serie`的`showAsPositiveNumber`配合使用。
|
||||
/// </summary>
|
||||
public bool showAsPositiveNumber
|
||||
{
|
||||
get { return m_ShowAsPositiveNumber; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowAsPositiveNumber, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刻度标签显示在0刻度上。
|
||||
/// </summary>
|
||||
public bool onZero
|
||||
{
|
||||
get { return m_OnZero; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_OnZero, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 文本的宽。为0时会自动匹配。
|
||||
/// </summary>
|
||||
public float width
|
||||
{
|
||||
get { return m_Width; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 文本的高。为0时会自动匹配。
|
||||
/// </summary>
|
||||
public float height
|
||||
{
|
||||
get { return m_Height; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to display the first label.
|
||||
/// 是否显示第一个文本。
|
||||
/// </summary>
|
||||
public bool showStartLabel
|
||||
{
|
||||
get { return m_ShowStartLabel; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowStartLabel, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to display the last label.
|
||||
/// 是否显示最后一个文本。
|
||||
/// </summary>
|
||||
public bool showEndLabel
|
||||
{
|
||||
get { return m_ShowEndLabel; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowEndLabel, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 文本限制。
|
||||
/// </summary>
|
||||
public TextLimit textLimit
|
||||
{
|
||||
get { return m_TextLimit; }
|
||||
set { if (value != null) { m_TextLimit = value; SetComponentDirty(); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The text style of axis name.
|
||||
/// 文本样式。
|
||||
/// </summary>
|
||||
public TextStyle textStyle
|
||||
{
|
||||
get { return m_TextStyle; }
|
||||
set { if (PropertyUtil.SetClass(ref m_TextStyle, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
public DelegateAxisLabelFormatter formatterFunction
|
||||
{
|
||||
set { m_FormatterFunction = value; }
|
||||
}
|
||||
|
||||
public override bool componentDirty { get { return m_ComponentDirty || m_TextLimit.componentDirty; } }
|
||||
public override void ClearComponentDirty()
|
||||
{
|
||||
base.ClearComponentDirty();
|
||||
textLimit.ClearComponentDirty();
|
||||
}
|
||||
|
||||
public static AxisLabel defaultAxisLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
return new AxisLabel()
|
||||
{
|
||||
m_Show = true,
|
||||
m_Interval = 0,
|
||||
m_Inside = false,
|
||||
m_Margin = 8,
|
||||
m_TextStyle = new TextStyle(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public AxisLabel Clone()
|
||||
{
|
||||
var axisLabel = new AxisLabel();
|
||||
axisLabel.show = show;
|
||||
axisLabel.formatter = formatter;
|
||||
axisLabel.interval = interval;
|
||||
axisLabel.inside = inside;
|
||||
axisLabel.margin = margin;
|
||||
axisLabel.numericFormatter = numericFormatter;
|
||||
axisLabel.width = width;
|
||||
axisLabel.height = height;
|
||||
axisLabel.showStartLabel = showStartLabel;
|
||||
axisLabel.showEndLabel = showEndLabel;
|
||||
axisLabel.textLimit = textLimit.Clone();
|
||||
axisLabel.textStyle.Copy(textStyle);
|
||||
return axisLabel;
|
||||
}
|
||||
|
||||
public void Copy(AxisLabel axisLabel)
|
||||
{
|
||||
show = axisLabel.show;
|
||||
formatter = axisLabel.formatter;
|
||||
interval = axisLabel.interval;
|
||||
inside = axisLabel.inside;
|
||||
margin = axisLabel.margin;
|
||||
numericFormatter = axisLabel.numericFormatter;
|
||||
width = axisLabel.width;
|
||||
height = axisLabel.height;
|
||||
showStartLabel = axisLabel.showStartLabel;
|
||||
showEndLabel = axisLabel.showEndLabel;
|
||||
textLimit.Copy(axisLabel.textLimit);
|
||||
textStyle.Copy(axisLabel.textStyle);
|
||||
}
|
||||
|
||||
public void SetRelatedText(ChartText txt, float labelWidth)
|
||||
{
|
||||
m_TextLimit.SetRelatedText(txt, labelWidth);
|
||||
}
|
||||
|
||||
public string GetFormatterContent(int labelIndex, string category)
|
||||
{
|
||||
if (m_FormatterFunction != null)
|
||||
{
|
||||
return m_FormatterFunction(labelIndex, 0, category);
|
||||
}
|
||||
if (string.IsNullOrEmpty(category))
|
||||
return category;
|
||||
|
||||
if (string.IsNullOrEmpty(m_Formatter))
|
||||
{
|
||||
return m_TextLimit.GetLimitContent(category);
|
||||
}
|
||||
else
|
||||
{
|
||||
var content = m_Formatter;
|
||||
FormatterHelper.ReplaceAxisLabelContent(ref content, category);
|
||||
return m_TextLimit.GetLimitContent(content);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFormatterContent(int labelIndex, double value, double minValue, double maxValue, bool isLog = false)
|
||||
{
|
||||
if (showAsPositiveNumber && value < 0)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
}
|
||||
if (m_FormatterFunction != null)
|
||||
{
|
||||
return m_FormatterFunction(labelIndex, value, null);
|
||||
}
|
||||
if (string.IsNullOrEmpty(m_Formatter))
|
||||
{
|
||||
if (isLog)
|
||||
{
|
||||
return ChartCached.NumberToStr(value, numericFormatter);
|
||||
}
|
||||
if (minValue >= -1 && minValue <= 1 && maxValue >= -1 && maxValue <= 1)
|
||||
{
|
||||
int minAcc = ChartHelper.GetFloatAccuracy(minValue);
|
||||
int maxAcc = ChartHelper.GetFloatAccuracy(maxValue);
|
||||
int curAcc = ChartHelper.GetFloatAccuracy(value);
|
||||
int acc = Mathf.Max(Mathf.Max(minAcc, maxAcc), curAcc);
|
||||
return ChartCached.FloatToStr(value, numericFormatter, acc);
|
||||
}
|
||||
return ChartCached.NumberToStr(value, numericFormatter);
|
||||
}
|
||||
else
|
||||
{
|
||||
var content = m_Formatter;
|
||||
FormatterHelper.ReplaceAxisLabelContent(ref content, numericFormatter, value);
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFormatterDateTime(int labelIndex, double value, double minValue, double maxValue)
|
||||
{
|
||||
if (m_FormatterFunction != null)
|
||||
{
|
||||
return m_FormatterFunction(labelIndex, value, null);
|
||||
}
|
||||
var timestamp = (int)value;
|
||||
var dateTime = DateTimeUtil.GetDateTime(timestamp);
|
||||
var dateString = string.Empty;
|
||||
if (string.IsNullOrEmpty(numericFormatter))
|
||||
{
|
||||
dateString = DateTimeUtil.GetDateTimeFormatString(dateTime, maxValue - minValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateString = dateTime.ToString(numericFormatter);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(m_Formatter))
|
||||
{
|
||||
var content = m_Formatter;
|
||||
FormatterHelper.ReplaceAxisLabelContent(ref content, dateString);
|
||||
return m_TextLimit.GetLimitContent(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_TextLimit.GetLimitContent(dateString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AxisLabel.cs.meta
Normal file
11
Runtime/Component/Axis/AxisLabel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 051f9473d1beb4e0bb35aa1600cb44bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
78
Runtime/Component/Axis/AxisLine.cs
Normal file
78
Runtime/Component/Axis/AxisLine.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings related to axis line.
|
||||
/// 坐标轴轴线。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AxisLine : BaseLine
|
||||
{
|
||||
[SerializeField] private bool m_OnZero;
|
||||
[SerializeField] private bool m_ShowArrow;
|
||||
[SerializeField] private ArrowStyle m_Arrow = new ArrowStyle();
|
||||
|
||||
/// <summary>
|
||||
/// When mutiple axes exists, this option can be used to specify which axis can be "onZero" to.
|
||||
/// X 轴或者 Y 轴的轴线是否在另一个轴的 0 刻度上,只有在另一个轴为数值轴且包含 0 刻度时有效。
|
||||
/// </summary>
|
||||
public bool onZero
|
||||
{
|
||||
get { return m_OnZero; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_OnZero, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to show the arrow symbol of axis.
|
||||
/// 是否显示箭头。
|
||||
/// </summary>
|
||||
public bool showArrow
|
||||
{
|
||||
get { return m_ShowArrow; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowArrow, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the arrow of line.
|
||||
/// 轴线箭头。
|
||||
/// </summary>
|
||||
public ArrowStyle arrow
|
||||
{
|
||||
get { return m_Arrow; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Arrow, value)) SetVerticesDirty(); }
|
||||
}
|
||||
public static AxisLine defaultAxisLine
|
||||
{
|
||||
get
|
||||
{
|
||||
var axisLine = new AxisLine
|
||||
{
|
||||
m_Show = true,
|
||||
m_OnZero = true,
|
||||
m_ShowArrow = false,
|
||||
m_Arrow = new ArrowStyle(),
|
||||
m_LineStyle = new LineStyle(LineStyle.Type.None),
|
||||
};
|
||||
return axisLine;
|
||||
}
|
||||
}
|
||||
|
||||
public AxisLine Clone()
|
||||
{
|
||||
var axisLine = new AxisLine();
|
||||
axisLine.show = show;
|
||||
axisLine.onZero = onZero;
|
||||
axisLine.showArrow = showArrow;
|
||||
axisLine.arrow = arrow.Clone();
|
||||
return axisLine;
|
||||
}
|
||||
|
||||
public void Copy(AxisLine axisLine)
|
||||
{
|
||||
base.Copy(axisLine);
|
||||
onZero = axisLine.onZero;
|
||||
showArrow = axisLine.showArrow;
|
||||
arrow.Copy(axisLine.arrow);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AxisLine.cs.meta
Normal file
11
Runtime/Component/Axis/AxisLine.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2748c2a8789724709aa76f6056eb708d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
99
Runtime/Component/Axis/AxisName.cs
Normal file
99
Runtime/Component/Axis/AxisName.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// the name of axis.
|
||||
/// 坐标轴名称。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisName : ChildComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// the location of axis name.
|
||||
/// 坐标轴名称显示位置。
|
||||
/// </summary>
|
||||
public enum Location
|
||||
{
|
||||
Start,
|
||||
Middle,
|
||||
End
|
||||
}
|
||||
[SerializeField] private bool m_Show;
|
||||
[SerializeField] private string m_Name;
|
||||
[SerializeField] private Location m_Location;
|
||||
[SerializeField] private TextStyle m_TextStyle = new TextStyle();
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show axis name.
|
||||
/// 是否显示坐标名称。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the name of axis.
|
||||
/// 坐标轴名称。
|
||||
/// </summary>
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Name, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Location of axis name.
|
||||
/// 坐标轴名称显示位置。
|
||||
/// </summary>
|
||||
public Location location
|
||||
{
|
||||
get { return m_Location; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Location, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The text style of axis name.
|
||||
/// 文本样式。
|
||||
/// </summary>
|
||||
public TextStyle textStyle
|
||||
{
|
||||
get { return m_TextStyle; }
|
||||
set { if (PropertyUtil.SetClass(ref m_TextStyle, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
public static AxisName defaultAxisName
|
||||
{
|
||||
get
|
||||
{
|
||||
return new AxisName()
|
||||
{
|
||||
m_Show = false,
|
||||
m_Name = "axisName",
|
||||
m_Location = Location.End,
|
||||
m_TextStyle = new TextStyle(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public AxisName Clone()
|
||||
{
|
||||
var axisName = new AxisName();
|
||||
axisName.show = show;
|
||||
axisName.name = name;
|
||||
axisName.location = location;
|
||||
axisName.textStyle.Copy(textStyle);
|
||||
return axisName;
|
||||
}
|
||||
|
||||
public void Copy(AxisName axisName)
|
||||
{
|
||||
show = axisName.show;
|
||||
name = axisName.name;
|
||||
location = axisName.location;
|
||||
textStyle.Copy(axisName.textStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AxisName.cs.meta
Normal file
11
Runtime/Component/Axis/AxisName.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 878555ba3c6b1479f94f38185700531e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
81
Runtime/Component/Axis/AxisSplitArea.cs
Normal file
81
Runtime/Component/Axis/AxisSplitArea.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Split area of axis in grid area, not shown by default.
|
||||
/// 坐标轴在 grid 区域中的分隔区域,默认不显示。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisSplitArea : ChildComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show;
|
||||
[SerializeField] private List<Color32> m_Color;
|
||||
|
||||
/// <summary>
|
||||
/// Set this to true to show the splitArea.
|
||||
/// 是否显示分隔区域。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Color of split area. SplitArea color could also be set in color array,
|
||||
/// which the split lines would take as their colors in turns.
|
||||
/// Dark and light colors in turns are used by default.
|
||||
/// 分隔区域颜色。分隔区域会按数组中颜色的顺序依次循环设置颜色。默认是一个深浅的间隔色。
|
||||
/// </summary>
|
||||
public List<Color32> color
|
||||
{
|
||||
get { return m_Color; }
|
||||
set { if (value != null) { m_Color = value; SetVerticesDirty(); } }
|
||||
}
|
||||
|
||||
public static AxisSplitArea defaultSplitArea
|
||||
{
|
||||
get
|
||||
{
|
||||
return new AxisSplitArea()
|
||||
{
|
||||
m_Show = false,
|
||||
m_Color = new List<Color32>() { }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public AxisSplitArea Clone()
|
||||
{
|
||||
var axisSplitArea = new AxisSplitArea();
|
||||
axisSplitArea.show = show;
|
||||
axisSplitArea.color = new List<Color32>();
|
||||
ChartHelper.CopyList(axisSplitArea.color, color);
|
||||
return axisSplitArea;
|
||||
}
|
||||
|
||||
public void Copy(AxisSplitArea splitArea)
|
||||
{
|
||||
show = splitArea.show;
|
||||
color.Clear();
|
||||
ChartHelper.CopyList(color, splitArea.color);
|
||||
}
|
||||
|
||||
public Color32 GetColor(int index, BaseAxisTheme theme)
|
||||
{
|
||||
if (color.Count > 0)
|
||||
{
|
||||
var i = index % color.Count;
|
||||
return color[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
var i = index % theme.splitAreaColors.Count;
|
||||
return theme.splitAreaColors[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AxisSplitArea.cs.meta
Normal file
11
Runtime/Component/Axis/AxisSplitArea.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18702fd7797054670af64546b7304bb4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
59
Runtime/Component/Axis/AxisSplitLine.cs
Normal file
59
Runtime/Component/Axis/AxisSplitLine.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Split line of axis in grid area.
|
||||
/// 坐标轴在 grid 区域中的分隔线。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisSplitLine : BaseLine
|
||||
{
|
||||
[SerializeField] private int m_Interval;
|
||||
|
||||
public int interval
|
||||
{
|
||||
get { return m_Interval; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public override bool vertsDirty { get { return m_VertsDirty || m_LineStyle.anyDirty; } }
|
||||
public override void ClearVerticesDirty()
|
||||
{
|
||||
base.ClearVerticesDirty();
|
||||
m_LineStyle.ClearVerticesDirty();
|
||||
}
|
||||
public static AxisSplitLine defaultSplitLine
|
||||
{
|
||||
get
|
||||
{
|
||||
return new AxisSplitLine()
|
||||
{
|
||||
m_Show = false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public AxisSplitLine Clone()
|
||||
{
|
||||
var axisSplitLine = new AxisSplitLine();
|
||||
axisSplitLine.show = show;
|
||||
axisSplitLine.interval = interval;
|
||||
axisSplitLine.lineStyle = lineStyle.Clone();
|
||||
return axisSplitLine;
|
||||
}
|
||||
|
||||
public void Copy(AxisSplitLine splitLine)
|
||||
{
|
||||
base.Copy(splitLine);
|
||||
interval = splitLine.interval;
|
||||
}
|
||||
|
||||
internal bool NeedShow(int index)
|
||||
{
|
||||
return show && (interval == 0 || index % (interval + 1) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AxisSplitLine.cs.meta
Normal file
11
Runtime/Component/Axis/AxisSplitLine.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3da942a7a6bea44e2998ed993c0641ab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
93
Runtime/Component/Axis/AxisTick.cs
Normal file
93
Runtime/Component/Axis/AxisTick.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings related to axis tick.
|
||||
/// 坐标轴刻度相关设置。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AxisTick : BaseLine
|
||||
{
|
||||
[SerializeField] private bool m_AlignWithLabel;
|
||||
[SerializeField] private bool m_Inside;
|
||||
[SerializeField] private bool m_ShowStartTick;
|
||||
[SerializeField] private bool m_ShowEndTick;
|
||||
|
||||
/// <summary>
|
||||
/// Align axis tick with label, which is available only when boundaryGap is set to be true in category axis.
|
||||
/// 类目轴中在 boundaryGap 为 true 的时候有效,可以保证刻度线和标签对齐。
|
||||
/// </summary>
|
||||
public bool alignWithLabel
|
||||
{
|
||||
get { return m_AlignWithLabel; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_AlignWithLabel, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Set this to true so the axis labels face the inside direction.
|
||||
/// 坐标轴刻度是否朝内,默认朝外。
|
||||
/// </summary>
|
||||
public bool inside
|
||||
{
|
||||
get { return m_Inside; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Inside, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to display the first tick.
|
||||
/// 是否显示第一个刻度。
|
||||
/// </summary>
|
||||
public bool showStartTick
|
||||
{
|
||||
get { return m_ShowStartTick; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowStartTick, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to display the last tick.
|
||||
/// 是否显示最后一个刻度。
|
||||
/// </summary>
|
||||
public bool showEndTick
|
||||
{
|
||||
get { return m_ShowEndTick; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowEndTick, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public static AxisTick defaultTick
|
||||
{
|
||||
get
|
||||
{
|
||||
var tick = new AxisTick
|
||||
{
|
||||
m_Show = true,
|
||||
m_AlignWithLabel = false,
|
||||
m_Inside = false,
|
||||
m_ShowStartTick = true,
|
||||
m_ShowEndTick = true
|
||||
};
|
||||
return tick;
|
||||
}
|
||||
}
|
||||
|
||||
public AxisTick Clone()
|
||||
{
|
||||
var axisTick = new AxisTick();
|
||||
axisTick.show = show;
|
||||
axisTick.alignWithLabel = alignWithLabel;
|
||||
axisTick.inside = inside;
|
||||
axisTick.showStartTick = showStartTick;
|
||||
axisTick.showEndTick = showEndTick;
|
||||
axisTick.lineStyle = lineStyle.Clone();
|
||||
return axisTick;
|
||||
}
|
||||
|
||||
public void Copy(AxisTick axisTick)
|
||||
{
|
||||
show = axisTick.show;
|
||||
alignWithLabel = axisTick.alignWithLabel;
|
||||
inside = axisTick.inside;
|
||||
showStartTick = axisTick.showStartTick;
|
||||
showEndTick = axisTick.showEndTick;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/AxisTick.cs.meta
Normal file
11
Runtime/Component/Axis/AxisTick.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60278762ed892450d85e27b7df8f997e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Axis/ParallelAxis.meta
Normal file
8
Runtime/Component/Axis/ParallelAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24693180b2a2e41b2ab4025b2bbebf01
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
32
Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs
Normal file
32
Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
[RequireChartComponent(typeof(ParallelCoord))]
|
||||
[ComponentHandler(typeof(ParallelAxisHander), true)]
|
||||
public class ParallelAxis : Axis
|
||||
{
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Value;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 0;
|
||||
m_BoundaryGap = true;
|
||||
m_Position = AxisPosition.Bottom;
|
||||
m_Offset = 0;
|
||||
m_Data = new List<string>() { "x1", "x2", "x3", "x4", "x5" };
|
||||
m_Icons = new List<Sprite>(5);
|
||||
splitLine.show = false;
|
||||
splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axisLabel.textLimit.enable = true;
|
||||
iconStyle.show = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs.meta
Normal file
11
Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7bc01c54f4d6485389fd57c37810c74
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
163
Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs
Normal file
163
Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class ParallelAxisHander : AxisHandler<ParallelAxis>
|
||||
{
|
||||
private Orient m_Orient;
|
||||
private ParallelCoord m_Parallel;
|
||||
|
||||
protected override Orient orient { get { return m_Orient; } }
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitParallelAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateContext(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
UpdateContext(component);
|
||||
DrawParallelAxisSplit(vh, component);
|
||||
DrawParallelAxisLine(vh, component);
|
||||
DrawParallelAxisTick(vh, component);
|
||||
}
|
||||
|
||||
private void UpdateContext(ParallelAxis axis)
|
||||
{
|
||||
var parallel = chart.GetChartComponent<ParallelCoord>(axis.parallelIndex);
|
||||
if (parallel == null)
|
||||
return;
|
||||
|
||||
m_Orient = parallel.orient;
|
||||
m_Parallel = parallel;
|
||||
var axisCount = chart.GetChartComponentNum<ParallelAxis>();
|
||||
|
||||
if (m_Orient == Orient.Horizonal)
|
||||
{
|
||||
var each = axisCount > 1 ? parallel.context.height / (axisCount - 1) : 0;
|
||||
axis.context.x = parallel.context.x;
|
||||
axis.context.y = parallel.context.y + (axis.index) * each;
|
||||
axis.context.width = parallel.context.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
var each = axisCount > 1 ? parallel.context.width / (axisCount - 1) : 0;
|
||||
axis.context.x = parallel.context.x + (axis.index) * each;
|
||||
axis.context.y = parallel.context.y;
|
||||
axis.context.width = parallel.context.height;
|
||||
}
|
||||
axis.context.orient = m_Orient;
|
||||
axis.context.height = 0;
|
||||
axis.context.position = new Vector3(axis.context.x, axis.context.y);
|
||||
}
|
||||
|
||||
private void InitParallelAxis(ParallelAxis axis)
|
||||
{
|
||||
var theme = chart.theme;
|
||||
var xAxisIndex = axis.index;
|
||||
axis.painter = chart.painter;
|
||||
axis.refreshComponent = delegate ()
|
||||
{
|
||||
UpdateContext(axis);
|
||||
InitAxis(axis, null, chart, this,
|
||||
m_Orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width,
|
||||
axis.context.height);
|
||||
};
|
||||
axis.refreshComponent();
|
||||
}
|
||||
|
||||
internal override void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
base.UpdateAxisLabelText(axis);
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
for (int i = 0; i < axis.context.labelObjectList.Count; i++)
|
||||
{
|
||||
var label = axis.context.labelObjectList[i];
|
||||
if (label != null)
|
||||
{
|
||||
var pos = GetLabelPosition(0, i);
|
||||
label.SetPosition(pos);
|
||||
CheckValueLabelActive(component, i, label, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
if (m_Parallel == null)
|
||||
return Vector3.zero;
|
||||
|
||||
return GetLabelPosition(i, m_Orient, component, null,
|
||||
chart.theme.axis,
|
||||
scaleWid,
|
||||
component.context.x,
|
||||
component.context.y,
|
||||
component.context.width,
|
||||
component.context.height);
|
||||
}
|
||||
|
||||
private void DrawParallelAxisSplit(VertexHelper vh, ParallelAxis axis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
if (m_Parallel == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
|
||||
DrawAxisSplit(vh, axis, chart.theme.axis, dataZoom,
|
||||
m_Orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width,
|
||||
axis.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawParallelAxisTick(VertexHelper vh, ParallelAxis axis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
if (m_Parallel == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
|
||||
DrawAxisTick(vh, axis, chart.theme.axis, dataZoom,
|
||||
m_Orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawParallelAxisLine(VertexHelper vh, ParallelAxis axis)
|
||||
{
|
||||
if (axis.show && axis.axisLine.show)
|
||||
{
|
||||
if (m_Parallel == null)
|
||||
return;
|
||||
|
||||
DrawAxisLine(vh, axis,
|
||||
chart.theme.axis,
|
||||
m_Orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26ab25bf702c54ad38461c91ba1451af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Axis/RadiusAxis.meta
Normal file
8
Runtime/Component/Axis/RadiusAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c8971958a94d47e68f7ebdff5872b71
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
28
Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs
Normal file
28
Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Radial axis of polar coordinate.
|
||||
/// 极坐标系的径向轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[ComponentHandler(typeof(RadiusAxisHandler), true)]
|
||||
public class RadiusAxis : Axis
|
||||
{
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
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);
|
||||
splitLine.show = true;
|
||||
splitLine.lineStyle.type = LineStyle.Type.Solid;
|
||||
axisLabel.textLimit.enable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs.meta
Normal file
11
Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6429398a27934726ba49d387d681728
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
154
Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs
Normal file
154
Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class RadiusAxisHandler : MainComponentHandler<RadiusAxis>
|
||||
{
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitRadiusAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateAxisMinMaxValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawRadiusAxis(vh, component);
|
||||
}
|
||||
|
||||
private void UpdateAxisMinMaxValue(RadiusAxis axis, bool updateChart = true)
|
||||
{
|
||||
if (axis.IsCategory() || !axis.show) return;
|
||||
double tempMinValue = 0;
|
||||
double tempMaxValue = 0;
|
||||
SeriesHelper.GetXMinMaxValue(chart.series, null, axis.polarIndex, true, axis.inverse, out tempMinValue,
|
||||
out tempMaxValue, true);
|
||||
AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true);
|
||||
if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue)
|
||||
{
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.offset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
|
||||
if (updateChart)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAxisLabelText(RadiusAxis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
|
||||
axis.UpdateLabelText(polar.context.radius, null, false);
|
||||
}
|
||||
|
||||
private void InitRadiusAxis(RadiusAxis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.index);
|
||||
if (polar == null)
|
||||
return;
|
||||
|
||||
var angleAxis = ComponentHelper.GetAngleAxis(chart.components, polar.index);
|
||||
if (angleAxis == null)
|
||||
return;
|
||||
|
||||
PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight);
|
||||
axis.context.labelObjectList.Clear();
|
||||
var radius = polar.context.radius;
|
||||
var objName = "axis_radius" + axis.index;
|
||||
var axisObj = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
axisObj.transform.localPosition = Vector3.zero;
|
||||
axisObj.SetActive(axis.show && axis.axisLabel.show);
|
||||
axisObj.hideFlags = chart.chartHideFlags;
|
||||
ChartHelper.HideAllObject(axisObj);
|
||||
var textStyle = axis.axisLabel.textStyle;
|
||||
var splitNumber = AxisHelper.GetSplitNumber(axis, radius, null);
|
||||
var totalWidth = 0f;
|
||||
var startAngle = angleAxis.startAngle;
|
||||
var cenPos = polar.context.center;
|
||||
var txtHig = textStyle.GetFontSize(chart.theme.axis) + 2;
|
||||
var dire = ChartHelper.GetDire(startAngle, true).normalized;
|
||||
var tickWidth = axis.axisTick.GetLength(chart.theme.axis.tickWidth);
|
||||
var tickVector = ChartHelper.GetVertialDire(dire)
|
||||
* (tickWidth + axis.axisLabel.margin);
|
||||
for (int i = 0; i <= splitNumber; i++)
|
||||
{
|
||||
var labelWidth = AxisHelper.GetScaleWidth(axis, radius, i, null);
|
||||
var inside = axis.axisLabel.inside;
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
var labelName = AxisHelper.GetLabelName(axis, radius, i, axis.context.minValue, axis.context.maxValue,
|
||||
null, isPercentStack);
|
||||
var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform, new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(labelWidth, txtHig), axis, chart.theme.axis,
|
||||
labelName);
|
||||
|
||||
if (i == 0)
|
||||
axis.axisLabel.SetRelatedText(label.label, labelWidth);
|
||||
|
||||
label.label.SetAlignment(textStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
label.SetText(labelName);
|
||||
label.SetPosition(ChartHelper.GetPos(cenPos, totalWidth, startAngle, true) + tickVector);
|
||||
label.SetActive(true);
|
||||
|
||||
axis.context.labelObjectList.Add(label);
|
||||
|
||||
totalWidth += labelWidth;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawRadiusAxis(VertexHelper vh, RadiusAxis radiusAxis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(radiusAxis.polarIndex);
|
||||
if (polar == null)
|
||||
return;
|
||||
|
||||
var angleAxis = ComponentHelper.GetAngleAxis(chart.components, polar.index);
|
||||
if (angleAxis == null)
|
||||
return;
|
||||
|
||||
var startAngle = angleAxis.startAngle;
|
||||
var radius = polar.context.radius;
|
||||
var cenPos = polar.context.center;
|
||||
var size = AxisHelper.GetScaleNumber(radiusAxis, radius, null);
|
||||
var totalWidth = 0f;
|
||||
var dire = ChartHelper.GetDire(startAngle, true).normalized;
|
||||
var tickWidth = radiusAxis.axisTick.GetLength(chart.theme.axis.tickWidth);
|
||||
var tickLength = radiusAxis.axisTick.GetLength(chart.theme.axis.tickLength);
|
||||
var tickVetor = ChartHelper.GetVertialDire(dire) * tickLength;
|
||||
for (int i = 0; i < size - 1; i++)
|
||||
{
|
||||
var scaleWidth = AxisHelper.GetScaleWidth(radiusAxis, radius, i);
|
||||
var pos = ChartHelper.GetPos(cenPos, totalWidth, startAngle, true);
|
||||
if (radiusAxis.show && radiusAxis.splitLine.show)
|
||||
{
|
||||
var outsideRaidus = totalWidth + radiusAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth) * 2;
|
||||
var splitLineColor = radiusAxis.splitLine.GetColor(chart.theme.axis.splitLineColor);
|
||||
UGL.DrawDoughnut(vh, cenPos, totalWidth, outsideRaidus, splitLineColor, Color.clear);
|
||||
}
|
||||
if (radiusAxis.show && radiusAxis.axisTick.show)
|
||||
{
|
||||
UGL.DrawLine(vh, pos, pos + tickVetor, tickWidth, chart.theme.axis.lineColor);
|
||||
}
|
||||
totalWidth += scaleWidth;
|
||||
}
|
||||
if (radiusAxis.show && radiusAxis.axisLine.show)
|
||||
{
|
||||
var lineStartPos = polar.context.center - dire * tickWidth;
|
||||
var lineEndPos = polar.context.center + dire * (radius + tickWidth);
|
||||
var lineWidth = radiusAxis.axisLine.GetWidth(chart.theme.axis.lineWidth);
|
||||
UGL.DrawLine(vh, lineStartPos, lineEndPos, lineWidth, chart.theme.axis.lineColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs.meta
Normal file
11
Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f2cb79bfe30c4f14a3117f9f30ed3bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Axis/SingleAxis.meta
Normal file
8
Runtime/Component/Axis/SingleAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17498717d39c14b43a91c67401407410
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
146
Runtime/Component/Axis/SingleAxis/SingleAxis.cs
Normal file
146
Runtime/Component/Axis/SingleAxis/SingleAxis.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Single axis.
|
||||
/// 单轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[ComponentHandler(typeof(SingleAxisHander), true)]
|
||||
public class SingleAxis : Axis, IUpdateRuntimeData
|
||||
{
|
||||
[SerializeField] protected Orient m_Orient = Orient.Horizonal;
|
||||
[SerializeField] private float m_Left = 0.1f;
|
||||
[SerializeField] private float m_Right = 0.1f;
|
||||
[SerializeField] private float m_Top = 0f;
|
||||
[SerializeField] private float m_Bottom = 0.2f;
|
||||
[SerializeField] private float m_Width = 0;
|
||||
[SerializeField] private float m_Height = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Orientation of the axis. By default, it's 'Horizontal'. You can set it to be 'Vertical' to make a vertical axis.
|
||||
/// 坐标轴朝向。默认为水平朝向。
|
||||
/// </summary>
|
||||
public Orient orient
|
||||
{
|
||||
get { return m_Orient; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Distance between component and the left side of the container.
|
||||
/// 组件离容器左侧的距离。
|
||||
/// </summary>
|
||||
public float left
|
||||
{
|
||||
get { return m_Left; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Distance between component and the right side of the container.
|
||||
/// 组件离容器右侧的距离。
|
||||
/// </summary>
|
||||
public float right
|
||||
{
|
||||
get { return m_Right; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Distance between component and the top side of the container.
|
||||
/// 组件离容器上侧的距离。
|
||||
/// </summary>
|
||||
public float top
|
||||
{
|
||||
get { return m_Top; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Distance between component and the bottom side of the container.
|
||||
/// 组件离容器下侧的距离。
|
||||
/// </summary>
|
||||
public float bottom
|
||||
{
|
||||
get { return m_Bottom; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetAllDirty(); }
|
||||
}
|
||||
public float width
|
||||
{
|
||||
get { return m_Width; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetAllDirty(); }
|
||||
}
|
||||
public float height
|
||||
{
|
||||
get { return m_Height; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetAllDirty(); }
|
||||
}
|
||||
|
||||
public void UpdateRuntimeData(float chartX, float chartY, float chartWidth, float chartHeight)
|
||||
{
|
||||
context.left = left <= 1 ? left * chartWidth : left;
|
||||
context.bottom = bottom <= 1 ? bottom * chartHeight : bottom;
|
||||
context.top = top <= 1 ? top * chartHeight : top;
|
||||
context.right = right <= 1 ? right * chartWidth : right;
|
||||
|
||||
context.height = height <= 1 ? height * chartHeight : height;
|
||||
|
||||
if (m_Orient == Orient.Horizonal)
|
||||
{
|
||||
context.width = width == 0
|
||||
? chartWidth - context.left - context.right
|
||||
: (width <= 1 ? chartWidth * width : width);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.width = width == 0
|
||||
? chartHeight - context.top - context.bottom
|
||||
: (width <= 1 ? chartHeight * width : width);
|
||||
}
|
||||
|
||||
if (context.left != 0 && context.right == 0)
|
||||
context.x = chartX + context.left;
|
||||
else if (context.left == 0 && context.right != 0)
|
||||
context.x = chartX + chartWidth - context.right - context.width;
|
||||
else
|
||||
context.x = chartX + context.left;
|
||||
|
||||
if (context.bottom != 0 && context.top == 0)
|
||||
context.y = chartY + context.bottom;
|
||||
else if (context.bottom == 0 && context.top != 0)
|
||||
context.y = chartY + chartHeight - context.top - context.height;
|
||||
else
|
||||
context.y = chartY + context.bottom;
|
||||
|
||||
context.position = new Vector3(context.x, context.y);
|
||||
}
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Category;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 0;
|
||||
m_BoundaryGap = true;
|
||||
m_Position = AxisPosition.Bottom;
|
||||
m_Offset = 0;
|
||||
|
||||
m_Left = 0.1f;
|
||||
m_Right = 0.1f;
|
||||
m_Top = 0;
|
||||
m_Bottom = 0.2f;
|
||||
m_Width = 0;
|
||||
m_Height = 50;
|
||||
|
||||
m_Data = new List<string>() { "x1", "x2", "x3", "x4", "x5" };
|
||||
m_Icons = new List<Sprite>(5);
|
||||
splitLine.show = false;
|
||||
splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axisLabel.textLimit.enable = true;
|
||||
axisTick.showStartTick = true;
|
||||
axisTick.showEndTick = true;
|
||||
iconStyle.show = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/SingleAxis/SingleAxis.cs.meta
Normal file
11
Runtime/Component/Axis/SingleAxis/SingleAxis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aeb871d6555744e609bd651306c601a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
122
Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs
Normal file
122
Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class SingleAxisHander : AxisHandler<SingleAxis>
|
||||
{
|
||||
protected override Orient orient { get { return component.orient; } }
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitXAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateAxisMinMaxValue(component.index, component);
|
||||
UpdatePointerValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawSingleAxisSplit(vh, component);
|
||||
DrawSingleAxisLine(vh, component);
|
||||
DrawSingleAxisTick(vh, component);
|
||||
}
|
||||
|
||||
private void InitXAxis(SingleAxis axis)
|
||||
{
|
||||
var theme = chart.theme;
|
||||
var xAxisIndex = axis.index;
|
||||
axis.painter = chart.painter;
|
||||
axis.refreshComponent = delegate ()
|
||||
{
|
||||
axis.UpdateRuntimeData(chart.chartX,
|
||||
chart.chartY,
|
||||
chart.chartWidth,
|
||||
chart.chartHeight);
|
||||
|
||||
InitAxis(axis, null, chart, this,
|
||||
axis.orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width,
|
||||
axis.context.height);
|
||||
};
|
||||
axis.refreshComponent();
|
||||
}
|
||||
|
||||
internal override void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
base.UpdateAxisLabelText(axis);
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
for (int i = 0; i < axis.context.labelObjectList.Count; i++)
|
||||
{
|
||||
var label = axis.context.labelObjectList[i];
|
||||
if (label != null)
|
||||
{
|
||||
var pos = GetLabelPosition(0, i);
|
||||
label.SetPosition(pos);
|
||||
CheckValueLabelActive(component, i, label, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
return GetLabelPosition(i, component.orient, component, null,
|
||||
chart.theme.axis,
|
||||
scaleWid,
|
||||
component.context.x,
|
||||
component.context.y,
|
||||
component.context.width,
|
||||
component.context.height);
|
||||
}
|
||||
|
||||
private void DrawSingleAxisSplit(VertexHelper vh, SingleAxis axis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
DrawAxisSplit(vh, axis, chart.theme.axis, dataZoom,
|
||||
axis.orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width,
|
||||
axis.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSingleAxisTick(VertexHelper vh, SingleAxis axis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
DrawAxisTick(vh, axis, chart.theme.axis, dataZoom,
|
||||
axis.orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSingleAxisLine(VertexHelper vh, SingleAxis axis)
|
||||
{
|
||||
if (axis.show && axis.axisLine.show)
|
||||
{
|
||||
var axisStartY = axis.context.y + axis.offset;
|
||||
DrawAxisLine(vh, axis,
|
||||
chart.theme.axis,
|
||||
axis.orient,
|
||||
axis.context.x,
|
||||
axisStartY,
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs.meta
Normal file
11
Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50b3514e3079543ea9000d21d809cad3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Axis/XAxis.meta
Normal file
8
Runtime/Component/Axis/XAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5e50f8f0f8bb406b99fb32d6b5c7769
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Runtime/Component/Axis/XAxis/XAxis.cs
Normal file
34
Runtime/Component/Axis/XAxis/XAxis.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The x axis in cartesian(rectangular) coordinate.
|
||||
/// <para>直角坐标系 grid 中的 x 轴。</para>
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[RequireChartComponent(typeof(GridCoord))]
|
||||
[ComponentHandler(typeof(XAxisHander), true)]
|
||||
public class XAxis : Axis
|
||||
{
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Category;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 0;
|
||||
m_BoundaryGap = true;
|
||||
m_Position = AxisPosition.Bottom;
|
||||
m_Offset = 0;
|
||||
m_Data = new List<string>() { "x1", "x2", "x3", "x4", "x5" };
|
||||
m_Icons = new List<Sprite>(5);
|
||||
splitLine.show = false;
|
||||
splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axisLabel.textLimit.enable = true;
|
||||
iconStyle.show = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/XAxis/XAxis.cs.meta
Normal file
11
Runtime/Component/Axis/XAxis/XAxis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a71be0d36b9745c2894e598b3d9188a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
152
Runtime/Component/Axis/XAxis/XAxisHander.cs
Normal file
152
Runtime/Component/Axis/XAxis/XAxisHander.cs
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class XAxisHander : AxisHandler<XAxis>
|
||||
{
|
||||
protected override Orient orient { get { return Orient.Horizonal; } }
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitXAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateAxisMinMaxValue(component.index, component);
|
||||
UpdatePointerValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawXAxisSplit(vh, component);
|
||||
DrawXAxisLine(vh, component);
|
||||
DrawXAxisTick(vh, component);
|
||||
}
|
||||
|
||||
private void InitXAxis(XAxis xAxis)
|
||||
{
|
||||
var theme = chart.theme;
|
||||
var xAxisIndex = xAxis.index;
|
||||
xAxis.painter = chart.painter;
|
||||
xAxis.refreshComponent = delegate ()
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
if (grid != null)
|
||||
{
|
||||
var yAxis = chart.GetChartComponent<YAxis>(xAxis.index);
|
||||
InitAxis(xAxis, yAxis, chart, this,
|
||||
orient,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.width,
|
||||
grid.context.height);
|
||||
}
|
||||
};
|
||||
xAxis.refreshComponent();
|
||||
}
|
||||
|
||||
internal override void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
base.UpdateAxisLabelText(axis);
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
for (int i = 0; i < axis.context.labelObjectList.Count; i++)
|
||||
{
|
||||
var label = axis.context.labelObjectList[i];
|
||||
if (label != null)
|
||||
{
|
||||
var pos = GetLabelPosition(0, i);
|
||||
label.SetPosition(pos);
|
||||
CheckValueLabelActive(component, i, label, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(component.gridIndex);
|
||||
if (grid == null)
|
||||
return Vector3.zero;
|
||||
|
||||
var yAxis = chart.GetChartComponent<YAxis>(component.index);
|
||||
|
||||
return GetLabelPosition(i, Orient.Horizonal, component, yAxis,
|
||||
chart.theme.axis,
|
||||
scaleWid,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.width,
|
||||
grid.context.height);
|
||||
}
|
||||
|
||||
private void DrawXAxisSplit(VertexHelper vh, XAxis xAxis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(xAxis))
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(xAxis);
|
||||
|
||||
DrawAxisSplit(vh, xAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Horizonal,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.width,
|
||||
grid.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawXAxisTick(VertexHelper vh, XAxis xAxis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(xAxis))
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(xAxis);
|
||||
|
||||
var startY = grid.context.y + xAxis.offset;
|
||||
if (xAxis.IsTop())
|
||||
startY += grid.context.height;
|
||||
else
|
||||
startY += ComponentHelper.GetXAxisOnZeroOffset(chart.components, xAxis);
|
||||
|
||||
DrawAxisTick(vh, xAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Horizonal,
|
||||
grid.context.x,
|
||||
startY,
|
||||
grid.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawXAxisLine(VertexHelper vh, XAxis xAxis)
|
||||
{
|
||||
if (xAxis.show && xAxis.axisLine.show)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var startY = grid.context.y + xAxis.offset;
|
||||
if (xAxis.IsTop())
|
||||
startY += grid.context.height;
|
||||
else
|
||||
startY += ComponentHelper.GetXAxisOnZeroOffset(chart.components, xAxis);
|
||||
|
||||
DrawAxisLine(vh, xAxis, chart.theme.axis,
|
||||
Orient.Horizonal,
|
||||
grid.context.x,
|
||||
startY,
|
||||
grid.context.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/XAxis/XAxisHander.cs.meta
Normal file
11
Runtime/Component/Axis/XAxis/XAxisHander.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7818e1175663412196de53f19b5ac08
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Axis/YAxis.meta
Normal file
8
Runtime/Component/Axis/YAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69f8ba8fcc7d84b12b42f837f9f2b94b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Runtime/Component/Axis/YAxis/YAxis.cs
Normal file
34
Runtime/Component/Axis/YAxis/YAxis.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The x axis in cartesian(rectangular) coordinate.
|
||||
/// <para>
|
||||
/// 直角坐标系 grid 中的 y 轴。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[RequireChartComponent(typeof(GridCoord), typeof(XAxis))]
|
||||
[ComponentHandler(typeof(YAxisHander), true)]
|
||||
public class YAxis : Axis
|
||||
{
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Value;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 0;
|
||||
m_BoundaryGap = false;
|
||||
m_Position = AxisPosition.Left;
|
||||
m_Data = new List<string>(5);
|
||||
splitLine.show = true;
|
||||
splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axisLabel.textLimit.enable = false;
|
||||
axisTick.showStartTick = true;
|
||||
iconStyle.show = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/YAxis/YAxis.cs.meta
Normal file
11
Runtime/Component/Axis/YAxis/YAxis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ac60b8329f7a45c3898c7539d78f091
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
149
Runtime/Component/Axis/YAxis/YAxisHander.cs
Normal file
149
Runtime/Component/Axis/YAxis/YAxisHander.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class YAxisHander : AxisHandler<YAxis>
|
||||
{
|
||||
protected override Orient orient { get { return Orient.Vertical; } }
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitYAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateAxisMinMaxValue(component.index, component);
|
||||
UpdatePointerValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawYAxisSplit(vh, component.index, component);
|
||||
DrawYAxisLine(vh, component.index, component);
|
||||
DrawYAxisTick(vh, component.index, component);
|
||||
}
|
||||
|
||||
private void InitYAxis(YAxis yAxis)
|
||||
{
|
||||
var theme = chart.theme;
|
||||
var yAxisIndex = yAxis.index;
|
||||
yAxis.painter = chart.painter;
|
||||
yAxis.refreshComponent = delegate ()
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
|
||||
if (grid != null)
|
||||
{
|
||||
var xAxis = chart.GetChartComponent<YAxis>(yAxis.index);
|
||||
InitAxis(yAxis, xAxis, chart, this,
|
||||
orient,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.height,
|
||||
grid.context.width);
|
||||
}
|
||||
};
|
||||
yAxis.refreshComponent();
|
||||
}
|
||||
|
||||
internal override void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
base.UpdateAxisLabelText(axis);
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
for (int i = 0; i < axis.context.labelObjectList.Count; i++)
|
||||
{
|
||||
var label = axis.context.labelObjectList[i];
|
||||
if (label != null)
|
||||
{
|
||||
var pos = GetLabelPosition(0, i);
|
||||
label.SetPosition(pos);
|
||||
CheckValueLabelActive(axis, i, label, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(component.gridIndex);
|
||||
if (grid == null)
|
||||
return Vector3.zero;
|
||||
|
||||
return GetLabelPosition(i, Orient.Vertical, component, null,
|
||||
chart.theme.axis,
|
||||
scaleWid,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.height,
|
||||
grid.context.width);
|
||||
}
|
||||
|
||||
private void DrawYAxisSplit(VertexHelper vh, int yAxisIndex, YAxis yAxis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(yAxis))
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(yAxis);
|
||||
DrawAxisSplit(vh, yAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Vertical,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.height,
|
||||
grid.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawYAxisTick(VertexHelper vh, int yAxisIndex, YAxis yAxis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(yAxis))
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(yAxis);
|
||||
|
||||
var startX = grid.context.x + yAxis.offset;
|
||||
if (yAxis.IsRight())
|
||||
startX += grid.context.width;
|
||||
else
|
||||
startX += ComponentHelper.GetYAxisOnZeroOffset(chart.components, yAxis);
|
||||
|
||||
DrawAxisTick(vh, yAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Vertical,
|
||||
startX,
|
||||
grid.context.y,
|
||||
grid.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawYAxisLine(VertexHelper vh, int yAxisIndex, YAxis yAxis)
|
||||
{
|
||||
if (yAxis.show && yAxis.axisLine.show)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var startX = grid.context.x + yAxis.offset;
|
||||
if (yAxis.IsRight())
|
||||
startX += grid.context.width;
|
||||
else
|
||||
startX += ComponentHelper.GetYAxisOnZeroOffset(chart.components, yAxis);
|
||||
|
||||
DrawAxisLine(vh, yAxis, chart.theme.axis,
|
||||
Orient.Vertical,
|
||||
startX,
|
||||
grid.context.y,
|
||||
grid.context.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Axis/YAxis/YAxisHander.cs.meta
Normal file
11
Runtime/Component/Axis/YAxis/YAxisHander.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f09b5dcb5fcc54583bcd7946f18dfa48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Background.meta
Normal file
8
Runtime/Component/Background.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7db6fdcbbbfd148f58ff7a1f1a569d51
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
81
Runtime/Component/Background/Background.cs
Normal file
81
Runtime/Component/Background/Background.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Background component.
|
||||
///
|
||||
/// 背景组件。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DisallowMultipleComponent]
|
||||
[ComponentHandler(typeof(BackgroundHandler), false)]
|
||||
public class Background : MainComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private Sprite m_Image;
|
||||
[SerializeField] private Image.Type m_ImageType;
|
||||
[SerializeField] private Color m_ImageColor = Color.white;
|
||||
[SerializeField] private bool m_HideThemeBackgroundColor = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to enable the background component.
|
||||
/// 是否启用背景组件。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
internal set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the image of background.
|
||||
/// 背景图。
|
||||
/// </summary>
|
||||
public Sprite image
|
||||
{
|
||||
get { return m_Image; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Image, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the fill type of background image.
|
||||
/// 背景图填充类型。
|
||||
/// </summary>
|
||||
public Image.Type imageType
|
||||
{
|
||||
get { return m_ImageType; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ImageType, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 背景图颜色。
|
||||
/// </summary>
|
||||
public Color imageColor
|
||||
{
|
||||
get { return m_ImageColor; }
|
||||
set { if (PropertyUtil.SetColor(ref m_ImageColor, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether to hide the background color set in the theme when the background component is on.
|
||||
/// 当background组件开启时,是否隐藏主题中设置的背景色。
|
||||
/// </summary>
|
||||
public bool hideThemeBackgroundColor
|
||||
{
|
||||
get { return m_HideThemeBackgroundColor; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_HideThemeBackgroundColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = false;
|
||||
m_Image = null;
|
||||
m_ImageType = Image.Type.Sliced;
|
||||
m_ImageColor = Color.white;
|
||||
m_HideThemeBackgroundColor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Background/Background.cs.meta
Normal file
11
Runtime/Component/Background/Background.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 524f7df5241cc4379ae241a73d5b2ff2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
76
Runtime/Component/Background/BackgroundHandler.cs
Normal file
76
Runtime/Component/Background/BackgroundHandler.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class BackgroundHandler : MainComponentHandler<Background>
|
||||
{
|
||||
private readonly string s_BackgroundObjectName = "background";
|
||||
public override void InitComponent()
|
||||
{
|
||||
component.painter = chart.painter;
|
||||
component.refreshComponent = delegate ()
|
||||
{
|
||||
var backgroundObj = ChartHelper.AddObject(s_BackgroundObjectName, chart.transform, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
component.gameObject = backgroundObj;
|
||||
backgroundObj.hideFlags = chart.chartHideFlags;
|
||||
|
||||
var backgroundImage = ChartHelper.GetOrAddComponent<Image>(backgroundObj);
|
||||
ChartHelper.UpdateRectTransform(backgroundObj, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
backgroundImage.sprite = component.image;
|
||||
backgroundImage.type = component.imageType;
|
||||
backgroundImage.color = component.imageColor;
|
||||
|
||||
backgroundObj.transform.SetSiblingIndex(0);
|
||||
backgroundObj.SetActive(component.show);
|
||||
};
|
||||
component.refreshComponent();
|
||||
}
|
||||
|
||||
//protected void DrawBackground(VertexHelper vh)
|
||||
//{
|
||||
//TODO: CooridateChart
|
||||
// if (SeriesHelper.IsAnyClipSerie(m_Series))
|
||||
// {
|
||||
// var xLineDiff = xAxis0.axisLine.GetWidth(m_Theme.axis.lineWidth);
|
||||
// var yLineDiff = yAxis0.axisLine.GetWidth(m_Theme.axis.lineWidth);
|
||||
// var xSplitDiff = xAxis0.splitLine.GetWidth(m_Theme.axis.splitLineWidth);
|
||||
// var ySplitDiff = yAxis0.splitLine.GetWidth(m_Theme.axis.splitLineWidth);
|
||||
// foreach (var grid in m_Grids)
|
||||
// {
|
||||
// var cpty = grid.context.runtimeY + grid.context.runtimeHeight + ySplitDiff;
|
||||
// var cp1 = new Vector3(grid.context.runtimeX - yLineDiff, grid.context.runtimeY - xLineDiff);
|
||||
// var cp2 = new Vector3(grid.context.runtimeX - yLineDiff, cpty);
|
||||
// var cp3 = new Vector3(grid.context.runtimeX + grid.context.runtimeWidth + xSplitDiff, cpty);
|
||||
// var cp4 = new Vector3(grid.context.runtimeX + grid.context.runtimeWidth + xSplitDiff, grid.context.runtimeY - xLineDiff);
|
||||
// var backgroundColor = ThemeHelper.GetBackgroundColor(m_Theme, m_Background);
|
||||
// UGL.DrawQuadrilateral(vh, cp1, cp2, cp3, cp4, backgroundColor);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// base.DrawBackground(vh);
|
||||
// }
|
||||
// }
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
if (!component.show)
|
||||
return;
|
||||
|
||||
var p1 = new Vector3(chart.chartX, chart.chartY + chart.chartHeight);
|
||||
var p2 = new Vector3(chart.chartX + chart.chartWidth, chart.chartY + chart.chartHeight);
|
||||
var p3 = new Vector3(chart.chartX + chart.chartWidth, chart.chartY);
|
||||
var p4 = new Vector3(chart.chartX, chart.chartY);
|
||||
var backgroundColor = chart.theme.GetBackgroundColor(component);
|
||||
|
||||
UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, backgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Background/BackgroundHandler.cs.meta
Normal file
11
Runtime/Component/Background/BackgroundHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1cb3d1a2aa224bbe84eef2681cf3df4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Component/Child.meta
Normal file
8
Runtime/Component/Child.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20d31ade0390641698e6b846b4294b74
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
141
Runtime/Component/Child/AreaStyle.cs
Normal file
141
Runtime/Component/Child/AreaStyle.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The style of area.
|
||||
/// 区域填充样式。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AreaStyle : ChildComponent, ISerieExtraComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Origin position of area.
|
||||
/// 图形区域的起始位置。默认情况下,图形会从坐标轴轴线到数据间进行填充。如果需要填充的区域是坐标轴最大值到数据间,或者坐标轴最小值到数据间,则可以通过这个配置项进行设置。
|
||||
/// </summary>
|
||||
public enum AreaOrigin
|
||||
{
|
||||
/// <summary>
|
||||
/// to fill between axis line to data.
|
||||
/// 填充坐标轴轴线到数据间的区域。
|
||||
/// </summary>
|
||||
Auto,
|
||||
/// <summary>
|
||||
/// to fill between min axis value (when not inverse) to data.
|
||||
/// 填充坐标轴底部到数据间的区域。
|
||||
/// </summary>
|
||||
Start,
|
||||
/// <summary>
|
||||
/// to fill between max axis value (when not inverse) to data.
|
||||
/// 填充坐标轴顶部到数据间的区域。
|
||||
/// </summary>
|
||||
End
|
||||
}
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private AreaOrigin m_Origin;
|
||||
[SerializeField] private Color32 m_Color;
|
||||
[SerializeField] private Color32 m_ToColor;
|
||||
[SerializeField] [Range(0, 1)] private float m_Opacity = 0.6f;
|
||||
[SerializeField] private bool m_TooltipHighlight;
|
||||
[SerializeField] private Color32 m_HighlightColor;
|
||||
[SerializeField] private Color32 m_HighlightToColor;
|
||||
|
||||
/// <summary>
|
||||
/// Set this to false to prevent the areafrom showing.
|
||||
/// 是否显示区域填充。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the origin of area.
|
||||
/// 区域填充的起始位置。
|
||||
/// </summary>
|
||||
public AreaOrigin origin
|
||||
{
|
||||
get { return m_Origin; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Origin, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the color of area,default use serie color.
|
||||
/// 区域填充的颜色,如果toColor不是默认值,则表示渐变色的起点颜色。
|
||||
/// </summary>
|
||||
public Color32 color
|
||||
{
|
||||
get { return m_Color; }
|
||||
set { if (PropertyUtil.SetColor(ref m_Color, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gradient color, start color to toColor.
|
||||
/// 渐变色的终点颜色。
|
||||
/// </summary>
|
||||
public Color32 toColor
|
||||
{
|
||||
get { return m_ToColor; }
|
||||
set { if (PropertyUtil.SetColor(ref m_ToColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Opacity of the component. Supports value from 0 to 1, and the component will not be drawn when set to 0.
|
||||
/// 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。
|
||||
/// </summary>
|
||||
public float opacity
|
||||
{
|
||||
get { return m_Opacity; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Opacity, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 鼠标悬浮时是否高亮之前的区域
|
||||
/// </summary>
|
||||
public bool tooltipHighlight
|
||||
{
|
||||
get { return m_TooltipHighlight; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_TooltipHighlight, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the color of area,default use serie color.
|
||||
/// 高亮时区域填充的颜色,如果highlightToColor不是默认值,则表示渐变色的起点颜色。
|
||||
/// </summary>
|
||||
public Color32 highlightColor
|
||||
{
|
||||
get { return m_HighlightColor; }
|
||||
set { if (PropertyUtil.SetColor(ref m_HighlightColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gradient color, start highlightColor to highlightToColor.
|
||||
/// 高亮时渐变色的终点颜色。
|
||||
/// </summary>
|
||||
public Color32 highlightToColor
|
||||
{
|
||||
get { return m_HighlightToColor; }
|
||||
set { if (PropertyUtil.SetColor(ref m_HighlightToColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public Color32 GetColor()
|
||||
{
|
||||
if (m_Opacity == 1)
|
||||
return m_Color;
|
||||
|
||||
var color = m_Color;
|
||||
color.a = (byte)(color.a * m_Opacity);
|
||||
return color;
|
||||
}
|
||||
|
||||
public Color32 GetColor(Color32 themeColor)
|
||||
{
|
||||
if (!ChartHelper.IsClearColor(color))
|
||||
{
|
||||
return GetColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
var color = themeColor;
|
||||
color.a = (byte)(color.a * opacity);
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Child/AreaStyle.cs.meta
Normal file
11
Runtime/Component/Child/AreaStyle.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec0d95a9298bb4c159dcae36020beec9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
93
Runtime/Component/Child/ArrowStyle.cs
Normal file
93
Runtime/Component/Child/ArrowStyle.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ArrowStyle : ChildComponent
|
||||
{
|
||||
[SerializeField] private float m_Width = 10;
|
||||
[SerializeField] private float m_Height = 15;
|
||||
[SerializeField] private float m_Offset = 0;
|
||||
[SerializeField] private float m_Dent = 3;
|
||||
[SerializeField] private Color32 m_Color = Color.clear;
|
||||
|
||||
/// <summary>
|
||||
/// The widht of arrow.
|
||||
/// 箭头宽。
|
||||
/// </summary>
|
||||
public float width
|
||||
{
|
||||
get { return m_Width; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The height of arrow.
|
||||
/// 箭头高。
|
||||
/// </summary>
|
||||
public float height
|
||||
{
|
||||
get { return m_Height; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The offset of arrow.
|
||||
/// 箭头偏移。
|
||||
/// </summary>
|
||||
public float offset
|
||||
{
|
||||
get { return m_Offset; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The dent of arrow.
|
||||
/// 箭头的凹度。
|
||||
/// </summary>
|
||||
public float dent
|
||||
{
|
||||
get { return m_Dent; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Dent, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the color of arrow.
|
||||
/// 箭头颜色。
|
||||
/// </summary>
|
||||
public Color32 color
|
||||
{
|
||||
get { return m_Color; }
|
||||
set { if (PropertyUtil.SetColor(ref m_Color, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public ArrowStyle Clone()
|
||||
{
|
||||
var arrow = new ArrowStyle();
|
||||
arrow.width = width;
|
||||
arrow.height = height;
|
||||
arrow.offset = offset;
|
||||
arrow.dent = dent;
|
||||
arrow.color = color;
|
||||
return arrow;
|
||||
}
|
||||
|
||||
public void Copy(ArrowStyle arrow)
|
||||
{
|
||||
width = arrow.width;
|
||||
height = arrow.height;
|
||||
offset = arrow.offset;
|
||||
dent = arrow.dent;
|
||||
color = arrow.color;
|
||||
}
|
||||
|
||||
public Color32 GetColor(Color32 defaultColor)
|
||||
{
|
||||
if (ChartHelper.IsClearColor(color))
|
||||
return defaultColor;
|
||||
else
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Component/Child/ArrowStyle.cs.meta
Normal file
11
Runtime/Component/Child/ArrowStyle.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2232b812c68f042d29c44863e38d0417
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user