Aimbot Enviroment very first

Basic environment include Multi scene, Reward Change, Visible chart, etc....
This commit is contained in:
2022-09-05 20:46:08 +09:00
parent aa337c5fc2
commit 2d404cfdf2
1552 changed files with 162551 additions and 0 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 900b05585ba864df1aa05dcdb36b324b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/BarChart", 14)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class BarChart : BaseChart
{
protected override void DefaultChart()
{
AddChartComponentWhenNoExist<GridCoord>();
AddChartComponentWhenNoExist<XAxis>();
AddChartComponentWhenNoExist<YAxis>();
var tooltip = GetOrAddChartComponent<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));
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 535d2697503c2a94a887354e22a5414d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/CandlestickChart", 23)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class CandlestickChart : BaseChart
{
protected override void DefaultChart()
{
AddChartComponentWhenNoExist<GridCoord>();
AddChartComponentWhenNoExist<XAxis>();
AddChartComponentWhenNoExist<YAxis>();
var tooltip = GetOrAddChartComponent<Tooltip>();
tooltip.type = Tooltip.Type.Shadow;
tooltip.trigger = Tooltip.Trigger.Axis;
RemoveData();
var serie = Candlestick.AddDefaultSerie(this, GenerateDefaultSerieName());
for (int i = 0; i < serie.dataCount; i++)
{
AddXAxisData("x" + (i + 1));
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7b64f0bb738cc4acfa72fff2c30212b4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,84 @@
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/HeatmapChart", 18)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class HeatmapChart : BaseChart
{
protected override void DefaultChart()
{
var tooltip = GetChartComponent<Tooltip>();
tooltip.type = Tooltip.Type.None;
tooltip.trigger = Tooltip.Trigger.Axis;
var grid = GetOrAddChartComponent<GridCoord>();
grid.left = 0.12f;
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.AddColors(colors);
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);
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31aa03cd4ce594c239ae746791b3b59f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/LineChart", 13)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class LineChart : BaseChart
{
protected override void DefaultChart()
{
AddChartComponentWhenNoExist<GridCoord>();
AddChartComponentWhenNoExist<XAxis>();
AddChartComponentWhenNoExist<YAxis>();
var tooltip = GetOrAddChartComponent<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));
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b4f38bd00b4648c448cabfc167538f7c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,30 @@
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/ParallelChart", 25)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class ParallelChart : BaseChart
{
protected override void DefaultChart()
{
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());
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 161753d0d6ce541c89483f8c3a21343f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/PieChart", 15)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class PieChart : BaseChart
{
protected override void DefaultChart()
{
var legend = GetOrAddChartComponent<Legend>();
legend.show = true;
RemoveData();
Pie.AddDefaultSerie(this, GenerateDefaultSerieName());
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d44276ba809fd92408b296835f6f7658
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/PolarChart", 23)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class PolarChart : BaseChart
{
protected override void DefaultChart()
{
AddChartComponentWhenNoExist<PolarCoord>();
AddChartComponentWhenNoExist<AngleAxis>();
AddChartComponentWhenNoExist<RadiusAxis>();
var tooltip = GetChartComponent<Tooltip>();
tooltip.type = Tooltip.Type.Corss;
tooltip.trigger = Tooltip.Trigger.Axis;
RemoveData();
var serie = Line.AddDefaultSerie(this, GenerateDefaultSerieName());
serie.SetCoord<PolarCoord>();
serie.ClearData();
for (int i = 0; i <= 360; i++)
{
var t = i / 180f * Mathf.PI;
var r = Mathf.Sin(2 * t) * Mathf.Cos(2 * t) * 2;
AddData(0, Mathf.Abs(r), i);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 574bcbd917fc148e8bb8735acda07f77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,19 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/RadarChart", 16)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class RadarChart : BaseChart
{
protected override void DefaultChart()
{
RemoveData();
RemoveChartComponents<RadarCoord>();
AddChartComponent<RadarCoord>();
Radar.AddDefaultSerie(this, GenerateDefaultSerieName());
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d2231a0d3e3a5b043b074f6739be4a86
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,18 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/RingChart", 20)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class RingChart : BaseChart
{
protected override void DefaultChart()
{
GetChartComponent<Tooltip>().type = Tooltip.Type.Line;
RemoveData();
Ring.AddDefaultSerie(this, GenerateDefaultSerieName());
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0ad8949f652ee4376a4a4fe5cb32029f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,31 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/ScatterChart", 17)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class ScatterChart : BaseChart
{
protected override void DefaultChart()
{
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());
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf16aac0bd6c24a8da75846c34c5193e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/SimplifiedBarChart", 27)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class SimplifiedBarChart : BaseChart
{
protected override void DefaultChart()
{
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));
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aa86c3bbf8877409c9d45716fbaf92f4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/SimplifiedCandlestickChart", 28)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class SimplifiedCandlestickChart : BaseChart
{
protected override void DefaultChart()
{
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));
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6dcc9bd1ca8344d938f386e6b32e8946
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using UnityEngine;
namespace XCharts.Runtime
{
[AddComponentMenu("XCharts/SimplifiedLineChart", 26)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class SimplifiedLineChart : BaseChart
{
protected override void DefaultChart()
{
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));
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a8233997c1b324ecd875a03af4d90972
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3be5f1d3b129a47dd8e41cffe3b8e428
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9f827513754e8436bbc63e64c5b5e6c3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,630 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
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;
/// <summary>
/// 自定义渐入动画延时函数。返回ms值。
/// </summary>
public AnimationDelayFunction fadeInDelayFunction;
/// <summary>
/// 自定义渐入动画时长函数。返回ms值。
/// </summary>
public AnimationDurationFunction fadeInDurationFunction;
/// <summary>
/// 自定义渐出动画延时函数。返回ms值。
/// </summary>
public AnimationDelayFunction fadeOutDelayFunction;
/// <summary>
/// 自定义渐出动画时长函数。返回ms值。
/// </summary>
public AnimationDurationFunction fadeOutDurationFunction;
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 easting { 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 && fadeOutDelayFunction != null)
return fadeOutDelayFunction(dataIndex);
else if (m_FadeIn && fadeInDelayFunction != null)
return fadeInDelayFunction(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 && fadeOutDurationFunction != null)
return fadeOutDurationFunction(dataIndex) / 1000f;
if (m_FadeIn && fadeInDurationFunction != null)
return fadeInDurationFunction(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 destProgress, ref bool isEnd, float startProgress = 0)
{
isEnd = false;
var initHig = m_FadeOut ? destProgress : startProgress;
var destHig = m_FadeOut ? startProgress : destProgress;
var currHig = GetDataCurrProgress(dataIndex, initHig, destHig, ref isEnd);
if (isEnd || IsFinish())
{
return m_FadeOuted ? startProgress : destProgress;
}
else if (IsInDelay() || IsInIndexDelay(dataIndex))
{
return m_FadeOut ? destProgress : startProgress;
}
else if (m_IsPause)
{
return currHig;
}
else
{
var duration = GetCurrAnimationDuration(dataIndex);
var delta = (destProgress - startProgress) / 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 ((destProgress - startProgress > 0 && currHig > destProgress) ||
(destProgress - startProgress < 0 && currHig < destProgress))
{
currHig = destProgress;
isEnd = true;
}
}
SetDataCurrProgress(dataIndex, currHig);
return currHig;
}
}
public 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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e31c30f2ef61c48718a626f93307ce92
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
public struct AnimationStyleContext
{
public AnimationType type;
public float currentPathDistance;
public bool isAllItemAnimationEnd;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b3dc504960589413fa6a76267067775c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,65 @@
using UnityEngine;
using XUGL;
namespace XCharts.Runtime
{
public static class AnimationStyleHelper
{
public static float CheckDataAnimation(BaseChart chart, Serie serie, int dataIndex, float destProgress, float startPorgress = 0)
{
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;
var currHig = serie.animation.CheckItemProgress(dataIndex, destProgress, ref isDataAnimationEnd, startPorgress);
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);
}
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);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 54cadaee0856b4f7085787fd450eec37
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 194a62edf7ec2484fa2eebbf5bde3e95
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 28b88ca3453f04fbdb23a53b5bcb4bf7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,48 @@
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
/// <summary>
/// Angle axis of Polar Coordinate.
/// |极坐标系的角度轴。
/// </summary>
[System.Serializable]
[RequireChartComponent(typeof(PolarCoord))]
[ComponentHandler(typeof(AngleAxisHandler), true)]
public class AngleAxis : Axis
{
[SerializeField] private float m_StartAngle = 0;
/// <summary>
/// Starting angle of axis. 0 degrees by default, standing for right position of center.
/// |起始刻度的角度,默认为 0 度,即圆心的正右方。
/// </summary>
public float startAngle
{
get { return m_StartAngle; }
set { if (PropertyUtil.SetStruct(ref m_StartAngle, value)) SetAllDirty(); }
}
public float GetValueAngle(float value)
{
return (value + context.startAngle + 360) % 360;
}
public override void SetDefaultValue()
{
m_Show = true;
m_Type = AxisType.Value;
m_SplitNumber = 12;
m_StartAngle = 0;
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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 787015be923a74e1da4000c7abc2dcdf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,164 @@
using UnityEngine;
using UnityEngine.UI;
using XUGL;
namespace XCharts.Runtime
{
[UnityEngine.Scripting.Preserve]
internal sealed class AngleAxisHandler : AxisHandler<AngleAxis>
{
public override void InitComponent()
{
InitAngleAxis(component);
}
public override void Update()
{
component.context.startAngle = 90 - component.startAngle;
UpdateAxisMinMaxValue(component);
UpdatePointerValue(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;
UpdateAxisTickValueList(axis);
if (updateChart)
{
UpdateAxisLabelText(axis);
chart.RefreshChart();
}
}
}
internal void UpdateAxisLabelText(AngleAxis axis)
{
var runtimeWidth = 360;
if (axis.context.labelObjectList.Count <= 0)
InitAngleAxis(axis);
else
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();
axis.context.startAngle = 90 - axis.startAngle;
string objName = component.GetType().Name + 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.context.startAngle;
var total = 360;
var cenPos = polar.context.center;
var txtHig = axis.axisLabel.textStyle.GetFontSize(chart.theme.axis) + 2;
var margin = axis.axisLabel.distance + axis.axisTick.GetLength(chart.theme.axis.tickLength);
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 + 1, 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(scaleAngle, txtHig), axis,
chart.theme.axis, labelName, Color.clear);
label.text.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.text, 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.context.startAngle;
var tickWidth = angleAxis.axisTick.GetWidth(chart.theme.axis.tickWidth);
var tickLength = angleAxis.axisTick.GetLength(chart.theme.axis.tickLength);
var tickColor = angleAxis.axisTick.GetColor(chart.theme.axis.lineColor);
var lineColor = angleAxis.axisLine.GetColor(chart.theme.axis.lineColor);
var splitLineColor = angleAxis.splitLine.GetColor(chart.theme.axis.splitLineColor);
for (int i = 1; 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 lineWidth = angleAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth);
UGL.DrawLine(vh, cenPos, pos, lineWidth, splitLineColor);
}
if (angleAxis.show && angleAxis.axisTick.show)
{
if ((i == 1 && angleAxis.axisTick.showStartTick) ||
(i == size - 1 && angleAxis.axisTick.showEndTick) ||
(i > 1 && i < size - 1))
{
var tickY = radius + tickLength;
var tickPos = ChartHelper.GetPos(cenPos, tickY, currAngle, true);
UGL.DrawLine(vh, pos, tickPos, tickWidth, tickColor);
}
}
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, lineColor, Color.clear);
}
}
protected override void UpdatePointerValue(Axis axis)
{
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
if (polar == null)
return;
if (!polar.context.isPointerEnter)
{
axis.context.pointerValue = double.PositiveInfinity;
return;
}
var dir = (chart.pointerPos - new Vector2(polar.context.center.x, polar.context.center.y)).normalized;
var angle = ChartHelper.GetAngle360(Vector2.up, dir);
axis.context.pointerValue = (angle - component.context.startAngle + 360) % 360;
axis.context.pointerLabelPosition = polar.context.center + new Vector3(dir.x, dir.y) * (polar.context.radius + 25);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 83f228c42435c4619943a2f187c98e7b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,791 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
/// <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 double m_Min;
[SerializeField] protected double m_Max;
[SerializeField] protected int m_SplitNumber = 0;
[SerializeField] protected double 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] 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 double 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 double 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 double 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(); }
}
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.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;
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 m_Type == AxisType.Category;
}
/// <summary>
/// 是否为数值轴。
/// </summary>
/// <returns></returns>
public bool IsValue()
{
return m_Type == AxisType.Value;
}
/// <summary>
/// 是否为对数轴。
/// </summary>
/// <returns></returns>
public bool IsLog()
{
return m_Type == AxisType.Log;
}
/// <summary>
/// 是否为时间轴。
/// </summary>
public bool IsTime()
{
return m_Type == AxisType.Time;
}
public bool IsLeft()
{
return m_Position == AxisPosition.Left;
}
public bool IsRight()
{
return m_Position == AxisPosition.Right;
}
public bool IsTop()
{
return m_Position == AxisPosition.Top;
}
public bool IsBottom()
{
return m_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)
{
RemoveData(m_InsertDataToHead ? m_Data.Count - 1 : 0);
}
}
if (m_InsertDataToHead)
m_Data.Insert(0, category);
else
m_Data.Add(category);
SetAllDirty();
}
public void RemoveData(int dataIndex)
{
context.isNeedUpdateFilterData = true;
m_Data.RemoveAt(dataIndex);
}
/// <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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d5c29555575e04db98ee243c3b17f0ed
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
public class AxisContext : MainComponentContext
{
public Orient orient;
public float x;
public float y;
public float zeroX;
public float zeroY;
public float width;
public float height;
public Vector3 position;
public float left;
public float right;
public float bottom;
public float top;
/// <summary>
/// the current minimun value.
/// |当前最小值。
/// </summary>
public double minValue;
/// <summary>
/// the current maximum value.
/// |当前最大值。
/// </summary>
public double maxValue;
/// <summary>
/// the offset of zero position.
/// |坐标轴原点在坐标轴的偏移。
/// </summary>
public float offset;
public double minMaxRange;
public float scaleWidth;
public float startAngle;
public double pointerValue;
public Vector3 pointerLabelPosition;
public double axisTooltipValue;
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;
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;
}
if (range > data.Count - start - 1)
start = data.Count - range - 1;
if (start >= 0)
filterData = data.GetRange(start, range);
else
filterData = data;
}
else
{
filterData = data;
}
}
else if (end == 0)
{
filterData = m_EmptyFliter;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6525f065fa5d04663ab7026a3467f56e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,782 @@
using System;
using UnityEngine;
using UnityEngine.UI;
using XCharts.Runtime;
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 float GetAxisLineXOrY()
{
return 0;
}
protected virtual Orient orient { get; set; }
protected virtual 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
{
var lastPointerValue = axis.context.pointerValue;
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;
if (axis is YAxis)
{
float splitWid = AxisHelper.GetDataWidth(axis, grid.context.height, dataCount, dataZoom);
for (int j = 0; j < axis.GetDataCount(dataZoom); j++)
{
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);
if (j != lastPointerValue)
{
if (chart.onAxisPointerValueChanged != null)
chart.onAxisPointerValueChanged(axis, j);
}
break;
}
}
}
else
{
float splitWid = AxisHelper.GetDataWidth(axis, grid.context.width, dataCount, dataZoom);
for (int j = 0; j < axis.GetDataCount(dataZoom); j++)
{
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);
if (j != lastPointerValue)
{
if (chart.onAxisPointerValueChanged != null)
chart.onAxisPointerValueChanged(axis, 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);
if (yValue != lastPointerValue)
{
if (chart.onAxisPointerValueChanged != null)
chart.onAxisPointerValueChanged(axis, yValue);
}
}
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);
if (xValue != lastPointerValue)
{
if (chart.onAxisPointerValueChanged != null)
chart.onAxisPointerValueChanged(axis, xValue);
}
}
}
}
}
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))))
);
axis.context.x = grid.context.x;
axis.context.y = GetAxisLineXOrY();
axis.context.zeroY = grid.context.y;
axis.context.zeroX = grid.context.x - (float) (axis.context.minValue * grid.context.width / axis.context.minMaxRange);
}
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))))
);
axis.context.x = GetAxisLineXOrY();
axis.context.y = grid.context.y;
axis.context.zeroX = grid.context.x;
axis.context.zeroY = grid.context.y - (float) (axis.context.minValue * grid.context.height / axis.context.minMaxRange);
}
}
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)
{
if (max <= 1) return max / 5;
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.show || !axis.axisLabel.show)
{
label.SetTextActive(false);
return;
}
if (axis.IsValue())
{
if (orient == Orient.Horizonal)
{
if (i == 0)
{
var dist = GetLabelPosition(0, 1).x - pos.x;
label.SetTextActive(dist > label.text.GetPreferredWidth());
}
else if (i == axis.context.labelValueList.Count - 1)
{
var dist = pos.x - GetLabelPosition(0, i - 1).x;
label.SetTextActive(dist > label.text.GetPreferredWidth());
}
}
else
{
if (i == 0)
{
var dist = GetLabelPosition(0, 1).y - pos.y;
label.SetTextActive(dist > label.text.GetPreferredHeight());
}
else if (i == axis.context.labelValueList.Count - 1)
{
var dist = pos.y - GetLabelPosition(0, i - 1).y;
label.SetTextActive(dist > label.text.GetPreferredHeight());
}
}
}
}
protected void InitAxis(Axis relativedAxis, Orient orient,
float axisStartX, float axisStartY, float axisLength, float relativedLength)
{
Axis axis = component;
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;
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
var inside = axis.axisLabel.inside;
var defaultAlignment = orient == Orient.Horizonal ? TextAnchor.MiddleCenter :
((inside && axis.IsLeft()) || (!inside && axis.IsRight()) ?
TextAnchor.MiddleLeft :
TextAnchor.MiddleRight);
if (axis.IsCategory() && axis.boundaryGap)
splitNumber -= 1;
for (int i = 0; i < splitNumber; i++)
{
var labelWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom);
var labelName = AxisHelper.GetLabelName(axis, axisLength, i,
axis.context.minValue,
axis.context.maxValue,
dataZoom, isPercentStack);
var label = ChartHelper.AddAxisLabelObject(splitNumber, i,
ChartCached.GetAxisLabelName(i),
axisObj.transform,
new Vector2(textWidth, textHeight),
axis, chart.theme.axis, labelName,
Color.clear,
defaultAlignment);
if (i == 0)
axis.axisLabel.SetRelatedText(label.text, labelWidth);
var pos = GetLabelPosition(totalWidth + gapWidth, i);
label.SetPosition(pos);
CheckValueLabelActive(axis, i, label, pos);
axis.context.labelObjectList.Add(label);
totalWidth += labelWidth;
}
if (axis.axisName.show)
{
ChartLabel label = null;
var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.offset);
var zeroPos = new Vector3(axisStartX, axisStartY + relativedDist);
var offset = axis.axisName.labelStyle.offset;
var autoColor = axis.axisLine.GetColor(chart.theme.axis.lineColor);
if (orient == Orient.Horizonal)
{
var posY = GetAxisLineXOrY() + offset.y;
switch (axis.axisName.labelStyle.position)
{
case LabelStyle.Position.Start:
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleRight);
label.SetActive(axis.axisName.labelStyle.show);
label.SetPosition(axis.position == Axis.AxisPosition.Top ?
new Vector2(zeroPos.x - offset.x, axisStartY + relativedLength + offset.y + axis.offset) :
new Vector2(zeroPos.x - offset.x, posY));
break;
case LabelStyle.Position.Middle:
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetPosition(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, posY));
break;
default:
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleLeft);
label.SetActive(axis.axisName.labelStyle.show);
label.SetPosition(axis.position == Axis.AxisPosition.Top ?
new Vector2(axisStartX + axisLength + offset.x, axisStartY + relativedLength + offset.y + axis.offset) :
new Vector2(axisStartX + axisLength + offset.x, posY));
break;
}
}
else
{
var posX = GetAxisLineXOrY() + offset.x;
switch (axis.axisName.labelStyle.position)
{
case LabelStyle.Position.Start:
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetPosition(axis.position == Axis.AxisPosition.Right ?
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY - offset.y) :
new Vector2(posX, axisStartY - offset.y));
break;
case LabelStyle.Position.Middle:
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetPosition(axis.position == Axis.AxisPosition.Right ?
new Vector2(axisStartX + relativedLength - offset.x + axis.offset, axisStartY + axisLength / 2 + offset.y) :
new Vector2(posX, axisStartY + axisLength / 2 + offset.y));
break;
default:
//LabelStyle.Position
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
label.SetActive(axis.axisName.labelStyle.show);
label.SetPosition(axis.position == Axis.AxisPosition.Right ?
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY + axisLength + offset.y) :
new Vector2(posX, axisStartY + axisLength + offset.y));
break;
}
}
}
}
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.distance + fontSize / 2;
else
current += axisStartY - axis.axisLabel.distance - fontSize / 2;
return new Vector3(axisStartX + scaleWid, current) + axis.axisLabel.offset;
}
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.distance;
else
current += axisStartX - axis.axisLabel.distance;
return new Vector3(current, axisStartY + scaleWid) + axis.axisLabel.offset;
}
}
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)));
}
}
}
}
protected void DrawAxisSplit(VertexHelper vh, AxisTheme theme, DataZoom dataZoom,
Orient orient, float startX, float startY, float axisLength, float splitLength, Axis relativedAxis = null)
{
Axis axis = component;
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)
{
if (relativedAxis == null || !MathUtil.Approximately(current, GetAxisLineXOrY()))
ChartDrawer.DrawLineStyle(vh,
lineType,
lineWidth,
new Vector3(current, startY),
new Vector3(current, startY + splitLength),
lineColor);
}
else
{
if (relativedAxis == null || !MathUtil.Approximately(current, GetAxisLineXOrY()))
ChartDrawer.DrawLineStyle(vh,
lineType,
lineWidth,
new Vector3(startX, current),
new Vector3(startX + splitLength, current),
lineColor);
}
}
}
current += scaleWidth;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0babef8a2708b4745bbb0a0648913a35
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,561 @@
using UnityEngine;
namespace XCharts.Runtime
{
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;
if (axis.IsValue())
return dataCount > 1 ? coordinateWidth / (dataCount - 1) : coordinateWidth;
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)
{
double value = axis.logBaseE ?
System.Math.Exp(axis.GetLogMinIndex() + index) :
System.Math.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(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
{
var txtWidth = txt.text.GetPreferredWidth();
var sizeDelta = new Vector2(txtWidth, txt.text.GetPreferredHeight());
txt.text.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(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
{
var txtWidth = txt.text.GetPreferredWidth();
var sizeDelta = new Vector2(txtWidth, txt.text.GetPreferredHeight());
txt.text.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.SetPosition(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 double GetAxisPositionValue(GridCoord grid, Axis axis, Vector3 pos)
{
if (axis is YAxis)
return GetAxisPositionValue(pos.y, grid.context.height, axis.context.minMaxRange, grid.context.y, axis.context.offset);
else if (axis is XAxis)
return GetAxisPositionValue(pos.x, grid.context.width, axis.context.minMaxRange, grid.context.x, axis.context.offset);
else
return 0;
}
public static double GetAxisPositionValue(float xy, float axisLength, double axisRange, float axisStart, float axisOffset)
{
var yRate = axisRange / axisLength;
return yRate * (xy - axisStart - axisOffset);
}
/// <summary>
/// 获得数值value在坐标轴上的坐标位置
/// </summary>
/// <param name="grid"></param>
/// <param name="axis"></param>
/// <param name="scaleWidth"></param>
/// <param name="value"></param>
/// <returns></returns>
public static float GetAxisValuePosition(GridCoord grid, Axis axis, float scaleWidth, double value)
{
return GetAxisPositionInternal(grid, axis, scaleWidth, value, true, false);
}
/// <summary>
/// 获得数值value在坐标轴上相对起点的距离
/// </summary>
/// <param name="grid"></param>
/// <param name="axis"></param>
/// <param name="scaleWidth"></param>
/// <param name="value"></param>
/// <returns></returns>
public static float GetAxisValueDistance(GridCoord grid, Axis axis, float scaleWidth, double value)
{
return GetAxisPositionInternal(grid, axis, scaleWidth, value, false, false);
}
/// <summary>
/// 获得数值value在坐标轴上对应的长度
/// </summary>
/// <param name="grid"></param>
/// <param name="axis"></param>
/// <param name="scaleWidth"></param>
/// <param name="value"></param>
/// <returns></returns>
public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value)
{
return GetAxisPositionInternal(grid, axis, scaleWidth, value, false, true);
}
private static float GetAxisPositionInternal(GridCoord grid, Axis axis, float scaleWidth, double value, bool includeGridXY, bool realLength)
{
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 = 0f;
if (axis.context.minMaxRange != 0)
{
if (realLength)
yDataHig = (float) (value * gridHeight / axis.context.minMaxRange);
else
yDataHig = (float) ((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight);
}
return includeGridXY ?
gridXY + yDataHig :
yDataHig;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 566e3426780cc4339a1fb92d9604d21f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,230 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace XCharts.Runtime
{
/// <summary>
/// Settings related to axis label.
/// |坐标轴刻度标签的相关设置。
/// </summary>
[Serializable]
public class AxisLabel : LabelStyle
{
[SerializeField] private int m_Interval = 0;
[SerializeField] private bool m_Inside = false;
[SerializeField] private bool m_ShowAsPositiveNumber = false;
[SerializeField] private bool m_OnZero = false;
[SerializeField] private bool m_ShowStartLabel = true;
[SerializeField] private bool m_ShowEndLabel = true;
[SerializeField] private TextLimit m_TextLimit = new TextLimit();
/// <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>
/// 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>
/// 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(); } }
}
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_Distance = 8,
m_TextStyle = new TextStyle(),
};
}
}
public new AxisLabel Clone()
{
var axisLabel = new AxisLabel();
axisLabel.show = show;
axisLabel.formatter = formatter;
axisLabel.interval = interval;
axisLabel.inside = inside;
axisLabel.distance = distance;
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;
distance = axisLabel.distance;
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);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 051f9473d1beb4e0bb35aa1600cb44bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,77 @@
using UnityEngine;
namespace XCharts.Runtime
{
/// <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);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2748c2a8789724709aa76f6056eb708d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,76 @@
using System;
using UnityEngine;
namespace XCharts.Runtime
{
/// <summary>
/// the name of axis.
/// |坐标轴名称。
/// </summary>
[Serializable]
public class AxisName : ChildComponent
{
[SerializeField] private bool m_Show;
[SerializeField] private string m_Name;
[SerializeField] private LabelStyle m_LabelStyle = new LabelStyle();
/// <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>
/// The text style of axis name.
/// |文本样式。
/// </summary>
public LabelStyle labelStyle
{
get { return m_LabelStyle; }
set { if (PropertyUtil.SetClass(ref m_LabelStyle, value)) SetComponentDirty(); }
}
public static AxisName defaultAxisName
{
get
{
var axisName = new AxisName()
{
m_Show = false,
m_Name = "axisName",
m_LabelStyle = new LabelStyle()
};
axisName.labelStyle.position = LabelStyle.Position.End;
return axisName;
}
}
public AxisName Clone()
{
var axisName = new AxisName();
axisName.show = show;
axisName.name = name;
axisName.m_LabelStyle.Copy(m_LabelStyle);
return axisName;
}
public void Copy(AxisName axisName)
{
show = axisName.show;
name = axisName.name;
m_LabelStyle.Copy(axisName.labelStyle);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 878555ba3c6b1479f94f38185700531e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
/// <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];
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18702fd7797054670af64546b7304bb4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,74 @@
using System;
using UnityEngine;
namespace XCharts.Runtime
{
/// <summary>
/// Split line of axis in grid area.
/// |坐标轴在 grid 区域中的分隔线。
/// </summary>
[Serializable]
public class AxisSplitLine : BaseLine
{
[SerializeField] private int m_Interval;
[SerializeField] private float m_Distance;
[SerializeField] private bool m_AutoColor;
/// <summary>
/// The distance between the split line and axis line.
/// |刻度线与轴线的距离。
/// </summary>
public float distance { get { return m_Distance; } set { m_Distance = value; } }
/// <summary>
/// auto color.
/// |自动设置颜色。
/// </summary>
public bool autoColor { get { return m_AutoColor; } set { m_AutoColor = value; } }
/// <summary>
/// Interval of Axis splitLine.
/// |坐标轴分隔线的显示间隔。
/// </summary>
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);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3da942a7a6bea44e2998ed993c0641ab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,110 @@
using UnityEngine;
namespace XCharts.Runtime
{
/// <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;
[SerializeField] private float m_Distance;
[SerializeField] protected int m_SplitNumber = 0;
[SerializeField] private bool m_AutoColor;
/// <summary>
/// The distance between the tick line and axis line.
/// |刻度线与轴线的距离。
/// </summary>
public float distance { get { return m_Distance; } set { m_Distance = value; } }
/// <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(); }
}
/// <summary>
/// Number of segments that the axis is split into.
/// |分隔线之间分割的刻度数。
/// </summary>
public int splitNumber
{
get { return m_SplitNumber; }
set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); }
}
public bool autoColor { get { return m_AutoColor; } set { m_AutoColor = value; } }
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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60278762ed892450d85e27b7df8f997e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 24693180b2a2e41b2ab4025b2bbebf01
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
[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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7bc01c54f4d6485389fd57c37810c74
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,167 @@
using UnityEngine;
using UnityEngine.UI;
namespace XCharts.Runtime
{
[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(null,
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, 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);
}
}
protected override float GetAxisLineXOrY()
{
return component.context.y;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26ab25bf702c54ad38461c91ba1451af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7c8971958a94d47e68f7ebdff5872b71
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace XCharts.Runtime
{
/// <summary>
/// Radial axis of polar coordinate.
/// |极坐标系的径向轴。
/// </summary>
[System.Serializable]
[RequireChartComponent(typeof(PolarCoord))]
[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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f6429398a27934726ba49d387d681728
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,188 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using XUGL;
namespace XCharts.Runtime
{
[UnityEngine.Scripting.Preserve]
internal sealed class RadiusAxisHandler : AxisHandler<RadiusAxis>
{
public override void InitComponent()
{
InitRadiusAxis(component);
}
public override void Update()
{
UpdateAxisMinMaxValue(component);
UpdatePointerValue(component);
}
public override void DrawBase(VertexHelper vh)
{
DrawRadiusAxis(vh, component);
}
protected override void UpdatePointerValue(Axis axis)
{
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
if (polar == null)
return;
if (!polar.context.isPointerEnter)
{
axis.context.pointerValue = double.PositiveInfinity;
return;
}
var angleAxis = ComponentHelper.GetAngleAxis(chart.components, polar.index);
if (angleAxis == null)
return;
var dist = Vector3.Distance(chart.pointerPos, polar.context.center);
axis.context.pointerValue = axis.context.minValue + (dist / polar.context.radius) * axis.context.minMaxRange;
axis.context.pointerLabelPosition = GetLabelPosition(polar, axis, angleAxis.context.startAngle, dist);
}
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;
UpdateAxisTickValueList(axis);
if (updateChart)
{
UpdateAxisLabelText(axis);
chart.RefreshChart();
}
}
}
internal void UpdateAxisLabelText(RadiusAxis axis)
{
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
if (axis.context.labelObjectList.Count <= 0)
InitRadiusAxis(axis);
else
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 = component.GetType().Name + 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.GetScaleNumber(axis, radius, null);
var totalWidth = 0f;
var txtHig = textStyle.GetFontSize(chart.theme.axis) + 2;
for (int i = 0; i < splitNumber; i++)
{
var labelWidth = AxisHelper.GetScaleWidth(axis, radius, i + 1, 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(labelWidth, txtHig), axis, chart.theme.axis, labelName, Color.clear);
if (i == 0)
axis.axisLabel.SetRelatedText(label.text, labelWidth);
label.text.SetAlignment(textStyle.GetAlignment(TextAnchor.MiddleCenter));
label.SetText(labelName);
label.SetPosition(GetLabelPosition(polar, axis, angleAxis.context.startAngle, totalWidth));
label.SetActive(true);
label.SetTextActive(true);
axis.context.labelObjectList.Add(label);
totalWidth += labelWidth;
}
}
private Vector3 GetLabelPosition(PolarCoord polar, Axis axis, float startAngle, float totalWidth)
{
var cenPos = polar.context.center;
var dire = ChartHelper.GetDire(startAngle, true).normalized;
var tickLength = axis.axisTick.GetLength(chart.theme.axis.tickLength);
var tickVector = ChartHelper.GetVertialDire(dire) *
(tickLength + axis.axisLabel.distance);
return ChartHelper.GetPos(cenPos, totalWidth, startAngle, true) + tickVector;
}
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.context.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.GetWidth(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; i++)
{
var scaleWidth = AxisHelper.GetScaleWidth(radiusAxis, radius, i);
var pos = ChartHelper.GetPos(cenPos, totalWidth + tickWidth, 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)
{
if ((i == 0 && radiusAxis.axisTick.showStartTick) ||
(i == size && radiusAxis.axisTick.showEndTick) ||
(i > 0 && i < size))
{
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);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3f2cb79bfe30c4f14a3117f9f30ed3bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 17498717d39c14b43a91c67401407410
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,152 @@
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
/// <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(); }
}
/// <summary>
/// width of axis.
/// |坐标轴宽。
/// </summary>
public float width
{
get { return m_Width; }
set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetAllDirty(); }
}
/// <summary>
/// height of axis.
/// |坐标轴高。
/// </summary>
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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aeb871d6555744e609bd651306c601a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,125 @@
using UnityEngine;
using UnityEngine.UI;
namespace XCharts.Runtime
{
[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(null,
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, 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)
{
DrawAxisLine(vh, axis,
chart.theme.axis,
axis.orient,
axis.context.x,
GetAxisLineXOrY(),
axis.context.width);
}
}
protected override float GetAxisLineXOrY()
{
return component.context.y + component.offset;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50b3514e3079543ea9000d21d809cad3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e5e50f8f0f8bb406b99fb32d6b5c7769
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
/// <summary>
/// The x axis in cartesian(rectangular) coordinate.
/// |直角坐标系 grid 中的 x 轴。
/// </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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0a71be0d36b9745c2894e598b3d9188a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,152 @@
using UnityEngine;
using UnityEngine.UI;
namespace XCharts.Runtime
{
[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(yAxis,
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 relativedAxis = chart.GetChartComponent<YAxis>(xAxis.gridIndex);
var dataZoom = chart.GetDataZoomOfAxis(xAxis);
DrawAxisSplit(vh, chart.theme.axis, dataZoom,
Orient.Horizonal,
grid.context.x,
grid.context.y,
grid.context.width,
grid.context.height,
relativedAxis);
}
}
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);
DrawAxisTick(vh, xAxis, chart.theme.axis, dataZoom,
Orient.Horizonal,
grid.context.x,
GetAxisLineXOrY(),
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;
DrawAxisLine(vh, xAxis, chart.theme.axis,
Orient.Horizonal,
grid.context.x,
GetAxisLineXOrY(),
grid.context.width);
}
}
protected override float GetAxisLineXOrY()
{
var xAxis = component;
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
var startY = grid.context.y + xAxis.offset;
if (xAxis.IsTop())
startY += grid.context.height;
else
startY += ComponentHelper.GetXAxisOnZeroOffset(chart.components, xAxis);
return startY;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7818e1175663412196de53f19b5ac08
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 69f8ba8fcc7d84b12b42f837f9f2b94b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,30 @@
using System.Collections.Generic;
namespace XCharts.Runtime
{
/// <summary>
/// The x axis in cartesian(rectangular) coordinate.
/// |直角坐标系 grid 中的 y 轴。
/// </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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ac60b8329f7a45c3898c7539d78f091
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,149 @@
using UnityEngine;
using UnityEngine.UI;
namespace XCharts.Runtime
{
[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(xAxis,
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 relativedAxis = chart.GetChartComponent<XAxis>(yAxis.gridIndex);
var dataZoom = chart.GetDataZoomOfAxis(yAxis);
DrawAxisSplit(vh, chart.theme.axis, dataZoom,
Orient.Vertical,
grid.context.x,
grid.context.y,
grid.context.height,
grid.context.width,
relativedAxis);
}
}
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);
DrawAxisTick(vh, yAxis, chart.theme.axis, dataZoom,
Orient.Vertical,
GetAxisLineXOrY(),
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;
DrawAxisLine(vh, yAxis, chart.theme.axis,
Orient.Vertical,
GetAxisLineXOrY(),
grid.context.y,
grid.context.height);
}
}
protected override float GetAxisLineXOrY()
{
var yAxis = component;
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
var startX = grid.context.x + yAxis.offset;
if (yAxis.IsRight())
startX += grid.context.width;
else
startX += ComponentHelper.GetYAxisOnZeroOffset(chart.components, yAxis);
return startX;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f09b5dcb5fcc54583bcd7946f18dfa48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7db6fdcbbbfd148f58ff7a1f1a569d51
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,80 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace XCharts.Runtime
{
/// <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_AutoColor = 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 use theme background color for component color when the background component is on.
/// |当background组件开启时,是否自动使用主题背景色作为backgrounnd组件的颜色。当设置为false时,用imageColor作为颜色。
/// </summary>
public bool autoColor
{
get { return m_AutoColor; }
set { if (PropertyUtil.SetStruct(ref m_AutoColor, value)) SetVerticesDirty(); }
}
public override void SetDefaultValue()
{
m_Show = true;
m_Image = null;
m_ImageType = Image.Type.Sliced;
m_ImageColor = Color.white;
m_AutoColor = true;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 524f7df5241cc4379ae241a73d5b2ff2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
using System;
using UnityEngine;
using UnityEngine.UI;
using XUGL;
namespace XCharts.Runtime
{
[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 = chart.theme.GetBackgroundColor(component);
backgroundObj.transform.SetSiblingIndex(0);
backgroundObj.SetActive(component.show);
};
component.refreshComponent();
}
public override void Update()
{
if (component.gameObject != null && component.gameObject.transform.GetSiblingIndex() != 0)
component.gameObject.transform.SetSiblingIndex(0);
}
public override void DrawBase(VertexHelper vh)
{
if (!component.show)
return;
if (component.image != null)
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);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1cb3d1a2aa224bbe84eef2681cf3df4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 20d31ade0390641698e6b846b4294b74
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,131 @@
using UnityEngine;
namespace XCharts.Runtime
{
/// <summary>
/// The style of area.
/// |区域填充样式。
/// </summary>
[System.Serializable]
public class AreaStyle : ChildComponent, ISerieExtraComponent, ISerieDataComponent
{
/// <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 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>
/// 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;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec0d95a9298bb4c159dcae36020beec9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,92 @@
using System;
using UnityEngine;
namespace XCharts.Runtime
{
/// <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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2232b812c68f042d29c44863e38d0417
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,82 @@
using UnityEngine;
namespace XCharts.Runtime
{
/// <summary>
/// Settings related to base line.
/// |线条基础配置。
/// </summary>
[System.Serializable]
public class BaseLine : ChildComponent
{
[SerializeField] protected bool m_Show;
[SerializeField] protected LineStyle m_LineStyle = new LineStyle();
/// <summary>
/// Set this to false to prevent the axis line from showing.
/// |是否显示坐标轴轴线。
/// </summary>
public bool show
{
get { return m_Show; }
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
}
/// <summary>
/// 线条样式
/// </summary>
public LineStyle lineStyle
{
get { return m_LineStyle; }
set { if (value != null) { m_LineStyle = value; SetVerticesDirty(); } }
}
public static BaseLine defaultBaseLine
{
get
{
var axisLine = new BaseLine
{
m_Show = true,
m_LineStyle = new LineStyle()
};
return axisLine;
}
}
public BaseLine()
{
lineStyle = new LineStyle();
}
public BaseLine(bool show) : base()
{
m_Show = show;
}
public void Copy(BaseLine axisLine)
{
show = axisLine.show;
lineStyle.Copy(axisLine.lineStyle);
}
public LineStyle.Type GetType(LineStyle.Type themeType)
{
return lineStyle.GetType(themeType);
}
public float GetWidth(float themeWidth)
{
return lineStyle.GetWidth(themeWidth);
}
public float GetLength(float themeLength)
{
return lineStyle.GetLength(themeLength);
}
public Color32 GetColor(Color32 themeColor)
{
return lineStyle.GetColor(themeColor);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c431b00ccffe4db4b61179b6df06eb2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,118 @@
using UnityEngine;
using UnityEngine.UI;
namespace XCharts.Runtime
{
[System.Serializable]
public class IconStyle : ChildComponent
{
public enum Layer
{
/// <summary>
/// The icon is display under the label text.
/// 图标在标签文字下
/// </summary>
UnderText,
/// <summary>
/// The icon is display above the label text.
/// 图标在标签文字上
/// </summary>
AboveText
}
[SerializeField] private bool m_Show = false;
[SerializeField] private Layer m_Layer;
[SerializeField] private Align m_Align = Align.Left;
[SerializeField] private Sprite m_Sprite;
[SerializeField] private Image.Type m_Type;
[SerializeField] private Color m_Color = Color.white;
[SerializeField] private float m_Width = 20;
[SerializeField] private float m_Height = 20;
[SerializeField] private Vector3 m_Offset;
[SerializeField] private bool m_AutoHideWhenLabelEmpty = false;
public void Reset()
{
m_Show = false;
m_Layer = Layer.UnderText;
m_Sprite = null;
m_Color = Color.white;
m_Width = 20;
m_Height = 20;
m_Offset = Vector3.zero;
m_AutoHideWhenLabelEmpty = false;
}
/// <summary>
/// Whether the data icon is show.
/// |是否显示图标。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// 显示在上层还是在下层。
/// </summary>
public Layer layer { get { return m_Layer; } set { m_Layer = value; } }
/// <summary>
/// The image of icon.
/// |图标的图片。
/// </summary>
public Sprite sprite { get { return m_Sprite; } set { m_Sprite = value; } }
/// <summary>
/// How to display the icon.
/// |图片的显示类型。
/// </summary>
public Image.Type type { get { return m_Type; } set { m_Type = value; } }
/// <summary>
/// 图标颜色。
/// </summary>
public Color color { get { return m_Color; } set { m_Color = value; } }
/// <summary>
/// 图标宽。
/// </summary>
public float width { get { return m_Width; } set { m_Width = value; } }
/// <summary>
/// 图标高。
/// </summary>
public float height { get { return m_Height; } set { m_Height = value; } }
/// <summary>
/// 图标偏移。
/// </summary>
public Vector3 offset { get { return m_Offset; } set { m_Offset = value; } }
/// <summary>
/// 水平方向对齐方式。
/// </summary>
public Align align { get { return m_Align; } set { m_Align = value; } }
/// <summary>
/// 当label内容为空时是否自动隐藏图标
/// </summary>
public bool autoHideWhenLabelEmpty { get { return m_AutoHideWhenLabelEmpty; } set { m_AutoHideWhenLabelEmpty = value; } }
public IconStyle Clone()
{
var iconStyle = new IconStyle();
iconStyle.show = show;
iconStyle.layer = layer;
iconStyle.sprite = sprite;
iconStyle.type = type;
iconStyle.color = color;
iconStyle.width = width;
iconStyle.height = height;
iconStyle.offset = offset;
iconStyle.align = align;
iconStyle.autoHideWhenLabelEmpty = autoHideWhenLabelEmpty;
return iconStyle;
}
public void Copy(IconStyle iconStyle)
{
show = iconStyle.show;
layer = iconStyle.layer;
sprite = iconStyle.sprite;
type = iconStyle.type;
color = iconStyle.color;
width = iconStyle.width;
height = iconStyle.height;
offset = iconStyle.offset;
align = iconStyle.align;
autoHideWhenLabelEmpty = iconStyle.autoHideWhenLabelEmpty;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 82c4d360f7b5b4ee7845e9bbe611c8a3
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