mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-18 14:30:10 +00:00
0.2版本,重构代码,增加Editor
This commit is contained in:
164
Scripts/UI/BarChart.cs
Normal file
164
Scripts/UI/BarChart.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
|
||||
|
||||
[AddComponentMenu("XCharts/BarChart", 13)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class BarChart : CoordinateChart
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Bar
|
||||
{
|
||||
[SerializeField] private float m_BarWidth = 0.7f;
|
||||
[SerializeField] private float m_Space;
|
||||
|
||||
public float barWidth { get { return m_BarWidth; } set { m_BarWidth = value; } }
|
||||
public float space { get { return m_Space; } set { m_Space = value; } }
|
||||
}
|
||||
|
||||
[SerializeField] private Bar m_Bar = new Bar();
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected override void DrawChart(VertexHelper vh)
|
||||
{
|
||||
base.DrawChart(vh);
|
||||
if (m_YAxis.type == Axis.AxisType.Category)
|
||||
{
|
||||
var stackSeries = m_Series.GetStackSeries();
|
||||
int seriesCount = stackSeries.Count;
|
||||
float scaleWid = m_YAxis.GetDataWidth(coordinateHig);
|
||||
float barWid = m_Bar.barWidth > 1 ? m_Bar.barWidth : scaleWid * m_Bar.barWidth;
|
||||
float offset = (scaleWid - barWid * seriesCount - m_Bar.space * (seriesCount - 1)) / 2;
|
||||
float max = GetMaxValue();
|
||||
int serieCount = 0;
|
||||
for (int j = 0; j < seriesCount; j++)
|
||||
{
|
||||
var seriesCurrHig = new Dictionary<int, float>();
|
||||
var serieList = stackSeries[j];
|
||||
for (int n = 0; n < serieList.Count; n++)
|
||||
{
|
||||
Serie serie = serieList[n];
|
||||
if (!m_Legend.IsShowSeries(serie.name)) continue;
|
||||
Color color = m_ThemeInfo.GetColor(serieCount);
|
||||
int maxCount = maxShowDataNumber > 0 ?
|
||||
(maxShowDataNumber > serie.data.Count ? serie.data.Count : maxShowDataNumber)
|
||||
: serie.data.Count;
|
||||
for (int i = minShowDataNumber; i < maxCount; i++)
|
||||
{
|
||||
if (!seriesCurrHig.ContainsKey(i))
|
||||
{
|
||||
seriesCurrHig[i] = 0;
|
||||
}
|
||||
float data = serie.data[i];
|
||||
float pX = seriesCurrHig[i] + zeroX + m_Coordinate.tickness;
|
||||
float pY = zeroY + i * scaleWid;
|
||||
if (!m_YAxis.boundaryGap) pY -= scaleWid / 2;
|
||||
float barHig = data / max * coordinateWid;
|
||||
float space = offset + j * (barWid + m_Bar.space);
|
||||
seriesCurrHig[i] += barHig;
|
||||
Vector3 p1 = new Vector3(pX, pY + space + barWid);
|
||||
Vector3 p2 = new Vector3(pX + barHig, pY + space + barWid);
|
||||
Vector3 p3 = new Vector3(pX + barHig, pY + space);
|
||||
Vector3 p4 = new Vector3(pX, pY + space);
|
||||
if (serie.show)
|
||||
{
|
||||
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, color);
|
||||
}
|
||||
}
|
||||
if (serie.show)
|
||||
{
|
||||
serieCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_Tooltip.show && m_Tooltip.dataIndex > 0)
|
||||
{
|
||||
float tooltipSplitWid = scaleWid < 1 ? 1 : scaleWid;
|
||||
float pX = zeroX + coordinateWid;
|
||||
float pY = zeroY + scaleWid * (m_Tooltip.dataIndex - 1) - (m_YAxis.boundaryGap ? 0 : scaleWid / 2);
|
||||
Vector3 p1 = new Vector3(zeroX, pY);
|
||||
Vector3 p2 = new Vector3(zeroX, pY + tooltipSplitWid);
|
||||
Vector3 p3 = new Vector3(pX, pY + tooltipSplitWid);
|
||||
Vector3 p4 = new Vector3(pX, pY);
|
||||
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, m_ThemeInfo.tooltipFlagAreaColor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var stackSeries = m_Series.GetStackSeries();
|
||||
int seriesCount = stackSeries.Count;
|
||||
float scaleWid = m_XAxis.GetDataWidth(coordinateWid);
|
||||
float barWid = m_Bar.barWidth > 1 ? m_Bar.barWidth : scaleWid * m_Bar.barWidth;
|
||||
float offset = (scaleWid - barWid * seriesCount - m_Bar.space * (seriesCount - 1)) / 2;
|
||||
float max = GetMaxValue();
|
||||
int serieCount = 0;
|
||||
for (int j = 0; j < seriesCount; j++)
|
||||
{
|
||||
var seriesCurrHig = new Dictionary<int, float>();
|
||||
var serieList = stackSeries[j];
|
||||
for (int n = 0; n < serieList.Count; n++)
|
||||
{
|
||||
Serie serie = serieList[n];
|
||||
if (!m_Legend.IsShowSeries(serie.name)) continue;
|
||||
Color color = m_ThemeInfo.GetColor(serieCount);
|
||||
int maxCount = maxShowDataNumber > 0 ?
|
||||
(maxShowDataNumber > serie.data.Count ? serie.data.Count : maxShowDataNumber)
|
||||
: serie.data.Count;
|
||||
for (int i = minShowDataNumber; i < maxCount; i++)
|
||||
{
|
||||
if (!seriesCurrHig.ContainsKey(i))
|
||||
{
|
||||
seriesCurrHig[i] = 0;
|
||||
}
|
||||
float data = serie.data[i];
|
||||
float pX = zeroX + i * scaleWid;
|
||||
if (!m_XAxis.boundaryGap) pX -= scaleWid / 2;
|
||||
float pY = seriesCurrHig[i] + zeroY + m_Coordinate.tickness;
|
||||
float barHig = data / max * coordinateHig;
|
||||
seriesCurrHig[i] += barHig;
|
||||
float space = offset + j * (barWid + m_Bar.space);
|
||||
Vector3 p1 = new Vector3(pX + space, pY);
|
||||
Vector3 p2 = new Vector3(pX + space, pY + barHig);
|
||||
Vector3 p3 = new Vector3(pX + space + barWid, pY + barHig);
|
||||
Vector3 p4 = new Vector3(pX + space + barWid, pY);
|
||||
if (serie.show)
|
||||
{
|
||||
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, color);
|
||||
}
|
||||
}
|
||||
if (serie.show)
|
||||
{
|
||||
serieCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_Tooltip.show && m_Tooltip.dataIndex > 0)
|
||||
{
|
||||
float tooltipSplitWid = scaleWid < 1 ? 1 : scaleWid;
|
||||
float pX = zeroX + scaleWid * (m_Tooltip.dataIndex - 1) - (m_XAxis.boundaryGap?0:scaleWid/2);
|
||||
float pY = zeroY + coordinateHig;
|
||||
Vector3 p1 = new Vector3(pX, zeroY);
|
||||
Vector3 p2 = new Vector3(pX, pY);
|
||||
Vector3 p3 = new Vector3(pX + tooltipSplitWid, pY);
|
||||
Vector3 p4 = new Vector3(pX + tooltipSplitWid, zeroY);
|
||||
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, m_ThemeInfo.tooltipFlagAreaColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/BarChart.cs.meta
Normal file
13
Scripts/UI/BarChart.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 535d2697503c2a94a887354e22a5414d
|
||||
timeCreated: 1536795169
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Scripts/UI/Interface.meta
Normal file
10
Scripts/UI/Interface.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 253203a243755c744880211dbbc988a2
|
||||
folderAsset: yes
|
||||
timeCreated: 1554979427
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Scripts/UI/Interface/IJsonData.cs
Normal file
10
Scripts/UI/Interface/IJsonData.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public interface IJsonData
|
||||
{
|
||||
void ParseJsonData(string json);
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Interface/IJsonData.cs.meta
Normal file
13
Scripts/UI/Interface/IJsonData.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9132f4c137015247b44450c2cb23606
|
||||
timeCreated: 1555379601
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
11
Scripts/UI/Interface/IPropertyChanged.cs
Normal file
11
Scripts/UI/Interface/IPropertyChanged.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public interface IPropertyChanged
|
||||
{
|
||||
void OnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
13
Scripts/UI/Interface/IPropertyChanged.cs.meta
Normal file
13
Scripts/UI/Interface/IPropertyChanged.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24f32e2d632f08245ae885545f14a2a3
|
||||
timeCreated: 1554979427
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Scripts/UI/Internal.meta
Normal file
10
Scripts/UI/Internal.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 750348e0c6842d74e872391f6ea942da
|
||||
folderAsset: yes
|
||||
timeCreated: 1554221587
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
259
Scripts/UI/Internal/Axis.cs
Normal file
259
Scripts/UI/Internal/Axis.cs
Normal file
@@ -0,0 +1,259 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Axis : JsonDataSupport,IEquatable<Axis>
|
||||
{
|
||||
public enum AxisType
|
||||
{
|
||||
Value,
|
||||
Category,
|
||||
Time,
|
||||
Log
|
||||
}
|
||||
|
||||
public enum SplitLineType
|
||||
{
|
||||
None,
|
||||
Solid,
|
||||
Dashed,
|
||||
Dotted
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class AxisTick
|
||||
{
|
||||
[SerializeField] private bool m_Show;
|
||||
[SerializeField] private bool m_AlignWithLabel;
|
||||
[SerializeField] private bool m_Inside;
|
||||
[SerializeField] private float m_Length;
|
||||
|
||||
public bool show { get { return m_Show; }set { m_Show = value; } }
|
||||
public bool alignWithLabel { get { return m_AlignWithLabel; } set { m_AlignWithLabel = value; } }
|
||||
public bool inside { get { return m_Inside; }set { m_Inside = value; } }
|
||||
public float length { get { return m_Length; }set { m_Length = value; } }
|
||||
|
||||
public static AxisTick defaultTick
|
||||
{
|
||||
get
|
||||
{
|
||||
var tick = new AxisTick
|
||||
{
|
||||
m_Show = true,
|
||||
m_AlignWithLabel = false,
|
||||
m_Inside = false,
|
||||
m_Length = 5f
|
||||
};
|
||||
return tick;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] protected bool m_Show = true;
|
||||
[SerializeField] protected AxisType m_Type;
|
||||
[SerializeField] protected int m_SplitNumber = 5;
|
||||
[SerializeField] protected int m_TextRotation = 0;
|
||||
[SerializeField] protected bool m_ShowSplitLine = false;
|
||||
[SerializeField] protected SplitLineType m_SplitLineType = SplitLineType.Dashed;
|
||||
[SerializeField] protected bool m_BoundaryGap = true;
|
||||
[SerializeField] protected List<string> m_Data = new List<string>();
|
||||
[SerializeField] protected AxisTick m_AxisTick = AxisTick.defaultTick;
|
||||
|
||||
public bool show { get { return m_Show; }set { m_Show = value; } }
|
||||
public AxisType type { get { return m_Type; } set { m_Type = value; } }
|
||||
public int splitNumber { get { return m_SplitNumber; } set { m_SplitNumber = value; } }
|
||||
public int textRotation { get { return m_TextRotation; } set { m_TextRotation = value; } }
|
||||
public bool showSplitLine { get { return m_ShowSplitLine; } set { m_ShowSplitLine = value; } }
|
||||
public SplitLineType splitLineType { get { return m_SplitLineType; } set { m_SplitLineType = value; } }
|
||||
public bool boundaryGap { get { return m_BoundaryGap; } set { m_BoundaryGap = value; } }
|
||||
public List<string> data { get { return m_Data; } }
|
||||
public AxisTick axisTick { get { return m_AxisTick; }set { m_AxisTick = value; } }
|
||||
|
||||
public void Copy(Axis other)
|
||||
{
|
||||
m_Show = other.show;
|
||||
m_Type = other.type;
|
||||
m_SplitNumber = other.splitNumber;
|
||||
m_TextRotation = other.textRotation;
|
||||
m_ShowSplitLine = other.showSplitLine;
|
||||
m_SplitLineType = other.splitLineType;
|
||||
m_BoundaryGap = other.boundaryGap;
|
||||
m_Data.Clear();
|
||||
foreach (var d in other.data) m_Data.Add(d);
|
||||
}
|
||||
|
||||
public void ClearData()
|
||||
{
|
||||
m_Data.Clear();
|
||||
}
|
||||
|
||||
public void AddData(string category,int maxDataNumber)
|
||||
{
|
||||
if (maxDataNumber > 0)
|
||||
{
|
||||
while (m_Data.Count > maxDataNumber) m_Data.RemoveAt(0);
|
||||
}
|
||||
m_Data.Add(category);
|
||||
}
|
||||
|
||||
public string GetData(int index)
|
||||
{
|
||||
if (index >= 0 && index < data.Count)
|
||||
return data[index];
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
public int GetSplitNumber()
|
||||
{
|
||||
if (data.Count > 2 * m_SplitNumber || data.Count <= 0)
|
||||
return m_SplitNumber;
|
||||
else
|
||||
return data.Count;
|
||||
}
|
||||
|
||||
public float GetSplitWidth(float coordinateWidth)
|
||||
{
|
||||
return coordinateWidth / (m_BoundaryGap ? GetSplitNumber() : GetSplitNumber() - 1);
|
||||
}
|
||||
|
||||
public int GetDataNumber()
|
||||
{
|
||||
return data.Count;
|
||||
}
|
||||
|
||||
public float GetDataWidth(float coordinateWidth)
|
||||
{
|
||||
return coordinateWidth / (m_BoundaryGap ? data.Count : data.Count - 1);
|
||||
}
|
||||
|
||||
public string GetScaleName(int index, float maxData = 0)
|
||||
{
|
||||
if (m_Type == AxisType.Value)
|
||||
{
|
||||
return ((int)(maxData * index / (GetSplitNumber() -1))).ToString();
|
||||
}
|
||||
int dataCount = data.Count;
|
||||
if (dataCount <= 0) return "";
|
||||
|
||||
if(index == GetSplitNumber() - 1 && !m_BoundaryGap)
|
||||
{
|
||||
return data[data.Count-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
float rate = dataCount / GetSplitNumber();
|
||||
if (rate < 1) rate = 1;
|
||||
int offset = m_BoundaryGap ? (int)(rate / 2) : 0;
|
||||
int newIndex = (int)(index * rate >= dataCount - 1 ? dataCount - 1 : offset + index * rate);
|
||||
return data[newIndex];
|
||||
}
|
||||
}
|
||||
|
||||
public int GetScaleNumber()
|
||||
{
|
||||
if (data.Count > 2 * splitNumber || data.Count <= 0)
|
||||
return m_BoundaryGap ? m_SplitNumber + 1 : m_SplitNumber;
|
||||
else
|
||||
return m_BoundaryGap ? data.Count + 1 : data.Count;
|
||||
}
|
||||
|
||||
public float GetScaleWidth(float coordinateWidth)
|
||||
{
|
||||
int num = GetScaleNumber() - 1;
|
||||
if (num <= 0) num = 1;
|
||||
return coordinateWidth / num;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Axis)) return false;
|
||||
return Equals((Axis)obj);
|
||||
}
|
||||
|
||||
public bool Equals(Axis other)
|
||||
{
|
||||
return show == other.show &&
|
||||
type == other.type &&
|
||||
splitNumber == other.splitNumber &&
|
||||
showSplitLine == other.showSplitLine &&
|
||||
textRotation == other.textRotation &&
|
||||
splitLineType == other.splitLineType &&
|
||||
boundaryGap == other.boundaryGap &&
|
||||
ChartHelper.IsValueEqualsList<string>(m_Data, other.data);
|
||||
}
|
||||
|
||||
public static bool operator ==(Axis point1, Axis point2)
|
||||
{
|
||||
return point1.Equals(point2);
|
||||
}
|
||||
|
||||
public static bool operator !=(Axis point1, Axis point2)
|
||||
{
|
||||
return !point1.Equals(point2);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public override void ParseJsonData(string jsonData)
|
||||
{
|
||||
if (string.IsNullOrEmpty(jsonData) || !m_DataFromJson) return;
|
||||
m_Data = ChartHelper.ParseStringFromString(jsonData);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class XAxis : Axis
|
||||
{
|
||||
public static XAxis defaultXAxis
|
||||
{
|
||||
get
|
||||
{
|
||||
var axis = new XAxis
|
||||
{
|
||||
m_Show = true,
|
||||
m_Type = AxisType.Category,
|
||||
m_SplitNumber = 5,
|
||||
m_TextRotation = 0,
|
||||
m_ShowSplitLine = false,
|
||||
m_SplitLineType = SplitLineType.Dashed,
|
||||
m_BoundaryGap = true,
|
||||
m_Data = new List<string>()
|
||||
{
|
||||
"x1","x2","x3","x4","x5"
|
||||
}
|
||||
};
|
||||
return axis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class YAxis : Axis
|
||||
{
|
||||
public static YAxis defaultYAxis
|
||||
{
|
||||
get
|
||||
{
|
||||
var axis = new YAxis
|
||||
{
|
||||
m_Show = true,
|
||||
m_Type = AxisType.Value,
|
||||
m_SplitNumber = 5,
|
||||
m_TextRotation = 0,
|
||||
m_ShowSplitLine = false,
|
||||
m_SplitLineType = SplitLineType.Dashed,
|
||||
m_BoundaryGap = false,
|
||||
m_Data = new List<string>(5),
|
||||
};
|
||||
return axis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Axis.cs.meta
Normal file
13
Scripts/UI/Internal/Axis.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84f640465300fb34facae554552063b9
|
||||
timeCreated: 1554422468
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
367
Scripts/UI/Internal/BaseChart.cs
Normal file
367
Scripts/UI/Internal/BaseChart.cs
Normal file
@@ -0,0 +1,367 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class BaseChart : MaskableGraphic
|
||||
{
|
||||
private static readonly string s_TitleObjectName = "title";
|
||||
private static readonly string s_LegendObjectName = "legend";
|
||||
|
||||
[SerializeField] protected Theme m_Theme = Theme.Default;
|
||||
[SerializeField] protected ThemeInfo m_ThemeInfo;
|
||||
[SerializeField] protected Title m_Title = Title.defaultTitle;
|
||||
[SerializeField] protected Legend m_Legend = Legend.defaultLegend;
|
||||
[SerializeField] protected Tooltip m_Tooltip = Tooltip.defaultTooltip;
|
||||
[SerializeField] protected Series m_Series;
|
||||
|
||||
[SerializeField] protected bool m_Large;
|
||||
[SerializeField] protected int m_MinShowDataNumber;
|
||||
[SerializeField] protected int m_MaxShowDataNumber;
|
||||
[SerializeField] protected int m_MaxCacheDataNumber;
|
||||
|
||||
[NonSerialized] private Theme m_CheckTheme = 0;
|
||||
[NonSerialized] private Title m_CheckTitle = Title.defaultTitle;
|
||||
[NonSerialized] private Legend m_CheckLegend = Legend.defaultLegend;
|
||||
[NonSerialized] private float m_CheckWidth = 0;
|
||||
[NonSerialized] private float m_CheckHeight = 0;
|
||||
[NonSerialized] protected List<Text> m_LegendTextList = new List<Text>();
|
||||
|
||||
protected float chartWidth { get { return rectTransform.sizeDelta.x; } }
|
||||
protected float chartHeight { get { return rectTransform.sizeDelta.y; } }
|
||||
protected Vector2 chartAnchorMax { get { return rectTransform.anchorMax; } }
|
||||
protected Vector2 chartAnchorMin { get { return rectTransform.anchorMin; } }
|
||||
protected Vector2 chartPivot { get { return rectTransform.pivot; } }
|
||||
|
||||
public Title title { get { return m_Title; } }
|
||||
public Legend legend { get { return m_Legend; } }
|
||||
public Tooltip tooltip { get { return m_Tooltip; } }
|
||||
public Series series { get { return m_Series; } }
|
||||
|
||||
public bool large { get { return m_Large; } set { m_Large = value; } }
|
||||
public int minShowDataNumber
|
||||
{
|
||||
get { return m_MinShowDataNumber; }
|
||||
set { m_MinShowDataNumber = value; if (m_MinShowDataNumber < 0) m_MinShowDataNumber = 0; }
|
||||
}
|
||||
public int maxShowDataNumber
|
||||
{
|
||||
get { return m_MaxShowDataNumber; }
|
||||
set { m_MaxShowDataNumber = value; if (m_MaxShowDataNumber < 0) m_MaxShowDataNumber = 0; }
|
||||
}
|
||||
public int maxCacheDataNumber
|
||||
{
|
||||
get { return m_MaxCacheDataNumber; }
|
||||
set { m_MaxCacheDataNumber = value; if (m_MaxCacheDataNumber < 0) m_MaxCacheDataNumber = 0; }
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
m_ThemeInfo = ThemeInfo.Default;
|
||||
rectTransform.anchorMax = Vector2.zero;
|
||||
rectTransform.anchorMin = Vector2.zero;
|
||||
rectTransform.pivot = Vector2.zero;
|
||||
m_CheckWidth = chartWidth;
|
||||
m_CheckHeight = chartHeight;
|
||||
m_CheckTheme = m_Theme;
|
||||
InitTitle();
|
||||
InitLegend();
|
||||
InitTooltip();
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
CheckSize();
|
||||
CheckTheme();
|
||||
CheckTile();
|
||||
CheckLegend();
|
||||
CheckTooltip();
|
||||
}
|
||||
|
||||
protected override void Reset()
|
||||
{
|
||||
ChartHelper.DestoryAllChilds(transform);
|
||||
m_ThemeInfo = ThemeInfo.Dark;
|
||||
m_Title = Title.defaultTitle;
|
||||
m_Legend = Legend.defaultLegend;
|
||||
m_Tooltip = Tooltip.defaultTooltip;
|
||||
m_Series = Series.defaultSeries;
|
||||
InitTitle();
|
||||
InitLegend();
|
||||
InitTooltip();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
for (int i = transform.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
DestroyImmediate(transform.GetChild(i).gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddData(string legend, float value)
|
||||
{
|
||||
m_Series.AddData(legend, value, m_MaxCacheDataNumber);
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
public void AddData(int legend, float value)
|
||||
{
|
||||
m_Series.AddData(legend, value, m_MaxCacheDataNumber);
|
||||
}
|
||||
|
||||
public void UpdateData(string legend, float value, int dataIndex = 0)
|
||||
{
|
||||
m_Series.UpdateData(legend, value, dataIndex);
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
public void UpdateData(int legendIndex, float value, int dataIndex = 0)
|
||||
{
|
||||
m_Series.UpdateData(legendIndex, value, dataIndex);
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
public void UpdateTheme(Theme theme)
|
||||
{
|
||||
this.m_Theme = theme;
|
||||
OnThemeChanged();
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
private void InitTitle()
|
||||
{
|
||||
m_Title.OnChanged();
|
||||
TextAnchor anchor = m_Title.location.textAnchor;
|
||||
Vector2 anchorMin = m_Title.location.anchorMin;
|
||||
Vector2 anchorMax = m_Title.location.anchorMax;
|
||||
Vector2 pivot = m_Title.location.pivot;
|
||||
Vector3 titlePosition = m_Title.location.GetPosition(chartWidth, chartHeight);
|
||||
Vector3 subTitlePosition = -new Vector3(0, m_Title.textFontSize + m_Title.itemGap, 0);
|
||||
float titleWid = chartWidth;
|
||||
|
||||
var titleObject = ChartHelper.AddObject(s_TitleObjectName, transform, anchorMin, anchorMax,
|
||||
pivot, new Vector2(chartWidth, chartHeight));
|
||||
titleObject.transform.localPosition = titlePosition;
|
||||
ChartHelper.HideAllObject(titleObject, s_TitleObjectName);
|
||||
|
||||
Text titleText = ChartHelper.AddTextObject(s_TitleObjectName, titleObject.transform,
|
||||
m_ThemeInfo.font, m_ThemeInfo.textColor, anchor, anchorMin, anchorMax, pivot,
|
||||
new Vector2(titleWid, m_Title.textFontSize), m_Title.textFontSize);
|
||||
|
||||
titleText.alignment = anchor;
|
||||
titleText.gameObject.SetActive(m_Title.show);
|
||||
titleText.transform.localPosition = Vector2.zero;
|
||||
titleText.text = m_Title.text;
|
||||
|
||||
Text subText = ChartHelper.AddTextObject(s_TitleObjectName + "_sub", titleObject.transform,
|
||||
m_ThemeInfo.font, m_ThemeInfo.textColor, anchor, anchorMin, anchorMax, pivot,
|
||||
new Vector2(titleWid, m_Title.subTextFontSize), m_Title.subTextFontSize);
|
||||
|
||||
subText.alignment = anchor;
|
||||
subText.gameObject.SetActive(m_Title.show && !string.IsNullOrEmpty(m_Title.subText));
|
||||
subText.transform.localPosition = subTitlePosition;
|
||||
subText.text = m_Title.subText;
|
||||
}
|
||||
|
||||
private void InitLegend()
|
||||
{
|
||||
m_Legend.OnChanged();
|
||||
ChartHelper.HideAllObject(transform, s_LegendObjectName);
|
||||
TextAnchor anchor = m_Legend.location.textAnchor;
|
||||
Vector2 anchorMin = m_Legend.location.anchorMin;
|
||||
Vector2 anchorMax = m_Legend.location.anchorMax;
|
||||
Vector2 pivot = m_Legend.location.pivot;
|
||||
|
||||
var legendObject = ChartHelper.AddObject(s_LegendObjectName, transform, anchorMin, anchorMax,
|
||||
pivot, new Vector2(chartWidth, chartHeight));
|
||||
legendObject.transform.localPosition = m_Legend.location.GetPosition(chartWidth, chartHeight);
|
||||
ChartHelper.HideAllObject(legendObject, s_LegendObjectName);
|
||||
|
||||
for (int i = 0; i < m_Legend.data.Count; i++)
|
||||
{
|
||||
Button btn = ChartHelper.AddButtonObject(s_LegendObjectName + "_" + i, legendObject.transform,
|
||||
m_ThemeInfo.font, m_Legend.itemFontSize, m_ThemeInfo.legendTextColor, anchor,
|
||||
anchorMin, anchorMax, pivot, new Vector2(m_Legend.itemWidth, m_Legend.itemHeight));
|
||||
|
||||
m_Legend.SetButton(i, btn);
|
||||
m_Legend.UpdateButtonColor(i, m_ThemeInfo.GetColor(i), m_ThemeInfo.unableColor);
|
||||
btn.GetComponentInChildren<Text>().text = m_Legend.data[i];
|
||||
btn.onClick.AddListener(delegate ()
|
||||
{
|
||||
int index = int.Parse(btn.name.Split('_')[1]);
|
||||
m_Legend.SetShowData(index, !m_Legend.IsShowSeries(index));
|
||||
m_Legend.UpdateButtonColor(index, m_ThemeInfo.GetColor(index), m_ThemeInfo.unableColor);
|
||||
OnYMaxValueChanged();
|
||||
OnLegendButtonClicked();
|
||||
RefreshChart();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void InitTooltip()
|
||||
{
|
||||
GameObject obj = ChartHelper.AddTooltipObject("tooltip", transform, m_ThemeInfo.font);
|
||||
m_Tooltip.SetObj(obj);
|
||||
m_Tooltip.SetBackgroundColor(m_ThemeInfo.tooltipBackgroundColor);
|
||||
m_Tooltip.SetTextColor(m_ThemeInfo.tooltipTextColor);
|
||||
m_Tooltip.SetActive(false);
|
||||
}
|
||||
|
||||
private Vector3 GetLegendPosition(int i)
|
||||
{
|
||||
return m_Legend.location.GetPosition(chartWidth, chartHeight);
|
||||
}
|
||||
|
||||
protected float GetMaxValue()
|
||||
{
|
||||
if (m_Series == null) return 100;
|
||||
else return m_Series.GetMaxValue(m_Legend);
|
||||
}
|
||||
|
||||
protected float GetMaxValue(int index)
|
||||
{
|
||||
if (m_Series == null) return 100;
|
||||
else return m_Series.GetMaxValue(index);
|
||||
}
|
||||
|
||||
private void CheckSize()
|
||||
{
|
||||
if (m_CheckWidth != chartWidth || m_CheckHeight != chartHeight)
|
||||
{
|
||||
m_CheckWidth = chartWidth;
|
||||
m_CheckHeight = chartHeight;
|
||||
OnSizeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckTheme()
|
||||
{
|
||||
if (m_CheckTheme != m_Theme)
|
||||
{
|
||||
m_CheckTheme = m_Theme;
|
||||
OnThemeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckTile()
|
||||
{
|
||||
if (!m_CheckTitle.Equals(m_Title))
|
||||
{
|
||||
m_CheckTitle.Copy(m_Title);
|
||||
OnTitleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckLegend()
|
||||
{
|
||||
if (m_CheckLegend != m_Legend)
|
||||
{
|
||||
m_CheckLegend.Copy(m_Legend);
|
||||
OnLegendChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckTooltip()
|
||||
{
|
||||
if (!m_Tooltip.show) return;
|
||||
m_Tooltip.dataIndex = 0;
|
||||
Vector2 local;
|
||||
|
||||
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform,
|
||||
Input.mousePosition, null, out local))
|
||||
return;
|
||||
|
||||
if (local.x < 0 || local.x > chartWidth ||
|
||||
local.y < 0 || local.y > chartHeight)
|
||||
return;
|
||||
|
||||
CheckTootipArea(local);
|
||||
}
|
||||
|
||||
protected virtual void CheckTootipArea(Vector2 localPostion)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnSizeChanged()
|
||||
{
|
||||
InitTitle();
|
||||
InitLegend();
|
||||
}
|
||||
|
||||
protected virtual void OnThemeChanged()
|
||||
{
|
||||
switch (m_Theme)
|
||||
{
|
||||
case Theme.Dark:
|
||||
m_ThemeInfo.Copy(ThemeInfo.Dark);
|
||||
break;
|
||||
case Theme.Default:
|
||||
m_ThemeInfo.Copy(ThemeInfo.Default);
|
||||
break;
|
||||
case Theme.Light:
|
||||
m_ThemeInfo.Copy(ThemeInfo.Light);
|
||||
break;
|
||||
}
|
||||
InitTitle();
|
||||
InitLegend();
|
||||
}
|
||||
|
||||
protected virtual void OnTitleChanged()
|
||||
{
|
||||
InitTitle();
|
||||
}
|
||||
|
||||
protected virtual void OnLegendChanged()
|
||||
{
|
||||
InitLegend();
|
||||
}
|
||||
|
||||
protected virtual void OnYMaxValueChanged()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnLegendButtonClicked()
|
||||
{
|
||||
}
|
||||
|
||||
public void RefreshChart()
|
||||
{
|
||||
int tempWid = (int)chartWidth;
|
||||
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, tempWid - 1);
|
||||
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, tempWid);
|
||||
}
|
||||
|
||||
protected virtual void RefreshTooltip()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
vh.Clear();
|
||||
DrawBackground(vh);
|
||||
DrawChart(vh);
|
||||
DrawTooltip(vh);
|
||||
}
|
||||
|
||||
protected virtual void DrawChart(VertexHelper vh)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void DrawTooltip(VertexHelper vh)
|
||||
{
|
||||
}
|
||||
|
||||
private void DrawBackground(VertexHelper vh)
|
||||
{
|
||||
// draw bg
|
||||
Vector3 p1 = new Vector3(0, chartHeight);
|
||||
Vector3 p2 = new Vector3(chartWidth, chartHeight);
|
||||
Vector3 p3 = new Vector3(chartWidth, 0);
|
||||
Vector3 p4 = new Vector3(0, 0);
|
||||
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, m_ThemeInfo.backgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/BaseChart.cs.meta
Normal file
13
Scripts/UI/Internal/BaseChart.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5053a63a1ebdfe4f8972f194156c3d3
|
||||
timeCreated: 1536967243
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
81
Scripts/UI/Internal/Coordinate.cs
Normal file
81
Scripts/UI/Internal/Coordinate.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[Serializable]
|
||||
public class Coordinate : IEquatable<Coordinate>
|
||||
{
|
||||
[SerializeField] private float m_Left;
|
||||
[SerializeField] private float m_Right;
|
||||
[SerializeField] private float m_Top;
|
||||
[SerializeField] private float m_Bottom;
|
||||
[SerializeField] private float m_Tickness;
|
||||
[SerializeField] private int m_FontSize;
|
||||
|
||||
public float left { get { return m_Left; } set { m_Left = value; } }
|
||||
public float right { get { return m_Right; } set { m_Right = value; } }
|
||||
public float top { get { return m_Top; } set { m_Top = value; } }
|
||||
public float bottom { get { return m_Bottom; } set { m_Bottom = value; } }
|
||||
public float tickness { get { return m_Tickness; } set { m_Tickness = value; } }
|
||||
public int fontSize { get { return m_FontSize; } set { m_FontSize = value; } }
|
||||
|
||||
public static Coordinate defaultCoordinate
|
||||
{
|
||||
get
|
||||
{
|
||||
var coordinate = new Coordinate
|
||||
{
|
||||
m_Left = 40f,
|
||||
m_Right = 80f,
|
||||
m_Top = 40f,
|
||||
m_Bottom = 25f,
|
||||
m_Tickness = 0.6f,
|
||||
m_FontSize = 16,
|
||||
};
|
||||
return coordinate;
|
||||
}
|
||||
}
|
||||
public void Copy(Coordinate other)
|
||||
{
|
||||
m_Left = other.left;
|
||||
m_Right = other.right;
|
||||
m_Top = other.top;
|
||||
m_Bottom = other.bottom;
|
||||
m_Tickness = other.tickness;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Coordinate)) return false;
|
||||
return Equals((Coordinate)obj);
|
||||
}
|
||||
|
||||
public bool Equals(Coordinate other)
|
||||
{
|
||||
return m_Left == other.left &&
|
||||
m_Right == other.right &&
|
||||
m_Top == other.top &&
|
||||
m_Bottom == other.bottom &&
|
||||
m_Tickness == other.tickness &&
|
||||
m_FontSize == other.fontSize;
|
||||
}
|
||||
|
||||
public static bool operator ==(Coordinate point1, Coordinate point2)
|
||||
{
|
||||
return point1.Equals(point2);
|
||||
}
|
||||
|
||||
public static bool operator !=(Coordinate point1, Coordinate point2)
|
||||
{
|
||||
return !point1.Equals(point2);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Coordinate.cs.meta
Normal file
13
Scripts/UI/Internal/Coordinate.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7dea6e12aeb93945888247ea97dbd13
|
||||
timeCreated: 1554422468
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
497
Scripts/UI/Internal/CoordinateChart.cs
Normal file
497
Scripts/UI/Internal/CoordinateChart.cs
Normal file
@@ -0,0 +1,497 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class CoordinateChart : BaseChart
|
||||
{
|
||||
private static readonly string s_DefaultSplitNameY = "split_y";
|
||||
private static readonly string s_DefaultSplitNameX = "split_x";
|
||||
|
||||
[SerializeField] protected Coordinate m_Coordinate = Coordinate.defaultCoordinate;
|
||||
[SerializeField] protected XAxis m_XAxis = XAxis.defaultXAxis;
|
||||
[SerializeField] protected YAxis m_YAxis = YAxis.defaultYAxis;
|
||||
|
||||
[NonSerialized] private float m_LastXMaxValue;
|
||||
[NonSerialized] private float m_LastYMaxValue;
|
||||
[NonSerialized] private XAxis m_CheckXAxis = XAxis.defaultXAxis;
|
||||
[NonSerialized] private YAxis m_CheckYAxis = YAxis.defaultYAxis;
|
||||
[NonSerialized] private Coordinate m_CheckCoordinate = Coordinate.defaultCoordinate;
|
||||
|
||||
protected List<Text> m_SplitYTextList = new List<Text>();
|
||||
protected List<Text> m_SplitXTextList = new List<Text>();
|
||||
|
||||
public float zeroX { get { return m_Coordinate.left; } }
|
||||
public float zeroY { get { return m_Coordinate.bottom; } }
|
||||
public float coordinateWid { get { return chartWidth - m_Coordinate.left - m_Coordinate.right; } }
|
||||
public float coordinateHig { get { return chartHeight - m_Coordinate.top - m_Coordinate.bottom; } }
|
||||
public Axis xAxis { get { return m_XAxis; } }
|
||||
public Axis yAxis { get { return m_YAxis; } }
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
InitSplitX();
|
||||
InitSplitY();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
CheckYAxis();
|
||||
CheckXAxis();
|
||||
CheckMaxValue();
|
||||
CheckCoordinate();
|
||||
}
|
||||
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
m_Coordinate = Coordinate.defaultCoordinate;
|
||||
m_XAxis = XAxis.defaultXAxis;
|
||||
m_YAxis = YAxis.defaultYAxis;
|
||||
InitSplitX();
|
||||
InitSplitY();
|
||||
}
|
||||
|
||||
protected override void DrawChart(VertexHelper vh)
|
||||
{
|
||||
base.DrawChart(vh);
|
||||
DrawCoordinate(vh);
|
||||
}
|
||||
|
||||
protected override void CheckTootipArea(Vector2 local)
|
||||
{
|
||||
if (local.x < zeroX || local.x > zeroX + coordinateWid ||
|
||||
local.y < zeroY || local.y > zeroY + coordinateHig)
|
||||
{
|
||||
m_Tooltip.dataIndex = 0;
|
||||
RefreshTooltip();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_XAxis.type == Axis.AxisType.Value)
|
||||
{
|
||||
float splitWid = m_YAxis.GetDataWidth(coordinateHig);
|
||||
for (int i = 0; i < m_YAxis.GetDataNumber(); i++)
|
||||
{
|
||||
float pY = zeroY + i * splitWid;
|
||||
if (m_YAxis.boundaryGap)
|
||||
{
|
||||
if (local.y > pY && local.y <= pY + splitWid)
|
||||
{
|
||||
m_Tooltip.dataIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2)
|
||||
{
|
||||
m_Tooltip.dataIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float splitWid = m_XAxis.GetDataWidth(coordinateWid);
|
||||
for (int i = 0; i < m_XAxis.GetDataNumber(); i++)
|
||||
{
|
||||
float pX = zeroX + i * splitWid;
|
||||
if (m_XAxis.boundaryGap)
|
||||
{
|
||||
if (local.x > pX && local.x <= pX + splitWid)
|
||||
{
|
||||
m_Tooltip.dataIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2)
|
||||
{
|
||||
m_Tooltip.dataIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_Tooltip.dataIndex > 0)
|
||||
{
|
||||
m_Tooltip.UpdatePos(new Vector2(local.x + 18, local.y - 25));
|
||||
RefreshTooltip();
|
||||
if (m_Tooltip.lastDataIndex != m_Tooltip.dataIndex)
|
||||
{
|
||||
RefreshChart();
|
||||
}
|
||||
m_Tooltip.lastDataIndex = m_Tooltip.dataIndex;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RefreshTooltip()
|
||||
{
|
||||
base.RefreshTooltip();
|
||||
int index = m_Tooltip.dataIndex - 1;
|
||||
Axis tempAxis = m_XAxis.type == Axis.AxisType.Value ? (Axis)m_YAxis : (Axis)m_XAxis;
|
||||
if (index < 0)
|
||||
{
|
||||
m_Tooltip.SetActive(false);
|
||||
return;
|
||||
}
|
||||
m_Tooltip.SetActive(true);
|
||||
if (m_Series.Count == 1)
|
||||
{
|
||||
string txt = tempAxis.GetData(index) + ": " + m_Series.GetData(0,index);
|
||||
m_Tooltip.UpdateTooltipText(txt);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(tempAxis.GetData(index));
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (m_Series.series[i].show)
|
||||
{
|
||||
string strColor = ColorUtility.ToHtmlStringRGBA(m_ThemeInfo.GetColor(i));
|
||||
string key = m_Series.series[i].name;
|
||||
float value = m_Series.series[i].data[index];
|
||||
sb.Append("\n");
|
||||
sb.AppendFormat("<color=#{0}>● </color>", strColor);
|
||||
sb.AppendFormat("{0}: {1}", key, value);
|
||||
}
|
||||
|
||||
}
|
||||
m_Tooltip.UpdateTooltipText(sb.ToString());
|
||||
}
|
||||
var pos = m_Tooltip.GetPos();
|
||||
if (pos.x + m_Tooltip.width > chartWidth)
|
||||
{
|
||||
pos.x = chartWidth - m_Tooltip.width;
|
||||
}
|
||||
if (pos.y - m_Tooltip.height < 0)
|
||||
{
|
||||
pos.y = m_Tooltip.height;
|
||||
}
|
||||
m_Tooltip.UpdatePos(pos);
|
||||
}
|
||||
|
||||
TextGenerationSettings GetTextSetting()
|
||||
{
|
||||
var setting = new TextGenerationSettings();
|
||||
var fontdata = FontData.defaultFontData;
|
||||
|
||||
//setting.generationExtents = rectTransform.rect.size;
|
||||
setting.generationExtents = new Vector2(200.0F, 50.0F);
|
||||
setting.fontSize = 14;
|
||||
setting.textAnchor = TextAnchor.MiddleCenter;
|
||||
setting.scaleFactor = 1f;
|
||||
setting.color = Color.red;
|
||||
setting.font = m_ThemeInfo.font;
|
||||
setting.pivot = new Vector2(0.5f, 0.5f);
|
||||
setting.richText = false;
|
||||
setting.lineSpacing = 0;
|
||||
setting.fontStyle = FontStyle.Normal;
|
||||
setting.resizeTextForBestFit = false;
|
||||
setting.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||
setting.verticalOverflow = VerticalWrapMode.Overflow;
|
||||
|
||||
return setting;
|
||||
|
||||
}
|
||||
|
||||
protected override void OnThemeChanged()
|
||||
{
|
||||
base.OnThemeChanged();
|
||||
InitSplitX();
|
||||
InitSplitY();
|
||||
}
|
||||
|
||||
public void AddXAxisData(string category)
|
||||
{
|
||||
m_XAxis.AddData(category,m_MaxCacheDataNumber);
|
||||
OnXAxisChanged();
|
||||
}
|
||||
|
||||
public void AddYAxisData(string category)
|
||||
{
|
||||
m_YAxis.AddData(category, m_MaxCacheDataNumber);
|
||||
OnYAxisChanged();
|
||||
}
|
||||
|
||||
private void InitSplitY()
|
||||
{
|
||||
m_SplitYTextList.Clear();
|
||||
float max = GetMaxValue();
|
||||
float splitWidth = m_YAxis.GetScaleWidth(coordinateHig);
|
||||
|
||||
var titleObject = ChartHelper.AddObject(s_DefaultSplitNameY, transform, chartAnchorMin,
|
||||
chartAnchorMax, chartPivot, new Vector2(chartWidth, chartHeight));
|
||||
titleObject.transform.localPosition = Vector3.zero;
|
||||
ChartHelper.HideAllObject(titleObject, s_DefaultSplitNameY);
|
||||
|
||||
for (int i = 0; i < m_YAxis.splitNumber; i++)
|
||||
{
|
||||
Text txt = ChartHelper.AddTextObject(s_DefaultSplitNameY + i, titleObject.transform,
|
||||
m_ThemeInfo.font, m_ThemeInfo.textColor, TextAnchor.MiddleRight, Vector2.zero,
|
||||
Vector2.zero, new Vector2(1, 0.5f), new Vector2(m_Coordinate.left, 20),
|
||||
m_Coordinate.fontSize, m_XAxis.textRotation);
|
||||
txt.transform.localPosition = GetSplitYPosition(splitWidth, i);
|
||||
txt.text = m_YAxis.GetScaleName(i, max);
|
||||
txt.gameObject.SetActive(m_YAxis.show);
|
||||
m_SplitYTextList.Add(txt);
|
||||
}
|
||||
}
|
||||
|
||||
public void InitSplitX()
|
||||
{
|
||||
m_SplitXTextList.Clear();
|
||||
float max = GetMaxValue();
|
||||
float splitWidth = m_XAxis.GetScaleWidth(coordinateWid);
|
||||
|
||||
var titleObject = ChartHelper.AddObject(s_DefaultSplitNameX, transform, chartAnchorMin,
|
||||
chartAnchorMax, chartPivot, new Vector2(chartWidth, chartHeight));
|
||||
titleObject.transform.localPosition = Vector3.zero;
|
||||
ChartHelper.HideAllObject(titleObject, s_DefaultSplitNameX);
|
||||
|
||||
for (int i = 0; i < m_XAxis.splitNumber; i++)
|
||||
{
|
||||
Text txt = ChartHelper.AddTextObject(s_DefaultSplitNameX + i, titleObject.transform,
|
||||
m_ThemeInfo.font, m_ThemeInfo.textColor, TextAnchor.MiddleCenter, Vector2.zero,
|
||||
Vector2.zero, new Vector2(1, 0.5f), new Vector2(splitWidth, 20),
|
||||
m_Coordinate.fontSize, m_XAxis.textRotation);
|
||||
|
||||
txt.transform.localPosition = GetSplitXPosition(splitWidth, i);
|
||||
txt.text = m_XAxis.GetScaleName(i, max);
|
||||
txt.gameObject.SetActive(m_XAxis.show);
|
||||
m_SplitXTextList.Add(txt);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 GetSplitYPosition(float scaleWid, int i)
|
||||
{
|
||||
if (m_YAxis.boundaryGap)
|
||||
{
|
||||
return new Vector3(zeroX - m_YAxis.axisTick.length - 2f,
|
||||
zeroY + (i + 0.5f) * scaleWid, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Vector3(zeroX - m_YAxis.axisTick.length - 2f,
|
||||
zeroY + i * scaleWid, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 GetSplitXPosition(float scaleWid, int i)
|
||||
{
|
||||
if (m_XAxis.boundaryGap)
|
||||
{
|
||||
return new Vector3(zeroX + (i + 1) * scaleWid, zeroY - m_XAxis.axisTick.length - 5, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Vector3(zeroX + (i + 1 - 0.5f) * scaleWid,
|
||||
zeroY - m_XAxis.axisTick.length - 10, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckCoordinate()
|
||||
{
|
||||
if (m_CheckCoordinate != m_Coordinate)
|
||||
{
|
||||
m_CheckCoordinate.Copy(m_Coordinate);
|
||||
OnCoordinateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckYAxis()
|
||||
{
|
||||
if (m_CheckYAxis != m_YAxis)
|
||||
{
|
||||
m_CheckYAxis.Copy(m_YAxis);
|
||||
OnYAxisChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckXAxis()
|
||||
{
|
||||
if (!m_CheckXAxis.Equals(m_XAxis))
|
||||
{
|
||||
m_CheckXAxis.Copy(m_XAxis);
|
||||
OnXAxisChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckMaxValue()
|
||||
{
|
||||
if (m_XAxis.type == Axis.AxisType.Value)
|
||||
{
|
||||
float max = GetMaxValue();
|
||||
if (m_LastXMaxValue != max)
|
||||
{
|
||||
m_LastXMaxValue = max;
|
||||
OnXMaxValueChanged();
|
||||
}
|
||||
}
|
||||
else if (m_YAxis.type == Axis.AxisType.Value)
|
||||
{
|
||||
|
||||
float max = GetMaxValue();
|
||||
|
||||
if (m_LastYMaxValue != max)
|
||||
{
|
||||
m_LastYMaxValue = max;
|
||||
OnYMaxValueChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnCoordinateChanged()
|
||||
{
|
||||
InitSplitX();
|
||||
InitSplitY();
|
||||
}
|
||||
|
||||
protected virtual void OnYAxisChanged()
|
||||
{
|
||||
InitSplitY();
|
||||
}
|
||||
|
||||
protected virtual void OnXAxisChanged()
|
||||
{
|
||||
InitSplitX();
|
||||
}
|
||||
|
||||
protected virtual void OnXMaxValueChanged()
|
||||
{
|
||||
float max = GetMaxValue();
|
||||
for (int i = 0; i < m_SplitXTextList.Count; i++)
|
||||
{
|
||||
m_SplitXTextList[i].text = m_XAxis.GetScaleName(i, max);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnSizeChanged()
|
||||
{
|
||||
base.OnSizeChanged();
|
||||
InitSplitX();
|
||||
InitSplitY();
|
||||
}
|
||||
|
||||
protected override void OnYMaxValueChanged()
|
||||
{
|
||||
float max = GetMaxValue();
|
||||
for (int i = 0; i < m_SplitYTextList.Count; i++)
|
||||
{
|
||||
m_SplitYTextList[i].text = m_YAxis.GetScaleName(i, max);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCoordinate(VertexHelper vh)
|
||||
{
|
||||
#region draw tick and splitline
|
||||
if (m_YAxis.show)
|
||||
{
|
||||
for (int i = 1; i < m_YAxis.GetScaleNumber(); i++)
|
||||
{
|
||||
float pX = zeroX - m_YAxis.axisTick.length;
|
||||
float pY = zeroY + i * m_YAxis.GetScaleWidth(coordinateHig);
|
||||
if (m_YAxis.boundaryGap && m_YAxis.axisTick.alignWithLabel)
|
||||
{
|
||||
pY -= m_YAxis.GetScaleWidth(coordinateHig) / 2;
|
||||
}
|
||||
if (m_YAxis.axisTick.show)
|
||||
{
|
||||
ChartHelper.DrawLine(vh, new Vector3(pX, pY), new Vector3(zeroX, pY),
|
||||
m_Coordinate.tickness, m_ThemeInfo.axisLineColor);
|
||||
}
|
||||
if (m_YAxis.showSplitLine)
|
||||
{
|
||||
DrawSplitLine(vh, true, m_YAxis.splitLineType, new Vector3(zeroX, pY),
|
||||
new Vector3(zeroX + coordinateWid, pY));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_XAxis.show)
|
||||
{
|
||||
for (int i = 1; i < m_XAxis.GetScaleNumber(); i++)
|
||||
{
|
||||
float pX = zeroX + i * m_XAxis.GetScaleWidth(coordinateWid);
|
||||
float pY = zeroY - m_XAxis.axisTick.length - 2;
|
||||
if (m_XAxis.boundaryGap && m_XAxis.axisTick.alignWithLabel)
|
||||
{
|
||||
pX -= m_XAxis.GetScaleWidth(coordinateWid) / 2;
|
||||
}
|
||||
if (m_XAxis.axisTick.show)
|
||||
{
|
||||
ChartHelper.DrawLine(vh, new Vector3(pX, zeroY), new Vector3(pX, pY), m_Coordinate.tickness,
|
||||
m_ThemeInfo.axisLineColor);
|
||||
}
|
||||
if (m_XAxis.showSplitLine)
|
||||
{
|
||||
DrawSplitLine(vh, false, m_XAxis.splitLineType, new Vector3(pX, zeroY),
|
||||
new Vector3(pX, zeroY + coordinateHig));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
//draw x,y axis
|
||||
if (m_YAxis.show)
|
||||
{
|
||||
ChartHelper.DrawLine(vh, new Vector3(zeroX, zeroY - m_YAxis.axisTick.length),
|
||||
new Vector3(zeroX, zeroY + coordinateHig + 2), m_Coordinate.tickness,
|
||||
m_ThemeInfo.axisLineColor);
|
||||
}
|
||||
if (m_XAxis.show)
|
||||
{
|
||||
ChartHelper.DrawLine(vh, new Vector3(zeroX - m_XAxis.axisTick.length, zeroY),
|
||||
new Vector3(zeroX + coordinateWid + 2, zeroY), m_Coordinate.tickness,
|
||||
m_ThemeInfo.axisLineColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSplitLine(VertexHelper vh, bool isYAxis, Axis.SplitLineType type, Vector3 startPos,
|
||||
Vector3 endPos)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Axis.SplitLineType.Dashed:
|
||||
case Axis.SplitLineType.Dotted:
|
||||
var startX = startPos.x;
|
||||
var startY = startPos.y;
|
||||
var dashLen = type == Axis.SplitLineType.Dashed ? 6 : 2.5f;
|
||||
var count = isYAxis ? (endPos.x - startPos.x) / (dashLen * 2) :
|
||||
(endPos.y - startPos.y) / (dashLen * 2);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (isYAxis)
|
||||
{
|
||||
var toX = startX + dashLen;
|
||||
ChartHelper.DrawLine(vh, new Vector3(startX, startY), new Vector3(toX, startY),
|
||||
m_Coordinate.tickness, m_ThemeInfo.axisSplitLineColor);
|
||||
startX += dashLen * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
var toY = startY + dashLen;
|
||||
ChartHelper.DrawLine(vh, new Vector3(startX, startY), new Vector3(startX, toY),
|
||||
m_Coordinate.tickness, m_ThemeInfo.axisSplitLineColor);
|
||||
startY += dashLen * 2;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case Axis.SplitLineType.Solid:
|
||||
ChartHelper.DrawLine(vh, startPos, endPos, m_Coordinate.tickness,
|
||||
m_ThemeInfo.axisSplitLineColor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
Scripts/UI/Internal/CoordinateChart.cs.meta
Normal file
13
Scripts/UI/Internal/CoordinateChart.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c20b1e83703d1084c899f1f1b605c278
|
||||
timeCreated: 1538087401
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
32
Scripts/UI/Internal/JsonDataSupport.cs
Normal file
32
Scripts/UI/Internal/JsonDataSupport.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class JsonDataSupport: IJsonData,ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField] protected string m_JsonData;
|
||||
[SerializeField] protected bool m_DataFromJson;
|
||||
|
||||
public string jsonData { get { return m_JsonData; } set { m_JsonData = value; ParseJsonData(value); } }
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
if (m_DataFromJson)
|
||||
{
|
||||
ParseJsonData(m_JsonData);
|
||||
m_DataFromJson = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void ParseJsonData(string json)
|
||||
{
|
||||
throw new Exception("no support yet");
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/JsonDataSupport.cs.meta
Normal file
13
Scripts/UI/Internal/JsonDataSupport.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73e326ed8a76f90408bfa9feb1797433
|
||||
timeCreated: 1555379601
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
243
Scripts/UI/Internal/Legend.cs
Normal file
243
Scripts/UI/Internal/Legend.cs
Normal file
@@ -0,0 +1,243 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Legend : JsonDataSupport, IPropertyChanged, IEquatable<Legend>
|
||||
{
|
||||
public enum Orient
|
||||
{
|
||||
Horizonal,
|
||||
Vertical
|
||||
}
|
||||
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private Orient m_Orient = Orient.Horizonal;
|
||||
[SerializeField] private Location m_Location = Location.defaultRight;
|
||||
[SerializeField] private float m_ItemWidth = 50.0f;
|
||||
[SerializeField] private float m_ItemHeight = 20.0f;
|
||||
[SerializeField] private float m_ItemGap = 5;
|
||||
[SerializeField] private int m_ItemFontSize = 18;
|
||||
[SerializeField] private List<string> m_Data = new List<string>();
|
||||
|
||||
[NonSerialized] private List<bool> m_DataShowList = new List<bool>();
|
||||
[NonSerialized] private List<Button> m_DataBtnList = new List<Button>();
|
||||
|
||||
public bool show { get { return m_Show; } set { m_Show = value; } }
|
||||
|
||||
public Orient orient { get { return m_Orient; } set { m_Orient = value; } }
|
||||
|
||||
public Location location { get { return m_Location; } set { m_Location = value; } }
|
||||
|
||||
public float itemWidth { get { return m_ItemWidth; } set { m_ItemWidth = value; } }
|
||||
|
||||
public float itemHeight { get { return m_ItemHeight; } set { m_ItemHeight = value; } }
|
||||
|
||||
public float itemGap { get { return m_ItemGap; } set { m_ItemGap = value; } }
|
||||
|
||||
public int itemFontSize { get { return m_ItemFontSize; } set { m_ItemFontSize = value; } }
|
||||
|
||||
public List<string> data { get { return m_Data; } }
|
||||
|
||||
public static Legend defaultLegend
|
||||
{
|
||||
get
|
||||
{
|
||||
var legend = new Legend
|
||||
{
|
||||
m_Show = true,
|
||||
m_Orient = Orient.Horizonal,
|
||||
m_Location = Location.defaultRight,
|
||||
m_ItemWidth = 60.0f,
|
||||
m_ItemHeight = 20.0f,
|
||||
m_ItemGap = 5,
|
||||
m_ItemFontSize = 16,
|
||||
m_Data = new List<string>()
|
||||
{
|
||||
"Legend"
|
||||
}
|
||||
};
|
||||
return legend;
|
||||
}
|
||||
}
|
||||
public void Copy(Legend legend)
|
||||
{
|
||||
m_Show = legend.show;
|
||||
m_Orient = legend.orient;
|
||||
m_Location.Copy(legend.location);
|
||||
m_ItemWidth = legend.itemWidth;
|
||||
m_ItemHeight = legend.itemHeight;
|
||||
m_ItemGap = legend.itemGap;
|
||||
m_ItemFontSize = legend.itemFontSize;
|
||||
m_Data.Clear();
|
||||
foreach (var d in legend.data) m_Data.Add(d);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Legend)) return false;
|
||||
return Equals((Legend)obj);
|
||||
}
|
||||
|
||||
public bool Equals(Legend other)
|
||||
{
|
||||
return show == other.show &&
|
||||
orient == other.orient &&
|
||||
location == other.location &&
|
||||
itemWidth == other.itemWidth &&
|
||||
itemHeight == other.itemHeight &&
|
||||
itemGap == other.itemGap &&
|
||||
itemFontSize == other.itemFontSize &&
|
||||
ChartHelper.IsValueEqualsList<string>(m_Data, other.data);
|
||||
}
|
||||
|
||||
public static bool operator ==(Legend point1, Legend point2)
|
||||
{
|
||||
return point1.Equals(point2);
|
||||
}
|
||||
|
||||
public static bool operator !=(Legend point1, Legend point2)
|
||||
{
|
||||
return !point1.Equals(point2);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public bool IsShowSeries(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name)) return true;
|
||||
for(int i = 0; i < data.Count; i++)
|
||||
{
|
||||
if (name.Equals(data[i])) return m_DataShowList[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsShowSeries(int seriesIndex)
|
||||
{
|
||||
if (seriesIndex < 0 || seriesIndex > data.Count - 1) seriesIndex = 0;
|
||||
if (seriesIndex >= data.Count) return false;
|
||||
if (seriesIndex < 0 || seriesIndex > m_DataShowList.Count - 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_DataShowList[seriesIndex];
|
||||
}
|
||||
}
|
||||
|
||||
public void SetShowData(int index, bool flag)
|
||||
{
|
||||
m_DataShowList[index] = flag;
|
||||
}
|
||||
|
||||
public void SetButton(int index, Button btn)
|
||||
{
|
||||
btn.transform.localPosition = GetButtonLocationPosition(index);
|
||||
if (index < 0 || index > m_DataBtnList.Count - 1)
|
||||
{
|
||||
m_DataBtnList.Add(btn);
|
||||
m_DataShowList.Add(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DataBtnList[index] = btn;
|
||||
}
|
||||
btn.gameObject.SetActive(show);
|
||||
btn.GetComponentInChildren<Text>().text = data[index];
|
||||
}
|
||||
|
||||
public void UpdateButtonColor(int index,Color ableColor,Color unableColor)
|
||||
{
|
||||
if (IsShowSeries(index))
|
||||
{
|
||||
m_DataBtnList[index].GetComponent<Image>().color = ableColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DataBtnList[index].GetComponent<Image>().color = unableColor;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetShowData(string name, bool flag)
|
||||
{
|
||||
for (int i = 0; i < data.Count; i++)
|
||||
{
|
||||
if (data[i].Equals(name))
|
||||
{
|
||||
m_DataShowList[i] = flag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnChanged()
|
||||
{
|
||||
m_Location.OnChanged();
|
||||
}
|
||||
|
||||
private Vector2 GetButtonLocationPosition(int index)
|
||||
{
|
||||
int size = m_Data.Count;
|
||||
switch (m_Orient)
|
||||
{
|
||||
case Orient.Vertical:
|
||||
switch (m_Location.align)
|
||||
{
|
||||
case Location.Align.TopCenter:
|
||||
case Location.Align.TopLeft:
|
||||
case Location.Align.TopRight:
|
||||
return new Vector2(0, -index * (itemHeight + itemGap));
|
||||
|
||||
case Location.Align.Center:
|
||||
case Location.Align.CenterLeft:
|
||||
case Location.Align.CenterRight:
|
||||
float totalHeight = size * itemHeight + (size - 1) * itemGap;
|
||||
float startY = totalHeight / 2;
|
||||
return new Vector2(0, startY - index * (itemHeight + itemGap));
|
||||
|
||||
case Location.Align.BottomCenter:
|
||||
case Location.Align.BottomLeft:
|
||||
case Location.Align.BottomRight:
|
||||
return new Vector2(0, (size - index - 1) * (itemHeight + itemGap));
|
||||
}
|
||||
return Vector2.zero;
|
||||
|
||||
case Orient.Horizonal:
|
||||
switch (m_Location.align)
|
||||
{
|
||||
case Location.Align.TopLeft:
|
||||
case Location.Align.CenterLeft:
|
||||
case Location.Align.BottomLeft:
|
||||
return new Vector2(index * (itemWidth + itemGap), 0);
|
||||
|
||||
case Location.Align.TopCenter:
|
||||
case Location.Align.Center:
|
||||
case Location.Align.BottomCenter:
|
||||
float totalWidth = size * itemWidth + (size - 1) * itemGap;
|
||||
float startX = totalWidth / 2;
|
||||
return new Vector2(-startX + itemWidth / 2 + index * (itemWidth + itemGap), 0);
|
||||
case Location.Align.TopRight:
|
||||
case Location.Align.CenterRight:
|
||||
case Location.Align.BottomRight:
|
||||
return new Vector2(-(size - index - 1) * (itemWidth + itemGap), 0);
|
||||
}
|
||||
return Vector2.zero;
|
||||
}
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
public override void ParseJsonData(string jsonData)
|
||||
{
|
||||
if (string.IsNullOrEmpty(jsonData) || !m_DataFromJson) return;
|
||||
m_Data = ChartHelper.ParseStringFromString(jsonData);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Legend.cs.meta
Normal file
13
Scripts/UI/Internal/Legend.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fba76b49d7dd644cb3953355d6caae4
|
||||
timeCreated: 1554222818
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
41
Scripts/UI/Internal/Line.cs
Normal file
41
Scripts/UI/Internal/Line.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Line
|
||||
{
|
||||
[SerializeField] private float m_Tickness;
|
||||
[SerializeField] private bool m_Point;
|
||||
[SerializeField] private float m_PointWidth;
|
||||
[SerializeField] private bool m_Smooth;
|
||||
[SerializeField] [Range(1f, 10f)] private float m_SmoothStyle;
|
||||
[SerializeField] private bool m_Area;
|
||||
[SerializeField] private Color m_AreaColor;
|
||||
|
||||
public float tickness { get { return m_Tickness; } set { m_Tickness = value; } }
|
||||
public bool point { get { return m_Point; } set { m_Point = value; } }
|
||||
public float pointWidth { get { return m_PointWidth; } set { m_PointWidth = value; } }
|
||||
public bool smooth { get { return m_Smooth; } set { m_Smooth = value; } }
|
||||
public float smoothStyle { get { return m_SmoothStyle; } set { m_SmoothStyle = value; } }
|
||||
public bool area { get { return m_Area; } set { m_Area = value; } }
|
||||
public Color areaColor { get { return m_AreaColor; } set { m_AreaColor = value; } }
|
||||
|
||||
public static Line defaultLine
|
||||
{
|
||||
get
|
||||
{
|
||||
var line = new Line
|
||||
{
|
||||
m_Tickness = 0.8f,
|
||||
m_Point = true,
|
||||
m_PointWidth = 2.5f,
|
||||
m_Smooth = false,
|
||||
m_SmoothStyle = 2f,
|
||||
m_Area = false
|
||||
};
|
||||
return line;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Line.cs.meta
Normal file
13
Scripts/UI/Internal/Line.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86acdbfd671c43949bf0cc4880a4ccb7
|
||||
timeCreated: 1555671450
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
240
Scripts/UI/Internal/Location.cs
Normal file
240
Scripts/UI/Internal/Location.cs
Normal file
@@ -0,0 +1,240 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[Serializable]
|
||||
public class Location : IPropertyChanged, IEquatable<Location>
|
||||
{
|
||||
public enum Align
|
||||
{
|
||||
TopLeft,
|
||||
TopRight,
|
||||
TopCenter,
|
||||
BottomLeft,
|
||||
BottomRight,
|
||||
BottomCenter,
|
||||
Center,
|
||||
CenterLeft,
|
||||
CenterRight
|
||||
}
|
||||
|
||||
[SerializeField] private Align m_Align = Align.TopCenter;
|
||||
[SerializeField] private float m_Left;
|
||||
[SerializeField] private float m_Right;
|
||||
[SerializeField] private float m_Top;
|
||||
[SerializeField] private float m_Bottom;
|
||||
|
||||
private TextAnchor m_TextAnchor;
|
||||
private Vector2 m_AnchorMin;
|
||||
private Vector2 m_AnchorMax;
|
||||
private Vector2 m_Pivot;
|
||||
|
||||
public Align align { get { return m_Align; } set { m_Align = value; UpdateAlign(); } }
|
||||
public float left { get { return m_Left; } set { m_Left = value; UpdateAlign(); } }
|
||||
public float right { get { return m_Right; } set { m_Right = value; UpdateAlign(); } }
|
||||
public float top { get { return m_Top; } set { m_Top = value; UpdateAlign(); } }
|
||||
public float bottom { get { return m_Bottom; } set { m_Bottom = value; UpdateAlign(); } }
|
||||
|
||||
public TextAnchor textAnchor { get { return m_TextAnchor; } }
|
||||
public Vector2 anchorMin { get { return m_AnchorMin; } }
|
||||
public Vector2 anchorMax { get { return m_AnchorMax; } }
|
||||
public Vector2 pivot { get { return m_Pivot; } }
|
||||
|
||||
public static Location defaultLeft
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Location()
|
||||
{
|
||||
align = Align.CenterRight,
|
||||
left = 5,
|
||||
right = 0,
|
||||
top = 0,
|
||||
bottom = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static Location defaultRight
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Location()
|
||||
{
|
||||
align = Align.CenterRight,
|
||||
left = 0,
|
||||
right = 5,
|
||||
top = 0,
|
||||
bottom = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static Location defaultTop
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Location()
|
||||
{
|
||||
align = Align.TopCenter,
|
||||
left = 0,
|
||||
right = 0,
|
||||
top = 5,
|
||||
bottom = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static Location defaultBottom
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Location()
|
||||
{
|
||||
align = Align.BottomCenter,
|
||||
left = 0,
|
||||
right = 0,
|
||||
top = 0,
|
||||
bottom = 5
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAlign()
|
||||
{
|
||||
switch (m_Align)
|
||||
{
|
||||
case Align.BottomCenter:
|
||||
m_TextAnchor = TextAnchor.LowerCenter;
|
||||
m_AnchorMin = new Vector2(0.5f, 0);
|
||||
m_AnchorMax = new Vector2(0.5f, 0);
|
||||
m_Pivot = new Vector2(0.5f, 0);
|
||||
break;
|
||||
case Align.BottomLeft:
|
||||
m_TextAnchor = TextAnchor.LowerLeft;
|
||||
m_AnchorMin = new Vector2(0, 0);
|
||||
m_AnchorMax = new Vector2(0, 0);
|
||||
m_Pivot = new Vector2(0, 0);
|
||||
break;
|
||||
case Align.BottomRight:
|
||||
m_TextAnchor = TextAnchor.LowerRight;
|
||||
m_AnchorMin = new Vector2(1, 0);
|
||||
m_AnchorMax = new Vector2(1, 0);
|
||||
m_Pivot = new Vector2(1, 0);
|
||||
break;
|
||||
case Align.Center:
|
||||
m_TextAnchor = TextAnchor.MiddleCenter;
|
||||
m_AnchorMin = new Vector2(0.5f, 0.5f);
|
||||
m_AnchorMax = new Vector2(0.5f, 0.5f);
|
||||
m_Pivot = new Vector2(0.5f, 0.5f);
|
||||
break;
|
||||
case Align.CenterLeft:
|
||||
m_TextAnchor = TextAnchor.MiddleLeft;
|
||||
m_AnchorMin = new Vector2(0, 0.5f);
|
||||
m_AnchorMax = new Vector2(0, 0.5f);
|
||||
m_Pivot = new Vector2(0, 0.5f);
|
||||
break;
|
||||
case Align.CenterRight:
|
||||
m_TextAnchor = TextAnchor.MiddleRight;
|
||||
m_AnchorMin = new Vector2(1, 0.5f);
|
||||
m_AnchorMax = new Vector2(1, 0.5f);
|
||||
m_Pivot = new Vector2(1, 0.5f);
|
||||
break;
|
||||
case Align.TopCenter:
|
||||
m_TextAnchor = TextAnchor.UpperCenter;
|
||||
m_AnchorMin = new Vector2(0.5f, 1);
|
||||
m_AnchorMax = new Vector2(0.5f, 1);
|
||||
m_Pivot = new Vector2(0.5f, 1);
|
||||
break;
|
||||
case Align.TopLeft:
|
||||
m_TextAnchor = TextAnchor.UpperLeft;
|
||||
m_AnchorMin = new Vector2(0, 1);
|
||||
m_AnchorMax = new Vector2(0, 1);
|
||||
m_Pivot = new Vector2(0, 1);
|
||||
break;
|
||||
case Align.TopRight:
|
||||
m_TextAnchor = TextAnchor.UpperRight;
|
||||
m_AnchorMin = new Vector2(1, 1);
|
||||
m_AnchorMax = new Vector2(1, 1);
|
||||
m_Pivot = new Vector2(1, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 GetPosition(float chartWidht, float chartHeight)
|
||||
{
|
||||
switch (align)
|
||||
{
|
||||
case Align.BottomCenter:
|
||||
return new Vector2(chartWidht / 2, bottom);
|
||||
case Align.BottomLeft:
|
||||
return new Vector2(left, bottom);
|
||||
case Align.BottomRight:
|
||||
return new Vector2(chartWidht - right, bottom);
|
||||
case Align.Center:
|
||||
return new Vector2(chartWidht / 2, chartHeight / 2);
|
||||
case Align.CenterLeft:
|
||||
return new Vector2(left, chartHeight / 2);
|
||||
case Align.CenterRight:
|
||||
return new Vector2(chartWidht - right, chartHeight / 2);
|
||||
case Align.TopCenter:
|
||||
return new Vector2(chartWidht / 2, chartHeight - top);
|
||||
case Align.TopLeft:
|
||||
return new Vector2(left, chartHeight - top);
|
||||
case Align.TopRight:
|
||||
return new Vector2(chartWidht - right, chartHeight - top);
|
||||
default:
|
||||
return Vector2.zero;
|
||||
}
|
||||
}
|
||||
|
||||
public void Copy(Location location)
|
||||
{
|
||||
m_Align = location.align;
|
||||
m_Left = location.left;
|
||||
m_Right = location.right;
|
||||
m_Top = location.top;
|
||||
m_Bottom = location.bottom;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Location))
|
||||
return false;
|
||||
|
||||
return Equals((Location)obj);
|
||||
}
|
||||
|
||||
public bool Equals(Location other)
|
||||
{
|
||||
return align == other.align &&
|
||||
left == other.left &&
|
||||
right == other.right &&
|
||||
top == other.top &&
|
||||
bottom == other.bottom;
|
||||
}
|
||||
|
||||
public static bool operator ==(Location point1, Location point2)
|
||||
{
|
||||
return point1.Equals(point2);
|
||||
}
|
||||
|
||||
public static bool operator !=(Location point1, Location point2)
|
||||
{
|
||||
return !point1.Equals(point2);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public void OnChanged()
|
||||
{
|
||||
UpdateAlign();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Location.cs.meta
Normal file
13
Scripts/UI/Internal/Location.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 453c586e78719f046a387172174edb36
|
||||
timeCreated: 1554306777
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
46
Scripts/UI/Internal/Pie.cs
Normal file
46
Scripts/UI/Internal/Pie.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Pie
|
||||
{
|
||||
[SerializeField] private string m_Name;
|
||||
[SerializeField] private float m_InsideRadius;
|
||||
[SerializeField] private float m_OutsideRadius;
|
||||
[SerializeField] private float m_TooltipExtraRadius;
|
||||
[SerializeField] private bool m_Rose;
|
||||
[SerializeField] private float m_Space;
|
||||
[SerializeField] private float m_Left;
|
||||
[SerializeField] private float m_Right;
|
||||
[SerializeField] private float m_Top;
|
||||
[SerializeField] private float m_Bottom;
|
||||
|
||||
public string name { get { return m_Name; } set { m_Name = value; } }
|
||||
public float insideRadius { get { return m_InsideRadius; } set { m_InsideRadius = value; } }
|
||||
public float outsideRadius { get { return m_OutsideRadius; } set { m_OutsideRadius = value; } }
|
||||
public float tooltipExtraRadius { get { return m_TooltipExtraRadius; } set { m_TooltipExtraRadius = value; } }
|
||||
public bool rose { get { return m_Rose; } set { m_Rose = value; } }
|
||||
public float space { get { return m_Space; } set { m_Space = value; } }
|
||||
public float left { get { return m_Left; } set { m_Left = value; } }
|
||||
public float right { get { return m_Right; } set { m_Right = value; } }
|
||||
public float top { get { return m_Top; } set { m_Top = value; } }
|
||||
public float bottom { get { return m_Bottom; } set { m_Bottom = value; } }
|
||||
|
||||
public static Pie defaultPie
|
||||
{
|
||||
get
|
||||
{
|
||||
var pie = new Pie
|
||||
{
|
||||
m_Name = "Pie",
|
||||
m_InsideRadius = 0f,
|
||||
m_OutsideRadius = 80f,
|
||||
m_TooltipExtraRadius = 10f,
|
||||
m_Rose = false
|
||||
};
|
||||
return pie;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Pie.cs.meta
Normal file
13
Scripts/UI/Internal/Pie.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f38ef4633bae5247a8c382a4d20fc39
|
||||
timeCreated: 1555671161
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
189
Scripts/UI/Internal/Radar.cs
Normal file
189
Scripts/UI/Internal/Radar.cs
Normal file
@@ -0,0 +1,189 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Radar : JsonDataSupport, IEquatable<Radar>
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Indicator: IEquatable<Indicator>
|
||||
{
|
||||
public string m_Name;
|
||||
public float m_Max;
|
||||
|
||||
public string name { get { return m_Name; }set { m_Name = value; } }
|
||||
public float max { get { return m_Max; }set { m_Max = value; } }
|
||||
|
||||
public Indicator Clone()
|
||||
{
|
||||
return new Indicator()
|
||||
{
|
||||
name = name,
|
||||
max = max
|
||||
};
|
||||
}
|
||||
|
||||
public bool Equals(Indicator other)
|
||||
{
|
||||
return name.Equals(other.name);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private bool m_Cricle;
|
||||
[SerializeField] private bool m_Area;
|
||||
|
||||
[SerializeField] private float m_Radius = 100;
|
||||
[SerializeField] private int m_SplitNumber = 5;
|
||||
|
||||
[SerializeField] private float m_Left;
|
||||
[SerializeField] private float m_Right;
|
||||
[SerializeField] private float m_Top;
|
||||
[SerializeField] private float m_Bottom;
|
||||
|
||||
[SerializeField] private float m_LineTickness = 1f;
|
||||
[SerializeField] private float m_LinePointSize = 5f;
|
||||
[SerializeField] private Color m_LineColor = Color.grey;
|
||||
|
||||
[SerializeField] private List<Color> m_BackgroundColorList = new List<Color>();
|
||||
[SerializeField] private bool m_Indicator = true;
|
||||
[SerializeField] private List<Indicator> m_IndicatorList = new List<Indicator>();
|
||||
|
||||
public bool cricle { get { return m_Cricle; } set { m_Cricle = value; } }
|
||||
public bool area { get { return m_Area; } set { m_Area = value; } }
|
||||
|
||||
public float radius { get { return m_Radius; } set { m_Radius = value; } }
|
||||
public int splitNumber { get { return m_SplitNumber; } set { m_SplitNumber = value; } }
|
||||
|
||||
public float left { get { return m_Left; } set { m_Left = value; } }
|
||||
public float right { get { return m_Right; } set { m_Right = value; } }
|
||||
public float top { get { return m_Top; } set { m_Top = value; } }
|
||||
public float bottom { get { return m_Bottom; } set { m_Bottom = value; } }
|
||||
|
||||
public float lineTickness { get { return m_LineTickness; } set { m_LineTickness = value; } }
|
||||
public float linePointSize { get { return m_LinePointSize; } set { m_LinePointSize = value; } }
|
||||
public Color lineColor { get { return m_LineColor; } set { m_LineColor = value; } }
|
||||
public List<Color> backgroundColorList { get { return m_BackgroundColorList; } }
|
||||
public bool indicator { get { return m_Indicator; } set { m_Indicator = value; } }
|
||||
public List<Indicator> indicatorList { get { return m_IndicatorList; } }
|
||||
|
||||
public static Radar defaultRadar
|
||||
{
|
||||
get {
|
||||
var radar = new Radar
|
||||
{
|
||||
m_Cricle = false,
|
||||
m_Area = false,
|
||||
m_Radius = 100,
|
||||
m_SplitNumber = 5,
|
||||
m_Left = 0,
|
||||
m_Right = 0,
|
||||
m_Top = 0,
|
||||
m_Bottom = 0,
|
||||
m_LineTickness = 1f,
|
||||
m_LinePointSize = 5f,
|
||||
m_LineColor = Color.grey,
|
||||
m_Indicator = true,
|
||||
m_BackgroundColorList = new List<Color> {
|
||||
new Color32(194, 53, 49, 255),
|
||||
new Color32(47, 69, 84, 255)
|
||||
},
|
||||
m_IndicatorList = new List<Indicator>(5)
|
||||
};
|
||||
return radar;
|
||||
}
|
||||
}
|
||||
|
||||
public void Copy(Radar other)
|
||||
{
|
||||
m_Radius = other.radius;
|
||||
m_SplitNumber = other.splitNumber;
|
||||
m_Left = other.left;
|
||||
m_Right = other.right;
|
||||
m_Top = other.top;
|
||||
m_Bottom = other.bottom;
|
||||
m_Indicator = other.indicator;
|
||||
indicatorList.Clear();
|
||||
foreach (var d in other.indicatorList) indicatorList.Add(d.Clone());
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Radar)) return false;
|
||||
return Equals((Radar)obj);
|
||||
}
|
||||
|
||||
public bool Equals(Radar other)
|
||||
{
|
||||
return radius == other.radius &&
|
||||
splitNumber == other.splitNumber &&
|
||||
left == other.left &&
|
||||
right == other.right &&
|
||||
top == other.top &&
|
||||
bottom == other.bottom &&
|
||||
indicator == other.indicator &&
|
||||
IsEqualsIndicatorList(indicatorList, other.indicatorList);
|
||||
}
|
||||
|
||||
private bool IsEqualsIndicatorList(List<Indicator> indicators1,List<Indicator> indicators2)
|
||||
{
|
||||
if (indicators1.Count != indicators2.Count) return false;
|
||||
for(int i = 0; i < indicators1.Count; i++)
|
||||
{
|
||||
var indicator1 = indicators1[i];
|
||||
var indicator2 = indicators2[i];
|
||||
if (!indicator1.Equals(indicator2)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator ==(Radar point1, Radar point2)
|
||||
{
|
||||
return point1.Equals(point2);
|
||||
}
|
||||
|
||||
public static bool operator !=(Radar point1, Radar point2)
|
||||
{
|
||||
return !point1.Equals(point2);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public override void ParseJsonData(string jsonData)
|
||||
{
|
||||
if (string.IsNullOrEmpty(jsonData) || !m_DataFromJson) return;
|
||||
string pattern = "[\"|'](.*?)[\"|']";
|
||||
if (Regex.IsMatch(jsonData, pattern))
|
||||
{
|
||||
m_IndicatorList.Clear();
|
||||
MatchCollection m = Regex.Matches(jsonData, pattern);
|
||||
foreach (Match match in m)
|
||||
{
|
||||
m_IndicatorList.Add(new Indicator() {
|
||||
name = match.Groups[1].Value
|
||||
});
|
||||
}
|
||||
}
|
||||
pattern = "(\\d+)";
|
||||
if (Regex.IsMatch(jsonData, pattern))
|
||||
{
|
||||
MatchCollection m = Regex.Matches(jsonData, pattern);
|
||||
int index = 0;
|
||||
foreach (Match match in m)
|
||||
{
|
||||
if (m_IndicatorList[index]!=null)
|
||||
{
|
||||
m_IndicatorList[index].max = int.Parse(match.Groups[1].Value);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Radar.cs.meta
Normal file
13
Scripts/UI/Internal/Radar.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3a368484f9598e4eb9dfce2471d34da
|
||||
timeCreated: 1555562622
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
100
Scripts/UI/Internal/Serie.cs
Normal file
100
Scripts/UI/Internal/Serie.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Serie : JsonDataSupport
|
||||
{
|
||||
public enum SerieType
|
||||
{
|
||||
Line,
|
||||
Bar
|
||||
}
|
||||
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private SerieType m_Type;
|
||||
[SerializeField] private string m_Name;
|
||||
[SerializeField] private string m_Stack;
|
||||
[SerializeField] private List<float> m_Data = new List<float>();
|
||||
[SerializeField] private bool m_Flodout;
|
||||
|
||||
public bool show { get { return m_Show; }set { m_Show = value; } }
|
||||
public SerieType type { get { return m_Type; } set { m_Type = value; } }
|
||||
public string name { get { return m_Name; } set { m_Name = value; } }
|
||||
public string stack { get { return m_Stack; } set { m_Stack = value; } }
|
||||
public List<float> data { get { return m_Data; } }
|
||||
|
||||
public float Max
|
||||
{
|
||||
get
|
||||
{
|
||||
float max = int.MinValue;
|
||||
foreach (var data in data)
|
||||
{
|
||||
if (data > max)
|
||||
{
|
||||
max = data;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
public float Total
|
||||
{
|
||||
get
|
||||
{
|
||||
float total = 0;
|
||||
foreach (var data in data)
|
||||
{
|
||||
total += data;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearData()
|
||||
{
|
||||
m_Data.Clear();
|
||||
}
|
||||
|
||||
public void RemoveData(int index)
|
||||
{
|
||||
m_Data.RemoveAt(index);
|
||||
}
|
||||
|
||||
public void AddData(float value, int maxDataNumber)
|
||||
{
|
||||
if (maxDataNumber > 0)
|
||||
{
|
||||
while (m_Data.Count > maxDataNumber) m_Data.RemoveAt(0);
|
||||
}
|
||||
m_Data.Add(value);
|
||||
}
|
||||
|
||||
public float GetData(int index)
|
||||
{
|
||||
if (index >= 0 && index <= data.Count - 1)
|
||||
{
|
||||
return data[index];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void UpdateData(int index, float value)
|
||||
{
|
||||
if (index >= 0 && index <= m_Data.Count - 1)
|
||||
{
|
||||
m_Data[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ParseJsonData(string jsonData)
|
||||
{
|
||||
if (string.IsNullOrEmpty(jsonData) || !m_DataFromJson) return;
|
||||
m_Data = ChartHelper.ParseFloatFromString(jsonData);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Serie.cs.meta
Normal file
13
Scripts/UI/Internal/Serie.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bde61eb0785bad4d91d84d5511514ba
|
||||
timeCreated: 1554222818
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
221
Scripts/UI/Internal/Series.cs
Normal file
221
Scripts/UI/Internal/Series.cs
Normal file
@@ -0,0 +1,221 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Series : JsonDataSupport
|
||||
{
|
||||
[SerializeField] protected List<Serie> m_Series;
|
||||
|
||||
public List<Serie> series { get { return m_Series; } }
|
||||
|
||||
public int Count { get { return m_Series.Count; } }
|
||||
|
||||
public static Series defaultSeries
|
||||
{
|
||||
get
|
||||
{
|
||||
var series = new Series
|
||||
{
|
||||
m_Series = new List<Serie>()
|
||||
};
|
||||
return series;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearData()
|
||||
{
|
||||
foreach(var serie in m_Series)
|
||||
{
|
||||
serie.ClearData();
|
||||
}
|
||||
}
|
||||
|
||||
public float GetData(int serieIndex,int dataIndex)
|
||||
{
|
||||
if(serieIndex >= 0 && serieIndex < Count)
|
||||
{
|
||||
return m_Series[serieIndex].GetData(dataIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddData(string legend, float value, int maxDataNumber = 0)
|
||||
{
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (m_Series[i].name.Equals(legend))
|
||||
{
|
||||
m_Series[i].AddData(value, maxDataNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddData(int legend, float value, int maxDataNumber = 0)
|
||||
{
|
||||
if (legend >= 0 && legend < Count)
|
||||
{
|
||||
m_Series[legend].AddData(value, maxDataNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateData(string legend, float value, int dataIndex = 0)
|
||||
{
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (m_Series[i].name.Equals(legend))
|
||||
{
|
||||
m_Series[i].UpdateData(dataIndex, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateData(int legendIndex, float value, int dataIndex = 0)
|
||||
{
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (i == legendIndex)
|
||||
{
|
||||
m_Series[i].UpdateData(dataIndex, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetMaxValue(Legend legend)
|
||||
{
|
||||
float max = int.MinValue;
|
||||
if (IsStack())
|
||||
{
|
||||
var stackSeries = GetStackSeries();
|
||||
foreach (var ss in stackSeries)
|
||||
{
|
||||
var seriesTotalValue = new Dictionary<int, float>();
|
||||
for (int i = 0; i < ss.Value.Count; i++)
|
||||
{
|
||||
var serie = ss.Value[i];
|
||||
for (int j = 0; j < serie.data.Count; j++)
|
||||
{
|
||||
if (!seriesTotalValue.ContainsKey(j))
|
||||
seriesTotalValue[j] = 0;
|
||||
seriesTotalValue[j] = seriesTotalValue[j] + serie.data[j];
|
||||
}
|
||||
}
|
||||
float tmax = 0;
|
||||
foreach (var tt in seriesTotalValue)
|
||||
{
|
||||
if (tt.Value > tmax) tmax = tt.Value;
|
||||
}
|
||||
if (tmax > max) max = tmax;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (legend.IsShowSeries(i) && m_Series[i].Max > max) max = m_Series[i].Max;
|
||||
}
|
||||
}
|
||||
if (max == int.MinValue) return 100;
|
||||
if (max < 1 && max > -1) return max;
|
||||
int bigger = (int)Mathf.Abs(max);
|
||||
int n = 1;
|
||||
while (bigger / (Mathf.Pow(10, n)) > 10)
|
||||
{
|
||||
n++;
|
||||
}
|
||||
float mm = bigger < 10 ? bigger : ((bigger - bigger % (Mathf.Pow(10, n))) + Mathf.Pow(10, n));
|
||||
if (max < 0) return -mm;
|
||||
else return mm;
|
||||
}
|
||||
|
||||
public float GetMaxValue(int index,int splitNumber = 0)
|
||||
{
|
||||
float max = int.MinValue;
|
||||
float min = int.MaxValue;
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (m_Series[i].data[index] > max)
|
||||
{
|
||||
max = Mathf.Ceil(m_Series[i].data[index]);
|
||||
}
|
||||
if (m_Series[i].data[index] < min)
|
||||
{
|
||||
min = Mathf.Ceil(m_Series[i].data[index]);
|
||||
}
|
||||
}
|
||||
if (max < 1 && max > -1) return max;
|
||||
if (max < 0 && min < 0) max = min;
|
||||
int bigger = (int)Mathf.Abs(max);
|
||||
int n = 1;
|
||||
while (bigger / (Mathf.Pow(10, n)) > 10)
|
||||
{
|
||||
n++;
|
||||
}
|
||||
float mm = bigger < 10 ? bigger : ((bigger - bigger % (Mathf.Pow(10, n))) + Mathf.Pow(10, n));
|
||||
if (max < 1 && max > -1) return max;
|
||||
else if (max < 0) return -mm;
|
||||
else return mm;
|
||||
}
|
||||
|
||||
public bool IsStack()
|
||||
{
|
||||
HashSet<string> sets = new HashSet<string>();
|
||||
foreach (var serie in m_Series)
|
||||
{
|
||||
if (string.IsNullOrEmpty(serie.stack)) continue;
|
||||
if (sets.Contains(serie.stack)) return true;
|
||||
else
|
||||
{
|
||||
sets.Add(serie.stack);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Dictionary<int, List<Serie>> GetStackSeries()
|
||||
{
|
||||
int count = 0;
|
||||
Dictionary<string, int> sets = new Dictionary<string, int>();
|
||||
Dictionary<int, List<Serie>> stackSeries = new Dictionary<int, List<Serie>>();
|
||||
foreach (var serie in m_Series)
|
||||
{
|
||||
if (string.IsNullOrEmpty(serie.stack))
|
||||
{
|
||||
stackSeries[count] = new List<Serie>();
|
||||
stackSeries[count].Add(serie);
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sets.ContainsKey(serie.stack))
|
||||
{
|
||||
sets.Add(serie.stack, count);
|
||||
stackSeries[count] = new List<Serie>();
|
||||
stackSeries[count].Add(serie);
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int stackIndex = sets[serie.stack];
|
||||
stackSeries[stackIndex].Add(serie);
|
||||
}
|
||||
}
|
||||
}
|
||||
return stackSeries;
|
||||
}
|
||||
|
||||
public override void ParseJsonData(string jsonData)
|
||||
{
|
||||
//TODO:
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Series.cs.meta
Normal file
13
Scripts/UI/Internal/Series.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 137f78d348f866943a9fb8c1c8eaceef
|
||||
timeCreated: 1556016849
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
232
Scripts/UI/Internal/Theme.cs
Normal file
232
Scripts/UI/Internal/Theme.cs
Normal file
@@ -0,0 +1,232 @@
|
||||
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public enum Theme
|
||||
{
|
||||
Default = 1,
|
||||
Light,
|
||||
Dark
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ThemeInfo : IEquatable<ThemeInfo>
|
||||
{
|
||||
[SerializeField] private Font m_Font;
|
||||
[SerializeField] private Color32 m_BackgroundColor;
|
||||
[SerializeField] private Color32 m_ContrastColor;
|
||||
[SerializeField] private Color32 m_TextColor;
|
||||
[SerializeField] private Color32 m_SubTextColor;
|
||||
[SerializeField] private Color32 m_LegendTextColor;
|
||||
[SerializeField] private Color32 m_UnableColor;
|
||||
[SerializeField] private Color32 m_AxisLineColor;
|
||||
[SerializeField] private Color32 m_AxisSplitLineColor;
|
||||
[SerializeField] private Color32 m_TooltipBackgroundColor;
|
||||
[SerializeField] private Color32 m_TooltipFlagAreaColor;
|
||||
[SerializeField] private Color32 m_TooltipTextColor;
|
||||
[SerializeField] private Color32[] m_ColorPalette;
|
||||
|
||||
public Font font { get { return m_Font; } set { m_Font = value; } }
|
||||
public Color32 backgroundColor { get { return m_BackgroundColor; } set { m_BackgroundColor = value; } }
|
||||
public Color32 contrastColor { get { return m_ContrastColor; } set { m_ContrastColor = value; } }
|
||||
public Color32 textColor { get { return m_TextColor; } set { m_TextColor = value; } }
|
||||
public Color32 subTextColor { get { return m_SubTextColor; } set { m_SubTextColor = value; } }
|
||||
public Color32 legendTextColor { get { return m_LegendTextColor; } set { m_LegendTextColor = value; } }
|
||||
public Color32 unableColor { get { return m_UnableColor; } set { m_UnableColor = value; } }
|
||||
public Color32 axisLineColor { get { return m_AxisLineColor; } set { m_AxisLineColor = value; } }
|
||||
public Color32 axisSplitLineColor { get { return m_AxisSplitLineColor; } set { m_AxisSplitLineColor = value; } }
|
||||
public Color32 tooltipBackgroundColor { get { return m_TooltipBackgroundColor; } set { m_TooltipBackgroundColor = value; } }
|
||||
public Color32 tooltipFlagAreaColor { get { return m_TooltipFlagAreaColor; } set { m_TooltipFlagAreaColor = value; } }
|
||||
public Color32 tooltipTextColor { get { return m_TooltipTextColor; } set { m_TooltipTextColor = value; } }
|
||||
public Color32[] colorPalette { get { return m_ColorPalette; } set { m_ColorPalette = value; } }
|
||||
|
||||
public Color32 GetColor(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
index = index % m_ColorPalette.Length;
|
||||
return m_ColorPalette[index];
|
||||
}
|
||||
|
||||
public void Copy(ThemeInfo theme)
|
||||
{
|
||||
m_Font = theme.m_Font;
|
||||
m_BackgroundColor = theme.m_BackgroundColor;
|
||||
m_ContrastColor = theme.m_ContrastColor;
|
||||
m_UnableColor = theme.m_UnableColor;
|
||||
m_TextColor = theme.m_TextColor;
|
||||
m_SubTextColor = theme.m_SubTextColor;
|
||||
m_LegendTextColor = theme.m_LegendTextColor;
|
||||
m_AxisLineColor = theme.m_AxisLineColor;
|
||||
m_AxisSplitLineColor = theme.m_AxisSplitLineColor;
|
||||
m_TooltipBackgroundColor = theme.m_TooltipBackgroundColor;
|
||||
m_TooltipTextColor = theme.m_TooltipTextColor;
|
||||
m_ColorPalette = new Color32[theme.m_ColorPalette.Length];
|
||||
for (int i = 0; i < theme.m_ColorPalette.Length; i++)
|
||||
{
|
||||
m_ColorPalette[i] = theme.m_ColorPalette[i];
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeInfo Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ThemeInfo()
|
||||
{
|
||||
m_Font = Resources.GetBuiltinResource<Font>("Arial.ttf"),
|
||||
m_BackgroundColor = new Color32(255, 255, 255, 255),
|
||||
m_ContrastColor = GetColor("#514D4D"),
|
||||
m_UnableColor = GetColor("#cccccc"),
|
||||
m_TextColor = GetColor("#514D4D"),
|
||||
m_SubTextColor = GetColor("#514D4D"),
|
||||
m_LegendTextColor = GetColor("#eee"),
|
||||
m_AxisLineColor = GetColor("#514D4D"),
|
||||
m_AxisSplitLineColor = GetColor("#51515120"),
|
||||
m_TooltipBackgroundColor = GetColor("#515151B5"),
|
||||
m_TooltipTextColor = GetColor("#FFFFFFFF"),
|
||||
m_TooltipFlagAreaColor = GetColor("#51515120"),
|
||||
m_ColorPalette = new Color32[]
|
||||
{
|
||||
new Color32(194, 53, 49, 255),
|
||||
new Color32(47, 69, 84, 255),
|
||||
new Color32(97, 160, 168, 255),
|
||||
new Color32(212, 130, 101, 255),
|
||||
new Color32(145, 199, 174, 255),
|
||||
new Color32(116, 159, 131, 255),
|
||||
new Color32(202, 134, 34, 255),
|
||||
new Color32(189, 162, 154, 255),
|
||||
new Color32(110, 112, 116, 255),
|
||||
new Color32(84, 101, 112, 255),
|
||||
new Color32(196, 204, 211, 255)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeInfo Light
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ThemeInfo()
|
||||
{
|
||||
m_Font = Resources.GetBuiltinResource<Font>("Arial.ttf"),
|
||||
m_BackgroundColor = new Color32(255, 255, 255, 255),
|
||||
m_ContrastColor = GetColor("#514D4D"),
|
||||
m_UnableColor = GetColor("#cccccc"),
|
||||
m_TextColor = GetColor("#514D4D"),
|
||||
m_SubTextColor = GetColor("#514D4D"),
|
||||
m_LegendTextColor = GetColor("#514D4D"),
|
||||
m_AxisLineColor = GetColor("#514D4D"),
|
||||
m_AxisSplitLineColor = GetColor("#51515120"),
|
||||
m_TooltipBackgroundColor = GetColor("#515151B5"),
|
||||
m_TooltipTextColor = GetColor("#FFFFFFFF"),
|
||||
m_TooltipFlagAreaColor = GetColor("#51515120"),
|
||||
m_ColorPalette = new Color32[]
|
||||
{
|
||||
new Color32(55, 162, 218, 255),
|
||||
new Color32(255, 159, 127, 255),
|
||||
new Color32(50, 197, 233, 255),
|
||||
new Color32(251, 114, 147, 255),
|
||||
new Color32(103, 224, 227, 255),
|
||||
new Color32(224, 98, 174, 255),
|
||||
new Color32(159, 230, 184, 255),
|
||||
new Color32(230, 144, 209, 255),
|
||||
new Color32(255, 219, 92, 255),
|
||||
new Color32(230, 188, 243, 255),
|
||||
new Color32(157, 150, 245, 255),
|
||||
new Color32(131, 120, 234, 255),
|
||||
new Color32(150, 191, 255, 255)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeInfo Dark
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ThemeInfo()
|
||||
{
|
||||
m_Font = Resources.GetBuiltinResource<Font>("Arial.ttf"),
|
||||
m_UnableColor = GetColor("#cccccc"),
|
||||
m_BackgroundColor = new Color32(34, 34, 34, 255),
|
||||
m_ContrastColor = GetColor("#eee"),
|
||||
m_TextColor = GetColor("#eee"),
|
||||
m_SubTextColor = GetColor("#eee"),
|
||||
m_LegendTextColor = GetColor("#eee"),
|
||||
m_AxisLineColor = GetColor("#eee"),
|
||||
m_AxisSplitLineColor = GetColor("#aaa"),
|
||||
m_TooltipBackgroundColor = GetColor("#515151B5"),
|
||||
m_TooltipTextColor = GetColor("#FFFFFFFF"),
|
||||
m_TooltipFlagAreaColor = GetColor("#51515120"),
|
||||
m_ColorPalette = new Color32[]
|
||||
{
|
||||
new Color32(221, 107, 102, 255),
|
||||
new Color32(117, 154, 160, 255),
|
||||
new Color32(230, 157, 135, 255),
|
||||
new Color32(141, 193, 169, 255),
|
||||
new Color32(234, 126, 83, 255),
|
||||
new Color32(238, 221, 120, 255),
|
||||
new Color32(115, 163, 115, 255),
|
||||
new Color32(115, 185, 188, 255),
|
||||
new Color32(114, 137, 171, 255),
|
||||
new Color32(145, 202, 140, 255),
|
||||
new Color32(244, 159, 66, 255)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static Color32 GetColor(string hexColorStr)
|
||||
{
|
||||
Color color;
|
||||
ColorUtility.TryParseHtmlString(hexColorStr, out color);
|
||||
return (Color32)color;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is ThemeInfo))
|
||||
return false;
|
||||
|
||||
return Equals((ThemeInfo)obj);
|
||||
}
|
||||
|
||||
public bool Equals(ThemeInfo other)
|
||||
{
|
||||
return m_Font == other.m_Font &&
|
||||
ChartHelper.IsValueEqualsColor(m_UnableColor, other.m_UnableColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_BackgroundColor, other.m_BackgroundColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_ContrastColor, other.m_ContrastColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_TextColor, other.m_TextColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_SubTextColor, other.m_SubTextColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_AxisLineColor, other.m_AxisLineColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_AxisSplitLineColor, other.m_AxisSplitLineColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_TooltipBackgroundColor, other.m_TooltipBackgroundColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_AxisSplitLineColor, other.m_AxisSplitLineColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_TooltipTextColor, other.m_TooltipTextColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_TooltipFlagAreaColor, other.m_TooltipFlagAreaColor) &&
|
||||
m_ColorPalette.Length == other.m_ColorPalette.Length;
|
||||
}
|
||||
|
||||
public static bool operator ==(ThemeInfo point1, ThemeInfo point2)
|
||||
{
|
||||
return point1.Equals(point2);
|
||||
}
|
||||
|
||||
public static bool operator !=(ThemeInfo point1, ThemeInfo point2)
|
||||
{
|
||||
return !point1.Equals(point2);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Theme.cs.meta
Normal file
13
Scripts/UI/Internal/Theme.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 337565e835799d44bb794677abf84498
|
||||
timeCreated: 1554221927
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
91
Scripts/UI/Internal/Title.cs
Normal file
91
Scripts/UI/Internal/Title.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[Serializable]
|
||||
public class Title: IPropertyChanged,IEquatable<Title>
|
||||
{
|
||||
[SerializeField] private bool m_Show;
|
||||
[SerializeField] private string m_Text;
|
||||
[SerializeField] private int m_TextFontSize;
|
||||
[SerializeField] private string m_SubText;
|
||||
[SerializeField] private int m_SubTextFontSize;
|
||||
[SerializeField] private float m_ItemGap;
|
||||
[SerializeField] private Location m_Location;
|
||||
|
||||
public bool show { get { return m_Show; } set { m_Show = value; } }
|
||||
public string text { get { return m_Text; } set { m_Text = value; } }
|
||||
public int textFontSize { get { return m_TextFontSize; }set { m_TextFontSize = value; } }
|
||||
public string subText { get { return m_SubText; } set { m_Text = value; } }
|
||||
public int subTextFontSize { get { return m_SubTextFontSize; } set { m_SubTextFontSize = value; } }
|
||||
public float itemGap { get { return m_ItemGap; } set { m_ItemGap = value; } }
|
||||
public Location location { get { return m_Location; } set { m_Location = value; } }
|
||||
|
||||
public static Title defaultTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
var title = new Title
|
||||
{
|
||||
m_Show = true,
|
||||
m_Text = "Chart Title",
|
||||
m_TextFontSize = 16,
|
||||
m_SubText = "",
|
||||
m_SubTextFontSize = 14,
|
||||
m_ItemGap = 14,
|
||||
m_Location = Location.defaultTop
|
||||
};
|
||||
return title;
|
||||
}
|
||||
}
|
||||
public void Copy(Title title)
|
||||
{
|
||||
m_Show = title.show;
|
||||
m_Text = title.text;
|
||||
m_TextFontSize = title.textFontSize;
|
||||
m_SubText = title.subText;
|
||||
m_SubTextFontSize = title.subTextFontSize;
|
||||
m_ItemGap = title.itemGap;
|
||||
m_Location.Copy(title.location);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Title)) return false;
|
||||
return Equals((Title)obj);
|
||||
}
|
||||
|
||||
public bool Equals(Title other)
|
||||
{
|
||||
return m_Show == other.show &&
|
||||
m_Text.Equals(other.text) &&
|
||||
m_TextFontSize == other.textFontSize &&
|
||||
m_SubText.Equals(other.subText) &&
|
||||
m_SubTextFontSize == other.subTextFontSize &&
|
||||
m_ItemGap == other.itemGap &&
|
||||
m_Location.Equals(other.location);
|
||||
}
|
||||
|
||||
public static bool operator == (Title point1, Title point2)
|
||||
{
|
||||
return point1.Equals(point2);
|
||||
}
|
||||
|
||||
public static bool operator != (Title point1, Title point2)
|
||||
{
|
||||
return !point1.Equals(point2);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public void OnChanged()
|
||||
{
|
||||
m_Location.OnChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Title.cs.meta
Normal file
13
Scripts/UI/Internal/Title.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e41a7f82b5a931408f301257fbc09e2
|
||||
timeCreated: 1554222818
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
74
Scripts/UI/Internal/Tooltip.cs
Normal file
74
Scripts/UI/Internal/Tooltip.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Tooltip
|
||||
{
|
||||
[SerializeField] private bool m_Show;
|
||||
|
||||
[NonSerialized] private GameObject m_GameObject;
|
||||
[NonSerialized] private Text m_Text;
|
||||
[NonSerialized] private RectTransform m_BackgroudRect;
|
||||
|
||||
public bool show { get { return m_Show; }set { m_Show = value; } }
|
||||
public int dataIndex { get; set; }
|
||||
public int lastDataIndex { get; set; }
|
||||
public float width { get { return m_BackgroudRect.sizeDelta.x; } }
|
||||
public float height { get { return m_BackgroudRect.sizeDelta.y; } }
|
||||
|
||||
public static Tooltip defaultTooltip
|
||||
{
|
||||
get
|
||||
{
|
||||
var tooltip = new Tooltip
|
||||
{
|
||||
m_Show = true
|
||||
};
|
||||
return tooltip;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetObj(GameObject obj)
|
||||
{
|
||||
m_GameObject = obj;
|
||||
m_BackgroudRect = m_GameObject.GetComponent<RectTransform>();
|
||||
m_Text = m_GameObject.GetComponentInChildren<Text>();
|
||||
}
|
||||
|
||||
public void SetBackgroundColor(Color color)
|
||||
{
|
||||
m_GameObject.GetComponent<Image>().color = color;
|
||||
}
|
||||
|
||||
public void SetTextColor(Color color)
|
||||
{
|
||||
m_Text.color = color;
|
||||
}
|
||||
|
||||
public void UpdateTooltipText(string txt)
|
||||
{
|
||||
m_Text.text = txt;
|
||||
m_BackgroudRect.sizeDelta = new Vector2(m_Text.preferredWidth + 8, m_Text.preferredHeight + 8);
|
||||
}
|
||||
|
||||
public void SetActive(bool flag)
|
||||
{
|
||||
if(m_GameObject)
|
||||
m_GameObject.SetActive(flag);
|
||||
}
|
||||
|
||||
public void UpdatePos(Vector2 pos)
|
||||
{
|
||||
if(m_GameObject)
|
||||
m_GameObject.transform.localPosition = pos;
|
||||
}
|
||||
|
||||
public Vector3 GetPos()
|
||||
{
|
||||
return m_GameObject.transform.localPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Internal/Tooltip.cs.meta
Normal file
13
Scripts/UI/Internal/Tooltip.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 015f1aafb9c2e8940be9ef79b984b843
|
||||
timeCreated: 1554222818
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
116
Scripts/UI/LineChart.cs
Normal file
116
Scripts/UI/LineChart.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class LineChart : CoordinateChart
|
||||
{
|
||||
[SerializeField] private Line m_Line = Line.defaultLine;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
m_Line = Line.defaultLine;
|
||||
}
|
||||
|
||||
protected override void DrawChart(VertexHelper vh)
|
||||
{
|
||||
base.DrawChart(vh);
|
||||
int seriesCount = m_Series.Count;
|
||||
float max = GetMaxValue();
|
||||
float scaleWid = m_XAxis.GetDataWidth(coordinateWid);
|
||||
for (int j = 0; j < seriesCount; j++)
|
||||
{
|
||||
if (!m_Legend.IsShowSeries(j)) continue;
|
||||
Serie serie = m_Series.series[j];
|
||||
Color32 color = m_ThemeInfo.GetColor(j);
|
||||
Vector3 lp = Vector3.zero;
|
||||
Vector3 np = Vector3.zero;
|
||||
float startX = zeroX + (m_XAxis.boundaryGap ? scaleWid / 2 : 0);
|
||||
|
||||
int maxCount = maxShowDataNumber > 0 ?
|
||||
(maxShowDataNumber > serie.data.Count ? serie.data.Count : maxShowDataNumber)
|
||||
: serie.data.Count;
|
||||
for (int i = minShowDataNumber; i < maxCount; i++)
|
||||
{
|
||||
float value = serie.data[i];
|
||||
|
||||
np = new Vector3(startX + i * scaleWid, zeroY + value * coordinateHig / max);
|
||||
if (i > 0)
|
||||
{
|
||||
if (m_Line.smooth)
|
||||
{
|
||||
var list = ChartHelper.GetBezierList(lp, np, m_Line.smoothStyle);
|
||||
Vector3 start, to;
|
||||
start = list[0];
|
||||
for (int k = 1; k < list.Length; k++)
|
||||
{
|
||||
to = list[k];
|
||||
ChartHelper.DrawLine(vh, start, to, m_Line.tickness, color);
|
||||
start = to;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ChartHelper.DrawLine(vh, lp, np, m_Line.tickness, color);
|
||||
if (m_Line.area)
|
||||
{
|
||||
ChartHelper.DrawPolygon(vh, lp, np, new Vector3(np.x, zeroY),
|
||||
new Vector3(lp.x, zeroY), color);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
lp = np;
|
||||
}
|
||||
// draw point
|
||||
if (m_Line.point)
|
||||
{
|
||||
for (int i = 0; i < serie.data.Count; i++)
|
||||
{
|
||||
float value = serie.data[i];
|
||||
|
||||
Vector3 p = new Vector3(startX + i * scaleWid,
|
||||
zeroY + value * coordinateHig / max);
|
||||
float pointWid = m_Line.pointWidth;
|
||||
if (m_Tooltip.show && i == m_Tooltip.dataIndex - 1)
|
||||
{
|
||||
pointWid = pointWid * 1.8f;
|
||||
}
|
||||
if (m_Theme == Theme.Dark)
|
||||
{
|
||||
|
||||
ChartHelper.DrawCricle(vh, p, pointWid, color,
|
||||
(int)m_Line.pointWidth * 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChartHelper.DrawCricle(vh, p, pointWid, Color.white);
|
||||
ChartHelper.DrawDoughnut(vh, p, pointWid - m_Line.tickness,
|
||||
pointWid, 0, 360, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//draw tooltip line
|
||||
if (m_Tooltip.show && m_Tooltip.dataIndex > 0)
|
||||
{
|
||||
float splitWidth = m_XAxis.GetSplitWidth(coordinateWid);
|
||||
float px = zeroX + (m_Tooltip.dataIndex - 1) * splitWidth + (m_XAxis.boundaryGap ? splitWidth / 2 : 0);
|
||||
Vector2 sp = new Vector2(px, zeroY);
|
||||
Vector2 ep = new Vector2(px, zeroY + coordinateHig);
|
||||
ChartHelper.DrawLine(vh, sp, ep, m_Coordinate.tickness, m_ThemeInfo.tooltipFlagAreaColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/LineChart.cs.meta
Normal file
13
Scripts/UI/LineChart.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4f38bd00b4648c448cabfc167538f7c
|
||||
timeCreated: 1536101435
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
202
Scripts/UI/PieChart.cs
Normal file
202
Scripts/UI/PieChart.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class PieChart : BaseChart
|
||||
{
|
||||
[SerializeField] private Pie m_Pie = Pie.defaultPie;
|
||||
|
||||
private float m_PieCenterX = 0f;
|
||||
private float m_PieCenterY = 0f;
|
||||
private float m_PieRadius = 0;
|
||||
private Vector2 m_PieCenter;
|
||||
private List<float> m_AngleList = new List<float>();
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected override void DrawChart(VertexHelper vh)
|
||||
{
|
||||
base.DrawChart(vh);
|
||||
UpdatePieCenter();
|
||||
float totalDegree = 360;
|
||||
float startDegree = 0;
|
||||
float dataTotal = GetDataTotal();
|
||||
float dataMax = GetDataMax();
|
||||
m_AngleList.Clear();
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (!m_Legend.IsShowSeries(i))
|
||||
{
|
||||
m_AngleList.Add(0);
|
||||
continue;
|
||||
}
|
||||
float value = m_Series.series[i].data[0];
|
||||
float degree = totalDegree * value / dataTotal;
|
||||
float toDegree = startDegree + degree;
|
||||
|
||||
float outSideRadius = m_Pie.rose ?
|
||||
m_Pie.insideRadius + (m_PieRadius - m_Pie.insideRadius) * value / dataMax :
|
||||
m_PieRadius;
|
||||
if (m_Tooltip.show && m_Tooltip.dataIndex == i + 1)
|
||||
{
|
||||
outSideRadius += m_Pie.tooltipExtraRadius;
|
||||
}
|
||||
ChartHelper.DrawDoughnut(vh, m_PieCenter, m_Pie.insideRadius,
|
||||
outSideRadius, startDegree, toDegree, m_ThemeInfo.GetColor(i));
|
||||
m_AngleList.Add(toDegree);
|
||||
startDegree = toDegree;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLegendButtonClicked()
|
||||
{
|
||||
base.OnLegendButtonClicked();
|
||||
|
||||
}
|
||||
|
||||
private float GetDataTotal()
|
||||
{
|
||||
float total = 0;
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (m_Legend.IsShowSeries(i))
|
||||
{
|
||||
total += m_Series.series[i].GetData(0);
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private float GetDataMax()
|
||||
{
|
||||
float max = 0;
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (m_Legend.IsShowSeries(i) && m_Series.series[i].GetData(0) > max)
|
||||
{
|
||||
max = m_Series.series[i].GetData(0);
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
private void UpdatePieCenter()
|
||||
{
|
||||
float diffX = chartWidth - m_Pie.left - m_Pie.right;
|
||||
float diffY = chartHeight - m_Pie.top - m_Pie.bottom;
|
||||
float diff = Mathf.Min(diffX, diffY);
|
||||
if (m_Pie.outsideRadius <= 0)
|
||||
{
|
||||
m_PieRadius = diff / 3 * 2;
|
||||
m_PieCenterX = m_Pie.left + m_PieRadius;
|
||||
m_PieCenterY = m_Pie.bottom + m_PieRadius;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PieRadius = m_Pie.outsideRadius;
|
||||
m_PieCenterX = chartWidth / 2;
|
||||
m_PieCenterY = chartHeight / 2;
|
||||
if (m_Pie.left > 0) m_PieCenterX = m_Pie.left + m_PieRadius;
|
||||
if (m_Pie.right > 0) m_PieCenterX = chartWidth - m_Pie.right - m_PieRadius;
|
||||
if (m_Pie.top > 0) m_PieCenterY = chartHeight - m_Pie.top - m_PieRadius;
|
||||
if (m_Pie.bottom > 0) m_PieCenterY = m_Pie.bottom + m_PieRadius;
|
||||
}
|
||||
m_PieCenter = new Vector2(m_PieCenterX, m_PieCenterY);
|
||||
}
|
||||
|
||||
protected override void CheckTootipArea(Vector2 local)
|
||||
{
|
||||
|
||||
float dist = Vector2.Distance(local, m_PieCenter);
|
||||
if (dist > m_PieRadius)
|
||||
{
|
||||
m_Tooltip.dataIndex = 0;
|
||||
m_Tooltip.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 dir = local - m_PieCenter;
|
||||
float angle = VectorAngle(Vector2.up, dir);
|
||||
m_Tooltip.dataIndex = 0;
|
||||
for (int i = m_AngleList.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (i == 0 && angle < m_AngleList[i])
|
||||
{
|
||||
m_Tooltip.dataIndex = 1;
|
||||
break;
|
||||
}
|
||||
else if (angle < m_AngleList[i] && angle > m_AngleList[i - 1])
|
||||
{
|
||||
m_Tooltip.dataIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_Tooltip.dataIndex > 0)
|
||||
{
|
||||
m_Tooltip.UpdatePos(new Vector2(local.x + 18, local.y - 25));
|
||||
RefreshTooltip();
|
||||
if (m_Tooltip.lastDataIndex != m_Tooltip.dataIndex)
|
||||
{
|
||||
RefreshChart();
|
||||
}
|
||||
m_Tooltip.lastDataIndex = m_Tooltip.dataIndex;
|
||||
}
|
||||
}
|
||||
|
||||
float VectorAngle(Vector2 from, Vector2 to)
|
||||
{
|
||||
float angle;
|
||||
|
||||
Vector3 cross = Vector3.Cross(from, to);
|
||||
angle = Vector2.Angle(from, to);
|
||||
angle = cross.z > 0 ? -angle : angle;
|
||||
angle = (angle + 360) % 360;
|
||||
return angle;
|
||||
}
|
||||
|
||||
protected override void RefreshTooltip()
|
||||
{
|
||||
base.RefreshTooltip();
|
||||
int index = m_Tooltip.dataIndex - 1;
|
||||
if (index < 0)
|
||||
{
|
||||
m_Tooltip.SetActive(false);
|
||||
return;
|
||||
}
|
||||
m_Tooltip.SetActive(true);
|
||||
string strColor = ColorUtility.ToHtmlStringRGBA(m_ThemeInfo.GetColor(index));
|
||||
string key = m_Legend.data[index];
|
||||
float value = m_Series.series[index].data[0];
|
||||
string txt = "";
|
||||
if (!string.IsNullOrEmpty(m_Pie.name))
|
||||
{
|
||||
txt += m_Pie.name + "\n";
|
||||
}
|
||||
txt += string.Format("<color=#{0}>● </color>{1}: {2}", strColor, key, value);
|
||||
m_Tooltip.UpdateTooltipText(txt);
|
||||
|
||||
var pos = m_Tooltip.GetPos();
|
||||
if (pos.x + m_Tooltip.width > chartWidth)
|
||||
{
|
||||
pos.x = chartWidth - m_Tooltip.width;
|
||||
}
|
||||
if (pos.y - m_Tooltip.height < 0)
|
||||
{
|
||||
pos.y = m_Tooltip.height;
|
||||
}
|
||||
m_Tooltip.UpdatePos(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/PieChart.cs.meta
Normal file
13
Scripts/UI/PieChart.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d44276ba809fd92408b296835f6f7658
|
||||
timeCreated: 1537541828
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
347
Scripts/UI/RadarChart.cs
Normal file
347
Scripts/UI/RadarChart.cs
Normal file
@@ -0,0 +1,347 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class RadarChart : BaseChart
|
||||
{
|
||||
private const string INDICATOR_TEXT = "indicator";
|
||||
|
||||
[SerializeField]
|
||||
private Radar m_Radar = Radar.defaultRadar;
|
||||
private Radar m_CheckRadar = Radar.defaultRadar;
|
||||
private float m_RadarCenterX = 0f;
|
||||
private float m_RadarCenterY = 0f;
|
||||
private float m_RadarRadius = 0;
|
||||
private List<Text> indicatorTextList = new List<Text>();
|
||||
private List<List<Vector3>> dataPosList = new List<List<Vector3>>();
|
||||
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
UpdateRadarCenter();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
CheckRadarInfoChanged();
|
||||
}
|
||||
|
||||
private void InitIndicator()
|
||||
{
|
||||
indicatorTextList.Clear();
|
||||
ChartHelper.HideAllObject(transform, INDICATOR_TEXT);
|
||||
int indicatorNum = m_Radar.indicatorList.Count;
|
||||
float txtWid = 100;
|
||||
float txtHig = 20;
|
||||
for (int i = 0; i < indicatorNum; i++)
|
||||
{
|
||||
var pos = GetIndicatorPosition(i);
|
||||
TextAnchor anchor = TextAnchor.MiddleCenter;
|
||||
var diff = pos.x - m_RadarCenterX;
|
||||
if (diff < -1f)
|
||||
{
|
||||
pos = new Vector3(pos.x - 5, pos.y);
|
||||
anchor = TextAnchor.MiddleRight;
|
||||
}
|
||||
else if (diff > 1f)
|
||||
{
|
||||
anchor = TextAnchor.MiddleLeft;
|
||||
pos = new Vector3(pos.x + txtWid + 5, pos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
anchor = TextAnchor.MiddleCenter;
|
||||
float y = pos.y > m_RadarCenterY ? pos.y + txtHig / 2 : pos.y - txtHig / 2;
|
||||
pos = new Vector3(pos.x + txtWid / 2, y);
|
||||
}
|
||||
Text txt = ChartHelper.AddTextObject(INDICATOR_TEXT + i, transform, m_ThemeInfo.font,
|
||||
m_ThemeInfo.textColor, anchor, Vector2.zero, Vector2.zero, new Vector2(1, 0.5f),
|
||||
new Vector2(txtWid, txtHig));
|
||||
txt.transform.localPosition = pos;
|
||||
txt.text = m_Radar.indicatorList[i].name;
|
||||
txt.gameObject.SetActive(m_Radar.indicator);
|
||||
indicatorTextList.Add(txt);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckRadarInfoChanged()
|
||||
{
|
||||
if (!m_CheckRadar.Equals(m_Radar))
|
||||
{
|
||||
m_CheckRadar.Copy(m_Radar);
|
||||
OnRadarChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRadarChanged()
|
||||
{
|
||||
UpdateRadarCenter();
|
||||
InitIndicator();
|
||||
}
|
||||
|
||||
private Vector3 GetIndicatorPosition(int i)
|
||||
{
|
||||
int indicatorNum = m_Radar.indicatorList.Count;
|
||||
var angle = 2 * Mathf.PI / indicatorNum * i;
|
||||
var x = m_RadarCenterX + m_Radar.radius * Mathf.Sin(angle);
|
||||
var y = m_RadarCenterY + m_Radar.radius * Mathf.Cos(angle);
|
||||
|
||||
return new Vector3(x, y);
|
||||
}
|
||||
|
||||
protected override void DrawChart(VertexHelper vh)
|
||||
{
|
||||
base.DrawChart(vh);
|
||||
UpdateRadarCenter();
|
||||
if (m_Radar.cricle)
|
||||
DrawCricleRadar(vh);
|
||||
else
|
||||
DrawRadar(vh);
|
||||
DrawData(vh);
|
||||
}
|
||||
|
||||
protected override void OnLegendButtonClicked()
|
||||
{
|
||||
base.OnLegendButtonClicked();
|
||||
}
|
||||
|
||||
protected override void OnThemeChanged()
|
||||
{
|
||||
base.OnThemeChanged();
|
||||
m_Radar.backgroundColorList.Clear();
|
||||
switch (m_Theme)
|
||||
{
|
||||
case Theme.Dark:
|
||||
m_Radar.backgroundColorList.Add(ThemeInfo.GetColor("#6f6f6f"));
|
||||
m_Radar.backgroundColorList.Add(ThemeInfo.GetColor("#606060"));
|
||||
break;
|
||||
case Theme.Default:
|
||||
m_Radar.backgroundColorList.Add(ThemeInfo.GetColor("#f6f6f6"));
|
||||
m_Radar.backgroundColorList.Add(ThemeInfo.GetColor("#e7e7e7"));
|
||||
break;
|
||||
case Theme.Light:
|
||||
m_Radar.backgroundColorList.Add(ThemeInfo.GetColor("#f6f6f6"));
|
||||
m_Radar.backgroundColorList.Add(ThemeInfo.GetColor("#e7e7e7"));
|
||||
break;
|
||||
}
|
||||
InitIndicator();
|
||||
}
|
||||
|
||||
private void DrawData(VertexHelper vh)
|
||||
{
|
||||
int indicatorNum = m_Radar.indicatorList.Count;
|
||||
var angle = 2 * Mathf.PI / indicatorNum;
|
||||
var p = new Vector3(m_RadarCenterX, m_RadarCenterY);
|
||||
Vector3 startPoint = Vector3.zero;
|
||||
Vector3 toPoint = Vector3.zero;
|
||||
Vector3 firstPoint = Vector3.zero;
|
||||
dataPosList.Clear();
|
||||
dataPosList.Capacity = m_Series.Count;
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (!m_Legend.IsShowSeries(i))
|
||||
{
|
||||
dataPosList.Add(new List<Vector3>());
|
||||
continue;
|
||||
}
|
||||
var dataList = m_Series.series[i].data;
|
||||
var color = m_ThemeInfo.GetColor(i);
|
||||
var areaColor = new Color(color.r, color.g, color.b, color.a * 0.7f);
|
||||
|
||||
List<Vector3> pointList = new List<Vector3>(dataList.Count);
|
||||
dataPosList.Add(pointList);
|
||||
for (int j = 0; j < dataList.Count; j++)
|
||||
{
|
||||
var max = m_Radar.indicatorList[j].max > 0 ?
|
||||
m_Radar.indicatorList[j].max :
|
||||
GetMaxValue(j);
|
||||
var radius = max<0? m_Radar.radius - m_Radar.radius * dataList[j] / max : m_Radar.radius * dataList[j] / max ;
|
||||
var currAngle = j * angle;
|
||||
if (j == 0)
|
||||
{
|
||||
startPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle),
|
||||
p.y + radius * Mathf.Cos(currAngle));
|
||||
firstPoint = startPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
toPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle),
|
||||
p.y + radius * Mathf.Cos(currAngle));
|
||||
if (m_Radar.area)
|
||||
{
|
||||
ChartHelper.DrawTriangle(vh, p, startPoint, toPoint, areaColor);
|
||||
}
|
||||
ChartHelper.DrawLine(vh, startPoint, toPoint, m_Radar.lineTickness, color);
|
||||
startPoint = toPoint;
|
||||
}
|
||||
pointList.Add(startPoint);
|
||||
}
|
||||
if (m_Radar.area) ChartHelper.DrawTriangle(vh, p, startPoint, firstPoint, areaColor);
|
||||
ChartHelper.DrawLine(vh, startPoint, firstPoint, m_Radar.lineTickness, color);
|
||||
foreach (var point in pointList)
|
||||
{
|
||||
float radius = m_Radar.linePointSize - m_Radar.lineTickness * 2;
|
||||
|
||||
ChartHelper.DrawCricle(vh, point, radius, Color.white);
|
||||
ChartHelper.DrawDoughnut(vh, point, radius, m_Radar.linePointSize, 0, 360, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawRadar(VertexHelper vh)
|
||||
{
|
||||
float insideRadius = 0, outsideRadius = 0;
|
||||
float block = m_Radar.radius / m_Radar.splitNumber;
|
||||
int indicatorNum = m_Radar.indicatorList.Count;
|
||||
Vector3 p1, p2, p3, p4;
|
||||
Vector3 p = new Vector3(m_RadarCenterX, m_RadarCenterY);
|
||||
float angle = 2 * Mathf.PI / indicatorNum;
|
||||
for (int i = 0; i < m_Radar.splitNumber; i++)
|
||||
{
|
||||
Color color = m_Radar.backgroundColorList[i % m_Radar.backgroundColorList.Count];
|
||||
outsideRadius = insideRadius + block;
|
||||
p1 = new Vector3(p.x + insideRadius * Mathf.Sin(0), p.y + insideRadius * Mathf.Cos(0));
|
||||
p2 = new Vector3(p.x + outsideRadius * Mathf.Sin(0), p.y + outsideRadius * Mathf.Cos(0));
|
||||
for (int j = 0; j <= indicatorNum; j++)
|
||||
{
|
||||
float currAngle = j * angle;
|
||||
p3 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle),
|
||||
p.y + outsideRadius * Mathf.Cos(currAngle));
|
||||
p4 = new Vector3(p.x + insideRadius * Mathf.Sin(currAngle),
|
||||
p.y + insideRadius * Mathf.Cos(currAngle));
|
||||
|
||||
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, color);
|
||||
ChartHelper.DrawLine(vh, p2, p3, m_Radar.lineTickness, m_Radar.lineColor);
|
||||
p1 = p4;
|
||||
p2 = p3;
|
||||
}
|
||||
insideRadius = outsideRadius;
|
||||
}
|
||||
for (int j = 0; j <= indicatorNum; j++)
|
||||
{
|
||||
float currAngle = j * angle;
|
||||
p3 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle),
|
||||
p.y + outsideRadius * Mathf.Cos(currAngle));
|
||||
ChartHelper.DrawLine(vh, p, p3, m_Radar.lineTickness / 2, m_Radar.lineColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCricleRadar(VertexHelper vh)
|
||||
{
|
||||
float insideRadius = 0, outsideRadius = 0;
|
||||
float block = m_Radar.radius / m_Radar.splitNumber;
|
||||
int indicatorNum = m_Radar.indicatorList.Count;
|
||||
Vector3 p = new Vector3(m_RadarCenterX, m_RadarCenterY);
|
||||
Vector3 p1;
|
||||
float angle = 2 * Mathf.PI / indicatorNum;
|
||||
for (int i = 0; i < m_Radar.splitNumber; i++)
|
||||
{
|
||||
Color color = m_Radar.backgroundColorList[i % m_Radar.backgroundColorList.Count];
|
||||
outsideRadius = insideRadius + block;
|
||||
ChartHelper.DrawDoughnut(vh, p, insideRadius, outsideRadius, 0, 360, color);
|
||||
ChartHelper.DrawCicleNotFill(vh, p, outsideRadius, m_Radar.lineTickness,
|
||||
m_Radar.lineColor);
|
||||
insideRadius = outsideRadius;
|
||||
}
|
||||
for (int j = 0; j <= indicatorNum; j++)
|
||||
{
|
||||
float currAngle = j * angle;
|
||||
p1 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle),
|
||||
p.y + outsideRadius * Mathf.Cos(currAngle));
|
||||
ChartHelper.DrawLine(vh, p, p1, m_Radar.lineTickness / 2, m_Radar.lineColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRadarCenter()
|
||||
{
|
||||
float diffX = chartWidth - m_Radar.left - m_Radar.right;
|
||||
float diffY = chartHeight - m_Radar.top - m_Radar.bottom;
|
||||
float diff = Mathf.Min(diffX, diffY);
|
||||
if (m_Radar.radius <= 0)
|
||||
{
|
||||
m_RadarRadius = diff / 3 * 2;
|
||||
m_RadarCenterX = m_Radar.left + m_RadarRadius;
|
||||
m_RadarCenterY = m_Radar.bottom + m_RadarRadius;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RadarRadius = m_Radar.radius;
|
||||
m_RadarCenterX = chartWidth / 2;
|
||||
m_RadarCenterY = chartHeight / 2;
|
||||
if (m_Radar.left > 0) m_RadarCenterX = m_Radar.left + m_RadarRadius;
|
||||
if (m_Radar.right > 0) m_RadarCenterX = chartWidth - m_Radar.right - m_RadarRadius;
|
||||
if (m_Radar.top > 0) m_RadarCenterY = chartHeight - m_Radar.top - m_RadarRadius;
|
||||
if (m_Radar.bottom > 0) m_RadarCenterY = m_Radar.bottom + m_RadarRadius;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CheckTootipArea(Vector2 local)
|
||||
{
|
||||
if (dataPosList.Count <= 0) return;
|
||||
m_Tooltip.dataIndex = 0;
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
if (!m_Legend.IsShowSeries(i)) continue;
|
||||
for (int j = 0; j < dataPosList[i].Count; j++)
|
||||
{
|
||||
if (Vector3.Distance(local, dataPosList[i][j]) <= m_Radar.linePointSize * 1.2f)
|
||||
{
|
||||
m_Tooltip.dataIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_Tooltip.dataIndex > 0)
|
||||
{
|
||||
m_Tooltip.UpdatePos(new Vector2(local.x + 18, local.y - 25));
|
||||
RefreshTooltip();
|
||||
if (m_Tooltip.lastDataIndex != m_Tooltip.dataIndex)
|
||||
{
|
||||
RefreshChart();
|
||||
}
|
||||
m_Tooltip.lastDataIndex = m_Tooltip.dataIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Tooltip.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RefreshTooltip()
|
||||
{
|
||||
base.RefreshTooltip();
|
||||
int index = m_Tooltip.dataIndex - 1;
|
||||
if (index < 0)
|
||||
{
|
||||
m_Tooltip.SetActive(false);
|
||||
return;
|
||||
}
|
||||
m_Tooltip.SetActive(true);
|
||||
StringBuilder sb = new StringBuilder(m_Legend.data[index]);
|
||||
for (int i = 0; i < m_Radar.indicatorList.Count; i++)
|
||||
{
|
||||
string key = m_Radar.indicatorList[i].name;
|
||||
float value = m_Series.series[index].data[i];
|
||||
sb.Append("\n");
|
||||
sb.AppendFormat("{0}: {1}", key, value);
|
||||
}
|
||||
m_Tooltip.UpdateTooltipText(sb.ToString());
|
||||
|
||||
var pos = m_Tooltip.GetPos();
|
||||
if (pos.x + m_Tooltip.width > chartWidth)
|
||||
{
|
||||
pos.x = chartWidth - m_Tooltip.width;
|
||||
}
|
||||
if (pos.y - m_Tooltip.height < 0)
|
||||
{
|
||||
pos.y = m_Tooltip.height;
|
||||
}
|
||||
m_Tooltip.UpdatePos(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/RadarChart.cs.meta
Normal file
13
Scripts/UI/RadarChart.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2231a0d3e3a5b043b074f6739be4a86
|
||||
timeCreated: 1537742341
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Scripts/UI/Utility.meta
Normal file
10
Scripts/UI/Utility.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3f97e494bd29fb43a2e17e14bd12b28
|
||||
folderAsset: yes
|
||||
timeCreated: 1554221615
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
440
Scripts/UI/Utility/ChartHelper.cs
Normal file
440
Scripts/UI/Utility/ChartHelper.cs
Normal file
@@ -0,0 +1,440 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public static class ChartHelper
|
||||
{
|
||||
private static float CRICLE_SMOOTHNESS = 1f;
|
||||
private static UIVertex[] vertex = new UIVertex[4];
|
||||
|
||||
public static void HideAllObject(GameObject obj, string match)
|
||||
{
|
||||
HideAllObject(obj.transform, match);
|
||||
}
|
||||
|
||||
public static void HideAllObject(Transform parent, string match)
|
||||
{
|
||||
for (int i = 0; i < parent.childCount; i++)
|
||||
{
|
||||
if (match == null)
|
||||
parent.GetChild(i).gameObject.SetActive(false);
|
||||
else
|
||||
{
|
||||
var go = parent.GetChild(i);
|
||||
if (go.name.StartsWith(match))
|
||||
{
|
||||
go.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void DestoryAllChilds(Transform parent)
|
||||
{
|
||||
while (parent.childCount > 0)
|
||||
{
|
||||
var go = parent.GetChild(0);
|
||||
if (go.childCount > 0) DestoryAllChilds(go);
|
||||
else GameObject.DestroyImmediate(go.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public static T GetOrAddComponent<T>(Transform transform) where T : Component
|
||||
{
|
||||
return GetOrAddComponent<T>(transform.gameObject);
|
||||
}
|
||||
|
||||
public static T GetOrAddComponent<T>(GameObject gameObject) where T : Component
|
||||
{
|
||||
if (gameObject.GetComponent<T>() == null)
|
||||
{
|
||||
gameObject.AddComponent<T>();
|
||||
}
|
||||
return gameObject.GetComponent<T>();
|
||||
}
|
||||
|
||||
public static GameObject AddObject(string name, Transform parent, Vector2 anchorMin,
|
||||
Vector2 anchorMax, Vector2 pivot, Vector2 sizeDelta)
|
||||
{
|
||||
GameObject obj;
|
||||
if (parent.Find(name))
|
||||
{
|
||||
obj = parent.Find(name).gameObject;
|
||||
obj.SetActive(true);
|
||||
obj.transform.localPosition = Vector3.zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = new GameObject();
|
||||
obj.name = name;
|
||||
obj.transform.parent = parent;
|
||||
obj.transform.localScale = Vector3.one;
|
||||
obj.transform.localPosition = Vector3.zero;
|
||||
}
|
||||
RectTransform rect = GetOrAddComponent<RectTransform>(obj);
|
||||
rect.localPosition = Vector3.zero;
|
||||
rect.sizeDelta = sizeDelta;
|
||||
rect.anchorMin = anchorMin;
|
||||
rect.anchorMax = anchorMax;
|
||||
rect.pivot = pivot;
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static Text AddTextObject(string name, Transform parent, Font font, Color color,
|
||||
TextAnchor anchor, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 sizeDelta,
|
||||
int fontSize = 14,float textRotation = 0)
|
||||
{
|
||||
GameObject txtObj = AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta);
|
||||
Text txt = GetOrAddComponent<Text>(txtObj);
|
||||
txt.font = font;
|
||||
txt.fontSize = fontSize;
|
||||
txt.text = "Text";
|
||||
txt.alignment = anchor;
|
||||
txt.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||
txt.verticalOverflow = VerticalWrapMode.Overflow;
|
||||
txt.color = color;
|
||||
if (textRotation > 0)
|
||||
{
|
||||
txtObj.transform.localEulerAngles = new Vector3(0,0,textRotation);
|
||||
}
|
||||
|
||||
RectTransform rect = GetOrAddComponent<RectTransform>(txtObj);
|
||||
rect.localPosition = Vector3.zero;
|
||||
rect.sizeDelta = sizeDelta;
|
||||
rect.anchorMin = anchorMin;
|
||||
rect.anchorMax = anchorMax;
|
||||
rect.pivot = pivot;
|
||||
return txtObj.GetComponent<Text>();
|
||||
}
|
||||
|
||||
public static Button AddButtonObject(string name, Transform parent, Font font, int fontSize,
|
||||
Color color, TextAnchor anchor, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot,
|
||||
Vector2 sizeDelta)
|
||||
{
|
||||
GameObject btnObj = AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta);
|
||||
GetOrAddComponent<Image>(btnObj);
|
||||
GetOrAddComponent<Button>(btnObj);
|
||||
Text txt = AddTextObject("Text", btnObj.transform, font, color, TextAnchor.MiddleCenter,
|
||||
new Vector2(0, 0), new Vector2(1, 1), new Vector2(0.5f, 0.5f),
|
||||
sizeDelta, fontSize);
|
||||
txt.rectTransform.offsetMin = Vector2.zero;
|
||||
txt.rectTransform.offsetMax = Vector2.zero;
|
||||
return btnObj.GetComponent<Button>();
|
||||
}
|
||||
|
||||
public static GameObject AddTooltipObject(string name, Transform parent, Font font)
|
||||
{
|
||||
var anchorMax = new Vector2(0, 1);
|
||||
var anchorMin = new Vector2(0, 1);
|
||||
var pivot = new Vector2(0, 1);
|
||||
var sizeDelta = new Vector2(100, 100);
|
||||
GameObject tooltipObj = AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta);
|
||||
var img = GetOrAddComponent<Image>(tooltipObj);
|
||||
img.color = Color.black;
|
||||
Text txt = AddTextObject("Text", tooltipObj.transform, font, Color.white, TextAnchor.UpperLeft,
|
||||
anchorMin, anchorMax, pivot, sizeDelta);
|
||||
txt.text = "Text";
|
||||
txt.transform.localPosition = new Vector2(3, -3);
|
||||
return tooltipObj;
|
||||
}
|
||||
|
||||
public static void DrawLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, Color32 color)
|
||||
{
|
||||
Vector3 v = Vector3.Cross(p2 - p1, Vector3.forward).normalized * size;
|
||||
vertex[0].position = p1 + v;
|
||||
vertex[1].position = p2 + v;
|
||||
vertex[2].position = p2 - v;
|
||||
vertex[3].position = p1 - v;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
vertex[j].color = color;
|
||||
vertex[j].uv0 = Vector2.zero;
|
||||
}
|
||||
vh.AddUIVertexQuad(vertex);
|
||||
}
|
||||
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p, float size, Color32 color)
|
||||
{
|
||||
Vector3 p1 = new Vector3(p.x - size, p.y - size);
|
||||
Vector3 p2 = new Vector3(p.x + size, p.y - size);
|
||||
Vector3 p3 = new Vector3(p.x + size, p.y + size);
|
||||
Vector3 p4 = new Vector3(p.x - size, p.y + size);
|
||||
DrawPolygon(vh, p1, p2, p3, p4, color, color);
|
||||
}
|
||||
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
|
||||
Color32 color)
|
||||
{
|
||||
DrawPolygon(vh, p1, p2, p3, p4, color, color);
|
||||
}
|
||||
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
|
||||
Color32 startColor, Color32 toColor)
|
||||
{
|
||||
vertex[0].position = p1;
|
||||
vertex[1].position = p2;
|
||||
vertex[2].position = p3;
|
||||
vertex[3].position = p4;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
vertex[j].color = j >= 2 ? toColor : startColor;
|
||||
vertex[j].uv0 = Vector2.zero;
|
||||
}
|
||||
vh.AddUIVertexQuad(vertex);
|
||||
}
|
||||
|
||||
public static void DrawTriangle(VertexHelper vh, Vector3 p1,
|
||||
Vector3 p2, Vector3 p3, Color32 color)
|
||||
{
|
||||
UIVertex v1 = new UIVertex();
|
||||
v1.position = p1;
|
||||
v1.color = color;
|
||||
v1.uv0 = Vector3.zero;
|
||||
UIVertex v2 = new UIVertex();
|
||||
v2.position = p2;
|
||||
v2.color = color;
|
||||
v2.uv0 = Vector3.zero;
|
||||
UIVertex v3 = new UIVertex();
|
||||
v3.position = p3;
|
||||
v3.color = color;
|
||||
v3.uv0 = Vector3.zero;
|
||||
int startIndex = vh.currentVertCount;
|
||||
vh.AddVert(v1);
|
||||
vh.AddVert(v2);
|
||||
vh.AddVert(v3);
|
||||
vh.AddTriangle(startIndex, startIndex + 1, startIndex + 2);
|
||||
}
|
||||
|
||||
public static void DrawCricle(VertexHelper vh, Vector3 p, float radius, Color32 color,
|
||||
int segments = 0, bool fill = true)
|
||||
{
|
||||
if (segments <= 0)
|
||||
{
|
||||
segments = (int)((2 * Mathf.PI * radius) / CRICLE_SMOOTHNESS);
|
||||
}
|
||||
DrawSector(vh, p, radius, color, 0, 360, segments);
|
||||
}
|
||||
|
||||
public static void DrawCicleNotFill(VertexHelper vh, Vector3 p, float radius, float tickness,
|
||||
Color32 color, int segments = 0)
|
||||
{
|
||||
if (segments <= 0)
|
||||
{
|
||||
segments = (int)((2 * Mathf.PI * radius) / CRICLE_SMOOTHNESS);
|
||||
}
|
||||
float startDegree = 0, toDegree = 360;
|
||||
Vector3 p2, p3;
|
||||
float startAngle = startDegree * Mathf.Deg2Rad;
|
||||
float angle = (toDegree - startDegree) * Mathf.Deg2Rad / segments;
|
||||
p2 = new Vector3(p.x + radius * Mathf.Sin(startAngle), p.y + radius * Mathf.Cos(startAngle));
|
||||
for (int i = 0; i <= segments; i++)
|
||||
{
|
||||
float currAngle = startAngle + i * angle;
|
||||
p3 = new Vector3(p.x + radius * Mathf.Sin(currAngle), p.y + radius * Mathf.Cos(currAngle));
|
||||
DrawLine(vh, p2, p3, tickness, color);
|
||||
p2 = p3;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawSector(VertexHelper vh, Vector3 p, float radius, Color32 color,
|
||||
float startDegree, float toDegree, int segments = 0)
|
||||
{
|
||||
if (segments <= 0)
|
||||
{
|
||||
segments = (int)((2 * Mathf.PI * radius) / CRICLE_SMOOTHNESS);
|
||||
}
|
||||
Vector3 p2, p3;
|
||||
float startAngle = startDegree * Mathf.Deg2Rad;
|
||||
float angle = (toDegree - startDegree) * Mathf.Deg2Rad / segments;
|
||||
p2 = new Vector3(p.x + radius * Mathf.Sin(startAngle), p.y + radius * Mathf.Cos(startAngle));
|
||||
for (int i = 0; i <= segments; i++)
|
||||
{
|
||||
float currAngle = startAngle + i * angle;
|
||||
p3 = new Vector3(p.x + radius * Mathf.Sin(currAngle),
|
||||
p.y + radius * Mathf.Cos(currAngle));
|
||||
DrawTriangle(vh, p, p2, p3, color);
|
||||
p2 = p3;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawDoughnut(VertexHelper vh, Vector3 p, float insideRadius, float outsideRadius,
|
||||
float startDegree, float toDegree, Color32 color, int segments = 0)
|
||||
{
|
||||
if (insideRadius <= 0)
|
||||
{
|
||||
DrawSector(vh, p, outsideRadius, color, startDegree, toDegree, segments);
|
||||
return;
|
||||
}
|
||||
if (segments <= 0)
|
||||
{
|
||||
segments = (int)((2 * Mathf.PI * outsideRadius) / CRICLE_SMOOTHNESS);
|
||||
}
|
||||
Vector3 p1, p2, p3, p4;
|
||||
float startAngle = startDegree * Mathf.Deg2Rad;
|
||||
float angle = (toDegree - startDegree) * Mathf.Deg2Rad / segments;
|
||||
p1 = new Vector3(p.x + insideRadius * Mathf.Sin(startAngle),
|
||||
p.y + insideRadius * Mathf.Cos(startAngle));
|
||||
p2 = new Vector3(p.x + outsideRadius * Mathf.Sin(startAngle),
|
||||
p.y + outsideRadius * Mathf.Cos(startAngle));
|
||||
for (int i = 0; i <= segments; i++)
|
||||
{
|
||||
float currAngle = startAngle + i * angle;
|
||||
p3 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle),
|
||||
p.y + outsideRadius * Mathf.Cos(currAngle));
|
||||
p4 = new Vector3(p.x + insideRadius * Mathf.Sin(currAngle),
|
||||
p.y + insideRadius * Mathf.Cos(currAngle));
|
||||
DrawPolygon(vh, p1, p2, p3, p4, color);
|
||||
p1 = p4;
|
||||
p2 = p3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Vector3[] GetBezierList(Vector3 sp, Vector3 ep, float k = 2.0f)
|
||||
{
|
||||
Vector3 dir = (ep - sp).normalized;
|
||||
float dist = Vector3.Distance(sp, ep);
|
||||
Vector3 cp1 = sp + dist / k * dir * 1;
|
||||
Vector3 cp2 = sp + dist / k * dir * (k - 1);
|
||||
cp1.y = sp.y;
|
||||
cp2.y = ep.y;
|
||||
int segment = (int)(dist / 0.3f);
|
||||
return GetBezierList2(sp, ep, segment, cp1, cp2);
|
||||
}
|
||||
|
||||
public static List<Vector3> GetBezierList(Vector3 sp, Vector3 ep, int segment, Vector3 cp)
|
||||
{
|
||||
List<Vector3> list = new List<Vector3>();
|
||||
for (int i = 0; i < segment; i++)
|
||||
{
|
||||
list.Add(GetBezier(i / (float)segment, sp, cp, ep));
|
||||
}
|
||||
list.Add(ep);
|
||||
return list;
|
||||
}
|
||||
|
||||
public static Vector3[] GetBezierList2(Vector3 sp, Vector3 ep, int segment, Vector3 cp,
|
||||
Vector3 cp2)
|
||||
{
|
||||
Vector3[] list = new Vector3[segment + 1];
|
||||
for (int i = 0; i < segment; i++)
|
||||
{
|
||||
list[i] = (GetBezier2(i / (float)segment, sp, cp, cp2, ep));
|
||||
}
|
||||
list[segment] = ep;
|
||||
return list;
|
||||
}
|
||||
|
||||
public static Vector3 GetBezier(float t, Vector3 sp, Vector3 cp, Vector3 ep)
|
||||
{
|
||||
Vector3 aa = sp + (cp - sp) * t;
|
||||
Vector3 bb = cp + (ep - cp) * t;
|
||||
return aa + (bb - aa) * t;
|
||||
}
|
||||
|
||||
public static Vector3 GetBezier2(float t, Vector3 sp, Vector3 p1, Vector3 p2, Vector3 ep)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
var oneMinusT = 1f - t;
|
||||
return oneMinusT * oneMinusT * oneMinusT * sp +
|
||||
3f * oneMinusT * oneMinusT * t * p1 +
|
||||
3f * oneMinusT * t * t * p2 +
|
||||
t * t * t * ep;
|
||||
}
|
||||
|
||||
public static List<Vector3> GetBezierN(List<Vector3> arrayToCurve, float smoothness = 1.0f)
|
||||
{
|
||||
List<Vector3> points;
|
||||
List<Vector3> curvedPoints;
|
||||
int pointsLength = 0;
|
||||
int curvedLength = 0;
|
||||
|
||||
if (smoothness < 1.0f) smoothness = 1.0f;
|
||||
|
||||
pointsLength = arrayToCurve.Count;
|
||||
|
||||
curvedLength = (pointsLength * Mathf.RoundToInt(smoothness)) - 1;
|
||||
curvedPoints = new List<Vector3>(curvedLength);
|
||||
|
||||
float t = 0.0f;
|
||||
for (int pointInTimeOnCurve = 0; pointInTimeOnCurve < curvedLength + 1; pointInTimeOnCurve++)
|
||||
{
|
||||
t = Mathf.InverseLerp(0, curvedLength, pointInTimeOnCurve);
|
||||
|
||||
points = new List<Vector3>(arrayToCurve);
|
||||
|
||||
for (int j = pointsLength - 1; j > 0; j--)
|
||||
{
|
||||
for (int i = 0; i < j; i++)
|
||||
{
|
||||
points[i] = (1 - t) * points[i] + t * points[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
curvedPoints.Add(points[0]);
|
||||
}
|
||||
|
||||
return curvedPoints;
|
||||
}
|
||||
|
||||
public static bool IsValueEqualsColor(Color32 color1, Color32 color2)
|
||||
{
|
||||
return color1.a == color2.a &&
|
||||
color1.b == color2.b &&
|
||||
color1.g == color2.g &&
|
||||
color1.r == color2.r;
|
||||
}
|
||||
|
||||
public static bool IsValueEqualsList<T>(List<T> list1, List<T> list2)
|
||||
{
|
||||
if (list1 == null || list2 == null) return false;
|
||||
if (list1.Count != list2.Count) return false;
|
||||
for (int i = 0; i < list1.Count; i++)
|
||||
{
|
||||
if (!list1[i].Equals(list2[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static List<float> ParseFloatFromString(string jsonData)
|
||||
{
|
||||
List<float> list = new List<float>();
|
||||
if (string.IsNullOrEmpty(jsonData)) return list;
|
||||
int startIndex = jsonData.IndexOf("[");
|
||||
int endIndex = jsonData.IndexOf("]");
|
||||
string temp = jsonData.Substring(startIndex + 1, endIndex - startIndex - 1);
|
||||
string[] datas = temp.Split(',');
|
||||
for (int i = 0; i < datas.Length; i++)
|
||||
{
|
||||
list.Add(float.Parse(datas[i].Trim()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<string> ParseStringFromString(string jsonData)
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
if (string.IsNullOrEmpty(jsonData)) return list;
|
||||
string pattern = "[\"'](.*?)[\"']";
|
||||
if (Regex.IsMatch(jsonData, pattern))
|
||||
{
|
||||
MatchCollection m = Regex.Matches(jsonData, pattern);
|
||||
foreach(Match match in m)
|
||||
{
|
||||
list.Add(match.Groups[1].Value);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static Color32 GetColor(string hexColorStr)
|
||||
{
|
||||
Color color;
|
||||
ColorUtility.TryParseHtmlString(hexColorStr, out color);
|
||||
return (Color32)color;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/UI/Utility/ChartHelper.cs.meta
Normal file
13
Scripts/UI/Utility/ChartHelper.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 049a2733eed58154eb8336d4e17312ad
|
||||
timeCreated: 1536792022
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user