diff --git a/Assets/XCharts/Editor/Charts/BaseChartEditor.cs b/Assets/XCharts/Editor/Charts/BaseChartEditor.cs index 03e46b54..5c4fffc7 100644 --- a/Assets/XCharts/Editor/Charts/BaseChartEditor.cs +++ b/Assets/XCharts/Editor/Charts/BaseChartEditor.cs @@ -252,10 +252,8 @@ namespace XCharts foreach (var kvp in typeMap) { var type = kvp; - if (RuntimeUtil.HasSubclass(type)) - continue; - - list.Add(type); + if (type.IsDefined(typeof(SerieHandlerAttribute), false)) + list.Add(type); } list.Sort((a, b) => { return a.Name.CompareTo(b.Name); }); return list; diff --git a/Assets/XCharts/Editor/Series/SerieBaseEditor.cs b/Assets/XCharts/Editor/Series/SerieBaseEditor.cs index 71ee6d3c..99d3cf07 100644 --- a/Assets/XCharts/Editor/Series/SerieBaseEditor.cs +++ b/Assets/XCharts/Editor/Series/SerieBaseEditor.cs @@ -21,6 +21,7 @@ namespace XCharts //Editor m_Inspector; internal SerializedProperty baseProperty; internal SerializedProperty showProperty; + internal List menus = new List(); protected Dictionary m_CoordOptionsDic; protected List m_CoordOptionsNames; diff --git a/Assets/XCharts/Editor/Series/SerieEditor.cs b/Assets/XCharts/Editor/Series/SerieEditor.cs index 8a0e81b3..c8018a63 100644 --- a/Assets/XCharts/Editor/Series/SerieEditor.cs +++ b/Assets/XCharts/Editor/Series/SerieEditor.cs @@ -62,7 +62,6 @@ namespace XCharts if (m_DataDimension.intValue < 1) m_DataDimension.intValue = 1; int dimension = m_DataDimension.intValue; bool showName = m_ShowDataName.boolValue; - bool showSelected = serie is Pie; if (listSize != m_Datas.arraySize) { while (listSize > m_Datas.arraySize) m_Datas.arraySize++; @@ -73,25 +72,25 @@ namespace XCharts int num = listSize > 10 ? 10 : listSize; for (int i = 0; i < num; i++) { - DrawSerieData(dimension, m_Datas, i, showName, showSelected); + DrawSerieData(dimension, m_Datas, i, showName); } if (num >= 10) { ChartEditorHelper.DrawHeader("... ", false, false, null, null); - DrawSerieData(dimension, m_Datas, listSize - 1, showName, showSelected); + DrawSerieData(dimension, m_Datas, listSize - 1, showName); } } else { for (int i = 0; i < m_Datas.arraySize; i++) { - DrawSerieData(dimension, m_Datas, i, showName, showSelected); + DrawSerieData(dimension, m_Datas, i, showName); } } EditorGUI.indentLevel--; } - private void DrawSerieData(int dimension, SerializedProperty m_Datas, int index, bool showName, bool showSelected) + private void DrawSerieData(int dimension, SerializedProperty m_Datas, int index, bool showName) { bool flag; if (!m_DataElementFoldout.TryGetValue(index, out flag)) @@ -112,8 +111,6 @@ namespace XCharts 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"); #if UNITY_2019_3_OR_NEWER var gap = 2; @@ -132,21 +129,9 @@ namespace XCharts } SerializedProperty element = data.GetArrayElementAtIndex(1); var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15 + gap; - if (showSelected) - { - drawRect.width = drawRect.width - 18; - EditorGUI.PropertyField(drawRect, element, GUIContent.none); - drawRect.x = currentWidth - 40; - EditorGUI.PropertyField(drawRect, selected, GUIContent.none); - drawRect.x = lastX; - drawRect.width = lastWid; - } - else - { - drawRect.x = startX; - drawRect.xMax = maxX; - EditorGUI.PropertyField(drawRect, element, GUIContent.none); - } + drawRect.x = startX; + drawRect.xMax = maxX; + EditorGUI.PropertyField(drawRect, element, GUIContent.none); } else { diff --git a/Assets/XCharts/Editor/Series/SerieListEditor.cs b/Assets/XCharts/Editor/Series/SerieListEditor.cs index b49235f2..2c1d767a 100644 --- a/Assets/XCharts/Editor/Series/SerieListEditor.cs +++ b/Assets/XCharts/Editor/Series/SerieListEditor.cs @@ -84,46 +84,20 @@ namespace XCharts { var editor = m_Editors[i]; string title = editor.GetDisplayTitle(); - int id = i; - var menus = new List(); - menus.Add(new HeaderMenuInfo("Remove", () => { RemoveSerieEditor(id); })); - if (i < m_Editors.Count - 1) - menus.Add(new HeaderMenuInfo("Move Down", () => - { - if (chart.MoveDownSerie(id)) - { - m_SeriesProperty = m_BaseEditor.RefreshSeries(); - RefreshEditors(); - } - })); - if (i > 0) - menus.Add(new HeaderMenuInfo("Move Up", () => - { - if (chart.MoveUpSerie(id)) - { - m_SeriesProperty = m_BaseEditor.RefreshSeries(); - RefreshEditors(); - } - })); bool displayContent = ChartEditorHelper.DrawHeader( title, editor.baseProperty, editor.showProperty, - menus.ToArray()); + editor.menus.ToArray()); if (displayContent) { editor.OnInternalInspectorGUI(); } } - if (m_Editors.Count > 0) - { - //EditorGUILayout.Space(); - } - else + if (m_Editors.Count <= 0) { EditorGUILayout.HelpBox("No serie.", MessageType.Info); } - //EditorGUILayout.Space(); } void RefreshEditors() @@ -142,7 +116,7 @@ namespace XCharts void CreateEditor(Serie serie, SerializedProperty property, int index = -1) { - + var id = index >= 0 ? index : m_Editors.Count; var settingsType = serie.GetType(); Type editorType; @@ -150,6 +124,39 @@ namespace XCharts editorType = typeof(SerieBaseEditor); var editor = (SerieBaseEditor)Activator.CreateInstance(editorType); editor.Init(chart, serie, property, m_BaseEditor); + editor.menus.Clear(); + editor.menus.Add(new HeaderMenuInfo("Clone", () => + { + CloneSerie(editor.serie); + })); + editor.menus.Add(new HeaderMenuInfo("Remove", () => + { + if (EditorUtility.DisplayDialog("", "Sure remove serie?", "Yes", "Cancel")) + RemoveSerieEditor(id); + })); + editor.menus.Add(new HeaderMenuInfo("Move Down", () => + { + if (chart.MoveDownSerie(id)) + { + m_SeriesProperty = m_BaseEditor.RefreshSeries(); + RefreshEditors(); + } + })); + editor.menus.Add(new HeaderMenuInfo("Move Up", () => + { + if (chart.MoveUpSerie(id)) + { + m_SeriesProperty = m_BaseEditor.RefreshSeries(); + RefreshEditors(); + } + })); + foreach (var type in GetCovertToSerie(editor.serie.GetType())) + { + editor.menus.Add(new HeaderMenuInfo("Covert to " + type.Name, () => + { + CovertSerie(editor.serie, type); + })); + } if (index < 0) m_Editors.Add(editor); @@ -173,6 +180,21 @@ namespace XCharts AssetDatabase.Refresh(); } + public void CovertSerie(Serie serie, Type type) + { + chart.CovertSerie(serie, type); + m_SeriesProperty = m_BaseEditor.RefreshSeries(); + RefreshEditors(); + } + + public void CloneSerie(Serie serie){ + var newSerie = serie.Clone(); + newSerie.serieName = chart.GenerateDefaultSerieName(); + chart.InsertSerie(newSerie); + m_SeriesProperty = m_BaseEditor.RefreshSeries(); + RefreshEditors(); + } + private void RemoveSerieEditor(int id) { m_Editors[id].OnDisable(); @@ -186,5 +208,23 @@ namespace XCharts AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } + + private List GetCovertToSerie(Type serie) + { + var list = new List(); + var typeMap = RuntimeUtil.GetAllTypesDerivedFrom(); + foreach (var kvp in typeMap) + { + var type = kvp; + if (type.IsDefined(typeof(SerieConvertAttribute), false)) + { + var attribute = type.GetAttribute(); + if (attribute != null && attribute.Contains(serie)) + list.Add(type); + } + } + list.Sort((a, b) => { return a.Name.CompareTo(b.Name); }); + return list; + } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Helper/SerieHelper.cs b/Assets/XCharts/Runtime/Helper/SerieHelper.cs index 25838572..923e2b70 100644 --- a/Assets/XCharts/Runtime/Helper/SerieHelper.cs +++ b/Assets/XCharts/Runtime/Helper/SerieHelper.cs @@ -5,7 +5,9 @@ /* */ /************************************************/ +using System; using System.Collections.Generic; +using System.Reflection; using System.Text; using UnityEngine; @@ -721,5 +723,24 @@ namespace XCharts break; } } + + public static T CloneSerie(Serie serie) where T : Serie + { + var newSerie = Activator.CreateInstance(); + SerieHelper.CopySerie(serie, newSerie); + return newSerie; + } + + public static void CopySerie(Serie oldSerie, Serie newSerie) + { + var fields = typeof(Serie).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + foreach (var field in fields) + { + if (field.IsDefined(typeof(SerializeField))) + { + field.SetValue(newSerie, field.GetValue(oldSerie)); + } + } + } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs index b3113f79..7ccb2ff4 100644 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs +++ b/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs @@ -9,6 +9,9 @@ using System; namespace XCharts { [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + /// + /// What serie can convert to me + /// public sealed class SerieConvertAttribute : Attribute { public readonly Type type0; @@ -39,9 +42,13 @@ namespace XCharts type3 = serie4; } - public bool Contains() where T : CoordSystem + public bool Contains() where T : Serie + { + return Contains(typeof(T)); + } + + public bool Contains(Type type) { - var type = typeof(T); return (type == type0 || type == type1 || type == type2 || type == type3); } } diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs b/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs index dfa1d3f2..77f73f76 100644 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs +++ b/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs @@ -8,6 +8,7 @@ using UnityEngine; using System.Collections.Generic; using System; +using System.Reflection; namespace XCharts { @@ -28,6 +29,16 @@ namespace XCharts return InsertSerie(index, typeof(T), serieName, show) as T; } + public void InsertSerie(Serie serie, int index = -1, bool addToHead = false) + { + serie.AnimationRestart(); + if (addToHead) m_Series.Insert(0, serie); + else if (index >= 0) m_Series.Insert(index, serie); + else m_Series.Add(serie); + ResetSeriesIndex(); + SeriesHelper.UpdateSerieNameList(this, ref m_LegendRealShowName); + } + public bool MoveUpSerie(int serieIndex) { if (serieIndex < 0 || serieIndex > m_Series.Count - 1) return false; @@ -145,6 +156,46 @@ namespace XCharts RefreshChart(); } + public bool CovertSerie(Serie serie) where T : Serie + { + return CovertSerie(serie, typeof(T)); + } + + public bool CovertSerie(Serie serie, Type type) + { + try + { + var newSerie = type.InvokeMember("CovertSerie", + BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public, null, null, + new object[] { serie }) as Serie; + return ReplaceSerie(serie, newSerie); + } + catch + { + Debug.LogError(string.Format("CovertSerie Failed: can't found {0}.CovertSerie(Serie serie)", type.Name)); + return false; + } + } + + public bool ReplaceSerie(Serie oldSerie, Serie newSerie) + { + if (oldSerie == null || newSerie == null) + return false; + + var index = m_Series.IndexOf(oldSerie); + if (index < 0) + return false; + + oldSerie.OnRemove(); + m_Series.RemoveAt(index); + m_Series.Insert(index, newSerie); + ResetSeriesIndex(); + InitSerieHandlers(); + RefreshAllComponent(); + RefreshChart(); + return true; + } + /// /// Add a data to serie. @@ -786,15 +837,12 @@ namespace XCharts { serie.symbol.show = false; } - serie.AnimationRestart(); - if (addToHead) m_Series.Insert(0, serie); - else if (index >= 0) m_Series.Insert(index, serie); - else m_Series.Add(serie); - ResetSeriesIndex(); - SeriesHelper.UpdateSerieNameList(this, ref m_LegendRealShowName); + InsertSerie(serie, index, addToHead); return serie; } + + private void ResetSeriesIndex() { for (int i = 0; i < m_Series.Count; i++) diff --git a/Assets/XCharts/Runtime/Serie/Bar/Bar.cs b/Assets/XCharts/Runtime/Serie/Bar/Bar.cs index b7614759..fdc17fdf 100644 --- a/Assets/XCharts/Runtime/Serie/Bar/Bar.cs +++ b/Assets/XCharts/Runtime/Serie/Bar/Bar.cs @@ -5,10 +5,15 @@ /* */ /************************************************/ +using System; +using System.Reflection; +using UnityEngine; + namespace XCharts { [System.Serializable] [SerieHandler(typeof(BarHandler), true)] + [SerieConvert(typeof(Line),typeof(Pie))] [RequireChartComponent(typeof(GridCoord))] public class Bar : Serie, INeedSerieContainer { @@ -23,5 +28,11 @@ namespace XCharts chart.AddData(serie.index, UnityEngine.Random.Range(10, 90)); } } + + public static Bar CovertSerie(Serie serie) + { + var newSerie = SerieHelper.CloneSerie(serie); + return newSerie; + } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/Line.cs b/Assets/XCharts/Runtime/Serie/Line/Line.cs index c6b3bc19..045eefb8 100644 --- a/Assets/XCharts/Runtime/Serie/Line/Line.cs +++ b/Assets/XCharts/Runtime/Serie/Line/Line.cs @@ -12,7 +12,7 @@ namespace XCharts { [Serializable] [SerieHandler(typeof(LineHandler), true)] - [SerieConvert(typeof(Bar))] + [SerieConvert(typeof(Bar), typeof(Pie))] [CoordOptions(typeof(GridCoord), typeof(PolarCoord))] public class Line : Serie, INeedSerieContainer { @@ -29,5 +29,11 @@ namespace XCharts chart.AddData(serie.index, UnityEngine.Random.Range(10, 90)); } } + + public static Line CovertSerie(Serie serie) + { + var newSerie = serie.Clone(); + return newSerie; + } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs index ca0161ac..53ee6927 100644 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs +++ b/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs @@ -177,6 +177,9 @@ namespace XCharts for (int i = 0; i < count; i++) { var serieData = serie.GetSerieData(i); + if (serieData == null) + continue; + var symbol = SerieHelper.GetSerieSymbol(serie, serieData); if (!symbol.show || !symbol.ShowSymbol(i, count)) diff --git a/Assets/XCharts/Runtime/Serie/Pie/Pie.cs b/Assets/XCharts/Runtime/Serie/Pie/Pie.cs index 2337c4da..0f6c4135 100644 --- a/Assets/XCharts/Runtime/Serie/Pie/Pie.cs +++ b/Assets/XCharts/Runtime/Serie/Pie/Pie.cs @@ -8,9 +8,12 @@ namespace XCharts { [System.Serializable] + [SerieConvert(typeof(Line), typeof(Bar))] [SerieHandler(typeof(PieHandler), true)] public class Pie : Serie { + public override bool useDataNameForColor { get { return true; } } + public static void AddDefaultSerie(BaseChart chart, string serieName) { var serie = chart.AddSerie(serieName); @@ -19,6 +22,10 @@ namespace XCharts chart.AddData(serie.index, 10, "pie3"); } - public override bool useDataNameForColor { get { return true; } } + public static Pie CovertSerie(Serie serie) + { + var newSerie = SerieHelper.CloneSerie(serie); + return newSerie; + } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Serie.cs b/Assets/XCharts/Runtime/Serie/Serie.cs index d6f643e5..08ed710f 100644 --- a/Assets/XCharts/Runtime/Serie/Serie.cs +++ b/Assets/XCharts/Runtime/Serie/Serie.cs @@ -1757,5 +1757,19 @@ namespace XCharts { return index.CompareTo((obj as Serie).index); } + + public T Clone() where T : Serie + { + var newSerie = Activator.CreateInstance(); + SerieHelper.CopySerie(this, newSerie); + return newSerie; + } + + public Serie Clone() + { + var newSerie = Activator.CreateInstance(GetType()) as Serie; + SerieHelper.CopySerie(this, newSerie); + return newSerie; + } } }