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

VisualMap.cs 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace XCharts.Runtime
  4. {
  5. [System.Serializable]
  6. public class VisualMapRange : ChildComponent
  7. {
  8. [SerializeField] private double m_Min;
  9. [SerializeField] private double m_Max;
  10. [SerializeField] private string m_Label;
  11. [SerializeField] private Color32 m_Color;
  12. /// <summary>
  13. /// 范围最小值
  14. /// </summary>
  15. public double min { get { return m_Min; } set { m_Min = value; } }
  16. /// <summary>
  17. /// 范围最大值
  18. /// </summary>
  19. public double max { get { return m_Max; } set { m_Max = value; } }
  20. /// <summary>
  21. /// 文字描述
  22. /// </summary>
  23. public string label { get { return m_Label; } set { m_Label = value; } }
  24. /// <summary>
  25. /// 颜色
  26. /// </summary>
  27. public Color32 color { get { return m_Color; } set { m_Color = value; } }
  28. public bool Contains(double value, double minMaxRange)
  29. {
  30. if (m_Min == 0 && m_Max == 0) return false;
  31. var cmin = System.Math.Abs(m_Min) < 1 ? minMaxRange * m_Min : m_Min;
  32. var cmax = System.Math.Abs(m_Max) < 1 ? minMaxRange * m_Max : m_Max;
  33. return value >= cmin && value < cmax;
  34. }
  35. }
  36. /// <summary>
  37. /// VisualMap component. Mapping data to visual elements such as colors.
  38. /// |视觉映射组件。用于进行『视觉编码』,也就是将数据映射到视觉元素(视觉通道)。
  39. /// </summary>
  40. [System.Serializable]
  41. [ComponentHandler(typeof(VisualMapHandler), true)]
  42. public class VisualMap : MainComponent
  43. {
  44. /// <summary>
  45. /// 类型。分为连续型和分段型。
  46. /// </summary>
  47. public enum Type
  48. {
  49. /// <summary>
  50. /// 连续型。
  51. /// </summary>
  52. Continuous,
  53. /// <summary>
  54. /// 分段型。
  55. /// </summary>
  56. Piecewise
  57. }
  58. /// <summary>
  59. /// 选择模式
  60. /// </summary>
  61. public enum SelectedMode
  62. {
  63. /// <summary>
  64. /// 多选。
  65. /// </summary>
  66. Multiple,
  67. /// <summary>
  68. /// 单选。
  69. /// </summary>
  70. Single
  71. }
  72. [SerializeField] private bool m_Show = true;
  73. [SerializeField] private bool m_ShowUI = false;
  74. [SerializeField] private Type m_Type = Type.Continuous;
  75. [SerializeField] private SelectedMode m_SelectedMode = SelectedMode.Multiple;
  76. [SerializeField] private int m_SerieIndex = 0;
  77. [SerializeField] private double m_Min = 0;
  78. [SerializeField] private double m_Max = 0;
  79. [SerializeField] private double[] m_Range = new double[2] { 0, 0 };
  80. [SerializeField] private string[] m_Text = new string[2] { "", "" };
  81. [SerializeField] private float[] m_TextGap = new float[2] { 10f, 10f };
  82. [SerializeField] private int m_SplitNumber = 5;
  83. [SerializeField] private bool m_Calculable = false;
  84. [SerializeField] private bool m_Realtime = true;
  85. [SerializeField] private float m_ItemWidth = 20f;
  86. [SerializeField] private float m_ItemHeight = 140f;
  87. [SerializeField] private float m_ItemGap = 10f;
  88. [SerializeField] private float m_BorderWidth = 0;
  89. [SerializeField] private int m_Dimension = -1;
  90. [SerializeField] private bool m_HoverLink = true;
  91. [SerializeField] private bool m_AutoMinMax = true;
  92. [SerializeField] private Orient m_Orient = Orient.Horizonal;
  93. [SerializeField] private Location m_Location = Location.defaultLeft;
  94. [SerializeField] private bool m_WorkOnLine = true;
  95. [SerializeField] private bool m_WorkOnArea = false;
  96. [SerializeField] private List<VisualMapRange> m_OutOfRange = new List<VisualMapRange>() { new VisualMapRange() { color = Color.gray } };
  97. [SerializeField] private List<VisualMapRange> m_InRange = new List<VisualMapRange>();
  98. public VisualMapContext context = new VisualMapContext();
  99. /// <summary>
  100. /// Whether to enable components.
  101. /// |组件是否生效。
  102. /// </summary>
  103. public bool show
  104. {
  105. get { return m_Show; }
  106. set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
  107. }
  108. /// <summary>
  109. /// Whether to display components. If set to false, it will not show up, but the data mapping function still exists.
  110. /// |是否显示组件。如果设置为 false,不会显示,但是数据映射的功能还存在。
  111. /// </summary>
  112. public bool showUI
  113. {
  114. get { return m_ShowUI; }
  115. set { if (PropertyUtil.SetStruct(ref m_ShowUI, value)) SetVerticesDirty(); }
  116. }
  117. /// <summary>
  118. /// the type of visualmap component.
  119. /// |组件类型。
  120. /// </summary>
  121. public Type type
  122. {
  123. get { return m_Type; }
  124. set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); }
  125. }
  126. /// <summary>
  127. /// the selected mode for Piecewise visualMap.
  128. /// |选择模式。
  129. /// </summary>
  130. public SelectedMode selectedMode
  131. {
  132. get { return m_SelectedMode; }
  133. set { if (PropertyUtil.SetStruct(ref m_SelectedMode, value)) SetVerticesDirty(); }
  134. }
  135. /// <summary>
  136. /// the serie index of visualMap.
  137. /// |影响的serie索引。
  138. /// </summary>
  139. public int serieIndex
  140. {
  141. get { return m_SerieIndex; }
  142. set { if (PropertyUtil.SetStruct(ref m_SerieIndex, value)) SetVerticesDirty(); }
  143. }
  144. /// <summary>
  145. /// The minimum allowed. 'min' must be user specified. [visualmap.min, visualmap.max] forms the "domain" of the visualMap.
  146. /// |
  147. /// 允许的最小值。`autoMinMax`为`false`时必须指定。[visualMap.min, visualMap.max] 形成了视觉映射的『定义域』。
  148. /// </summary>
  149. public double min
  150. {
  151. get { return m_Min; }
  152. set { if (PropertyUtil.SetStruct(ref m_Min, value)) SetVerticesDirty(); }
  153. }
  154. /// <summary>
  155. /// The maximum allowed. 'max' must be user specified. [visualmap.min, visualmap.max] forms the "domain" of the visualMap.
  156. /// |
  157. /// 允许的最大值。`autoMinMax`为`false`时必须指定。[visualMap.min, visualMax.max] 形成了视觉映射的『定义域』。
  158. /// </summary>
  159. public double max
  160. {
  161. get { return m_Max; }
  162. set { m_Max = (value < min ? min + 1 : value); SetVerticesDirty(); }
  163. }
  164. /// <summary>
  165. /// Specifies the position of the numeric value corresponding to the handle. Range should be within the range of [min,max].
  166. /// |
  167. /// 指定手柄对应数值的位置。range 应在[min,max]范围内。
  168. /// </summary>
  169. public double[] range { get { return m_Range; } }
  170. /// <summary>
  171. /// Text on both ends.
  172. /// |两端的文本,如 ['High', 'Low']。
  173. /// </summary>
  174. public string[] text { get { return m_Text; } }
  175. /// <summary>
  176. /// The distance between the two text bodies.
  177. /// |两端文字主体之间的距离,单位为px。
  178. /// </summary>
  179. public float[] textGap { get { return m_TextGap; } }
  180. /// <summary>
  181. /// For continuous data, it is automatically evenly divided into several segments
  182. /// and automatically matches the size of inRange color list when the default is 0.
  183. /// |
  184. /// 对于连续型数据,自动平均切分成几段,默认为0时自动匹配inRange颜色列表大小。
  185. /// </summary>
  186. /// <value></value>
  187. public int splitNumber
  188. {
  189. get { return m_SplitNumber; }
  190. set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetVerticesDirty(); }
  191. }
  192. /// <summary>
  193. /// Whether the handle used for dragging is displayed (the handle can be dragged to adjust the selected range).
  194. /// |
  195. /// 是否显示拖拽用的手柄(手柄能拖拽调整选中范围)。
  196. /// </summary>
  197. public bool calculable
  198. {
  199. get { return m_Calculable; }
  200. set { if (PropertyUtil.SetStruct(ref m_Calculable, value)) SetVerticesDirty(); }
  201. }
  202. /// <summary>
  203. /// Whether to update in real time while dragging.
  204. /// |
  205. /// 拖拽时,是否实时更新。
  206. /// </summary>
  207. public bool realtime
  208. {
  209. get { return m_Realtime; }
  210. set { if (PropertyUtil.SetStruct(ref m_Realtime, value)) SetVerticesDirty(); }
  211. }
  212. /// <summary>
  213. /// The width of the figure, that is, the width of the color bar.
  214. /// |
  215. /// 图形的宽度,即颜色条的宽度。
  216. /// </summary>
  217. public float itemWidth
  218. {
  219. get { return m_ItemWidth; }
  220. set { if (PropertyUtil.SetStruct(ref m_ItemWidth, value)) SetVerticesDirty(); }
  221. }
  222. /// <summary>
  223. /// The height of the figure, that is, the height of the color bar.
  224. /// |
  225. /// 图形的高度,即颜色条的高度。
  226. /// </summary>
  227. public float itemHeight
  228. {
  229. get { return m_ItemHeight; }
  230. set { if (PropertyUtil.SetStruct(ref m_ItemHeight, value)) SetVerticesDirty(); }
  231. }
  232. /// <summary>
  233. /// 每个图元之间的间隔距离。
  234. /// </summary>
  235. public float itemGap
  236. {
  237. get { return m_ItemGap; }
  238. set { if (PropertyUtil.SetStruct(ref m_ItemGap, value)) SetVerticesDirty(); }
  239. }
  240. /// <summary>
  241. /// Border line width.
  242. /// |
  243. /// 边框线宽,单位px。
  244. /// </summary>
  245. public float borderWidth
  246. {
  247. get { return m_BorderWidth; }
  248. set { if (PropertyUtil.SetStruct(ref m_BorderWidth, value)) SetVerticesDirty(); }
  249. }
  250. /// <summary>
  251. /// Specifies "which dimension" of the data to map to the visual element. "Data" is series.data.
  252. /// |Starting at 1, the default is 0 to take the last dimension in data.
  253. /// |
  254. /// 指定用数据的『哪个维度』,映射到视觉元素上。『数据』即 series.data。从1开始,默认为0取 data 中最后一个维度。
  255. /// </summary>
  256. public int dimension
  257. {
  258. get { return m_Dimension; }
  259. set { if (PropertyUtil.SetStruct(ref m_Dimension, value)) SetVerticesDirty(); }
  260. }
  261. /// <summary>
  262. /// When the hoverLink function is turned on, when the mouse hovers over the visualMap component,
  263. /// the corresponding value of the mouse position is highlighted in the corresponding graphic element in the diagram.
  264. /// |Conversely, when the mouse hovers over a graphic element in a diagram,
  265. /// the corresponding value of the visualMap component is triangulated in the corresponding position.
  266. /// |
  267. /// 打开 hoverLink 功能时,鼠标悬浮到 visualMap 组件上时,鼠标位置对应的数值 在 图表中对应的图形元素,会高亮。
  268. /// 反之,鼠标悬浮到图表中的图形元素上时,在 visualMap 组件的相应位置会有三角提示其所对应的数值。
  269. /// </summary>
  270. /// <value></value>
  271. public bool hoverLink
  272. {
  273. get { return m_HoverLink; }
  274. set { if (PropertyUtil.SetStruct(ref m_HoverLink, value)) SetVerticesDirty(); }
  275. }
  276. /// <summary>
  277. /// Automatically set min, Max value
  278. /// 自动设置min,max的值
  279. /// </summary>
  280. public bool autoMinMax
  281. {
  282. get { return m_AutoMinMax; }
  283. set { if (PropertyUtil.SetStruct(ref m_AutoMinMax, value)) SetVerticesDirty(); }
  284. }
  285. /// <summary>
  286. /// Specify whether the layout of component is horizontal or vertical.
  287. /// |
  288. /// 布局方式是横还是竖。
  289. /// </summary>
  290. public Orient orient
  291. {
  292. get { return m_Orient; }
  293. set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetVerticesDirty(); }
  294. }
  295. /// <summary>
  296. /// The location of component.
  297. /// |组件显示的位置。
  298. /// </summary>
  299. public Location location
  300. {
  301. get { return m_Location; }
  302. set { if (PropertyUtil.SetClass(ref m_Location, value)) SetVerticesDirty(); }
  303. }
  304. /// <summary>
  305. /// Whether the visualmap is work on linestyle of linechart.
  306. /// |组件是否对LineChart的LineStyle有效。
  307. /// </summary>
  308. public bool workOnLine
  309. {
  310. get { return m_WorkOnLine; }
  311. set { if (PropertyUtil.SetStruct(ref m_WorkOnLine, value)) SetVerticesDirty(); }
  312. }
  313. /// <summary>
  314. /// Whether the visualmap is work on areaStyle of linechart.
  315. /// |组件是否对LineChart的AreaStyle有效。
  316. /// </summary>
  317. public bool workOnArea
  318. {
  319. get { return m_WorkOnArea; }
  320. set { if (PropertyUtil.SetStruct(ref m_WorkOnArea, value)) SetVerticesDirty(); }
  321. }
  322. /// <summary>
  323. /// Defines a visual color outside of the selected range.
  324. /// |定义 在选中范围外 的视觉颜色。
  325. /// </summary>
  326. public List<VisualMapRange> outOfRange
  327. {
  328. get { return m_OutOfRange; }
  329. set { if (value != null) { m_OutOfRange = value; SetVerticesDirty(); } }
  330. }
  331. /// <summary>
  332. /// 分段式每一段的相关配置。
  333. /// </summary>
  334. public List<VisualMapRange> inRange
  335. {
  336. get { return m_InRange; }
  337. set { if (value != null) { m_InRange = value; SetVerticesDirty(); } }
  338. }
  339. public override bool vertsDirty { get { return m_VertsDirty || location.anyDirty; } }
  340. public override void ClearVerticesDirty()
  341. {
  342. base.ClearVerticesDirty();
  343. location.ClearVerticesDirty();
  344. }
  345. public override void ClearComponentDirty()
  346. {
  347. base.ClearComponentDirty();
  348. location.ClearComponentDirty();
  349. }
  350. public double rangeMin
  351. {
  352. get
  353. {
  354. if (m_Range[0] == 0 && m_Range[1] == 0) return min;
  355. else if (m_Range[0] < min || m_Range[0] > max) return min;
  356. else return m_Range[0];
  357. }
  358. set
  359. {
  360. if (value >= min && value <= m_Range[1]) m_Range[0] = value;
  361. }
  362. }
  363. public double rangeMax
  364. {
  365. get
  366. {
  367. if (m_Range[0] == 0 && m_Range[1] == 0) return max;
  368. if (m_Range[1] >= m_Range[0] && m_Range[1] < max) return m_Range[1];
  369. else return max;
  370. }
  371. set
  372. {
  373. if (value >= m_Range[0] && value <= max) m_Range[1] = value;
  374. }
  375. }
  376. public float runtimeRangeMinHeight { get { return (float) ((rangeMin - min) / (max - min) * itemHeight); } }
  377. public float runtimeRangeMaxHeight { get { return (float) ((rangeMax - min) / (max - min) * itemHeight); } }
  378. public void AddColors(List<Color32> colors)
  379. {
  380. m_InRange.Clear();
  381. foreach (var color in colors)
  382. {
  383. m_InRange.Add(new VisualMapRange()
  384. {
  385. color = color
  386. });
  387. }
  388. }
  389. public void AddColors(List<string> colors)
  390. {
  391. m_InRange.Clear();
  392. foreach (var str in colors)
  393. {
  394. m_InRange.Add(new VisualMapRange()
  395. {
  396. color = ThemeStyle.GetColor(str)
  397. });
  398. }
  399. }
  400. public Color32 GetColor(double value)
  401. {
  402. int index = GetIndex(value);
  403. if (index == -1)
  404. {
  405. if (m_OutOfRange.Count > 0)
  406. return m_OutOfRange[0].color;
  407. else
  408. return ChartConst.clearColor32;
  409. }
  410. if (m_Type == VisualMap.Type.Piecewise)
  411. {
  412. return m_InRange[index].color;
  413. }
  414. else
  415. {
  416. int splitNumber = m_InRange.Count;
  417. var diff = (m_Max - m_Min) / (splitNumber - 1);
  418. var nowMin = m_Min + index * diff;
  419. var rate = (value - nowMin) / diff;
  420. if (index == splitNumber - 1)
  421. return m_InRange[index].color;
  422. else
  423. return Color32.Lerp(m_InRange[index].color, m_InRange[index + 1].color, (float) rate);
  424. }
  425. }
  426. private bool IsNeedPieceColor(double value, out int index)
  427. {
  428. bool flag = false;
  429. index = -1;
  430. for (int i = 0; i < m_InRange.Count; i++)
  431. {
  432. var range = m_InRange[i];
  433. if (range.min != 0 || range.max != 0)
  434. {
  435. flag = true;
  436. if (range.Contains(value, max - min))
  437. {
  438. index = i;
  439. return true;
  440. }
  441. }
  442. }
  443. return flag;
  444. }
  445. private Color32 GetPiecesColor(double value)
  446. {
  447. foreach (var piece in m_InRange)
  448. {
  449. if (piece.Contains(value, max - min))
  450. {
  451. return piece.color;
  452. }
  453. }
  454. if (m_OutOfRange.Count > 0)
  455. return m_OutOfRange[0].color;
  456. else
  457. return ChartConst.clearColor32;
  458. }
  459. public int GetIndex(double value)
  460. {
  461. int splitNumber = m_InRange.Count;
  462. if (splitNumber <= 0)
  463. return -1;
  464. var index = -1;
  465. if (IsNeedPieceColor(value, out index))
  466. {
  467. return index;
  468. }
  469. value = MathUtil.Clamp(value, m_Min, m_Max);
  470. var diff = (m_Max - m_Min) / (splitNumber - 1);
  471. for (int i = 0; i < splitNumber; i++)
  472. {
  473. if (value <= m_Min + (i + 1) * diff)
  474. {
  475. index = i;
  476. break;
  477. }
  478. }
  479. return index;
  480. }
  481. public bool IsPiecewise()
  482. {
  483. return m_Type == VisualMap.Type.Piecewise;
  484. }
  485. public bool IsInSelectedValue(double value)
  486. {
  487. if (context.pointerIndex < 0)
  488. return true;
  489. else
  490. return context.pointerIndex == GetIndex(value);
  491. }
  492. public double GetValue(Vector3 pos, Rect chartRect)
  493. {
  494. var vertical = orient == Orient.Vertical;
  495. var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
  496. var pos1 = centerPos + (vertical ? Vector3.down : Vector3.left) * itemHeight / 2;
  497. var pos2 = centerPos + (vertical ? Vector3.up : Vector3.right) * itemHeight / 2;
  498. if (vertical)
  499. {
  500. if (pos.y < pos1.y)
  501. return min;
  502. else if (pos.y > pos2.y)
  503. return max;
  504. else
  505. return min + (pos.y - pos1.y) / (pos2.y - pos1.y) * (max - min);
  506. }
  507. else
  508. {
  509. if (pos.x < pos1.x)
  510. return min;
  511. else if (pos.x > pos2.x)
  512. return max;
  513. else
  514. return min + (pos.x - pos1.x) / (pos2.x - pos1.x) * (max - min);
  515. }
  516. }
  517. public bool IsInRect(Vector3 local, Rect chartRect, float triangleLen = 20)
  518. {
  519. var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
  520. var diff = calculable ? triangleLen : 0;
  521. if (local.x >= centerPos.x - itemWidth / 2 - diff &&
  522. local.x <= centerPos.x + itemWidth / 2 + diff &&
  523. local.y >= centerPos.y - itemHeight / 2 - diff &&
  524. local.y <= centerPos.y + itemHeight / 2 + diff)
  525. {
  526. return true;
  527. }
  528. else
  529. {
  530. return false;
  531. }
  532. }
  533. public bool IsInRangeRect(Vector3 local, Rect chartRect)
  534. {
  535. var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
  536. if (orient == Orient.Vertical)
  537. {
  538. var pos1 = centerPos + Vector3.down * itemHeight / 2;
  539. return local.x >= centerPos.x - itemWidth / 2 &&
  540. local.x <= centerPos.x + itemWidth / 2 &&
  541. local.y >= pos1.y + runtimeRangeMinHeight &&
  542. local.y <= pos1.y + runtimeRangeMaxHeight;
  543. }
  544. else
  545. {
  546. var pos1 = centerPos + Vector3.left * itemHeight / 2;
  547. return local.x >= pos1.x + runtimeRangeMinHeight &&
  548. local.x <= pos1.x + runtimeRangeMaxHeight &&
  549. local.y >= centerPos.y - itemWidth / 2 &&
  550. local.y <= centerPos.y + itemWidth / 2;
  551. }
  552. }
  553. public bool IsInRangeMinRect(Vector3 local, Rect chartRect, float triangleLen)
  554. {
  555. var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
  556. if (orient == Orient.Vertical)
  557. {
  558. var radius = triangleLen / 2;
  559. var pos1 = centerPos + Vector3.down * itemHeight / 2;
  560. var cpos = new Vector3(pos1.x + itemWidth / 2 + radius, pos1.y + runtimeRangeMinHeight - radius);
  561. return local.x >= cpos.x - radius &&
  562. local.x <= cpos.x + radius &&
  563. local.y >= cpos.y - radius &&
  564. local.y <= cpos.y + radius;
  565. }
  566. else
  567. {
  568. var radius = triangleLen / 2;
  569. var pos1 = centerPos + Vector3.left * itemHeight / 2;
  570. var cpos = new Vector3(pos1.x + runtimeRangeMinHeight, pos1.y + itemWidth / 2 + radius);
  571. return local.x >= cpos.x - radius &&
  572. local.x <= cpos.x + radius &&
  573. local.y >= cpos.y - radius &&
  574. local.y <= cpos.y + radius;
  575. }
  576. }
  577. public bool IsInRangeMaxRect(Vector3 local, Rect chartRect, float triangleLen)
  578. {
  579. var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
  580. if (orient == Orient.Vertical)
  581. {
  582. var radius = triangleLen / 2;
  583. var pos1 = centerPos + Vector3.down * itemHeight / 2;
  584. var cpos = new Vector3(pos1.x + itemWidth / 2 + radius, pos1.y + runtimeRangeMaxHeight + radius);
  585. return local.x >= cpos.x - radius &&
  586. local.x <= cpos.x + radius &&
  587. local.y >= cpos.y - radius &&
  588. local.y <= cpos.y + radius;
  589. }
  590. else
  591. {
  592. var radius = triangleLen / 2;
  593. var pos1 = centerPos + Vector3.left * itemHeight / 2;
  594. var cpos = new Vector3(pos1.x + runtimeRangeMaxHeight + radius, pos1.y + itemWidth / 2 + radius);
  595. return local.x >= cpos.x - radius &&
  596. local.x <= cpos.x + radius &&
  597. local.y >= cpos.y - radius &&
  598. local.y <= cpos.y + radius;
  599. }
  600. }
  601. }
  602. }