AirControl  1.3.0
Open Source, Modular, and Extensible Flight Simulator For Deep Learning Research
SerieDrawer.cs
1 /************************************************/
2 /* */
3 /* Copyright (c) 2018 - 2021 monitor1394 */
4 /* https://github.com/monitor1394 */
5 /* */
6 /************************************************/
7 
8 using System.Collections.Generic;
9 using UnityEditor;
10 using UnityEngine;
11 
12 namespace XCharts
13 {
14  [CustomPropertyDrawer(typeof(Serie), true)]
16  {
17  private bool m_IsPolar = false;
18  private List<bool> m_DataFoldout = new List<bool>();
19  public override string ClassName { get { return "Serie"; } }
20  public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
21  {
22  pos.width -= 9;
23  base.OnGUI(pos, prop, label);
24  var chart = prop.serializedObject.targetObject as BaseChart;
25  var type = prop.FindPropertyRelative("m_Type");
26  var serieType = (SerieType)type.enumValueIndex;
27  if (!MakeFoldout(prop, "m_Show"))
28  {
29  var orderButton = 48;
30  var gap = 4;
31  var drawRect = pos;
32  drawRect.x += EditorGUIUtility.labelWidth + gap;
33  drawRect.width = pos.width - drawRect.x + ChartEditorHelper.BOOL_WIDTH - orderButton;
34  type.enumValueIndex = EditorGUI.Popup(drawRect, (int)serieType, GetChartSerieTypeNames(chart));
35  }
36  else
37  {
38  m_IsPolar = chart is PolarChart;
39  ++EditorGUI.indentLevel;
40 
41  type.enumValueIndex = EditorGUI.Popup(m_DrawRect, "Type", (int)serieType, GetChartSerieTypeNames(chart));
42  var hig = EditorGUI.GetPropertyHeight(prop);
43  m_DrawRect.y += hig;
44  m_Heights[m_KeyName] += hig;
45 
46  PropertyField(prop, "m_InsertDataToHead");
47  PropertyField(prop, "m_Name");
48  switch (serieType)
49  {
50  case SerieType.Line:
51  PropertyField(prop, "m_Stack");
52  if (m_IsPolar)
53  {
54  PropertyField(prop, "m_PolarIndex");
55  }
56  else
57  {
58  PropertyField(prop, "m_XAxisIndex");
59  PropertyField(prop, "m_YAxisIndex");
60  }
61  PropertyFieldLimitMin(prop, "m_MinShow", 0);
62  PropertyFieldLimitMin(prop, "m_MaxShow", 0);
63  PropertyFieldLimitMin(prop, "m_MaxCache", 0);
64  PropertyField(prop, "m_LineType");
65  PropertyField(prop, "m_SampleDist");
66  PropertyField(prop, "m_SampleType");
67  PropertyField(prop, "m_SampleAverage");
68  PropertyField(prop, "m_Clip");
69  PropertyField(prop, "m_Ignore");
70  PropertyField(prop, "m_IgnoreValue");
71  PropertyField(prop, "m_IgnoreLineBreak");
72  PropertyField(prop, "m_ShowAsPositiveNumber");
73  PropertyField(prop, "m_Large");
74  PropertyField(prop, "m_LargeThreshold");
75  PropertyField(prop, "m_Symbol");
76  PropertyField(prop, "m_LineStyle");
77  PropertyField(prop, "m_LineArrow");
78  PropertyField(prop, "m_AreaStyle");
79  PropertyField(prop, "m_MarkLine");
80  break;
81  case SerieType.Bar:
82  PropertyField(prop, "m_Stack");
83  if (m_IsPolar)
84  {
85  PropertyField(prop, "m_PolarIndex");
86  }
87  else
88  {
89  PropertyField(prop, "m_XAxisIndex");
90  PropertyField(prop, "m_YAxisIndex");
91  }
92  PropertyFieldLimitMin(prop, "m_MinShow", 0);
93  PropertyFieldLimitMin(prop, "m_MaxShow", 0);
94  PropertyFieldLimitMin(prop, "m_MaxCache", 0);
95  PropertyField(prop, "m_BarType");
96  PropertyField(prop, "m_BarPercentStack");
97  PropertyField(prop, "m_BarWidth");
98  PropertyField(prop, "m_BarGap");
99  PropertyField(prop, "m_BarZebraWidth");
100  PropertyField(prop, "m_BarZebraGap");
101  PropertyField(prop, "m_Clip");
102  PropertyField(prop, "m_Ignore");
103  PropertyField(prop, "m_IgnoreValue");
104  PropertyField(prop, "m_ShowAsPositiveNumber");
105  PropertyField(prop, "m_Large");
106  PropertyField(prop, "m_LargeThreshold");
107  PropertyField(prop, "m_MarkLine");
108  break;
109  case SerieType.Pie:
110  PropertyField(prop, "m_RoseType");
111  PropertyField(prop, "m_Space");
112  PropertyTwoFiled(prop, "m_Center");
113  PropertyTwoFiled(prop, "m_Radius");
114  PropertyField(prop, "m_MinAngle");
115  PropertyField(prop, "m_RoundCap");
116  PropertyField(prop, "m_Ignore");
117  PropertyField(prop, "m_IgnoreValue");
118  PropertyField(prop, "m_AvoidLabelOverlap");
119  break;
120  case SerieType.Ring:
121  PropertyTwoFiled(prop, "m_Center");
122  PropertyTwoFiled(prop, "m_Radius");
123  PropertyField(prop, "m_StartAngle");
124  PropertyField(prop, "m_RingGap");
125  PropertyField(prop, "m_RoundCap");
126  PropertyField(prop, "m_Clockwise");
127  PropertyField(prop, "m_TitleStyle");
128  break;
129  case SerieType.Radar:
130  PropertyField(prop, "m_RadarType");
131  PropertyField(prop, "m_RadarIndex");
132  PropertyField(prop, "m_Symbol");
133  PropertyField(prop, "m_LineStyle");
134  PropertyField(prop, "m_AreaStyle");
135  break;
136  case SerieType.Scatter:
137  case SerieType.EffectScatter:
138  PropertyField(prop, "m_Clip");
139  PropertyField(prop, "m_Symbol");
140  break;
141  case SerieType.Heatmap:
142  PropertyField(prop, "m_Ignore");
143  PropertyField(prop, "m_IgnoreValue");
144  break;
145  case SerieType.Gauge:
146  PropertyField(prop, "m_GaugeType");
147  PropertyTwoFiled(prop, "m_Center");
148  PropertyTwoFiled(prop, "m_Radius");
149  PropertyField(prop, "m_Min");
150  PropertyField(prop, "m_Max");
151  PropertyField(prop, "m_StartAngle");
152  PropertyField(prop, "m_EndAngle");
153  PropertyFieldLimitMax(prop, "m_SplitNumber", 36);
154  PropertyField(prop, "m_RoundCap");
155  PropertyField(prop, "m_TitleStyle");
156  PropertyField(prop, "m_GaugeAxis");
157  PropertyField(prop, "m_GaugePointer");
158  break;
159  case SerieType.Liquid:
160  PropertyField(prop, "m_VesselIndex");
161  PropertyField(prop, "m_Min");
162  PropertyField(prop, "m_Max");
163  PropertyField(prop, "m_WaveLength");
164  PropertyField(prop, "m_WaveHeight");
165  PropertyField(prop, "m_WaveSpeed");
166  PropertyField(prop, "m_WaveOffset");
167  break;
168  case SerieType.Candlestick:
169  PropertyField(prop, "m_XAxisIndex");
170  PropertyField(prop, "m_YAxisIndex");
171  PropertyFieldLimitMin(prop, "m_MinShow", 0);
172  PropertyFieldLimitMin(prop, "m_MaxShow", 0);
173  PropertyFieldLimitMin(prop, "m_MaxCache", 0);
174  PropertyField(prop, "m_BarWidth");
175  PropertyField(prop, "m_Clip");
176  PropertyField(prop, "m_ShowAsPositiveNumber");
177  PropertyField(prop, "m_Large");
178  PropertyField(prop, "m_LargeThreshold");
179  break;
180  case SerieType.Custom:
181  var fileds = chart.GetCustomSerieInspectorShowFileds();
182  if (fileds != null && fileds.Length > 0)
183  {
184  foreach (var filed in fileds)
185  {
186  PropertyField(prop, filed);
187  }
188  }
189  var customs = chart.GetCustomSerieInspectorCustomFileds();
190  if (customs != null && customs.Length > 0)
191  {
192  foreach (var custom in customs)
193  {
194  var customProp = prop.FindPropertyRelative(custom[0]);
195  var anatherName = custom[1] + " (" + customProp.displayName + ")";
196  EditorGUI.PropertyField(m_DrawRect, customProp, new GUIContent(anatherName));
197  m_DrawRect.y += EditorGUI.GetPropertyHeight(prop);
198  m_Heights[m_KeyName] += hig;
199  }
200  }
201  break;
202  }
203  PropertyField(prop, "m_ItemStyle");
204  PropertyField(prop, "m_IconStyle");
205  PropertyField(prop, "m_Label");
206  PropertyField(prop, "m_Emphasis");
207  PropertyField(prop, "m_Animation");
208  DrawData(pos, prop, serieType, ref m_DrawRect);
209  --EditorGUI.indentLevel;
210  }
211  }
212 
213  private string[] GetChartSerieTypeNames(BaseChart chart)
214  {
215  var list = System.Enum.GetNames(typeof(SerieType));
216  for (int i = 0; i < list.Length; i++)
217  {
218  if (list[i].Equals("Custom"))
219  {
220  var customName = chart.GetCustomSerieTypeName();
221  if (!string.IsNullOrEmpty(customName))
222  {
223  list[i] = customName;
224  }
225  }
226  }
227  return list;
228  }
229 
230  private void DrawData(Rect pos, SerializedProperty prop, SerieType serieType, ref Rect drawRect)
231  {
232  SerializedProperty m_Datas = prop.FindPropertyRelative("m_Data");
233  SerializedProperty m_DataDimension = prop.FindPropertyRelative("m_ShowDataDimension");
234  SerializedProperty m_ShowDataName = prop.FindPropertyRelative("m_ShowDataName");
235  SerializedProperty m_ShowDataIcon = prop.FindPropertyRelative("m_ShowDataIcon");
236  int index = InitToggle(prop);
237  drawRect.width = EditorGUIUtility.labelWidth + 10;
238  m_DataFoldout[index] = EditorGUI.Foldout(drawRect, m_DataFoldout[index], "Data", true);
239  drawRect.width = pos.width;
240 
241  AddSingleLineHeight();
242  if (m_DataFoldout[index])
243  {
244  EditorGUI.indentLevel++;
245 
246  float nameWid = 45;
247 #if UNITY_2019_3_OR_NEWER
248  var gap = 2;
249  var namegap = 3;
250 #else
251  var gap = 0;
252  var namegap = 0;
253 #endif
254  EditorGUI.PropertyField(new Rect(drawRect.x, drawRect.y, pos.width - 2 * nameWid - 2, pos.height),
255  m_DataDimension);
256  var nameRect = new Rect(pos.width - 2 * nameWid + 14 + gap, drawRect.y, nameWid - gap, pos.height);
257  if (XChartsSettings.editorBlockEnable)
258  {
259  nameRect.x += ChartEditorHelper.BLOCK_WIDTH;
260  }
261  if (GUI.Button(nameRect, new GUIContent("name")))
262  {
263  m_ShowDataName.boolValue = !m_ShowDataName.boolValue;
264  }
265  var iconRect = new Rect(pos.width - nameWid + 14, drawRect.y, nameWid + namegap, pos.height);
266  if (XChartsSettings.editorBlockEnable)
267  {
268  iconRect.x += ChartEditorHelper.BLOCK_WIDTH;
269  }
270  if (GUI.Button(iconRect, new GUIContent("more")))
271  {
272  m_ShowDataIcon.boolValue = !m_ShowDataIcon.boolValue;
273  }
274  var jsonRect = new Rect(pos.width - 70, drawRect.y - pos.height - 2, 90, pos.height);
275  if (GUI.Button(jsonRect, new GUIContent("data from json")))
276  {
277  PraseJsonDataEditor.chart = prop.serializedObject.targetObject as BaseChart;
278  PraseJsonDataEditor.serieIndex = index;
279  PraseJsonDataEditor.ShowWindow();
280  }
281  AddSingleLineHeight();
282  var listSize = m_Datas.arraySize;
283  listSize = EditorGUI.IntField(drawRect, "Size", listSize);
284  AddSingleLineHeight();
285 
286  if (listSize < 0) listSize = 0;
287  if (m_DataDimension.intValue < 1) m_DataDimension.intValue = 1;
288  int dimension = m_DataDimension.intValue;
289  bool showName = m_ShowDataName.boolValue;
290  bool showIcon = m_ShowDataIcon.boolValue;
291  bool showSelected = (serieType == SerieType.Pie);
292  if (listSize != m_Datas.arraySize)
293  {
294  while (listSize > m_Datas.arraySize) m_Datas.arraySize++;
295  while (listSize < m_Datas.arraySize) m_Datas.arraySize--;
296  }
297  if (listSize > 30 && !XChartsSettings.editorShowAllListData)
298  {
299  int num = listSize > 10 ? 10 : listSize;
300  for (int i = 0; i < num; i++)
301  {
302  DrawDataElement(ref drawRect, dimension, m_Datas, showName, showIcon, showSelected, i, pos.width);
303  }
304  if (num >= 10)
305  {
306  EditorGUI.LabelField(drawRect, "...");
307  AddSingleLineHeight();
308  DrawDataElement(ref drawRect, dimension, m_Datas, showName, showIcon, showSelected, listSize - 1, pos.width);
309  }
310  }
311  else
312  {
313  for (int i = 0; i < m_Datas.arraySize; i++)
314  {
315  DrawDataElement(ref drawRect, dimension, m_Datas, showName, showIcon, showSelected, i, pos.width);
316  }
317  }
318  AddHeight(EditorGUIUtility.standardVerticalSpacing);
319  EditorGUI.indentLevel--;
320  }
321  }
322 
323  private void DrawDataElement(ref Rect drawRect, int dimension, SerializedProperty m_Datas, bool showName,
324  bool showDetail, bool showSelected, int index, float currentWidth)
325  {
326  var lastX = drawRect.x;
327  var lastWid = drawRect.width;
328  var lastFieldWid = EditorGUIUtility.fieldWidth;
329  var lastLabelWid = EditorGUIUtility.labelWidth;
330  var serieData = m_Datas.GetArrayElementAtIndex(index);
331  var sereName = serieData.FindPropertyRelative("m_Name");
332  var selected = serieData.FindPropertyRelative("m_Selected");
333 
334  var data = serieData.FindPropertyRelative("m_Data");
335  var fieldCount = dimension + (showName ? 1 : 0);
336 
337  if (fieldCount <= 1)
338  {
339  while (2 > data.arraySize)
340  {
341  var value = data.arraySize == 0 ? index : 0;
342  data.arraySize++;
343  data.GetArrayElementAtIndex(data.arraySize - 1).floatValue = value;
344  }
345  SerializedProperty element = data.GetArrayElementAtIndex(1);
346  if (showSelected)
347  {
348  drawRect.width = drawRect.width - 18;
349  EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + index));
350  drawRect.x = currentWidth - 40;
351  EditorGUI.PropertyField(drawRect, selected, GUIContent.none);
352  drawRect.x = lastX;
353  drawRect.width = lastWid;
354  }
355  else
356  {
357  EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + index));
358  }
359  AddHeight(EditorGUI.GetPropertyHeight(element));
360  }
361  else
362  {
363 #if UNITY_2019_3_OR_NEWER
364  var gap = 2;
365  var namegap = 3;
366 #else
367  var gap = 0;
368  var namegap = 0;
369 #endif
370  EditorGUI.LabelField(drawRect, "Element " + index);
371  var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15 + gap;
372  var dataWidTotal = (currentWidth - (startX + 20.5f + 1));
373  var dataWid = dataWidTotal / fieldCount;
374  var xWid = dataWid - 2;
375  for (int i = 0; i < dimension; i++)
376  {
377  var dataCount = i < 1 ? 2 : i + 1;
378  while (dataCount > data.arraySize)
379  {
380  var value = data.arraySize == 0 ? index : 0;
381  data.arraySize++;
382  data.GetArrayElementAtIndex(data.arraySize - 1).floatValue = value;
383  }
384  drawRect.x = startX + i * xWid;
385  drawRect.width = dataWid + 40;
386  SerializedProperty element = data.GetArrayElementAtIndex(dimension <= 1 ? 1 : i);
387  EditorGUI.PropertyField(drawRect, element, GUIContent.none);
388  }
389  if (showName)
390  {
391  drawRect.x = startX + (fieldCount - 1) * xWid;
392  drawRect.width = dataWid + 40 + dimension * namegap;
393  EditorGUI.PropertyField(drawRect, sereName, GUIContent.none);
394  }
395  AddSingleLineHeight();
396  drawRect.x = lastX;
397  drawRect.width = lastWid;
398  EditorGUIUtility.fieldWidth = lastFieldWid;
399  EditorGUIUtility.labelWidth = lastLabelWid;
400  }
401  if (showDetail)
402  {
403  EditorGUI.indentLevel += 2;
404  var m_Ignore = serieData.FindPropertyRelative("m_Ignore");
405  var m_Selected = serieData.FindPropertyRelative("m_Selected");
406  var m_Id = serieData.FindPropertyRelative("m_Id");
407  var m_EnableIcon = serieData.FindPropertyRelative("m_EnableIconStyle");
408  var m_Icon = serieData.FindPropertyRelative("m_IconStyle");
409  var m_EnableLabel = serieData.FindPropertyRelative("m_EnableLabel");
410  var m_Label = serieData.FindPropertyRelative("m_Label");
411  var m_EnableItemStyle = serieData.FindPropertyRelative("m_EnableItemStyle");
412  var m_ItemStyle = serieData.FindPropertyRelative("m_ItemStyle");
413  var m_EnableEmphasis = serieData.FindPropertyRelative("m_EnableEmphasis");
414  var m_Emphasis = serieData.FindPropertyRelative("m_Emphasis");
415  var m_EnableSymbol = serieData.FindPropertyRelative("m_EnableSymbol");
416  var m_Symbol = serieData.FindPropertyRelative("m_Symbol");
417  EditorGUI.PropertyField(drawRect, m_Ignore);
418  AddHeight(EditorGUI.GetPropertyHeight(m_Ignore));
419  EditorGUI.PropertyField(drawRect, m_Selected);
420  AddHeight(EditorGUI.GetPropertyHeight(m_Selected));
421  EditorGUI.PropertyField(drawRect, m_Id);
422  AddHeight(EditorGUI.GetPropertyHeight(m_Id));
423  EditorGUI.PropertyField(drawRect, m_Icon);
424  ChartEditorHelper.MakeBool(drawRect, m_EnableIcon, 1, "(enable)");
425  AddHeight(EditorGUI.GetPropertyHeight(m_Icon));
426  EditorGUI.PropertyField(drawRect, m_Symbol);
427  ChartEditorHelper.MakeBool(drawRect, m_EnableSymbol, 1, "(enable)");
428  AddHeight(EditorGUI.GetPropertyHeight(m_Symbol));
429  EditorGUI.PropertyField(drawRect, m_Label);
430  ChartEditorHelper.MakeBool(drawRect, m_EnableLabel, 1, "(enable)");
431  AddHeight(EditorGUI.GetPropertyHeight(m_Label));
432  EditorGUI.PropertyField(drawRect, m_ItemStyle);
433  ChartEditorHelper.MakeBool(drawRect, m_EnableItemStyle, 1, "(enable)");
434  AddHeight(EditorGUI.GetPropertyHeight(m_ItemStyle));
435  EditorGUI.PropertyField(drawRect, m_Emphasis);
436  ChartEditorHelper.MakeBool(drawRect, m_EnableEmphasis, 1, "(enable)");
437  AddHeight(EditorGUI.GetPropertyHeight(m_Emphasis));
438  EditorGUI.indentLevel -= 2;
439  }
440  }
441 
442  private int InitToggle(SerializedProperty prop)
443  {
444  int index = 0;
445  var sindex = prop.propertyPath.LastIndexOf('[');
446  var eindex = prop.propertyPath.LastIndexOf(']');
447  if (sindex >= 0 && eindex >= 0)
448  {
449  var str = prop.propertyPath.Substring(sindex + 1, eindex - sindex - 1);
450  int.TryParse(str, out index);
451  }
452  while (index >= m_DataFoldout.Count)
453  {
454  m_DataFoldout.Add(false);
455  }
456  return index;
457  }
458  }
459 }
XCharts.ChartEditorHelper
Definition: ChartEditorHelper.cs:14
XCharts.BasePropertyDrawer
Definition: BasePropertyDrawer.cs:15
XCharts.SerieType
SerieType
the type of serie. 系列类型。
Definition: Serie.cs:19
XCharts
Definition: RewardChart.cs:14
XCharts.SerieDrawer
Definition: SerieDrawer.cs:15
XCharts.SerieSymbolType.Rect
@ Rect
正方形。可通过设置itemStyle的cornerRadius变成圆角矩形。
XCharts.PraseJsonDataEditor
Definition: PraseJsonDataEditor.cs:14
XCharts.BaseChart
The base class of all charts. 所有Chart的基类。
Definition: BaseChart_API.cs:21
XCharts.PolarChart
Definition: PolarChart.cs:20
XCharts.XChartsSettings
Definition: XChartsSettings.cs:25