No Description
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.

Axis.cs 30KB

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