暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

LegendHandler.cs 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEngine.EventSystems;
  5. using UnityEngine.UI;
  6. using XUGL;
  7. namespace XCharts.Runtime
  8. {
  9. [UnityEngine.Scripting.Preserve]
  10. internal sealed class LegendHandler : MainComponentHandler<Legend>
  11. {
  12. private static readonly string s_LegendObjectName = "legend";
  13. public override void InitComponent()
  14. {
  15. InitLegend(component);
  16. }
  17. public override void CheckComponent(System.Text.StringBuilder sb)
  18. {
  19. var legend = component;
  20. if (ChartHelper.IsColorAlphaZero(legend.labelStyle.textStyle.color))
  21. sb.AppendFormat("warning:legend{0}->textStyle->color alpha is 0\n", legend.index);
  22. var serieNameList = SeriesHelper.GetLegalSerieNameList(chart.series);
  23. if (serieNameList.Count == 0)
  24. sb.AppendFormat("warning:legend{0} need serie.serieName or serieData.name not empty\n", legend.index);
  25. foreach (var category in legend.data)
  26. {
  27. if (!serieNameList.Contains(category))
  28. {
  29. sb.AppendFormat("warning:legend{0} [{1}] is invalid, must be one of serie.serieName or serieData.name\n",
  30. legend.index, category);
  31. }
  32. }
  33. }
  34. public override void DrawTop(VertexHelper vh)
  35. {
  36. DrawLegend(vh);
  37. }
  38. public override void OnSerieDataUpdate(int serieIndex)
  39. {
  40. if (FormatterHelper.NeedFormat(component.formatter))
  41. component.refreshComponent();
  42. }
  43. private void InitLegend(Legend legend)
  44. {
  45. legend.painter = null;
  46. legend.refreshComponent = delegate()
  47. {
  48. legend.OnChanged();
  49. var legendObject = ChartHelper.AddObject(s_LegendObjectName + legend.index, chart.transform, chart.chartMinAnchor,
  50. chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
  51. legend.gameObject = legendObject;
  52. legendObject.hideFlags = chart.chartHideFlags;
  53. //ChartHelper.DestoryGameObjectByMatch(legendObject.transform, "_");
  54. SeriesHelper.UpdateSerieNameList(chart, ref chart.m_LegendRealShowName);
  55. legend.context.background = ChartHelper.AddIcon("background", legendObject.transform, 0, 0);
  56. legend.context.background.transform.SetSiblingIndex(0);
  57. ChartHelper.SetBackground(legend.context.background, legend.background);
  58. List<string> datas;
  59. if (legend.show && legend.data.Count > 0)
  60. {
  61. datas = new List<string>();
  62. foreach (var data in legend.data)
  63. {
  64. if (chart.m_LegendRealShowName.Contains(data) || chart.IsSerieName(data))
  65. datas.Add(data);
  66. }
  67. }
  68. else
  69. {
  70. datas = chart.m_LegendRealShowName;
  71. }
  72. int totalLegend = 0;
  73. for (int i = 0; i < datas.Count; i++)
  74. {
  75. if (!SeriesHelper.IsLegalLegendName(datas[i])) continue;
  76. totalLegend++;
  77. }
  78. legend.RemoveButton();
  79. ChartHelper.HideAllObject(legendObject);
  80. if (!legend.show) return;
  81. for (int i = 0; i < datas.Count; i++)
  82. {
  83. if (!SeriesHelper.IsLegalLegendName(datas[i])) continue;
  84. string legendName = datas[i];
  85. var legendContent = GetFormatterContent(legend, i, datas[i]);
  86. var readIndex = chart.m_LegendRealShowName.IndexOf(datas[i]);
  87. var active = chart.IsActiveByLegend(datas[i]);
  88. var bgColor = LegendHelper.GetIconColor(chart, legend, readIndex, datas[i], active);
  89. bgColor.a = legend.itemOpacity;
  90. var item = LegendHelper.AddLegendItem(chart, legend, i, datas[i], legendObject.transform, chart.theme,
  91. legendContent, bgColor, active, readIndex);
  92. legend.SetButton(legendName, item, totalLegend);
  93. ChartHelper.ClearEventListener(item.button.gameObject);
  94. ChartHelper.AddEventListener(item.button.gameObject, EventTriggerType.PointerDown, (data) =>
  95. {
  96. if (data.selectedObject == null || legend.selectedMode == Legend.SelectedMode.None) return;
  97. var temp = data.selectedObject.name.Split('_');
  98. string selectedName = temp[1];
  99. int clickedIndex = int.Parse(temp[0]);
  100. if (legend.selectedMode == Legend.SelectedMode.Multiple)
  101. {
  102. OnLegendButtonClick(legend, clickedIndex, selectedName, !chart.IsActiveByLegend(selectedName));
  103. }
  104. else
  105. {
  106. var btnList = legend.context.buttonList.Values.ToArray();
  107. if (btnList.Length == 1)
  108. {
  109. OnLegendButtonClick(legend, 0, selectedName, !chart.IsActiveByLegend(selectedName));
  110. }
  111. else
  112. {
  113. for (int n = 0; n < btnList.Length; n++)
  114. {
  115. temp = btnList[n].name.Split('_');
  116. selectedName = btnList[n].legendName;
  117. var index = btnList[n].index;
  118. OnLegendButtonClick(legend, n, selectedName, index == clickedIndex ? true : false);
  119. }
  120. }
  121. }
  122. });
  123. ChartHelper.AddEventListener(item.button.gameObject, EventTriggerType.PointerEnter, (data) =>
  124. {
  125. if (item.button == null) return;
  126. var temp = item.button.name.Split('_');
  127. string selectedName = temp[1];
  128. int index = int.Parse(temp[0]);
  129. OnLegendButtonEnter(legend, index, selectedName);
  130. });
  131. ChartHelper.AddEventListener(item.button.gameObject, EventTriggerType.PointerExit, (data) =>
  132. {
  133. if (item.button == null) return;
  134. var temp = item.button.name.Split('_');
  135. string selectedName = temp[1];
  136. int index = int.Parse(temp[0]);
  137. OnLegendButtonExit(legend, index, selectedName);
  138. });
  139. }
  140. LegendHelper.ResetItemPosition(legend, chart.chartPosition, chart.chartWidth, chart.chartHeight);
  141. };
  142. legend.refreshComponent();
  143. }
  144. private string GetFormatterContent(Legend legend, int dataIndex, string category)
  145. {
  146. if (string.IsNullOrEmpty(legend.formatter))
  147. return category;
  148. else
  149. {
  150. var content = legend.formatter.Replace("{name}", category);
  151. content = content.Replace("{value}", category);
  152. var serie = chart.GetSerie(0);
  153. FormatterHelper.ReplaceContent(ref content, dataIndex, legend.numericFormatter, serie, chart, category);
  154. return content;
  155. }
  156. }
  157. private void OnLegendButtonClick(Legend legend, int index, string legendName, bool show)
  158. {
  159. chart.OnLegendButtonClick(index, legendName, show);
  160. if (chart.onLegendClick != null)
  161. chart.onLegendClick(legend, index, legendName, show);
  162. }
  163. private void OnLegendButtonEnter(Legend legend, int index, string legendName)
  164. {
  165. chart.OnLegendButtonEnter(index, legendName);
  166. if (chart.onLegendEnter != null)
  167. chart.onLegendEnter(legend, index, legendName);
  168. }
  169. private void OnLegendButtonExit(Legend legend, int index, string legendName)
  170. {
  171. chart.OnLegendButtonExit(index, legendName);
  172. if (chart.onLegendExit != null)
  173. chart.onLegendExit(legend, index, legendName);
  174. }
  175. private void DrawLegend(VertexHelper vh)
  176. {
  177. if (chart.series.Count == 0) return;
  178. var legend = component;
  179. if (!legend.show) return;
  180. if (legend.iconType == Legend.Type.Custom) return;
  181. foreach (var kv in legend.context.buttonList)
  182. {
  183. var item = kv.Value;
  184. var rect = item.GetIconRect();
  185. var radius = Mathf.Min(rect.width, rect.height) / 2;
  186. var color = item.GetIconColor();
  187. var iconType = legend.iconType;
  188. if (legend.iconType == Legend.Type.Auto)
  189. {
  190. var serie = chart.GetSerie(item.legendName);
  191. if (serie != null)
  192. {
  193. if (serie is Line || serie is SimplifiedLine)
  194. {
  195. var sp = new Vector3(rect.center.x - rect.width / 2, rect.center.y);
  196. var ep = new Vector3(rect.center.x + rect.width / 2, rect.center.y);
  197. UGL.DrawLine(vh, sp, ep, chart.settings.legendIconLineWidth, color);
  198. if (!serie.symbol.show) continue;
  199. switch (serie.symbol.type)
  200. {
  201. case SymbolType.None:
  202. continue;
  203. case SymbolType.Circle:
  204. iconType = Legend.Type.Circle;
  205. break;
  206. case SymbolType.Diamond:
  207. iconType = Legend.Type.Diamond;
  208. break;
  209. case SymbolType.EmptyCircle:
  210. iconType = Legend.Type.EmptyCircle;
  211. break;
  212. case SymbolType.Rect:
  213. iconType = Legend.Type.Rect;
  214. break;
  215. case SymbolType.Triangle:
  216. iconType = Legend.Type.Triangle;
  217. break;
  218. }
  219. }
  220. else
  221. {
  222. iconType = Legend.Type.Rect;
  223. }
  224. }
  225. else
  226. {
  227. iconType = Legend.Type.Rect;
  228. }
  229. }
  230. switch (iconType)
  231. {
  232. case Legend.Type.Rect:
  233. var cornerRadius = chart.settings.legendIconCornerRadius;
  234. UGL.DrawRoundRectangle(vh, rect.center, rect.width, rect.height, color, color,
  235. 0, cornerRadius, false, 0.5f);
  236. break;
  237. case Legend.Type.Circle:
  238. UGL.DrawCricle(vh, rect.center, radius, color);
  239. break;
  240. case Legend.Type.Diamond:
  241. UGL.DrawDiamond(vh, rect.center, radius, color);
  242. break;
  243. case Legend.Type.EmptyCircle:
  244. var backgroundColor = chart.GetChartBackgroundColor();
  245. UGL.DrawEmptyCricle(vh, rect.center, radius, 2 * chart.settings.legendIconLineWidth,
  246. color, color, backgroundColor, 1f);
  247. break;
  248. case Legend.Type.Triangle:
  249. UGL.DrawTriangle(vh, rect.center, 1.2f * radius, color);
  250. break;
  251. case Legend.Type.Candlestick:
  252. UGL.DrawRoundRectangle(vh, rect.center, rect.width / 2, rect.height / 2, color, color,
  253. 0, null, false, 0.5f);
  254. UGL.DrawLine(vh, new Vector3(rect.center.x, rect.center.y - rect.height / 2),
  255. new Vector3(rect.center.x, rect.center.y + rect.height / 2), 1, color);
  256. break;
  257. }
  258. }
  259. }
  260. }
  261. }