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