Bez popisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LabelStyle.cs 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. using System;
  2. using UnityEngine;
  3. namespace XCharts.Runtime
  4. {
  5. /// <summary>
  6. /// Text label of chart, to explain some data information about graphic item like value, name and so on.
  7. /// |图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
  8. /// </summary>
  9. [System.Serializable]
  10. public class LabelStyle : ChildComponent, ISerieExtraComponent, ISerieDataComponent
  11. {
  12. /// <summary>
  13. /// The position of label.
  14. /// |标签的位置。
  15. /// </summary>
  16. public enum Position
  17. {
  18. Default,
  19. /// <summary>
  20. /// Outside of sectors of pie chart, which relates to corresponding sector through visual guide line.
  21. /// |饼图扇区外侧,通过视觉引导线连到相应的扇区。
  22. /// </summary>
  23. Outside,
  24. /// <summary>
  25. /// Inside the sectors of pie chart.
  26. /// |饼图扇区内部。
  27. /// </summary>
  28. Inside,
  29. /// <summary>
  30. /// In the center of pie chart.
  31. /// |在饼图中心位置。
  32. /// </summary>
  33. Center,
  34. /// <summary>
  35. /// top of symbol.
  36. /// |图形标志的顶部。
  37. /// </summary>
  38. Top,
  39. /// <summary>
  40. /// the bottom of symbol.
  41. /// |图形标志的底部。
  42. /// </summary>
  43. Bottom,
  44. /// <summary>
  45. /// the left of symbol.
  46. /// |图形标志的左边。
  47. /// </summary>
  48. Left,
  49. /// <summary>
  50. /// the right of symbol.
  51. /// |图形标志的右边。
  52. /// </summary>
  53. Right,
  54. /// <summary>
  55. /// the start of line.
  56. /// |线的起始点。
  57. /// </summary>
  58. Start,
  59. /// <summary>
  60. /// the middle of line.
  61. /// |线的中点。
  62. /// </summary>
  63. Middle,
  64. /// <summary>
  65. /// the end of line.
  66. /// |线的结束点。
  67. /// </summary>
  68. End
  69. }
  70. [SerializeField] protected bool m_Show = true;
  71. [SerializeField] Position m_Position = Position.Default;
  72. [SerializeField] protected bool m_AutoOffset = false;
  73. [SerializeField] protected Vector3 m_Offset;
  74. [SerializeField] protected float m_Rotate;
  75. [SerializeField] protected float m_Distance;
  76. [SerializeField] protected string m_Formatter;
  77. [SerializeField] protected string m_NumericFormatter = "";
  78. [SerializeField] protected float m_Width = 0;
  79. [SerializeField] protected float m_Height = 0;
  80. [SerializeField] protected IconStyle m_Icon = new IconStyle();
  81. [SerializeField] protected ImageStyle m_Background = new ImageStyle();
  82. [SerializeField] protected TextPadding m_TextPadding = new TextPadding();
  83. [SerializeField] protected TextStyle m_TextStyle = new TextStyle();
  84. protected LabelFormatterFunction m_FormatterFunction;
  85. public void Reset()
  86. {
  87. m_Show = false;
  88. m_Position = Position.Default;
  89. m_Offset = Vector3.zero;
  90. m_Distance = 0;
  91. m_Rotate = 0;
  92. m_Width = 0;
  93. m_Height = 0;
  94. m_NumericFormatter = "";
  95. m_AutoOffset = false;
  96. }
  97. /// <summary>
  98. /// Whether the label is showed.
  99. /// |是否显示文本标签。
  100. /// </summary>
  101. public bool show
  102. {
  103. get { return m_Show; }
  104. set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetAllDirty(); }
  105. }
  106. /// <summary>
  107. /// The position of label.
  108. /// |标签的位置。
  109. /// </summary>
  110. public Position position
  111. {
  112. get { return m_Position; }
  113. set { if (PropertyUtil.SetStruct(ref m_Position, value)) SetAllDirty(); }
  114. }
  115. /// <summary>
  116. /// formatter of label.
  117. /// |标签内容字符串模版格式器。支持用 \n 换行。
  118. /// 模板变量有:
  119. /// {.}:圆点标记。
  120. /// {a}:系列名。
  121. /// {a}:系列名。
  122. /// {b}:类目值或数据名。
  123. /// {c}:数据值。
  124. /// {d}:百分比。
  125. /// {e}:数据名。
  126. /// {f}:数据和。
  127. /// 示例:“{b}:{c}”
  128. /// </summary>
  129. public string formatter
  130. {
  131. get { return m_Formatter; }
  132. set { if (PropertyUtil.SetClass(ref m_Formatter, value)) SetComponentDirty(); }
  133. }
  134. /// <summary>
  135. /// offset to the host graphic element.
  136. /// |距离图形元素的偏移
  137. /// </summary>
  138. public Vector3 offset
  139. {
  140. get { return m_Offset; }
  141. set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetAllDirty(); }
  142. }
  143. /// <summary>
  144. /// Rotation of label.
  145. /// |文本的旋转。
  146. /// </summary>
  147. public float rotate
  148. {
  149. get { return m_Rotate; }
  150. set { if (PropertyUtil.SetStruct(ref m_Rotate, value)) SetComponentDirty(); }
  151. }
  152. /// <summary>
  153. /// 距离轴线的距离。
  154. /// </summary>
  155. public float distance
  156. {
  157. get { return m_Distance; }
  158. set { if (PropertyUtil.SetStruct(ref m_Distance, value)) SetAllDirty(); }
  159. }
  160. /// <summary>
  161. /// the width of label. If set as default value 0, it means than the label width auto set as the text width.
  162. /// |标签的宽度。一般不用指定,不指定时则自动是文字的宽度。
  163. /// </summary>
  164. /// <value></value>
  165. public float width
  166. {
  167. get { return m_Width; }
  168. set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetComponentDirty(); }
  169. }
  170. /// <summary>
  171. /// the height of label. If set as default value 0, it means than the label height auto set as the text height.
  172. /// |标签的高度。一般不用指定,不指定时则自动是文字的高度。
  173. /// </summary>
  174. /// <value></value>
  175. public float height
  176. {
  177. get { return m_Height; }
  178. set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetComponentDirty(); }
  179. }
  180. /// <summary>
  181. /// the text padding of label.
  182. /// |文本的边距。
  183. /// </summary>
  184. public TextPadding textPadding
  185. {
  186. get { return m_TextPadding; }
  187. set { if (PropertyUtil.SetClass(ref m_TextPadding, value)) SetComponentDirty(); }
  188. }
  189. /// <summary>
  190. /// Standard numeric format strings.
  191. /// |标准数字格式字符串。用于将数值格式化显示为字符串。
  192. /// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。
  193. /// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings
  194. /// </summary>
  195. /// <value></value>
  196. public string numericFormatter
  197. {
  198. get { return m_NumericFormatter; }
  199. set { if (PropertyUtil.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); }
  200. }
  201. /// <summary>
  202. /// 是否开启自动偏移。当开启时,Y的偏移会自动判断曲线的开口来决定向上还是向下偏移。
  203. /// </summary>
  204. public bool autoOffset
  205. {
  206. get { return m_AutoOffset; }
  207. set { if (PropertyUtil.SetStruct(ref m_AutoOffset, value)) SetAllDirty(); }
  208. }
  209. /// <summary>
  210. /// the sytle of background.
  211. /// |背景图样式。
  212. /// </summary>
  213. public ImageStyle background
  214. {
  215. get { return m_Background; }
  216. set { if (PropertyUtil.SetClass(ref m_Background, value)) SetAllDirty(); }
  217. }
  218. /// <summary>
  219. /// the sytle of icon.
  220. /// |图标样式。
  221. /// </summary>
  222. public IconStyle icon
  223. {
  224. get { return m_Icon; }
  225. set { if (PropertyUtil.SetClass(ref m_Icon, value)) SetAllDirty(); }
  226. }
  227. /// <summary>
  228. /// the sytle of text.
  229. /// |文本样式。
  230. /// </summary>
  231. public TextStyle textStyle
  232. {
  233. get { return m_TextStyle; }
  234. set { if (PropertyUtil.SetClass(ref m_TextStyle, value)) SetAllDirty(); }
  235. }
  236. public LabelFormatterFunction formatterFunction
  237. {
  238. get { return m_FormatterFunction; }
  239. set { m_FormatterFunction = value; }
  240. }
  241. public bool IsInside()
  242. {
  243. return m_Position == Position.Inside || m_Position == Position.Center;
  244. }
  245. public bool IsDefaultPosition(Position position)
  246. {
  247. return m_Position == Position.Default || m_Position == position;
  248. }
  249. public bool IsAutoSize()
  250. {
  251. return width == 0 && height == 0;
  252. }
  253. public Vector3 GetOffset(float radius)
  254. {
  255. var x = ChartHelper.GetActualValue(m_Offset.x, radius);
  256. var y = ChartHelper.GetActualValue(m_Offset.y, radius);
  257. var z = ChartHelper.GetActualValue(m_Offset.z, radius);
  258. return new Vector3(x, y, z);
  259. }
  260. public Color GetColor(Color defaultColor)
  261. {
  262. if (ChartHelper.IsClearColor(textStyle.color))
  263. {
  264. return IsInside() ? Color.black : defaultColor;
  265. }
  266. else
  267. {
  268. return textStyle.color;
  269. }
  270. }
  271. public virtual LabelStyle Clone()
  272. {
  273. var label = new LabelStyle();
  274. label.m_Show = m_Show;
  275. label.m_Position = m_Position;
  276. label.m_Offset = m_Offset;
  277. label.m_Rotate = m_Rotate;
  278. label.m_Distance = m_Distance;
  279. label.m_Formatter = m_Formatter;
  280. label.m_Width = m_Width;
  281. label.m_Height = m_Height;
  282. label.m_NumericFormatter = m_NumericFormatter;
  283. label.m_AutoOffset = m_AutoOffset;
  284. label.m_Icon.Copy(m_Icon);
  285. label.m_Background.Copy(m_Background);
  286. label.m_TextPadding = m_TextPadding;
  287. label.m_TextStyle.Copy(m_TextStyle);
  288. return label;
  289. }
  290. public virtual void Copy(LabelStyle label)
  291. {
  292. m_Show = label.m_Show;
  293. m_Position = label.m_Position;
  294. m_Offset = label.m_Offset;
  295. m_Rotate = label.m_Rotate;
  296. m_Distance = label.m_Distance;
  297. m_Formatter = label.m_Formatter;
  298. m_Width = label.m_Width;
  299. m_Height = label.m_Height;
  300. m_NumericFormatter = label.m_NumericFormatter;
  301. m_AutoOffset = label.m_AutoOffset;
  302. m_Icon.Copy(label.m_Icon);
  303. m_Background.Copy(label.m_Background);
  304. m_TextPadding = label.m_TextPadding;
  305. m_TextStyle.Copy(label.m_TextStyle);
  306. }
  307. public virtual string GetFormatterContent(int labelIndex, string category)
  308. {
  309. if (string.IsNullOrEmpty(category))
  310. return GetFormatterFunctionContent(labelIndex, category, category);
  311. if (string.IsNullOrEmpty(m_Formatter))
  312. {
  313. return GetFormatterFunctionContent(labelIndex, category, category);
  314. }
  315. else
  316. {
  317. var content = m_Formatter;
  318. FormatterHelper.ReplaceAxisLabelContent(ref content, category);
  319. return GetFormatterFunctionContent(labelIndex, category, category);
  320. }
  321. }
  322. public virtual string GetFormatterContent(int labelIndex, double value, double minValue, double maxValue, bool isLog = false)
  323. {
  324. if (string.IsNullOrEmpty(m_Formatter))
  325. {
  326. if (isLog)
  327. {
  328. return GetFormatterFunctionContent(labelIndex, value, ChartCached.NumberToStr(value, numericFormatter));
  329. }
  330. if (minValue >= -1 && minValue <= 1 && maxValue >= -1 && maxValue <= 1)
  331. {
  332. int minAcc = ChartHelper.GetFloatAccuracy(minValue);
  333. int maxAcc = ChartHelper.GetFloatAccuracy(maxValue);
  334. int curAcc = ChartHelper.GetFloatAccuracy(value);
  335. int acc = Mathf.Max(Mathf.Max(minAcc, maxAcc), curAcc);
  336. return GetFormatterFunctionContent(labelIndex, value, ChartCached.FloatToStr(value, numericFormatter, acc));
  337. }
  338. return GetFormatterFunctionContent(labelIndex, value, ChartCached.NumberToStr(value, numericFormatter));
  339. }
  340. else
  341. {
  342. var content = m_Formatter;
  343. FormatterHelper.ReplaceAxisLabelContent(ref content, numericFormatter, value);
  344. return GetFormatterFunctionContent(labelIndex, value, content);
  345. }
  346. }
  347. public string GetFormatterDateTime(int labelIndex, double value, double minValue, double maxValue)
  348. {
  349. var timestamp = (int) value;
  350. var dateTime = DateTimeUtil.GetDateTime(timestamp);
  351. var dateString = string.Empty;
  352. if (string.IsNullOrEmpty(numericFormatter) || numericFormatter.Equals("f2"))
  353. {
  354. dateString = DateTimeUtil.GetDateTimeFormatString(dateTime, maxValue - minValue);
  355. }
  356. else
  357. {
  358. dateString = dateTime.ToString(numericFormatter);
  359. }
  360. if (!string.IsNullOrEmpty(m_Formatter))
  361. {
  362. var content = m_Formatter;
  363. FormatterHelper.ReplaceAxisLabelContent(ref content, dateString);
  364. return GetFormatterFunctionContent(labelIndex, value, content);
  365. }
  366. else
  367. {
  368. return GetFormatterFunctionContent(labelIndex, value, dateString);
  369. }
  370. }
  371. protected string GetFormatterFunctionContent(int labelIndex, string category, string currentContent)
  372. {
  373. return m_FormatterFunction == null ? currentContent :
  374. m_FormatterFunction(labelIndex, labelIndex, category, currentContent);
  375. }
  376. protected string GetFormatterFunctionContent(int labelIndex, double value, string currentContent)
  377. {
  378. return m_FormatterFunction == null ? currentContent :
  379. m_FormatterFunction(labelIndex, labelIndex, null, currentContent);
  380. }
  381. }
  382. }