diff --git a/Demo/Scripts/Demo11_AddSinCurve.cs b/Demo/Scripts/Demo11_AddSinCurve.cs index d3c61fbc..1df9231e 100644 --- a/Demo/Scripts/Demo11_AddSinCurve.cs +++ b/Demo/Scripts/Demo11_AddSinCurve.cs @@ -34,7 +34,6 @@ public class Demo11_AddSinCurve : MonoBehaviour chart.xAxises[0].boundaryGap = false; chart.maxCacheDataNumber = 0; - chart.line.point = false; chart.line.step = false; chart.line.smooth = false; chart.line.area = false; diff --git a/Demo/Scripts/Demo_Dynamic.cs b/Demo/Scripts/Demo_Dynamic.cs index 4719ea2f..bdd31ac3 100644 --- a/Demo/Scripts/Demo_Dynamic.cs +++ b/Demo/Scripts/Demo_Dynamic.cs @@ -22,7 +22,8 @@ public class Demo_Dynamic : MonoBehaviour { chart = gameObject.GetComponentInChildren(); chart.RemoveData(); - chart.AddSerie("data", SerieType.Line); + var serie = chart.AddSerie("data", SerieType.Line); + serie.symbol = SerieSymbolType.None; chart.maxCacheDataNumber = maxCacheDataNumber; timeNow = DateTime.Now; timeNow = timeNow.AddSeconds(-maxCacheDataNumber); diff --git a/Scripts/Editor/PropertyDrawers/LineDrawer.cs b/Scripts/Editor/PropertyDrawers/LineDrawer.cs index 4477cc9b..09828b92 100644 --- a/Scripts/Editor/PropertyDrawers/LineDrawer.cs +++ b/Scripts/Editor/PropertyDrawers/LineDrawer.cs @@ -7,9 +7,6 @@ namespace XCharts public class LineDrawer : PropertyDrawer { SerializedProperty m_Tickness; - SerializedProperty m_Point; - SerializedProperty m_PointWidth; - SerializedProperty m_PointSelectedWidth; SerializedProperty m_Smooth; SerializedProperty m_SmoothStyle; SerializedProperty m_Area; @@ -21,9 +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_PointSelectedWidth = prop.FindPropertyRelative("m_PointSelectedWidth"); m_Smooth = prop.FindPropertyRelative("m_Smooth"); m_SmoothStyle = prop.FindPropertyRelative("m_SmoothStyle"); m_Area = prop.FindPropertyRelative("m_Area"); @@ -45,18 +39,6 @@ namespace XCharts EditorGUI.PropertyField(drawRect, m_Tickness); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - EditorGUI.PropertyField(drawRect, m_Point); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - if (m_Point.boolValue) - { - ++EditorGUI.indentLevel; - EditorGUI.PropertyField(drawRect, m_PointWidth); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - - EditorGUI.PropertyField(drawRect, m_PointSelectedWidth); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - --EditorGUI.indentLevel; - } drawRect.width = EditorGUIUtility.labelWidth + 10; EditorGUI.PropertyField(drawRect, m_Smooth); if (m_Smooth.boolValue) @@ -101,10 +83,6 @@ namespace XCharts if (m_LineModuleToggle) { height = 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing; - var m_Point = prop.FindPropertyRelative("m_Point"); - if(m_Point.boolValue){ - height += 2 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing; - } return height; } else diff --git a/Scripts/Editor/PropertyDrawers/SerieDrawer.cs b/Scripts/Editor/PropertyDrawers/SerieDrawer.cs index e2398d74..35988713 100644 --- a/Scripts/Editor/PropertyDrawers/SerieDrawer.cs +++ b/Scripts/Editor/PropertyDrawers/SerieDrawer.cs @@ -22,6 +22,9 @@ namespace XCharts SerializedProperty name = prop.FindPropertyRelative("m_Name"); 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"); @@ -42,6 +45,15 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_AxisIndex); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + 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; + } EditorGUI.PropertyField(drawRect, m_TwoDimensionData); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; drawRect.width = EditorGUIUtility.labelWidth + 10; @@ -132,6 +144,11 @@ namespace XCharts else { height += 7 * EditorGUIUtility.singleLineHeight + 6 * 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; + } if (m_DataFoldout[index]) { SerializedProperty m_Data = prop.FindPropertyRelative("m_YData"); @@ -150,7 +167,7 @@ namespace XCharts private int InitToggle(SerializedProperty prop) { int index = 0; - int.TryParse(prop.displayName.Split(' ')[1],out index); + int.TryParse(prop.displayName.Split(' ')[1], out index); if (index >= m_DataFoldout.Count) { m_DataFoldout.Add(false); diff --git a/Scripts/UI/Internal/BaseChart.cs b/Scripts/UI/Internal/BaseChart.cs index f8c66d7a..b90f915d 100644 --- a/Scripts/UI/Internal/BaseChart.cs +++ b/Scripts/UI/Internal/BaseChart.cs @@ -1,5 +1,4 @@ -using System.Runtime.CompilerServices; -using UnityEngine; +using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using System; @@ -147,52 +146,62 @@ namespace XCharts /// /// Add a data to serie. - /// If serie doesn't exist,will be add to series. + /// When serie doesn't exist, the data is ignored. /// If serieName doesn't exist in legend,will be add to legend. /// /// the name of serie /// the data to add - public virtual void AddData(string serieName, float value) + /// Returns True on success + public virtual bool AddData(string serieName, float value) { m_Legend.AddData(serieName); - m_Series.AddData(serieName, value, m_MaxCacheDataNumber); - RefreshChart(); + var success = m_Series.AddData(serieName, value, m_MaxCacheDataNumber); + if (success) RefreshChart(); + return success; } /// /// Add a data to serie. - /// If serie doesn't exist, the data is ignored. + /// When serie doesn't exist, the data is ignored. /// /// the index of serie /// the data to add - public virtual void AddData(int serieIndex, float value) + /// Returns True on success + public virtual bool AddData(int serieIndex, float value) { - m_Series.AddData(serieIndex, value, m_MaxCacheDataNumber); - RefreshChart(); + var success = m_Series.AddData(serieIndex, value, m_MaxCacheDataNumber); + if (success) RefreshChart(); + return success; } /// - /// Add a (x,y) data to serie + /// Add a (x,y) data to serie. + /// When serie doesn't exist, the data is ignored. /// /// the name of serie /// x data /// y data - public virtual void AddXYData(string serieName, float xValue, float yValue) + /// Returns True on success + public virtual bool AddXYData(string serieName, float xValue, float yValue) { - m_Series.AddXYData(serieName, xValue, yValue, m_MaxCacheDataNumber); - RefreshChart(); + var success = m_Series.AddXYData(serieName, xValue, yValue, m_MaxCacheDataNumber); + if (success) RefreshChart(); + return true; } /// - /// Add a (x,y) data to serie + /// Add a (x,y) data to serie. + /// When serie doesn't exist, the data is ignored. /// /// the index of serie /// x data /// y data - public virtual void AddXYData(int serieIndex, float xValue, float yValue) + /// Returns True on success + public virtual bool AddXYData(int serieIndex, float xValue, float yValue) { - m_Series.AddXYData(serieIndex, xValue, yValue, m_MaxCacheDataNumber); - RefreshChart(); + var success = m_Series.AddXYData(serieIndex, xValue, yValue, m_MaxCacheDataNumber); + if (success) RefreshChart(); + return success; } /// /// Update serie data by serie name. @@ -652,6 +661,40 @@ 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); + break; + case SerieSymbolType.EmptyCircle: + ChartHelper.DrawCricle(vh, pos, symbolSize, m_ThemeInfo.backgroundColor); + ChartHelper.DrawDoughnut(vh, pos, symbolSize - tickness, symbolSize, 0, 360, color); + 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; + } + } + public virtual void OnPointerDown(PointerEventData eventData) { } diff --git a/Scripts/UI/Internal/Line.cs b/Scripts/UI/Internal/Line.cs index bc0cba9d..5a1f2ea4 100644 --- a/Scripts/UI/Internal/Line.cs +++ b/Scripts/UI/Internal/Line.cs @@ -12,9 +12,6 @@ namespace XCharts End } [SerializeField] private float m_Tickness; - [SerializeField] private bool m_Point; - [SerializeField] private float m_PointWidth; - [SerializeField] private float m_PointSelectedWidth; [SerializeField] private bool m_Smooth; [SerializeField] [Range(1f, 10f)] private float m_SmoothStyle; [SerializeField] private bool m_Area; @@ -22,9 +19,6 @@ namespace XCharts [SerializeField] private StepType m_StepType; 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 float pointSelectedWidth { get { return m_PointSelectedWidth; } set { m_PointSelectedWidth = value; } } public float smoothStyle { get { return m_SmoothStyle; } set { m_SmoothStyle = value; } } public bool smooth { get { return m_Smooth; } set { m_Smooth = value; } } public bool area { get { return m_Area; } set { m_Area = value; } } @@ -38,9 +32,6 @@ namespace XCharts var line = new Line { m_Tickness = 0.8f, - m_Point = true, - m_PointWidth = 2.5f, - m_PointSelectedWidth = 5.5f, m_Smooth = false, m_SmoothStyle = 2f, m_Area = false, diff --git a/Scripts/UI/Internal/Serie.cs b/Scripts/UI/Internal/Serie.cs index 6e711e89..2990b6a6 100644 --- a/Scripts/UI/Internal/Serie.cs +++ b/Scripts/UI/Internal/Serie.cs @@ -7,34 +7,52 @@ namespace XCharts { public enum SerieType { - None, Line, Bar, Pie, - Radar + Radar, + Scatter, + EffectScatter + } + + public enum SerieSymbolType + { + EmptyCircle, + Circle, + Rect, + Triangle, + Diamond, + None, } [System.Serializable] public class Serie : JsonDataSupport { - [SerializeField] [DefaultValue("true")] private bool m_Show; + [SerializeField] [DefaultValue("true")] private bool m_Show = true; [SerializeField] private SerieType m_Type; [SerializeField] private bool m_Selected; [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; [FormerlySerializedAs("m_Data")] [SerializeField] private List m_YData = new List(); [SerializeField] private List m_XData = new List(); public int index { get; set; } + public int dataCount { get { return m_YData.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; } } diff --git a/Scripts/UI/Internal/Series.cs b/Scripts/UI/Internal/Series.cs index f28f0def..3ef43ade 100644 --- a/Scripts/UI/Internal/Series.cs +++ b/Scripts/UI/Internal/Series.cs @@ -125,6 +125,23 @@ namespace XCharts 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; + } + else if (type == SerieType.Line) + { + serie.symbol = SerieSymbolType.EmptyCircle; + serie.symbolSize = 2.5f; + serie.symbolSelectedSize = 5f; + } + else + { + serie.symbol = SerieSymbolType.None; + } m_Series.Add(serie); } else @@ -134,41 +151,48 @@ namespace XCharts return serie; } - public Serie AddData(string name, float value, int maxDataNumber = 0) + public bool AddData(string serieName, float value, int maxDataNumber = 0) { - var serie = AddSerie(name, SerieType.None); - serie.AddYData(value, maxDataNumber); - return serie; + var serie = GetSerie(serieName); + if (serie != null) + { + serie.AddYData(value, maxDataNumber); + return true; + } + return false; } - public Serie AddData(int index, float value, int maxDataNumber = 0) + public bool AddData(int index, float value, int maxDataNumber = 0) { var serie = GetSerie(index); if (serie != null) { serie.AddYData(value, maxDataNumber); + return true; } - return serie; + return false; } - public Serie AddXYData(string serieName, float xValue, float yValue, int maxDataNumber = 0) + public bool AddXYData(string serieName, float xValue, float yValue, int maxDataNumber = 0) { var serie = GetSerie(serieName); if (serie != null) { serie.AddXYData(xValue, yValue, maxDataNumber); + return true; } - return serie; + return false; } - public Serie AddXYData(int index, float xValue, float yValue, int maxDataNumber = 0) + public bool AddXYData(int index, float xValue, float yValue, int maxDataNumber = 0) { var serie = GetSerie(index); if (serie != null) { serie.AddXYData(xValue, yValue, maxDataNumber); + return true; } - return serie; + return false; } public void UpdateData(string name, float value, int dataIndex = 0) diff --git a/Scripts/UI/LineChart.cs b/Scripts/UI/LineChart.cs index 4540ab3c..8d9ad10a 100644 --- a/Scripts/UI/LineChart.cs +++ b/Scripts/UI/LineChart.cs @@ -52,7 +52,7 @@ namespace XCharts int serieCount = 0; List points = new List(); - List colors = new List(); + List pointSerieIndex = new List(); int dataCount = 0; HashSet serieNameSet = new HashSet(); int serieNameCount = -1; @@ -70,13 +70,13 @@ namespace XCharts serieNameCount++; } Color color = m_ThemeInfo.GetColor(serieNameCount); - DrawXLineSerie(vh, serieCount, color, serie, ref dataCount, ref points, ref colors, ref seriesCurrHig); + DrawXLineSerie(vh, serieCount, color, serie, ref dataCount, ref points, ref pointSerieIndex, ref seriesCurrHig); if (serie.show) { serieCount++; } } - DrawLinePoint(vh, dataCount, points, colors); + DrawLinePoint(vh, dataCount, points, pointSerieIndex); } DrawXTooltipIndicator(vh); } @@ -87,7 +87,7 @@ namespace XCharts int seriesCount = stackSeries.Count; int serieCount = 0; List points = new List(); - List colors = new List(); + List pointSerieIndex = new List(); int dataCount = 0; HashSet serieNameSet = new HashSet(); int serieNameCount = -1; @@ -105,54 +105,45 @@ namespace XCharts serieNameCount++; } Color color = m_ThemeInfo.GetColor(serieNameCount); - DrawYLineSerie(vh, serieCount, color, serie, ref dataCount, ref points, ref colors, ref seriesHig); + DrawYLineSerie(vh, serieCount, color, serie, ref dataCount, ref points, ref pointSerieIndex, ref seriesHig); if (serie.show) { serieCount++; } } - DrawLinePoint(vh, dataCount, points, colors); + DrawLinePoint(vh, dataCount, points, pointSerieIndex); } DrawYTooltipIndicator(vh); } - private void DrawLinePoint(VertexHelper vh, int dataCount, List points, List colors) + private void DrawLinePoint(VertexHelper vh, int dataCount, List points, List pointSerieIndex) { - if (m_Line.point) + for (int i = 0; i < points.Count; i++) { - for (int i = 0; i < points.Count; i++) + Vector3 p = points[i]; + var serie = m_Series.GetSerie(pointSerieIndex[i]); + float symbolSize = serie.symbolSize; + if (m_Tooltip.show && m_Tooltip.IsSelectedDataIndex(i % dataCount)) { - Vector3 p = points[i]; - float pointWid = m_Line.pointWidth; - if (m_Tooltip.show && m_Tooltip.IsSelectedDataIndex(i % dataCount)) + if (IsCartesian()) { - if (IsCartesian()) + if (m_Series.IsTooltipSelected(i / dataCount)) { - if (m_Series.IsTooltipSelected(i / dataCount)) - { - pointWid = m_Line.pointSelectedWidth; - } + symbolSize = serie.symbolSelectedSize; } - else - { - pointWid = m_Line.pointSelectedWidth; - } - } - if (m_Theme == Theme.Dark) - { - ChartHelper.DrawCricle(vh, p, pointWid, colors[i], (int)m_Line.pointWidth * 5); } else { - ChartHelper.DrawCricle(vh, p, pointWid, Color.white); - ChartHelper.DrawDoughnut(vh, p, pointWid - m_Line.tickness, pointWid, 0, 360, colors[i]); + symbolSize = serie.symbolSelectedSize; } } + var color = m_ThemeInfo.GetColor(serie.index); + DrawSymbol(vh, serie.symbol, symbolSize, m_Line.tickness, p, color); } } private void DrawXLineSerie(VertexHelper vh, int serieIndex, Color color, Serie serie, ref int dataCount, - ref List points, ref List colors, ref Dictionary seriesHig) + ref List points, ref List pointSerieIndexs, ref Dictionary seriesHig) { if (!IsActive(serie.index)) return; List lastPoints = new List(); @@ -337,10 +328,10 @@ namespace XCharts } } } - if (m_Line.point) + if (serie.symbol != SerieSymbolType.None || m_Line.area) { points.Add(np); - colors.Add(color); + pointSerieIndexs.Add(serie.index); } seriesHig[i] += yDataHig; lp = np; @@ -348,7 +339,7 @@ namespace XCharts } private void DrawYLineSerie(VertexHelper vh, int serieIndex, Color color, Serie serie, ref int dataCount, - ref List points, ref List colors, ref Dictionary seriesHig) + ref List points, ref List pointSerieIndexs, ref Dictionary seriesHig) { if (!IsActive(serie.index)) return; List lastPoints = new List(); @@ -515,10 +506,10 @@ namespace XCharts } } } - if (m_Line.point) + if (serie.symbol != SerieSymbolType.None || m_Line.area) { points.Add(np); - colors.Add(color); + pointSerieIndexs.Add(serie.index); } seriesHig[i] += dataHig; lp = np; diff --git a/Scripts/UI/PieChart.cs b/Scripts/UI/PieChart.cs index c4e1a793..1c00474c 100644 --- a/Scripts/UI/PieChart.cs +++ b/Scripts/UI/PieChart.cs @@ -26,13 +26,15 @@ namespace XCharts /// /// the name of data /// the data - public override void AddData(string serieName, float value) + /// Return true forever + public override bool AddData(string serieName, float value) { m_Legend.AddData(serieName); var serie = m_Series.AddSerie(serieName, SerieType.Pie); serie.ClearData(); serie.AddYData(value); RefreshChart(); + return true; } ///