From ff8057690c8b00f95f8b02ec3de3e2e7fbfd6cb1 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Sun, 21 Jul 2019 22:58:51 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84SerieSymbol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/Scripts/Demo11_AddSinCurve.cs | 3 +- Demo/Scripts/Demo_Dynamic.cs | 2 +- Scripts/Editor/PropertyDrawers/SerieDrawer.cs | 174 ++++++++------ .../PropertyDrawers/SerieSymbolDrawer.cs | 74 ++++++ .../PropertyDrawers/SerieSymbolDrawer.cs.meta | 11 + Scripts/UI/Internal/BaseChart.cs | 18 +- Scripts/UI/Internal/Serie.cs | 216 ++++++++++++++++-- Scripts/UI/Internal/Series.cs | 24 +- Scripts/UI/LineChart.cs | 17 +- 9 files changed, 430 insertions(+), 109 deletions(-) create mode 100644 Scripts/Editor/PropertyDrawers/SerieSymbolDrawer.cs create mode 100644 Scripts/Editor/PropertyDrawers/SerieSymbolDrawer.cs.meta diff --git a/Demo/Scripts/Demo11_AddSinCurve.cs b/Demo/Scripts/Demo11_AddSinCurve.cs index 1df9231e..73eaa6d1 100644 --- a/Demo/Scripts/Demo11_AddSinCurve.cs +++ b/Demo/Scripts/Demo11_AddSinCurve.cs @@ -40,7 +40,8 @@ public class Demo11_AddSinCurve : MonoBehaviour chart.RemoveData(); - chart.AddSerie("test", SerieType.Line); + var serie = chart.AddSerie("test", SerieType.Line); + serie.symbol.type = SerieSymbolType.None; for (angle = 0; angle < 1080; angle++) { float xvalue = Mathf.PI / 180 * angle; diff --git a/Demo/Scripts/Demo_Dynamic.cs b/Demo/Scripts/Demo_Dynamic.cs index bdd31ac3..faf2e9b8 100644 --- a/Demo/Scripts/Demo_Dynamic.cs +++ b/Demo/Scripts/Demo_Dynamic.cs @@ -23,7 +23,7 @@ public class Demo_Dynamic : MonoBehaviour chart = gameObject.GetComponentInChildren(); chart.RemoveData(); var serie = chart.AddSerie("data", SerieType.Line); - serie.symbol = SerieSymbolType.None; + serie.symbol.type = SerieSymbolType.None; chart.maxCacheDataNumber = maxCacheDataNumber; timeNow = DateTime.Now; timeNow = timeNow.AddSeconds(-maxCacheDataNumber); diff --git a/Scripts/Editor/PropertyDrawers/SerieDrawer.cs b/Scripts/Editor/PropertyDrawers/SerieDrawer.cs index 35988713..4a9c70c7 100644 --- a/Scripts/Editor/PropertyDrawers/SerieDrawer.cs +++ b/Scripts/Editor/PropertyDrawers/SerieDrawer.cs @@ -7,6 +7,7 @@ namespace XCharts [CustomPropertyDrawer(typeof(Serie), true)] public class SerieDrawer : PropertyDrawer { + private List m_SerieModuleToggle = new List(); private List m_DataFoldout = new List(); private int m_DataSize = 0; @@ -23,11 +24,9 @@ namespace XCharts SerializedProperty stack = prop.FindPropertyRelative("m_Stack"); SerializedProperty m_AxisIndex = prop.FindPropertyRelative("m_AxisIndex"); SerializedProperty m_Symbol = prop.FindPropertyRelative("m_Symbol"); - SerializedProperty m_SymbolSize = prop.FindPropertyRelative("m_SymbolSize"); - SerializedProperty m_SymbolSelectedSize = prop.FindPropertyRelative("m_SymbolSelectedSize"); - SerializedProperty m_TwoDimensionData = prop.FindPropertyRelative("m_TwoDimensionData"); - SerializedProperty m_XData = prop.FindPropertyRelative("m_XData"); - SerializedProperty m_YData = prop.FindPropertyRelative("m_YData"); + SerializedProperty m_DataDimension = prop.FindPropertyRelative("m_ShowDataDimension"); + SerializedProperty m_ShowDataName = prop.FindPropertyRelative("m_ShowDataName"); + SerializedProperty m_Datas = prop.FindPropertyRelative("m_Data"); int index = InitToggle(prop); string moduleName = "Serie " + index; @@ -48,89 +47,114 @@ namespace XCharts if (type.enumValueIndex == (int)SerieType.Line || type.enumValueIndex == (int)SerieType.Scatter) { EditorGUI.PropertyField(drawRect, m_Symbol); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - EditorGUI.PropertyField(drawRect, m_SymbolSize); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - EditorGUI.PropertyField(drawRect, m_SymbolSelectedSize); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + drawRect.y += EditorGUI.GetPropertyHeight(m_Symbol); } - EditorGUI.PropertyField(drawRect, m_TwoDimensionData); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + 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); drawRect.width = pos.width; if (m_DataFoldout[index]) { - if (m_TwoDimensionData.boolValue) + EditorGUI.indentLevel++; + EditorGUI.PropertyField(drawRect, m_ShowDataName); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, m_DataDimension); + 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; + if (listSize != m_Datas.arraySize) { - EditorGUI.indentLevel++; - var listSize = m_YData.arraySize; - listSize = EditorGUI.IntField(drawRect, "Size", listSize); - if (listSize < 0) listSize = 0; - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - if (listSize != m_XData.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++) { - while (listSize > m_XData.arraySize) - m_XData.InsertArrayElementAtIndex(m_XData.arraySize); - while (listSize < m_XData.arraySize) - m_XData.DeleteArrayElementAtIndex(m_XData.arraySize - 1); + DrawDataElement(ref drawRect, dimension, m_Datas, showName, i); } - if (listSize != m_YData.arraySize) + if (num >= 10) { - while (listSize > m_YData.arraySize) - m_YData.InsertArrayElementAtIndex(m_YData.arraySize); - while (listSize < m_YData.arraySize) - m_YData.DeleteArrayElementAtIndex(m_YData.arraySize - 1); + EditorGUI.LabelField(drawRect, "..."); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + DrawDataElement(ref drawRect, dimension, m_Datas, showName, listSize - 1); } - if (listSize > 30) - { - int num = listSize > 10 ? 10 : listSize; - for (int i = 0; i < num; i++) - { - DrawTwoDimensionDataElement(ref drawRect, m_XData, m_YData, i); - } - if (num >= 10) - { - EditorGUI.LabelField(drawRect, "..."); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - DrawTwoDimensionDataElement(ref drawRect, m_XData, m_YData, listSize - 1); - } - } - else - { - for (int i = 0; i < m_YData.arraySize; i++) - { - DrawTwoDimensionDataElement(ref drawRect, m_XData, m_YData, i); - } - } - EditorGUI.indentLevel--; } else { - ChartEditorHelper.MakeList(ref drawRect, ref m_DataSize, m_YData); + for (int i = 0; i < m_Datas.arraySize; i++) + { + DrawDataElement(ref drawRect, dimension, m_Datas, showName, i); + } } + EditorGUI.indentLevel--; } --EditorGUI.indentLevel; } } - private void DrawTwoDimensionDataElement(ref Rect drawRect, SerializedProperty m_Data1, - SerializedProperty m_Data2, int i) + private void DrawDataElement(ref Rect drawRect, int dimension, SerializedProperty m_Datas, bool showName, int index) { var lastX = drawRect.x; - SerializedProperty element1 = m_Data1.GetArrayElementAtIndex(i); - SerializedProperty element2 = m_Data2.GetArrayElementAtIndex(i); - EditorGUI.LabelField(drawRect, "Element " + i); - var startX = EditorGUIUtility.labelWidth - (EditorGUI.indentLevel - 1) * 15 - 1; - var dataWid = (EditorGUIUtility.currentViewWidth - startX) / 2 + 15; - drawRect.x = startX; - drawRect.width = dataWid; - element1.floatValue = EditorGUI.FloatField(drawRect, element1.floatValue); - drawRect.x += dataWid - 35; - element2.floatValue = EditorGUI.FloatField(drawRect, element2.floatValue); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - drawRect.x = lastX; + 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 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); + 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 - 1; + var dataWidTotal = (EditorGUIUtility.currentViewWidth - (startX + EditorGUI.indentLevel * 15 + 1) - 5); + 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(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; + } + SerializedProperty element1 = data.GetArrayElementAtIndex(0); + SerializedProperty element2 = data.GetArrayElementAtIndex(1); } public override float GetPropertyHeight(SerializedProperty prop, GUIContent label) @@ -143,16 +167,17 @@ namespace XCharts } else { - height += 7 * EditorGUIUtility.singleLineHeight + 6 * EditorGUIUtility.standardVerticalSpacing; + height += 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing; SerializedProperty type = prop.FindPropertyRelative("m_Type"); if (type.enumValueIndex == (int)SerieType.Line || type.enumValueIndex == (int)SerieType.Scatter) { - height += 3 * EditorGUIUtility.singleLineHeight + 2 * EditorGUIUtility.standardVerticalSpacing; + + height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Symbol")); } if (m_DataFoldout[index]) { - SerializedProperty m_Data = prop.FindPropertyRelative("m_YData"); - int num = m_Data.arraySize + 1; + SerializedProperty m_Data = prop.FindPropertyRelative("m_Data"); + int num = m_Data.arraySize + 3; if (num > 30) num = 13; height += num * EditorGUIUtility.singleLineHeight + (num - 1) * EditorGUIUtility.standardVerticalSpacing; } @@ -167,7 +192,16 @@ namespace XCharts private int InitToggle(SerializedProperty prop) { int index = 0; - int.TryParse(prop.displayName.Split(' ')[1], out index); + var temp = prop.displayName.Split(' '); + if (temp == null || temp.Length < 2) + { + Debug.LogError("SERIE:"+prop.name+","+prop.displayName+","+prop.FindPropertyRelative("m_Name").stringValue); + index =0; + } + else + { + int.TryParse(temp[1], out index); + } if (index >= m_DataFoldout.Count) { m_DataFoldout.Add(false); diff --git a/Scripts/Editor/PropertyDrawers/SerieSymbolDrawer.cs b/Scripts/Editor/PropertyDrawers/SerieSymbolDrawer.cs new file mode 100644 index 00000000..d3bebb2f --- /dev/null +++ b/Scripts/Editor/PropertyDrawers/SerieSymbolDrawer.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace XCharts +{ + [CustomPropertyDrawer(typeof(SerieSymbol), true)] + public class SerieSymbolDrawer : PropertyDrawer + { + + private List m_SerieModuleToggle = new List(); + private List m_DataFoldout = new List(); + private int m_DataSize = 0; + private bool m_ShowJsonDataArea = false; + private string m_JsonDataAreaText; + + 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"); + + SerializedProperty m_SizeCallback = prop.FindPropertyRelative("m_SizeCallback"); + SerializedProperty m_SelectedSizeCallback = prop.FindPropertyRelative("m_SelectedSizeCallback"); + + 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 + 3 * EditorGUIUtility.standardVerticalSpacing; + case SerieSymbolSizeType.FromData: + return 5 * EditorGUIUtility.singleLineHeight + 4 * EditorGUIUtility.standardVerticalSpacing; + case SerieSymbolSizeType.Callback: + return 4 * EditorGUIUtility.singleLineHeight + 3 * EditorGUIUtility.standardVerticalSpacing; + } + return 4 * EditorGUIUtility.singleLineHeight + 3 * EditorGUIUtility.standardVerticalSpacing; + } + } +} \ No newline at end of file diff --git a/Scripts/Editor/PropertyDrawers/SerieSymbolDrawer.cs.meta b/Scripts/Editor/PropertyDrawers/SerieSymbolDrawer.cs.meta new file mode 100644 index 00000000..16a02c29 --- /dev/null +++ b/Scripts/Editor/PropertyDrawers/SerieSymbolDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e0c4d3c3303994821bde654cf67d414d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/UI/Internal/BaseChart.cs b/Scripts/UI/Internal/BaseChart.cs index b90f915d..88868f1f 100644 --- a/Scripts/UI/Internal/BaseChart.cs +++ b/Scripts/UI/Internal/BaseChart.cs @@ -28,7 +28,7 @@ namespace XCharts [SerializeField] protected Tooltip m_Tooltip = Tooltip.defaultTooltip; [SerializeField] protected Series m_Series = Series.defaultSeries; - [SerializeField] protected bool m_Large; + [SerializeField] protected float m_Large = 1; [SerializeField] protected int m_MinShowDataNumber; [SerializeField] protected int m_MaxShowDataNumber; [SerializeField] protected int m_MaxCacheDataNumber; @@ -668,11 +668,12 @@ namespace XCharts case SerieSymbolType.None: break; case SerieSymbolType.Circle: - ChartHelper.DrawCricle(vh, pos, symbolSize, color); + ChartHelper.DrawCricle(vh, pos, symbolSize, color, GetSymbolCricleSegment(symbolSize)); break; case SerieSymbolType.EmptyCircle: - ChartHelper.DrawCricle(vh, pos, symbolSize, m_ThemeInfo.backgroundColor); - ChartHelper.DrawDoughnut(vh, pos, symbolSize - tickness, symbolSize, 0, 360, color); + 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); @@ -695,6 +696,15 @@ namespace XCharts } } + 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) { } diff --git a/Scripts/UI/Internal/Serie.cs b/Scripts/UI/Internal/Serie.cs index 2990b6a6..e7a99e88 100644 --- a/Scripts/UI/Internal/Serie.cs +++ b/Scripts/UI/Internal/Serie.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.ComponentModel; using UnityEngine; using UnityEngine.Serialization; @@ -25,6 +26,106 @@ namespace XCharts None, } + /// + /// The way to get serie symbol size. + /// `Custom`:Specify constant for symbol size. + /// `FromData`:Specify the dataIndex and dataScale to calculate symbol size,the formula:data[dataIndex]*dataScale. + /// `Callback`:Specify callback function for symbol size. + /// + public enum SerieSymbolSizeType + { + /// + /// Specify constant for symbol size. + /// + Custom, + /// + /// Specify the dataIndex and dataScale to calculate symbol size + /// + FromData, + /// + /// Specify callback function for symbol size + /// + Callback, + } + + [System.Serializable] + public class SerieData + { + [SerializeField] private string m_Name; + [SerializeField] private List m_Data = new List(); + + public string name { get { return m_Name; } set { m_Name = value; } } + public List data { get { return m_Data; } set { m_Data = value; } } + } + + public delegate float SymbolSizeCallback(List data); + + [System.Serializable] + public class SerieSymbol + { + [SerializeField] private SerieSymbolType m_Type = SerieSymbolType.EmptyCircle; + [SerializeField] private SerieSymbolSizeType m_SizeType = SerieSymbolSizeType.Custom; + [SerializeField] private float m_Size = 20f; + [SerializeField] private float m_SelectedSize = 30f; + [SerializeField] private int m_DataIndex = 1; + [SerializeField] private float m_DataScale = 1; + [SerializeField] private float m_SelectedDataScale = 1.5f; + [SerializeField] private SymbolSizeCallback m_SizeCallback; + [SerializeField] private SymbolSizeCallback m_SelectedSizeCallback; + + public SerieSymbolType type { get { return m_Type; } set { m_Type = value; } } + public float size { get { return m_Size; } set { m_Size = value; } } + public float selectedSize { get { return m_SelectedSize; } set { m_SelectedSize = value; } } + public int dataIndex { get { return m_DataIndex; } set { m_DataIndex = value; } } + public float dataScale { get { return m_DataScale; } set { m_DataScale = value; } } + public float selectedDataScale { get { return m_SelectedDataScale; } set { m_SelectedDataScale = value; } } + public SymbolSizeCallback sizeCallback { get { return m_SizeCallback; } set { m_SizeCallback = value; } } + public SymbolSizeCallback selectedSizeCallback { get { return m_SelectedSizeCallback; } set { m_SelectedSizeCallback = value; } } + + public float GetSize(List data) + { + switch (m_SizeType) + { + case SerieSymbolSizeType.Custom: + return size; + case SerieSymbolSizeType.FromData: + if (dataIndex >= 0 && dataIndex < data.Count) + { + return data[dataIndex] * m_DataScale; + } + else + { + return size; + } + case SerieSymbolSizeType.Callback: + if (sizeCallback != null) return sizeCallback(data); + else return size; + default: return size; + } + } + + public float GetSelectedSize(List data) + { + switch (m_SizeType) + { + case SerieSymbolSizeType.Custom: + return selectedSize; + case SerieSymbolSizeType.FromData: + if (dataIndex >= 0 && dataIndex < data.Count) + { + return data[dataIndex] * m_SelectedDataScale; + } + else + { + return selectedSize; + } + case SerieSymbolSizeType.Callback: + if (selectedSizeCallback != null) return selectedSizeCallback(data); + else return selectedSize; + default: return selectedSize; + } + } + } [System.Serializable] public class Serie : JsonDataSupport { @@ -34,33 +135,34 @@ namespace XCharts [SerializeField] private string m_Name; [SerializeField] private string m_Stack; [SerializeField] private int m_AxisIndex; - [SerializeField] private SerieSymbolType m_Symbol = SerieSymbolType.Circle; - [SerializeField] private float m_SymbolSize = 2.5f; - [SerializeField] private float m_SymbolSelectedSize = 5f; - [SerializeField] private bool m_TwoDimensionData; + [SerializeField] private SerieSymbol m_Symbol = new SerieSymbol(); + + [SerializeField] private int m_ShowDataDimension; + [SerializeField] private bool m_ShowDataName; [FormerlySerializedAs("m_Data")] [SerializeField] private List m_YData = new List(); [SerializeField] private List m_XData = new List(); + [SerializeField] private List m_Data = new List(); public int index { get; set; } - public int dataCount { get { return m_YData.Count; } } + public int dataCount { get { return m_Data.Count; } } public bool selected { get { return m_Selected; } set { m_Selected = value; } } public bool show { get { return m_Show; } set { m_Show = value; } } public SerieType type { get { return m_Type; } set { m_Type = value; } } public string name { get { return m_Name; } set { m_Name = value; } } public string stack { get { return m_Stack; } set { m_Stack = value; } } public int axisIndex { get { return m_AxisIndex; } set { m_AxisIndex = value; } } - public SerieSymbolType symbol { get { return m_Symbol; } set { m_Symbol = value; } } - public float symbolSize { get { return m_SymbolSize; } set { m_SymbolSize = value; } } - public float symbolSelectedSize { get { return m_SymbolSelectedSize; } set { m_SymbolSelectedSize = value; } } - public List yData { get { return m_YData; } set { m_YData = value; } } - public List xData { get { return m_XData; } set { m_XData = value; } } + public SerieSymbol symbol { get { return m_Symbol; } set { m_Symbol = value; } } + public List yData { get { return m_YData; } } + public List xData { get { return m_XData; } } + public List data { get { return m_Data; } } public int filterStart { get; set; } public int filterEnd { get; set; } private List yFilterData { get; set; } private List xFilterData { get; set; } + private List filterData { get; set; } public float yMax { @@ -156,34 +258,41 @@ namespace XCharts { m_XData.Clear(); m_YData.Clear(); + m_Data.Clear(); } public void RemoveData(int index) { m_XData.RemoveAt(index); m_YData.RemoveAt(index); + m_Data.RemoveAt(index); } - public void AddYData(float value, int maxDataNumber = 0) + public void AddYData(float value, int maxDataNumber = 0, string dataName = null) { 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(m_XData.Count); + int xValue = m_XData.Count; + m_XData.Add(xValue); m_YData.Add(value); + m_Data.Add(new SerieData() { data = new List() { xValue, value }, name = dataName }); } - public void AddXYData(float xValue, float yValue, int maxDataNumber = 0) + public void AddXYData(float xValue, float yValue, int maxDataNumber = 0, string dataName = null) { 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() { xValue, yValue }, name = dataName }); } public float GetYData(int index, DataZoom dataZoom = null) @@ -244,6 +353,25 @@ namespace XCharts } } + public List 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; + } + } + public void UpdateFilterData(DataZoom dataZoom) { if (dataZoom != null && dataZoom.show) @@ -254,9 +382,9 @@ namespace XCharts { filterStart = startIndex; filterEnd = endIndex; + var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1; if (m_YData.Count > 0) { - var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1; yFilterData = m_YData.GetRange(startIndex, count); } else @@ -265,18 +393,26 @@ namespace XCharts } if (m_XData.Count > 0) { - var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1; 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(); xFilterData = new List(); + filterData = new List(); } } } @@ -304,7 +440,53 @@ namespace XCharts public override void ParseJsonData(string jsonData) { if (string.IsNullOrEmpty(jsonData) || !m_DataFromJson) return; - m_YData = ChartHelper.ParseFloatFromString(jsonData); + ClearData(); + jsonData = jsonData.Replace("\r\n", ""); + jsonData = jsonData.Replace(" ", ""); + jsonData = jsonData.Replace("\n", ""); + int startIndex = jsonData.IndexOf("["); + int endIndex = jsonData.LastIndexOf("]"); + 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 + { + 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.Add(value); + m_Data.Add(serieData); + m_XData.Add(value); + } + } + } } } } diff --git a/Scripts/UI/Internal/Series.cs b/Scripts/UI/Internal/Series.cs index 3ef43ade..e1cb0886 100644 --- a/Scripts/UI/Internal/Series.cs +++ b/Scripts/UI/Internal/Series.cs @@ -124,23 +124,22 @@ namespace XCharts serie.show = show; serie.name = serieName; serie.index = m_Series.Count; - serie.yData = new List(); if (type == SerieType.Scatter) { - serie.symbol = SerieSymbolType.Circle; - serie.symbolSize = 20f; - serie.symbolSelectedSize = 30f; + serie.symbol.type = SerieSymbolType.Circle; + serie.symbol.size = 20f; + serie.symbol.selectedSize = 30f; } else if (type == SerieType.Line) { - serie.symbol = SerieSymbolType.EmptyCircle; - serie.symbolSize = 2.5f; - serie.symbolSelectedSize = 5f; + serie.symbol.type = SerieSymbolType.EmptyCircle; + serie.symbol.size = 2.5f; + serie.symbol.selectedSize = 5f; } else { - serie.symbol = SerieSymbolType.None; + serie.symbol.type = SerieSymbolType.None; } m_Series.Add(serie); } @@ -463,6 +462,15 @@ namespace XCharts return list; } + public void SetSerieSymbolSizeCallback(SymbolSizeCallback size, SymbolSizeCallback selectedSize) + { + foreach (var serie in m_Series) + { + serie.symbol.sizeCallback = size; + serie.symbol.selectedSizeCallback = selectedSize; + } + } + public override void ParseJsonData(string jsonData) { //TODO: diff --git a/Scripts/UI/LineChart.cs b/Scripts/UI/LineChart.cs index 8d9ad10a..72512c77 100644 --- a/Scripts/UI/LineChart.cs +++ b/Scripts/UI/LineChart.cs @@ -121,24 +121,25 @@ namespace XCharts for (int i = 0; i < points.Count; i++) { Vector3 p = points[i]; + var dataIndex = i % dataCount; var serie = m_Series.GetSerie(pointSerieIndex[i]); - float symbolSize = serie.symbolSize; - if (m_Tooltip.show && m_Tooltip.IsSelectedDataIndex(i % dataCount)) + float symbolSize = serie.symbol.size; + if (m_Tooltip.show && m_Tooltip.IsSelectedDataIndex(dataIndex)) { if (IsCartesian()) { - if (m_Series.IsTooltipSelected(i / dataCount)) + if (m_Series.IsTooltipSelected(serie.index)) { - symbolSize = serie.symbolSelectedSize; + symbolSize = serie.symbol.selectedSize; } } else { - symbolSize = serie.symbolSelectedSize; + symbolSize = serie.symbol.selectedSize; } } var color = m_ThemeInfo.GetColor(serie.index); - DrawSymbol(vh, serie.symbol, symbolSize, m_Line.tickness, p, color); + DrawSymbol(vh, serie.symbol.type, symbolSize, m_Line.tickness, p, color); } } @@ -328,7 +329,7 @@ namespace XCharts } } } - if (serie.symbol != SerieSymbolType.None || m_Line.area) + if (serie.symbol.type != SerieSymbolType.None || m_Line.area) { points.Add(np); pointSerieIndexs.Add(serie.index); @@ -506,7 +507,7 @@ namespace XCharts } } } - if (serie.symbol != SerieSymbolType.None || m_Line.area) + if (serie.symbol.type != SerieSymbolType.None || m_Line.area) { points.Add(np); pointSerieIndexs.Add(serie.index);