Axis.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace XCharts.Runtime
  5. {
  6. /// <summary>
  7. /// The axis in rectangular coordinate.
  8. /// ||直角坐标系的坐标轴组件。
  9. /// </summary>
  10. [System.Serializable]
  11. public class Axis : MainComponent
  12. {
  13. /// <summary>
  14. /// the type of axis.
  15. /// ||坐标轴类型。
  16. /// </summary>
  17. public enum AxisType
  18. {
  19. /// <summary>
  20. /// Numerical axis, suitable for continuous data.
  21. /// ||数值轴。适用于连续数据。
  22. /// </summary>
  23. Value,
  24. /// <summary>
  25. /// Category axis, suitable for discrete category data. Data should only be set via data for this type.
  26. /// ||类目轴。适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。serie的数据第0维数据对应坐标轴data的index。
  27. /// </summary>
  28. Category,
  29. /// <summary>
  30. /// Log axis, suitable for log data.
  31. /// ||对数轴。适用于对数数据。
  32. /// </summary>
  33. Log,
  34. /// <summary>
  35. /// Time axis, suitable for continuous time series data.
  36. /// ||时间轴。适用于连续的时序数据。
  37. /// </summary>
  38. Time
  39. }
  40. /// <summary>
  41. /// the type of axis min and max value.
  42. /// ||坐标轴最大最小刻度显示类型。
  43. /// </summary>
  44. public enum AxisMinMaxType
  45. {
  46. /// <summary>
  47. /// 0 - maximum.
  48. /// ||0-最大值。
  49. /// </summary>
  50. Default,
  51. /// <summary>
  52. /// minimum - maximum.
  53. /// ||最小值-最大值。
  54. /// </summary>
  55. MinMax,
  56. /// <summary>
  57. /// Customize the minimum and maximum.
  58. /// ||自定义最小值最大值。
  59. /// </summary>
  60. Custom,
  61. /// <summary>
  62. /// [since("v3.7.0")]minimum - maximum, automatically calculate the appropriate values.
  63. /// ||[since("v3.7.0")]最小值-最大值。自动计算合适的值。
  64. /// </summary>
  65. MinMaxAuto,
  66. }
  67. /// <summary>
  68. /// the position of axis in grid.
  69. /// ||坐标轴在Grid中的位置
  70. /// </summary>
  71. public enum AxisPosition
  72. {
  73. Left,
  74. Right,
  75. Bottom,
  76. Top
  77. }
  78. [SerializeField] protected bool m_Show = true;
  79. [SerializeField] protected Axis.AxisType m_Type;
  80. [SerializeField] protected Axis.AxisMinMaxType m_MinMaxType;
  81. [SerializeField] protected int m_GridIndex;
  82. [SerializeField] protected int m_PolarIndex;
  83. [SerializeField] protected int m_ParallelIndex;
  84. [SerializeField] protected Axis.AxisPosition m_Position;
  85. [SerializeField] protected float m_Offset;
  86. [SerializeField] protected double m_Min;
  87. [SerializeField] protected double m_Max;
  88. [SerializeField] protected int m_SplitNumber = 0;
  89. [SerializeField] protected double m_Interval = 0;
  90. [SerializeField] protected bool m_BoundaryGap = true;
  91. [SerializeField] protected int m_MaxCache = 0;
  92. [SerializeField] protected float m_LogBase = 10;
  93. [SerializeField] protected bool m_LogBaseE = false;
  94. [SerializeField] protected double m_CeilRate = 0;
  95. [SerializeField] protected bool m_Inverse = false;
  96. [SerializeField] private bool m_Clockwise = true;
  97. [SerializeField] private bool m_InsertDataToHead;
  98. [SerializeField] protected List<Sprite> m_Icons = new List<Sprite>();
  99. [SerializeField] protected List<string> m_Data = new List<string>();
  100. [SerializeField] protected AxisLine m_AxisLine = AxisLine.defaultAxisLine;
  101. [SerializeField] protected AxisName m_AxisName = AxisName.defaultAxisName;
  102. [SerializeField] protected AxisTick m_AxisTick = AxisTick.defaultTick;
  103. [SerializeField] protected AxisLabel m_AxisLabel = AxisLabel.defaultAxisLabel;
  104. [SerializeField] protected AxisSplitLine m_SplitLine = AxisSplitLine.defaultSplitLine;
  105. [SerializeField] protected AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea;
  106. [SerializeField] protected AxisAnimation m_Animation = new AxisAnimation();
  107. [SerializeField][Since("v3.2.0")] protected AxisMinorTick m_MinorTick = AxisMinorTick.defaultMinorTick;
  108. [SerializeField][Since("v3.2.0")] protected AxisMinorSplitLine m_MinorSplitLine = AxisMinorSplitLine.defaultMinorSplitLine;
  109. [SerializeField][Since("v3.4.0")] protected LabelStyle m_IndicatorLabel = new LabelStyle() { numericFormatter = "f2" };
  110. public AxisContext context = new AxisContext();
  111. /// <summary>
  112. /// Whether to show axis.
  113. /// ||是否显示坐标轴。
  114. /// </summary>
  115. public bool show
  116. {
  117. get { return m_Show; }
  118. set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetAllDirty(); }
  119. }
  120. /// <summary>
  121. /// the type of axis.
  122. /// ||坐标轴类型。
  123. /// </summary>
  124. public AxisType type
  125. {
  126. get { return m_Type; }
  127. set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetAllDirty(); }
  128. }
  129. /// <summary>
  130. /// the type of axis minmax.
  131. /// ||坐标轴刻度最大最小值显示类型。
  132. /// </summary>
  133. public AxisMinMaxType minMaxType
  134. {
  135. get { return m_MinMaxType; }
  136. set { if (PropertyUtil.SetStruct(ref m_MinMaxType, value)) SetAllDirty(); }
  137. }
  138. /// <summary>
  139. /// The index of the grid on which the axis are located, by default, is in the first grid.
  140. /// ||坐标轴所在的 grid 的索引,默认位于第一个 grid。
  141. /// </summary>
  142. public int gridIndex
  143. {
  144. get { return m_GridIndex; }
  145. set { if (PropertyUtil.SetStruct(ref m_GridIndex, value)) SetAllDirty(); }
  146. }
  147. /// <summary>
  148. /// The index of the polar on which the axis are located, by default, is in the first polar.
  149. /// ||坐标轴所在的 ploar 的索引,默认位于第一个 polar。
  150. /// </summary>
  151. public int polarIndex
  152. {
  153. get { return m_PolarIndex; }
  154. set { if (PropertyUtil.SetStruct(ref m_PolarIndex, value)) SetAllDirty(); }
  155. }
  156. /// <summary>
  157. /// The index of the parallel on which the axis are located, by default, is in the first parallel.
  158. /// ||坐标轴所在的 parallel 的索引,默认位于第一个 parallel。
  159. /// </summary>
  160. public int parallelIndex
  161. {
  162. get { return m_ParallelIndex; }
  163. set { if (PropertyUtil.SetStruct(ref m_ParallelIndex, value)) SetAllDirty(); }
  164. }
  165. /// <summary>
  166. /// the position of axis in grid.
  167. /// ||坐标轴在Grid中的位置。
  168. /// </summary>
  169. public AxisPosition position
  170. {
  171. get { return m_Position; }
  172. set { if (PropertyUtil.SetStruct(ref m_Position, value)) SetAllDirty(); }
  173. }
  174. /// <summary>
  175. /// the offset of axis from the default position. Useful when the same position has multiple axes.
  176. /// ||坐标轴相对默认位置的偏移。在相同position有多个坐标轴时有用。
  177. /// </summary>
  178. public float offset
  179. {
  180. get { return m_Offset; }
  181. set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetAllDirty(); }
  182. }
  183. /// <summary>
  184. /// The minimun value of axis.Valid when `minMaxType` is `Custom`
  185. /// ||设定的坐标轴刻度最小值,当minMaxType为Custom时有效。
  186. /// </summary>
  187. public double min
  188. {
  189. get { return m_Min; }
  190. set { if (PropertyUtil.SetStruct(ref m_Min, value)) SetAllDirty(); }
  191. }
  192. /// <summary>
  193. /// The maximum value of axis.Valid when `minMaxType` is `Custom`
  194. /// ||设定的坐标轴刻度最大值,当minMaxType为Custom时有效。
  195. /// </summary>
  196. public double max
  197. {
  198. get { return m_Max; }
  199. set { if (PropertyUtil.SetStruct(ref m_Max, value)) SetAllDirty(); }
  200. }
  201. /// <summary>
  202. /// Number of segments that the axis is split into.
  203. /// ||坐标轴的期望的分割段数。默认为0表示自动分割。
  204. /// </summary>
  205. public int splitNumber
  206. {
  207. get { return m_SplitNumber; }
  208. set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); }
  209. }
  210. /// <summary>
  211. /// Compulsively set segmentation interval for axis.This is unavailable for category axis.
  212. /// ||强制设置坐标轴分割间隔。无法在类目轴中使用。
  213. /// </summary>
  214. public double interval
  215. {
  216. get { return m_Interval; }
  217. set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetAllDirty(); }
  218. }
  219. /// <summary>
  220. /// The boundary gap on both sides of a coordinate axis, which is valid only for category axis with type: 'Category'.
  221. /// ||坐标轴两边是否留白。只对类目轴有效。
  222. /// </summary>
  223. public bool boundaryGap
  224. {
  225. get { return IsCategory() ? m_BoundaryGap : false; }
  226. set { if (PropertyUtil.SetStruct(ref m_BoundaryGap, value)) SetAllDirty(); }
  227. }
  228. /// <summary>
  229. /// Base of logarithm, which is valid only for numeric axes with type: 'Log'.
  230. /// ||对数轴的底数,只在对数轴(type:'Log')中有效。
  231. /// </summary>
  232. public float logBase
  233. {
  234. get { return m_LogBase; }
  235. set
  236. {
  237. if (value <= 0 || value == 1) value = 10;
  238. if (PropertyUtil.SetStruct(ref m_LogBase, value)) SetAllDirty();
  239. }
  240. }
  241. /// <summary>
  242. /// On the log axis, if base e is the natural number, and is true, logBase fails.
  243. /// ||对数轴是否以自然数 e 为底数,为 true 时 logBase 失效。
  244. /// </summary>
  245. public bool logBaseE
  246. {
  247. get { return m_LogBaseE; }
  248. set { if (PropertyUtil.SetStruct(ref m_LogBaseE, value)) SetAllDirty(); }
  249. }
  250. /// <summary>
  251. /// The max number of axis data cache.
  252. /// ||The first data will be remove when the size of axis data is larger then maxCache.
  253. /// ||可缓存的最大数据量。默认为0没有限制,大于0时超过指定值会移除旧数据再插入新数据。
  254. /// </summary>
  255. public int maxCache
  256. {
  257. get { return m_MaxCache; }
  258. set { if (PropertyUtil.SetStruct(ref m_MaxCache, value < 0 ? 0 : value)) SetAllDirty(); }
  259. }
  260. /// <summary>
  261. /// The ratio of maximum and minimum values rounded upward. The default is 0, which is automatically calculated.
  262. /// ||最大最小值向上取整的倍率。默认为0时自动计算。
  263. /// </summary>
  264. public double ceilRate
  265. {
  266. get { return m_CeilRate; }
  267. set { if (PropertyUtil.SetStruct(ref m_CeilRate, value < 0 ? 0 : value)) SetAllDirty(); }
  268. }
  269. /// <summary>
  270. /// Whether the axis are reversed or not. Invalid in `Category` axis.
  271. /// ||是否反向坐标轴。在类目轴中无效。
  272. /// </summary>
  273. public bool inverse
  274. {
  275. get { return m_Inverse; }
  276. set { if (m_Type == AxisType.Value && PropertyUtil.SetStruct(ref m_Inverse, value)) SetAllDirty(); }
  277. }
  278. /// <summary>
  279. /// Whether the positive position of axis is in clockwise. True for clockwise by default.
  280. /// ||刻度增长是否按顺时针,默认顺时针。
  281. /// </summary>
  282. public bool clockwise
  283. {
  284. get { return m_Clockwise; }
  285. set { if (PropertyUtil.SetStruct(ref m_Clockwise, value)) SetAllDirty(); }
  286. }
  287. /// <summary>
  288. /// Category data, available in type: 'Category' axis.
  289. /// ||类目数据,在类目轴(type: 'category')中有效。
  290. /// </summary>
  291. public List<string> data
  292. {
  293. get { return m_Data; }
  294. set { if (value != null) { m_Data = value; SetAllDirty(); } }
  295. }
  296. /// <summary>
  297. /// 类目数据对应的图标。
  298. /// </summary>
  299. public List<Sprite> icons
  300. {
  301. get { return m_Icons; }
  302. set { if (value != null) { m_Icons = value; SetAllDirty(); } }
  303. }
  304. /// <summary>
  305. /// axis Line.
  306. /// ||坐标轴轴线。
  307. /// </summary>
  308. public AxisLine axisLine
  309. {
  310. get { return m_AxisLine; }
  311. set { if (value != null) { m_AxisLine = value; SetVerticesDirty(); } }
  312. }
  313. /// <summary>
  314. /// axis name.
  315. /// ||坐标轴名称。
  316. /// </summary>
  317. public AxisName axisName
  318. {
  319. get { return m_AxisName; }
  320. set { if (value != null) { m_AxisName = value; SetComponentDirty(); } }
  321. }
  322. /// <summary>
  323. /// axis tick.
  324. /// ||坐标轴刻度。
  325. /// </summary>
  326. public AxisTick axisTick
  327. {
  328. get { return m_AxisTick; }
  329. set { if (value != null) { m_AxisTick = value; SetVerticesDirty(); } }
  330. }
  331. /// <summary>
  332. /// axis label.
  333. /// ||坐标轴刻度标签。
  334. /// </summary>
  335. public AxisLabel axisLabel
  336. {
  337. get { return m_AxisLabel; }
  338. set { if (value != null) { m_AxisLabel = value; SetComponentDirty(); } }
  339. }
  340. /// <summary>
  341. /// axis split line.
  342. /// ||坐标轴分割线。
  343. /// </summary>
  344. public AxisSplitLine splitLine
  345. {
  346. get { return m_SplitLine; }
  347. set { if (value != null) { m_SplitLine = value; SetVerticesDirty(); } }
  348. }
  349. /// <summary>
  350. /// axis split area.
  351. /// ||坐标轴分割区域。
  352. /// </summary>
  353. public AxisSplitArea splitArea
  354. {
  355. get { return m_SplitArea; }
  356. set { if (value != null) { m_SplitArea = value; SetVerticesDirty(); } }
  357. }
  358. /// <summary>
  359. /// axis minor tick.
  360. /// ||坐标轴次刻度。
  361. /// </summary>
  362. public AxisMinorTick minorTick
  363. {
  364. get { return m_MinorTick; }
  365. set { if (value != null) { m_MinorTick = value; SetVerticesDirty(); } }
  366. }
  367. /// <summary>
  368. /// axis minor split line.
  369. /// ||坐标轴次分割线。
  370. /// </summary>
  371. public AxisMinorSplitLine minorSplitLine
  372. {
  373. get { return m_MinorSplitLine; }
  374. set { if (value != null) { m_MinorSplitLine = value; SetVerticesDirty(); } }
  375. }
  376. /// <summary>
  377. /// Style of axis tooltip indicator label.
  378. /// ||指示器文本的样式。Tooltip为Cross时使用。
  379. /// </summary>
  380. public LabelStyle indicatorLabel
  381. {
  382. get { return m_IndicatorLabel; }
  383. set { if (value != null) { m_IndicatorLabel = value; SetComponentDirty(); } }
  384. }
  385. /// <summary>
  386. /// animation of axis.
  387. /// ||坐标轴动画。
  388. /// </summary>
  389. public AxisAnimation animation
  390. {
  391. get { return m_Animation; }
  392. set { if (value != null) { m_Animation = value; SetComponentDirty(); } }
  393. }
  394. /// <summary>
  395. /// Whether to add new data at the head or at the end of the list.
  396. /// ||添加新数据时是在列表的头部还是尾部加入。
  397. /// </summary>
  398. public bool insertDataToHead
  399. {
  400. get { return m_InsertDataToHead; }
  401. set { if (PropertyUtil.SetStruct(ref m_InsertDataToHead, value)) SetAllDirty(); }
  402. }
  403. public override bool vertsDirty
  404. {
  405. get
  406. {
  407. return m_VertsDirty ||
  408. axisLine.anyDirty ||
  409. axisTick.anyDirty ||
  410. splitLine.anyDirty ||
  411. splitArea.anyDirty ||
  412. minorTick.anyDirty ||
  413. minorSplitLine.anyDirty;
  414. }
  415. }
  416. public override bool componentDirty
  417. {
  418. get
  419. {
  420. return m_ComponentDirty ||
  421. axisName.anyDirty ||
  422. axisLabel.anyDirty ||
  423. indicatorLabel.anyDirty;
  424. }
  425. }
  426. public override void ClearComponentDirty()
  427. {
  428. base.ClearComponentDirty();
  429. axisName.ClearComponentDirty();
  430. axisLabel.ClearComponentDirty();
  431. indicatorLabel.ClearComponentDirty();
  432. }
  433. public override void ClearVerticesDirty()
  434. {
  435. base.ClearVerticesDirty();
  436. axisLabel.ClearVerticesDirty();
  437. axisLine.ClearVerticesDirty();
  438. axisTick.ClearVerticesDirty();
  439. splitLine.ClearVerticesDirty();
  440. splitArea.ClearVerticesDirty();
  441. minorTick.ClearVerticesDirty();
  442. minorSplitLine.ClearVerticesDirty();
  443. indicatorLabel.ClearVerticesDirty();
  444. }
  445. public override void SetComponentDirty()
  446. {
  447. context.isNeedUpdateFilterData = true;
  448. base.SetComponentDirty();
  449. }
  450. public Axis Clone()
  451. {
  452. var axis = new Axis();
  453. axis.show = show;
  454. axis.type = type;
  455. axis.gridIndex = 0;
  456. axis.minMaxType = minMaxType;
  457. axis.min = min;
  458. axis.max = max;
  459. axis.splitNumber = splitNumber;
  460. axis.interval = interval;
  461. axis.boundaryGap = boundaryGap;
  462. axis.maxCache = maxCache;
  463. axis.logBase = logBase;
  464. axis.logBaseE = logBaseE;
  465. axis.ceilRate = ceilRate;
  466. axis.insertDataToHead = insertDataToHead;
  467. axis.axisLine = axisLine.Clone();
  468. axis.axisName = axisName.Clone();
  469. axis.axisTick = axisTick.Clone();
  470. axis.axisLabel = axisLabel.Clone();
  471. axis.splitLine = splitLine.Clone();
  472. axis.splitArea = splitArea.Clone();
  473. axis.minorTick = minorTick.Clone();
  474. axis.minorSplitLine = minorSplitLine.Clone();
  475. axis.indicatorLabel = indicatorLabel.Clone();
  476. axis.animation = animation.Clone();
  477. axis.icons = new List<Sprite>();
  478. axis.data = new List<string>();
  479. ChartHelper.CopyList(axis.data, data);
  480. return axis;
  481. }
  482. public void Copy(Axis axis)
  483. {
  484. show = axis.show;
  485. type = axis.type;
  486. minMaxType = axis.minMaxType;
  487. gridIndex = axis.gridIndex;
  488. min = axis.min;
  489. max = axis.max;
  490. splitNumber = axis.splitNumber;
  491. interval = axis.interval;
  492. boundaryGap = axis.boundaryGap;
  493. maxCache = axis.maxCache;
  494. logBase = axis.logBase;
  495. logBaseE = axis.logBaseE;
  496. ceilRate = axis.ceilRate;
  497. insertDataToHead = axis.insertDataToHead;
  498. axisLine.Copy(axis.axisLine);
  499. axisName.Copy(axis.axisName);
  500. axisTick.Copy(axis.axisTick);
  501. axisLabel.Copy(axis.axisLabel);
  502. splitLine.Copy(axis.splitLine);
  503. splitArea.Copy(axis.splitArea);
  504. minorTick.Copy(axis.minorTick);
  505. minorSplitLine.Copy(axis.minorSplitLine);
  506. indicatorLabel.Copy(axis.indicatorLabel);
  507. animation.Copy(axis.animation);
  508. ChartHelper.CopyList(data, axis.data);
  509. ChartHelper.CopyList<Sprite>(icons, axis.icons);
  510. }
  511. /// <summary>
  512. /// 清空类目数据
  513. /// </summary>
  514. public override void ClearData()
  515. {
  516. m_Data.Clear();
  517. m_Icons.Clear();
  518. context.Clear();
  519. SetAllDirty();
  520. }
  521. /// <summary>
  522. /// 是否为类目轴。
  523. /// </summary>
  524. /// <returns></returns>
  525. public bool IsCategory()
  526. {
  527. return m_Type == AxisType.Category;
  528. }
  529. /// <summary>
  530. /// 是否为数值轴。
  531. /// </summary>
  532. /// <returns></returns>
  533. public bool IsValue()
  534. {
  535. return m_Type == AxisType.Value;
  536. }
  537. /// <summary>
  538. /// 是否为对数轴。
  539. /// </summary>
  540. /// <returns></returns>
  541. public bool IsLog()
  542. {
  543. return m_Type == AxisType.Log;
  544. }
  545. /// <summary>
  546. /// 是否为时间轴。
  547. /// </summary>
  548. public bool IsTime()
  549. {
  550. return m_Type == AxisType.Time;
  551. }
  552. public bool IsLeft()
  553. {
  554. return m_Position == AxisPosition.Left;
  555. }
  556. public bool IsRight()
  557. {
  558. return m_Position == AxisPosition.Right;
  559. }
  560. public bool IsTop()
  561. {
  562. return m_Position == AxisPosition.Top;
  563. }
  564. public bool IsBottom()
  565. {
  566. return m_Position == AxisPosition.Bottom;
  567. }
  568. public bool IsNeedShowLabel(int index, int total = 0)
  569. {
  570. if (total == 0)
  571. {
  572. total = context.labelValueList.Count;
  573. }
  574. return axisLabel.IsNeedShowLabel(index, total);
  575. }
  576. public void SetNeedUpdateFilterData()
  577. {
  578. context.isNeedUpdateFilterData = true;
  579. }
  580. /// <summary>
  581. /// 添加一个类目到类目数据列表
  582. /// </summary>
  583. /// <param name="category"></param>
  584. public void AddData(string category)
  585. {
  586. if (maxCache > 0)
  587. {
  588. if (context.addedDataCount < m_Data.Count)
  589. context.addedDataCount = m_Data.Count;
  590. while (m_Data.Count >= maxCache)
  591. {
  592. RemoveData(m_InsertDataToHead ? m_Data.Count - 1 : 0);
  593. }
  594. }
  595. context.addedDataCount++;
  596. if (m_InsertDataToHead)
  597. m_Data.Insert(0, category);
  598. else
  599. m_Data.Add(category);
  600. SetAllDirty();
  601. }
  602. /// <summary>
  603. /// get the history data count.
  604. /// ||获得添加过的历史数据总数
  605. /// </summary>
  606. /// <returns></returns>
  607. public int GetAddedDataCount()
  608. {
  609. return context.addedDataCount < m_Data.Count ? m_Data.Count : context.addedDataCount;
  610. }
  611. public void RemoveData(int dataIndex)
  612. {
  613. context.isNeedUpdateFilterData = true;
  614. m_Data.RemoveAt(dataIndex);
  615. }
  616. /// <summary>
  617. /// 更新类目数据
  618. /// </summary>
  619. /// <param name="index"></param>
  620. /// <param name="category"></param>
  621. public void UpdateData(int index, string category)
  622. {
  623. if (index >= 0 && index < m_Data.Count)
  624. {
  625. m_Data[index] = category;
  626. SetComponentDirty();
  627. }
  628. }
  629. /// <summary>
  630. /// 添加图标
  631. /// </summary>
  632. /// <param name="icon"></param>
  633. public void AddIcon(Sprite icon)
  634. {
  635. if (maxCache > 0)
  636. {
  637. while (m_Icons.Count > maxCache)
  638. {
  639. m_Icons.RemoveAt(m_InsertDataToHead ? m_Icons.Count - 1 : 0);
  640. }
  641. }
  642. if (m_InsertDataToHead) m_Icons.Insert(0, icon);
  643. else m_Icons.Add(icon);
  644. SetAllDirty();
  645. }
  646. /// <summary>
  647. /// 更新图标
  648. /// </summary>
  649. /// <param name="index"></param>
  650. /// <param name="icon"></param>
  651. public void UpdateIcon(int index, Sprite icon)
  652. {
  653. if (index >= 0 && index < m_Icons.Count)
  654. {
  655. m_Icons[index] = icon;
  656. SetComponentDirty();
  657. }
  658. }
  659. /// <summary>
  660. /// 获得指定索引的类目数据
  661. /// </summary>
  662. /// <param name="index"></param>
  663. /// <returns></returns>
  664. public string GetData(int index)
  665. {
  666. if (index >= 0 && index < m_Data.Count)
  667. return m_Data[index];
  668. else
  669. return null;
  670. }
  671. /// <summary>
  672. /// 获得在dataZoom范围内指定索引的类目数据
  673. /// </summary>
  674. /// <param name="index">类目数据索引</param>
  675. /// <param name="dataZoom">区域缩放</param>
  676. /// <returns></returns>
  677. public string GetData(int index, DataZoom dataZoom)
  678. {
  679. var showData = GetDataList(dataZoom);
  680. if (index >= 0 && index < showData.Count)
  681. return showData[index];
  682. else
  683. return "";
  684. }
  685. public Sprite GetIcon(int index)
  686. {
  687. if (index >= 0 && index < m_Icons.Count)
  688. return m_Icons[index];
  689. else
  690. return null;
  691. }
  692. /// <summary>
  693. /// 获得值在坐标轴上的距离
  694. /// </summary>
  695. /// <param name="value"></param>
  696. /// <param name="axisLength"></param>
  697. /// <returns></returns>
  698. public float GetDistance(double value, float axisLength)
  699. {
  700. if (context.minMaxRange == 0)
  701. return 0;
  702. if (IsCategory() && boundaryGap)
  703. {
  704. var each = axisLength / data.Count;
  705. return (float)(each * (value + 0.5f));
  706. }
  707. else if (IsLog())
  708. {
  709. var logValue = GetLogValue(value);
  710. var logMin = GetLogValue(context.minValue);
  711. var logMax = GetLogValue(context.maxValue);
  712. return axisLength * (float)((logValue - logMin) / (logMax - logMin));
  713. }
  714. else
  715. {
  716. return axisLength * (float)((value - context.minValue) / context.minMaxRange);
  717. }
  718. }
  719. public float GetValueLength(double value, float axisLength)
  720. {
  721. if (context.minMaxRange > 0)
  722. {
  723. return axisLength * ((float)(value / context.minMaxRange));
  724. }
  725. else
  726. {
  727. return 0;
  728. }
  729. }
  730. /// <summary>
  731. /// 获得指定区域缩放的类目数据列表
  732. /// </summary>
  733. /// <param name="dataZoom">区域缩放</param>
  734. /// <returns></returns>
  735. internal List<string> GetDataList(DataZoom dataZoom)
  736. {
  737. if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this))
  738. {
  739. UpdateFilterData(dataZoom);
  740. return context.filterData;
  741. }
  742. else
  743. {
  744. return m_Data.Count > 0 ? m_Data : context.runtimeData;
  745. }
  746. }
  747. internal List<string> GetDataList()
  748. {
  749. return m_Data.Count > 0 ? m_Data : context.runtimeData;
  750. }
  751. /// <summary>
  752. /// 更新dataZoom对应的类目数据列表
  753. /// </summary>
  754. /// <param name="dataZoom"></param>
  755. internal void UpdateFilterData(DataZoom dataZoom)
  756. {
  757. if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this))
  758. {
  759. var data = GetDataList();
  760. context.UpdateFilterData(data, dataZoom);
  761. }
  762. }
  763. /// <summary>
  764. /// 获得类目数据个数
  765. /// </summary>
  766. /// <param name="dataZoom"></param>
  767. /// <returns></returns>
  768. internal int GetDataCount(DataZoom dataZoom)
  769. {
  770. return IsCategory() ? GetDataList(dataZoom).Count : 0;
  771. }
  772. /// <summary>
  773. /// 更新刻度标签文字
  774. /// </summary>
  775. /// <param name="dataZoom"></param>
  776. internal void UpdateLabelText(float coordinateWidth, DataZoom dataZoom, bool forcePercent)
  777. {
  778. for (int i = 0; i < context.labelObjectList.Count; i++)
  779. {
  780. if (context.labelObjectList[i] != null)
  781. {
  782. var text = AxisHelper.GetLabelName(this, coordinateWidth, i, context.destMinValue, context.destMaxValue, dataZoom, forcePercent);
  783. context.labelObjectList[i].SetText(text);
  784. }
  785. }
  786. }
  787. internal Vector3 GetLabelObjectPosition(int index)
  788. {
  789. if (context.labelObjectList != null && index < context.labelObjectList.Count)
  790. return context.labelObjectList[index].GetPosition();
  791. else
  792. return Vector3.zero;
  793. }
  794. internal void UpdateMinMaxValue(double minValue, double maxValue, bool needAnimation = false)
  795. {
  796. if (needAnimation)
  797. {
  798. if (context.lastMinValue == 0 && context.lastMaxValue == 0)
  799. {
  800. context.minValue = minValue;
  801. context.maxValue = maxValue;
  802. }
  803. context.lastMinValue = context.minValue;
  804. context.lastMaxValue = context.maxValue;
  805. context.destMinValue = minValue;
  806. context.destMaxValue = maxValue;
  807. }
  808. else
  809. {
  810. context.minValue = minValue;
  811. context.maxValue = maxValue;
  812. context.destMinValue = minValue;
  813. context.destMaxValue = maxValue;
  814. }
  815. double tempRange = maxValue - minValue;
  816. if (context.minMaxRange != tempRange)
  817. {
  818. context.minMaxRange = tempRange;
  819. if (type == Axis.AxisType.Value && interval > 0)
  820. {
  821. SetComponentDirty();
  822. }
  823. }
  824. }
  825. public float GetLogValue(double value)
  826. {
  827. if (value <= 0 || value == 1)
  828. return 0;
  829. else
  830. return logBaseE ? (float)Math.Log(value) : (float)Math.Log(value, logBase);
  831. }
  832. public double GetLogMinIndex()
  833. {
  834. if (context.minValue <= 0 || context.minValue == 1)
  835. return 0;
  836. return logBaseE ?
  837. Math.Log(context.minValue) :
  838. Math.Log(context.minValue, logBase);
  839. }
  840. public double GetLogMaxIndex()
  841. {
  842. if (context.maxValue <= 0 || context.maxValue == 1)
  843. return 0;
  844. return logBaseE ?
  845. Math.Log(context.maxValue) :
  846. Math.Log(context.maxValue, logBase);
  847. }
  848. public double GetLabelValue(int index)
  849. {
  850. if (index < 0)
  851. return context.minValue;
  852. else if (index > context.labelValueList.Count - 1)
  853. return context.maxValue;
  854. else
  855. return context.labelValueList[index];
  856. }
  857. public double GetLastLabelValue()
  858. {
  859. if (context.labelValueList.Count > 0)
  860. return context.labelValueList[context.labelValueList.Count - 1];
  861. else
  862. return 0;
  863. }
  864. public void UpdateZeroOffset(float axisLength)
  865. {
  866. context.offset = context.minValue > 0 || context.minMaxRange == 0 ?
  867. 0 :
  868. (context.maxValue < 0 ?
  869. axisLength :
  870. (float)(Math.Abs(context.minValue) * (axisLength / (Math.Abs(context.minValue) + Math.Abs(context.maxValue))))
  871. );
  872. }
  873. }
  874. }