CoordinateChart_DrawBar.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /************************************************/
  2. /* */
  3. /* Copyright (c) 2018 - 2021 monitor1394 */
  4. /* https://github.com/monitor1394 */
  5. /* */
  6. /************************************************/
  7. using System;
  8. using System.Collections.Generic;
  9. using UnityEngine;
  10. using UnityEngine.EventSystems;
  11. using UnityEngine.UI;
  12. using XUGL;
  13. namespace XCharts
  14. {
  15. public partial class CoordinateChart
  16. {
  17. protected Action<PointerEventData, int> m_OnPointerClickBar;
  18. protected void DrawYBarSerie(VertexHelper vh, Serie serie, int colorIndex)
  19. {
  20. if (!IsActive(serie.name)) return;
  21. if (serie.animation.HasFadeOut()) return;
  22. var xAxis = m_XAxes[serie.xAxisIndex];
  23. var yAxis = m_YAxes[serie.yAxisIndex];
  24. var grid = GetSerieGridOrDefault(serie);
  25. var dataZoom = DataZoomHelper.GetAxisRelatedDataZoom(yAxis, dataZooms);
  26. var showData = serie.GetDataList(dataZoom);
  27. float categoryWidth = AxisHelper.GetDataWidth(yAxis, grid.runtimeHeight, showData.Count, dataZoom);
  28. float barGap = Internal_GetBarGap(SerieType.Bar);
  29. float totalBarWidth = Internal_GetBarTotalWidth(categoryWidth, barGap, SerieType.Bar);
  30. float barWidth = serie.GetBarWidth(categoryWidth);
  31. float offset = (categoryWidth - totalBarWidth) / 2;
  32. float barGapWidth = barWidth + barWidth * barGap;
  33. float space = serie.barGap == -1 ? offset : offset + Internal_GetBarIndex(serie, SerieType.Bar) * barGapWidth;
  34. var isStack = SeriesHelper.IsStack(m_Series, serie.stack, SerieType.Bar);
  35. m_StackSerieData.Clear();
  36. if (isStack) SeriesHelper.UpdateStackDataList(m_Series, serie, dataZoom, m_StackSerieData);
  37. int maxCount = serie.maxShow > 0 ?
  38. (serie.maxShow > showData.Count ? showData.Count : serie.maxShow)
  39. : showData.Count;
  40. var isPercentStack = SeriesHelper.IsPercentStack(m_Series, serie.stack, SerieType.Bar);
  41. bool dataChanging = false;
  42. float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
  43. double xMinValue = xAxis.GetCurrMinValue(dataChangeDuration);
  44. double xMaxValue = xAxis.GetCurrMaxValue(dataChangeDuration);
  45. var isAllBarEnd = true;
  46. for (int i = serie.minShow; i < maxCount; i++)
  47. {
  48. var serieData = showData[i];
  49. if (!serieData.show || serie.IsIgnoreValue(serieData))
  50. {
  51. serie.dataPoints.Add(Vector3.zero);
  52. continue;
  53. }
  54. var highlight = (tooltip.show && tooltip.IsSelected(i))
  55. || serie.data[i].highlighted
  56. || serie.highlighted;
  57. var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight);
  58. serieData.canShowLabel = true;
  59. double value = showData[i].GetCurrData(1, dataChangeDuration, xAxis.inverse, xMinValue, xMaxValue);
  60. float borderWidth = value == 0 ? 0 : itemStyle.runtimeBorderWidth;
  61. if (showData[i].IsDataChanged()) dataChanging = true;
  62. float axisLineWidth = value == 0 ? 0
  63. : ((value < 0 ? -1 : 1) * yAxis.axisLine.GetWidth(m_Theme.axis.lineWidth));
  64. float pY = grid.runtimeY + i * categoryWidth;
  65. if (!yAxis.boundaryGap) pY -= categoryWidth / 2;
  66. float pX = grid.runtimeX + xAxis.runtimeZeroXOffset + axisLineWidth;
  67. if (isStack)
  68. {
  69. for (int n = 0; n < m_StackSerieData.Count - 1; n++)
  70. {
  71. pX += m_StackSerieData[n][i].runtimeStackHig;
  72. }
  73. }
  74. var barHig = 0f;
  75. double valueTotal = 0f;
  76. if (isPercentStack)
  77. {
  78. valueTotal = Internal_GetBarSameStackTotalValue(serie.stack, i, SerieType.Bar);
  79. barHig = valueTotal != 0 ? (float)((value / valueTotal * grid.runtimeWidth)) : 0;
  80. }
  81. else
  82. {
  83. if (yAxis.IsLog())
  84. {
  85. int minIndex = xAxis.runtimeMinLogIndex;
  86. float nowIndex = xAxis.GetLogValue(value);
  87. barHig = (nowIndex - minIndex) / xAxis.splitNumber * grid.runtimeWidth;
  88. }
  89. else
  90. {
  91. valueTotal = xMaxValue - xMinValue;
  92. if (valueTotal != 0)
  93. barHig = (float)((xMinValue > 0 ? value - xMinValue : value)
  94. / valueTotal * grid.runtimeWidth);
  95. }
  96. }
  97. serieData.runtimeStackHig = barHig;
  98. var isBarEnd = false;
  99. float currHig = Internal_CheckBarAnimation(serie, i, barHig, out isBarEnd);
  100. if (!isBarEnd) isAllBarEnd = false;
  101. Vector3 plt, prt, prb, plb, top;
  102. if (value < 0)
  103. {
  104. plt = new Vector3(pX - borderWidth, pY + space + barWidth - borderWidth);
  105. prt = new Vector3(pX + currHig + borderWidth, pY + space + barWidth - borderWidth);
  106. prb = new Vector3(pX + currHig + borderWidth, pY + space + borderWidth);
  107. plb = new Vector3(pX - borderWidth, pY + space + borderWidth);
  108. }
  109. else
  110. {
  111. plt = new Vector3(pX + borderWidth, pY + space + barWidth - borderWidth);
  112. prt = new Vector3(pX + currHig - borderWidth, pY + space + barWidth - borderWidth);
  113. prb = new Vector3(pX + currHig - borderWidth, pY + space + borderWidth);
  114. plb = new Vector3(pX + borderWidth, pY + space + borderWidth);
  115. }
  116. top = new Vector3(pX + currHig - borderWidth, pY + space + barWidth / 2);
  117. if (serie.clip)
  118. {
  119. plt = ClampInGrid(grid, plt);
  120. prt = ClampInGrid(grid, prt);
  121. prb = ClampInGrid(grid, prb);
  122. plb = ClampInGrid(grid, plb);
  123. top = ClampInGrid(grid, top);
  124. }
  125. serie.dataPoints.Add(top);
  126. if (serie.show)
  127. {
  128. switch (serie.barType)
  129. {
  130. case BarType.Normal:
  131. DrawNormalBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth,
  132. pX, pY, plb, plt, prt, prb, true, grid);
  133. break;
  134. case BarType.Zebra:
  135. DrawZebraBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth,
  136. pX, pY, plb, plt, prt, prb, true, grid);
  137. break;
  138. case BarType.Capsule:
  139. DrawCapsuleBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth,
  140. pX, pY, plb, plt, prt, prb, true, grid);
  141. break;
  142. }
  143. }
  144. }
  145. if (isAllBarEnd) serie.animation.AllBarEnd();
  146. if (dataChanging)
  147. {
  148. RefreshPainter(serie);
  149. }
  150. }
  151. public float Internal_CheckBarAnimation(Serie serie, int dataIndex, float barHig, out bool isBarEnd)
  152. {
  153. float currHig = serie.animation.CheckBarProgress(dataIndex, barHig, serie.dataCount, out isBarEnd);
  154. if (!serie.animation.IsFinish())
  155. {
  156. RefreshPainter(serie);
  157. m_IsPlayingAnimation = true;
  158. }
  159. return currHig;
  160. }
  161. protected void DrawXBarSerie(VertexHelper vh, Serie serie, int colorIndex)
  162. {
  163. if (!IsActive(serie.index)) return;
  164. if (serie.animation.HasFadeOut()) return;
  165. var yAxis = m_YAxes[serie.yAxisIndex];
  166. var xAxis = m_XAxes[serie.xAxisIndex];
  167. var grid = GetSerieGridOrDefault(serie);
  168. var dataZoom = DataZoomHelper.GetAxisRelatedDataZoom(xAxis, dataZooms);
  169. var showData = serie.GetDataList(dataZoom);
  170. var isStack = SeriesHelper.IsStack(m_Series, serie.stack, SerieType.Bar);
  171. m_StackSerieData.Clear();
  172. if (isStack) SeriesHelper.UpdateStackDataList(m_Series, serie, dataZoom, m_StackSerieData);
  173. float categoryWidth = AxisHelper.GetDataWidth(xAxis, grid.runtimeWidth, showData.Count, dataZoom);
  174. float barGap = Internal_GetBarGap(SerieType.Bar);
  175. float totalBarWidth = Internal_GetBarTotalWidth(categoryWidth, barGap, SerieType.Bar);
  176. float barWidth = serie.GetBarWidth(categoryWidth);
  177. float offset = (categoryWidth - totalBarWidth) / 2;
  178. float barGapWidth = barWidth + barWidth * barGap;
  179. float space = serie.barGap == -1 ? offset : offset + Internal_GetBarIndex(serie, SerieType.Bar) * barGapWidth;
  180. int maxCount = serie.maxShow > 0
  181. ? (serie.maxShow > showData.Count ? showData.Count : serie.maxShow)
  182. : showData.Count;
  183. var isPercentStack = SeriesHelper.IsPercentStack(m_Series, serie.stack, SerieType.Bar);
  184. bool dataChanging = false;
  185. float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
  186. double yMinValue = yAxis.GetCurrMinValue(dataChangeDuration);
  187. double yMaxValue = yAxis.GetCurrMaxValue(dataChangeDuration);
  188. var isAllBarEnd = true;
  189. for (int i = serie.minShow; i < maxCount; i++)
  190. {
  191. var serieData = showData[i];
  192. if (!serieData.show || serie.IsIgnoreValue(serieData))
  193. {
  194. serie.dataPoints.Add(Vector3.zero);
  195. continue;
  196. }
  197. var highlight = (tooltip.show && tooltip.IsSelected(i))
  198. || serie.data[i].highlighted
  199. || serie.highlighted;
  200. var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight);
  201. double value = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
  202. float borderWidth = value == 0 ? 0 : itemStyle.runtimeBorderWidth;
  203. if (serieData.IsDataChanged()) dataChanging = true;
  204. float pX = grid.runtimeX + i * categoryWidth;
  205. float zeroY = grid.runtimeY + yAxis.runtimeZeroYOffset;
  206. if (!xAxis.boundaryGap) pX -= categoryWidth / 2;
  207. float axisLineWidth = value == 0 ? 0 :
  208. ((value < 0 ? -1 : 1) * xAxis.axisLine.GetWidth(m_Theme.axis.lineWidth));
  209. float pY = zeroY + axisLineWidth;
  210. if (isStack)
  211. {
  212. for (int n = 0; n < m_StackSerieData.Count - 1; n++)
  213. {
  214. pY += m_StackSerieData[n][i].runtimeStackHig;
  215. }
  216. }
  217. var barHig = 0f;
  218. double valueTotal = 0f;
  219. if (isPercentStack)
  220. {
  221. valueTotal = Internal_GetBarSameStackTotalValue(serie.stack, i, SerieType.Bar);
  222. barHig = valueTotal != 0 ? (float)(value / valueTotal * grid.runtimeHeight) : 0;
  223. }
  224. else
  225. {
  226. valueTotal = (double)(yMaxValue - yMinValue);
  227. if (valueTotal != 0)
  228. {
  229. if (yAxis.IsLog())
  230. {
  231. int minIndex = yAxis.runtimeMinLogIndex;
  232. var nowIndex = yAxis.GetLogValue(value);
  233. barHig = (nowIndex - minIndex) / yAxis.splitNumber * grid.runtimeHeight;
  234. }
  235. else
  236. {
  237. barHig = (float)((yMinValue > 0 ? value - yMinValue : value) / valueTotal * grid.runtimeHeight);
  238. }
  239. }
  240. }
  241. serieData.runtimeStackHig = barHig;
  242. var isBarEnd = false;
  243. float currHig = Internal_CheckBarAnimation(serie, i, barHig, out isBarEnd);
  244. if (!isBarEnd) isAllBarEnd = false;
  245. Vector3 plb, plt, prt, prb, top;
  246. if (value < 0)
  247. {
  248. plb = new Vector3(pX + space + borderWidth, pY - borderWidth);
  249. plt = new Vector3(pX + space + borderWidth, pY + currHig + borderWidth);
  250. prt = new Vector3(pX + space + barWidth - borderWidth, pY + currHig + borderWidth);
  251. prb = new Vector3(pX + space + barWidth - borderWidth, pY - borderWidth);
  252. }
  253. else
  254. {
  255. plb = new Vector3(pX + space + borderWidth, pY + borderWidth);
  256. plt = new Vector3(pX + space + borderWidth, pY + currHig - borderWidth);
  257. prt = new Vector3(pX + space + barWidth - borderWidth, pY + currHig - borderWidth);
  258. prb = new Vector3(pX + space + barWidth - borderWidth, pY + borderWidth);
  259. }
  260. top = new Vector3(pX + space + barWidth / 2, pY + currHig - borderWidth);
  261. if (serie.clip)
  262. {
  263. plb = ClampInGrid(grid, plb);
  264. plt = ClampInGrid(grid, plt);
  265. prt = ClampInGrid(grid, prt);
  266. prb = ClampInGrid(grid, prb);
  267. top = ClampInGrid(grid, top);
  268. }
  269. serie.dataPoints.Add(top);
  270. if (serie.show && currHig != 0)
  271. {
  272. switch (serie.barType)
  273. {
  274. case BarType.Normal:
  275. DrawNormalBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth,
  276. pX, pY, plb, plt, prt, prb, false, grid);
  277. break;
  278. case BarType.Zebra:
  279. DrawZebraBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth,
  280. pX, pY, plb, plt, prt, prb, false, grid);
  281. break;
  282. case BarType.Capsule:
  283. DrawCapsuleBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth,
  284. pX, pY, plb, plt, prt, prb, false, grid);
  285. break;
  286. }
  287. }
  288. }
  289. if (isAllBarEnd)
  290. {
  291. serie.animation.AllBarEnd();
  292. }
  293. if (dataChanging)
  294. {
  295. RefreshPainter(serie);
  296. }
  297. }
  298. private void DrawNormalBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex,
  299. bool highlight, float space, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt,
  300. Vector3 prb, bool isYAxis, Grid grid)
  301. {
  302. var areaColor = SerieHelper.GetItemColor(serie, serieData, m_Theme, colorIndex, highlight);
  303. var areaToColor = SerieHelper.GetItemToColor(serie, serieData, m_Theme, colorIndex, highlight);
  304. DrawBarBackground(vh, serie, serieData, itemStyle, colorIndex, highlight, pX, pY, space, barWidth, isYAxis, grid);
  305. var borderWidth = itemStyle.runtimeBorderWidth;
  306. if (isYAxis)
  307. {
  308. if (serie.clip)
  309. {
  310. prb = ClampInGrid(grid, prb);
  311. plb = ClampInGrid(grid, plb);
  312. plt = ClampInGrid(grid, plt);
  313. prt = ClampInGrid(grid, prt);
  314. }
  315. var itemWidth = Mathf.Abs(prb.x - plt.x);
  316. var itemHeight = Mathf.Abs(prt.y - plb.y);
  317. var center = new Vector3((plt.x + prb.x) / 2, (prt.y + plb.y) / 2);
  318. if (itemWidth > 0 && itemHeight > 0)
  319. {
  320. var invert = center.x < plb.x;
  321. if (ItemStyleHelper.IsNeedCorner(itemStyle))
  322. {
  323. UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaToColor, 0,
  324. itemStyle.cornerRadius, isYAxis, m_Settings.cicleSmoothness, invert);
  325. }
  326. else
  327. {
  328. Internal_CheckClipAndDrawPolygon(vh, plb, plt, prt, prb, areaColor, areaToColor, serie.clip, grid);
  329. }
  330. UGL.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, itemStyle.borderColor,
  331. itemStyle.borderToColor, 0, itemStyle.cornerRadius, isYAxis, m_Settings.cicleSmoothness, invert);
  332. }
  333. }
  334. else
  335. {
  336. if (serie.clip)
  337. {
  338. prb = ClampInGrid(grid, prb);
  339. plb = ClampInGrid(grid, plb);
  340. plt = ClampInGrid(grid, plt);
  341. prt = ClampInGrid(grid, prt);
  342. }
  343. var itemWidth = Mathf.Abs(prt.x - plb.x);
  344. var itemHeight = Mathf.Abs(plt.y - prb.y);
  345. var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2);
  346. if (itemWidth > 0 && itemHeight > 0)
  347. {
  348. var invert = center.y < plb.y;
  349. if (ItemStyleHelper.IsNeedCorner(itemStyle))
  350. {
  351. UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaToColor, 0,
  352. itemStyle.cornerRadius, isYAxis, m_Settings.cicleSmoothness, invert);
  353. }
  354. else
  355. {
  356. Internal_CheckClipAndDrawPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaToColor,
  357. serie.clip, grid);
  358. }
  359. UGL.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, itemStyle.borderColor,
  360. itemStyle.borderToColor, 0, itemStyle.cornerRadius, isYAxis, m_Settings.cicleSmoothness, invert);
  361. }
  362. }
  363. }
  364. private void DrawZebraBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex,
  365. bool highlight, float space, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt,
  366. Vector3 prb, bool isYAxis, Grid grid)
  367. {
  368. var barColor = SerieHelper.GetItemColor(serie, serieData, m_Theme, colorIndex, highlight);
  369. var barToColor = SerieHelper.GetItemToColor(serie, serieData, m_Theme, colorIndex, highlight);
  370. DrawBarBackground(vh, serie, serieData, itemStyle, colorIndex, highlight, pX, pY, space, barWidth, isYAxis, grid);
  371. if (isYAxis)
  372. {
  373. plt = (plb + plt) / 2;
  374. prt = (prt + prb) / 2;
  375. Internal_CheckClipAndDrawZebraLine(vh, plt, prt, barWidth / 2, serie.barZebraWidth, serie.barZebraGap,
  376. barColor, barToColor, serie.clip, grid);
  377. }
  378. else
  379. {
  380. plb = (prb + plb) / 2;
  381. plt = (plt + prt) / 2;
  382. Internal_CheckClipAndDrawZebraLine(vh, plb, plt, barWidth / 2, serie.barZebraWidth, serie.barZebraGap,
  383. barColor, barToColor, serie.clip, grid);
  384. }
  385. }
  386. private void DrawCapsuleBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex,
  387. bool highlight, float space, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt,
  388. Vector3 prb, bool isYAxis, Grid grid)
  389. {
  390. var areaColor = SerieHelper.GetItemColor(serie, serieData, m_Theme, colorIndex, highlight);
  391. var areaToColor = SerieHelper.GetItemToColor(serie, serieData, m_Theme, colorIndex, highlight);
  392. DrawBarBackground(vh, serie, serieData, itemStyle, colorIndex, highlight, pX, pY, space, barWidth, isYAxis, grid);
  393. var borderWidth = itemStyle.runtimeBorderWidth;
  394. var radius = barWidth / 2 - borderWidth;
  395. var isGradient = !ChartHelper.IsValueEqualsColor(areaColor, areaToColor);
  396. if (isYAxis)
  397. {
  398. var diff = Vector3.right * radius;
  399. if (plt.x < prt.x)
  400. {
  401. var pcl = (plt + plb) / 2 + diff;
  402. var pcr = (prt + prb) / 2 - diff;
  403. if (pcr.x > pcl.x)
  404. {
  405. if (isGradient)
  406. {
  407. var barLen = prt.x - plt.x;
  408. var rectStartColor = Color32.Lerp(areaColor, areaToColor, radius / barLen);
  409. var rectEndColor = Color32.Lerp(areaColor, areaToColor, (barLen - radius) / barLen);
  410. Internal_CheckClipAndDrawPolygon(vh, plb + diff, plt + diff, prt - diff, prb - diff, rectStartColor,
  411. rectEndColor, serie.clip, grid);
  412. UGL.DrawSector(vh, pcl, radius, areaColor, rectStartColor, 180, 360, 1, isYAxis);
  413. UGL.DrawSector(vh, pcr, radius, rectEndColor, areaToColor, 0, 180, 1, isYAxis);
  414. }
  415. else
  416. {
  417. Internal_CheckClipAndDrawPolygon(vh, plb + diff, plt + diff, prt - diff, prb - diff, areaColor,
  418. areaToColor, serie.clip, grid);
  419. UGL.DrawSector(vh, pcl, radius, areaColor, 180, 360);
  420. UGL.DrawSector(vh, pcr, radius, areaToColor, 0, 180);
  421. }
  422. }
  423. }
  424. else if (plt.x > prt.x)
  425. {
  426. var pcl = (plt + plb) / 2 - diff;
  427. var pcr = (prt + prb) / 2 + diff;
  428. if (pcr.x < pcl.x)
  429. {
  430. if (isGradient)
  431. {
  432. var barLen = plt.x - prt.x;
  433. var rectStartColor = Color32.Lerp(areaColor, areaToColor, radius / barLen);
  434. var rectEndColor = Color32.Lerp(areaColor, areaToColor, (barLen - radius) / barLen);
  435. Internal_CheckClipAndDrawPolygon(vh, plb - diff, plt - diff, prt + diff, prb + diff, rectStartColor,
  436. rectEndColor, serie.clip, grid);
  437. UGL.DrawSector(vh, pcl, radius, rectStartColor, areaColor, 0, 180, 1, isYAxis);
  438. UGL.DrawSector(vh, pcr, radius, areaToColor, rectEndColor, 180, 360, 1, isYAxis);
  439. }
  440. else
  441. {
  442. Internal_CheckClipAndDrawPolygon(vh, plb - diff, plt - diff, prt + diff, prb + diff, areaColor,
  443. areaToColor, serie.clip, grid);
  444. UGL.DrawSector(vh, pcl, radius, areaColor, 0, 180);
  445. UGL.DrawSector(vh, pcr, radius, areaToColor, 180, 360);
  446. }
  447. }
  448. }
  449. }
  450. else
  451. {
  452. var diff = Vector3.up * radius;
  453. if (plt.y > plb.y)
  454. {
  455. var pct = (plt + prt) / 2 - diff;
  456. var pcb = (plb + prb) / 2 + diff;
  457. if (pct.y > pcb.y)
  458. {
  459. if (isGradient)
  460. {
  461. var barLen = plt.y - plb.y;
  462. var rectStartColor = Color32.Lerp(areaColor, areaToColor, radius / barLen);
  463. var rectEndColor = Color32.Lerp(areaColor, areaToColor, (barLen - radius) / barLen);
  464. Internal_CheckClipAndDrawPolygon(vh, prb + diff, plb + diff, plt - diff, prt - diff, rectStartColor,
  465. rectEndColor, serie.clip, grid);
  466. UGL.DrawSector(vh, pct, radius, rectEndColor, areaToColor, 270, 450, 1, isYAxis);
  467. UGL.DrawSector(vh, pcb, radius, rectStartColor, areaColor, 90, 270, 1, isYAxis);
  468. }
  469. else
  470. {
  471. Internal_CheckClipAndDrawPolygon(vh, prb + diff, plb + diff, plt - diff, prt - diff, areaColor,
  472. areaToColor, serie.clip, grid);
  473. UGL.DrawSector(vh, pct, radius, areaToColor, 270, 450);
  474. UGL.DrawSector(vh, pcb, radius, areaColor, 90, 270);
  475. }
  476. }
  477. }
  478. else if (plt.y < plb.y)
  479. {
  480. var pct = (plt + prt) / 2 + diff;
  481. var pcb = (plb + prb) / 2 - diff;
  482. if (pct.y < pcb.y)
  483. {
  484. if (isGradient)
  485. {
  486. var barLen = plb.y - plt.y;
  487. var rectStartColor = Color32.Lerp(areaColor, areaToColor, radius / barLen);
  488. var rectEndColor = Color32.Lerp(areaColor, areaToColor, (barLen - radius) / barLen);
  489. Internal_CheckClipAndDrawPolygon(vh, prb - diff, plb - diff, plt + diff, prt + diff, rectStartColor,
  490. rectEndColor, serie.clip, grid);
  491. UGL.DrawSector(vh, pct, radius, rectEndColor, areaToColor, 90, 270, 1, isYAxis);
  492. UGL.DrawSector(vh, pcb, radius, rectStartColor, areaColor, 270, 450, 1, isYAxis);
  493. }
  494. else
  495. {
  496. Internal_CheckClipAndDrawPolygon(vh, prb - diff, plb - diff, plt + diff, prt + diff, areaColor,
  497. areaToColor, serie.clip, grid);
  498. UGL.DrawSector(vh, pct, radius, areaToColor, 90, 270);
  499. UGL.DrawSector(vh, pcb, radius, areaColor, 270, 450);
  500. }
  501. }
  502. }
  503. }
  504. }
  505. private void DrawBarBackground(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle,
  506. int colorIndex, bool highlight, float pX, float pY, float space, float barWidth, bool isYAxis, Grid grid)
  507. {
  508. var color = SerieHelper.GetItemBackgroundColor(serie, serieData, m_Theme, colorIndex, highlight, false);
  509. if (ChartHelper.IsClearColor(color)) return;
  510. if (isYAxis)
  511. {
  512. var axis = m_YAxes[serie.yAxisIndex];
  513. var axisWidth = axis.axisLine.GetWidth(m_Theme.axis.lineWidth);
  514. Vector3 plt = new Vector3(grid.runtimeX + axisWidth, pY + space + barWidth);
  515. Vector3 prt = new Vector3(grid.runtimeX + axisWidth + grid.runtimeWidth, pY + space + barWidth);
  516. Vector3 prb = new Vector3(grid.runtimeX + axisWidth + grid.runtimeWidth, pY + space);
  517. Vector3 plb = new Vector3(grid.runtimeX + axisWidth, pY + space);
  518. if (serie.barType == BarType.Capsule)
  519. {
  520. var radius = barWidth / 2;
  521. var diff = Vector3.right * radius;
  522. var pcl = (plt + plb) / 2 + diff;
  523. var pcr = (prt + prb) / 2 - diff;
  524. Internal_CheckClipAndDrawPolygon(vh, plb + diff, plt + diff, prt - diff, prb - diff, color, color, serie.clip, grid);
  525. UGL.DrawSector(vh, pcl, radius, color, 180, 360);
  526. UGL.DrawSector(vh, pcr, radius, color, 0, 180);
  527. if (itemStyle.NeedShowBorder())
  528. {
  529. var borderWidth = itemStyle.borderWidth;
  530. var borderColor = itemStyle.borderColor;
  531. var smoothness = settings.cicleSmoothness;
  532. var inRadius = radius - borderWidth;
  533. var outRadius = radius;
  534. var p1 = plb + diff + Vector3.up * borderWidth / 2;
  535. var p2 = prb - diff + Vector3.up * borderWidth / 2;
  536. var p3 = plt + diff - Vector3.up * borderWidth / 2;
  537. var p4 = prt - diff - Vector3.up * borderWidth / 2;
  538. UGL.DrawLine(vh, p1, p2, borderWidth / 2, borderColor);
  539. UGL.DrawLine(vh, p3, p4, borderWidth / 2, borderColor);
  540. UGL.DrawDoughnut(vh, pcl, inRadius, outRadius, borderColor, ChartConst.clearColor32,
  541. 180, 360, smoothness);
  542. UGL.DrawDoughnut(vh, pcr, inRadius, outRadius, borderColor, ChartConst.clearColor32,
  543. 0, 180, smoothness);
  544. }
  545. }
  546. else
  547. {
  548. Internal_CheckClipAndDrawPolygon(vh, ref plb, ref plt, ref prt, ref prb, color, color, serie.clip, grid);
  549. }
  550. }
  551. else
  552. {
  553. var axis = m_XAxes[serie.xAxisIndex];
  554. var axisWidth = axis.axisLine.GetWidth(m_Theme.axis.lineWidth);
  555. Vector3 plb = new Vector3(pX + space, grid.runtimeY + axisWidth);
  556. Vector3 plt = new Vector3(pX + space, grid.runtimeY + grid.runtimeHeight + axisWidth);
  557. Vector3 prt = new Vector3(pX + space + barWidth, grid.runtimeY + grid.runtimeHeight + axisWidth);
  558. Vector3 prb = new Vector3(pX + space + barWidth, grid.runtimeY + axisWidth);
  559. if (serie.barType == BarType.Capsule)
  560. {
  561. var radius = barWidth / 2;
  562. var diff = Vector3.up * radius;
  563. var pct = (plt + prt) / 2 - diff;
  564. var pcb = (plb + prb) / 2 + diff;
  565. Internal_CheckClipAndDrawPolygon(vh, prb + diff, plb + diff, plt - diff, prt - diff, color, color,
  566. serie.clip, grid);
  567. UGL.DrawSector(vh, pct, radius, color, 270, 450);
  568. UGL.DrawSector(vh, pcb, radius, color, 90, 270);
  569. if (itemStyle.NeedShowBorder())
  570. {
  571. var borderWidth = itemStyle.borderWidth;
  572. var borderColor = itemStyle.borderColor;
  573. var smoothness = settings.cicleSmoothness;
  574. var inRadius = radius - borderWidth;
  575. var outRadius = radius;
  576. var p1 = plb + diff + Vector3.right * borderWidth / 2;
  577. var p2 = plt - diff + Vector3.right * borderWidth / 2;
  578. var p3 = prb + diff - Vector3.right * borderWidth / 2;
  579. var p4 = prt - diff - Vector3.right * borderWidth / 2;
  580. UGL.DrawLine(vh, p1, p2, borderWidth / 2, borderColor);
  581. UGL.DrawLine(vh, p3, p4, borderWidth / 2, borderColor);
  582. UGL.DrawDoughnut(vh, pct, inRadius, outRadius, borderColor, ChartConst.clearColor32,
  583. 270, 450, smoothness);
  584. UGL.DrawDoughnut(vh, pcb, inRadius, outRadius, borderColor, ChartConst.clearColor32,
  585. 90, 270, smoothness);
  586. }
  587. }
  588. else
  589. {
  590. Internal_CheckClipAndDrawPolygon(vh, ref prb, ref plb, ref plt, ref prt, color, color, serie.clip, grid);
  591. }
  592. }
  593. }
  594. public float Internal_GetBarGap(SerieType type)
  595. {
  596. float gap = 0f;
  597. for (int i = 0; i < m_Series.Count; i++)
  598. {
  599. var serie = m_Series.list[i];
  600. if (serie.type == type)
  601. {
  602. if (serie.barGap != 0)
  603. {
  604. gap = serie.barGap;
  605. }
  606. }
  607. }
  608. return gap;
  609. }
  610. public double Internal_GetBarSameStackTotalValue(string stack, int dataIndex, SerieType type)
  611. {
  612. if (string.IsNullOrEmpty(stack)) return 0;
  613. double total = 0;
  614. foreach (var serie in m_Series.list)
  615. {
  616. if (serie.type == type)
  617. {
  618. if (stack.Equals(serie.stack))
  619. {
  620. total += serie.data[dataIndex].data[1];
  621. }
  622. }
  623. }
  624. return total;
  625. }
  626. private HashSet<string> barStackSet = new HashSet<string>();
  627. public float Internal_GetBarTotalWidth(float categoryWidth, float gap, SerieType type)
  628. {
  629. float total = 0;
  630. float lastGap = 0;
  631. barStackSet.Clear();
  632. for (int i = 0; i < m_Series.Count; i++)
  633. {
  634. var serie = m_Series.list[i];
  635. if (!serie.show) continue;
  636. if (serie.type == type)
  637. {
  638. if (!string.IsNullOrEmpty(serie.stack))
  639. {
  640. if (barStackSet.Contains(serie.stack)) continue;
  641. barStackSet.Add(serie.stack);
  642. }
  643. var width = GetStackBarWidth(categoryWidth, serie, type);
  644. if (gap == -1)
  645. {
  646. if (width > total) total = width;
  647. }
  648. else
  649. {
  650. lastGap = width * gap;
  651. total += width;
  652. total += lastGap;
  653. }
  654. }
  655. }
  656. if (total > 0 && gap != -1) total -= lastGap;
  657. return total;
  658. }
  659. private float GetStackBarWidth(float categoryWidth, Serie now, SerieType type)
  660. {
  661. if (string.IsNullOrEmpty(now.stack)) return now.GetBarWidth(categoryWidth);
  662. float barWidth = 0;
  663. for (int i = 0; i < m_Series.Count; i++)
  664. {
  665. var serie = m_Series.list[i];
  666. if ((serie.type == type)
  667. && serie.show && now.stack.Equals(serie.stack))
  668. {
  669. if (serie.barWidth > barWidth) barWidth = serie.barWidth;
  670. }
  671. }
  672. if (barWidth > 1) return barWidth;
  673. else return barWidth * categoryWidth;
  674. }
  675. private List<string> tempList = new List<string>();
  676. public int Internal_GetBarIndex(Serie currSerie, SerieType type)
  677. {
  678. tempList.Clear();
  679. int index = 0;
  680. for (int i = 0; i < m_Series.Count; i++)
  681. {
  682. var serie = m_Series.GetSerie(i);
  683. if (serie.type != type) continue;
  684. if (string.IsNullOrEmpty(serie.stack))
  685. {
  686. if (serie.index == currSerie.index) return index;
  687. tempList.Add(string.Empty);
  688. index++;
  689. }
  690. else
  691. {
  692. if (!tempList.Contains(serie.stack))
  693. {
  694. if (serie.index == currSerie.index) return index;
  695. tempList.Add(serie.stack);
  696. index++;
  697. }
  698. else
  699. {
  700. if (serie.index == currSerie.index) return tempList.IndexOf(serie.stack);
  701. }
  702. }
  703. }
  704. return 0;
  705. }
  706. }
  707. }