Compare commits

..

27 Commits

Author SHA1 Message Date
monitor1394
501d6458f3 发布v0.8.0版本 2019-08-04 18:32:28 +08:00
monitor1394
587cfab8d3 优化RadarChart雷达图,增加多雷达图支持 2019-08-04 15:24:31 +08:00
monitor1394
916b68441b 增加代码API注释文档,整理代码 2019-08-01 23:49:30 +08:00
monitor1394
08230727df 增加Radius、Area两种南丁格尔玫瑰图展示类型 2019-07-29 08:01:39 +08:00
monitor1394
a756f70e74 增加SerieLabel配置饼图标签,支持Center,inside,Outside等显示位置 2019-07-29 00:25:10 +08:00
monitor1394
7e5d805037 增加PieChart多饼图支持 2019-07-28 00:44:53 +08:00
monitor1394
f51c498503 优化代码 2019-07-25 21:10:57 +08:00
monitor1394
51e3707072 优化Editor 2019-07-25 19:11:47 +08:00
monitor1394
763c0d9304 增加旧版本数据自动转移功能;完善AddData数据接口 2019-07-25 09:42:00 +08:00
monitor1394
925e6317bc 修复Font无法自定义问题,优化代码 2019-07-24 23:38:23 +08:00
monitor1394
53acc084f8 优化Theme主题的自定义,切换主题时自定义配置不受影响 2019-07-24 09:41:27 +08:00
monitor1394
00158aed82 优化性能,降低GC 2019-07-23 21:43:01 +08:00
monitor1394
ec35122b16 优化Demo,增加Editor 2019-07-22 23:20:26 +08:00
monitor1394
ecba7db371 增加EffectScatter类型的散点图 2019-07-22 19:02:28 +08:00
monitor1394
d0331456ac fixed bug 2019-07-21 23:19:46 +08:00
monitor1394
7a01713842 增加ScatterChart散点图 2019-07-21 23:10:38 +08:00
monitor1394
c86747e0ed 重构SerieSymbol 2019-07-21 22:58:51 +08:00
monitor1394
abd6b166c2 增加Symbol配置Serie标志图形的显示 2019-07-20 12:18:07 +08:00
monitor1394
9f93d71279 增加用代码添加动态正弦曲线的示例 2019-07-19 23:17:06 +08:00
monitor1394
3c17d7763b 优化Legend的显示和控制 2019-07-19 21:55:22 +08:00
monitor1394
456d1ff81b 调整UI渲染模式为Camera模式,开启MSAA,设置4倍抗锯齿,曲线更平滑 2019-07-18 18:26:55 +08:00
monitor1394
79541c17a1 增加Tooltip指示器类型,优化显示控制 2019-07-18 09:42:36 +08:00
monitor1394
c0ae5eed32 增加设置图表Size支持 2019-07-15 19:21:22 +08:00
monitor1394
8fadbca405 代码整理,接口优化 2019-07-15 00:24:04 +08:00
monitor1394
0297702565 增加二维数据支持,XY轴都可以设置为数值轴 2019-07-14 14:34:18 +08:00
monitor1394
0cc7da662f 双坐标轴demo 2019-07-13 16:48:21 +08:00
monitor1394
40d7949588 增加双坐标轴支持 2019-07-13 16:38:38 +08:00
134 changed files with 403551 additions and 144138 deletions

3
.gitignore vendored
View File

@@ -4,7 +4,8 @@
/Library
/Temp
/UnityPackageManager
/Assets/Res
/Assets/Res.meta
/Assets/XCharts/Demo/demo_test.unity
/Assets/XCharts/Demo/demo_test.unity.meta

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cc28a4ebefb884f6ab7132e3910b7461
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(ChartModule), true)]
public class ChartModuleDrawer : PropertyDrawer
{
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
var lastX = drawRect.x;
var lastWid = drawRect.width;
SerializedProperty m_Name = prop.FindPropertyRelative("m_Name");
SerializedProperty m_Title = prop.FindPropertyRelative("m_Title");
SerializedProperty m_Selected = prop.FindPropertyRelative("m_Selected");
SerializedProperty m_Panel = prop.FindPropertyRelative("m_Panel");
var fieldWid = EditorGUIUtility.currentViewWidth - 30 - 5 - 50 - 90;
drawRect.width = 15;
EditorGUI.PropertyField(drawRect,m_Selected,GUIContent.none);
drawRect.x += 15;
drawRect.width = 50;
EditorGUI.PropertyField(drawRect,m_Name,GUIContent.none);
drawRect.x += 52;
drawRect.width = fieldWid;
EditorGUI.PropertyField(drawRect,m_Title,GUIContent.none);
drawRect.x += fieldWid + 2;
drawRect.width = 90;
EditorGUI.PropertyField(drawRect,m_Panel,GUIContent.none);
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
return 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 79b834e804f7aa844bc2ad80cf2bda9f
timeCreated: 1557366438
licenseType: Free
guid: 97c0f1cf754c54fd1913ec5b4129c6e5
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,59 @@
using UnityEditor;
using UnityEngine;
namespace XCharts
{
/// <summary>
/// Editor class used to edit UI BaseChart.
/// </summary>
[CustomEditor(typeof(Demo), false)]
public class DemoEditor : Editor
{
protected Demo m_Target;
protected SerializedProperty m_Script;
protected SerializedProperty m_ButtonNormalColor;
protected SerializedProperty m_ButtonSelectedColor;
protected SerializedProperty m_ButtonHighlightColor;
protected SerializedProperty m_ChartModule;
protected virtual void OnEnable()
{
m_Target = (Demo)target;
m_Script = serializedObject.FindProperty("m_Script");
m_ButtonNormalColor = serializedObject.FindProperty("m_ButtonNormalColor");
m_ButtonSelectedColor = serializedObject.FindProperty("m_ButtonSelectedColor");
m_ButtonHighlightColor = serializedObject.FindProperty("m_ButtonHighlightColor");
m_ChartModule = serializedObject.FindProperty("m_ChartModule");
}
public override void OnInspectorGUI()
{
if (m_Target == null && target == null)
{
base.OnInspectorGUI();
return;
}
serializedObject.Update();
EditorGUILayout.PropertyField(m_ButtonNormalColor);
EditorGUILayout.PropertyField(m_ButtonSelectedColor);
EditorGUILayout.PropertyField(m_ButtonHighlightColor);
var size = m_ChartModule.arraySize;
size = EditorGUILayout.IntField("Chart Module Size", size);
if (size != m_ChartModule.arraySize)
{
while (size > m_ChartModule.arraySize)
m_ChartModule.InsertArrayElementAtIndex(m_ChartModule.arraySize);
while (size < m_ChartModule.arraySize)
m_ChartModule.DeleteArrayElementAtIndex(m_ChartModule.arraySize - 1);
}
for (int i = 0; i < size; i++)
{
EditorGUILayout.PropertyField(m_ChartModule.GetArrayElementAtIndex(i));
}
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: e7dea6e12aeb93945888247ea97dbd13
timeCreated: 1554422468
licenseType: Free
guid: bc37c9f35cd6b4f0f936526a63fb19a5
MonoImporter:
externalObjects: {}
serializedVersion: 2

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +1,43 @@
using UnityEngine;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using XCharts;
[System.Serializable]
public class ChartModule
{
[SerializeField] private string m_Name;
[SerializeField] private string m_Title;
[SerializeField] private bool m_Selected;
[SerializeField] private GameObject m_Panel;
public string name { get { return m_Name; } set { m_Name = value; } }
public string title { get { return m_Title; } set { m_Title = value; } }
public bool select { get { return m_Selected; } set { m_Selected = value; } }
public GameObject panel { get { return m_Panel; } set { m_Panel = value; } }
public Button button { get; set; }
}
[DisallowMultipleComponent]
[ExecuteInEditMode]
public class Demo : MonoBehaviour
{
private Theme m_SelectedTheme;
private GameObject m_SelectedModule;
[SerializeField] private Color m_ButtonNormalColor;
[SerializeField] private Color m_ButtonSelectedColor;
[SerializeField] private Color m_ButtonHighlightColor;
[SerializeField] private List<ChartModule> m_ChartModule;
private GameObject m_LineChartModule;
private GameObject m_BarChartModule;
private GameObject m_PieChartModule;
private GameObject m_RadarChartModule;
private GameObject m_OtherModule;
private GameObject m_BtnClone;
private Theme m_SelectedTheme;
private int m_LastSelectedModuleIndex;
private Button m_DefaultThemeButton;
private Button m_LightThemeButton;
private Button m_DarkThemeButton;
private Button m_LineChartButton;
private Button m_BarChartButton;
private Button m_PieChartButton;
private Button m_RadarChartButton;
private Button m_OtherButton;
private Text m_Title;
private Color m_NormalColor;
private Color m_SelectedColor;
private Color m_HighlightColor;
private ScrollRect m_ScrollRect;
private Mask m_Mark;
@@ -35,46 +46,114 @@ public class Demo : MonoBehaviour
{
m_SelectedTheme = Theme.Default;
m_NormalColor = ChartHelper.GetColor("#293C55FF");
m_SelectedColor = ChartHelper.GetColor("#e43c59ff");
m_HighlightColor = ChartHelper.GetColor("#0E151FFF");
m_ButtonNormalColor = ChartHelper.GetColor("#293C55FF");
m_ButtonSelectedColor = ChartHelper.GetColor("#e43c59ff");
m_ButtonHighlightColor = ChartHelper.GetColor("#0E151FFF");
m_ScrollRect = transform.Find("chart_detail").GetComponent<ScrollRect>();
m_LineChartModule = transform.Find("chart_detail/Viewport/line_chart").gameObject;
m_BarChartModule = transform.Find("chart_detail/Viewport/bar_chart").gameObject;
m_PieChartModule = transform.Find("chart_detail/Viewport/pie_chart").gameObject;
m_RadarChartModule = transform.Find("chart_detail/Viewport/radar_chart").gameObject;
m_OtherModule = transform.Find("chart_detail/Viewport/other").gameObject;
m_Mark = transform.Find("chart_detail/Viewport").GetComponent<Mask>();
m_Mark.enabled = true;
m_Title = transform.Find("chart_title/Text").GetComponent<Text>();
InitThemeButton();
InitChartButton();
InitModuleButton();
}
void Update()
{
#if UNITY_EDITOR
if (m_ChartModule.Count <= 0) return;
int selectedModuleIndex = -1;
for (int i = 0; i < m_ChartModule.Count; i++)
{
if (selectedModuleIndex >= 0 && i > selectedModuleIndex)
{
m_ChartModule[i].select = false;
}
else if (m_ChartModule[i].select)
{
selectedModuleIndex = i;
}
}
if (selectedModuleIndex < 0) selectedModuleIndex = 0;
if (selectedModuleIndex != m_LastSelectedModuleIndex)
{
InitModuleButton();
}
#endif
}
void InitChartButton()
void InitModuleButton()
{
m_LineChartButton = transform.Find("chart_list/btn_linechart").GetComponent<Button>();
m_BarChartButton = transform.Find("chart_list/btn_barchart").GetComponent<Button>();
m_PieChartButton = transform.Find("chart_list/btn_piechart").GetComponent<Button>();
m_RadarChartButton = transform.Find("chart_list/btn_radarchart").GetComponent<Button>();
m_OtherButton = transform.Find("chart_list/btn_other").GetComponent<Button>();
var btnPanel = transform.Find("chart_list");
m_BtnClone = transform.Find("btn_clone").gameObject;
m_BtnClone.SetActive(false);
ChartHelper.DestoryAllChilds(btnPanel);
foreach (var module in m_ChartModule)
{
var btnName = "btn_" + module.name;
GameObject btn;
if (btnPanel.Find(btnName))
{
btn = btnPanel.Find(btnName).gameObject;
btn.SetActive(true);
}
else
{
btn = GameObject.Instantiate(m_BtnClone);
btn.SetActive(true);
btn.name = btnName;
btn.transform.SetParent(btnPanel);
btn.transform.localPosition = Vector3.zero;
}
btn.transform.localScale = Vector3.one;
module.button = btn.GetComponent<Button>();
module.button.GetComponentInChildren<Text>().text = module.name;
m_LineChartButton.onClick.AddListener(delegate () { SelectedModule(m_LineChartModule); });
m_BarChartButton.onClick.AddListener(delegate () { SelectedModule(m_BarChartModule); });
m_PieChartButton.onClick.AddListener(delegate () { SelectedModule(m_PieChartModule); });
m_RadarChartButton.onClick.AddListener(delegate () { SelectedModule(m_RadarChartModule); });
m_OtherButton.onClick.AddListener(delegate () { SelectedModule(m_OtherModule); });
ChartHelper.AddEventListener(btn.gameObject, EventTriggerType.PointerDown, (data) =>
{
ClickModule(module);
});
}
SelectedModule(m_LineChartModule);
for (int i = 0; i < m_ChartModule.Count; i++)
{
var module = m_ChartModule[i];
if (module.select)
{
ClickModule(module);
m_LastSelectedModuleIndex = i;
break;
}
}
}
void ClickModule(ChartModule selectedModule)
{
foreach (var module in m_ChartModule)
{
if (selectedModule != module)
{
var block = module.button.colors;
block.highlightedColor = m_ButtonHighlightColor;
block.normalColor = m_ButtonNormalColor;
module.button.colors = block;
module.panel.SetActive(false);
module.select = false;
}
else
{
var block = module.button.colors;
block.highlightedColor = m_ButtonSelectedColor;
block.normalColor = m_ButtonSelectedColor;
module.button.colors = block;
module.panel.SetActive(true);
module.select = true;
}
}
m_ScrollRect.content = selectedModule.panel.GetComponent<RectTransform>();
m_Title.text = string.IsNullOrEmpty(selectedModule.title) ?
selectedModule.name : selectedModule.title;
}
void InitThemeButton()
@@ -91,56 +170,7 @@ public class Demo : MonoBehaviour
m_LightThemeButton.onClick.AddListener(delegate () { SelecteTheme(Theme.Light); });
m_DarkThemeButton.onClick.AddListener(delegate () { SelecteTheme(Theme.Dark); });
SelecteTheme(Theme.Default);
}
void SelectedModule(GameObject module)
{
m_SelectedModule = module;
m_LineChartModule.SetActive(module == m_LineChartModule);
m_BarChartModule.SetActive(module == m_BarChartModule);
m_PieChartModule.SetActive(module == m_PieChartModule);
m_RadarChartModule.SetActive(module == m_RadarChartModule);
m_OtherModule.SetActive(module == m_OtherModule);
SetButtonColor(m_LineChartButton, m_SelectedModule, m_LineChartModule);
SetButtonColor(m_BarChartButton, m_SelectedModule, m_BarChartModule);
SetButtonColor(m_PieChartButton, m_SelectedModule, m_PieChartModule);
SetButtonColor(m_RadarChartButton, m_SelectedModule, m_RadarChartModule);
SetButtonColor(m_OtherButton, m_SelectedModule, m_OtherModule);
m_ScrollRect.content = m_SelectedModule.GetComponent<RectTransform>();
if (module == m_LineChartModule)
{
m_Title.text = "折线图 Line";
}
else if (module == m_BarChartModule)
{
m_Title.text = "柱状图 Bar";
}
else if (module == m_PieChartModule)
{
m_Title.text = "饼图 Pie";
}
else if (module == m_RadarChartModule)
{
m_Title.text = "雷达图 Radar";
}
else if (module == m_OtherModule)
{
m_Title.text = "其他";
}
SelecteTheme(m_SelectedTheme);
}
void SetButtonColor(Button btn, GameObject selected, GameObject module)
{
var block = btn.colors;
block.highlightedColor = selected == module ? m_SelectedColor : m_HighlightColor;
block.normalColor = selected == module ? m_SelectedColor : m_NormalColor;
btn.colors = block;
//SelecteTheme(Theme.Default);
}
void SelecteTheme(Theme theme)

View File

@@ -0,0 +1,39 @@
using UnityEngine;
using XCharts;
[DisallowMultipleComponent]
[ExecuteInEditMode]
public class Demo10_LineSimple : MonoBehaviour
{
void Awake()
{
var chart = gameObject.GetComponent<LineChart>();
if (chart == null) return;
chart.title.show = true;
chart.title.text = "Line Simple";
chart.tooltip.show = true;
chart.legend.show = false;
chart.xAxises[0].show = true;
chart.xAxises[1].show = false;
chart.yAxises[0].show = true;
chart.yAxises[1].show = false;
chart.xAxises[0].type = Axis.AxisType.Category;
chart.yAxises[0].type = Axis.AxisType.Value;
int dataCount = 10;
chart.xAxises[0].splitNumber = dataCount;
chart.xAxises[0].boundaryGap = true;
chart.RemoveData();
chart.AddSerie("test", SerieType.Line);
for (int i = 0; i < dataCount; i++)
{
chart.AddXAxisData("x" + i);
chart.AddData(0, Random.Range(10, 20));
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 38e8e72dd7107db429232ccab308e27c
timeCreated: 1554506762
licenseType: Free
guid: 75496d488607d421fbf2c190f80ed0a7
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,61 @@
using UnityEngine;
using XCharts;
[DisallowMultipleComponent]
[ExecuteInEditMode]
public class Demo11_AddSinCurve : MonoBehaviour
{
private float time;
public int angle;
private LineChart chart;
void Awake()
{
chart = gameObject.GetComponent<LineChart>();
if (chart != null)
{
GameObject.DestroyImmediate(chart);
}
chart = gameObject.AddComponent<LineChart>();
chart.title.show = true;
chart.title.text = "Sin Curve";
chart.tooltip.show = true;
chart.legend.show = false;
chart.xAxises[0].show = true;
chart.xAxises[1].show = false;
chart.yAxises[0].show = true;
chart.yAxises[1].show = false;
chart.xAxises[0].type = Axis.AxisType.Value;
chart.yAxises[0].type = Axis.AxisType.Value;
chart.xAxises[0].boundaryGap = false;
chart.maxCacheDataNumber = 0;
chart.line.step = false;
chart.line.smooth = false;
chart.line.area = false;
chart.RemoveData();
var serie = chart.AddSerie("test", SerieType.Line);
serie.symbol.type = SerieSymbolType.None;
for (angle = 0; angle < 1080; angle++)
{
float xvalue = Mathf.PI / 180 * angle;
float yvalue = Mathf.Sin(xvalue);
chart.AddData(0, xvalue, yvalue);
}
}
void Update()
{
if(angle > 3000) return;
angle++;
float xvalue = Mathf.PI / 180 * angle;
float yvalue = Mathf.Sin(xvalue);
chart.AddData(0, xvalue, yvalue);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee2ff4f81f1754f9e8e1df797df8c201
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
using System.Collections.Generic;
using UnityEngine;
using XCharts;
[DisallowMultipleComponent]
[ExecuteInEditMode]
public class Demo50_Scatter : MonoBehaviour
{
private ScatterChart chart;
void Awake()
{
chart = gameObject.GetComponent<ScatterChart>();
if (chart == null) return;
chart.series.SetSerieSymbolSizeCallback(SymbolSize,SymbolSelectedSize);
}
float SymbolSize(List<float> data)
{
//return Mathf.Clamp(data[1] * 10,1,100);
return (float)(Mathf.Sqrt(data[2]) / 6e2);
}
float SymbolSelectedSize(List<float> data)
{
//return Mathf.Clamp(data[1] * 10,1,100);
return (float)(Mathf.Sqrt(data[2]) / 5e2);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bb4941eb0bbd14736b16b39d256255bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -21,8 +21,9 @@ public class Demo_Dynamic : MonoBehaviour
void Awake()
{
chart = gameObject.GetComponentInChildren<CoordinateChart>();
chart.xAxis.ClearData();
chart.series.ClearData();
chart.RemoveData();
var serie = chart.AddSerie("data", SerieType.Line);
serie.symbol.type = SerieSymbolType.None;
chart.maxCacheDataNumber = maxCacheDataNumber;
timeNow = DateTime.Now;
timeNow = timeNow.AddSeconds(-maxCacheDataNumber);
@@ -30,14 +31,16 @@ public class Demo_Dynamic : MonoBehaviour
void Update()
{
if (initCount< maxCacheDataNumber)
if (initCount < maxCacheDataNumber)
{
int count = (int)(maxCacheDataNumber / initDataTime * Time.deltaTime);
for (int i = 0; i < count; i++)
{
timeNow = timeNow.AddSeconds(1);
chart.AddXAxisData(timeNow.ToString("hh:mm:ss"));
chart.AddData(0, UnityEngine.Random.Range(60, 150));
string category = timeNow.ToString("hh:mm:ss");
float value = UnityEngine.Random.Range(60, 150);
chart.AddXAxisData(category);
chart.AddData(0, value);
initCount++;
if (initCount > maxCacheDataNumber) break;
}
@@ -48,8 +51,10 @@ public class Demo_Dynamic : MonoBehaviour
{
updateTime = 0;
count++;
chart.AddXAxisData(DateTime.Now.ToString("hh:mm:ss"));
chart.AddData(0, UnityEngine.Random.Range(60, 150));
string category = DateTime.Now.ToString("hh:mm:ss");
float value = UnityEngine.Random.Range(60, 150);
chart.AddXAxisData(category);
chart.AddData(0, value);
chart.RefreshChart();
}
}

View File

@@ -18,7 +18,7 @@ public class Demo_LargeData : MonoBehaviour
{
chart = gameObject.GetComponentInChildren<CoordinateChart>();
timeNow = System.DateTime.Now;
chart.xAxis.ClearData();
chart.ClearAxisData();
chart.series.ClearData();
chart.maxCacheDataNumber = maxCacheDataNumber;
timeNow = timeNow.AddSeconds(-maxCacheDataNumber);
@@ -37,34 +37,6 @@ public class Demo_LargeData : MonoBehaviour
initCount++;
if (initCount > maxCacheDataNumber) break;
}
chart.RefreshChart();
}
}
void GenerateData(int count, CoordinateChart chart)
{
var baseValue = Random.Range(0, 1000);
var time = new System.DateTime(2011, 1, 1);
var smallBaseValue = 0;
chart.xAxis.ClearData();
for (var i = 0; i < count; i++)
{
chart.AddXAxisData(time.ToString("hh:mm:ss"));
smallBaseValue = i % 30 == 0
? Random.Range(0, 700)
: (smallBaseValue + Random.Range(0, 500) - 250);
baseValue += Random.Range(0, 20) - 10;
float value = Mathf.Max(
0,
Mathf.Round(baseValue + smallBaseValue) + 3000
);
//var index = i % 100;
//var value = (Mathf.Sin(index / 5) * (index / 5 - 10) + index / 6) * 5;
value = Mathf.Abs(value);
chart.AddData(0, value);
time = time.AddSeconds(1);
}
}
}

View File

@@ -24,12 +24,12 @@ public class Demo_PieChart : MonoBehaviour
time = 0;
if (count < 5)
{
chart.AddData("time" + count, Random.Range(10, 100));
chart.AddData(0, Random.Range(10, 100), "time" + count);
}
else
{
int index = count % 5;
chart.UpdateData("time" + index, Random.Range(10, 100));
chart.UpdateData(0, Random.Range(10, 100),index);
}
count++;
}

View File

@@ -1,30 +0,0 @@
using UnityEngine;
using XCharts;
[DisallowMultipleComponent]
[ExecuteInEditMode]
//[RequireComponent(typeof(CoordinateChart))]
public class Demo_Test : MonoBehaviour
{
private CoordinateChart chart;
private float time;
private int count;
void Awake()
{
chart = gameObject.GetComponentInChildren<CoordinateChart>();
}
void Update()
{
time += Time.deltaTime;
if (time >= 1)
{
time = 0;
count++;
chart.UpdateData(0, Random.Range(60, 150));
chart.AddXAxisData("time" + count);
chart.AddData(0, Random.Range(60, 150));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,8 @@ namespace XCharts
{
protected BaseChart m_Target;
protected SerializedProperty m_Script;
protected SerializedProperty m_ChartWidth;
protected SerializedProperty m_ChartHeight;
protected SerializedProperty m_Theme;
protected SerializedProperty m_ThemeInfo;
protected SerializedProperty m_Title;
@@ -26,19 +28,15 @@ namespace XCharts
protected float m_DefaultLabelWidth;
protected float m_DefaultFieldWidth;
private int m_SeriesSize;
private bool m_ThemeModuleToggle = false;
private bool m_BaseModuleToggle = false;
protected virtual void OnEnable()
{
m_Target = (BaseChart)target;
m_Script = serializedObject.FindProperty("m_Script");
m_ChartWidth = serializedObject.FindProperty("m_ChartWidth");
m_ChartHeight = serializedObject.FindProperty("m_ChartHeight");
m_Theme = serializedObject.FindProperty("m_Theme");
m_ThemeInfo = serializedObject.FindProperty("m_ThemeInfo");
m_Title = serializedObject.FindProperty("m_Title");
@@ -73,18 +71,9 @@ namespace XCharts
protected virtual void OnStartInspectorGUI()
{
EditorGUILayout.PropertyField(m_Script);
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.fieldWidth = EditorGUIUtility.labelWidth - 5;
m_ThemeModuleToggle = EditorGUILayout.Foldout(m_ThemeModuleToggle, "Theme",
ChartEditorHelper.foldoutStyle);
EditorGUILayout.PropertyField(m_Theme, GUIContent.none);
EditorGUILayout.EndHorizontal();
EditorGUIUtility.labelWidth = m_DefaultLabelWidth;
EditorGUIUtility.fieldWidth = m_DefaultFieldWidth;
if (m_ThemeModuleToggle)
{
EditorGUILayout.PropertyField(m_ThemeInfo, true);
}
EditorGUILayout.PropertyField(m_ChartWidth);
EditorGUILayout.PropertyField(m_ChartHeight);
EditorGUILayout.PropertyField(m_ThemeInfo, true);
EditorGUILayout.PropertyField(m_Title, true);
EditorGUILayout.PropertyField(m_Legend, true);
EditorGUILayout.PropertyField(m_Tooltip, true);
@@ -93,12 +82,14 @@ namespace XCharts
protected virtual void OnMiddleInspectorGUI()
{
EditorGUILayout.PropertyField(m_Series, true);
m_BaseModuleToggle = EditorGUILayout.Foldout(m_BaseModuleToggle, "Base",
m_BaseModuleToggle = EditorGUILayout.Foldout(m_BaseModuleToggle,
new GUIContent("Base", "基础配置"),
ChartEditorHelper.foldoutStyle);
if (m_BaseModuleToggle)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_Large, true);
var largeTip = "Whether to enable the optimization of large-scale graph. \n是否启用大规模线图的优化在数据图形特别多的时候>=5k可以开启。";
EditorGUILayout.PropertyField(m_Large, new GUIContent("Large", largeTip));
EditorGUILayout.PropertyField(m_MinShowDataNumber, true);
EditorGUILayout.PropertyField(m_MaxShowDataNumber, true);
EditorGUILayout.PropertyField(m_MaxCacheDataNumber, true);

View File

@@ -1,4 +1,5 @@
using UnityEditor;
using UnityEngine;
namespace XCharts
{
@@ -9,18 +10,20 @@ namespace XCharts
[CustomEditor(typeof(CoordinateChart), false)]
public class CoordinateChartEditor : BaseChartEditor
{
protected SerializedProperty m_Coordinate;
protected SerializedProperty m_XAxis;
protected SerializedProperty m_YAxis;
protected SerializedProperty m_Grid;
protected SerializedProperty m_MultipleXAxis;
protected SerializedProperty m_XAxises;
protected SerializedProperty m_MultipleYAxis;
protected SerializedProperty m_YAxises;
protected SerializedProperty m_DataZoom;
protected override void OnEnable()
{
base.OnEnable();
m_Target = (CoordinateChart)target;
m_Coordinate = serializedObject.FindProperty("m_Coordinate");
m_XAxis = serializedObject.FindProperty("m_XAxis");
m_YAxis = serializedObject.FindProperty("m_YAxis");
m_Grid = serializedObject.FindProperty("m_Grid");
m_XAxises = serializedObject.FindProperty("m_XAxises");
m_YAxises = serializedObject.FindProperty("m_YAxises");
m_DataZoom = serializedObject.FindProperty("m_DataZoom");
}
@@ -28,9 +31,17 @@ namespace XCharts
{
base.OnStartInspectorGUI();
EditorGUILayout.PropertyField(m_DataZoom);
EditorGUILayout.PropertyField(m_Coordinate);
EditorGUILayout.PropertyField(m_XAxis);
EditorGUILayout.PropertyField(m_YAxis);
EditorGUILayout.PropertyField(m_Grid);
for (int i = 0; i < m_XAxises.arraySize; i++)
{
SerializedProperty axis = m_XAxises.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(axis);
}
for (int i = 0; i < m_YAxises.arraySize; i++)
{
SerializedProperty axis = m_YAxises.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(axis);
}
}
}
}

View File

@@ -0,0 +1,53 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(AreaStyle), true)]
public class AreaStyleDrawer : PropertyDrawer
{
private Dictionary<string, bool> m_AreaStyleToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_Origin = prop.FindPropertyRelative("m_Origin");
SerializedProperty m_Color = prop.FindPropertyRelative("m_Color");
SerializedProperty m_ToColor = prop.FindPropertyRelative("m_ToColor");
SerializedProperty m_Opacity = prop.FindPropertyRelative("m_Opacity");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_AreaStyleToggle, prop, "Area Style", show, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (ChartEditorHelper.IsToggle(m_AreaStyleToggle, prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Origin);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Color);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_ToColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Opacity);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
--EditorGUI.indentLevel;
}
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (ChartEditorHelper.IsToggle(m_AreaStyleToggle, prop))
{
height += 5 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
}
else
{
height += 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
}
return height;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c51fd822c8be44490832d81652d1aef5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +1,5 @@
using UnityEditor;
using UnityEditorInternal;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
@@ -7,30 +7,16 @@ namespace XCharts
[CustomPropertyDrawer(typeof(Axis), true)]
public class AxisDrawer : PropertyDrawer
{
private ReorderableList m_DataList;
private bool m_DataFoldout = false;
private List<bool> m_AxisModuleToggle = new List<bool>();
private List<bool> m_DataFoldout = new List<bool>();
private int m_DataSize = 0;
private bool m_ShowJsonDataArea = false;
private string m_JsonDataAreaText;
private bool m_AxisModuleToggle = false;
private void InitReorderableList(SerializedProperty prop)
protected virtual string GetDisplayName(string displayName)
{
if (m_DataList == null)
{
SerializedProperty data = prop.FindPropertyRelative("m_Data");
m_DataList = new ReorderableList(data.serializedObject, data, false, false, true, true);
m_DataList.elementHeight = EditorGUIUtility.singleLineHeight;
m_DataList.drawHeaderCallback += delegate (Rect rect)
{
EditorGUI.LabelField(rect, data.displayName);
};
m_DataList.drawElementCallback = delegate (Rect rect, int index, bool isActive, bool isFocused)
{
EditorGUI.PropertyField(rect, data.GetArrayElementAtIndex(index), true);
};
}
return displayName;
}
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
@@ -54,9 +40,12 @@ namespace XCharts
SerializedProperty m_Min = prop.FindPropertyRelative("m_Min");
SerializedProperty m_Max = prop.FindPropertyRelative("m_Max");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_AxisModuleToggle, prop.displayName, m_Show);
int index = InitToggle(prop);
bool toggle = m_AxisModuleToggle[index];
m_AxisModuleToggle[index] = ChartEditorHelper.MakeFoldout(ref drawRect, ref toggle,
GetDisplayName(prop.displayName), m_Show);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_AxisModuleToggle)
if (m_AxisModuleToggle[index])
{
Axis.AxisType type = (Axis.AxisType)m_Type.enumValueIndex;
EditorGUI.indentLevel++;
@@ -123,10 +112,10 @@ namespace XCharts
if (type == Axis.AxisType.Category)
{
drawRect.width = EditorGUIUtility.labelWidth + 10;
m_DataFoldout = EditorGUI.Foldout(drawRect, m_DataFoldout, "Data");
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_ShowJsonDataArea, ref m_JsonDataAreaText, prop);
m_DataFoldout[index] = EditorGUI.Foldout(drawRect, m_DataFoldout[index], "Data");
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_ShowJsonDataArea, ref m_JsonDataAreaText, prop, pos.width);
drawRect.width = pos.width;
if (m_DataFoldout)
if (m_DataFoldout[index])
{
ChartEditorHelper.MakeList(ref drawRect, ref m_DataSize, m_Data);
}
@@ -137,7 +126,8 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
if (!m_AxisModuleToggle)
int index = InitToggle(prop);
if (!m_AxisModuleToggle[index])
{
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
@@ -154,7 +144,7 @@ namespace XCharts
Axis.AxisType type = (Axis.AxisType)m_Type.enumValueIndex;
if (type == Axis.AxisType.Category)
{
if (m_DataFoldout)
if (m_DataFoldout[index])
{
SerializedProperty m_Data = prop.FindPropertyRelative("m_Data");
int num = m_Data.arraySize + 2;
@@ -187,7 +177,21 @@ namespace XCharts
height += EditorGUI.GetPropertyHeight(m_SplitArea);
return height;
}
}
private int InitToggle(SerializedProperty prop)
{
int index = 0;
int.TryParse(prop.displayName.Split(' ')[1],out index);
if (index >= m_DataFoldout.Count)
{
m_DataFoldout.Add(false);
}
if (index >= m_AxisModuleToggle.Count)
{
m_AxisModuleToggle.Add(false);
}
return index;
}
}
}

View File

@@ -1,12 +1,13 @@
using UnityEditor;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(Axis.AxisLabel), true)]
[CustomPropertyDrawer(typeof(AxisLabel), true)]
public class AxisLabelDrawer : PropertyDrawer
{
private bool m_AxisLabelToggle = false;
private Dictionary<string, bool> m_AxisLabelToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
@@ -21,9 +22,9 @@ namespace XCharts
SerializedProperty m_FontSize = prop.FindPropertyRelative("m_FontSize");
SerializedProperty m_FontStyle = prop.FindPropertyRelative("m_FontStyle");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_AxisLabelToggle, "Axis Label", show, false);
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_AxisLabelToggle,prop, "Axis Label", show, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_AxisLabelToggle)
if (ChartEditorHelper.IsToggle(m_AxisLabelToggle,prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Inside);
@@ -47,9 +48,9 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (m_AxisLabelToggle)
if (ChartEditorHelper.IsToggle(m_AxisLabelToggle,prop))
{
height += 8 * EditorGUIUtility.singleLineHeight + 7 * EditorGUIUtility.standardVerticalSpacing;
height += 7 * EditorGUIUtility.singleLineHeight + 6 * EditorGUIUtility.standardVerticalSpacing;
}
return height;
}

View File

@@ -1,29 +1,33 @@
using UnityEditor;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(Axis.AxisLine), true)]
[CustomPropertyDrawer(typeof(AxisLine), true)]
public class AxisLineDrawer : PropertyDrawer
{
private bool m_AxisLineToggle = false;
private Dictionary<string, bool> m_AxisLineToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_OnZero = prop.FindPropertyRelative("m_OnZero");
SerializedProperty m_Symbol = prop.FindPropertyRelative("m_Symbol");
SerializedProperty m_SymbolWidth = prop.FindPropertyRelative("m_SymbolWidth");
SerializedProperty m_SymbolHeight = prop.FindPropertyRelative("m_SymbolHeight");
SerializedProperty m_SymbolOffset = prop.FindPropertyRelative("m_SymbolOffset");
SerializedProperty m_SymbolDent = prop.FindPropertyRelative("m_SymbolDent");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_AxisLineToggle, "Axis Line", show, false);
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_AxisLineToggle, prop, "Axis Line", show, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_AxisLineToggle)
if (ChartEditorHelper.IsToggle(m_AxisLineToggle,prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_OnZero);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Symbol);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SymbolWidth);
@@ -41,9 +45,9 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (m_AxisLineToggle)
if (ChartEditorHelper.IsToggle(m_AxisLineToggle,prop))
{
height += 5 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
height += 6 * EditorGUIUtility.singleLineHeight + 7 * EditorGUIUtility.standardVerticalSpacing;
}
return height;
}

View File

@@ -1,12 +1,13 @@
using UnityEditor;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(Axis.AxisName), true)]
[CustomPropertyDrawer(typeof(AxisName), true)]
public class AxisNameDrawer : PropertyDrawer
{
private bool m_AxisNameToggle = false;
private Dictionary<string, bool> m_AxisNameToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
@@ -21,9 +22,9 @@ namespace XCharts
SerializedProperty m_FontSize = prop.FindPropertyRelative("m_FontSize");
SerializedProperty m_FontStyle = prop.FindPropertyRelative("m_FontStyle");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_AxisNameToggle, "Axis Name", show, false);
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_AxisNameToggle, prop, "Axis Name", show, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_AxisNameToggle)
if (ChartEditorHelper.IsToggle(m_AxisNameToggle, prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Name);
@@ -47,7 +48,7 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (m_AxisNameToggle)
if (ChartEditorHelper.IsToggle(m_AxisNameToggle, prop))
{
height += 7 * EditorGUIUtility.singleLineHeight + 6 * EditorGUIUtility.standardVerticalSpacing;
}

View File

@@ -1,15 +1,15 @@
using UnityEditor;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(Axis.SplitArea), true)]
[CustomPropertyDrawer(typeof(AxisSplitArea), true)]
public class AxisSplitAreaDrawer : PropertyDrawer
{
private bool m_ColorFoldout = false;
private int m_ColorSize = 0;
private bool m_SplitAreaToggle = false;
private Dictionary<string, bool> m_SplitAreaToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
@@ -18,9 +18,9 @@ namespace XCharts
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_Color = prop.FindPropertyRelative("m_Color");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_SplitAreaToggle, "Split Area", show, false);
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_SplitAreaToggle, prop, "Split Area", show, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_SplitAreaToggle)
if (ChartEditorHelper.IsToggle(m_SplitAreaToggle, prop))
{
++EditorGUI.indentLevel;
m_ColorFoldout = EditorGUI.Foldout(drawRect, m_ColorFoldout, "Color");
@@ -37,7 +37,7 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (m_SplitAreaToggle)
if (ChartEditorHelper.IsToggle(m_SplitAreaToggle, prop))
{
height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_ColorFoldout)

View File

@@ -3,7 +3,7 @@ using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(Axis.AxisTick), true)]
[CustomPropertyDrawer(typeof(AxisTick), true)]
public class AxisTickDrawer : PropertyDrawer
{
private bool m_AxisTickToggle = false;

View File

@@ -3,7 +3,7 @@ using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(BarChart.Bar), true)]
[CustomPropertyDrawer(typeof(Bar), true)]
public class BarDrawer : PropertyDrawer
{
SerializedProperty m_InSameBar;

View File

@@ -3,27 +3,27 @@ using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(Coordinate), true)]
public class CoordinateDrawer : PropertyDrawer
[CustomPropertyDrawer(typeof(Grid), true)]
public class GridDrawer : PropertyDrawer
{
private bool m_CoordinateModuleToggle = false;
private bool m_GridModuleToggle = false;
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty m_Show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_Left = prop.FindPropertyRelative("m_Left");
SerializedProperty m_Right = prop.FindPropertyRelative("m_Right");
SerializedProperty m_Top = prop.FindPropertyRelative("m_Top");
SerializedProperty m_Bottom = prop.FindPropertyRelative("m_Bottom");
SerializedProperty m_Tickness = prop.FindPropertyRelative("m_Tickness");
SerializedProperty m_FontSize = prop.FindPropertyRelative("m_FontSize");
SerializedProperty m_BackgroundColor = prop.FindPropertyRelative("m_BackgroundColor");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_CoordinateModuleToggle, "Coordinate");
EditorGUI.LabelField(drawRect, "Coordinate", EditorStyles.boldLabel);
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_GridModuleToggle, "Grid",m_Show);
EditorGUI.LabelField(drawRect, "Grid", EditorStyles.boldLabel);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_CoordinateModuleToggle)
if (m_GridModuleToggle)
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Left);
@@ -34,9 +34,7 @@ namespace XCharts
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Bottom);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Tickness);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_FontSize);
EditorGUI.PropertyField(drawRect, m_BackgroundColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
--EditorGUI.indentLevel;
}
@@ -44,8 +42,8 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
if (m_CoordinateModuleToggle)
return 7 * EditorGUIUtility.singleLineHeight + 6 * EditorGUIUtility.standardVerticalSpacing;
if (m_GridModuleToggle)
return 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing;
else
return 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f4142159d55a64e1d88d81ac84b714d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -17,6 +17,7 @@ namespace XCharts
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_SelectedMode = prop.FindPropertyRelative("m_SelectedMode");
SerializedProperty orient = prop.FindPropertyRelative("m_Orient");
SerializedProperty location = prop.FindPropertyRelative("m_Location");
SerializedProperty itemWidth = prop.FindPropertyRelative("m_ItemWidth");
@@ -38,13 +39,15 @@ namespace XCharts
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, itemFontSize);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SelectedMode);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, orient);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, location);
drawRect.y += EditorGUI.GetPropertyHeight(location);
drawRect.width = EditorGUIUtility.labelWidth + 10;
m_DataFoldout = EditorGUI.Foldout(drawRect, m_DataFoldout, "Data");
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_ShowJsonDataArea, ref m_JsonDataAreaText, prop);
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_ShowJsonDataArea, ref m_JsonDataAreaText, prop,pos.width);
drawRect.width = pos.width;
if (m_DataFoldout)
{
@@ -60,7 +63,7 @@ namespace XCharts
if (m_LegendModuleToggle)
{
SerializedProperty location = prop.FindPropertyRelative("m_Location");
height += 5 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
height += 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(location);
height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_DataFoldout)
@@ -73,7 +76,7 @@ namespace XCharts
}
if (m_ShowJsonDataArea)
{
height += EditorGUIUtility.singleLineHeight * 3 + EditorGUIUtility.standardVerticalSpacing;
height += EditorGUIUtility.singleLineHeight * 4 + EditorGUIUtility.standardVerticalSpacing;
}
height += 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
return height;

View File

@@ -7,8 +7,6 @@ namespace XCharts
public class LineDrawer : PropertyDrawer
{
SerializedProperty m_Tickness;
SerializedProperty m_Point;
SerializedProperty m_PointWidth;
SerializedProperty m_Smooth;
SerializedProperty m_SmoothStyle;
SerializedProperty m_Area;
@@ -20,8 +18,6 @@ namespace XCharts
private void InitProperty(SerializedProperty prop)
{
m_Tickness = prop.FindPropertyRelative("m_Tickness");
m_Point = prop.FindPropertyRelative("m_Point");
m_PointWidth = prop.FindPropertyRelative("m_PointWidth");
m_Smooth = prop.FindPropertyRelative("m_Smooth");
m_SmoothStyle = prop.FindPropertyRelative("m_SmoothStyle");
m_Area = prop.FindPropertyRelative("m_Area");
@@ -43,22 +39,6 @@ namespace XCharts
EditorGUI.PropertyField(drawRect, m_Tickness);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
drawRect.width = EditorGUIUtility.labelWidth + 10;
EditorGUI.PropertyField(drawRect, m_Point);
if (m_Point.boolValue)
{
drawRect.x = EditorGUIUtility.labelWidth + 15;
EditorGUI.LabelField(drawRect, "Width");
drawRect.x = EditorGUIUtility.labelWidth + 65;
float tempWidth = EditorGUIUtility.currentViewWidth - EditorGUIUtility.labelWidth - 70;
if (tempWidth < 20) tempWidth = 20;
drawRect.width = tempWidth;
EditorGUI.PropertyField(drawRect, m_PointWidth, GUIContent.none);
drawRect.x = pos.x;
drawRect.width = pos.width;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
drawRect.width = EditorGUIUtility.labelWidth + 10;
EditorGUI.PropertyField(drawRect, m_Smooth);
if (m_Smooth.boolValue)
@@ -99,9 +79,11 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (m_LineModuleToggle)
{
return 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing;
height = 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing;
return height;
}
else
{

View File

@@ -0,0 +1,52 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(LineStyle), true)]
public class LineStyleDrawer : PropertyDrawer
{
private Dictionary<string, bool> m_LineStyleToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_Type = prop.FindPropertyRelative("m_Type");
SerializedProperty m_Color = prop.FindPropertyRelative("m_Color");
SerializedProperty m_Width = prop.FindPropertyRelative("m_Width");
SerializedProperty m_Opacity = prop.FindPropertyRelative("m_Opacity");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_LineStyleToggle, prop, "Line Style", show, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (ChartEditorHelper.IsToggle(m_LineStyleToggle, prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Type);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Color);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Width);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Opacity);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
--EditorGUI.indentLevel;
}
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (ChartEditorHelper.IsToggle(m_LineStyleToggle, prop))
{
height += 5 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
}
else
{
height += 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
}
return height;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4a36d5076e1414d619b53d1ef998806f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -72,14 +72,14 @@ namespace XCharts
switch ((Location.Align)align.enumValueIndex)
{
case Location.Align.Center:
return 1 * EditorGUIUtility.singleLineHeight + 0 * EditorGUIUtility.standardVerticalSpacing;
return 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
case Location.Align.TopCenter:
case Location.Align.BottomCenter:
case Location.Align.CenterLeft:
case Location.Align.CenterRight:
return 2 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
return 2 * EditorGUIUtility.singleLineHeight + 2 * EditorGUIUtility.standardVerticalSpacing;
default:
return 3 * EditorGUIUtility.singleLineHeight + 2 * EditorGUIUtility.standardVerticalSpacing;
return 3 * EditorGUIUtility.singleLineHeight + 3 * EditorGUIUtility.standardVerticalSpacing;
}
}
}

View File

@@ -23,18 +23,7 @@ namespace XCharts
private void InitProperty(SerializedProperty prop)
{
m_Name = prop.FindPropertyRelative("m_Name");
m_InsideRadius = prop.FindPropertyRelative("m_InsideRadius");
m_OutsideRadius = prop.FindPropertyRelative("m_OutsideRadius");
m_TooltipExtraRadius = prop.FindPropertyRelative("m_TooltipExtraRadius");
m_Rose = prop.FindPropertyRelative("m_Rose");
m_Space = prop.FindPropertyRelative("m_Space");
m_Left = prop.FindPropertyRelative("m_Left");
m_Right = prop.FindPropertyRelative("m_Right");
m_Top = prop.FindPropertyRelative("m_Top");
m_Bottom = prop.FindPropertyRelative("m_Bottom");
m_Selected = prop.FindPropertyRelative("m_Selected");
m_SelectedIndex = prop.FindPropertyRelative("m_SelectedIndex");
m_SelectedOffset = prop.FindPropertyRelative("m_SelectedOffset");
}
@@ -48,32 +37,10 @@ namespace XCharts
if (m_PieModuleToggle)
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Name);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_InsideRadius);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_OutsideRadius);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_TooltipExtraRadius);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Selected);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SelectedIndex);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SelectedOffset);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Rose);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Space);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Left);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Right);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Top);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Bottom);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
--EditorGUI.indentLevel;
}
@@ -82,7 +49,7 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
if (m_PieModuleToggle)
return 14 * EditorGUIUtility.singleLineHeight + 13 * EditorGUIUtility.standardVerticalSpacing;
return 3 * EditorGUIUtility.singleLineHeight + 2 * EditorGUIUtility.standardVerticalSpacing;
else
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}

View File

@@ -1,4 +1,5 @@
using UnityEditor;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
@@ -6,24 +7,17 @@ namespace XCharts
[CustomPropertyDrawer(typeof(Radar), true)]
public class RadarDrawer : PropertyDrawer
{
SerializedProperty m_Cricle;
SerializedProperty m_Area;
SerializedProperty m_Shape;
SerializedProperty m_Radius;
SerializedProperty m_SplitNumber;
SerializedProperty m_Left;
SerializedProperty m_Right;
SerializedProperty m_Top;
SerializedProperty m_Bottom;
SerializedProperty m_LineTickness;
SerializedProperty m_LinePointSize;
SerializedProperty m_BackgroundColorList;
SerializedProperty m_LineColor;
SerializedProperty m_AreaAlpha;
SerializedProperty m_Center;
SerializedProperty m_LineStyle;
SerializedProperty m_SplitArea;
SerializedProperty m_Indicator;
SerializedProperty m_IndicatorList;
private bool m_RadarModuleToggle = false;
private bool m_IndicatorToggle = false;
private Dictionary<string, bool> m_RadarModuleToggle = new Dictionary<string, bool>();
private Dictionary<string, bool> m_IndicatorToggle = new Dictionary<string, bool>();
private bool m_IndicatorJsonAreaToggle = false;
private string m_IndicatorJsonAreaText;
private int m_IndicatorSize;
@@ -32,19 +26,12 @@ namespace XCharts
private void InitProperty(SerializedProperty prop)
{
m_Cricle = prop.FindPropertyRelative("m_Cricle");
m_Area = prop.FindPropertyRelative("m_Area");
m_Shape = prop.FindPropertyRelative("m_Shape");
m_Radius = prop.FindPropertyRelative("m_Radius");
m_SplitNumber = prop.FindPropertyRelative("m_SplitNumber");
m_Left = prop.FindPropertyRelative("m_Left");
m_Right = prop.FindPropertyRelative("m_Right");
m_Top = prop.FindPropertyRelative("m_Top");
m_Bottom = prop.FindPropertyRelative("m_Bottom");
m_LineTickness = prop.FindPropertyRelative("m_LineTickness");
m_LinePointSize = prop.FindPropertyRelative("m_LinePointSize");
m_LineColor = prop.FindPropertyRelative("m_LineColor");
m_AreaAlpha = prop.FindPropertyRelative("m_AreaAlpha");
m_BackgroundColorList = prop.FindPropertyRelative("m_BackgroundColorList");
m_Center = prop.FindPropertyRelative("m_Center");
m_LineStyle = prop.FindPropertyRelative("m_LineStyle");
m_SplitArea = prop.FindPropertyRelative("m_SplitArea");
m_Indicator = prop.FindPropertyRelative("m_Indicator");
m_IndicatorList = prop.FindPropertyRelative("m_IndicatorList");
}
@@ -56,65 +43,46 @@ namespace XCharts
float defaultLabelWidth = EditorGUIUtility.labelWidth;
float defaultFieldWidth = EditorGUIUtility.fieldWidth;
drawRect.height = EditorGUIUtility.singleLineHeight;
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_RadarModuleToggle, "Radar");
int index = ChartEditorHelper.GetIndexFromPath(prop);
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_RadarModuleToggle, prop, "Radar " + index, null, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_RadarModuleToggle)
if (ChartEditorHelper.IsToggle(m_RadarModuleToggle,prop))
{
++EditorGUI.indentLevel;
EditorGUIUtility.fieldWidth = 10;
EditorGUIUtility.labelWidth = 50;
drawRect.width = 60;
EditorGUI.PropertyField(drawRect, m_Cricle);
EditorGUIUtility.labelWidth = 45;
drawRect.x += 60;
EditorGUI.PropertyField(drawRect, m_Area);
EditorGUIUtility.labelWidth = 70;
drawRect.x += 55;
drawRect.width = 80;
EditorGUI.PropertyField(drawRect, m_Indicator);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
drawRect.x = pos.x;
drawRect.width = pos.width;
EditorGUIUtility.labelWidth = defaultLabelWidth;
EditorGUIUtility.fieldWidth = defaultFieldWidth;
EditorGUI.PropertyField(drawRect, m_Shape);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.LabelField(drawRect, "Center");
var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15;
var tempWidth = (pos.width - startX + 35) / 2;
var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height);
var centerYRect = new Rect(centerXRect.x + tempWidth - 20, drawRect.y, tempWidth, drawRect.height);
while (m_Center.arraySize < 2)
{
m_Center.InsertArrayElementAtIndex(m_Center.arraySize);
}
EditorGUI.PropertyField(centerXRect, m_Center.GetArrayElementAtIndex(0), GUIContent.none);
EditorGUI.PropertyField(centerYRect, m_Center.GetArrayElementAtIndex(1), GUIContent.none);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Radius);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SplitNumber);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Left);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Right);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Top);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Bottom);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_LineTickness);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_LinePointSize);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_AreaAlpha);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_LineColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
m_BackgroundColorToggle = EditorGUI.Foldout(drawRect, m_BackgroundColorToggle, "BackgroundColors");
EditorGUI.PropertyField(drawRect, m_LineStyle);
drawRect.y += EditorGUI.GetPropertyHeight(m_LineStyle);
EditorGUI.PropertyField(drawRect, m_SplitArea);
drawRect.y += EditorGUI.GetPropertyHeight(m_SplitArea);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_IndicatorToggle, prop, "Indicators", m_Indicator, false);
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_IndicatorJsonAreaToggle, ref m_IndicatorJsonAreaText, prop, pos.width, 20);
drawRect.width = pos.width;
if (m_BackgroundColorToggle)
{
ChartEditorHelper.MakeList(ref drawRect, ref m_BackgroundColorSize, m_BackgroundColorList);
}
drawRect.width = EditorGUIUtility.labelWidth + 10;
m_IndicatorToggle = EditorGUI.Foldout(drawRect, m_IndicatorToggle, "Indicators");
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_IndicatorJsonAreaToggle, ref m_IndicatorJsonAreaText, prop);
drawRect.width = pos.width;
if (m_IndicatorToggle)
drawRect.x = pos.x;
if (ChartEditorHelper.IsToggle(m_IndicatorToggle, prop))
{
ChartEditorHelper.MakeList(ref drawRect, ref m_IndicatorSize, m_IndicatorList);
}
@@ -125,27 +93,20 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
int propNum = 1;
if (m_RadarModuleToggle)
if (ChartEditorHelper.IsToggle(m_RadarModuleToggle,prop))
{
propNum += 13;
if (m_BackgroundColorToggle)
{
m_BackgroundColorList = prop.FindPropertyRelative("m_BackgroundColorList");
propNum += 2;
propNum += m_BackgroundColorList.arraySize;
}
propNum += 6;
if (m_IndicatorJsonAreaToggle) propNum += 4;
float height = propNum * EditorGUIUtility.singleLineHeight + (propNum - 1) * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_LineStyle"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_SplitArea"));
if (m_IndicatorToggle)
if (ChartEditorHelper.IsToggle(m_IndicatorToggle, prop))
{
m_IndicatorList = prop.FindPropertyRelative("m_IndicatorList");
height += EditorGUIUtility.singleLineHeight * 2 + EditorGUIUtility.standardVerticalSpacing;
for (int i = 0; i < m_IndicatorSize; i++)
for (int i = 0; i < m_IndicatorList.arraySize; i++)
{
height += EditorGUI.GetPropertyHeight(m_IndicatorList.GetArrayElementAtIndex(i));
}

View File

@@ -1,4 +1,5 @@
using UnityEditor;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
@@ -6,35 +7,34 @@ namespace XCharts
[CustomPropertyDrawer(typeof(Radar.Indicator), true)]
public class RadarIndicatorDrawer : PropertyDrawer
{
SerializedProperty m_Name;
SerializedProperty m_Max;
private bool m_RadarModuleToggle = false;
private void InitProperty(SerializedProperty prop)
{
m_Name = prop.FindPropertyRelative("m_Name");
m_Max = prop.FindPropertyRelative("m_Max");
}
private Dictionary<string, bool> m_RadarModuleToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
InitProperty(prop);
SerializedProperty m_Name = prop.FindPropertyRelative("m_Name");
SerializedProperty m_Max = prop.FindPropertyRelative("m_Max");
SerializedProperty m_Min = prop.FindPropertyRelative("m_Min");
SerializedProperty m_Color = prop.FindPropertyRelative("m_Color");
Rect drawRect = pos;
float defaultLabelWidth = EditorGUIUtility.labelWidth;
float defaultFieldWidth = EditorGUIUtility.fieldWidth;
drawRect.height = EditorGUIUtility.singleLineHeight;
m_RadarModuleToggle = EditorGUI.Foldout(drawRect, m_RadarModuleToggle, "Indicator");
int index = ChartEditorHelper.GetIndexFromPath(prop);
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_RadarModuleToggle, prop, "Indicator " + index, m_Name, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_RadarModuleToggle)
if (ChartEditorHelper.IsToggle(m_RadarModuleToggle,prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Name);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Min);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Max);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Color);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
--EditorGUI.indentLevel;
}
@@ -42,11 +42,9 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
int propNum = 1;
if (m_RadarModuleToggle)
if (ChartEditorHelper.IsToggle(m_RadarModuleToggle,prop))
{
propNum += 2;
return propNum * EditorGUIUtility.singleLineHeight + (propNum - 1) * EditorGUIUtility.standardVerticalSpacing;
return 5 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
}
else
{

View File

@@ -1,4 +1,5 @@
using UnityEditor;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
@@ -6,71 +7,305 @@ namespace XCharts
[CustomPropertyDrawer(typeof(Serie), true)]
public class SerieDrawer : PropertyDrawer
{
private bool m_DataFoldout = false;
private int m_DataSize = 0;
private Dictionary<string, bool> m_SerieModuleToggle = new Dictionary<string, bool>();
private List<bool> m_DataFoldout = new List<bool>();
private bool m_ShowJsonDataArea = false;
private string m_JsonDataAreaText;
private bool m_SerieModuleToggle = false;
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty show = prop.FindPropertyRelative("m_Show");
//SerializedProperty type = prop.FindPropertyRelative("m_Type");
SerializedProperty type = prop.FindPropertyRelative("m_Type");
SerializedProperty name = prop.FindPropertyRelative("m_Name");
SerializedProperty stack = prop.FindPropertyRelative("m_Stack");
SerializedProperty m_Data = prop.FindPropertyRelative("m_Data");
SerializedProperty m_AxisIndex = prop.FindPropertyRelative("m_AxisIndex");
SerializedProperty m_RadarIndex = prop.FindPropertyRelative("m_RadarIndex");
SerializedProperty m_LineStyle = prop.FindPropertyRelative("m_LineStyle");
SerializedProperty m_AreaStyle = prop.FindPropertyRelative("m_AreaStyle");
SerializedProperty m_Symbol = prop.FindPropertyRelative("m_Symbol");
SerializedProperty m_RoseType = prop.FindPropertyRelative("m_RoseType");
SerializedProperty m_ClickOffset = prop.FindPropertyRelative("m_ClickOffset");
SerializedProperty m_Space = prop.FindPropertyRelative("m_Space");
SerializedProperty m_Center = prop.FindPropertyRelative("m_Center");
SerializedProperty m_Radius = prop.FindPropertyRelative("m_Radius");
SerializedProperty m_Label = prop.FindPropertyRelative("m_Label");
SerializedProperty m_HighlightLabel = prop.FindPropertyRelative("m_HighlightLabel");
SerializedProperty m_DataDimension = prop.FindPropertyRelative("m_ShowDataDimension");
SerializedProperty m_ShowDataName = prop.FindPropertyRelative("m_ShowDataName");
SerializedProperty m_Datas = prop.FindPropertyRelative("m_Data");
string moduleName = "Serie " + prop.displayName.Split(' ')[1];
if (!string.IsNullOrEmpty(name.stringValue))
moduleName += ":" + name.stringValue;
m_SerieModuleToggle = EditorGUI.Foldout(drawRect, m_SerieModuleToggle, "Serie");
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_SerieModuleToggle)
int index = InitToggle(prop);
string moduleName = "Serie " + index;
var toggle = ChartEditorHelper.MakeFoldout(ref drawRect, ref m_SerieModuleToggle, prop, moduleName, show);
if (!toggle)
{
drawRect.x = EditorGUIUtility.labelWidth - (EditorGUI.indentLevel - 1) * 15 - 2 + 20;
drawRect.width = pos.width - drawRect.x + 15;
EditorGUI.PropertyField(drawRect, type, GUIContent.none);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
else
{
var serieType = (SerieType)type.enumValueIndex;
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, show);
drawRect.x = pos.x;
drawRect.width = pos.width;
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, type);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, name);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, stack);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
drawRect.width = EditorGUIUtility.labelWidth + 10;
m_DataFoldout = EditorGUI.Foldout(drawRect, m_DataFoldout, "Data");
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_ShowJsonDataArea, ref m_JsonDataAreaText, prop);
drawRect.width = pos.width;
if (m_DataFoldout)
if (serieType == SerieType.Radar)
{
ChartEditorHelper.MakeList(ref drawRect, ref m_DataSize, m_Data);
EditorGUI.PropertyField(drawRect, m_RadarIndex);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
else
{
EditorGUI.PropertyField(drawRect, m_AxisIndex);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
if (serieType == SerieType.Line
|| serieType == SerieType.Scatter
|| serieType == SerieType.EffectScatter
|| serieType == SerieType.Radar)
{
EditorGUI.PropertyField(drawRect, m_Symbol);
drawRect.y += EditorGUI.GetPropertyHeight(m_Symbol);
}
if (serieType == SerieType.Pie)
{
EditorGUI.PropertyField(drawRect, m_RoseType);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Space);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.LabelField(drawRect, "Center");
var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15;
var tempWidth = (pos.width - startX + 35) / 2;
var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height);
var centerYRect = new Rect(centerXRect.x + tempWidth - 20, drawRect.y, tempWidth, drawRect.height);
while (m_Center.arraySize < 2)
{
m_Center.InsertArrayElementAtIndex(m_Center.arraySize);
}
EditorGUI.PropertyField(centerXRect, m_Center.GetArrayElementAtIndex(0), GUIContent.none);
EditorGUI.PropertyField(centerYRect, m_Center.GetArrayElementAtIndex(1), GUIContent.none);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height);
centerYRect = new Rect(centerXRect.x + tempWidth - 20, drawRect.y, tempWidth, drawRect.height);
EditorGUI.LabelField(drawRect, "Radius");
while (m_Radius.arraySize < 2)
{
m_Radius.InsertArrayElementAtIndex(m_Radius.arraySize);
}
EditorGUI.PropertyField(centerXRect, m_Radius.GetArrayElementAtIndex(0), GUIContent.none);
EditorGUI.PropertyField(centerYRect, m_Radius.GetArrayElementAtIndex(1), GUIContent.none);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_ClickOffset);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
EditorGUI.PropertyField(drawRect, m_LineStyle);
drawRect.y += EditorGUI.GetPropertyHeight(m_LineStyle);
EditorGUI.PropertyField(drawRect, m_AreaStyle);
drawRect.y += EditorGUI.GetPropertyHeight(m_AreaStyle);
EditorGUI.PropertyField(drawRect, m_Label, new GUIContent("Normal Label"));
drawRect.y += EditorGUI.GetPropertyHeight(m_Label);
EditorGUI.PropertyField(drawRect, m_HighlightLabel, new GUIContent("Highlight Label"));
drawRect.y += EditorGUI.GetPropertyHeight(m_HighlightLabel);
drawRect.width = EditorGUIUtility.labelWidth + 10;
m_DataFoldout[index] = EditorGUI.Foldout(drawRect, m_DataFoldout[index], "Data");
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_ShowJsonDataArea, ref m_JsonDataAreaText, prop, pos.width);
drawRect.width = pos.width;
if (m_DataFoldout[index])
{
EditorGUI.indentLevel++;
float nameWid = 76;
EditorGUI.PropertyField(new Rect(drawRect.x, drawRect.y, pos.width - nameWid - 2, pos.height), m_DataDimension);
var nameRect = new Rect(pos.width - nameWid + 14, drawRect.y, nameWid, pos.height);
var btnName = m_ShowDataName.boolValue ? "Hide Name" : "Show Name";
if (GUI.Button(nameRect, new GUIContent(btnName)))
{
m_ShowDataName.boolValue = !m_ShowDataName.boolValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
var listSize = m_Datas.arraySize;
listSize = EditorGUI.IntField(drawRect, "Size", listSize);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (listSize < 0) listSize = 0;
if (m_DataDimension.intValue < 1) m_DataDimension.intValue = 1;
int dimension = m_DataDimension.intValue;
bool showName = m_ShowDataName.boolValue;
bool showSelected = (serieType == SerieType.Pie);
if (listSize != m_Datas.arraySize)
{
while (listSize > m_Datas.arraySize)
m_Datas.InsertArrayElementAtIndex(m_Datas.arraySize);
while (listSize < m_Datas.arraySize)
m_Datas.DeleteArrayElementAtIndex(m_Datas.arraySize - 1);
}
if (listSize > 30)
{
int num = listSize > 10 ? 10 : listSize;
for (int i = 0; i < num; i++)
{
DrawDataElement(ref drawRect, dimension, m_Datas, showName, showSelected, i, pos.width);
}
if (num >= 10)
{
EditorGUI.LabelField(drawRect, "...");
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
DrawDataElement(ref drawRect, dimension, m_Datas, showName, showSelected, listSize - 1, pos.width);
}
}
else
{
for (int i = 0; i < m_Datas.arraySize; i++)
{
DrawDataElement(ref drawRect, dimension, m_Datas, showName, showSelected, i, pos.width);
}
}
EditorGUI.indentLevel--;
}
--EditorGUI.indentLevel;
}
}
private void DrawDataElement(ref Rect drawRect, int dimension, SerializedProperty m_Datas, bool showName,
bool showSelected, int index, float currentWidth)
{
var lastX = drawRect.x;
var lastWid = drawRect.width;
var lastFieldWid = EditorGUIUtility.fieldWidth;
var lastLabelWid = EditorGUIUtility.labelWidth;
var serieData = m_Datas.GetArrayElementAtIndex(index);
var sereName = serieData.FindPropertyRelative("m_Name");
var selected = serieData.FindPropertyRelative("m_Selected");
var data = serieData.FindPropertyRelative("m_Data");
var fieldCount = dimension + (showName ? 1 : 0);
if (fieldCount <= 1)
{
while (2 > data.arraySize)
data.InsertArrayElementAtIndex(data.arraySize);
SerializedProperty element = data.GetArrayElementAtIndex(1);
if (showSelected)
{
drawRect.width = drawRect.width - 18;
EditorGUI.PropertyField(drawRect, element);
drawRect.x = currentWidth - 45;
EditorGUI.PropertyField(drawRect, selected, GUIContent.none);
drawRect.x = lastX;
drawRect.width = lastWid;
}
else
{
EditorGUI.PropertyField(drawRect, element);
}
drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing;
}
else
{
EditorGUI.LabelField(drawRect, "Element " + index);
var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15;
var dataWidTotal = (currentWidth - (startX + 20.5f + 1));
var dataWid = dataWidTotal / fieldCount;
var xWid = dataWid - 4;
for (int i = 0; i < dimension; i++)
{
if (i >= data.arraySize - 1)
{
data.InsertArrayElementAtIndex(data.arraySize);
}
drawRect.x = startX + i * xWid;
drawRect.width = dataWid + 40;
SerializedProperty element = data.GetArrayElementAtIndex(dimension <= 1 ? 1 : i);
EditorGUI.PropertyField(drawRect, element, GUIContent.none);
}
if (showName)
{
drawRect.x = startX + (fieldCount - 1) * xWid;
drawRect.width = dataWid + 40;
EditorGUI.PropertyField(drawRect, sereName, GUIContent.none);
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
drawRect.x = lastX;
drawRect.width = lastWid;
EditorGUIUtility.fieldWidth = lastFieldWid;
EditorGUIUtility.labelWidth = lastLabelWid;
}
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (!m_SerieModuleToggle)
int index = InitToggle(prop);
if (!m_SerieModuleToggle[prop.propertyPath])
{
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
else
{
height += 5 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
if (m_DataFoldout)
height += 6 * EditorGUIUtility.singleLineHeight + 6 * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_LineStyle"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_AreaStyle"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Label"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_HighlightLabel"));
SerializedProperty type = prop.FindPropertyRelative("m_Type");
var serieType = (SerieType)type.enumValueIndex;
if (serieType == SerieType.Line
|| serieType == SerieType.Scatter
|| serieType == SerieType.EffectScatter
|| serieType == SerieType.Radar)
{
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Symbol"));
}
if (serieType == SerieType.Pie)
{
height += 5 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
}
if (m_DataFoldout[index])
{
SerializedProperty m_Data = prop.FindPropertyRelative("m_Data");
int num = m_Data.arraySize + 1;
if (num > 50) num = 13;
int num = m_Data.arraySize + 2;
if (num > 30) num = 14;
height += num * EditorGUIUtility.singleLineHeight + (num - 1) * EditorGUIUtility.standardVerticalSpacing;
}
if (m_ShowJsonDataArea)
{
height += EditorGUIUtility.singleLineHeight * 3 + EditorGUIUtility.standardVerticalSpacing;
height += EditorGUIUtility.singleLineHeight * 4 + EditorGUIUtility.standardVerticalSpacing;
}
return height;
}
}
private int InitToggle(SerializedProperty prop)
{
int index = 0;
var sindex = prop.propertyPath.LastIndexOf('[');
var eindex = prop.propertyPath.LastIndexOf(']');
if (sindex >= 0 && eindex >= 0)
{
var str = prop.propertyPath.Substring(sindex + 1, eindex - sindex - 1);
int.TryParse(str, out index);
}
if (index >= m_DataFoldout.Count)
{
m_DataFoldout.Add(false);
}
return index;
}
}
}

View File

@@ -0,0 +1,71 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(SerieLabel), true)]
public class SerieLabelDrawer : PropertyDrawer
{
private Dictionary<string, bool> m_SerieLabelToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_Position = prop.FindPropertyRelative("m_Position");
SerializedProperty m_Distance = prop.FindPropertyRelative("m_Distance");
SerializedProperty m_Rotate = prop.FindPropertyRelative("m_Rotate");
SerializedProperty m_Color = prop.FindPropertyRelative("m_Color");
SerializedProperty m_FontSize = prop.FindPropertyRelative("m_FontSize");
SerializedProperty m_FontStyle = prop.FindPropertyRelative("m_FontStyle");
SerializedProperty m_Line = prop.FindPropertyRelative("m_Line");
SerializedProperty m_LineWidth = prop.FindPropertyRelative("m_LineWidth");
SerializedProperty m_LineLength1 = prop.FindPropertyRelative("m_LineLength1");
SerializedProperty m_LineLength2 = prop.FindPropertyRelative("m_LineLength2");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_SerieLabelToggle, prop, null, show, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (ChartEditorHelper.IsToggle(m_SerieLabelToggle, prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Position);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Distance);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Color);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Rotate);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_FontSize);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_FontStyle);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Line);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_LineWidth);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_LineLength1);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_LineLength2);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
--EditorGUI.indentLevel;
}
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (ChartEditorHelper.IsToggle(m_SerieLabelToggle, prop))
{
height += 11 * EditorGUIUtility.singleLineHeight + 10 * EditorGUIUtility.standardVerticalSpacing;
}
else
{
height = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
return height;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d30d82b48b553451fad726478777a02e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(SerieSymbol), true)]
public class SerieSymbolDrawer : PropertyDrawer
{
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty m_Type = prop.FindPropertyRelative("m_Type");
SerializedProperty m_SizeType = prop.FindPropertyRelative("m_SizeType");
SerializedProperty m_Size = prop.FindPropertyRelative("m_Size");
SerializedProperty m_SelectedSize = prop.FindPropertyRelative("m_SelectedSize");
SerializedProperty m_DataIndex = prop.FindPropertyRelative("m_DataIndex");
SerializedProperty m_DataScale = prop.FindPropertyRelative("m_DataScale");
SerializedProperty m_SelectedDataScale = prop.FindPropertyRelative("m_SelectedDataScale");
EditorGUI.PropertyField(drawRect, m_Type, new GUIContent("Symbol Type"));
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SizeType, new GUIContent("Symbol SizeType"));
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
SerieSymbolSizeType sizeType = (SerieSymbolSizeType)m_SizeType.enumValueIndex;
switch (sizeType)
{
case SerieSymbolSizeType.Custom:
EditorGUI.PropertyField(drawRect, m_Size, new GUIContent("Symbol Size"));
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SelectedSize, new GUIContent("Symbol SelectedSize"));
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
break;
case SerieSymbolSizeType.FromData:
EditorGUI.PropertyField(drawRect, m_DataIndex, new GUIContent("Symbol DataIndex"));
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_DataScale, new GUIContent("Symbol DataScale"));
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SelectedDataScale, new GUIContent("Symbol SelectedDataScale"));
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
break;
case SerieSymbolSizeType.Callback:
break;
}
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
SerializedProperty m_SizeType = prop.FindPropertyRelative("m_SizeType");
SerieSymbolSizeType sizeType = (SerieSymbolSizeType)m_SizeType.enumValueIndex;
switch (sizeType)
{
case SerieSymbolSizeType.Custom:
return 4 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
case SerieSymbolSizeType.FromData:
return 5 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing;
case SerieSymbolSizeType.Callback:
return 4 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
}
return 4 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e0c4d3c3303994821bde654cf67d414d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -9,33 +9,18 @@ namespace XCharts
{
ReorderableList m_ColorPaletteList;
bool m_ColorPaletteFoldout;
private void InitReorderableList(SerializedProperty prop)
{
if (m_ColorPaletteList == null)
{
SerializedProperty colorPalette = prop.FindPropertyRelative("m_ColorPalette");
m_ColorPaletteList = new ReorderableList(colorPalette.serializedObject, colorPalette, false, false, true, true);
m_ColorPaletteList.elementHeight = EditorGUIUtility.singleLineHeight;
m_ColorPaletteList.drawHeaderCallback += delegate (Rect rect)
{
EditorGUI.LabelField(rect, colorPalette.displayName);
};
m_ColorPaletteList.drawElementCallback = delegate (Rect rect, int index, bool isActive, bool isFocused)
{
EditorGUI.PropertyField(rect, colorPalette.GetArrayElementAtIndex(index), true);
};
}
}
bool m_ThemeModuleToggle = false;
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
var defaultWidth = drawRect.width;
var defaultX = drawRect.x;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty m_Theme = prop.FindPropertyRelative("m_Theme");
SerializedProperty m_Font = prop.FindPropertyRelative("m_Font");
SerializedProperty m_BackgroundColor = prop.FindPropertyRelative("m_BackgroundColor");
SerializedProperty m_TextColor = prop.FindPropertyRelative("m_TextColor");
SerializedProperty m_TextColor = prop.FindPropertyRelative("m_TitleTextColor");
SerializedProperty m_SubTextColor = prop.FindPropertyRelative("m_TitleSubTextColor");
SerializedProperty m_LegendTextColor = prop.FindPropertyRelative("m_LegendTextColor");
SerializedProperty m_LegendUnableColor = prop.FindPropertyRelative("m_LegendUnableColor");
@@ -52,74 +37,298 @@ namespace XCharts
SerializedProperty m_DataZoomTextColor = prop.FindPropertyRelative("m_DataZoomTextColor");
SerializedProperty m_ColorPalette = prop.FindPropertyRelative("m_ColorPalette");
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Font);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_BackgroundColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_TextColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SubTextColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_LegendTextColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_LegendUnableColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_AxisTextColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_AxisLineColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_AxisSplitLineColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_TooltipBackgroundColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_TooltipFlagAreaColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_TooltipTextColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_TooltipLabelColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_TooltipLineColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_DataZoomLineColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_DataZoomSelectedColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_DataZoomTextColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
SerializedProperty m_CustomFont = prop.FindPropertyRelative("m_CustomFont");
SerializedProperty m_CustomBackgroundColor = prop.FindPropertyRelative("m_CustomBackgroundColor");
SerializedProperty m_CustomTextColor = prop.FindPropertyRelative("m_CustomTitleTextColor");
SerializedProperty m_CustomSubTextColor = prop.FindPropertyRelative("m_CustomTitleSubTextColor");
SerializedProperty m_CustomLegendTextColor = prop.FindPropertyRelative("m_CustomLegendTextColor");
SerializedProperty m_CustomLegendUnableColor = prop.FindPropertyRelative("m_CustomLegendUnableColor");
SerializedProperty m_CustomAxisTextColor = prop.FindPropertyRelative("m_CustomAxisTextColor");
SerializedProperty m_CustomAxisLineColor = prop.FindPropertyRelative("m_CustomAxisLineColor");
SerializedProperty m_CustomAxisSplitLineColor = prop.FindPropertyRelative("m_CustomAxisSplitLineColor");
SerializedProperty m_CustomTooltipBackgroundColor = prop.FindPropertyRelative("m_CustomTooltipBackgroundColor");
SerializedProperty m_CustomTooltipFlagAreaColor = prop.FindPropertyRelative("m_CustomTooltipFlagAreaColor");
SerializedProperty m_CustomTooltipTextColor = prop.FindPropertyRelative("m_CustomTooltipTextColor");
SerializedProperty m_CustomTooltipLabelColor = prop.FindPropertyRelative("m_CustomTooltipLabelColor");
SerializedProperty m_CustomTooltipLineColor = prop.FindPropertyRelative("m_CustomTooltipLineColor");
SerializedProperty m_CustomDataZoomLineColor = prop.FindPropertyRelative("m_CustomDataZoomLineColor");
SerializedProperty m_CustomDataZoomSelectedColor = prop.FindPropertyRelative("m_CustomDataZoomSelectedColor");
SerializedProperty m_CustomDataZoomTextColor = prop.FindPropertyRelative("m_CustomDataZoomTextColor");
SerializedProperty m_CustomColorPalette = prop.FindPropertyRelative("m_CustomColorPalette");
m_ColorPaletteFoldout = EditorGUI.Foldout(drawRect, m_ColorPaletteFoldout, "ColorPalette");
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_ColorPaletteFoldout)
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_ThemeModuleToggle, "Theme");
drawRect.x = EditorGUIUtility.labelWidth - (EditorGUI.indentLevel - 1) * 15 - 2;
drawRect.width = defaultWidth - EditorGUIUtility.labelWidth - (m_ThemeModuleToggle ? 45 : 0);
EditorGUI.PropertyField(drawRect, m_Theme, GUIContent.none);
if (m_ThemeModuleToggle)
{
EditorGUI.indentLevel++;
for (int i = 0; i < m_ColorPalette.arraySize; i++)
drawRect.x = defaultWidth - 30;
drawRect.width = 45;
if (GUI.Button(drawRect, new GUIContent("Reset", "Reset to theme default color")))
{
SerializedProperty element = m_ColorPalette.GetArrayElementAtIndex(i);
EditorGUI.PropertyField(drawRect, element);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
EditorGUI.indentLevel--;
}
m_CustomFont.objectReferenceValue = null;
m_CustomBackgroundColor.colorValue = Color.clear;
m_CustomTextColor.colorValue = Color.clear;
m_CustomSubTextColor.colorValue = Color.clear;
m_CustomLegendTextColor.colorValue = Color.clear;
m_CustomLegendUnableColor.colorValue = Color.clear;
m_CustomAxisTextColor.colorValue = Color.clear;
m_CustomAxisLineColor.colorValue = Color.clear;
m_CustomAxisSplitLineColor.colorValue = Color.clear;
m_CustomTooltipBackgroundColor.colorValue = Color.clear;
m_CustomTooltipFlagAreaColor.colorValue = Color.clear;
m_CustomTooltipTextColor.colorValue = Color.clear;
m_CustomTooltipLabelColor.colorValue = Color.clear;
m_CustomTooltipLineColor.colorValue = Color.clear;
m_CustomDataZoomLineColor.colorValue = Color.clear;
m_CustomDataZoomSelectedColor.colorValue = Color.clear;
m_CustomDataZoomTextColor.colorValue = Color.clear;
for (int i = 0; i < m_CustomColorPalette.arraySize; i++)
{
m_CustomColorPalette.GetArrayElementAtIndex(i).colorValue = Color.clear;
}
--EditorGUI.indentLevel;
ThemeInfo defaultThemeInfo = ThemeInfo.Default;
switch (m_Theme.enumValueIndex)
{
case ((int)Theme.Default): defaultThemeInfo = ThemeInfo.Default; break;
case ((int)Theme.Light): defaultThemeInfo = ThemeInfo.Light; break;
case ((int)Theme.Dark): defaultThemeInfo = ThemeInfo.Dark; break;
}
m_Font.objectReferenceValue = defaultThemeInfo.font;
m_BackgroundColor.colorValue = defaultThemeInfo.backgroundColor;
m_TextColor.colorValue = defaultThemeInfo.titleTextColor;
m_SubTextColor.colorValue = defaultThemeInfo.titleSubTextColor;
m_LegendTextColor.colorValue = defaultThemeInfo.legendTextColor;
m_LegendUnableColor.colorValue = defaultThemeInfo.legendUnableColor;
m_AxisTextColor.colorValue = defaultThemeInfo.axisTextColor;
m_AxisLineColor.colorValue = defaultThemeInfo.axisLineColor;
m_AxisSplitLineColor.colorValue = defaultThemeInfo.axisSplitLineColor;
m_TooltipBackgroundColor.colorValue = defaultThemeInfo.tooltipBackgroundColor;
m_TooltipFlagAreaColor.colorValue = defaultThemeInfo.tooltipFlagAreaColor;
m_TooltipTextColor.colorValue = defaultThemeInfo.tooltipTextColor;
m_TooltipLabelColor.colorValue = defaultThemeInfo.tooltipLabelColor;
m_TooltipLineColor.colorValue = defaultThemeInfo.tooltipLineColor;
m_DataZoomLineColor.colorValue = defaultThemeInfo.dataZoomLineColor;
m_DataZoomSelectedColor.colorValue = defaultThemeInfo.dataZoomSelectedColor;
m_DataZoomTextColor.colorValue = defaultThemeInfo.dataZoomTextColor;
for (int i = 0; i < m_ColorPalette.arraySize; i++)
{
m_ColorPalette.GetArrayElementAtIndex(i).colorValue = defaultThemeInfo.GetColor(i);
}
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
drawRect.x = defaultX;
drawRect.width = defaultWidth;
++EditorGUI.indentLevel;
EditorGUI.BeginChangeCheck();
var font =m_CustomFont.objectReferenceValue != null?m_CustomFont: m_Font;
EditorGUI.PropertyField(drawRect, font);
if (EditorGUI.EndChangeCheck())
{
m_CustomFont.objectReferenceValue = font.objectReferenceValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
var color = m_CustomBackgroundColor.colorValue != Color.clear ? m_CustomBackgroundColor : m_BackgroundColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("Background Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomBackgroundColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomTextColor.colorValue != Color.clear ? m_CustomTextColor : m_TextColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("Title Text Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomTextColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomSubTextColor.colorValue != Color.clear ? m_CustomSubTextColor : m_SubTextColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("Title SubText Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomSubTextColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomLegendTextColor.colorValue != Color.clear ? m_CustomLegendTextColor : m_LegendTextColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("LegendText Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomLegendTextColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomLegendUnableColor.colorValue != Color.clear ? m_CustomLegendUnableColor : m_LegendUnableColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("LegendUnable Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomLegendUnableColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomAxisTextColor.colorValue != Color.clear ? m_CustomAxisTextColor : m_AxisTextColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("AxisText Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomAxisTextColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomAxisLineColor.colorValue != Color.clear ? m_CustomAxisLineColor : m_AxisLineColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("AxisLine Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomAxisLineColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomAxisSplitLineColor.colorValue != Color.clear ? m_CustomAxisSplitLineColor : m_AxisSplitLineColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("AxisSplitLine Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomAxisSplitLineColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomTooltipBackgroundColor.colorValue != Color.clear ? m_CustomTooltipBackgroundColor : m_TooltipBackgroundColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("Tooltip Background Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomTooltipBackgroundColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomTooltipFlagAreaColor.colorValue != Color.clear ? m_CustomTooltipFlagAreaColor : m_TooltipFlagAreaColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("Tooltip FlagArea Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomTooltipFlagAreaColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomTooltipTextColor.colorValue != Color.clear ? m_CustomTooltipTextColor : m_TooltipTextColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("Tooltip Text Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomTooltipTextColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomTooltipLabelColor.colorValue != Color.clear ? m_CustomTooltipLabelColor : m_TooltipLabelColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("Tooltip Label Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomTooltipLabelColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomTooltipLineColor.colorValue != Color.clear ? m_CustomTooltipLineColor : m_TooltipLineColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("Tooltip Line Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomTooltipLineColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomDataZoomLineColor.colorValue != Color.clear ? m_CustomDataZoomLineColor : m_DataZoomLineColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("DataZoom Line Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomDataZoomLineColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomDataZoomSelectedColor.colorValue != Color.clear ? m_CustomDataZoomSelectedColor : m_DataZoomSelectedColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("DataZoom Selected Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomDataZoomSelectedColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomDataZoomTextColor.colorValue != Color.clear ? m_CustomDataZoomTextColor : m_DataZoomTextColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("DataZoom Text Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomDataZoomTextColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
m_ColorPaletteFoldout = EditorGUI.Foldout(drawRect, m_ColorPaletteFoldout, "ColorPalette");
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_ColorPaletteFoldout)
{
EditorGUI.indentLevel++;
for (int i = 0; i < m_ColorPalette.arraySize; i++)
{
while (i > m_CustomColorPalette.arraySize - 1)
{
m_CustomColorPalette.InsertArrayElementAtIndex(m_CustomColorPalette.arraySize);
}
var customElement = m_CustomColorPalette.GetArrayElementAtIndex(i);
color = customElement.colorValue != Color.clear ?
customElement :
m_ColorPalette.GetArrayElementAtIndex(i);
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(drawRect, color);
if (EditorGUI.EndChangeCheck())
{
customElement.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
EditorGUI.indentLevel--;
}
--EditorGUI.indentLevel;
}
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
int propertyCount = 17;
if (m_ColorPaletteFoldout)
if (!m_ThemeModuleToggle)
{
SerializedProperty m_ColorPalette = prop.FindPropertyRelative("m_ColorPalette");
propertyCount += m_ColorPalette.arraySize + 1;
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
else
{
propertyCount += 1;
float height = 0;
int propertyCount = 18;
if (m_ColorPaletteFoldout)
{
SerializedProperty m_ColorPalette = prop.FindPropertyRelative("m_ColorPalette");
propertyCount += m_ColorPalette.arraySize + 1;
}
else
{
propertyCount += 1;
}
height += propertyCount * EditorGUIUtility.singleLineHeight + (propertyCount - 1) * EditorGUIUtility.standardVerticalSpacing;
return height;
}
height += propertyCount * EditorGUIUtility.singleLineHeight + (propertyCount - 1) * EditorGUIUtility.standardVerticalSpacing;
return height;
}
}
}

View File

@@ -13,13 +13,13 @@ namespace XCharts
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty crossLabel = prop.FindPropertyRelative("m_CrossLabel");
SerializedProperty type = prop.FindPropertyRelative("m_Type");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_TooltipModuleToggle, "Tooltip", show);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_TooltipModuleToggle)
{
EditorGUI.PropertyField(drawRect, crossLabel);
EditorGUI.PropertyField(drawRect, type);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
}
@@ -27,9 +27,9 @@ namespace XCharts
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
if (m_TooltipModuleToggle)
return 2 * (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
return 2 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
else
return 1 * (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
}
}

View File

@@ -0,0 +1,19 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(XAxis), true)]
public class XAxisDrawer : AxisDrawer
{
protected override string GetDisplayName(string displayName)
{
if (displayName.StartsWith("Element"))
{
displayName = displayName.Replace("Element", "X Axis");
}
return displayName;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 723807bbaeaa64991a421011ce530266
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(YAxis), true)]
public class YAxisDrawer : AxisDrawer
{
protected override string GetDisplayName(string displayName)
{
if (displayName.StartsWith("Element"))
{
displayName = displayName.Replace("Element", "Y Axis");
}
return displayName;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6d1fca6c98f3d41fd989d0e41fbd4eb9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -10,19 +10,19 @@ namespace XCharts
public class RadarChartEditor : BaseChartEditor
{
protected SerializedProperty m_Radar;
protected bool m_RadarModuleToggle = false;
protected SerializedProperty m_Radars;
protected override void OnEnable()
{
base.OnEnable();
m_Target = (RadarChart)target;
m_Radar = serializedObject.FindProperty("m_Radar");
m_Radars = serializedObject.FindProperty("m_Radars");
}
protected override void OnEndInspectorGUI()
{
base.OnEndInspectorGUI();
EditorGUILayout.PropertyField(m_Radar, true);
EditorGUILayout.PropertyField(m_Radars, true);
}
}
}

View File

@@ -0,0 +1,23 @@
using UnityEditor;
namespace XCharts
{
/// <summary>
/// Editor class used to edit UI ScatterChart.
/// </summary>
[CustomEditor(typeof(ScatterChart), false)]
public class ScatterChartEditor : CoordinateChartEditor
{
protected override void OnEnable()
{
base.OnEnable();
m_Target = (ScatterChart)target;
}
protected override void OnEndInspectorGUI()
{
base.OnEndInspectorGUI();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3995bd8e5f80b49008624a5746622f68
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +1,6 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
public class ChartEditorHelper
{
@@ -19,14 +20,14 @@ public class ChartEditorHelper
}
public static void MakeJsonData(ref Rect drawRect, ref bool showTextArea, ref string inputString,
SerializedProperty prop)
SerializedProperty prop, float currentWidth, float diff = 0)
{
SerializedProperty stringDataProp = prop.FindPropertyRelative("m_JsonData");
SerializedProperty needParseProp = prop.FindPropertyRelative("m_DataFromJson");
float defalutX = drawRect.x;
drawRect.x = EditorGUIUtility.labelWidth + 40;
drawRect.width = EditorGUIUtility.currentViewWidth - EditorGUIUtility.labelWidth - 60;
if (GUI.Button(drawRect, new GUIContent("Parse Json", "Parse data from input json")))
drawRect.x = EditorGUIUtility.labelWidth + 14 + diff;
drawRect.width = currentWidth - EditorGUIUtility.labelWidth - diff;
if (GUI.Button(drawRect, new GUIContent("Parse JsonData", "Parse data from input json")))
{
showTextArea = !showTextArea;
bool needParse = !showTextArea;
@@ -40,15 +41,15 @@ public class ChartEditorHelper
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (showTextArea)
{
drawRect.width = EditorGUIUtility.currentViewWidth - drawRect.x - 20;
drawRect.height = EditorGUIUtility.singleLineHeight * 3;
drawRect.width = currentWidth;
drawRect.height = EditorGUIUtility.singleLineHeight * 4;
inputString = EditorGUI.TextArea(drawRect, inputString);
drawRect.y += EditorGUIUtility.singleLineHeight * 3 + EditorGUIUtility.standardVerticalSpacing;
drawRect.y += EditorGUIUtility.singleLineHeight * 4 + EditorGUIUtility.standardVerticalSpacing;
drawRect.height = EditorGUIUtility.singleLineHeight;
}
}
public static void MakeFoldout(ref Rect drawRect, ref bool moduleToggle, string content,
public static bool MakeFoldout(ref Rect drawRect, ref bool moduleToggle, string content,
SerializedProperty prop = null, bool bold = true)
{
float defaultWidth = drawRect.width;
@@ -56,13 +57,51 @@ public class ChartEditorHelper
drawRect.width = EditorGUIUtility.labelWidth;
moduleToggle = EditorGUI.Foldout(drawRect, moduleToggle, content, bold ? foldoutStyle : EditorStyles.foldout);
drawRect.x = EditorGUIUtility.labelWidth - (EditorGUI.indentLevel - 1) * 15 - 2;
drawRect.width = EditorGUIUtility.currentViewWidth - EditorGUIUtility.labelWidth - 70;
drawRect.width = 40;
if (prop != null)
{
EditorGUI.PropertyField(drawRect, prop, GUIContent.none);
}
drawRect.width = defaultWidth;
drawRect.x = defaultX;
return moduleToggle;
}
public static bool MakeFoldout(ref Rect drawRect, ref Dictionary<string, bool> moduleToggle, SerializedProperty prop,
string moduleName, SerializedProperty showProp = null, bool bold = true)
{
var key = prop.propertyPath;
if (!moduleToggle.ContainsKey(key))
{
moduleToggle.Add(key, false);
}
var toggle = moduleToggle[key];
float defaultWidth = drawRect.width;
float defaultX = drawRect.x;
drawRect.width = EditorGUIUtility.labelWidth;
var displayName = string.IsNullOrEmpty(moduleName) ? prop.displayName : moduleName;
toggle = EditorGUI.Foldout(drawRect, toggle, displayName, bold ? foldoutStyle : EditorStyles.foldout);
if (moduleToggle[key] != toggle)
{
moduleToggle[key] = toggle;
}
drawRect.x = EditorGUIUtility.labelWidth - (EditorGUI.indentLevel - 1) * 15 - 2;
if (showProp != null)
{
if (showProp.propertyType == SerializedPropertyType.Boolean)
{
drawRect.width = 40;
}
else
{
drawRect.width = defaultWidth - drawRect.x + 15;
}
EditorGUI.PropertyField(drawRect, showProp, GUIContent.none);
}
drawRect.width = defaultWidth;
drawRect.x = defaultX;
return toggle;
}
public static void MakeList(ref Rect drawRect, ref int listSize, SerializedProperty listProp, SerializedProperty large = null)
@@ -80,14 +119,14 @@ public class ChartEditorHelper
while (listSize < listProp.arraySize)
listProp.DeleteArrayElementAtIndex(listProp.arraySize - 1);
}
if (listSize > 50)
if (listSize > 30)
{
SerializedProperty element;
int num = listSize > 10 ? 10 : listSize;
for (int i = 0; i < num; i++)
{
element = listProp.GetArrayElementAtIndex(i);
EditorGUI.PropertyField(drawRect, element);
EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + i));
drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing;
}
if (num >= 10)
@@ -95,7 +134,7 @@ public class ChartEditorHelper
EditorGUI.LabelField(drawRect, "...");
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
element = listProp.GetArrayElementAtIndex(listSize - 1);
EditorGUI.PropertyField(drawRect, element);
EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + (listSize - 1)));
drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing;
}
}
@@ -104,10 +143,47 @@ public class ChartEditorHelper
for (int i = 0; i < listProp.arraySize; i++)
{
SerializedProperty element = listProp.GetArrayElementAtIndex(i);
EditorGUI.PropertyField(drawRect, element);
EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + i));
drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing;
}
}
EditorGUI.indentLevel--;
}
public static int InitModuleToggle(ref List<bool> moduleToggle, SerializedProperty prop)
{
int index = 0;
var temp = prop.displayName.Split(' ');
if (temp == null || temp.Length < 2)
{
index = 0;
}
else
{
int.TryParse(temp[1], out index);
}
if (index >= moduleToggle.Count)
{
moduleToggle.Add(false);
}
return index;
}
public static int GetIndexFromPath(SerializedProperty prop)
{
int index = 0;
var sindex = prop.propertyPath.LastIndexOf('[');
var eindex = prop.propertyPath.LastIndexOf(']');
if (sindex >= 0 && eindex >= 0)
{
var str = prop.propertyPath.Substring(sindex + 1, eindex - sindex - 1);
int.TryParse(str, out index);
}
return index;
}
public static bool IsToggle(Dictionary<string, bool> toggle, SerializedProperty prop)
{
return toggle.ContainsKey(prop.propertyPath) && toggle[prop.propertyPath] == true;
}
}

View File

@@ -4,193 +4,179 @@ using UnityEngine.UI;
namespace XCharts
{
[AddComponentMenu("XCharts/BarChart", 13)]
[AddComponentMenu("XCharts/BarChart", 14)]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
[DisallowMultipleComponent]
public class BarChart : CoordinateChart
{
[System.Serializable]
public class Bar
{
[SerializeField] private bool m_InSameBar;
[SerializeField] private float m_BarWidth = 0.7f;
[SerializeField] private float m_Space;
public bool inSameBar { get { return m_InSameBar; } set { m_InSameBar = value; } }
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();
[SerializeField] private Bar m_Bar = Bar.defaultBar;
public Bar bar { get { return m_Bar; } }
protected override void DrawChart(VertexHelper vh)
#if UNITY_EDITOR
protected override void Reset()
{
base.DrawChart(vh);
if (m_YAxis.type == Axis.AxisType.Category)
base.Reset();
m_Bar = Bar.defaultBar;
m_Title.text = "BarChart";
m_Tooltip.type = Tooltip.Type.Shadow;
RemoveData();
AddSerie("serie1", SerieType.Line);
for (int i = 0; i < 5; i++)
{
var stackSeries = m_Series.GetStackSeries();
int seriesCount = stackSeries.Count;
float scaleWid = m_YAxis.GetDataWidth(coordinateHig, m_DataZoom);
float barWid = m_Bar.barWidth > 1 ? m_Bar.barWidth : scaleWid * m_Bar.barWidth;
float offset = m_Bar.inSameBar ?
(scaleWid - barWid - m_Bar.space * (seriesCount - 1)) / 2 :
(scaleWid - barWid * seriesCount - m_Bar.space * (seriesCount - 1)) / 2;
int serieCount = 0;
for (int j = 0; j < seriesCount; j++)
AddXAxisData("x" + (i + 1));
AddData(0, Random.Range(10, 90));
}
}
#endif
private void DrawYBarSerie(VertexHelper vh, int serieIndex, int stackCount,
Serie serie, Color color, ref List<float> seriesHig)
{
if (!IsActive(serie.name)) return;
var xAxis = m_XAxises[serie.axisIndex];
var yAxis = m_YAxises[serie.axisIndex];
if (!yAxis.show) yAxis = m_YAxises[(serie.axisIndex + 1) % m_YAxises.Count];
float scaleWid = yAxis.GetDataWidth(coordinateHig, m_DataZoom);
float barWid = m_Bar.barWidth > 1 ? m_Bar.barWidth : scaleWid * m_Bar.barWidth;
float offset = m_Bar.inSameBar ?
(scaleWid - barWid - m_Bar.space * (stackCount - 1)) / 2 :
(scaleWid - barWid * stackCount - m_Bar.space * (stackCount - 1)) / 2;
int maxCount = maxShowDataNumber > 0 ?
(maxShowDataNumber > serie.yData.Count ? serie.yData.Count : maxShowDataNumber)
: serie.yData.Count;
if (seriesHig.Count < minShowDataNumber)
{
for (int i = 0; i < minShowDataNumber; i++)
{
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.IsActive(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 value = serie.data[i];
float pX = seriesCurrHig[i] + zeroX + m_Coordinate.tickness;
float pY = coordinateY + i * scaleWid;
if (!m_YAxis.boundaryGap) pY -= scaleWid / 2;
float barHig = (minValue > 0 ? value - minValue : value)
/ (maxValue - minValue) * coordinateWid;
float space = m_Bar.inSameBar ? offset :
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)
{
if (m_Tooltip.crossLabel)
{
Vector3 sp = new Vector2(m_Tooltip.pointerPos.x, zeroY);
Vector3 ep = new Vector2(m_Tooltip.pointerPos.x, zeroY + coordinateHig);
DrawSplitLine(vh, false, Axis.SplitLineType.Dashed, sp, ep, m_ThemeInfo.tooltipLineColor);
float splitWidth = m_YAxis.GetSplitWidth(coordinateHig, m_DataZoom);
float pY = zeroY + (m_Tooltip.dataIndex - 1) * splitWidth +
(m_YAxis.boundaryGap ? splitWidth / 2 : 0);
sp = new Vector2(coordinateX, pY);
ep = new Vector2(coordinateX + coordinateWid, pY);
DrawSplitLine(vh, true, Axis.SplitLineType.Dashed, sp, ep, m_ThemeInfo.tooltipLineColor);
}
else
{
float tooltipSplitWid = scaleWid < 1 ? 1 : scaleWid;
float pX = coordinateX + coordinateWid;
float pY = coordinateY + scaleWid * (m_Tooltip.dataIndex - 1) -
(m_YAxis.boundaryGap ? 0 : scaleWid / 2);
Vector3 p1 = new Vector3(coordinateX, pY);
Vector3 p2 = new Vector3(coordinateX, 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);
}
seriesHig.Add(0);
}
}
else
for (int i = minShowDataNumber; i < maxCount; i++)
{
var stackSeries = m_Series.GetStackSeries();
int seriesCount = stackSeries.Count;
float scaleWid = m_XAxis.GetDataWidth(coordinateWid, m_DataZoom);
float barWid = m_Bar.barWidth > 1 ? m_Bar.barWidth : scaleWid * m_Bar.barWidth;
float offset = m_Bar.inSameBar ?
(scaleWid - barWid - m_Bar.space * (seriesCount - 1)) / 2 :
(scaleWid - barWid * seriesCount - m_Bar.space * (seriesCount - 1)) / 2;
int serieCount = 0;
for (int j = 0; j < seriesCount; j++)
if (i >= seriesHig.Count)
{
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.IsActive(serie.name)) continue;
Color color = m_ThemeInfo.GetColor(serieCount);
List<float> showData = serie.GetData(m_DataZoom);
int maxCount = maxShowDataNumber > 0 ?
(maxShowDataNumber > showData.Count ? showData.Count : maxShowDataNumber)
: showData.Count;
for (int i = minShowDataNumber; i < maxCount; i++)
{
if (!seriesCurrHig.ContainsKey(i))
{
seriesCurrHig[i] = 0;
}
float value = showData[i];
float pX = zeroX + i * scaleWid;
if (!m_XAxis.boundaryGap) pX -= scaleWid / 2;
float pY = seriesCurrHig[i] + zeroY + m_Coordinate.tickness;
float barHig = (minValue > 0 ? value - minValue : value)
/ (maxValue - minValue) * coordinateHig;
seriesCurrHig[i] += barHig;
float space = m_Bar.inSameBar ? offset :
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++;
}
}
seriesHig.Add(0);
}
if (m_Tooltip.show && m_Tooltip.dataIndex > 0)
float value = serie.yData[i];
float pX = seriesHig[i] + coordinateX + xAxis.zeroXOffset + yAxis.axisLine.width;
float pY = coordinateY + +i * scaleWid;
if (!yAxis.boundaryGap) pY -= scaleWid / 2;
float barHig = (xAxis.minValue > 0 ? value - xAxis.minValue : value)
/ (xAxis.maxValue - xAxis.minValue) * coordinateWid;
float space = m_Bar.inSameBar ? offset :
offset + serieIndex * (barWid + m_Bar.space);
seriesHig[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 ((m_Tooltip.show && m_Tooltip.IsSelected(i))
|| serie.data[i].highlighted
|| serie.highlighted)
{
if (m_Tooltip.crossLabel)
{
Vector3 sp = new Vector2(zeroX, m_Tooltip.pointerPos.y);
Vector3 ep = new Vector2(zeroX + coordinateWid, m_Tooltip.pointerPos.y);
DrawSplitLine(vh, true, Axis.SplitLineType.Dashed, sp, ep, m_ThemeInfo.tooltipLineColor);
float splitWidth = m_XAxis.GetSplitWidth(coordinateWid, m_DataZoom);
float px = zeroX + (m_Tooltip.dataIndex - 1) * splitWidth
+ (m_XAxis.boundaryGap ? splitWidth / 2 : 0);
sp = new Vector2(px, coordinateY);
ep = new Vector2(px, coordinateY + coordinateHig);
DrawSplitLine(vh, false, Axis.SplitLineType.Dashed, sp, ep, m_ThemeInfo.tooltipLineColor);
}
else
{
float tooltipSplitWid = scaleWid < 1 ? 1 : scaleWid;
float pX = coordinateX + scaleWid * (m_Tooltip.dataIndex - 1) -
(m_XAxis.boundaryGap ? 0 : scaleWid / 2);
float pY = coordinateY + coordinateHig;
Vector3 p1 = new Vector3(pX, coordinateY);
Vector3 p2 = new Vector3(pX, pY);
Vector3 p3 = new Vector3(pX + tooltipSplitWid, pY);
Vector3 p4 = new Vector3(pX + tooltipSplitWid, coordinateY);
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, m_ThemeInfo.tooltipFlagAreaColor);
}
color *= 1.05f;
}
if (serie.show)
{
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, color);
}
}
}
private void DrawXBarSerie(VertexHelper vh, int serieIndex, int stackCount,
Serie serie, Color color, ref List<float> seriesHig)
{
if (!IsActive(serie.name)) return;
List<float> showData = serie.GetYDataList(m_DataZoom);
var yAxis = m_YAxises[serie.axisIndex];
var xAxis = m_XAxises[serie.axisIndex];
if (!xAxis.show) xAxis = m_XAxises[(serie.axisIndex + 1) % m_XAxises.Count];
float scaleWid = xAxis.GetDataWidth(coordinateWid, m_DataZoom);
float barWid = m_Bar.barWidth > 1 ? m_Bar.barWidth : scaleWid * m_Bar.barWidth;
float offset = m_Bar.inSameBar ?
(scaleWid - barWid - m_Bar.space * (stackCount - 1)) / 2 :
(scaleWid - barWid * stackCount - m_Bar.space * (stackCount - 1)) / 2;
int maxCount = maxShowDataNumber > 0 ?
(maxShowDataNumber > showData.Count ? showData.Count : maxShowDataNumber)
: showData.Count;
if (seriesHig.Count < minShowDataNumber)
{
for (int i = 0; i < minShowDataNumber; i++)
{
seriesHig.Add(0);
}
}
for (int i = minShowDataNumber; i < maxCount; i++)
{
if (i >= seriesHig.Count)
{
seriesHig.Add(0);
}
float value = showData[i];
float pX = coordinateX + i * scaleWid;
float zeroY = coordinateY + yAxis.zeroYOffset;
if (!xAxis.boundaryGap) pX -= scaleWid / 2;
float pY = seriesHig[i] + zeroY + xAxis.axisLine.width;
float barHig = (yAxis.minValue > 0 ? value - yAxis.minValue : value)
/ (yAxis.maxValue - yAxis.minValue) * coordinateHig;
seriesHig[i] += barHig;
float space = m_Bar.inSameBar ? offset :
offset + serieIndex * (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 ((m_Tooltip.show && m_Tooltip.IsSelected(i))
|| serie.data[i].highlighted
|| serie.highlighted)
{
color *= 1.05f;
}
if (serie.show)
{
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, color);
}
}
}
private HashSet<string> serieNameSet = new HashSet<string>();
private Dictionary<int, List<Serie>> stackSeries = new Dictionary<int, List<Serie>>();
private List<float> seriesCurrHig = new List<float>();
protected override void DrawChart(VertexHelper vh)
{
base.DrawChart(vh);
bool yCategory = m_YAxises[0].IsCategory() || m_YAxises[1].IsCategory();
m_Series.GetStackSeries(ref stackSeries);
int seriesCount = stackSeries.Count;
int serieNameCount = -1;
serieNameSet.Clear();
for (int j = 0; j < seriesCount; j++)
{
var serieList = stackSeries[j];
seriesCurrHig.Clear();
if (seriesCurrHig.Capacity != serieList[0].dataCount)
{
seriesCurrHig.Capacity = serieList[0].dataCount;
}
for (int n = 0; n < serieList.Count; n++)
{
Serie serie = serieList[n];
if (string.IsNullOrEmpty(serie.name)) serieNameCount++;
else if (!serieNameSet.Contains(serie.name))
{
serieNameSet.Add(serie.name);
serieNameCount++;
}
Color color = m_ThemeInfo.GetColor(serieNameCount);
if (yCategory) DrawYBarSerie(vh, j, seriesCount, serie, color, ref seriesCurrHig);
else DrawXBarSerie(vh, j, seriesCount, serie, color, ref seriesCurrHig);
}
}
if (yCategory) DrawYTooltipIndicator(vh);
else DrawXTooltipIndicator(vh);
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3be5f1d3b129a47dd8e41cffe3b8e428
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,721 @@
using System.Net.Mime;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace XCharts
{
/// <summary>
/// The axis in rectangular coordinate.
/// 直角坐标系的坐标轴组件。
/// </summary>
[System.Serializable]
public class Axis : JsonDataSupport, IEquatable<Axis>
{
/// <summary>
/// the type of axis.
/// 坐标轴类型。
/// </summary>
public enum AxisType
{
/// <summary>
/// Numerical axis, suitable for continuous data.
/// 数值轴,适用于连续数据。
/// </summary>
Value,
/// <summary>
/// Category axis, suitable for discrete category data. Data should only be set via data for this type.
/// 类目轴,适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。
/// </summary>
Category
}
/// <summary>
/// the type of axis min and max value.
/// 坐标轴最大最小刻度显示类型。
/// </summary>
public enum AxisMinMaxType
{
/// <summary>
/// 0 - maximum.
/// 0-最大值。
/// </summary>
Default,
/// <summary>
/// minimum - maximum.
/// 最小值-最大值。
/// </summary>
MinMax,
/// <summary>
/// Customize the minimum and maximum.
/// 自定义最小值最大值。
/// </summary>
Custom
}
/// <summary>
/// the type of split line.
/// 分割线类型
/// </summary>
public enum SplitLineType
{
/// <summary>
/// 不显示分割线
/// </summary>
None,
/// <summary>
/// 实线
/// </summary>
Solid,
/// <summary>
/// 破折线
/// </summary>
Dashed,
/// <summary>
/// 虚线
/// </summary>
Dotted
}
[SerializeField] protected bool m_Show = true;
[SerializeField] protected AxisType m_Type;
[SerializeField] protected AxisMinMaxType m_MinMaxType;
[SerializeField] protected int m_Min;
[SerializeField] protected int m_Max;
[SerializeField] protected int m_SplitNumber = 5;
[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 AxisLine m_AxisLine = AxisLine.defaultAxisLine;
[SerializeField] protected AxisName m_AxisName = AxisName.defaultAxisName;
[SerializeField] protected AxisTick m_AxisTick = AxisTick.defaultTick;
[SerializeField] protected AxisLabel m_AxisLabel = AxisLabel.defaultAxisLabel;
[SerializeField] protected AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea;
/// <summary>
/// Set this to false to prevent the axis from showing.
/// 是否显示坐标轴。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// the type of axis.
/// 坐标轴类型。
/// </summary>
public AxisType type { get { return m_Type; } set { m_Type = value; } }
/// <summary>
/// the type of axis minmax.
/// 坐标轴刻度最大最小值显示类型。
/// </summary>
public AxisMinMaxType minMaxType { get { return m_MinMaxType; } set { m_MinMaxType = value; } }
/// <summary>
/// The minimun value of axis.
/// 设定的坐标轴刻度最小值当minMaxType为Custom时有效。
/// </summary>
public int min { get { return m_Min; } set { m_Min = value; } }
/// <summary>
/// The maximum value of axis.
/// 设定的坐标轴刻度最大值当minMaxType为Custom时有效。
/// </summary>
public int max { get { return m_Max; } set { m_Max = value; } }
/// <summary>
/// Number of segments that the axis is split into.
/// 坐标轴的分割段数。
/// </summary>
public int splitNumber { get { return m_SplitNumber; } set { m_SplitNumber = value; } }
/// <summary>
/// showSplitLineSet this to false to prevent the splitLine from showing. value type axes are shown by default, while category type axes are hidden.
/// 是否显示分隔线。默认数值轴显示,类目轴不显示。
/// </summary>
public bool showSplitLine { get { return m_ShowSplitLine; } set { m_ShowSplitLine = value; } }
/// <summary>
/// the type of split line.
/// 分割线类型。
/// </summary>
public SplitLineType splitLineType { get { return m_SplitLineType; } set { m_SplitLineType = value; } }
/// <summary>
/// The boundary gap on both sides of a coordinate axis.
/// 坐标轴两边是否留白。
/// </summary>
public bool boundaryGap { get { return m_BoundaryGap; } set { m_BoundaryGap = value; } }
/// <summary>
/// Category data, available in type: 'Category' axis.
/// 类目数据在类目轴type: 'category')中有效。
/// </summary>
public List<string> data { get { return m_Data; } }
/// <summary>
/// axis Line.
/// 坐标轴轴线。
/// </summary>
public AxisLine axisLine { get { return m_AxisLine; } set { m_AxisLine = value; } }
/// <summary>
/// axis name.
/// 坐标轴名称。
/// </summary>
public AxisName axisName { get { return m_AxisName; } set { m_AxisName = value; } }
/// <summary>
/// axis tick.
/// 坐标轴刻度。
/// </summary>
public AxisTick axisTick { get { return m_AxisTick; } set { m_AxisTick = value; } }
/// <summary>
/// axis label.
/// 坐标轴刻度标签。
/// </summary>
public AxisLabel axisLabel { get { return m_AxisLabel; } set { m_AxisLabel = value; } }
/// <summary>
/// axis split area.
/// 坐标轴分割区域。
/// </summary>
public AxisSplitArea splitArea { get { return m_SplitArea; } set { m_SplitArea = value; } }
/// <summary>
/// the axis label text list.
/// 坐标轴刻度标签的Text列表。
/// </summary>
public List<Text> axisLabelTextList { get { return m_AxisLabelTextList; } set { m_AxisLabelTextList = value; } }
/// <summary>
/// the current minimun value.
/// 当前最小值。
/// </summary>
public float minValue { get; set; }
/// <summary>
/// the current maximum value.
/// 当前最大值。
/// </summary>
public float maxValue { get; set; }
/// <summary>
/// the x offset of zero position.
/// 坐标轴原点在X轴的偏移。
/// </summary>
public float zeroXOffset { get; set; }
/// <summary>
/// the y offset of zero position.
/// 坐标轴原点在Y轴的偏移。
/// </summary>
public float zeroYOffset { get; set; }
private int filterStart;
private int filterEnd;
private List<string> filterData;
private List<Text> m_AxisLabelTextList = new List<Text>();
private GameObject m_TooltipLabel;
private Text m_TooltipLabelText;
private RectTransform m_TooltipLabelRect;
public void Copy(Axis other)
{
m_Show = other.show;
m_Type = other.type;
m_Min = other.min;
m_Max = other.max;
m_SplitNumber = other.splitNumber;
m_ShowSplitLine = other.showSplitLine;
m_SplitLineType = other.splitLineType;
m_BoundaryGap = other.boundaryGap;
m_AxisName.Copy(other.axisName);
m_AxisLabel.Copy(other.axisLabel);
m_Data.Clear();
foreach (var d in other.data) m_Data.Add(d);
}
/// <summary>
/// 清空类目数据
/// </summary>
public void ClearData()
{
m_Data.Clear();
}
/// <summary>
/// 当前坐标轴是否时类目轴
/// </summary>
/// <returns></returns>
public bool IsCategory()
{
return type == AxisType.Category;
}
/// <summary>
/// 当前坐标轴是否时数值轴
/// </summary>
/// <returns></returns>
public bool IsValue()
{
return type == AxisType.Value;
}
/// <summary>
/// 添加一个类目到类目数据列表
/// </summary>
/// <param name="category"></param>
/// <param name="maxDataNumber"></param>
public void AddData(string category, int maxDataNumber)
{
if (maxDataNumber > 0)
{
while (m_Data.Count > maxDataNumber) m_Data.RemoveAt(0);
}
m_Data.Add(category);
}
/// <summary>
/// 获得在dataZoom范围内指定索引的类目数据
/// </summary>
/// <param name="index">类目数据索引</param>
/// <param name="dataZoom">区域缩放</param>
/// <returns></returns>
public string GetData(int index, DataZoom dataZoom)
{
var showData = GetDataList(dataZoom);
if (index >= 0 && index < showData.Count)
return showData[index];
else
return "";
}
/// <summary>
/// 获得指定区域缩放的类目数据列表
/// </summary>
/// <param name="dataZoom">区域缩放</param>
/// <returns></returns>
public List<string> GetDataList(DataZoom dataZoom)
{
if (dataZoom != null && dataZoom.show)
{
var startIndex = (int)((data.Count - 1) * dataZoom.start / 100);
var endIndex = (int)((data.Count - 1) * dataZoom.end / 100);
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
if (filterData == null || filterData.Count != count)
{
UpdateFilterData(dataZoom);
}
return filterData;
}
else
{
return m_Data;
}
}
/// <summary>
/// 更新dataZoom对应的类目数据列表
/// </summary>
/// <param name="dataZoom"></param>
public void UpdateFilterData(DataZoom dataZoom)
{
if (dataZoom != null && dataZoom.show)
{
var startIndex = (int)((data.Count - 1) * dataZoom.start / 100);
var endIndex = (int)((data.Count - 1) * dataZoom.end / 100);
if (startIndex != filterStart || endIndex != filterEnd)
{
filterStart = startIndex;
filterEnd = endIndex;
if (m_Data.Count > 0)
{
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
filterData = m_Data.GetRange(startIndex, count);
}
else
{
filterData = m_Data;
}
}
else if (endIndex == 0)
{
filterData = new List<string>();
}
}
}
/// <summary>
/// 获得分割段数
/// </summary>
/// <param name="dataZoom"></param>
/// <returns></returns>
public int GetSplitNumber(DataZoom dataZoom)
{
if (type == AxisType.Value) return m_SplitNumber;
int dataCount = GetDataList(dataZoom).Count;
if (dataCount > 2 * m_SplitNumber || dataCount <= 0)
return m_SplitNumber;
else
return dataCount;
}
/// <summary>
/// 获得分割段的宽度
/// </summary>
/// <param name="coordinateWidth"></param>
/// <param name="dataZoom"></param>
/// <returns></returns>
public float GetSplitWidth(float coordinateWidth, DataZoom dataZoom)
{
return coordinateWidth / (m_BoundaryGap ? GetSplitNumber(dataZoom) : GetSplitNumber(dataZoom) - 1);
}
/// <summary>
/// 获得类目数据个数
/// </summary>
/// <param name="dataZoom"></param>
/// <returns></returns>
public int GetDataNumber(DataZoom dataZoom)
{
return GetDataList(dataZoom).Count;
}
/// <summary>
/// 获得一个类目数据在坐标系中代表的宽度
/// </summary>
/// <param name="coordinateWidth"></param>
/// <param name="dataZoom"></param>
/// <returns></returns>
public float GetDataWidth(float coordinateWidth, DataZoom dataZoom)
{
var dataCount = GetDataNumber(dataZoom);
return coordinateWidth / (m_BoundaryGap ? dataCount : dataCount - 1);
}
private Dictionary<float, string> _cacheValue2str = new Dictionary<float, string>();
/// <summary>
/// 获得标签显示的名称
/// </summary>
/// <param name="index"></param>
/// <param name="minValue"></param>
/// <param name="maxValue"></param>
/// <param name="dataZoom"></param>
/// <returns></returns>
public string GetLabelName(int index, float minValue, float maxValue, DataZoom dataZoom)
{
if (m_Type == AxisType.Value)
{
float value = (minValue + (maxValue - minValue) * index / (GetSplitNumber(dataZoom) - 1));
if (_cacheValue2str.ContainsKey(value)) return _cacheValue2str[value];
else
{
if (value - (int)value == 0)
_cacheValue2str[value] = (value).ToString();
else
_cacheValue2str[value] = (value).ToString("f1");
return _cacheValue2str[value];
}
}
var showData = GetDataList(dataZoom);
int dataCount = showData.Count;
if (dataCount <= 0) return "";
if (index == GetSplitNumber(dataZoom) - 1 && !m_BoundaryGap)
{
return showData[dataCount - 1];
}
else
{
float rate = dataCount / GetSplitNumber(dataZoom);
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 showData[newIndex];
}
}
/// <summary>
/// 获得分割线条数
/// </summary>
/// <param name="dataZoom"></param>
/// <returns></returns>
public int GetScaleNumber(DataZoom dataZoom)
{
if (type == AxisType.Value)
{
return m_BoundaryGap ? m_SplitNumber + 1 : m_SplitNumber;
}
else
{
var showData = GetDataList(dataZoom);
int dataCount = showData.Count;
if (dataCount > 2 * splitNumber || dataCount <= 0)
return m_BoundaryGap ? m_SplitNumber + 1 : m_SplitNumber;
else
return m_BoundaryGap ? dataCount + 1 : dataCount;
}
}
/// <summary>
/// 获得分割段宽度
/// </summary>
/// <param name="coordinateWidth"></param>
/// <param name="dataZoom"></param>
/// <returns></returns>
public float GetScaleWidth(float coordinateWidth, DataZoom dataZoom)
{
int num = GetScaleNumber(dataZoom) - 1;
if (num <= 0) num = 1;
return coordinateWidth / num;
}
/// <summary>
/// 更新刻度标签文字
/// </summary>
/// <param name="dataZoom"></param>
public void UpdateLabelText(DataZoom dataZoom)
{
for (int i = 0; i < axisLabelTextList.Count; i++)
{
if (axisLabelTextList[i] != null)
{
axisLabelTextList[i].text = GetLabelName(i, minValue, maxValue, dataZoom);
}
}
}
public void SetTooltipLabel(GameObject label)
{
m_TooltipLabel = label;
m_TooltipLabelRect = label.GetComponent<RectTransform>();
m_TooltipLabelText = label.GetComponentInChildren<Text>();
m_TooltipLabel.SetActive(true);
}
public void SetTooltipLabelColor(Color bgColor, Color textColor)
{
m_TooltipLabel.GetComponent<Image>().color = bgColor;
m_TooltipLabelText.color = textColor;
}
public void SetTooltipLabelActive(bool flag)
{
if (m_TooltipLabel && m_TooltipLabel.activeInHierarchy != flag)
{
m_TooltipLabel.SetActive(flag);
}
}
public void UpdateTooptipLabelText(string text)
{
if (m_TooltipLabelText)
{
m_TooltipLabelText.text = text;
m_TooltipLabelRect.sizeDelta = new Vector2(m_TooltipLabelText.preferredWidth + 8,
m_TooltipLabelText.preferredHeight + 8);
}
}
public void UpdateTooltipLabelPos(Vector2 pos)
{
if (m_TooltipLabel)
{
m_TooltipLabel.transform.localPosition = pos;
}
}
/// <summary>
/// 调整最大最小值
/// </summary>
/// <param name="minValue"></param>
/// <param name="maxValue"></param>
public void AdjustMinMaxValue(ref int minValue, ref int maxValue)
{
if (minMaxType == Axis.AxisMinMaxType.Custom)
{
if (min != 0 || max != 0)
{
minValue = min;
maxValue = max;
}
}
else
{
switch (minMaxType)
{
case Axis.AxisMinMaxType.Default:
if (minValue > 0 && maxValue > 0)
{
minValue = 0;
maxValue = ChartHelper.GetMaxDivisibleValue(maxValue);
}
else if (minValue < 0 && maxValue < 0)
{
minValue = ChartHelper.GetMinDivisibleValue(minValue);
maxValue = 0;
}
else
{
minValue = ChartHelper.GetMinDivisibleValue(minValue);
maxValue = ChartHelper.GetMaxDivisibleValue(maxValue);
}
break;
case Axis.AxisMinMaxType.MinMax:
minValue = ChartHelper.GetMinDivisibleValue(minValue);
maxValue = ChartHelper.GetMaxDivisibleValue(maxValue);
break;
}
}
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
else if (obj is Axis)
{
return Equals((Axis)obj);
}
else
{
return false;
}
}
public bool Equals(Axis other)
{
if (ReferenceEquals(null, other))
{
return false;
}
return show == other.show &&
type == other.type &&
min == other.min &&
max == other.max &&
splitNumber == other.splitNumber &&
showSplitLine == other.showSplitLine &&
m_AxisLabel.Equals(other.axisLabel) &&
splitLineType == other.splitLineType &&
boundaryGap == other.boundaryGap &&
axisName.Equals(other.axisName) &&
ChartHelper.IsValueEqualsList<string>(m_Data, other.data);
}
public static bool operator ==(Axis left, Axis right)
{
if (ReferenceEquals(left, null) && ReferenceEquals(right, null))
{
return true;
}
else if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
{
return false;
}
return Equals(left, right);
}
public static bool operator !=(Axis left, Axis right)
{
return !(left == right);
}
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);
}
}
/// <summary>
/// The x axis in cartesian(rectangular) coordinate. a grid component can place at most 2 x axis,
/// one on the bottom and another on the top.
/// <para>直角坐标系 grid 中的 x 轴,单个 grid 组件最多只能放上下两个 x 轴。</para>
/// </summary>
[System.Serializable]
public class XAxis : Axis
{
public XAxis Clone()
{
var axis = new XAxis();
axis.show = show;
axis.type = type;
axis.min = min;
axis.max = max;
axis.splitNumber = splitNumber;
axis.showSplitLine = showSplitLine;
axis.splitLineType = splitLineType;
axis.boundaryGap = boundaryGap;
axis.axisName.Copy(axisName);
axis.axisLabel.Copy(axisLabel);
axis.data.Clear();
foreach (var d in data) axis.data.Add(d);
return axis;
}
public static XAxis defaultXAxis
{
get
{
var axis = new XAxis
{
m_Show = true,
m_Type = AxisType.Category,
m_Min = 0,
m_Max = 0,
m_SplitNumber = 5,
m_ShowSplitLine = false,
m_SplitLineType = SplitLineType.Dashed,
m_BoundaryGap = true,
m_Data = new List<string>()
{
"x1","x2","x3","x4","x5"
}
};
return axis;
}
}
}
/// <summary>
/// The x axis in cartesian(rectangular) coordinate. a grid component can place at most 2 x axis,
/// one on the bottom and another on the top.
/// <para>直角坐标系 grid 中的 y 轴,单个 grid 组件最多只能放左右两个 y 轴</para>
/// </summary>
[System.Serializable]
public class YAxis : Axis
{
public YAxis Clone()
{
var axis = new YAxis();
axis.show = show;
axis.type = type;
axis.min = min;
axis.max = max;
axis.splitNumber = splitNumber;
axis.showSplitLine = showSplitLine;
axis.splitLineType = splitLineType;
axis.boundaryGap = boundaryGap;
axis.axisName.Copy(axisName);
axis.axisLabel.Copy(axisLabel);
axis.data.Clear();
foreach (var d in data) axis.data.Add(d);
return axis;
}
public static YAxis defaultYAxis
{
get
{
var axis = new YAxis
{
m_Show = true,
m_Type = AxisType.Value,
m_Min = 0,
m_Max = 0,
m_SplitNumber = 5,
m_ShowSplitLine = true,
m_SplitLineType = SplitLineType.Dashed,
m_BoundaryGap = false,
m_Data = new List<string>(5),
};
return axis;
}
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 84f640465300fb34facae554552063b9
timeCreated: 1554422468
licenseType: Free
guid: 42232255fb44747ba8d680aa7d76c2ee
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,45 @@
using UnityEngine;
namespace XCharts
{
/// <summary>
/// bar component.global setting for bar chart.
/// 柱状图的全局配置组件。
/// </summary>
[System.Serializable]
public class Bar
{
[SerializeField] private bool m_InSameBar = false;
[SerializeField] private float m_BarWidth = 0.7f;
[SerializeField] private float m_Space = 10;
/// <summary>
/// Whether to draw all bar in the same bar,but not stacked.
/// 非堆叠同柱。多序列绘制在同一bar上但不堆叠而是覆盖绘制。
/// </summary>
public bool inSameBar { get { return m_InSameBar; } set { m_InSameBar = value; } }
/// <summary>
/// the width of bar.
/// 状态的宽度。
/// </summary>
public float barWidth { get { return m_BarWidth; } set { m_BarWidth = value; } }
/// <summary>
/// the space of bars.
/// 多柱状间的间距。
/// </summary>
public float space { get { return m_Space; } set { m_Space = value; } }
public static Bar defaultBar
{
get
{
return new Bar()
{
m_InSameBar = false,
m_BarWidth = 0.6f,
m_Space = 10
};
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f4f93f97ce4c4274a4153986a3e5752
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -7,6 +7,7 @@ namespace XCharts
/// DataZoom component is used for zooming a specific area,
/// which enables user to investigate data in detail,
/// or get an overview of the data, or get rid of outlier points.
/// <para>DataZoom 组件 用于区域缩放,从而能自由关注细节的数据信息,或者概览数据整体,或者去除离群点的影响。</para>
/// </summary>
[System.Serializable]
public class DataZoom
@@ -16,11 +17,13 @@ namespace XCharts
/// <summary>
/// DataZoom functionalities is embeded inside coordinate systems, enable user to
/// zoom or roam coordinate system by mouse dragging, mouse move or finger touch (in touch screen).
/// 内置于坐标系中,使用户可以在坐标系上通过鼠标拖拽、鼠标滚轮、手指滑动(触屏上)来缩放或漫游坐标系。
/// </summary>
Inside,
/// <summary>
/// A special slider bar is provided, on which coordinate systems can be zoomed or
/// roamed by mouse dragging or finger touch (in touch screen).
/// 有单独的滑动条,用户在滑动条上进行缩放或漫游。
/// </summary>
Slider
}
@@ -28,34 +31,42 @@ namespace XCharts
/// <summary>
/// Generally dataZoom component zoom or roam coordinate system through data filtering
/// and set the windows of axes internally.
/// Its behaviours vary according to filtering mode settings
/// Its behaviours vary according to filtering mode settings.
/// dataZoom 的运行原理是通过 数据过滤 来达到 数据窗口缩放 的效果。数据过滤模式的设置不同,效果也不同。
/// </summary>
public enum FilterMode
{
/// <summary>
/// data that outside the window will be filtered, which may lead to some changes of windows of other axes.
/// For each data item, it will be filtered if one of the relevant dimensions is out of the window.
/// 当前数据窗口外的数据,被 过滤掉。即 会 影响其他轴的数据范围。每个数据项,只要有一个维度在数据窗口外,整个数据项就会被过滤掉。
/// </summary>
Filter,
/// <summary>
/// data that outside the window will be filtered, which may lead to some changes of windows of other axes.
/// For each data item, it will be filtered only if all of the relevant dimensions are out of the same side of the window.
/// 当前数据窗口外的数据,被 过滤掉。即 会 影响其他轴的数据范围。每个数据项,只有当全部维度都在数据窗口同侧外部,整个数据项才会被过滤掉。
/// </summary>
WeakFilter,
/// <summary>
/// data that outside the window will be set to NaN, which will not lead to changes of windows of other axes
/// data that outside the window will be set to NaN, which will not lead to changes of windows of other axes.
/// 当前数据窗口外的数据,被 设置为空。即 不会 影响其他轴的数据范围。
/// </summary>
Empty,
/// <summary>
/// Do not filter data.
/// 不过滤数据,只改变数轴范围。
/// </summary>
None
}
/// <summary>
/// The value type of start and end.取值类型
/// </summary>
public enum RangeMode
{
//Value,
/// <summary>
/// percent value
/// percent value. 百分比
/// </summary>
Percent
}
@@ -63,6 +74,8 @@ namespace XCharts
[SerializeField] private DataZoomType m_Type;
[SerializeField] private FilterMode m_FilterMode;
[SerializeField] private Orient m_Orient;
[SerializeField] private int m_XAxisIndex;
[SerializeField] private int m_YAxisIndex;
[SerializeField] private bool m_ShowDataShadow;
[SerializeField] private bool m_ShowDetail;
[SerializeField] private bool m_ZoomLock;
@@ -78,81 +91,118 @@ namespace XCharts
[Range(1f, 20f)]
[SerializeField] private float m_ScrollSensitivity;
/// <summary>
/// Whether to show dataZoom.
/// 是否显示缩放区域。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// The type of dataZoom.
/// 缩放区域的类型。
/// </summary>
public DataZoomType type { get { return m_Type; } set { m_Type = value; } }
/// <summary>
/// The mode of data filter.
/// 数据过滤类型。
/// </summary>
public FilterMode filterMode { get { return m_FilterMode; } set { m_FilterMode = value; } }
/// <summary>
/// Specify whether the layout of dataZoom component is horizontal or vertical.
/// 水平还是垂直显示。
/// </summary>
public Orient orient { get { return m_Orient; } set { m_Orient = value; } }
/// <summary>
/// Specify which xAxis is controlled by the dataZoom.
/// 控制哪个一 x 轴。
/// </summary>
public int xAxisIndex { get { return m_XAxisIndex; } set { m_XAxisIndex = value; } }
/// <summary>
/// Specify which yAxis is controlled by the dataZoom.
/// 控制哪一个 y 轴。
/// </summary>
public int yAxisIndex { get { return m_YAxisIndex; } set { m_YAxisIndex = value; } }
/// <summary>
/// Whether to show data shadow, to indicate the data tendency in brief.
/// default:true
/// 是否显示数据阴影。数据阴影可以简单地反应数据走势。
/// </summary>
public bool showDataShadow { get { return m_ShowDataShadow; } set { m_ShowDataShadow = value; } }
/// <summary>
/// Whether to show detail, that is, show the detailed data information when dragging.
/// 是否显示detail即拖拽时候显示详细数值信息。
/// </summary>
/// <value></value>
public bool showDetail { get { return m_ShowDetail; } set { m_ShowDetail = value; } }
/// <summary>
/// Specify whether to lock the size of window (selected area).
/// default:false
/// 是否锁定选择区域(或叫做数据窗口)的大小。
/// 如果设置为 true 则锁定选择区域的大小,也就是说,只能平移,不能缩放。
/// </summary>
public bool zoomLock { get { return m_ZoomLock; } set { m_ZoomLock = value; } }
/// <summary>
/// Whether to show data shadow in dataZoom-silder component, to indicate the data tendency in brief.
/// default:true
/// 如果设置为 true 则锁定选择区域的大小,也就是说,只能平移,不能缩放。
/// </summary>
public bool realtime { get { return m_Realtime; } set { m_Realtime = value; } }
/// <summary>
/// The background color of the component.
/// 组件的背景颜色。
/// </summary>
public Color backgroundColor { get { return m_BackgroundColor; } set { m_BackgroundColor = value; } }
/// <summary>
/// Distance between dataZoom component and the bottom side of the container.
/// bottom value is a instant pixel value like 10.
/// default:10
/// 组件离容器下侧的距离。
/// </summary>
public float bottom { get { return m_Bottom; } set { m_Bottom = value; } }
/// <summary>
/// The height of dataZoom component.
/// height value is a instant pixel value like 10.
/// default:50
/// 组件高度。
/// </summary>
public float height { get { return m_Height; } set { m_Height = value; } }
/// <summary>
/// Use absolute value or percent value in DataZoom.start and DataZoom.end.
/// default:RangeMode.Percent
/// default:RangeMode.Percent.
/// 取绝对值还是百分比。
/// </summary>
public RangeMode rangeMode { get { return m_RangeMode; } set { m_RangeMode = value; } }
/// <summary>
/// The start percentage of the window out of the data extent, in the range of 0 ~ 100.
/// default:30
/// 数据窗口范围的起始百分比。范围是0 ~ 100。
/// </summary>
public float start { get { return m_Start; } set { m_Start = value; } }
/// <summary>
/// The end percentage of the window out of the data extent, in the range of 0 ~ 100.
/// default:70
/// 数据窗口范围的结束百分比。范围是0 ~ 100。
/// </summary>
public float end { get { return m_End; } set { m_End = value; } }
/// <summary>
/// The sensitivity of dataZoom scroll.
/// The larger the number, the more sensitive it is.
/// default:10
/// 缩放区域组件的敏感度。值越高每次缩放所代表的数据越多。
/// </summary>
public float scrollSensitivity { get { return m_ScrollSensitivity; } set { m_ScrollSensitivity = value; } }
/// <summary>
/// DataZoom is in draging.
/// 正在拖拽组件。
/// </summary>
public bool isDraging { get; set; }
/// <summary>
/// The start label.
/// 组件的开始信息文本。
/// </summary>
public Text startLabel { get; set; }
/// <summary>
/// The end label.
/// 组件的结束信息文本。
/// </summary>
public Text endLabel { get; set; }
@@ -165,6 +215,8 @@ namespace XCharts
m_Type = DataZoomType.Slider,
filterMode = FilterMode.None,
orient = Orient.Horizonal,
xAxisIndex = 0,
yAxisIndex = 0,
showDataShadow = true,
showDetail = false,
zoomLock = false,
@@ -179,12 +231,26 @@ namespace XCharts
}
}
/// <summary>
/// 给定的坐标是否在缩放区域内
/// </summary>
/// <param name="pos"></param>
/// <param name="startX"></param>
/// <param name="width"></param>
/// <returns></returns>
public bool IsInZoom(Vector2 pos, float startX, float width)
{
Rect rect = Rect.MinMaxRect(startX, m_Bottom, startX + width, m_Bottom + m_Height);
return rect.Contains(pos);
}
/// <summary>
/// 给定的坐标是否在选中区域内
/// </summary>
/// <param name="pos"></param>
/// <param name="startX"></param>
/// <param name="width"></param>
/// <returns></returns>
public bool IsInSelectedZoom(Vector2 pos, float startX, float width)
{
var start = startX + width * m_Start / 100;
@@ -193,6 +259,13 @@ namespace XCharts
return rect.Contains(pos);
}
/// <summary>
/// 给定的坐标是否在开始活动条触发区域内
/// </summary>
/// <param name="pos"></param>
/// <param name="startX"></param>
/// <param name="width"></param>
/// <returns></returns>
public bool IsInStartZoom(Vector2 pos, float startX, float width)
{
var start = startX + width * m_Start / 100;
@@ -200,6 +273,13 @@ namespace XCharts
return rect.Contains(pos);
}
/// <summary>
/// 给定的坐标是否在结束活动条触发区域内
/// </summary>
/// <param name="pos"></param>
/// <param name="startX"></param>
/// <param name="width"></param>
/// <returns></returns>
public bool IsInEndZoom(Vector2 pos, float startX, float width)
{
var end = startX + width * m_End / 100;
@@ -207,6 +287,10 @@ namespace XCharts
return rect.Contains(pos);
}
/// <summary>
/// 是否显示文本
/// </summary>
/// <param name="flag"></param>
public void SetLabelActive(bool flag)
{
if (startLabel && startLabel.gameObject.activeInHierarchy != flag)
@@ -219,11 +303,19 @@ namespace XCharts
}
}
/// <summary>
/// 设置开始文本内容
/// </summary>
/// <param name="text"></param>
public void SetStartLabelText(string text)
{
if (startLabel) startLabel.text = text;
}
/// <summary>
/// 设置结束文本内容
/// </summary>
/// <param name="text"></param>
public void SetEndLabelText(string text)
{
if (endLabel) endLabel.text = text;

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 55000eccffd85064ea6a4d1d39ff63bb
timeCreated: 1559526210
licenseType: Free
guid: 46383c1c58e1f4c1a891ab60c86446eb
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,136 @@
using System;
using UnityEngine;
namespace XCharts
{
/// <summary>
/// Grid component.
/// Drawing grid in rectangular coordinate. In a single grid, at most two X and Y axes each is allowed.
/// Line chart, bar chart, and scatter chart can be drawn in grid.
/// There is only one single grid component at most in a single echarts instance.
/// <para>
/// 网格组件。
/// 直角坐标系内绘图网格,单个 grid 内最多可以放置上下两个 X 轴,左右两个 Y 轴。可以在网格上绘制折线图,柱状图,散点图。
/// 单个xcharts实例中只能存在一个grid组件。
/// </para>
/// </summary>
[Serializable]
public class Grid : IEquatable<Grid>
{
[SerializeField] private bool m_Show;
[SerializeField] private float m_Left;
[SerializeField] private float m_Right;
[SerializeField] private float m_Top;
[SerializeField] private float m_Bottom;
[SerializeField] private Color m_BackgroundColor;
/// <summary>
/// Whether to show the grid in rectangular coordinate.
/// 是否显示直角坐标系网格。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// Distance between grid component and the left side of the container.
/// grid 组件离容器左侧的距离。
/// </summary>
public float left { get { return m_Left; } set { m_Left = value; } }
/// <summary>
/// Distance between grid component and the right side of the container.
/// grid 组件离容器右侧的距离。
/// </summary>
public float right { get { return m_Right; } set { m_Right = value; } }
/// <summary>
/// Distance between grid component and the top side of the container.
/// grid 组件离容器上侧的距离。
/// </summary>
public float top { get { return m_Top; } set { m_Top = value; } }
/// <summary>
/// Distance between grid component and the bottom side of the container.
/// grid 组件离容器下侧的距离。
/// </summary>
public float bottom { get { return m_Bottom; } set { m_Bottom = value; } }
/// <summary>
/// Background color of grid, which is transparent by default.
/// 网格背景色,默认透明。
/// </summary>
public Color backgroundColor { get { return m_BackgroundColor; } set { m_BackgroundColor = value; } }
public static Grid defaultGrid
{
get
{
var coordinate = new Grid
{
m_Show = false,
m_Left = 50,
m_Right = 30,
m_Top = 50,
m_Bottom = 30
};
return coordinate;
}
}
public void Copy(Grid other)
{
m_Show = other.show;
m_Left = other.left;
m_Right = other.right;
m_Top = other.top;
m_Bottom = other.bottom;
m_BackgroundColor = other.backgroundColor;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
else if (obj is Grid)
{
return Equals((Grid)obj);
}
else
{
return false;
}
}
public bool Equals(Grid other)
{
if (ReferenceEquals(null, other))
{
return false;
}
return m_Show == other.show &&
m_Left == other.left &&
m_Right == other.right &&
m_Top == other.top &&
m_Bottom == other.bottom &&
ChartHelper.IsValueEqualsColor(m_BackgroundColor, other.backgroundColor);
}
public static bool operator ==(Grid left, Grid right)
{
if (ReferenceEquals(left, null) && ReferenceEquals(right, null))
{
return true;
}
else if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
{
return false;
}
return Equals(left, right);
}
public static bool operator !=(Grid left, Grid right)
{
return !(left == right);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 15d97f34ea6674855859ef7d7941e2e0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,14 +1,40 @@
using System;
using System.Linq;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace XCharts
{
/// <summary>
/// 图例组件。
/// 图例组件展现了不同系列的标记,颜色和名字。可以通过点击图例控制哪些系列不显示。
/// </summary>
[System.Serializable]
public class Legend : JsonDataSupport, IPropertyChanged, IEquatable<Legend>
{
/// <summary>
/// Selected mode of legend, which controls whether series can be toggled displaying by clicking legends.
/// It is enabled by default, and you may set it to be false to disabled it.
/// 图例选择的模式,控制是否可以通过点击图例改变系列的显示状态。默认开启图例选择,可以设成 None 关闭。
/// </summary>
public enum SelectedMode
{
/// <summary>
/// 多选。
/// </summary>
Multiple,
/// <summary>
/// 单选。
/// </summary>
Single,
/// <summary>
/// 无法选择。
/// </summary>
None
}
[SerializeField] private bool m_Show = true;
[SerializeField] private SelectedMode m_SelectedMode;
[SerializeField] private Orient m_Orient = Orient.Horizonal;
[SerializeField] private Location m_Location = Location.defaultRight;
[SerializeField] private float m_ItemWidth = 50.0f;
@@ -17,49 +43,90 @@ namespace XCharts
[SerializeField] private int m_ItemFontSize = 18;
[SerializeField] private List<string> m_Data = new List<string>();
[NonSerialized] private List<bool> m_DataActiveList = new List<bool>();
[NonSerialized] private List<Button> m_DataBtnList = new List<Button>();
private Dictionary<string, Button> m_DataBtnList = new Dictionary<string, Button>();
/// <summary>
/// Whether to show legend component.
/// 是否显示图例组件。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// Selected mode of legend, which controls whether series can be toggled displaying by clicking legends.
/// 选择模式。控制是否可以通过点击图例改变系列的显示状态。默认开启图例选择,可以设成 None 关闭。
/// </summary>
/// <value></value>
public SelectedMode selectedMode { get { return m_SelectedMode; } set { m_SelectedMode = value; } }
/// <summary>
/// Specify whether the layout of legend component is horizontal or vertical.
/// 布局方式是横还是竖。
/// </summary>
public Orient orient { get { return m_Orient; } set { m_Orient = value; } }
/// <summary>
/// The location of legend.
/// 图例显示的位置。
/// </summary>
public Location location { get { return m_Location; } set { m_Location = value; } }
/// <summary>
/// the width of legend item.
/// 每个图例项的宽度。
/// </summary>
public float itemWidth { get { return m_ItemWidth; } set { m_ItemWidth = value; } }
/// <summary>
/// the height of legend item.
/// 每个图例项的高度。
/// </summary>
public float itemHeight { get { return m_ItemHeight; } set { m_ItemHeight = value; } }
/// <summary>
/// The distance between each legend, horizontal distance in horizontal layout, and vertical distance in vertical layout.
/// 图例每项之间的间隔。横向布局时为水平间隔,纵向布局时为纵向间隔。
/// </summary>
public float itemGap { get { return m_ItemGap; } set { m_ItemGap = value; } }
/// <summary>
/// font size of item text.
/// 图例项的字体大小。
/// </summary>
public int itemFontSize { get { return m_ItemFontSize; } set { m_ItemFontSize = value; } }
/// <summary>
/// Data array of legend. An array item is usually a name representing string. (If it is a pie chart,
/// it could also be the name of a single data in the pie chart) of a series.
/// If data is not specified, it will be auto collected from series.
/// 图例的数据数组。数组项通常为一个字符串,每一项代表一个系列的 name如果是饼图也可以是饼图单个数据的 name
/// 如果 data 没有被指定会自动从当前系列中获取。指定data时里面的数据项和serie匹配时才会生效。
/// </summary>
public List<string> data { get { return m_Data; } }
/// <summary>
/// the button list of legend.
/// 图例按钮列表。
/// </summary>
/// <value></value>
public Dictionary<string, Button> buttonList { get { return m_DataBtnList; } }
/// <summary>
/// 一个在顶部居中显示的默认图例。
/// </summary>
public static Legend defaultLegend
{
get
{
var legend = new Legend
{
m_Show = true,
m_Show = false,
m_SelectedMode = SelectedMode.Multiple,
m_Orient = Orient.Horizonal,
m_Location = Location.defaultRight,
m_Location = Location.defaultTop,
m_ItemWidth = 60.0f,
m_ItemHeight = 20.0f,
m_ItemGap = 5,
m_ItemFontSize = 16,
m_Data = new List<string>()
{
"Legend"
}
m_ItemFontSize = 16
};
legend.location.top = 30;
return legend;
}
}
public void Copy(Legend legend)
{
m_Show = legend.show;
m_SelectedMode = legend.selectedMode;
m_Orient = legend.orient;
m_Location.Copy(legend.location);
m_ItemWidth = legend.itemWidth;
@@ -93,6 +160,7 @@ namespace XCharts
return false;
}
return show == other.show &&
selectedMode == other.selectedMode &&
orient == other.orient &&
location == other.location &&
itemWidth == other.itemWidth &&
@@ -125,36 +193,28 @@ namespace XCharts
return base.GetHashCode();
}
public bool IsActive(string name)
{
if (string.IsNullOrEmpty(name)) return true;
for (int i = 0; i < data.Count; i++)
{
if (data[i].Equals(name)) return m_DataActiveList[i];
}
return false;
}
public bool IsActive(int seriesIndex)
{
if (seriesIndex < 0 || seriesIndex > data.Count - 1) seriesIndex = 0;
if (seriesIndex >= data.Count) return true;
if (seriesIndex < 0 || seriesIndex > m_DataActiveList.Count - 1)
return true;
else
return m_DataActiveList[seriesIndex];
}
/// <summary>
/// 清空
/// </summary>
public void ClearData()
{
m_Data.Clear();
}
/// <summary>
/// 是否包括由指定名字的图例
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public bool ContainsData(string name)
{
return m_Data.Contains(name);
}
/// <summary>
/// 移除指定名字的图例
/// </summary>
/// <param name="name"></param>
public void RemoveData(string name)
{
if (m_Data.Contains(name))
@@ -163,67 +223,94 @@ namespace XCharts
}
}
/// <summary>
/// 添加图例项
/// </summary>
/// <param name="name"></param>
public void AddData(string name)
{
if (!m_Data.Contains(name))
if (!m_Data.Contains(name) && !string.IsNullOrEmpty(name))
{
m_Data.Add(name);
}
}
public void SetActive(int index, bool flag)
/// <summary>
/// 获得指定索引的图例
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public string GetData(int index)
{
m_DataActiveList[index] = flag;
if (index >= 0 && index < m_Data.Count)
{
return m_Data[index];
}
return null;
}
public void SetActive(string name, bool flag)
/// <summary>
/// 获得指定图例的索引
/// </summary>
/// <param name="legendName"></param>
/// <returns></returns>
public int GetIndex(string legendName)
{
for (int i = 0; i < data.Count; i++)
{
if (data[i].Equals(name))
{
m_DataActiveList[i] = flag;
break;
}
}
return m_Data.IndexOf(legendName);
}
public void SetButton(int index, Button btn)
/// <summary>
/// 移除所有图例按钮
/// </summary>
public void RemoveButton()
{
btn.transform.localPosition = GetButtonLocationPosition(index);
if (index < 0 || index > m_DataBtnList.Count - 1)
{
m_DataBtnList.Add(btn);
m_DataActiveList.Add(true);
}
else
{
m_DataBtnList[index] = btn;
}
m_DataBtnList.Clear();
}
/// <summary>
/// 给图例绑定按钮
/// </summary>
/// <param name="name"></param>
/// <param name="btn"></param>
/// <param name="total"></param>
public void SetButton(string name, Button btn, int total)
{
int index = m_DataBtnList.Values.Count;
btn.transform.localPosition = GetButtonLocationPosition(total, index);
m_DataBtnList[name] = btn;
btn.gameObject.SetActive(show);
btn.GetComponentInChildren<Text>().text = data[index];
btn.GetComponentInChildren<Text>().text = name;
}
public void UpdateButtonColor(int index, Color ableColor, Color unableColor)
/// <summary>
/// 更新图例按钮颜色
/// </summary>
/// <param name="name"></param>
/// <param name="color"></param>
public void UpdateButtonColor(string name, Color color)
{
if (IsActive(index))
if (m_DataBtnList.ContainsKey(name))
{
m_DataBtnList[index].GetComponent<Image>().color = ableColor;
}
else
{
m_DataBtnList[index].GetComponent<Image>().color = unableColor;
m_DataBtnList[name].GetComponent<Image>().color = color;
}
}
/// <summary>
/// 参数变更时的回调处理
/// </summary>
public void OnChanged()
{
m_Location.OnChanged();
}
private Vector2 GetButtonLocationPosition(int index)
/// <summary>
/// 根据图例的布局和位置类型获得具体位置
/// </summary>
/// <param name="size"></param>
/// <param name="index"></param>
/// <returns></returns>
private Vector2 GetButtonLocationPosition(int size, int index)
{
int size = m_Data.Count;
switch (m_Orient)
{
case Orient.Vertical:
@@ -272,6 +359,10 @@ namespace XCharts
return Vector2.zero;
}
/// <summary>
/// 从json字符串解析数据json格式如['邮件营销','联盟广告','视频广告','直接访问','搜索引擎']
/// </summary>
/// <param name="jsonData"></param>
public override void ParseJsonData(string jsonData)
{
if (string.IsNullOrEmpty(jsonData) || !m_DataFromJson) return;

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 3fba76b49d7dd644cb3953355d6caae4
timeCreated: 1554222818
licenseType: Free
guid: f7a925c1e6149497098620272a65057f
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -2,31 +2,68 @@
namespace XCharts
{
/// <summary>
/// The global settings of line chart.
/// LineChart的全局配置。
/// </summary>
[System.Serializable]
public class Line
{
/// <summary>
/// the type fo step line.
/// 阶梯线图类型。
/// </summary>
public enum StepType
{
/// <summary>
/// 当前点。
/// </summary>
Start,
/// <summary>
/// 当前点和下一个点的中间。
/// </summary>
Middle,
/// <summary>
/// 下一个拐点
/// </summary>
End
}
[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 bool m_Step;
[SerializeField] private StepType m_StepType;
/// <summary>
/// the tickness of lines.
/// 线条粗细。
/// </summary>
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; } }
/// <summary>
/// smoothness.
/// 平滑风格。
/// </summary>
public float smoothStyle { get { return m_SmoothStyle; } set { m_SmoothStyle = value; } }
/// <summary>
/// Whether the lines are displayed smoothly.
/// 是否平滑显示。
/// </summary>
public bool smooth { get { return m_Smooth; } set { m_Smooth = value; } }
/// <summary>
/// Whether to show area.
/// 是否显示区域填充颜色。
/// </summary>
public bool area { get { return m_Area; } set { m_Area = value; } }
/// <summary>
/// Whether to show as a step line.
/// 是否是阶梯线图。
/// </summary>
public bool step { get { return m_Step; } set { m_Step = value; } }
/// <summary>
/// the type of step line.
/// 阶梯线图类型。
/// </summary>
public StepType stepTpe { get { return m_StepType; } set { m_StepType = value; } }
public static Line defaultLine
@@ -36,8 +73,6 @@ namespace XCharts
var line = new Line
{
m_Tickness = 0.8f,
m_Point = true,
m_PointWidth = 2.5f,
m_Smooth = false,
m_SmoothStyle = 2f,
m_Area = false,

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 86acdbfd671c43949bf0cc4880a4ccb7
timeCreated: 1555671450
licenseType: Free
guid: 1a4ce8176d040474db7238ccc962c79f
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,38 @@
using UnityEngine;
namespace XCharts
{
/// <summary>
/// the global setting of pie chart.
/// 饼图的全局设置。
/// </summary>
[System.Serializable]
public class Pie
{
[SerializeField] private float m_TooltipExtraRadius;
[SerializeField] private float m_SelectedOffset;
/// <summary>
/// the extra dadius of pie chart when the tooltip indicatored pie.
/// 提示框指示时的额外半径。
/// </summary>
public float tooltipExtraRadius { get { return m_TooltipExtraRadius; } set { m_TooltipExtraRadius = value; } }
/// <summary>
/// the offset of pie when the pie item is selected.
/// 饼图项被选中时的偏移。
/// </summary>
public float selectedOffset { get { return m_SelectedOffset; } set { m_SelectedOffset = value; } }
public static Pie defaultPie
{
get
{
var pie = new Pie
{
m_TooltipExtraRadius = 10f,
m_SelectedOffset = 10f,
};
return pie;
}
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 7f38ef4633bae5247a8c382a4d20fc39
timeCreated: 1555671161
licenseType: Free
guid: a657ed0fd5aeb4312801338fb5308811
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,369 @@
using UnityEngine;
using System.Collections.Generic;
using System;
using System.Text.RegularExpressions;
using UnityEngine.UI;
namespace XCharts
{
/// <summary>
/// Coordinate for radar charts.
/// 雷达图坐标系组件,只适用于雷达图。
/// </summary>
[System.Serializable]
public class Radar : JsonDataSupport, IEquatable<Radar>
{
/// <summary>
/// Radar render type, in which 'Polygon' and 'Circle' are supported.
/// 雷达图绘制类型,支持 'Polygon' 和 'Circle'。
/// </summary>
public enum Shape
{
Polygon,
Circle
}
/// <summary>
/// Indicator of radar chart, which is used to assign multiple variables(dimensions) in radar chart.
/// 雷达图的指示器,用来指定雷达图中的多个变量(维度)。
/// </summary>
[System.Serializable]
public class Indicator : IEquatable<Indicator>
{
[SerializeField] private string m_Name;
[SerializeField] private float m_Max;
[SerializeField] private float m_Min;
[SerializeField] private Color m_Color;
/// <summary>
/// 指示器名称。
/// </summary>
public string name { get { return m_Name; } set { m_Name = value; } }
/// <summary>
/// The maximum value of indicator, with default value of 0, but we recommend to set it manually.
/// 指示器的最大值,默认为 0 无限制。
/// </summary>
public float max { get { return m_Max; } set { m_Max = value; } }
/// <summary>
/// The minimum value of indicator, with default value of 0.
/// 指示器的最小值,默认为 0 无限制。
/// </summary>
public float min { get { return m_Min; } set { m_Min = value; } }
/// <summary>
/// Specfy a color the the indicator.
/// 标签特定的颜色。默认取自主题的axisTextColor。
/// </summary>
public Color color { get { return m_Color; } set { m_Color = value; } }
/// <summary>
/// the text conponent of indicator.
/// 指示器的文本组件。
/// </summary>
public Text text { get; set; }
public Indicator Clone()
{
return new Indicator()
{
m_Name = name,
m_Max = max,
m_Min = min,
m_Color = color
};
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
else if (obj is Indicator)
{
return Equals((Indicator)obj);
}
else
{
return false;
}
}
public bool Equals(Indicator other)
{
if (ReferenceEquals(null, other))
{
return false;
}
return m_Name.Equals(other.name) &&
ChartHelper.IsValueEqualsColor(m_Color, other.color);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
[SerializeField] private Shape m_Shape;
[SerializeField] private float m_Radius = 100;
[SerializeField] private int m_SplitNumber = 5;
[SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.5f };
[SerializeField] private LineStyle m_LineStyle = new LineStyle();
[SerializeField] private AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea;
[SerializeField] private bool m_Indicator = true;
[SerializeField] private List<Indicator> m_IndicatorList = new List<Indicator>();
/// <summary>
/// Radar render type, in which 'Polygon' and 'Circle' are supported.
/// 雷达图绘制类型,支持 'Polygon' 和 'Circle'。
/// </summary>
/// <value></value>
public Shape shape { get { return m_Shape; } set { m_Shape = value; } }
/// <summary>
/// the radius of radar.
/// 雷达图的半径。
/// </summary>
public float radius { get { return m_Radius; } set { m_Radius = value; } }
/// <summary>
/// Segments of indicator axis.
/// 指示器轴的分割段数。
/// </summary>
public int splitNumber { get { return m_SplitNumber; } set { m_SplitNumber = value; } }
/// <summary>
/// the center of radar chart.
/// 雷达图的中心点。数组的第一项是横坐标,第二项是纵坐标。
/// 当值为0-1之间时表示百分比设置成百分比时第一项是相对于容器宽度第二项是相对于容器高度。
/// </summary>
public float[] center { get { return m_Center; } set { m_Center = value; } }
/// <summary>
/// the line style of radar.
/// 线条样式。
/// </summary>
public LineStyle lineStyle { get { return m_LineStyle; } set { m_LineStyle = value; } }
/// <summary>
/// Split area of axis in grid area.
/// 分割区域。
/// </summary>
public AxisSplitArea splitArea { get { return m_SplitArea; } set { m_SplitArea = value; } }
/// <summary>
/// Whether to show indicator.
/// 是否显示指示器。
/// </summary>
public bool indicator { get { return m_Indicator; } set { m_Indicator = value; } }
/// <summary>
/// the indicator list.
/// 指示器列表。
/// </summary>
public List<Indicator> indicatorList { get { return m_IndicatorList; } }
/// <summary>
/// the center position of radar in container.
/// 雷达图在容器中的具体中心点。
/// </summary>
/// <value></value>
public Vector2 centerPos { get; set; }
/// <summary>
/// the true radius of radar.
/// 雷达图的运行时实际半径。
/// </summary>
/// <value></value>
public float actualRadius { get; set; }
/// <summary>
/// the data position list of radar.
/// 雷达图的所有数据坐标点列表。
/// </summary>
/// <returns></returns>
public Dictionary<int,List<Vector3>> dataPosList = new Dictionary<int,List<Vector3>>();
public static Radar defaultRadar
{
get
{
var radar = new Radar
{
m_Shape = Shape.Polygon,
m_Radius = 0.4f,
m_SplitNumber = 5,
m_Indicator = true,
m_IndicatorList = new List<Indicator>(5){
new Indicator(){name="indicator1",max = 100},
new Indicator(){name="indicator2",max = 100},
new Indicator(){name="indicator3",max = 100},
new Indicator(){name="indicator4",max = 100},
new Indicator(){name="indicator5",max = 100},
}
};
radar.center[0] = 0.5f;
radar.center[1] = 0.45f;
radar.splitArea.show = true;
radar.lineStyle.width = 0.3f;
return radar;
}
}
public void Copy(Radar other)
{
m_Shape = other.shape;
m_Radius = other.radius;
m_SplitNumber = other.splitNumber;
m_Center[0] = other.center[0];
m_Center[1] = other.center[1];
m_Indicator = other.indicator;
indicatorList.Clear();
foreach (var d in other.indicatorList) indicatorList.Add(d.Clone());
}
public Radar Clone()
{
var radar = new Radar();
radar.shape = shape;
radar.radius = radius;
radar.splitNumber = splitNumber;
radar.center[0] = center[0];
radar.center[1] = center[1];
radar.indicatorList.Clear();
radar.indicator = indicator;
foreach (var d in indicatorList) radar.indicatorList.Add(d.Clone());
return radar;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
else if (obj is Radar)
{
return Equals((Radar)obj);
}
else
{
return false;
}
}
public bool Equals(Radar other)
{
if (ReferenceEquals(null, other))
{
return false;
}
return radius == other.radius &&
shape == other.shape &&
splitNumber == other.splitNumber &&
center[0] == other.center[0] &&
center[1] == other.center[1] &&
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 left, Radar right)
{
if (ReferenceEquals(left, null) && ReferenceEquals(right, null))
{
return true;
}
else if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
{
return false;
}
return Equals(left, right);
}
public static bool operator !=(Radar left, Radar right)
{
return !(left == right);
}
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++;
}
}
}
public float GetIndicatorMin(int index)
{
if (index >= 0 && index < m_IndicatorList.Count)
{
return m_IndicatorList[index].min;
}
return 0;
}
public float GetIndicatorMax(int index)
{
if (index >= 0 && index < m_IndicatorList.Count)
{
return m_IndicatorList[index].max;
}
return 0;
}
public void UpdateRadarCenter(float chartWidth, float chartHeight)
{
if (center.Length < 2) return;
var centerX = center[0] <= 1 ? chartWidth * center[0] : center[0];
var centerY = center[1] <= 1 ? chartHeight * center[1] : center[1];
centerPos = new Vector2(centerX, centerY);
if (radius <= 0)
{
actualRadius = 0;
}
else if (radius <= 1)
{
actualRadius = Mathf.Min(chartWidth, chartHeight) * radius;
}
else
{
actualRadius = radius;
}
}
public Vector3 GetIndicatorPosition(int index)
{
int indicatorNum = indicatorList.Count;
var angle = 2 * Mathf.PI / indicatorNum * index;
var x = centerPos.x + actualRadius * Mathf.Sin(angle);
var y = centerPos.y + actualRadius * Mathf.Cos(angle);
return new Vector3(x, y);
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: e3a368484f9598e4eb9dfce2471d34da
timeCreated: 1555562622
licenseType: Free
guid: 0edd44f3a0d104bcbb1371b511d15550
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,835 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;
using UnityEngine.Serialization;
namespace XCharts
{
/// <summary>
/// the type of serie.
/// 系列类型。
/// </summary>
public enum SerieType
{
/// <summary>
/// 折线图。折线图是用折线将各个数据点标志连接起来的图表,用于展现数据的变化趋势。可用于直角坐标系和极坐标系上。
/// </summary>
Line,
/// <summary>
/// 柱状图。柱状/条形图 通过 柱形的高度/条形的宽度 来表现数据的大小,用于有至少一个类目轴或时间轴的直角坐标系上。
/// </summary>
Bar,
/// <summary>
/// 饼图。饼图主要用于表现不同类目的数据在总和中的占比。每个的弧度表示数据数量的比例。
/// 饼图更适合表现数据相对于总数的百分比等关系。
/// </summary>
Pie,
/// <summary>
/// 雷达图。雷达图主要用于表现多变量的数据,例如球员的各个属性分析。依赖 radar 组件。
/// </summary>
Radar,
/// <summary>
/// 散点图。直角坐标系上的散点图可以用来展现数据的 xy 之间的关系,如果数据项有多个维度,
/// 其它维度的值可以通过不同大小的 symbol 展现成气泡图,也可以用颜色来表现。
/// </summary>
Scatter,
/// <summary>
/// 带有涟漪特效动画的散点图。利用动画特效可以将某些想要突出的数据进行视觉突出。
/// </summary>
EffectScatter
}
/// <summary>
/// Whether to show as Nightingale chart, which distinguishs data through radius.
/// 是否展示成南丁格尔图,通过半径区分数据大小。
/// </summary>
public enum RoseType
{
/// <summary>
/// Don't show as Nightingale chart.不展示成南丁格尔玫瑰图
/// </summary>
None,
/// <summary>
/// Use central angle to show the percentage of data, radius to show data size.
/// 扇区圆心角展现数据的百分比,半径展现数据的大小。
/// </summary>
Radius,
/// <summary>
/// All the sectors will share the same central angle, the data size is shown only through radiuses.
/// 所有扇区圆心角相同,仅通过半径展现数据大小。
/// </summary>
Area
}
/// <summary>
/// 系列。每个系列通过 type 决定自己的图表类型。
/// </summary>
[System.Serializable]
public class Serie : JsonDataSupport
{
[SerializeField] [DefaultValue("true")] private bool m_Show = true;
[SerializeField] private SerieType m_Type;
[SerializeField] private string m_Name;
[SerializeField] private string m_Stack;
[SerializeField] [Range(0, 1)] private int m_AxisIndex = 0;
[SerializeField] private int m_RadarIndex = 0;
[SerializeField] private LineStyle m_LineStyle = new LineStyle();
[SerializeField] private AreaStyle m_AreaStyle = AreaStyle.defaultAreaStyle;
[SerializeField] private SerieSymbol m_Symbol = new SerieSymbol();
#region PieChart field
[SerializeField] private bool m_ClickOffset = true;
[SerializeField] private RoseType m_RoseType = RoseType.None;
[SerializeField] private float m_Space;
[SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.5f };
[SerializeField] private float[] m_Radius = new float[2] { 0, 80 };
#endregion
[SerializeField] private SerieLabel m_Label = new SerieLabel();
[SerializeField] private SerieLabel m_HighlightLabel = new SerieLabel();
[SerializeField] [Range(1, 10)] private int m_ShowDataDimension;
[SerializeField] private bool m_ShowDataName;
[FormerlySerializedAs("m_Data")]
[SerializeField] private List<float> m_YData = new List<float>();
[SerializeField] private List<float> m_XData = new List<float>();
[SerializeField] private List<SerieData> m_Data = new List<SerieData>();
/// <summary>
/// Whether to show serie in chart.
/// 系列是否显示在图表上。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// the chart type of serie.
/// 系列的图表类型。
/// </summary>
public SerieType type { get { return m_Type; } set { m_Type = value; } }
/// <summary>
/// Series name used for displaying in tooltip and filtering with legend.
/// 系列名称,用于 tooltip 的显示legend 的图例筛选。
/// </summary>
public string name { get { return m_Name; } set { m_Name = value; } }
/// <summary>
/// If stack the value. On the same category axis, the series with the same stack name would be put on top of each other.
/// 数据堆叠同个类目轴上系列配置相同的stack值后后一个系列的值会在前一个系列的值上相加。
/// </summary>
public string stack { get { return m_Stack; } set { m_Stack = value; } }
/// <summary>
/// Index of axis to combine with, which is useful for multiple x axes in one chart.
/// 使用的坐标轴轴的 index在单个图表实例中存在多个坐标轴轴的时候有用。
/// </summary>
public int axisIndex { get { return m_AxisIndex; } set { m_AxisIndex = value; } }
/// <summary>
/// Index of radar component that radar chart uses.
/// 雷达图所使用的 radar 组件的 index。
/// </summary>
public int radarIndex { get { return m_RadarIndex; } set { m_RadarIndex = value; } }
/// <summary>
/// The style of line.
/// 线条样式。
/// </summary>
/// <value></value>
public LineStyle lineStyle { get { return m_LineStyle; } set { m_LineStyle = value; } }
/// <summary>
/// The style of area.
/// 区域填充样式。
/// </summary>
/// <value></value>
public AreaStyle areaStyle { get { return m_AreaStyle; } set { m_AreaStyle = value; } }
/// <summary>
/// the symbol of serie data item.
/// 标记的图形。
/// </summary>
public SerieSymbol symbol { get { return m_Symbol; } set { m_Symbol = value; } }
/// <summary>
/// Whether offset when mouse click pie chart item.
/// 鼠标点击时是否开启偏移一般用在PieChart图表中。
/// </summary>
public bool clickOffset { get { return m_ClickOffset; } set { m_ClickOffset = value; } }
/// <summary>
/// Whether to show as Nightingale chart.
/// 是否展示成南丁格尔图,通过半径区分数据大小。
/// </summary>
public RoseType roseType { get { return m_RoseType; } set { m_RoseType = value; } }
/// <summary>
/// the space of pie chart item.
/// 饼图项间的空隙留白。
/// </summary>
public float space { get { return m_Space; } set { m_Space = value; } }
/// <summary>
/// the center of pie chart.
/// 饼图的中心点。
/// </summary>
public float[] center { get { return m_Center; } set { m_Center = value; } }
/// <summary>
/// the radius of pie chart.
/// 饼图的半径。radius[0]表示内径radius[1]表示外径。
/// </summary>
public float[] radius { get { return m_Radius; } set { m_Radius = value; } }
/// <summary>
/// Text label of graphic element,to explain some data information about graphic item like value, name and so on.
/// 图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
/// </summary>
public SerieLabel label { get { return m_Label; } set { m_Label = value; } }
/// <summary>
/// Text label of highlight graphic element.
/// 高亮时的文本标签配置。
/// </summary>
public SerieLabel highlightLabel { get { return m_HighlightLabel; } set { m_HighlightLabel = value; } }
/// <summary>
/// 维度Y的数据列表。默认对应yAxis。
/// </summary>
public List<float> yData { get { return m_YData; } }
/// <summary>
/// 维度X的数据列表。默认对应xAxis。
/// </summary>
public List<float> xData { get { return m_XData; } }
/// <summary>
/// 系列中的数据内容数组。SerieData可以设置1到n维数据。
/// </summary>
public List<SerieData> data { get { return m_Data; } }
/// <summary>
/// The index of serie,start at 0.
/// 系列的索引从0开始。
/// </summary>
public int index { get; set; }
/// <summary>
/// Whether the serie is highlighted.
/// 该系列是否高亮,一般由图例悬停触发。
/// </summary>
public bool highlighted { get; set; }
/// <summary>
/// the count of data list.
/// 数据项个数。
/// </summary>
public int dataCount { get { return m_Data.Count; } }
private int filterStart { get; set; }
private int filterEnd { get; set; }
private List<float> yFilterData { get; set; }
private List<float> xFilterData { get; set; }
private List<SerieData> filterData { get; set; }
/// <summary>
/// 维度Y对应数据中最大值。
/// </summary>
public float yMax
{
get
{
float max = int.MinValue;
foreach (var sdata in data)
{
if (sdata.show && sdata.data[1] > max)
{
max = sdata.data[1];
}
}
return max;
}
}
/// <summary>
/// 维度X对应数据中的最大值。
/// </summary>
public float xMax
{
get
{
float max = int.MinValue;
foreach (var sdata in data)
{
if (sdata.show && sdata.data[0] > max)
{
max = sdata.data[0];
}
}
return max;
}
}
/// <summary>
/// 维度Y对应数据的最小值。
/// </summary>
public float yMin
{
get
{
float min = int.MaxValue;
foreach (var sdata in data)
{
if (sdata.show && sdata.data[1] < min)
{
min = sdata.data[1];
}
}
return min;
}
}
/// <summary>
/// 维度X对应数据的最小值。
/// </summary>
public float xMin
{
get
{
float min = int.MaxValue;
foreach (var sdata in data)
{
if (sdata.show && sdata.data[0] < min)
{
min = sdata.data[0];
}
}
return min;
}
}
/// <summary>
/// 维度Y数据的总和。
/// </summary>
public float yTotal
{
get
{
float total = 0;
foreach (var sdata in data)
{
if (sdata.show)
total += sdata.data[1];
}
return total;
}
}
/// <summary>
/// 维度X数据的总和。
/// </summary>
public float xTotal
{
get
{
float total = 0;
foreach (var sdata in data)
{
if (sdata.show)
total += sdata.data[0];
}
return total;
}
}
/// <summary>
/// 清空所有数据
/// </summary>
public void ClearData()
{
m_XData.Clear();
m_YData.Clear();
m_Data.Clear();
}
/// <summary>
/// 移除指定索引的数据
/// </summary>
/// <param name="index"></param>
public void RemoveData(int index)
{
m_XData.RemoveAt(index);
m_YData.RemoveAt(index);
m_Data.RemoveAt(index);
}
/// <summary>
/// 添加一个数据到维度Y此时维度X对应的数据是索引
/// </summary>
/// <param name="value"></param>
/// <param name="dataName"></param>
/// <param name="maxDataNumber"></param>
public void AddYData(float value, string dataName = null, int maxDataNumber = 0)
{
if (maxDataNumber > 0)
{
while (m_XData.Count > maxDataNumber) m_XData.RemoveAt(0);
while (m_YData.Count > maxDataNumber) m_YData.RemoveAt(0);
while (m_Data.Count > maxDataNumber) m_Data.RemoveAt(0);
}
int xValue = m_XData.Count;
m_XData.Add(xValue);
m_YData.Add(value);
m_Data.Add(new SerieData() { data = new List<float>() { xValue, value }, name = dataName });
}
/// <summary>
/// 添加xy数据到维度X和维度Y
/// </summary>
/// <param name="xValue"></param>
/// <param name="yValue"></param>
/// <param name="dataName"></param>
/// <param name="maxDataNumber"></param>
public void AddXYData(float xValue, float yValue, string dataName = null, int maxDataNumber = 0)
{
if (maxDataNumber > 0)
{
while (m_XData.Count > maxDataNumber) m_XData.RemoveAt(0);
while (m_YData.Count > maxDataNumber) m_YData.RemoveAt(0);
while (m_Data.Count > maxDataNumber) m_Data.RemoveAt(0);
}
m_XData.Add(xValue);
m_YData.Add(yValue);
m_Data.Add(new SerieData() { data = new List<float>() { xValue, yValue }, name = dataName });
}
/// <summary>
/// 将一组数据添加到系列中。
/// 如果数据只有一个默认添加到维度Y中。
/// </summary>
/// <param name="valueList"></param>
/// <param name="dataName"></param>
/// <param name="maxDataNumber"></param>
public void AddData(List<float> valueList, string dataName = null, int maxDataNumber = 0)
{
if (valueList == null || valueList.Count == 0) return;
if (valueList.Count == 1)
{
AddYData(valueList[0], dataName, maxDataNumber);
}
else if (valueList.Count == 2)
{
AddXYData(valueList[0], valueList[1], dataName, maxDataNumber);
}
else
{
if (maxDataNumber > 0)
{
while (m_XData.Count > maxDataNumber) m_XData.RemoveAt(0);
while (m_YData.Count > maxDataNumber) m_YData.RemoveAt(0);
while (m_Data.Count > maxDataNumber) m_Data.RemoveAt(0);
}
var serieData = new SerieData();
serieData.name = dataName;
for (int i = 0; i < valueList.Count; i++)
{
if (i == 0) m_XData.Add(valueList[i]);
else if (i == 1) m_YData.Add(valueList[i]);
serieData.data.Add(valueList[i]);
}
m_Data.Add(serieData);
}
}
/// <summary>
/// 获得维度Y索引对应的数据
/// </summary>
/// <param name="index"></param>
/// <param name="dataZoom"></param>
/// <returns></returns>
public float GetYData(int index, DataZoom dataZoom = null)
{
if (index < 0) return 0;
var serieData = GetDataList(dataZoom);
if (index < serieData.Count)
{
return serieData[index].data[1];
}
return 0;
}
/// <summary>
/// 获得维度Y索引对应的数据和数据名
/// </summary>
/// <param name="index">索引</param>
/// <param name="yData">对应的数据值</param>
/// <param name="dataName">对应的数据名</param>
/// <param name="dataZoom">区域缩放</param>
public void GetYData(int index, out float yData, out string dataName, DataZoom dataZoom = null)
{
yData = 0;
dataName = null;
if (index < 0) return;
var serieData = GetDataList(dataZoom);
if (index < serieData.Count)
{
yData = serieData[index].data[1];
dataName = serieData[index].name;
}
}
/// <summary>
/// 获得指定索引的数据项
/// </summary>
/// <param name="index"></param>
/// <param name="dataZoom"></param>
/// <returns></returns>
public SerieData GetSerieData(int index, DataZoom dataZoom = null)
{
var data = GetDataList(dataZoom);
if (index >= 0 && index <= data.Count - 1)
{
return data[index];
}
return null;
}
/// <summary>
/// 获得指定索引的维度X和维度Y的数据
/// </summary>
/// <param name="index"></param>
/// <param name="dataZoom"></param>
/// <param name="xValue"></param>
/// <param name="yVlaue"></param>
public void GetXYData(int index, DataZoom dataZoom, out float xValue, out float yVlaue)
{
xValue = 0;
yVlaue = 0;
if (index < 0) return;
var showData = GetDataList(dataZoom);
if (index < showData.Count)
{
var serieData = showData[index];
xValue = serieData.data[0];
yVlaue = serieData.data[1];
}
}
/// <summary>
/// 获得维度Y的数据列表
/// </summary>
/// <param name="dataZoom"></param>
/// <returns></returns>
public List<float> GetYDataList(DataZoom dataZoom)
{
if (dataZoom != null && dataZoom.show)
{
var startIndex = (int)((yData.Count - 1) * dataZoom.start / 100);
var endIndex = (int)((yData.Count - 1) * dataZoom.end / 100);
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
if (yFilterData == null || yFilterData.Count != count)
{
UpdateFilterData(dataZoom);
}
return yFilterData;
}
else
{
return m_YData;
}
}
/// <summary>
/// 获得维度X的数据列表
/// </summary>
/// <param name="dataZoom"></param>
/// <returns></returns>
public List<float> GetXDataList(DataZoom dataZoom)
{
if (dataZoom != null && dataZoom.show)
{
var startIndex = (int)((xData.Count - 1) * dataZoom.start / 100);
var endIndex = (int)((xData.Count - 1) * dataZoom.end / 100);
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
if (xFilterData == null || xFilterData.Count != count)
{
UpdateFilterData(dataZoom);
}
return xFilterData;
}
else
{
return m_XData;
}
}
/// <summary>
/// 获得系列的数据列表
/// </summary>
/// <param name="dataZoom"></param>
/// <returns></returns>
public List<SerieData> GetDataList(DataZoom dataZoom)
{
if (dataZoom != null && dataZoom.show)
{
var startIndex = (int)((m_Data.Count - 1) * dataZoom.start / 100);
var endIndex = (int)((m_Data.Count - 1) * dataZoom.end / 100);
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
if (filterData == null || filterData.Count != count)
{
UpdateFilterData(dataZoom);
}
return filterData;
}
else
{
return m_Data;
}
}
/// <summary>
/// 获得指定维数的最大最小值
/// </summary>
/// <param name="dimension"></param>
/// <param name="dataZoom"></param>
/// <returns></returns>
public void GetMinMaxData(int dimension, out float minValue, out float maxValue, DataZoom dataZoom = null)
{
var dataList = GetDataList(dataZoom);
float max = float.MinValue;
float min = float.MaxValue;
for (int i = 0; i < dataList.Count; i++)
{
var serieData = dataList[i];
if (serieData.data.Count > dimension)
{
var value = serieData.data[dimension];
if (value > max) max = value;
if (value < min) min = value;
}
}
maxValue = max;
minValue = min;
}
/// <summary>
/// 根据dataZoom更新数据列表缓存
/// </summary>
/// <param name="dataZoom"></param>
public void UpdateFilterData(DataZoom dataZoom)
{
if (dataZoom != null && dataZoom.show)
{
var startIndex = (int)((yData.Count - 1) * dataZoom.start / 100);
var endIndex = (int)((yData.Count - 1) * dataZoom.end / 100);
if (startIndex != filterStart || endIndex != filterEnd)
{
filterStart = startIndex;
filterEnd = endIndex;
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
if (m_YData.Count > 0)
{
yFilterData = m_YData.GetRange(startIndex, count);
}
else
{
yFilterData = m_YData;
}
if (m_XData.Count > 0)
{
xFilterData = m_XData.GetRange(startIndex, count);
}
else
{
xFilterData = m_XData;
}
if (m_Data.Count > 0)
{
filterData = m_Data.GetRange(startIndex, count);
}
else
{
filterData = m_Data;
}
}
else if (endIndex == 0)
{
yFilterData = new List<float>();
xFilterData = new List<float>();
filterData = new List<SerieData>();
}
}
}
/// <summary>
/// 更新指定索引的维度Y数据
/// </summary>
/// <param name="index"></param>
/// <param name="value"></param>
public void UpdateYData(int index, float value)
{
UpdateData(index, 2, value);
}
/// <summary>
/// 更新指定索引的维度X和维度Y的数据
/// </summary>
/// <param name="index"></param>
/// <param name="xValue"></param>
/// <param name="yValue"></param>
public void UpdateXYData(int index, float xValue, float yValue)
{
UpdateData(index, 1, xValue);
UpdateData(index, 2, yValue);
}
/// <summary>
/// 更新指定索引指定维数的数据
/// </summary>
/// <param name="index">要更新数据的索引</param>
/// <param name="dimension">要更新数据的维数</param>
/// <param name="value">新的数据值</param>
public void UpdateData(int index, int dimension, float value)
{
if (index < 0) return;
if (dimension == 1)
{
if (index < m_XData.Count) m_XData[index] = value;
}
else if (dimension == 2)
{
if (index < m_YData.Count) m_YData[index] = value;
}
if (index < m_Data.Count && dimension < m_Data[index].data.Count)
{
m_Data[index].data[dimension] = value;
}
}
/// <summary>
/// 清除所有数据的高亮标志
/// </summary>
public void ClearHighlight()
{
highlighted = false;
foreach (var sd in m_Data)
{
sd.highlighted = false;
}
}
/// <summary>
/// 设置指定索引的数据为高亮状态
/// </summary>
/// <param name="index"></param>
public void SetHighlight(int index)
{
if (index <= 0) return;
for (int i = 0; i < m_Data.Count; i++)
{
m_Data[i].highlighted = index == i;
}
}
public Color GetAreaColor(ThemeInfo theme, int index, bool highlight)
{
if (areaStyle.color != Color.clear)
{
var color = areaStyle.color;
if (highlight) color *= color;
color.a *= areaStyle.opactiy;
return color;
}
else
{
var color = (Color)theme.GetColor(index);
if (highlight) color *= color;
color.a *= areaStyle.opactiy;
return color;
}
}
public Color GetLineColor(ThemeInfo theme, int index, bool highlight)
{
if (lineStyle.color != Color.clear)
{
var color = lineStyle.color;
if (highlight) color *= color;
color.a *= lineStyle.opactiy;
return color;
}
else
{
var color = (Color)theme.GetColor(index);
if (highlight) color *= color;
color.a *= lineStyle.opactiy;
return color;
}
}
/// <summary>
/// 从json中导入数据
/// </summary>
/// <param name="jsonData"></param>
public override void ParseJsonData(string jsonData)
{
if (string.IsNullOrEmpty(jsonData) || !m_DataFromJson) return;
jsonData = jsonData.Replace("\r\n", "");
jsonData = jsonData.Replace(" ", "");
jsonData = jsonData.Replace("\n", "");
int startIndex = jsonData.IndexOf("[");
int endIndex = jsonData.LastIndexOf("]");
if (startIndex == -1 || endIndex == -1)
{
Debug.LogError("json data need include in [ ]");
return;
}
ClearData();
string temp = jsonData.Substring(startIndex + 1, endIndex - startIndex - 1);
if (temp.IndexOf("],") > -1 || temp.IndexOf("] ,") > -1)
{
string[] datas = temp.Split(new string[] { "],", "] ," }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < datas.Length; i++)
{
var data = datas[i].Split(new char[] { '[', ',' }, StringSplitOptions.RemoveEmptyEntries);
var serieData = new SerieData();
for (int j = 0; j < data.Length; j++)
{
var txt = data[j].Trim().Replace("]", "");
float value;
var flag = float.TryParse(txt, out value);
if (flag)
{
serieData.data.Add(value);
if (j == 0) m_XData.Add(value);
else if (j == 1) m_YData.Add(value);
}
else serieData.name = txt.Replace("\"", "").Trim();
}
m_Data.Add(serieData);
}
}
else if (temp.IndexOf("value") > -1 && temp.IndexOf("name") > -1)
{
string[] datas = temp.Split(new string[] { "},", "} ,", "}" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < datas.Length; i++)
{
var arr = datas[i].Replace("{", "").Split(',');
var serieData = new SerieData();
foreach (var a in arr)
{
if (a.StartsWith("value:"))
{
float value = float.Parse(a.Substring(6, a.Length - 6));
serieData.data = new List<float>() { i, value };
}
else if (a.StartsWith("name:"))
{
string name = a.Substring(6, a.Length - 6 - 1);
serieData.name = name;
}
else if (a.StartsWith("selected:"))
{
string selected = a.Substring(9, a.Length - 9);
serieData.selected = bool.Parse(selected);
}
}
m_Data.Add(serieData);
}
}
else
{
string[] datas = temp.Split(',');
for (int i = 0; i < datas.Length; i++)
{
float value;
var flag = float.TryParse(datas[i].Trim(), out value);
if (flag)
{
var serieData = new SerieData();
serieData.data = new List<float>() { i, value };
m_Data.Add(serieData);
}
}
}
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 5bde61eb0785bad4d91d84d5511514ba
timeCreated: 1554222818
licenseType: Free
guid: 0e8779db31fe5441ba4491407ee03cd1
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,718 @@
using UnityEngine;
using System.Collections.Generic;
namespace XCharts
{
/// <summary>
/// the list of series.
/// 系列列表。每个系列通过 type 决定自己的图表类型。
/// </summary>
[System.Serializable]
public class Series : JsonDataSupport
{
[SerializeField] protected List<Serie> m_Series;
/// <summary>
/// the list of serie
/// 系列列表。
/// </summary>
/// <value></value>
public List<Serie> series { get { return m_Series; } }
/// <summary>
/// the size of serie list.
/// 系列个数。
/// </summary>
/// <value></value>
public int Count { get { return m_Series.Count; } }
public static Series defaultSeries
{
get
{
var series = new Series
{
m_Series = new List<Serie>(){new Serie(){
show = true,
name = "serie1",
index = 0
}}
};
return series;
}
}
/// <summary>
/// 清空所有系列的数据
/// </summary>
public void ClearData()
{
foreach (var serie in m_Series)
{
serie.ClearData();
}
}
/// <summary>
/// 获得指定序列指定索引的数据值
/// </summary>
/// <param name="serieIndex"></param>
/// <param name="dataIndex"></param>
/// <returns></returns>
public float GetData(int serieIndex, int dataIndex)
{
if (serieIndex >= 0 && serieIndex < Count)
{
return m_Series[serieIndex].GetYData(dataIndex);
}
else
{
return 0;
}
}
/// <summary>
/// 获得指定系列名的第一个系列
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public Serie GetSerie(string name)
{
for (int i = 0; i < m_Series.Count; i++)
{
if (name.Equals(m_Series[i].name))
{
m_Series[i].index = i;
return m_Series[i];
}
}
return null;
}
/// <summary>
/// 获得指定系列名的所有系列
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public List<Serie> GetSeries(string name)
{
var list = new List<Serie>();
if (name == null) return list;
foreach (var serie in m_Series)
{
if (name.Equals(serie.name)) list.Add(serie);
}
return list;
}
/// <summary>
/// 获得指定索引的系列
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public Serie GetSerie(int index)
{
if (index >= 0 && index < m_Series.Count)
{
return m_Series[index];
}
return null;
}
/// <summary>
/// 是否包含指定名字的系列
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public bool Contains(string name)
{
for (int i = 0; i < m_Series.Count; i++)
{
if (name.Equals(m_Series[i].name))
{
return true;
}
}
return false;
}
/// <summary>
/// Remove serie from series.
/// 移除指定名字的系列。
/// </summary>
/// <param name="serieName">the name of serie</param>
public void Remove(string serieName)
{
var serie = GetSerie(serieName);
if (serie != null)
{
m_Series.Remove(serie);
}
}
/// <summary>
/// Remove all serie from series.
/// 移除所有系列。
/// </summary>
public void RemoveAll()
{
m_Series.Clear();
}
/// <summary>
/// 添加一个系列到列表中。
/// </summary>
/// <param name="serieName"></param>
/// <param name="type"></param>
/// <param name="show"></param>
/// <returns></returns>
public Serie AddSerie(string serieName, SerieType type, bool show = true)
{
var serie = GetSerie(serieName);
if (serie == null)
{
serie = new Serie();
serie.type = type;
serie.show = show;
serie.name = serieName;
serie.index = m_Series.Count;
if (type == SerieType.Scatter)
{
serie.symbol.type = SerieSymbolType.Circle;
serie.symbol.size = 20f;
serie.symbol.selectedSize = 30f;
}
else if (type == SerieType.Line)
{
serie.symbol.type = SerieSymbolType.EmptyCircle;
serie.symbol.size = 2.5f;
serie.symbol.selectedSize = 5f;
}
else
{
serie.symbol.type = SerieSymbolType.None;
}
m_Series.Add(serie);
}
else
{
serie.show = show;
}
return serie;
}
/// <summary>
/// 添加一个数据到指定系列的维度Y数据中
/// </summary>
/// <param name="serieName"></param>
/// <param name="value"></param>
/// <param name="dataName"></param>
/// <param name="maxDataNumber"></param>
/// <returns></returns>
public bool AddData(string serieName, float value, string dataName = null, int maxDataNumber = 0)
{
var serie = GetSerie(serieName);
if (serie != null)
{
serie.AddYData(value, dataName, maxDataNumber);
return true;
}
return false;
}
/// <summary>
/// 添加一个数据到指定系列的维度Y中
/// </summary>
/// <param name="index"></param>
/// <param name="value"></param>
/// <param name="dataName"></param>
/// <param name="maxDataNumber"></param>
/// <returns></returns>
public bool AddData(int index, float value, string dataName = null, int maxDataNumber = 0)
{
var serie = GetSerie(index);
if (serie != null)
{
serie.AddYData(value, dataName, maxDataNumber);
return true;
}
return false;
}
/// <summary>
/// 添加一组数据到指定的系列中
/// </summary>
/// <param name="serieName"></param>
/// <param name="multidimensionalData"></param>
/// <param name="dataName"></param>
/// <param name="maxDataNumber"></param>
/// <returns></returns>
public bool AddData(string serieName, List<float> multidimensionalData, string dataName = null, int maxDataNumber = 0)
{
var serie = GetSerie(serieName);
if (serie != null)
{
serie.AddData(multidimensionalData, dataName, maxDataNumber);
return true;
}
return false;
}
/// <summary>
/// 添加一组数据到指定的系列中
/// </summary>
/// <param name="serieIndex"></param>
/// <param name="multidimensionalData"></param>
/// <param name="dataName"></param>
/// <param name="maxDataNumber"></param>
/// <returns></returns>
public bool AddData(int serieIndex, List<float> multidimensionalData, string dataName = null, int maxDataNumber = 0)
{
var serie = GetSerie(serieIndex);
if (serie != null)
{
serie.AddData(multidimensionalData, dataName, maxDataNumber);
return true;
}
return false;
}
/// <summary>
/// 添加(x,y)数据到指定的系列中
/// </summary>
/// <param name="serieName"></param>
/// <param name="xValue"></param>
/// <param name="yValue"></param>
/// <param name="dataName"></param>
/// <param name="maxDataNumber"></param>
/// <returns></returns>
public bool AddXYData(string serieName, float xValue, float yValue, string dataName = null, int maxDataNumber = 0)
{
var serie = GetSerie(serieName);
if (serie != null)
{
serie.AddXYData(xValue, yValue, dataName, maxDataNumber);
return true;
}
return false;
}
/// <summary>
/// 添加(x,y)数据到指定的系列中
/// </summary>
/// <param name="index"></param>
/// <param name="xValue"></param>
/// <param name="yValue"></param>
/// <param name="dataName"></param>
/// <param name="maxDataNumber"></param>
/// <returns></returns>
public bool AddXYData(int index, float xValue, float yValue, string dataName = null, int maxDataNumber = 0)
{
var serie = GetSerie(index);
if (serie != null)
{
serie.AddXYData(xValue, yValue, dataName, maxDataNumber);
return true;
}
return false;
}
/// <summary>
/// 更新指定系列的维度Y数据
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <param name="dataIndex"></param>
public void UpdateData(string name, float value, int dataIndex = 0)
{
var serie = GetSerie(name);
if (serie != null)
{
serie.UpdateYData(dataIndex, value);
}
}
/// <summary>
/// 更新指定系列的维度Y数据
/// </summary>
/// <param name="index"></param>
/// <param name="value"></param>
/// <param name="dataIndex"></param>
public void UpdateData(int index, float value, int dataIndex = 0)
{
var serie = GetSerie(index);
if (serie != null)
{
serie.UpdateYData(dataIndex, value);
}
}
/// <summary>
/// 更新指定系列的维度X和维度Y数据
/// </summary>
/// <param name="name"></param>
/// <param name="xValue"></param>
/// <param name="yValue"></param>
/// <param name="dataIndex"></param>
public void UpdateXYData(string name, float xValue, float yValue, int dataIndex = 0)
{
var serie = GetSerie(name);
if (serie != null)
{
serie.UpdateXYData(dataIndex, xValue, yValue);
}
}
/// <summary>
/// 更新指定系列的维度X和维度Y数据
/// </summary>
/// <param name="index"></param>
/// <param name="xValue"></param>
/// <param name="yValue"></param>
/// <param name="dataIndex"></param>
public void UpdateXYData(int index, float xValue, float yValue, int dataIndex = 0)
{
var serie = GetSerie(index);
if (serie != null)
{
serie.UpdateXYData(dataIndex, xValue, yValue);
}
}
/// <summary>
/// dataZoom由变化是更新系列的缓存数据
/// </summary>
/// <param name="dataZoom"></param>
public void UpdateFilterData(DataZoom dataZoom)
{
if (dataZoom != null && dataZoom.show)
{
for (int i = 0; i < m_Series.Count; i++)
{
m_Series[i].UpdateFilterData(dataZoom);
}
}
}
/// <summary>
/// 指定系列是否显示
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public bool IsActive(string name)
{
var serie = GetSerie(name);
return serie == null ? false : serie.show;
}
/// <summary>
/// 指定系列是否显示
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public bool IsActive(int index)
{
var serie = GetSerie(index);
return serie == null ? false : serie.show;
}
/// <summary>
/// 设置指定系列是否显示
/// </summary>
/// <param name="name"></param>
/// <param name="active"></param>
public void SetActive(string name, bool active)
{
var serie = GetSerie(name);
if (serie != null)
{
serie.show = active;
}
}
/// <summary>
/// 设置指定系列是否显示
/// </summary>
/// <param name="index"></param>
/// <param name="active"></param>
public void SetActive(int index, bool active)
{
var serie = GetSerie(index);
if (serie != null)
{
serie.show = active;
}
}
/// <summary>
/// 是否由系列在用指定索引的axis
/// </summary>
/// <param name="axisIndex"></param>
/// <returns></returns>
public bool IsUsedAxisIndex(int axisIndex)
{
foreach (var serie in series)
{
if (serie.axisIndex == axisIndex) return true;
}
return false;
}
/// <summary>
/// 指定系列是否处于高亮选中状态
/// </summary>
/// <param name="serieIndex"></param>
/// <returns></returns>
public bool IsHighlight(int serieIndex)
{
var serie = GetSerie(serieIndex);
if (serie != null) return serie.highlighted;
else return false;
}
/// <summary>
/// 获得维度X的最大最小值
/// </summary>
/// <param name="dataZoom"></param>
/// <param name="axisIndex"></param>
/// <param name="minVaule"></param>
/// <param name="maxValue"></param>
public void GetXMinMaxValue(DataZoom dataZoom, int axisIndex, out int minVaule, out int maxValue)
{
GetMinMaxValue(dataZoom, axisIndex, false, out minVaule, out maxValue);
}
/// <summary>
/// 获得维度Y的最大最小值
/// </summary>
/// <param name="dataZoom"></param>
/// <param name="axisIndex"></param>
/// <param name="minVaule"></param>
/// <param name="maxValue"></param>
public void GetYMinMaxValue(DataZoom dataZoom, int axisIndex, out int minVaule, out int maxValue)
{
GetMinMaxValue(dataZoom, axisIndex, true, out minVaule, out maxValue);
}
private Dictionary<int, List<Serie>> _stackSeriesForMinMax = new Dictionary<int, List<Serie>>();
private Dictionary<int, float> _serieTotalValueForMinMax = new Dictionary<int, float>();
public void GetMinMaxValue(DataZoom dataZoom, int axisIndex, bool yValue, out int minVaule, out int maxValue)
{
float min = int.MaxValue;
float max = int.MinValue;
if (IsStack())
{
GetStackSeries(ref _stackSeriesForMinMax);
foreach (var ss in _stackSeriesForMinMax)
{
_serieTotalValueForMinMax.Clear();
for (int i = 0; i < ss.Value.Count; i++)
{
var serie = ss.Value[i];
if (serie.axisIndex != axisIndex) continue;
var showData = yValue ? serie.GetYDataList(dataZoom) : serie.GetXDataList(dataZoom);
for (int j = 0; j < showData.Count; j++)
{
if (!_serieTotalValueForMinMax.ContainsKey(j))
_serieTotalValueForMinMax[j] = 0;
_serieTotalValueForMinMax[j] = _serieTotalValueForMinMax[j] + showData[j];
}
}
float tmax = int.MinValue;
float tmin = int.MaxValue;
foreach (var tt in _serieTotalValueForMinMax)
{
if (tt.Value > tmax) tmax = tt.Value;
if (tt.Value < tmin) tmin = tt.Value;
}
if (tmax > max) max = tmax;
if (tmin < min) min = tmin;
}
}
else
{
for (int i = 0; i < m_Series.Count; i++)
{
if (m_Series[i].axisIndex != axisIndex) continue;
if (IsActive(i))
{
var showData = yValue ? m_Series[i].GetYDataList(dataZoom) : m_Series[i].GetXDataList(dataZoom);
foreach (var data in showData)
{
if (data > max) max = data;
if (data < min) min = data;
}
}
}
}
if (max == int.MinValue && min == int.MaxValue)
{
minVaule = 0;
maxValue = 90;
}
else
{
minVaule = Mathf.FloorToInt(min);
maxValue = Mathf.CeilToInt(max);
}
}
private HashSet<string> _setForStack = new HashSet<string>();
/// <summary>
/// 是否由数据堆叠
/// </summary>
/// <returns></returns>
public bool IsStack()
{
_setForStack.Clear();
foreach (var serie in m_Series)
{
if (string.IsNullOrEmpty(serie.stack)) continue;
if (_setForStack.Contains(serie.stack)) return true;
else
{
_setForStack.Add(serie.stack);
}
}
return false;
}
/// <summary>
/// 获得堆叠系列列表
/// </summary>
/// <returns></returns>
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>>();
for (int i = 0; i < m_Series.Count; i++)
{
var serie = m_Series[i];
serie.index = i;
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;
}
private Dictionary<string, int> sets = new Dictionary<string, int>();
/// <summary>
/// 获得堆叠系列列表
/// </summary>
/// <param name="Dictionary<int"></param>
/// <param name="stackSeries"></param>
public void GetStackSeries(ref Dictionary<int, List<Serie>> stackSeries)
{
int count = 0;
sets.Clear();
if (stackSeries == null)
{
stackSeries = new Dictionary<int, List<Serie>>(m_Series.Count);
}
else
{
foreach (var kv in stackSeries)
{
kv.Value.Clear();
}
}
for (int i = 0; i < m_Series.Count; i++)
{
var serie = m_Series[i];
serie.index = i;
if (string.IsNullOrEmpty(serie.stack))
{
if (!stackSeries.ContainsKey(count))
stackSeries[count] = new List<Serie>(m_Series.Count);
stackSeries[count].Add(serie);
count++;
}
else
{
if (!sets.ContainsKey(serie.stack))
{
sets.Add(serie.stack, count);
if (!stackSeries.ContainsKey(count))
stackSeries[count] = new List<Serie>(m_Series.Count);
stackSeries[count].Add(serie);
count++;
}
else
{
int stackIndex = sets[serie.stack];
stackSeries[stackIndex].Add(serie);
}
}
}
}
private List<string> serieNameList = new List<string>();
/// <summary>
/// 获得所有系列名,不包含空名字。
/// </summary>
/// <returns></returns>
public List<string> GetSerieNameList()
{
serieNameList.Clear();
foreach (var serie in m_Series)
{
if (!string.IsNullOrEmpty(serie.name) && !serieNameList.Contains(serie.name))
{
serieNameList.Add(serie.name);
}
foreach (var data in serie.data)
{
if (!string.IsNullOrEmpty(data.name) && !serieNameList.Contains(data.name))
{
serieNameList.Add(data.name);
}
}
}
return serieNameList;
}
/// <summary>
/// 设置获得标志图形大小的回调
/// </summary>
/// <param name="size"></param>
/// <param name="selectedSize"></param>
public void SetSerieSymbolSizeCallback(SymbolSizeCallback size, SymbolSizeCallback selectedSize)
{
foreach (var serie in m_Series)
{
serie.symbol.sizeCallback = size;
serie.symbol.selectedSizeCallback = selectedSize;
}
}
/// <summary>
/// 从json中解析数据
/// </summary>
/// <param name="jsonData"></param>
public override void ParseJsonData(string jsonData)
{
//TODO:
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 137f78d348f866943a9fb8c1c8eaceef
timeCreated: 1556016849
licenseType: Free
guid: 96ea96c66cf5d47c481d8d692a35ed93
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,603 @@
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.Serialization;
namespace XCharts
{
/// <summary>
/// 主题
/// </summary>
public enum Theme
{
/// <summary>
/// 默认主题。
/// </summary>
Default,
/// <summary>
/// 亮主题。
/// </summary>
Light,
/// <summary>
/// 暗主题。
/// </summary>
Dark
}
[Serializable]
/// <summary>
/// Theme.
/// 主题相关配置。
/// </summary>
public class ThemeInfo : IEquatable<ThemeInfo>
{
[SerializeField] private Theme m_Theme = Theme.Default;
[SerializeField] private Font m_Font;
[SerializeField] private Color32 m_BackgroundColor;
[FormerlySerializedAs("m_TextColor")]
[SerializeField] private Color32 m_TitleTextColor;
[SerializeField] private Color32 m_TitleSubTextColor;
[SerializeField] private Color32 m_LegendTextColor;
[SerializeField] private Color32 m_LegendUnableColor;
[SerializeField] private Color32 m_AxisTextColor;
[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_TooltipLabelColor;
[SerializeField] private Color32 m_TooltipLineColor;
[SerializeField] private Color32 m_DataZoomTextColor;
[SerializeField] private Color32 m_DataZoomLineColor;
[SerializeField] private Color32 m_DataZoomSelectedColor;
[SerializeField] private Color32[] m_ColorPalette;
[SerializeField] private Font m_CustomFont;
[SerializeField] private Color32 m_CustomBackgroundColor;
[FormerlySerializedAs("m_CustomTextColor")]
[SerializeField] private Color32 m_CustomTitleTextColor;
[SerializeField] private Color32 m_CustomTitleSubTextColor;
[SerializeField] private Color32 m_CustomLegendTextColor;
[SerializeField] private Color32 m_CustomLegendUnableColor;
[SerializeField] private Color32 m_CustomAxisTextColor;
[SerializeField] private Color32 m_CustomAxisLineColor;
[SerializeField] private Color32 m_CustomAxisSplitLineColor;
[SerializeField] private Color32 m_CustomTooltipBackgroundColor;
[SerializeField] private Color32 m_CustomTooltipFlagAreaColor;
[SerializeField] private Color32 m_CustomTooltipTextColor;
[SerializeField] private Color32 m_CustomTooltipLabelColor;
[SerializeField] private Color32 m_CustomTooltipLineColor;
[SerializeField] private Color32 m_CustomDataZoomTextColor;
[SerializeField] private Color32 m_CustomDataZoomLineColor;
[SerializeField] private Color32 m_CustomDataZoomSelectedColor;
[SerializeField] private List<Color32> m_CustomColorPalette = new List<Color32>(13);
/// <summary>
/// the theme of chart.
/// 主题类型。
/// </summary>
public Theme theme { get { return m_Theme; } set { m_Theme = value; } }
/// <summary>
/// the font of chart text。
/// 字体。
/// </summary>
public Font font
{
get { return m_CustomFont != null ? m_CustomFont : m_Font; }
set { m_CustomFont = value; }
}
/// <summary>
/// the background color of chart.
/// 背景颜色。
/// </summary>
public Color32 backgroundColor
{
get { return m_CustomBackgroundColor != Color.clear ? m_CustomBackgroundColor : m_BackgroundColor; }
set { m_CustomBackgroundColor = value; }
}
/// <summary>
/// the main title text color.
/// 主标题颜色。
/// </summary>
public Color32 titleTextColor
{
get { return m_CustomTitleTextColor != Color.clear ? m_CustomTitleTextColor : m_TitleTextColor; }
set { m_CustomTitleTextColor = value; }
}
/// <summary>
/// the subtitie text color.
/// 副标题颜色。
/// </summary>
public Color32 titleSubTextColor
{
get { return m_CustomTitleSubTextColor != Color.clear ? m_CustomTitleSubTextColor : m_TitleSubTextColor; }
set { m_CustomTitleSubTextColor = value; }
}
/// <summary>
/// the legend text color.
/// 图例文字的颜色。
/// </summary>
public Color32 legendTextColor
{
get { return m_CustomLegendTextColor != Color.clear ? m_CustomLegendTextColor : m_LegendTextColor; }
set { m_CustomLegendTextColor = value; }
}
/// <summary>
/// the legend unable text color.
/// 图例变为不可用时的按钮颜色。
/// </summary>
public Color32 legendUnableColor
{
get { return m_CustomLegendUnableColor != Color.clear ? m_CustomLegendUnableColor : m_LegendUnableColor; }
set { m_CustomLegendUnableColor = value; }
}
/// <summary>
/// the axis text color.
/// 坐标轴上标签的颜色。
/// </summary>
public Color32 axisTextColor
{
get { return m_CustomAxisTextColor != Color.clear ? m_CustomAxisTextColor : m_AxisTextColor; }
set { m_CustomAxisTextColor = value; }
}
/// <summary>
/// the color of axis line.
/// 坐标轴轴线的颜色。
/// </summary>
public Color32 axisLineColor
{
get { return m_CustomAxisLineColor != Color.clear ? m_CustomAxisLineColor : m_AxisLineColor; }
set { m_CustomAxisLineColor = value; }
}
/// <summary>
/// the color of axis split line.
/// 分割线的颜色,默认和坐标轴轴线颜色一致。
/// </summary>
public Color32 axisSplitLineColor
{
get { return m_CustomAxisSplitLineColor != Color.clear ? m_CustomAxisSplitLineColor : m_AxisSplitLineColor; }
set { m_CustomAxisSplitLineColor = value; }
}
/// <summary>
/// the tooltip background color.
/// 提示框背景颜色。
/// </summary>
public Color32 tooltipBackgroundColor
{
get { return m_CustomTooltipBackgroundColor != Color.clear ? m_CustomTooltipBackgroundColor : m_TooltipBackgroundColor; }
set { m_CustomTooltipBackgroundColor = value; }
}
/// <summary>
/// the color of tooltip shadow crosshair indicator.
/// 提示框阴影指示器的颜色。
/// </summary>
public Color32 tooltipFlagAreaColor
{
get { return m_CustomTooltipFlagAreaColor != Color.clear ? m_CustomTooltipFlagAreaColor : m_TooltipFlagAreaColor; }
set { m_CustomTooltipFlagAreaColor = value; }
}
/// <summary>
/// the color of tooltip text.
/// 提示框文字颜色。
/// </summary>
public Color32 tooltipTextColor
{
get { return m_CustomTooltipTextColor != Color.clear ? m_CustomTooltipTextColor : m_TooltipTextColor; }
set { m_CustomTooltipTextColor = value; }
}
/// <summary>
/// the background color of tooltip cross indicator's axis label.
/// 提示框的十字指示器坐标轴标签的背景颜色。
/// </summary>
public Color32 tooltipLabelColor
{
get { return m_CustomTooltipLabelColor != Color.clear ? m_CustomTooltipLabelColor : m_TooltipLabelColor; }
set { m_CustomTooltipLabelColor = value; }
}
/// <summary>
/// the color tooltip indicator line.
/// 提示框的指示线的颜色。
/// </summary>
public Color32 tooltipLineColor
{
get { return m_CustomTooltipLineColor != Color.clear ? m_CustomTooltipLineColor : m_TooltipLineColor; }
set { m_CustomTooltipLineColor = value; }
}
/// <summary>
/// the color of datazoom text.
/// 区域缩放的文字颜色。
/// </summary>
public Color32 dataZoomTextColor
{
get { return m_CustomDataZoomTextColor != Color.clear ? m_CustomDataZoomTextColor : m_DataZoomTextColor; }
set { m_CustomDataZoomTextColor = value; }
}
/// <summary>
/// the color of datazoom line.
/// 区域缩放的线条颜色。
/// </summary>
public Color32 dataZoomLineColor
{
get { return m_CustomDataZoomLineColor != Color.clear ? m_CustomDataZoomLineColor : m_DataZoomLineColor; }
set { m_CustomDataZoomLineColor = value; }
}
/// <summary>
/// the color of datazoom selected area.
/// 区域缩放的选中区域颜色。
/// </summary>
public Color32 dataZoomSelectedColor
{
get { return m_CustomDataZoomSelectedColor != Color.clear ? m_CustomDataZoomSelectedColor : m_DataZoomSelectedColor; }
set { m_CustomDataZoomSelectedColor = value; }
}
/// <summary>
/// The color list of palette. If no color is set in series, the colors would be adopted sequentially and circularly from this list as the colors of series.
/// 调色盘颜色列表。如果系列没有设置颜色,则会依次循环从该列表中取颜色作为系列颜色。
/// </summary>
public List<Color32> colorPalette { set { m_CustomColorPalette = value; } }
/// <summary>
/// Gets the color of the specified index from the palette.
/// 获得调色盘对应系列索引的颜色值。
/// </summary>
/// <param name="index">编号索引</param>
/// <returns>the color,or Color.clear when failed.颜色值失败时返回Color.clear</returns>
public Color32 GetColor(int index)
{
if (index < 0) index = 0;
var customIndex = index >= m_CustomColorPalette.Count ? index : index % m_CustomColorPalette.Count;
if (customIndex < m_CustomColorPalette.Count && m_CustomColorPalette[customIndex] != Color.clear)
{
return m_CustomColorPalette[customIndex];
}
else
{
var newIndex = index >= m_ColorPalette.Length ? index : index % m_ColorPalette.Length;
if (newIndex < m_ColorPalette.Length)
return m_ColorPalette[newIndex];
else return Color.clear;
}
}
Dictionary<int, string> _colorDic = new Dictionary<int, string>();
/// <summary>
/// Gets the hexadecimal color string of the specified index from the palette.
/// 获得指定索引的十六进制颜色值字符串。
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public string GetColorStr(int index)
{
if (index < 0)
{
index = 0;
}
index = index % m_ColorPalette.Length;
if (_colorDic.ContainsKey(index)) return _colorDic[index];
else
{
_colorDic[index] = ColorUtility.ToHtmlStringRGBA(GetColor(index));
return _colorDic[index];
}
}
/// <summary>
/// copy all configurations from theme.
/// 复制主题的所有配置。
/// </summary>
/// <param name="theme"></param>
public void Copy(ThemeInfo theme)
{
m_Theme = theme.theme;
m_Font = theme.m_Font;
m_BackgroundColor = theme.m_BackgroundColor;
m_LegendUnableColor = theme.m_LegendUnableColor;
m_TitleTextColor = theme.m_TitleTextColor;
m_TitleSubTextColor = theme.m_TitleSubTextColor;
m_LegendTextColor = theme.m_LegendTextColor;
m_AxisTextColor = theme.m_AxisTextColor;
m_AxisLineColor = theme.m_AxisLineColor;
m_AxisSplitLineColor = theme.m_AxisSplitLineColor;
m_TooltipBackgroundColor = theme.m_TooltipBackgroundColor;
m_TooltipTextColor = theme.m_TooltipTextColor;
m_TooltipLabelColor = theme.m_TooltipLabelColor;
m_TooltipLineColor = theme.m_TooltipLineColor;
m_DataZoomLineColor = theme.m_DataZoomLineColor;
m_DataZoomSelectedColor = theme.m_DataZoomSelectedColor;
m_DataZoomTextColor = theme.m_DataZoomTextColor;
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];
}
}
/// <summary>
/// Clear all custom configurations.
/// 重置,清除所有自定义配置。
/// </summary>
public void Reset()
{
m_Theme = Theme.Default;
m_Font = null;
m_BackgroundColor = Color.clear;
m_LegendUnableColor = Color.clear;
m_TitleTextColor = Color.clear;
m_TitleSubTextColor = Color.clear;
m_LegendTextColor = Color.clear;
m_AxisTextColor = Color.clear;
m_AxisLineColor = Color.clear;
m_AxisSplitLineColor = Color.clear;
m_TooltipBackgroundColor = Color.clear;
m_TooltipTextColor = Color.clear;
m_TooltipLabelColor = Color.clear;
m_TooltipLineColor = Color.clear;
m_DataZoomLineColor = Color.clear;
m_DataZoomSelectedColor = Color.clear;
m_DataZoomTextColor = Color.clear;
for (int i = 0; i < m_CustomColorPalette.Count; i++)
{
m_CustomColorPalette[i] = Color.clear;
}
}
/// <summary>
/// default theme.
/// 默认主题。
/// </summary>
/// <value></value>
public static ThemeInfo Default
{
get
{
return new ThemeInfo()
{
m_Theme = Theme.Default,
m_Font = Resources.GetBuiltinResource<Font>("Arial.ttf"),
m_BackgroundColor = new Color32(255, 255, 255, 255),
m_LegendUnableColor = GetColor("#cccccc"),
m_TitleTextColor = GetColor("#514D4D"),
m_TitleSubTextColor = GetColor("#514D4D"),
m_LegendTextColor = GetColor("#eee"),
m_AxisTextColor = GetColor("#514D4D"),
m_AxisLineColor = GetColor("#514D4D"),
m_AxisSplitLineColor = GetColor("#51515120"),
m_TooltipBackgroundColor = GetColor("#515151C8"),
m_TooltipTextColor = GetColor("#FFFFFFFF"),
m_TooltipFlagAreaColor = GetColor("#51515120"),
m_TooltipLabelColor = GetColor("#292929FF"),
m_TooltipLineColor = GetColor("#29292964"),
m_DataZoomLineColor = GetColor("#51515120"),
m_DataZoomSelectedColor = GetColor("#51515120"),
m_DataZoomTextColor = GetColor("#514D4D"),
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)
},
m_CustomColorPalette = new List<Color32>{
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear
}
};
}
}
/// <summary>
/// light theme.
/// 亮主题。
/// </summary>
/// <value></value>
public static ThemeInfo Light
{
get
{
return new ThemeInfo()
{
m_Theme = Theme.Light,
m_Font = Resources.GetBuiltinResource<Font>("Arial.ttf"),
m_BackgroundColor = new Color32(255, 255, 255, 255),
m_LegendUnableColor = GetColor("#cccccc"),
m_TitleTextColor = GetColor("#514D4D"),
m_TitleSubTextColor = GetColor("#514D4D"),
m_LegendTextColor = GetColor("#514D4D"),
m_AxisTextColor = GetColor("#514D4D"),
m_AxisLineColor = GetColor("#514D4D"),
m_AxisSplitLineColor = GetColor("#51515120"),
m_TooltipBackgroundColor = GetColor("#515151C8"),
m_TooltipTextColor = GetColor("#FFFFFFFF"),
m_TooltipFlagAreaColor = GetColor("#51515120"),
m_TooltipLabelColor = GetColor("#292929FF"),
m_TooltipLineColor = GetColor("#29292964"),
m_DataZoomLineColor = GetColor("#51515120"),
m_DataZoomSelectedColor = GetColor("#51515120"),
m_DataZoomTextColor = GetColor("#514D4D"),
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)
},
m_CustomColorPalette = new List<Color32>{
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear
}
};
}
}
/// <summary>
/// dark theme.
/// 暗主题。
/// </summary>
/// <value></value>
public static ThemeInfo Dark
{
get
{
return new ThemeInfo()
{
m_Theme = Theme.Dark,
m_Font = Resources.GetBuiltinResource<Font>("Arial.ttf"),
m_LegendUnableColor = GetColor("#cccccc"),
m_BackgroundColor = new Color32(34, 34, 34, 255),
m_TitleTextColor = GetColor("#eee"),
m_TitleSubTextColor = GetColor("#eee"),
m_LegendTextColor = GetColor("#eee"),
m_AxisTextColor = GetColor("#eee"),
m_AxisLineColor = GetColor("#eee"),
m_AxisSplitLineColor = GetColor("#aaa"),
m_TooltipBackgroundColor = GetColor("#515151C8"),
m_TooltipTextColor = GetColor("#FFFFFFFF"),
m_TooltipFlagAreaColor = GetColor("#51515120"),
m_TooltipLabelColor = GetColor("#A7A7A7FF"),
m_TooltipLineColor = GetColor("#eee"),
m_DataZoomLineColor = GetColor("#FFFFFF45"),
m_DataZoomSelectedColor = GetColor("#D0D0D03D"),
m_DataZoomTextColor = GetColor("#FFFFFFFF"),
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)
},
m_CustomColorPalette = new List<Color32>{
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear
}
};
}
}
/// <summary>
/// Convert the html string to color.
/// 将字符串颜色值转成Color。
/// </summary>
/// <param name="hexColorStr"></param>
/// <returns></returns>
public static Color32 GetColor(string hexColorStr)
{
Color color;
ColorUtility.TryParseHtmlString(hexColorStr, out color);
return (Color32)color;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
else if (obj is ThemeInfo)
{
return Equals((ThemeInfo)obj);
}
else
{
return false;
}
}
public bool Equals(ThemeInfo other)
{
if (ReferenceEquals(null, other))
{
return false;
}
return m_Font == other.m_Font &&
ChartHelper.IsValueEqualsColor(m_LegendUnableColor, other.m_LegendUnableColor) &&
ChartHelper.IsValueEqualsColor(m_BackgroundColor, other.m_BackgroundColor) &&
ChartHelper.IsValueEqualsColor(m_TitleTextColor, other.m_TitleTextColor) &&
ChartHelper.IsValueEqualsColor(m_TitleSubTextColor, other.m_TitleSubTextColor) &&
ChartHelper.IsValueEqualsColor(m_AxisTextColor, other.m_AxisTextColor) &&
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) &&
ChartHelper.IsValueEqualsColor(m_DataZoomLineColor, other.m_DataZoomLineColor) &&
ChartHelper.IsValueEqualsColor(m_DataZoomSelectedColor, other.m_DataZoomSelectedColor) &&
ChartHelper.IsValueEqualsColor(m_DataZoomTextColor, other.m_DataZoomTextColor) &&
m_ColorPalette.Length == other.m_ColorPalette.Length;
}
public static bool operator ==(ThemeInfo left, ThemeInfo right)
{
if (ReferenceEquals(left, null) && ReferenceEquals(right, null))
{
return true;
}
else if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
{
return false;
}
return Equals(left, right);
}
public static bool operator !=(ThemeInfo left, ThemeInfo right)
{
return !(left == right);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 337565e835799d44bb794677abf84498
timeCreated: 1554221927
licenseType: Free
guid: abf18feda656241b0be785d95b57aab9
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -3,10 +3,14 @@ using System;
namespace XCharts
{
/// <summary>
/// Title component, including main title and subtitle.
/// 标题组件,包含主标题和副标题。
/// </summary>
[Serializable]
public class Title : IPropertyChanged, IEquatable<Title>
{
[SerializeField] private bool m_Show;
[SerializeField] private bool m_Show = true;
[SerializeField] private string m_Text;
[SerializeField] private int m_TextFontSize;
[SerializeField] private string m_SubText;
@@ -14,12 +18,44 @@ namespace XCharts
[SerializeField] private float m_ItemGap;
[SerializeField] private Location m_Location;
/// <summary>
/// [default:true]
/// Set this to false to prevent the title from showing.
/// 是否显示标题组件。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// The main title text, supporting for \n for newlines.
/// 主标题文本,支持使用 \n 换行。
/// </summary>
public string text { get { return m_Text; } set { m_Text = value; } }
/// <summary>
/// [default:16]
/// main title font size.
/// 主标题文字的字体大小。
/// </summary>
public int textFontSize { get { return m_TextFontSize; } set { m_TextFontSize = value; } }
/// <summary>
/// Subtitle text, supporting for \n for newlines.
/// 副标题文本,支持使用 \n 换行。
/// </summary>
public string subText { get { return m_SubText; } set { m_Text = value; } }
/// <summary>
/// [default:14]
/// subtitle font size.
/// 副标题文字的字体大小。
/// </summary>
public int subTextFontSize { get { return m_SubTextFontSize; } set { m_SubTextFontSize = value; } }
/// <summary>
/// [default:14]
/// The gap between the main title and subtitle.
/// 主副标题之间的间距。
/// </summary>
public float itemGap { get { return m_ItemGap; } set { m_ItemGap = value; } }
/// <summary>
/// The location of title component.
/// 标题显示位置。
/// </summary>
public Location location { get { return m_Location; } set { m_Location = value; } }
public static Title defaultTitle

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 1e41a7f82b5a931408f301257fbc09e2
timeCreated: 1554222818
licenseType: Free
guid: d24bcb046d3e74a898fc64f02a2a5985
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,278 @@
using System.Collections.Generic;
using System;
using UnityEngine;
using UnityEngine.UI;
namespace XCharts
{
/// <summary>
/// Tooltip component.
/// 提示框组件
/// </summary>
[System.Serializable]
public class Tooltip
{
/// <summary>
/// Indicator type.
/// 阴影指示器。
/// </summary>
public enum Type
{
/// <summary>
/// line indicator.
/// 直线指示器
/// </summary>
Line,
/// <summary>
/// shadow crosshair indicator.
/// 阴影指示器
/// </summary>
Shadow,
/// <summary>
/// no indicator displayed.
/// 无指示器
/// </summary>
None,
/// <summary>
/// crosshair indicator, which is actually the shortcut of enable two axisPointers of two orthometric axes.
/// 十字准星指示器。坐标轴显示Label和交叉线。
/// </summary>
Corss
}
[SerializeField] private bool m_Show;
[SerializeField] private Type m_Type;
private GameObject m_GameObject;
private GameObject m_Content;
private Text m_ContentText;
private RectTransform m_ContentRect;
private List<int> lastDataIndex { get; set; }
/// <summary>
/// Whether to show the tooltip component.
/// 是否显示提示框组件。
/// </summary>
/// <returns></returns>
public bool show { get { return m_Show; } set { m_Show = value; SetActive(value); } }
/// <summary>
/// Indicator type.
/// 提示框指示器类型。
/// </summary>
public Type type { get { return m_Type; } set { m_Type = value; } }
/// <summary>
/// The data index currently indicated by Tooltip.
/// 当前提示框所指示的数据项索引。
/// </summary>
public List<int> dataIndex { get; set; }
/// <summary>
/// the value for x indicator label.
/// 指示器X轴上要显示的值。
/// </summary>
public float[] xValues { get; set; }
/// <summary>
/// the value for y indicator label.
/// 指示器Y轴上要显示的值。
/// </summary>
public float[] yValues { get; set; }
/// <summary>
/// the current pointer position.
/// 当前鼠标位置。
/// </summary>
public Vector2 pointerPos { get; set; }
/// <summary>
/// the width of tooltip.
/// 提示框宽。
/// </summary>
public float width { get { return m_ContentRect.sizeDelta.x; } }
/// <summary>
/// the height of tooltip.
/// 提示框高。
/// </summary>
public float height { get { return m_ContentRect.sizeDelta.y; } }
/// <summary>
/// Whether the tooltip has been initialized.
/// 提示框是否已初始化。
/// </summary>
public bool inited { get { return m_GameObject != null; } }
/// <summary>
/// the gameObject of tooltip.
/// 提示框的gameObject。
/// </summary>
public GameObject gameObject { get { return m_GameObject; } }
public static Tooltip defaultTooltip
{
get
{
var tooltip = new Tooltip
{
m_Show = true,
xValues = new float[2],
yValues = new float[2],
dataIndex = new List<int>() { -1, -1 },
lastDataIndex = new List<int>() { -1, -1 }
};
return tooltip;
}
}
/// <summary>
/// 绑定提示框gameObject
/// </summary>
/// <param name="obj"></param>
public void SetObj(GameObject obj)
{
m_GameObject = obj;
m_GameObject.SetActive(false);
}
/// <summary>
/// 绑定提示框的文本框gameObject
/// </summary>
/// <param name="content"></param>
public void SetContentObj(GameObject content)
{
m_Content = content;
m_ContentRect = m_Content.GetComponent<RectTransform>();
m_ContentText = m_Content.GetComponentInChildren<Text>();
}
/// <summary>
/// Keep Tooltiop displayed at the top.
/// 保持Tooltiop显示在最顶上
/// </summary>
public void UpdateToTop()
{
int count = m_GameObject.transform.parent.childCount;
m_GameObject.GetComponent<RectTransform>().SetSiblingIndex(count - 1);
}
/// <summary>
/// 设置提示框文本背景色
/// </summary>
/// <param name="color"></param>
public void SetContentBackgroundColor(Color color)
{
m_Content.GetComponent<Image>().color = color;
}
/// <summary>
/// 设置提示框文本字体颜色
/// </summary>
/// <param name="color"></param>
public void SetContentTextColor(Color color)
{
if (m_ContentText)
{
m_ContentText.color = color;
}
}
/// <summary>
/// 设置提示框文本内容
/// </summary>
/// <param name="txt"></param>
public void UpdateContentText(string txt)
{
if (m_ContentText)
{
m_ContentText.text = txt;
m_ContentRect.sizeDelta = new Vector2(m_ContentText.preferredWidth + 8,
m_ContentText.preferredHeight + 8);
}
}
/// <summary>
/// 清除提示框指示数据
/// </summary>
public void ClearValue()
{
dataIndex[0] = dataIndex[1] = -1;
xValues[0] = xValues[1] = -1;
yValues[0] = yValues[1] = -1;
}
/// <summary>
/// 提示框是否显示
/// </summary>
/// <returns></returns>
public bool IsActive()
{
return m_GameObject != null && m_GameObject.activeInHierarchy;
}
/// <summary>
/// 设置提示框是否显示
/// </summary>
/// <param name="flag"></param>
public void SetActive(bool flag)
{
lastDataIndex[0] = lastDataIndex[1] = -1;
if (m_GameObject && m_GameObject.activeInHierarchy != flag)
m_GameObject.SetActive(flag);
}
/// <summary>
/// 更新文本框位置
/// </summary>
/// <param name="pos"></param>
public void UpdateContentPos(Vector2 pos)
{
if (m_Content)
m_Content.transform.localPosition = pos;
}
/// <summary>
/// 获得当前提示框的位置
/// </summary>
/// <returns></returns>
public Vector3 GetContentPos()
{
if (m_Content)
return m_Content.transform.localPosition;
else
return Vector3.zero;
}
/// <summary>
/// Whether the data item indicated by tooltip has changed.
/// 提示框所指示的数据项是否发生变化。
/// </summary>
/// <returns></returns>
public bool IsDataIndexChanged()
{
return dataIndex[0] != lastDataIndex[0] ||
dataIndex[1] != lastDataIndex[1];
}
/// <summary>
/// 当前索引缓存
/// </summary>
public void UpdateLastDataIndex()
{
lastDataIndex[0] = dataIndex[0];
lastDataIndex[1] = dataIndex[1];
}
/// <summary>
/// 当前提示框是否选中数据项
/// </summary>
/// <returns></returns>
public bool IsSelected()
{
return dataIndex[0] >= 0 || dataIndex[1] >= 0;
}
/// <summary>
/// 指定索引的数据项是否被提示框选中
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public bool IsSelected(int index)
{
return dataIndex[0] == index || dataIndex[1] == index;
}
}
}

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 015f1aafb9c2e8940be9ef79b984b843
timeCreated: 1554222818
licenseType: Free
guid: 1ffc80b624e394046a373c94978bbb04
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,5 +1,8 @@
namespace XCharts
{
/// <summary>
/// 从json导入数据接口
/// </summary>
public interface IJsonData
{
void ParseJsonData(string json);

View File

@@ -1,5 +1,8 @@
namespace XCharts
{
/// <summary>
/// 属性变更接口
/// </summary>
public interface IPropertyChanged
{
void OnChanged();

View File

@@ -0,0 +1,83 @@
using UnityEngine;
namespace XCharts
{
/// <summary>
/// The style of area.
/// 区域填充样式。
/// </summary>
[System.Serializable]
public class AreaStyle
{
/// <summary>
/// Origin position of area.
/// 图形区域的起始位置。默认情况下,图形会从坐标轴轴线到数据间进行填充。如果需要填充的区域是坐标轴最大值到数据间,或者坐标轴最小值到数据间,则可以通过这个配置项进行设置。
/// </summary>
public enum AreaOrigin
{
/// <summary>
/// to fill between axis line to data.
/// 填充坐标轴轴线到数据间的区域。
/// </summary>
Auto,
/// <summary>
/// to fill between min axis value (when not inverse) to data.
/// 填充坐标轴底部到数据间的区域。
/// </summary>
Start,
/// <summary>
/// to fill between max axis value (when not inverse) to data.
/// 填充坐标轴顶部到数据间的区域。
/// </summary>
End
}
[SerializeField] private bool m_Show;
[SerializeField] private AreaOrigin m_Origin;
[SerializeField] private Color m_Color;
[SerializeField] private Color m_ToColor;
[SerializeField][Range(0,1)] private float m_Opacity;
/// <summary>
/// Set this to false to prevent the areafrom showing.
/// 是否显示区域填充。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
///
/// 图形区域的起始位置。
/// </summary>
public AreaOrigin origin { get { return m_Origin; } set { m_Origin = value; } }
/// <summary>
/// the color of area,default use serie color.
/// 区域填充的颜色如果toColor不是默认值则表示渐变色的起点颜色。
/// </summary>
public Color color { get { return m_Color; } set { m_Color = value; } }
/// <summary>
/// Gradient color, start color to toColor.
/// 渐变色的终点颜色。
/// </summary>
/// <value></value>
public Color toColor { get { return m_ToColor; } set { m_ToColor = value; } }
/// <summary>
/// Opacity of the component. Supports value from 0 to 1, and the component will not be drawn when set to 0.
/// 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。
/// </summary>
public float opactiy { get { return m_Opacity; } set { m_Opacity = value; } }
public static AreaStyle defaultAreaStyle
{
get
{
var area = new AreaStyle
{
m_Show = false,
m_Color = Color.clear,
m_ToColor = Color.clear,
m_Opacity = 1
};
return area;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 031cbc008c7d34cb0ad96257d0bfa6d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,612 +0,0 @@
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 AxisMinMaxType
{
Default,
MinMax,
Custom
}
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;
}
}
}
[System.Serializable]
public class AxisLine
{
[SerializeField] private bool m_Show;
[SerializeField] private bool m_Symbol;
[SerializeField] private float m_SymbolWidth;
[SerializeField] private float m_SymbolHeight;
[SerializeField] private float m_SymbolOffset;
[SerializeField] private float m_SymbolDent;
public bool show { get { return m_Show; } set { m_Show = value; } }
public bool symbol { get { return m_Symbol; } set { m_Symbol = value; } }
public float symbolWidth { get { return m_SymbolWidth; } set { m_SymbolWidth = value; } }
public float symbolHeight { get { return m_SymbolHeight; } set { m_SymbolHeight = value; } }
public float symbolOffset { get { return m_SymbolOffset; } set { m_SymbolOffset = value; } }
public float symbolDent { get { return m_SymbolDent; } set { m_SymbolDent = value; } }
public static AxisLine defaultAxisLine
{
get
{
var axisLine = new AxisLine
{
m_Show = true,
m_Symbol = false,
m_SymbolWidth = 10,
m_SymbolHeight = 15,
m_SymbolOffset = 0,
m_SymbolDent = 3,
};
return axisLine;
}
}
}
[Serializable]
public class AxisName
{
[Serializable]
public enum Location
{
Start,
Middle,
End
}
[SerializeField] private bool m_Show;
[SerializeField] private string m_Name;
[SerializeField] private Location m_Location;
[SerializeField] private float m_Gap;
[SerializeField] private float m_Rotate;
[SerializeField] private Color m_Color;
[SerializeField] private int m_FontSize;
[SerializeField] private FontStyle m_FontStyle;
public bool show { get { return m_Show; } set { m_Show = value; } }
public string name { get { return m_Name; } set { m_Name = value; } }
public Location location { get { return m_Location; } set { m_Location = value; } }
public float gap { get { return m_Gap; } set { m_Gap = value; } }
public float rotate { get { return m_Rotate; } set { m_Rotate = value; } }
public Color color { get { return m_Color; } set { m_Color = value; } }
public int fontSize { get { return m_FontSize; } set { m_FontSize = value; } }
public FontStyle fontStyle { get { return m_FontStyle; } set { m_FontStyle = value; } }
public static AxisName defaultAxisName
{
get
{
return new AxisName()
{
m_Show = false,
m_Name = "axisName",
m_Location = Location.End,
m_Gap = 5,
m_Rotate = 0,
m_Color = Color.clear,
m_FontSize = 18,
m_FontStyle = FontStyle.Normal
};
}
}
public void Copy(AxisName other)
{
m_Show = other.show;
m_Name = other.name;
m_Location = other.location;
m_Gap = other.gap;
m_Rotate = other.rotate;
m_Color = other.color;
m_FontSize = other.fontSize;
m_FontStyle = other.fontStyle;
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var other = (AxisName)obj;
return m_Show == other.show &&
m_Name.Equals(other.name) &&
m_Location == other.location &&
m_Gap == other.gap &&
m_Rotate == other.rotate &&
m_Color == other.color &&
m_FontSize == other.fontSize &&
m_FontStyle == other.fontStyle;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
/// <summary>
/// Split area of axis in grid area, not shown by default.
/// </summary>
[Serializable]
public class SplitArea
{
[SerializeField] private bool m_Show;
[SerializeField] private List<Color> m_Color;
/// <summary>
/// Set this to true to show the splitArea.
/// </summary>
/// <value>false</value>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// Color of split area. SplitArea color could also be set in color array,
/// which the split lines would take as their colors in turns.
/// Dark and light colors in turns are used by default.
/// </summary>
/// <value>['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)']</value>
public List<Color> color { get { return m_Color; } set { m_Color = value; } }
public static SplitArea defaultSplitArea
{
get
{
return new SplitArea()
{
m_Show = false,
m_Color = new List<Color>(){
new Color32(250,250,250,77),
new Color32(200,200,200,77)
}
};
}
}
public Color getColor(int index)
{
var i = index % color.Count;
return color[i];
}
}
[Serializable]
public class AxisLabel
{
[SerializeField] private bool m_Show;
[SerializeField] private int m_Interval;
[SerializeField] private bool m_Inside;
[SerializeField] private float m_Rotate;
[SerializeField] private float m_Margin;
[SerializeField] private Color m_Color;
[SerializeField] private int m_FontSize;
[SerializeField] private FontStyle m_FontStyle;
public bool show { get { return m_Show; } set { m_Show = value; } }
public int interval { get { return m_Interval; } set { m_Interval = value; } }
public bool inside { get { return m_Inside; } set { m_Inside = value; } }
public float rotate { get { return m_Rotate; } set { m_Rotate = value; } }
public float margin { get { return m_Margin; } set { m_Margin = value; } }
public Color color { get { return m_Color; } set { m_Color = value; } }
public int fontSize { get { return m_FontSize; } set { m_FontSize = value; } }
public FontStyle fontStyle { get { return m_FontStyle; } set { m_FontStyle = value; } }
public static AxisLabel defaultAxisLabel
{
get
{
return new AxisLabel()
{
m_Show = true,
m_Interval = 0,
m_Inside = false,
m_Rotate = 0,
m_Margin = 8,
m_Color = Color.clear,
m_FontSize = 18,
m_FontStyle = FontStyle.Normal
};
}
}
public void Copy(AxisLabel other)
{
m_Show = other.show;
m_Interval = other.interval;
m_Inside = other.inside;
m_Rotate = other.rotate;
m_Margin = other.margin;
m_Color = other.color;
m_FontSize = other.fontSize;
m_FontStyle = other.fontStyle;
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var other = (AxisLabel)obj;
return m_Show == other.show &&
m_Interval.Equals(other.interval) &&
m_Inside == other.inside &&
m_Rotate == other.rotate &&
m_Margin == other.margin &&
m_Color == other.color &&
m_FontSize == other.fontSize &&
m_FontStyle == other.fontStyle;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
[SerializeField] protected bool m_Show = true;
[SerializeField] protected AxisType m_Type;
[SerializeField] protected AxisMinMaxType m_MinMaxType;
[SerializeField] protected int m_Min;
[SerializeField] protected int m_Max;
[SerializeField] protected int m_SplitNumber = 5;
[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 AxisLine m_AxisLine = AxisLine.defaultAxisLine;
[SerializeField] protected AxisName m_AxisName = AxisName.defaultAxisName;
[SerializeField] protected AxisTick m_AxisTick = AxisTick.defaultTick;
[SerializeField] protected AxisLabel m_AxisLabel = AxisLabel.defaultAxisLabel;
[SerializeField] protected SplitArea m_SplitArea = SplitArea.defaultSplitArea;
public bool show { get { return m_Show; } set { m_Show = value; } }
public AxisType type { get { return m_Type; } set { m_Type = value; } }
public AxisMinMaxType minMaxType { get { return m_MinMaxType; } set { m_MinMaxType = value; } }
public int min { get { return m_Min; } set { m_Min = value; } }
public int max { get { return m_Max; } set { m_Max = value; } }
public int splitNumber { get { return m_SplitNumber; } set { m_SplitNumber = 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 AxisLine axisLine { get { return m_AxisLine; } set { m_AxisLine = value; } }
public AxisName axisName { get { return m_AxisName; } set { m_AxisName = value; } }
public AxisTick axisTick { get { return m_AxisTick; } set { m_AxisTick = value; } }
public AxisLabel axisLabel { get { return m_AxisLabel; } set { m_AxisLabel = value; } }
public SplitArea splitArea { get { return m_SplitArea; } set { m_SplitArea = value; } }
public int filterStart { get; set; }
public int filterEnd { get; set; }
public List<string> filterData { get; set; }
public void Copy(Axis other)
{
m_Show = other.show;
m_Type = other.type;
m_Min = other.min;
m_Max = other.max;
m_SplitNumber = other.splitNumber;
m_ShowSplitLine = other.showSplitLine;
m_SplitLineType = other.splitLineType;
m_BoundaryGap = other.boundaryGap;
m_AxisName.Copy(other.axisName);
m_AxisLabel.Copy(other.axisLabel);
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, DataZoom dataZoom)
{
var showData = GetData(dataZoom);
if (index >= 0 && index < showData.Count)
return showData[index];
else
return "";
}
public List<string> GetData(DataZoom dataZoom)
{
if (dataZoom != null && dataZoom.show)
{
var startIndex = (int)((data.Count - 1) * dataZoom.start / 100);
var endIndex = (int)((data.Count - 1) * dataZoom.end / 100);
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
if (filterData == null || filterData.Count != count)
{
UpdateFilterData(dataZoom);
}
return filterData;
}
else
{
return m_Data;
}
}
public void UpdateFilterData(DataZoom dataZoom)
{
if (dataZoom != null && dataZoom.show)
{
var startIndex = (int)((data.Count - 1) * dataZoom.start / 100);
var endIndex = (int)((data.Count - 1) * dataZoom.end / 100);
if (startIndex != filterStart || endIndex != filterEnd)
{
filterStart = startIndex;
filterEnd = endIndex;
if (m_Data.Count > 0)
{
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
filterData = m_Data.GetRange(startIndex, count);
}
else
{
filterData = m_Data;
}
}
else if (endIndex == 0)
{
filterData = new List<string>();
}
}
}
public int GetSplitNumber(DataZoom dataZoom)
{
if (type == AxisType.Value) return m_SplitNumber;
int dataCount = GetData(dataZoom).Count;
if (dataCount > 2 * m_SplitNumber || dataCount <= 0)
return m_SplitNumber;
else
return dataCount;
}
public float GetSplitWidth(float coordinateWidth, DataZoom dataZoom)
{
return coordinateWidth / (m_BoundaryGap ? GetSplitNumber(dataZoom) : GetSplitNumber(dataZoom) - 1);
}
public int GetDataNumber(DataZoom dataZoom)
{
return GetData(dataZoom).Count;
}
public float GetDataWidth(float coordinateWidth, DataZoom dataZoom)
{
var dataCount = GetDataNumber(dataZoom);
return coordinateWidth / (m_BoundaryGap ? dataCount : dataCount - 1);
}
public string GetScaleName(int index, float minValue, float maxValue, DataZoom dataZoom)
{
if (m_Type == AxisType.Value)
{
float value = (minValue + (maxValue - minValue) * index / (GetSplitNumber(dataZoom) - 1));
if (value - (int)value == 0)
return (value).ToString();
else
return (value).ToString("f1");
}
var showData = GetData(dataZoom);
int dataCount = showData.Count;
if (dataCount <= 0) return "";
if (index == GetSplitNumber(dataZoom) - 1 && !m_BoundaryGap)
{
return showData[dataCount - 1];
}
else
{
float rate = dataCount / GetSplitNumber(dataZoom);
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 showData[newIndex];
}
}
public int GetScaleNumber(DataZoom dataZoom)
{
if (type == AxisType.Value)
{
return m_BoundaryGap ? m_SplitNumber + 1 : m_SplitNumber;
}
else
{
var showData = GetData(dataZoom);
int dataCount = showData.Count;
if (dataCount > 2 * splitNumber || dataCount <= 0)
return m_BoundaryGap ? m_SplitNumber + 1 : m_SplitNumber;
else
return m_BoundaryGap ? dataCount + 1 : dataCount;
}
}
public float GetScaleWidth(float coordinateWidth, DataZoom dataZoom)
{
int num = GetScaleNumber(dataZoom) - 1;
if (num <= 0) num = 1;
return coordinateWidth / num;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
else if (obj is Axis)
{
return Equals((Axis)obj);
}
else
{
return false;
}
}
public bool Equals(Axis other)
{
if (ReferenceEquals(null, other))
{
return false;
}
return show == other.show &&
type == other.type &&
min == other.min &&
max == other.max &&
splitNumber == other.splitNumber &&
showSplitLine == other.showSplitLine &&
m_AxisLabel.Equals(other.axisLabel) &&
splitLineType == other.splitLineType &&
boundaryGap == other.boundaryGap &&
axisName.Equals(other.axisName) &&
ChartHelper.IsValueEqualsList<string>(m_Data, other.data);
}
public static bool operator ==(Axis left, Axis right)
{
if (ReferenceEquals(left, null) && ReferenceEquals(right, null))
{
return true;
}
else if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
{
return false;
}
return Equals(left, right);
}
public static bool operator !=(Axis left, Axis right)
{
return !(left == right);
}
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_Min = 0,
m_Max = 0,
m_SplitNumber = 5,
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_Min = 0,
m_Max = 0,
m_SplitNumber = 5,
m_ShowSplitLine = false,
m_SplitLineType = SplitLineType.Dashed,
m_BoundaryGap = false,
m_Data = new List<string>(5),
};
return axis;
}
}
}
}

View File

@@ -0,0 +1,114 @@
using System;
using UnityEngine;
namespace XCharts
{
/// <summary>
/// Settings related to axis label.
/// 坐标轴刻度标签的相关设置。
/// </summary>
[Serializable]
public class AxisLabel
{
[SerializeField] private bool m_Show = true;
[SerializeField] private int m_Interval = 0;
[SerializeField] private bool m_Inside = false;
[SerializeField] private float m_Rotate;
[SerializeField] private float m_Margin;
[SerializeField] private Color m_Color;
[SerializeField] private int m_FontSize;
[SerializeField] private FontStyle m_FontStyle;
/// <summary>
/// Set this to false to prevent the axis label from appearing.
/// 是否显示刻度标签。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// The display interval of the axis label.
/// 坐标轴刻度标签的显示间隔在类目轴中有效。0表示显示所有标签1表示隔一个隔显示一个标签以此类推。
/// </summary>
public int interval { get { return m_Interval; } set { m_Interval = value; } }
/// <summary>
/// Set this to true so the axis labels face the inside direction.
/// 刻度标签是否朝内,默认朝外。
/// </summary>
public bool inside { get { return m_Inside; } set { m_Inside = value; } }
/// <summary>
/// Rotation degree of axis label, which is especially useful when there is no enough space for category axis.
/// 刻度标签旋转的角度,在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠。
/// </summary>
public float rotate { get { return m_Rotate; } set { m_Rotate = value; } }
/// <summary>
/// The margin between the axis label and the axis line.
/// 刻度标签与轴线之间的距离。
/// </summary>
public float margin { get { return m_Margin; } set { m_Margin = value; } }
/// <summary>
/// the color of axis label text.
/// 刻度标签文字的颜色默认取Theme的axisTextColor。
/// </summary>
public Color color { get { return m_Color; } set { m_Color = value; } }
/// <summary>
/// font size.
/// 文字的字体大小。
/// </summary>
public int fontSize { get { return m_FontSize; } set { m_FontSize = value; } }
/// <summary>
/// font style.
/// 文字字体的风格。
/// </summary>
public FontStyle fontStyle { get { return m_FontStyle; } set { m_FontStyle = value; } }
public static AxisLabel defaultAxisLabel
{
get
{
return new AxisLabel()
{
m_Show = true,
m_Interval = 0,
m_Inside = false,
m_Rotate = 0,
m_Margin = 8,
m_Color = Color.clear,
m_FontSize = 18,
m_FontStyle = FontStyle.Normal
};
}
}
public void Copy(AxisLabel other)
{
m_Show = other.show;
m_Interval = other.interval;
m_Inside = other.inside;
m_Rotate = other.rotate;
m_Margin = other.margin;
m_Color = other.color;
m_FontSize = other.fontSize;
m_FontStyle = other.fontStyle;
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var other = (AxisLabel)obj;
return m_Show == other.show &&
m_Interval.Equals(other.interval) &&
m_Inside == other.inside &&
m_Rotate == other.rotate &&
m_Margin == other.margin &&
m_Color == other.color &&
m_FontSize == other.fontSize &&
m_FontStyle == other.fontStyle;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db5e17c2b8ab840598b3dba837294b98
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
using UnityEngine;
namespace XCharts
{
/// <summary>
/// Settings related to axis line.
/// 坐标轴的分隔线。
/// </summary>
[System.Serializable]
public class AxisLine
{
[SerializeField] private bool m_Show;
[SerializeField] private bool m_OnZero;
[SerializeField] private float m_Width = 0.6f;
[SerializeField] private bool m_Symbol;
[SerializeField] private float m_SymbolWidth;
[SerializeField] private float m_SymbolHeight;
[SerializeField] private float m_SymbolOffset;
[SerializeField] private float m_SymbolDent;
/// <summary>
/// Set this to false to prevent the axis line from showing.
/// 是否显示坐标轴轴线。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// When mutiple axes exists, this option can be used to specify which axis can be "onZero" to.
/// X 轴或者 Y 轴的轴线是否在另一个轴的 0 刻度上,只有在另一个轴为数值轴且包含 0 刻度时有效。
/// </summary>
public bool onZero { get { return m_OnZero; } set { m_OnZero = value; } }
/// <summary>
/// line style line width.
/// 坐标轴线线宽。
/// </summary>
public float width { get { return m_Width; } set { m_Width = value; } }
/// <summary>
/// Whether to show the arrow symbol of axis.
/// 是否显示箭头。
/// </summary>
public bool symbol { get { return m_Symbol; } set { m_Symbol = value; } }
/// <summary>
/// the width of arrow symbol.
/// 箭头宽。
/// </summary>
public float symbolWidth { get { return m_SymbolWidth; } set { m_SymbolWidth = value; } }
/// <summary>
/// the height of arrow symbol.
/// 箭头高。
/// </summary>
public float symbolHeight { get { return m_SymbolHeight; } set { m_SymbolHeight = value; } }
/// <summary>
/// the offset of arrow symbol.
/// 箭头偏移。
/// </summary>
public float symbolOffset { get { return m_SymbolOffset; } set { m_SymbolOffset = value; } }
/// <summary>
/// the dent of arrow symbol.
/// 箭头的凹陷程度。
/// </summary>
public float symbolDent { get { return m_SymbolDent; } set { m_SymbolDent = value; } }
public static AxisLine defaultAxisLine
{
get
{
var axisLine = new AxisLine
{
m_Show = true,
m_OnZero = true,
m_Width = 0.7f,
m_Symbol = false,
m_SymbolWidth = 10,
m_SymbolHeight = 15,
m_SymbolOffset = 0,
m_SymbolDent = 3,
};
return axisLine;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 099051c3869774418aac3d53375d1ba9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,125 @@
using System;
using UnityEngine;
namespace XCharts
{
/// <summary>
/// the name of axis.
/// 坐标轴名称。
/// </summary>
[Serializable]
public class AxisName
{
/// <summary>
/// the location of axis name.
/// 坐标轴名称显示位置。
/// </summary>
public enum Location
{
Start,
Middle,
End
}
[SerializeField] private bool m_Show;
[SerializeField] private string m_Name;
[SerializeField] private Location m_Location;
[SerializeField] private float m_Gap;
[SerializeField] private float m_Rotate;
[SerializeField] private Color m_Color;
[SerializeField] private int m_FontSize;
[SerializeField] private FontStyle m_FontStyle;
/// <summary>
/// Whether to show axis name.
/// 是否显示坐标名称。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// the name of axis.
/// 坐标轴名称。
/// </summary>
public string name { get { return m_Name; } set { m_Name = value; } }
/// <summary>
/// Location of axis name.
/// 坐标轴名称显示位置。
/// </summary>
public Location location { get { return m_Location; } set { m_Location = value; } }
/// <summary>
/// Gap between axis name and axis line.
/// 坐标轴名称与轴线之间的距离。
/// </summary>
public float gap { get { return m_Gap; } set { m_Gap = value; } }
/// <summary>
/// Rotation of axis name.
/// 坐标轴名字旋转,角度值。
/// </summary>
public float rotate { get { return m_Rotate; } set { m_Rotate = value; } }
/// <summary>
/// Color of axis name.
/// 坐标轴名称的文字颜色。
/// </summary>
public Color color { get { return m_Color; } set { m_Color = value; } }
/// <summary>
/// axis name font size.
/// 坐标轴名称的文字大小。
/// </summary>
public int fontSize { get { return m_FontSize; } set { m_FontSize = value; } }
/// <summary>
/// axis name font style.
/// 坐标轴名称的文字风格。
/// </summary>
public FontStyle fontStyle { get { return m_FontStyle; } set { m_FontStyle = value; } }
public static AxisName defaultAxisName
{
get
{
return new AxisName()
{
m_Show = false,
m_Name = "axisName",
m_Location = Location.End,
m_Gap = 5,
m_Rotate = 0,
m_Color = Color.clear,
m_FontSize = 18,
m_FontStyle = FontStyle.Normal
};
}
}
public void Copy(AxisName other)
{
m_Show = other.show;
m_Name = other.name;
m_Location = other.location;
m_Gap = other.gap;
m_Rotate = other.rotate;
m_Color = other.color;
m_FontSize = other.fontSize;
m_FontStyle = other.fontStyle;
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var other = (AxisName)obj;
return m_Show == other.show &&
m_Name.Equals(other.name) &&
m_Location == other.location &&
m_Gap == other.gap &&
m_Rotate == other.rotate &&
m_Color == other.color &&
m_FontSize == other.fontSize &&
m_FontStyle == other.fontStyle;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 049b2f7f73a1c45d8a5c2eddfa1cbab5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace XCharts
{
/// <summary>
/// Split area of axis in grid area, not shown by default.
/// 坐标轴在 grid 区域中的分隔区域,默认不显示。
/// </summary>
[Serializable]
public class AxisSplitArea
{
[SerializeField] private bool m_Show;
[SerializeField] private List<Color> m_Color;
/// <summary>
/// Set this to true to show the splitArea.
/// 是否显示分隔区域。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// Color of split area. SplitArea color could also be set in color array,
/// which the split lines would take as their colors in turns.
/// Dark and light colors in turns are used by default.
/// 分隔区域颜色。分隔区域会按数组中颜色的顺序依次循环设置颜色。默认是一个深浅的间隔色。
/// </summary>
public List<Color> color { get { return m_Color; } set { m_Color = value; } }
public static AxisSplitArea defaultSplitArea
{
get
{
return new AxisSplitArea()
{
m_Show = false,
m_Color = new List<Color>(){
new Color32(250,250,250,77),
new Color32(200,200,200,77)
}
};
}
}
public Color getColor(int index)
{
var i = index % color.Count;
return color[i];
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bb80a429322884027a1edb34a097df44
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
using UnityEngine;
namespace XCharts
{
/// <summary>
/// Settings related to axis tick.
/// 坐标轴刻度相关设置。
/// </summary>
[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;
/// <summary>
/// Set this to false to prevent the axis tick from showing.
/// 是否显示坐标轴刻度。
/// </summary>
public bool show { get { return m_Show; } set { m_Show = value; } }
/// <summary>
/// Align axis tick with label, which is available only when boundaryGap is set to be true in category axis.
/// 类目轴中在 boundaryGap 为 true 的时候有效,可以保证刻度线和标签对齐。
/// </summary>
public bool alignWithLabel { get { return m_AlignWithLabel; } set { m_AlignWithLabel = value; } }
/// <summary>
/// Set this to true so the axis labels face the inside direction.
/// 坐标轴刻度是否朝内,默认朝外。
/// </summary>
public bool inside { get { return m_Inside; } set { m_Inside = value; } }
/// <summary>
/// The length of the axis tick.
/// 坐标轴刻度的长度。
/// </summary>
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;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7aa134b37e87943e6a031ea0af777782
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System;
@@ -6,27 +7,38 @@ using UnityEngine.EventSystems;
namespace XCharts
{
/// <summary>
/// the layout is horizontal or vertical.
/// 垂直还是水平布局方式。
/// </summary>
public enum Orient
{
/// <summary>
/// 水平
/// </summary>
Horizonal,
/// <summary>
/// 垂直
/// </summary>
Vertical
}
public class BaseChart : MaskableGraphic, IPointerDownHandler, IPointerUpHandler,
public partial class BaseChart : Graphic, IPointerDownHandler, IPointerUpHandler,
IPointerEnterHandler, IPointerExitHandler, IBeginDragHandler,
IDragHandler, IEndDragHandler, IScrollHandler
{
private static readonly string s_TitleObjectName = "title";
private static readonly string s_LegendObjectName = "legend";
private static readonly string s_SerieLabelObjectName = "label";
[SerializeField] protected Theme m_Theme = Theme.Default;
[SerializeField] protected float m_ChartWidth;
[SerializeField] protected float m_ChartHeight;
[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 Series m_Series = Series.defaultSeries;
[SerializeField] protected float m_Large = 1;
[SerializeField] protected int m_MinShowDataNumber;
[SerializeField] protected int m_MaxShowDataNumber;
[SerializeField] protected int m_MaxCacheDataNumber;
@@ -36,37 +48,15 @@ namespace XCharts
[NonSerialized] private Legend m_CheckLegend = Legend.defaultLegend;
[NonSerialized] private float m_CheckWidth = 0;
[NonSerialized] private float m_CheckHeight = 0;
[NonSerialized] private float m_CheckSerieCount = 0;
[NonSerialized] private List<string> m_CheckSerieName = new List<string>();
[NonSerialized] private bool m_RefreshChart = false;
[NonSerialized] protected List<Text> m_LegendTextList = new List<Text>();
[NonSerialized] private bool m_RefreshLabel = false;
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()
{
if (m_ThemeInfo == null)
@@ -77,12 +67,21 @@ namespace XCharts
rectTransform.anchorMax = Vector2.zero;
rectTransform.anchorMin = Vector2.zero;
rectTransform.pivot = Vector2.zero;
m_CheckWidth = chartWidth;
m_CheckHeight = chartHeight;
m_CheckTheme = m_Theme;
m_ChartWidth = rectTransform.sizeDelta.x;
m_ChartHeight = rectTransform.sizeDelta.y;
m_CheckWidth = m_ChartWidth;
m_CheckHeight = m_ChartHeight;
m_CheckTheme = m_ThemeInfo.theme;
InitTitle();
InitLegend();
InitSerieLabel();
InitTooltip();
TransferOldVersionData();
}
protected override void Start()
{
RefreshChart();
}
protected virtual void Update()
@@ -93,12 +92,30 @@ namespace XCharts
CheckLegend();
CheckTooltip();
CheckRefreshChart();
CheckRefreshLabel();
}
protected override void OnEnable()
{
base.OnEnable();
Awake();
}
protected override void OnDisable()
{
base.OnDisable();
ChartHelper.HideAllObject(transform);
}
#if UNITY_EDITOR
protected override void Reset()
{
ChartHelper.DestoryAllChilds(transform);
var sizeDelta = rectTransform.sizeDelta;
if (sizeDelta.x < 580 && sizeDelta.y < 300)
{
rectTransform.sizeDelta = new Vector2(580, 300);
}
ChartHelper.HideAllObject(transform);
m_ThemeInfo = ThemeInfo.Default;
m_Title = Title.defaultTitle;
m_Legend = Legend.defaultLegend;
@@ -116,70 +133,32 @@ namespace XCharts
}
}
public void ClearData()
private void TransferOldVersionData()
{
m_Series.ClearData();
m_Legend.ClearData();
}
public virtual void AddData(string legend, float value)
{
m_Legend.AddData(legend);
m_Series.AddData(legend, value, m_MaxCacheDataNumber);
RefreshChart();
}
public virtual void AddData(int legend, float value)
{
m_Series.AddData(legend, value, m_MaxCacheDataNumber);
}
public virtual void UpdateData(string legend, float value, int dataIndex = 0)
{
m_Series.UpdateData(legend, value, dataIndex);
RefreshChart();
}
public virtual void UpdateData(int legendIndex, float value, int dataIndex = 0)
{
m_Series.UpdateData(legendIndex, value, dataIndex);
RefreshChart();
}
public virtual void SetActive(string legend, bool active)
{
m_Legend.SetActive(legend, active);
m_Series.SetActive(legend, active);
}
public virtual void SetActive(int index, bool active)
{
m_Legend.SetActive(index, active);
m_Series.SetActive(index, active);
}
public virtual bool IsActive(string name)
{
return m_Legend.IsActive(name) || m_Series.IsActive(name);
}
public virtual bool IsActive(int index)
{
return m_Legend.IsActive(index) || m_Series.IsActive(index);
}
public virtual void RemoveData(string legend)
{
m_Legend.RemoveData(legend);
m_Series.RemoveData(legend);
RefreshChart();
}
public void UpdateTheme(Theme theme)
{
this.m_Theme = theme;
OnThemeChanged();
SetAllDirty();
foreach (var serie in m_Series.series)
{
if (serie.yData.Count <= 0) continue;
bool needTransfer = true;
foreach (var sd in serie.data)
{
foreach (var value in sd.data)
{
if (value != 0) needTransfer = false;
}
}
if (needTransfer)
{
serie.data.Clear();
for (int i = 0; i < serie.yData.Count; i++)
{
float xvalue = i < serie.xData.Count ? serie.xData[i] : i;
float yvalue = serie.yData[i];
var serieData = new SerieData();
serieData.data = new List<float>() { xvalue, yvalue };
serie.data.Add(serieData);
}
}
}
}
private void InitTitle()
@@ -199,22 +178,22 @@ namespace XCharts
ChartHelper.HideAllObject(titleObject, s_TitleObjectName);
Text titleText = ChartHelper.AddTextObject(s_TitleObjectName, titleObject.transform,
m_ThemeInfo.font, m_ThemeInfo.textColor, anchor, anchorMin, anchorMax, pivot,
m_ThemeInfo.font, m_ThemeInfo.titleTextColor, 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;
titleText.text = m_Title.text.Replace("\\n", "\n");
Text subText = ChartHelper.AddTextObject(s_TitleObjectName + "_sub", titleObject.transform,
m_ThemeInfo.font, m_ThemeInfo.textColor, anchor, anchorMin, anchorMax, pivot,
m_ThemeInfo.font, m_ThemeInfo.titleTextColor, 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;
subText.text = m_Title.subText.Replace("\\n", "\n");
}
private void InitLegend()
@@ -231,27 +210,106 @@ namespace XCharts
legendObject.transform.localPosition = m_Legend.location.GetPosition(chartWidth, chartHeight);
ChartHelper.HideAllObject(legendObject, s_LegendObjectName);
for (int i = 0; i < m_Legend.data.Count; i++)
var serieNameList = m_Series.GetSerieNameList();
List<string> datas;
if (m_Legend.data.Count > 0)
{
Button btn = ChartHelper.AddButtonObject(s_LegendObjectName + "_" + i, legendObject.transform,
datas = new List<string>();
for (int i = 0; i < m_Legend.data.Count; i++)
{
var category = m_Legend.data[i];
if (serieNameList.Contains(category)) datas.Add(category);
}
}
else
{
datas = serieNameList;
}
m_Legend.RemoveButton();
for (int i = 0; i < datas.Count; i++)
{
string legendName = datas[i];
Button btn = ChartHelper.AddButtonObject(s_LegendObjectName + "_" + i + "_" + legendName, 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.SetActive(i, IsActive(i));
m_Legend.UpdateButtonColor(i, m_ThemeInfo.GetColor(i), m_ThemeInfo.legendUnableColor);
btn.GetComponentInChildren<Text>().text = m_Legend.data[i];
var bgColor = IsActiveByLegend(legendName) ? m_ThemeInfo.GetColor(i) : m_ThemeInfo.legendUnableColor;
m_Legend.SetButton(legendName, btn, datas.Count);
m_Legend.UpdateButtonColor(legendName, bgColor);
btn.GetComponentInChildren<Text>().text = legendName;
ChartHelper.ClearEventListener(btn.gameObject);
ChartHelper.AddEventListener(btn.gameObject, EventTriggerType.PointerDown, (data) =>
{
int count = (data as PointerEventData).clickCount;
int index = int.Parse(data.selectedObject.name.Split('_')[1]);
SetActive(index, !m_Legend.IsActive(index));
m_Legend.UpdateButtonColor(index, m_ThemeInfo.GetColor(index),
m_ThemeInfo.legendUnableColor);
OnYMaxValueChanged();
OnLegendButtonClicked();
RefreshChart();
if (data.selectedObject == null || m_Legend.selectedMode == Legend.SelectedMode.None) return;
var temp = data.selectedObject.name.Split('_');
string selectedName = temp[2];
int clickedIndex = int.Parse(temp[1]);
if (m_Legend.selectedMode == Legend.SelectedMode.Multiple)
{
OnLegendButtonClick(clickedIndex, selectedName, !IsActiveByLegend(selectedName));
}
else
{
var btnList = m_Legend.buttonList.Values.ToArray();
for (int n = 0; n < btnList.Length; n++)
{
temp = btnList[n].name.Split('_');
selectedName = temp[2];
var index = int.Parse(temp[1]);
OnLegendButtonClick(n, selectedName, index == clickedIndex ? true : false);
}
}
});
ChartHelper.AddEventListener(btn.gameObject, EventTriggerType.PointerEnter, (data) =>
{
if (btn == null) return;
var temp = btn.name.Split('_');
string selectedName = temp[2];
int index = int.Parse(temp[1]);
OnLegendButtonEnter(index, selectedName);
});
ChartHelper.AddEventListener(btn.gameObject, EventTriggerType.PointerExit, (data) =>
{
if (btn == null) return;
var temp = btn.name.Split('_');
string selectedName = temp[2];
int index = int.Parse(temp[1]);
OnLegendButtonExit(index, selectedName);
});
}
if (m_Legend.selectedMode == Legend.SelectedMode.Single)
{
for (int n = 0; n < datas.Count; n++)
{
OnLegendButtonClick(n, datas[n], n == 0 ? true : false);
}
}
}
private void InitSerieLabel()
{
ChartHelper.HideAllObject(transform, s_SerieLabelObjectName);
var labelObject = ChartHelper.AddObject(s_SerieLabelObjectName, transform, chartAnchorMin,
chartAnchorMax, chartPivot, new Vector2(chartWidth, chartHeight));
int count = 0;
for (int i = 0; i < m_Series.Count; i++)
{
var serie = m_Series.series[i];
if (serie.type != SerieType.Pie) continue;
for (int j = 0; j < serie.data.Count; j++)
{
var serieData = serie.data[j];
var textName = s_SerieLabelObjectName + "_" + i + "_" + j + "_" + serieData.name;
var color = (serie.label.position == SerieLabel.Position.Inside) ? Color.white :
(Color)m_ThemeInfo.GetColor(count++);
var anchorMin = new Vector2(0.5f, 0.5f);
var anchorMax = new Vector2(0.5f, 0.5f);
var pivot = new Vector2(0.5f, 0.5f);
serieData.label = ChartHelper.AddTextObject(textName, labelObject.transform,
m_ThemeInfo.font, color, TextAnchor.MiddleCenter, anchorMin, anchorMax, pivot,
new Vector2(50, serie.label.fontSize), serie.label.fontSize);
serieData.label.text = serieData.name;
serieData.label.gameObject.SetActive(true);
}
}
}
@@ -264,15 +322,10 @@ namespace XCharts
var parent = tooltipObject.transform;
ChartHelper.HideAllObject(tooltipObject.transform);
GameObject content = ChartHelper.AddTooltipContent("content", parent, m_ThemeInfo.font);
GameObject labelX = ChartHelper.AddTooltipLabel("label_x", parent, m_ThemeInfo.font, new Vector2(0.5f, 1));
GameObject labelY = ChartHelper.AddTooltipLabel("label_y", parent, m_ThemeInfo.font, new Vector2(1, 0.5f));
m_Tooltip.SetObj(tooltipObject);
m_Tooltip.SetContentObj(content);
m_Tooltip.SetLabelObj(labelX, labelY);
m_Tooltip.SetContentBackgroundColor(m_ThemeInfo.tooltipBackgroundColor);
m_Tooltip.SetContentTextColor(m_ThemeInfo.tooltipTextColor);
m_Tooltip.SetLabelBackgroundColor(m_ThemeInfo.tooltipLabelColor);
m_Tooltip.SetLabelTextColor(m_ThemeInfo.tooltipTextColor);
m_Tooltip.SetActive(false);
}
@@ -281,27 +334,24 @@ namespace XCharts
return m_Legend.location.GetPosition(chartWidth, chartHeight);
}
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)
var sizeDelta = rectTransform.sizeDelta;
if (m_CheckWidth == 0 && m_CheckHeight == 0 && (sizeDelta.x != 0 || sizeDelta.y != 0))
{
m_CheckWidth = chartWidth;
m_CheckHeight = chartHeight;
OnSizeChanged();
Awake();
}
else if (m_CheckWidth != sizeDelta.x || m_CheckHeight != sizeDelta.y)
{
SetSize(sizeDelta.x, sizeDelta.y);
}
}
private void CheckTheme()
{
if (m_CheckTheme != m_Theme)
if (m_CheckTheme != m_ThemeInfo.theme)
{
m_CheckTheme = m_Theme;
m_CheckTheme = m_ThemeInfo.theme;
OnThemeChanged();
}
}
@@ -322,37 +372,56 @@ namespace XCharts
m_CheckLegend.Copy(m_Legend);
OnLegendChanged();
}
else if (m_Legend.show)
{
if (m_CheckSerieCount != m_Series.Count)
{
m_CheckSerieCount = m_Series.Count;
m_CheckSerieName.Clear();
var serieNames = m_Series.GetSerieNameList();
foreach (var name in serieNames) m_CheckSerieName.Add(name);
OnLegendChanged();
}
else if (!ChartHelper.IsValueEqualsList(m_CheckSerieName, m_Series.GetSerieNameList()))
{
var serieNames = m_Series.GetSerieNameList();
foreach (var name in serieNames) m_CheckSerieName.Add(name);
OnLegendChanged();
}
}
}
private void CheckTooltip()
{
if (!m_Tooltip.show || !m_Tooltip.isInited)
if (!m_Tooltip.show || !m_Tooltip.inited)
{
if (m_Tooltip.dataIndex != 0)
if (m_Tooltip.dataIndex[0] != 0 || m_Tooltip.dataIndex[1] != 0)
{
m_Tooltip.dataIndex = 0;
m_Tooltip.dataIndex[0] = m_Tooltip.dataIndex[1] = -1;
m_Tooltip.SetActive(false);
RefreshChart();
}
return;
}
m_Tooltip.SetLabelActive(m_Tooltip.crossLabel);
m_Tooltip.dataIndex = 0;
for (int i = 0; i < m_Tooltip.dataIndex.Count; i++)
{
m_Tooltip.dataIndex[i] = -1;
}
Vector2 local;
if (canvas == null) return;
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform,
Input.mousePosition, canvas.worldCamera, out local))
{
if (m_Tooltip.IsActive()) RefreshChart();
m_Tooltip.SetActive(false);
RefreshChart();
return;
}
if (local.x < 0 || local.x > chartWidth ||
local.y < 0 || local.y > chartHeight)
{
if (m_Tooltip.IsActive()) RefreshChart();
m_Tooltip.SetActive(false);
RefreshChart();
return;
}
m_Tooltip.pointerPos = local;
@@ -374,15 +443,30 @@ namespace XCharts
}
}
protected void CheckRefreshLabel()
{
if (m_RefreshLabel)
{
m_RefreshLabel = false;
OnRefreshLabel();
}
}
protected virtual void OnRefreshLabel()
{
}
protected virtual void OnSizeChanged()
{
InitTitle();
InitLegend();
InitTooltip();
}
protected virtual void OnThemeChanged()
{
switch (m_Theme)
switch (m_ThemeInfo.theme)
{
case Theme.Dark:
m_ThemeInfo.Copy(ThemeInfo.Dark);
@@ -413,13 +497,79 @@ namespace XCharts
{
}
protected virtual void OnLegendButtonClicked()
protected virtual void OnLegendButtonClick(int index, string legendName, bool show)
{
foreach (var serie in m_Series.GetSeries(legendName))
{
SetActive(serie.index, show);
}
OnYMaxValueChanged();
RefreshChart();
}
public void RefreshChart()
protected virtual void OnLegendButtonEnter(int index, string legendName)
{
m_RefreshChart = true;
var serie = m_Series.GetSerie(index);
serie.highlighted = true;
RefreshChart();
}
protected virtual void OnLegendButtonExit(int index, string legendName)
{
var serie = m_Series.GetSerie(index);
serie.highlighted = false;
RefreshChart();
}
protected bool CheckDataShow(string legendName, bool show)
{
bool needShow = false;
foreach (var serie in m_Series.series)
{
if (legendName.Equals(serie.name))
{
serie.show = show;
serie.highlighted = false;
if (serie.show) needShow = true;
}
else
{
foreach (var data in serie.data)
{
if (legendName.Equals(data.name))
{
data.show = show;
data.highlighted = false;
if (data.show) needShow = true;
}
}
}
}
return needShow;
}
protected bool CheckDataHighlighted(string legendName, bool heighlight)
{
bool show = false;
foreach (var serie in m_Series.series)
{
if (legendName.Equals(serie.name))
{
serie.highlighted = heighlight;
}
else
{
foreach (var data in serie.data)
{
if (legendName.Equals(data.name))
{
data.highlighted = heighlight;
if (data.highlighted) show = true;
}
}
}
}
return show;
}
protected virtual void RefreshTooltip()
@@ -432,6 +582,7 @@ namespace XCharts
DrawBackground(vh);
DrawChart(vh);
DrawTooltip(vh);
m_RefreshLabel = true;
}
protected virtual void DrawChart(VertexHelper vh)
@@ -452,6 +603,51 @@ namespace XCharts
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, m_ThemeInfo.backgroundColor);
}
protected void DrawSymbol(VertexHelper vh, SerieSymbolType type, float symbolSize,
float tickness, Vector3 pos, Color color)
{
switch (type)
{
case SerieSymbolType.None:
break;
case SerieSymbolType.Circle:
ChartHelper.DrawCricle(vh, pos, symbolSize, color, GetSymbolCricleSegment(symbolSize));
break;
case SerieSymbolType.EmptyCircle:
int segment = GetSymbolCricleSegment(symbolSize);
ChartHelper.DrawCricle(vh, pos, symbolSize, m_ThemeInfo.backgroundColor, segment);
ChartHelper.DrawDoughnut(vh, pos, symbolSize - tickness, symbolSize, 0, 360, color, segment);
break;
case SerieSymbolType.Rect:
ChartHelper.DrawPolygon(vh, pos, symbolSize, color);
break;
case SerieSymbolType.Triangle:
var x = symbolSize * Mathf.Cos(30 * Mathf.PI / 180);
var y = symbolSize * Mathf.Sin(30 * Mathf.PI / 180);
var p1 = new Vector2(pos.x - x, pos.y - y);
var p2 = new Vector2(pos.x, pos.y + symbolSize);
var p3 = new Vector2(pos.x + x, pos.y - y);
ChartHelper.DrawTriangle(vh, p1, p2, p3, color);
break;
case SerieSymbolType.Diamond:
p1 = new Vector2(pos.x - symbolSize, pos.y);
p2 = new Vector2(pos.x, pos.y + symbolSize);
p3 = new Vector2(pos.x + symbolSize, pos.y);
var p4 = new Vector2(pos.x, pos.y - symbolSize);
ChartHelper.DrawPolygon(vh, p1, p2, p3, p4, color);
break;
}
}
private int GetSymbolCricleSegment(float radiu)
{
int max = 50;
int segent = (int)(2 * Mathf.PI * radiu / ChartHelper.CRICLE_SMOOTHNESS);
if (segent > max) segent = max;
segent = (int)(segent / (1 + (m_Large - 1) / 10));
return segent;
}
public virtual void OnPointerDown(PointerEventData eventData)
{
}

View File

@@ -0,0 +1,368 @@
using UnityEngine;
using System.Collections.Generic;
namespace XCharts
{
/// <summary>
/// The base class of all charts.
/// 所有Chart的基类不可直接使用。
/// </summary>
public partial class BaseChart
{
/// <summary>
/// The title setting of chart.
/// 标题组件
/// </summary>
public Title title { get { return m_Title; } }
/// <summary>
/// The legend setting of chart.
/// 图例组件
/// </summary>
public Legend legend { get { return m_Legend; } }
/// <summary>
/// The tooltip setting of chart.
/// 提示框组件
/// </summary>
public Tooltip tooltip { get { return m_Tooltip; } }
/// <summary>
/// The series setting of chart.
/// 系列列表
/// </summary>
public Series series { get { return m_Series; } }
/// <summary>
/// The width of chart.
/// 图表的宽
/// </summary>
public float chartWidth { get { return m_ChartWidth; } }
/// <summary>
/// The height of chart.
/// 图表的高
/// </summary>
/// <value></value>
public float chartHeight { get { return m_ChartHeight; } }
/// <summary>
/// The min number of data to show in chart.
/// 图表所显示数据的最小索引
/// </summary>
public int minShowDataNumber
{
get { return m_MinShowDataNumber; }
set { m_MinShowDataNumber = value; if (m_MinShowDataNumber < 0) m_MinShowDataNumber = 0; }
}
/// <summary>
/// The max number of data to show in chart.
/// 图表所显示数据的最大索引
/// </summary>
public int maxShowDataNumber
{
get { return m_MaxShowDataNumber; }
set { m_MaxShowDataNumber = value; if (m_MaxShowDataNumber < 0) m_MaxShowDataNumber = 0; }
}
/// <summary>
/// The max number of serie and axis data cache.
/// The first data will be remove when the size of serie and axis data is larger then maxCacheDataNumber.
/// default:0,unlimited.
/// 图表每个系列中可缓存的最大数据量。默认为0没有限制大于0时超过指定值会移除旧数据再插入新数据。
/// </summary>
public int maxCacheDataNumber
{
get { return m_MaxCacheDataNumber; }
set { m_MaxCacheDataNumber = value; if (m_MaxCacheDataNumber < 0) m_MaxCacheDataNumber = 0; }
}
/// <summary>
/// Set the size of chart.
/// 设置图表的大小。
/// </summary>
/// <param name="width">width</param>
/// <param name="height">height</param>
public virtual void SetSize(float width, float height)
{
Debug.LogError("setsize:" + m_CheckWidth + "," + m_CheckHeight + "," + width + height);
m_ChartWidth = width;
m_ChartHeight = height;
m_CheckWidth = width;
m_CheckHeight = height;
rectTransform.sizeDelta = new Vector2(m_ChartWidth, m_ChartHeight);
OnSizeChanged();
}
/// <summary>
/// Remove all series and legend data.
/// It just emptying all of serie's data without emptying the list of series.
/// 清除所有数据,系列中只是移除数据,列表会保留。
/// </summary>
public virtual void ClearData()
{
m_Series.ClearData();
m_Legend.ClearData();
RefreshChart();
}
/// <summary>
/// Remove all data from series and legend.
/// The series list is also cleared.
/// 清除所有系列和图例数据,系列的列表也会被清除。
/// </summary>
public virtual void RemoveData()
{
m_Legend.ClearData();
m_Series.RemoveAll();
RefreshChart();
}
/// <summary>
/// Remove legend and serie by name.
/// 清除指定系列名称的数据。
/// </summary>
/// <param name="serieName">the name of serie</param>
public virtual void RemoveData(string serieName)
{
m_Series.Remove(serieName);
m_Legend.RemoveData(serieName);
RefreshChart();
}
/// <summary>
/// Add a serie to serie list.
/// 添加一个系列到系列列表中。
/// </summary>
/// <param name="serieName">the name of serie</param>
/// <param name="type">the type of serie</param>
/// <param name="show">whether to show this serie</param>
/// <returns>the added serie</returns>
public virtual Serie AddSerie(string serieName, SerieType type, bool show = true)
{
m_Legend.AddData(serieName);
return m_Series.AddSerie(serieName, type);
}
/// <summary>
/// Add a data to serie.
/// If serieName doesn't exist in legend,will be add to legend.
/// 添加一个数据到指定的系列中。
/// </summary>
/// <param name="serieName">the name of serie</param>
/// <param name="data">the data to add</param>
/// <param name="dataName">the name of data</param>
/// <returns>Returns True on success</returns>
public virtual bool AddData(string serieName, float data, string dataName = null)
{
m_Legend.AddData(serieName);
var success = m_Series.AddData(serieName, data, dataName, m_MaxCacheDataNumber);
if (success) RefreshChart();
return success;
}
/// <summary>
/// Add a data to serie.
/// 添加一个数据到指定的系列中。
/// </summary>
/// <param name="serieIndex">the index of serie</param>
/// <param name="data">the data to add</param>
/// <param name="dataName">the name of data</param>
/// <returns>Returns True on success</returns>
public virtual bool AddData(int serieIndex, float data, string dataName = null)
{
var success = m_Series.AddData(serieIndex, data, dataName, m_MaxCacheDataNumber);
if (success) RefreshChart();
return success;
}
/// <summary>
/// Add an arbitray dimension data to serie,such as (x,y,z,...).
/// 添加多维数据x,y,z...)到指定的系列中。
/// </summary>
/// <param name="serieName">the name of serie</param>
/// <param name="multidimensionalData">the (x,y,z,...) data</param>
/// <param name="dataName">the name of data</param>
/// <returns>Returns True on success</returns>
public virtual bool AddData(string serieName, List<float> multidimensionalData, string dataName = null)
{
var success = m_Series.AddData(serieName, multidimensionalData, dataName, m_MaxCacheDataNumber);
if (success) RefreshChart();
return success;
}
/// <summary>
/// Add an arbitray dimension data to serie,such as (x,y,z,...).
/// 添加多维数据x,y,z...)到指定的系列中。
/// </summary>
/// <param name="serieIndex">the index of serie,index starts at 0</param>
/// <param name="multidimensionalData">the (x,y,z,...) data</param>
/// <param name="dataName">the name of data</param>
/// <returns>Returns True on success</returns>
public virtual bool AddData(int serieIndex, List<float> multidimensionalData, string dataName = null)
{
var success = m_Series.AddData(serieIndex, multidimensionalData, dataName, m_MaxCacheDataNumber);
if (success) RefreshChart();
return success;
}
/// <summary>
/// Add a (x,y) data to serie.
/// 添加x,y数据到指定系列中。
/// </summary>
/// <param name="serieName">the name of serie</param>
/// <param name="xValue">x data</param>
/// <param name="yValue">y data</param>
/// <param name="dataName">the name of data</param>
/// <returns>Returns True on success</returns>
public virtual bool AddData(string serieName, float xValue, float yValue, string dataName)
{
var success = m_Series.AddXYData(serieName, xValue, yValue, dataName, m_MaxCacheDataNumber);
if (success) RefreshChart();
return true;
}
/// <summary>
/// Add a (x,y) data to serie.
/// 添加x,y数据到指定系列中。
/// </summary>
/// <param name="serieIndex">the index of serie</param>
/// <param name="xValue">x data</param>
/// <param name="yValue">y data</param>
/// <param name="dataName">the name of data</param>
/// <returns>Returns True on success</returns>
public virtual bool AddData(int serieIndex, float xValue, float yValue, string dataName = null)
{
var success = m_Series.AddXYData(serieIndex, xValue, yValue, dataName, m_MaxCacheDataNumber);
if (success) RefreshChart();
return success;
}
/// <summary>
/// Update serie data by serie name.
/// 更新指定系列中的指定索引数据。
/// </summary>
/// <param name="serieName">the name of serie</param>
/// <param name="value">the data will be update</param>
/// <param name="dataIndex">the index of data</param>
public virtual void UpdateData(string serieName, float value, int dataIndex = 0)
{
m_Series.UpdateData(serieName, value, dataIndex);
RefreshChart();
}
/// <summary>
/// Update serie data by serie index.
/// 更新指定系列中的指定索引数据。
/// </summary>
/// <param name="serieIndex">the index of serie</param>
/// <param name="value">the data will be update</param>
/// <param name="dataIndex">the index of data</param>
public virtual void UpdateData(int serieIndex, float value, int dataIndex = 0)
{
m_Series.UpdateData(serieIndex, value, dataIndex);
RefreshChart();
}
/// <summary>
/// Whether to show serie.
/// 设置指定系列是否显示。
/// </summary>
/// <param name="serieName">the name of serie</param>
/// <param name="active">Active or not</param>
public virtual void SetActive(string serieName, bool active)
{
var serie = m_Series.GetSerie(serieName);
if (serie != null)
{
SetActive(serie.index, active);
}
}
/// <summary>
/// Whether to show serie.
/// 设置指定系列是否显示。
/// </summary>
/// <param name="serieIndex">the index of serie</param>
/// <param name="active">Active or not</param>
public virtual void SetActive(int serieIndex, bool active)
{
m_Series.SetActive(serieIndex, active);
var serie = m_Series.GetSerie(serieIndex);
if (serie != null && !string.IsNullOrEmpty(serie.name))
{
var bgColor1 = active ? m_ThemeInfo.GetColor(serie.index) : m_ThemeInfo.legendUnableColor;
m_Legend.UpdateButtonColor(serie.name, bgColor1);
}
}
/// <summary>
/// Whether serie is activated.
/// 获取指定系列是否显示。
/// </summary>
/// <param name="serieName">the name of serie</param>
/// <returns>True when activated</returns>
public virtual bool IsActive(string serieName)
{
return m_Series.IsActive(serieName);
}
/// <summary>
/// Whether serie is activated.
/// 获取指定系列是否显示。
/// </summary>
/// <param name="serieIndex">the index of serie</param>
/// <returns>True when activated</returns>
public virtual bool IsActive(int serieIndex)
{
return m_Series.IsActive(serieIndex);
}
/// <summary>
/// Whether serie is activated.
/// 获得指定图例名字的系列是否显示。
/// </summary>
/// <param name="legendName"></param>
/// <returns></returns>
public virtual bool IsActiveByLegend(string legendName)
{
foreach (var serie in m_Series.series)
{
if (serie.show && legendName.Equals(serie.name))
{
return true;
}
else
{
foreach (var serieData in serie.data)
{
if (serieData.show && legendName.Equals(serieData.name))
{
return true;
}
}
}
}
return false;
}
/// <summary>
/// Redraw chart in next frame.
/// 在下一帧刷新图表。
/// </summary>
public void RefreshChart()
{
m_RefreshChart = true;
}
/// <summary>
/// Update chart theme.
/// 切换图表主题。
/// </summary>
/// <param name="theme">theme</param>
public void UpdateTheme(Theme theme)
{
m_ThemeInfo.theme = theme;
OnThemeChanged();
RefreshChart();
}
}
}

Some files were not shown because too many files have changed in this diff Show More