1 using System.Runtime.InteropServices.ComTypes;
10 using System.Collections.Generic;
17 public partial class CoordinateChart
19 protected void DrawLinePoint(VertexHelper vh, Serie serie)
21 if (!serie.show || serie.IsPerformanceMode())
return;
23 var count = serie.dataPoints.Count;
24 var clip = SeriesHelper.IsAnyClipSerie(m_Series);
25 var
grid = GetSerieGridOrDefault(serie);
26 for (
int i = 0; i < count; i++)
28 var serieData = serie.GetSerieData(i);
29 var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
30 if (!symbol.show || !symbol.ShowSymbol(i, count))
continue;
31 if (serie.lineArrow.show)
33 if (serie.lineArrow.position == LineArrow.Position.Start && i == 0)
continue;
34 if (serie.lineArrow.position == LineArrow.Position.End && i == count - 1)
continue;
36 if (ChartHelper.IsIngore(serie.dataPoints[i]))
continue;
37 bool highlight = (tooltip.show && tooltip.IsSelected(i))
38 || serie.data[i].highlighted || serie.highlighted;
39 float symbolSize = highlight
40 ? symbol.GetSelectedSize(serie.data[i].data, m_Theme.serie.lineSymbolSelectedSize)
41 : symbol.GetSize(serie.data[i].data, m_Theme.serie.lineSymbolSize);
42 var symbolColor = SerieHelper.GetItemColor(serie, serieData, m_Theme, serie.index, highlight);
43 var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, m_Theme, serie.index, highlight);
44 var backgroundColor = SerieHelper.GetItemBackgroundColor(serie, serieData, m_Theme, serie.index, highlight,
false);
45 var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, m_Theme, highlight);
46 var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight);
47 symbolSize = serie.animation.GetSysmbolSize(symbolSize);
48 Internal_CheckClipAndDrawSymbol(vh, symbol.type, symbolSize, symbolBorder, serie.dataPoints[i], symbolColor,
49 symbolToColor, backgroundColor, symbol.gap, clip, cornerRadius,
grid,
50 i > 0 ? serie.dataPoints[i - 1] :
grid.runtimePosition);
54 protected void DrawLineArrow(VertexHelper vh, Serie serie)
57 if (!serie.show || !serie.lineArrow.show)
return;
58 if (serie.dataPoints.Count < 2)
return;
59 Color32 lineColor = SerieHelper.GetLineColor(serie, m_Theme, serie.index,
false);
60 Vector3 startPos, arrowPos;
61 var lineArrow = serie.lineArrow.arrow;
62 switch (serie.lineArrow.position)
64 case LineArrow.Position.End:
65 var dataPoints = serie.GetUpSmoothList(serie.dataCount - 1);
66 if (dataPoints.Count < 3)
68 dataPoints = serie.dataPoints;
69 startPos = dataPoints[dataPoints.Count - 2];
70 arrowPos = dataPoints[dataPoints.Count - 1];
74 startPos = dataPoints[dataPoints.Count - 3];
75 arrowPos = dataPoints[dataPoints.Count - 2];
77 UGL.DrawArrow(vh, startPos, arrowPos, lineArrow.width, lineArrow.height,
78 lineArrow.offset, lineArrow.dent, lineArrow.GetColor(lineColor));
80 case LineArrow.Position.Start:
81 dataPoints = serie.GetUpSmoothList(1);
82 if (dataPoints.Count < 2) dataPoints = serie.dataPoints;
83 startPos = dataPoints[1];
84 arrowPos = dataPoints[0];
85 UGL.DrawArrow(vh, startPos, arrowPos, lineArrow.width, lineArrow.height,
86 lineArrow.offset, lineArrow.dent, lineArrow.GetColor(lineColor));
91 protected void DrawXLineSerie(VertexHelper vh, Serie serie,
int colorIndex)
93 if (!IsActive(serie.index))
return;
94 if (serie.animation.HasFadeOut())
return;
95 var yAxis = GetSerieYAxisOrDefault(serie);
96 var xAxis = GetSerieXAxisOrDefault(serie);
97 var
grid = GetSerieGridOrDefault(serie);
98 var dataZoom = DataZoomHelper.GetAxisRelatedDataZoom(xAxis, dataZooms);
99 var showData = serie.GetDataList(dataZoom);
100 if (showData.Count <= 0)
return;
101 Color32 lineColor = SerieHelper.GetLineColor(serie, m_Theme, colorIndex, serie.highlighted);
102 Color32 srcAreaColor = SerieHelper.GetAreaColor(serie, m_Theme, colorIndex,
false);
103 Color32 srcAreaToColor = SerieHelper.GetAreaToColor(serie, m_Theme, colorIndex,
false);
104 Color32 highlightAreaColor = SerieHelper.GetAreaColor(serie, m_Theme, colorIndex,
true);
105 Color32 highlightAreaToColor = SerieHelper.GetAreaToColor(serie, m_Theme, colorIndex,
true);
106 Color32 areaColor, areaToColor;
107 Vector3 lp = Vector3.zero, np = Vector3.zero, llp = Vector3.zero, nnp = Vector3.zero;
108 var zeroPos =
new Vector3(
grid.runtimeX,
grid.runtimeY + yAxis.runtimeZeroYOffset);
109 var isStack = SeriesHelper.IsStack(m_Series, serie.stack,
SerieType.Line);
110 m_StackSerieData.Clear();
111 if (isStack) SeriesHelper.UpdateStackDataList(m_Series, serie, dataZoom, m_StackSerieData);
112 float scaleWid = AxisHelper.GetDataWidth(xAxis,
grid.runtimeWidth, showData.Count, dataZoom);
113 xAxis.runtimeScaleWidth = scaleWid;
114 float startX =
grid.runtimeX + (xAxis.boundaryGap ? scaleWid / 2 : 0);
115 int maxCount = serie.maxShow > 0 ?
116 (serie.maxShow > showData.Count ? showData.Count : serie.maxShow)
120 var sampleDist = serie.sampleDist;
121 if (sampleDist > 0) rate = (int)((maxCount - serie.minShow) / (
grid.runtimeWidth / sampleDist));
122 if (rate < 1) rate = 1;
123 var includeLastData =
false;
124 var totalAverage = serie.sampleAverage > 0 ? serie.sampleAverage :
125 DataAverage(ref showData, serie.sampleType, serie.minShow, maxCount, rate);
126 var dataChanging =
false;
127 var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
128 for (i = serie.minShow; i < maxCount; i += rate)
130 if (i == maxCount - 1) includeLastData =
true;
131 if (serie.IsIgnoreValue(showData[i]))
133 serie.dataPoints.Add(Vector3.zero);
134 showData[i].runtimeStackHig = 0;
138 double yValue = SampleValue(ref showData, serie.sampleType, rate, serie.minShow, maxCount, totalAverage,
139 i, dataChangeDuration, ref dataChanging, yAxis);
140 showData[i].runtimeStackHig = GetDataPoint(xAxis, yAxis, showData, yValue, startX, i, scaleWid, isStack,
141 ref np, dataChangeDuration);
142 serie.dataPoints.Add(np);
147 RefreshPainter(serie);
149 if (!includeLastData)
152 if (serie.IsIgnoreValue(showData[i]))
154 serie.dataPoints.Add(Vector3.zero);
155 showData[i].runtimeStackHig = 0;
159 double yValue = showData[i].GetCurrData(1, dataChangeDuration, yAxis.inverse, yAxis.runtimeMinValue, yAxis.runtimeMaxValue);
160 showData[i].runtimeStackHig = GetDataPoint(xAxis, yAxis, showData, yValue, startX, i, scaleWid, isStack, ref np,
162 serie.dataPoints.Add(np);
165 if (serie.dataPoints.Count <= 0)
170 var endIndex = serie.dataPoints.Count;
171 var startPos = GetStartPos(serie.dataPoints, ref startIndex, serie.ignoreLineBreak);
172 var endPos = GetEndPos(serie.dataPoints, ref endIndex, serie.ignoreLineBreak);
174 stPos1 = stPos2 = lastDir = lastDnPos = Vector3.zero;
175 smoothStartPosUp = smoothStartPosDn = Vector3.zero;
177 Vector3 firstLastPos = Vector3.zero, lastNextPos = Vector3.zero;
178 if (serie.minShow > 0 && serie.minShow < showData.Count)
180 i = serie.minShow - 1;
181 if (serie.IsIgnoreValue(showData[i]))
183 serie.dataPoints.Add(Vector3.zero);
184 showData[i].runtimeStackHig = 0;
188 double yValue = showData[i].GetCurrData(1, dataChangeDuration, yAxis.inverse, yAxis.runtimeMinValue, yAxis.runtimeMaxValue);
189 showData[i].runtimeStackHig = GetDataPoint(xAxis, yAxis, showData, yValue, startX, i, scaleWid, isStack, ref firstLastPos, dataChangeDuration);
196 if (serie.maxShow > 0 && serie.maxShow < showData.Count)
199 if (serie.IsIgnoreValue(showData[i]))
201 serie.dataPoints.Add(Vector3.zero);
202 showData[i].runtimeStackHig = 0;
206 double yValue = showData[i].GetCurrData(1, dataChangeDuration, yAxis.inverse, yAxis.runtimeMinValue, yAxis.runtimeMaxValue);
207 showData[i].runtimeStackHig = GetDataPoint(xAxis, yAxis, showData, yValue, startX, i, scaleWid, isStack, ref lastNextPos, dataChangeDuration);
212 lastNextPos = endPos;
214 VisualMapHelper.AutoSetLineMinMax(visualMap, serie, xAxis, yAxis);
216 float currDetailProgress = lp.x;
217 float totalDetailProgress = endPos.x;
218 if (serie.animation.alongWithLinePath)
220 currDetailProgress = 0;
221 totalDetailProgress = 0;
222 var tempLp = startPos;
223 for (i = startIndex + 1; i < serie.dataPoints.Count; i++)
225 np = serie.dataPoints[i];
226 if (np != Vector3.zero)
228 totalDetailProgress += Vector3.Distance(np, tempLp);
232 serie.animation.SetLinePathStartPos(startPos);
234 serie.animation.InitProgress(serie.dataPoints.Count, currDetailProgress, totalDetailProgress);
235 serie.animation.SetDataFinish(startIndex);
236 for (i = startIndex + 1; i < serie.dataPoints.Count; i++)
238 np = serie.dataPoints[i];
239 serie.ClearSmoothList(i);
240 var isIgnoreBreak =
false;
241 if (np == Vector3.zero)
243 if (serie.ignoreLineBreak)
244 isIgnoreBreak =
true;
247 serie.animation.SetDataFinish(i);
251 if (!serie.animation.NeedAnimation(i))
break;
252 bool isFinish =
true;
253 if (serie.areaStyle.tooltipHighlight && tooltip.show && i <= tooltip.runtimeDataIndex[0])
255 areaColor = highlightAreaColor;
256 areaToColor = highlightAreaToColor;
260 areaColor = srcAreaColor;
261 areaToColor = srcAreaToColor;
263 switch (serie.lineType)
266 lp = GetLastPos(serie.dataPoints, i, np, serie.ignoreLineBreak);
267 nnp = GetNNPos(serie.dataPoints, i, np, serie.ignoreLineBreak);
268 if (lp == Vector3.zero && serie.ignoreLineBreak) isIgnoreBreak =
true;
269 isFinish = DrawNormalLine(vh, serie, xAxis, lp, np, nnp, i,
270 isIgnoreBreak ? ColorUtil.clearColor32 : lineColor,
271 isIgnoreBreak ? ColorUtil.clearColor32 : areaColor,
272 isIgnoreBreak ? ColorUtil.clearColor32 : areaToColor,
273 zeroPos, startIndex);
277 llp = GetLLPos(serie.dataPoints, i, firstLastPos, serie.ignoreLineBreak);
278 nnp = GetNNPos(serie.dataPoints, i, lastNextPos, serie.ignoreLineBreak);
279 if (lp == Vector3.zero && serie.ignoreLineBreak) isIgnoreBreak =
true;
280 isFinish = DrawSmoothLine(vh, serie, xAxis, lp, np, llp, nnp, i,
281 isIgnoreBreak ? ColorUtil.clearColor32 : lineColor,
282 isIgnoreBreak ? ColorUtil.clearColor32 : areaColor,
283 isIgnoreBreak ? ColorUtil.clearColor32 : areaToColor,
284 isStack, zeroPos, startIndex);
289 nnp = GetNNPos(serie.dataPoints, i, np, serie.ignoreLineBreak);
290 if (lp == Vector3.zero && serie.ignoreLineBreak) isIgnoreBreak =
true;
291 isFinish = DrawStepLine(vh, serie, xAxis, lp, np, nnp, i,
292 isIgnoreBreak ? ColorUtil.clearColor32 : lineColor,
293 isIgnoreBreak ? ColorUtil.clearColor32 : areaColor,
294 isIgnoreBreak ? ColorUtil.clearColor32 : areaToColor,
301 if (lp == Vector3.zero && serie.ignoreLineBreak) isIgnoreBreak =
true;
302 DrawOtherLine(vh, serie, xAxis, lp, np, i,
303 isIgnoreBreak ? ColorUtil.clearColor32 : lineColor,
304 isIgnoreBreak ? ColorUtil.clearColor32 : areaColor,
305 isIgnoreBreak ? ColorUtil.clearColor32 : areaToColor,
309 if (isFinish) serie.animation.SetDataFinish(i);
310 if (np != Vector3.zero || serie.ignoreLineBreak)
315 if (!serie.animation.IsFinish())
317 serie.animation.CheckProgress(totalDetailProgress - currDetailProgress);
318 serie.animation.CheckSymbol(serie.symbol.GetSize(
null, m_Theme.serie.lineSymbolSize));
319 m_IsPlayingAnimation =
true;
320 RefreshPainter(serie);
324 private Vector3 GetNNPos(List<Vector3> dataPoints,
int index, Vector3 np,
bool ignoreLineBreak)
326 int size = dataPoints.Count;
327 if (index >= size)
return np;
328 for (
int i = index + 1; i < size; i++)
330 if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
return dataPoints[i];
335 private Vector3 GetStartPos(List<Vector3> dataPoints, ref
int start,
bool ignoreLineBreak)
337 for (
int i = 0; i < dataPoints.Count; i++)
339 if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
342 return dataPoints[i];
348 private Vector3 GetEndPos(List<Vector3> dataPoints, ref
int end,
bool ignoreLineBreak)
350 for (
int i = dataPoints.Count - 1; i >= 0; i--)
352 if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
355 return dataPoints[i];
361 private Vector3 GetLastPos(List<Vector3> dataPoints,
int index, Vector3 pos,
bool ignoreLineBreak)
363 if (index <= 0)
return pos;
364 for (
int i = index - 1; i >= 0; i--)
366 if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
return dataPoints[i];
371 private Vector3 GetLLPos(List<Vector3> dataPoints,
int index, Vector3 lp,
bool ignoreLineBreak)
373 if (index <= 1)
return lp;
374 for (
int i = index - 2; i >= 0; i--)
376 if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
return dataPoints[i];
381 internal double DataAverage(ref List<SerieData> showData,
SampleType sampleType,
int minCount,
int maxCount,
int rate)
383 double totalAverage = 0;
384 if (rate > 1 && sampleType ==
SampleType.Peak)
387 for (
int i = minCount; i < maxCount; i++)
389 total += showData[i].data[1];
391 totalAverage = total / (maxCount - minCount);
396 internal double SampleValue(ref List<SerieData> showData,
SampleType sampleType,
int rate,
397 int minCount,
int maxCount,
double totalAverage,
int index,
float dataChangeDuration,
398 ref
bool dataChanging, Axis axis)
400 var inverse = axis.inverse;
401 double minValue = axis.runtimeMinValue;
402 double MaxValue = axis.runtimeMaxValue;
403 if (rate <= 1 || index == minCount)
405 if (showData[index].IsDataChanged()) dataChanging =
true;
406 return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
413 for (
int i = index; i > index - rate; i--)
415 total += showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
416 if (showData[i].IsDataChanged()) dataChanging =
true;
418 if (sampleType ==
SampleType.Average)
return total / rate;
421 double max =
double.MinValue;
422 for (
int i = index; i > index - rate; i--)
424 var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
425 if (value > max) max = value;
426 if (showData[i].IsDataChanged()) dataChanging =
true;
430 double min =
double.MaxValue;
431 for (
int i = index; i > index - rate; i--)
433 var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
434 if (value < min) min = value;
435 if (showData[i].IsDataChanged()) dataChanging =
true;
439 max =
double.MinValue;
440 min =
double.MaxValue;
442 for (
int i = index; i > index - rate; i--)
444 var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
446 if (value < min) min = value;
447 if (value > max) max = value;
448 if (showData[i].IsDataChanged()) dataChanging =
true;
450 var average = total / rate;
451 if (average >= totalAverage)
return max;
454 if (showData[index].IsDataChanged()) dataChanging =
true;
455 return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
458 private float GetDataPoint(Axis xAxis, Axis yAxis, List<SerieData> showData,
double yValue,
float startX,
int i,
459 float scaleWid,
bool isStack, ref Vector3 np,
float duration,
bool isIngoreValue =
false)
466 float xDataHig, yDataHig;
467 double xMinValue = xAxis.GetCurrMinValue(duration);
468 double xMaxValue = xAxis.GetCurrMaxValue(duration);
469 double yMinValue = yAxis.GetCurrMinValue(duration);
470 double yMaxValue = yAxis.GetCurrMaxValue(duration);
471 if (xAxis.IsValue() || xAxis.IsLog())
473 var
grid = GetAxisGridOrDefault(xAxis);
474 var axisLineWidth = xAxis.axisLine.GetWidth(m_Theme.axis.lineWidth);
475 double xValue = i > showData.Count - 1 ? 0 : showData[i].GetData(0, xAxis.inverse);
476 float pX =
grid.runtimeX + axisLineWidth;
477 float pY =
grid.runtimeY + axisLineWidth;
480 for (
int n = 0; n < m_StackSerieData.Count - 1; n++)
482 pY += m_StackSerieData[n][i].runtimeStackHig;
487 int minIndex = xAxis.runtimeMinLogIndex;
488 float nowIndex = xAxis.GetLogValue(xValue);
489 xDataHig = (nowIndex - minIndex) / xAxis.splitNumber *
grid.runtimeWidth;
493 if ((xMaxValue - xMinValue) <= 0) xDataHig = 0;
494 else xDataHig = (float)((xValue - xMinValue) / (xMaxValue - xMinValue)) *
grid.runtimeWidth;
498 int minIndex = yAxis.runtimeMinLogIndex;
499 float nowIndex = yAxis.GetLogValue(yValue);
500 yDataHig = (nowIndex - minIndex) / yAxis.splitNumber *
grid.runtimeHeight;
504 double valueTotal = yMaxValue - yMinValue;
505 if (valueTotal <= 0) yDataHig = 0;
506 else yDataHig = (float)((yValue - yMinValue) / valueTotal) *
grid.runtimeHeight;
508 np =
new Vector3(pX + xDataHig, pY + yDataHig);
512 var
grid = GetAxisGridOrDefault(yAxis);
513 var axisLineWidth = yAxis.axisLine.GetWidth(m_Theme.axis.lineWidth);
514 float pX = startX + i * scaleWid;
515 float pY =
grid.runtimeY + axisLineWidth;
518 for (
int n = 0; n < m_StackSerieData.Count - 1; n++)
520 pY += m_StackSerieData[n][i].runtimeStackHig;
525 int minIndex = yAxis.runtimeMinLogIndex;
526 float nowIndex = yAxis.GetLogValue(yValue);
527 yDataHig = (nowIndex - minIndex) / yAxis.splitNumber *
grid.runtimeHeight;
531 double valueTotal = yMaxValue - yMinValue;
532 if (valueTotal <= 0) yDataHig = 0;
533 else yDataHig = (float)((yValue - yMinValue) / valueTotal *
grid.runtimeHeight);
535 np =
new Vector3(pX, pY + yDataHig);
540 List<List<SerieData>> m_StackSerieData =
new List<List<SerieData>>();
541 protected void DrawYLineSerie(VertexHelper vh, Serie serie,
int colorIndex)
543 if (!IsActive(serie.index))
return;
544 if (serie.animation.HasFadeOut())
return;
545 Vector3 lp = Vector3.zero;
546 Vector3 np = Vector3.zero;
547 Vector3 llp = Vector3.zero;
548 Vector3 nnp = Vector3.zero;
549 var lineColor = SerieHelper.GetLineColor(serie, m_Theme, colorIndex, serie.highlighted);
550 var srcAreaColor = SerieHelper.GetAreaColor(serie, m_Theme, colorIndex,
false);
551 var srcAreaToColor = SerieHelper.GetAreaToColor(serie, m_Theme, colorIndex,
false);
552 var highlightAreaColor = SerieHelper.GetAreaColor(serie, m_Theme, colorIndex,
true);
553 var highlightAreaToColor = SerieHelper.GetAreaToColor(serie, m_Theme, colorIndex,
true);
554 Color32 areaColor, areaToColor;
555 var xAxis = m_XAxes[serie.xAxisIndex];
556 var yAxis = m_YAxes[serie.yAxisIndex];
557 var
grid = GetSerieGridOrDefault(serie);
558 var dataZoom = DataZoomHelper.GetAxisRelatedDataZoom(yAxis, dataZooms);
559 var showData = serie.GetDataList(dataZoom);
560 var zeroPos =
new Vector3(
grid.runtimeX + xAxis.runtimeZeroXOffset,
grid.runtimeY);
561 var isStack = SeriesHelper.IsStack(m_Series, serie.stack,
SerieType.Line);
562 m_StackSerieData.Clear();
563 if (isStack) SeriesHelper.UpdateStackDataList(m_Series, serie, dataZoom, m_StackSerieData);
564 if (!yAxis.show) yAxis = m_YAxes[(serie.yAxisIndex + 1) % m_YAxes.Count];
565 float scaleWid = AxisHelper.GetDataWidth(yAxis,
grid.runtimeHeight, showData.Count, dataZoom);
566 float startY =
grid.runtimeY + (yAxis.boundaryGap ? scaleWid / 2 : 0);
567 int maxCount = serie.maxShow > 0 ?
568 (serie.maxShow > showData.Count ? showData.Count : serie.maxShow)
572 var sampleDist = serie.sampleDist;
573 if (sampleDist > 0) rate = (int)((maxCount - serie.minShow) / (
grid.runtimeWidth / sampleDist));
574 if (rate < 1) rate = 1;
575 var dataChanging =
false;
576 float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
577 double xMinValue = xAxis.GetCurrMinValue(dataChangeDuration);
578 double xMaxValue = xAxis.GetCurrMaxValue(dataChangeDuration);
579 for (i = serie.minShow; i < maxCount; i += rate)
581 double value = showData[i].GetCurrData(1, dataChangeDuration, xAxis.inverse, xAxis.runtimeMinValue, xAxis.runtimeMaxValue);
582 float pY = startY + i * scaleWid;
583 float pX =
grid.runtimeX + yAxis.axisLine.GetWidth(m_Theme.axis.lineWidth);
586 for (
int n = 0; n < m_StackSerieData.Count - 1; n++)
588 pX += m_StackSerieData[n][i].runtimeStackHig;
594 int minIndex = xAxis.runtimeMinLogIndex;
595 float nowIndex = xAxis.GetLogValue(value);
596 dataHig = (nowIndex - minIndex) / (xAxis.splitNumber - 1) *
grid.runtimeWidth;
600 dataHig = (float)((value - xMinValue) / (xMaxValue - xMinValue) *
grid.runtimeWidth);
602 showData[i].runtimeStackHig = dataHig;
603 np =
new Vector3(pX + dataHig, pY);
604 serie.dataPoints.Add(np);
605 if (showData[i].IsDataChanged()) dataChanging =
true;
609 RefreshPainter(serie);
611 if (maxCount % rate != 0)
614 double value = showData[i].GetCurrData(1, dataChangeDuration, xAxis.inverse, xAxis.runtimeMinValue, xAxis.runtimeMaxValue);
615 float pY = startY + i * scaleWid;
616 float pX =
grid.runtimeX + yAxis.axisLine.GetWidth(m_Theme.axis.lineWidth);
619 for (
int n = 0; n < m_StackSerieData.Count - 1; n++)
621 pX += m_StackSerieData[n][i].runtimeStackHig;
627 int minIndex = xAxis.runtimeMinLogIndex;
628 float nowIndex = xAxis.GetLogValue(value);
629 dataHig = (nowIndex - minIndex) / xAxis.splitNumber *
grid.runtimeWidth;
633 dataHig = (float)((value - xMinValue) / (xMaxValue - xMinValue)) *
grid.runtimeWidth;
635 showData[i].runtimeStackHig = dataHig;
636 np =
new Vector3(pX + dataHig, pY);
637 serie.dataPoints.Add(np);
639 lp = serie.dataPoints[0];
640 int dataCount = serie.dataPoints.Count;
641 float currDetailProgress = lp.y;
642 float totalDetailProgress = serie.dataPoints[dataCount - 1].y;
643 serie.animation.InitProgress(dataCount, currDetailProgress, totalDetailProgress);
644 for (i = 1; i < serie.dataPoints.Count; i++)
646 np = serie.dataPoints[i];
647 serie.ClearSmoothList(i);
648 if (!serie.animation.NeedAnimation(i))
break;
649 bool isFinish =
true;
650 if (serie.areaStyle.tooltipHighlight && tooltip.show && i < tooltip.runtimeDataIndex[0])
652 areaColor = highlightAreaColor;
653 areaToColor = highlightAreaToColor;
657 areaColor = srcAreaColor;
658 areaToColor = srcAreaToColor;
660 switch (serie.lineType)
663 nnp = i < serie.dataPoints.Count - 1 ? serie.dataPoints[i + 1] : np;
664 isFinish = DrawNormalLine(vh, serie, yAxis, lp, np, nnp, i, lineColor,
665 areaColor, areaToColor, zeroPos, 0);
669 llp = i > 1 ? serie.dataPoints[i - 2] : lp;
670 nnp = i < serie.dataPoints.Count - 1 ? serie.dataPoints[i + 1] : np;
671 isFinish = DrawSmoothLine(vh, serie, yAxis, lp, np, llp, nnp, i,
672 lineColor, areaColor, areaToColor, isStack, zeroPos);
677 nnp = i < serie.dataPoints.Count - 1 ? serie.dataPoints[i + 1] : np;
678 isFinish = DrawStepLine(vh, serie, yAxis, lp, np, nnp, i, lineColor,
679 areaColor, areaToColor, zeroPos);
682 UGL.DrawDashLine(vh, lp, np, serie.lineStyle.GetWidth(m_Theme.serie.lineWidth), lineColor, lineColor);
686 UGL.DrawDotLine(vh, lp, np, serie.lineStyle.GetWidth(m_Theme.serie.lineWidth), lineColor, lineColor);
690 UGL.DrawDashDotLine(vh, lp, np, serie.lineStyle.GetWidth(m_Theme.serie.lineWidth), lineColor);
694 UGL.DrawDashDotDotLine(vh, lp, np, serie.lineStyle.GetWidth(m_Theme.serie.lineWidth), lineColor);
698 if (isFinish) serie.animation.SetDataFinish(i);
701 if (!serie.animation.IsFinish())
703 float total = totalDetailProgress - currDetailProgress - dataCount * serie.lineStyle.GetWidth(m_Theme.serie.lineWidth) * 0.5f;
704 serie.animation.CheckProgress(total);
705 serie.animation.CheckSymbol(serie.symbol.GetSize(
null, m_Theme.serie.lineSymbolSize));
706 m_IsPlayingAnimation =
true;
707 RefreshPainter(serie);
711 private double GetStackValue(List<List<SerieData>> stackDataList,
int dataIndex,
float dataChangeDuration, Axis xAxis)
714 foreach (var dataList
in stackDataList)
716 value += dataList[dataIndex].GetCurrData(1, dataChangeDuration, xAxis.inverse, xAxis.runtimeMinValue, xAxis.runtimeMaxValue);
721 private Vector3 stPos1, stPos2, lastDir, lastDnPos;
722 private bool lastIsDown;
723 private bool DrawNormalLine(VertexHelper vh, Serie serie, Axis axis, Vector3 lp, Vector3 np, Vector3 nnp,
724 int dataIndex, Color32 lineColor, Color32 areaColor, Color32 areaToColor,
725 Vector3 zeroPos,
int startIndex)
727 var defaultLineColor = lineColor;
728 var isSecond = dataIndex == startIndex + 1;
729 var isTheLastPos = np == nnp;
730 bool isYAxis = axis is YAxis;
731 var isTurnBack = IsInRightOrUp(isYAxis, np, lp);
732 var lineWidth = serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
733 var
grid = GetSerieGridOrDefault(serie);
735 Vector3 dnPos, upPos1, upPos2, dir1v, dir2v;
737 var dir1 = (np - lp).normalized;
738 dir1v = Vector3.Cross(dir1, Vector3.forward).normalized * (isYAxis ? -1 : 1);
741 var dir2 = (nnp - np).normalized;
742 var dir3 = (dir1 + dir2).normalized;
743 var normal = Vector3.Cross(dir1, dir2);
744 isDown = isYAxis ? normal.z >= 0 : normal.z <= 0;
745 var angle = (180 - Vector3.Angle(dir1, dir2)) * Mathf.Deg2Rad / 2;
746 var diff = serie.lineStyle.GetWidth(m_Theme.serie.lineWidth) / Mathf.Sin(angle);
747 var dirDp = Vector3.Cross(dir3, Vector3.forward).normalized * (isYAxis ? -1 : 1);
748 dir2v = Vector3.Cross(dir2, Vector3.forward).normalized * (isYAxis ? -1 : 1);
749 dnPos = np + (isDown ? dirDp : -dirDp) * diff;
750 upPos1 = np + (isDown ? -dir1v : dir1v) * serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
751 upPos2 = np + (isDown ? -dir2v : dir2v) * serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
755 if (isYAxis && dnPos.x < lp.x && dnPos.x < nnp.x) dnPos.x = lp.x;
756 if (!isYAxis && dnPos.y < lp.y && dnPos.y < nnp.y) dnPos.y = lp.y;
760 if (isYAxis && dnPos.x > lp.x && dnPos.x > nnp.x) dnPos.x = lp.x;
761 if (!isYAxis && dnPos.y > lp.y && dnPos.y > nnp.y) dnPos.y = lp.y;
766 isDown = Vector3.Cross(dir1, lastDir).z <= 0;
767 if (isYAxis) isDown = !isDown;
768 dir1v = Vector3.Cross(dir1, Vector3.forward).normalized * (isYAxis ? -1 : 1);
769 upPos1 = np - dir1v * serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
770 upPos2 = np + dir1v * serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
771 dnPos = isDown ? upPos2 : upPos1;
776 stPos1 = lp - dir1v * serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
777 stPos2 = lp + dir1v * serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
779 var smoothPoints = serie.GetUpSmoothList(dataIndex);
780 var smoothDownPoints = serie.GetDownSmoothList(dataIndex);
781 var dist = Vector3.Distance(lp, np);
782 var lastSmoothPoint = Vector3.zero;
783 var lastSmoothDownPoint = Vector3.zero;
784 int segment = (int)(dist / settings.lineSegmentDistance);
785 if (segment <= 3) segment = (int)(dist / lineWidth);
786 if (segment < 2) segment = 2;
787 if (dataIndex > startIndex)
789 lastSmoothPoint = ChartHelper.GetLastPoint(serie.GetUpSmoothList(dataIndex - 1));
790 lastSmoothDownPoint = ChartHelper.GetLastPoint(serie.GetDownSmoothList(dataIndex - 1));
792 smoothPoints.Clear();
793 smoothDownPoints.Clear();
794 if (!TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, stPos1,
false))
796 smoothPoints.Add(lastSmoothPoint);
798 if (!TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, stPos2,
false))
800 smoothDownPoints.Add(lastSmoothDownPoint);
803 Vector3 ltp1 = stPos1, ltp2 = stPos2;
804 bool isBreak =
false;
805 bool isStart =
false;
806 bool isShort =
false;
807 for (
int i = 1; i < segment; i++)
809 var isEndPos = i == segment - 1;
810 var cp = lp + dir1 * (dist * i / segment);
811 if (serie.animation.CheckDetailBreak(cp, isYAxis)) isBreak =
true;
812 var tp1 = cp - dir1v * serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
813 var tp2 = cp + dir1v * serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
814 CheckLineGradientColor(cp, serie.lineStyle, axis, defaultLineColor, ref lineColor);
825 Internal_CheckClipAndDrawPolygon(vh, stPos1, upPos1, upPos2, stPos2, lineColor, serie.clip,
grid);
826 Internal_CheckClipAndDrawTriangle(vh, stPos2, upPos2, dnPos, lineColor, serie.clip,
grid);
827 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, stPos1, isEndPos);
828 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, upPos1, isEndPos);
829 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, dnPos, isEndPos);
831 else if (isSecond || isTurnBack ||
832 (lastIsDown && IsInRightOrUp(isYAxis, lastDnPos, tp2)) ||
833 (!lastIsDown && IsInRightOrUp(isYAxis, lastDnPos, tp1)))
836 if (stPos1 != Vector3.zero && stPos2 != Vector3.zero)
837 Internal_CheckClipAndDrawPolygon(vh, stPos1, tp1, tp2, stPos2, lineColor, serie.clip,
grid);
846 Internal_CheckClipAndDrawPolygon(vh, ltp1, upPos1, dnPos, ltp2, lineColor, serie.clip,
grid);
847 Internal_CheckClipAndDrawTriangle(vh, upPos1, upPos2, dnPos, lineColor, serie.clip,
grid);
851 Internal_CheckClipAndDrawPolygon(vh, ltp1, upPos1, upPos2, ltp2, lineColor, serie.clip,
grid);
856 if (IsInRightOrUp(isYAxis, tp2, dnPos) || isTurnBack)
858 Internal_CheckClipAndDrawLine(vh, start, cp, serie.lineStyle.GetWidth(m_Theme.serie.lineWidth), lineColor, serie.clip,
grid);
862 Internal_CheckClipAndDrawPolygon(vh, ltp1, upPos1, dnPos, ltp2, lineColor, serie.clip,
grid);
863 Internal_CheckClipAndDrawTriangle(vh, upPos1, upPos2, dnPos, lineColor, serie.clip,
grid);
872 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, tp1, isEndPos);
873 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, tp2, isEndPos);
887 Internal_CheckClipAndDrawPolygon(vh, stPos1, dnPos, upPos2, stPos2, lineColor, serie.clip,
grid);
890 Internal_CheckClipAndDrawPolygon(vh, stPos1, dnPos, upPos1, stPos2, lineColor, serie.clip,
grid);
891 Internal_CheckClipAndDrawTriangle(vh, dnPos, upPos1, upPos2, lineColor, serie.clip,
grid);
893 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, dnPos, isEndPos);
894 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, stPos2, isEndPos);
895 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos2, isEndPos);
897 else if (isSecond || isTurnBack ||
898 (lastIsDown && IsInRightOrUp(isYAxis, lastDnPos, tp2)) ||
899 (!lastIsDown && IsInRightOrUp(isYAxis, lastDnPos, tp1)))
902 if (stPos2 != Vector3.zero)
904 Internal_CheckClipAndDrawPolygon(vh, stPos1, tp1, tp2, stPos2, lineColor, serie.clip,
grid);
914 Internal_CheckClipAndDrawPolygon(vh, ltp1, dnPos, upPos1, ltp2, lineColor, serie.clip,
grid);
915 Internal_CheckClipAndDrawTriangle(vh, dnPos, upPos2, upPos1, lineColor, serie.clip,
grid);
917 else Internal_CheckClipAndDrawPolygon(vh, ltp1, upPos1, upPos2, ltp2, lineColor, serie.clip,
grid);
921 if (IsInRightOrUp(isYAxis, tp1, dnPos) || isTurnBack)
923 Internal_CheckClipAndDrawLine(vh, start, cp, serie.lineStyle.GetWidth(m_Theme.serie.lineWidth), lineColor, serie.clip,
grid);
927 Internal_CheckClipAndDrawPolygon(vh, ltp1, dnPos, upPos1, ltp2, lineColor, serie.clip,
grid);
928 Internal_CheckClipAndDrawTriangle(vh, dnPos, upPos2, upPos1, lineColor, serie.clip,
grid);
936 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, tp1, isEndPos);
937 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, tp2, isEndPos);
944 if (!isBreak && !isShort)
948 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, upPos1,
true);
949 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, upPos2,
true);
950 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, dnPos,
true);
954 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, dnPos,
true);
957 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, isTheLastPos ? upPos1 : upPos2,
true);
958 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, isTheLastPos ? upPos2 : upPos1,
true);
964 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos2,
true);
965 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos1,
true);
969 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos1,
true);
970 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos2,
true);
975 if (serie.areaStyle.show)
977 var lastSerie = SeriesHelper.GetLastStackSerie(m_Series, serie);
978 if (lastSerie !=
null)
980 var lastSmoothPoints = lastSerie.GetUpSmoothList(dataIndex);
981 DrawStackArea(vh, serie, axis, smoothDownPoints, lastSmoothPoints, areaColor, areaToColor);
985 var points = ((isYAxis && lp.x < zeroPos.x) || (!isYAxis && lp.y < zeroPos.y)) ? smoothPoints : smoothDownPoints;
986 Vector3 aep = isYAxis ?
new Vector3(zeroPos.x, zeroPos.y +
grid.runtimeHeight) : new Vector3(zeroPos.x +
grid.runtimeWidth, zeroPos.y);
989 var sp = GetStartPos(points, ref sindex, serie.ignoreLineBreak);
990 var ep = GetEndPos(points, ref eindex, serie.ignoreLineBreak);
991 var cross = ChartHelper.GetIntersection(lp, np, zeroPos, aep);
992 if (cross == Vector3.zero || smoothDownPoints.Count <= 3)
995 for (
int i = sindex + 1; i <= eindex; i++)
998 if (serie.animation.CheckDetailBreak(ep, isYAxis))
break;
999 DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero);
1005 var sp1 = smoothDownPoints[0];
1006 var ep1 = smoothDownPoints[smoothDownPoints.Count - 1];
1007 var axisLineWidth = axis.axisLine.GetWidth(m_Theme.axis.lineWidth);
1008 var axisUpStart = zeroPos + (isYAxis ? Vector3.right : Vector3.up) * axisLineWidth;
1009 var axisUpEnd = axisUpStart + (isYAxis ? Vector3.up *
grid.runtimeHeight : Vector3.right *
grid.runtimeWidth);
1010 var axisDownStart = zeroPos - (isYAxis ? Vector3.right : Vector3.up) * axisLineWidth;
1011 var axisDownEnd = axisDownStart + (isYAxis ? Vector3.up *
grid.runtimeHeight : Vector3.right *
grid.runtimeWidth);
1012 var luPos = ChartHelper.GetIntersection(sp1, ep1, axisUpStart, axisUpEnd);
1013 sp1 = smoothPoints[0];
1014 ep1 = smoothPoints[smoothPoints.Count - 2];
1015 var rdPos = ChartHelper.GetIntersection(sp1, ep1, axisDownStart, axisDownEnd);
1016 if ((isYAxis && lp.x >= zeroPos.x) || (!isYAxis && lp.y >= zeroPos.y))
1018 sp = smoothDownPoints[0];
1019 for (
int i = 1; i < smoothDownPoints.Count; i++)
1021 ep = smoothDownPoints[i];
1022 if (serie.animation.CheckDetailBreak(ep, isYAxis))
break;
1023 if (luPos == Vector3.zero)
1029 if ((isYAxis && ep.y > luPos.y) || (!isYAxis && ep.x > luPos.x))
1031 var tp = isYAxis ?
new Vector3(luPos.x, sp.y) : new Vector3(sp.x, luPos.y);
1032 Internal_CheckClipAndDrawTriangle(vh, sp, luPos, tp, areaColor, areaToColor, areaToColor, serie.clip,
grid);
1035 DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero);
1038 sp = smoothPoints[0];
1040 for (
int i = 1; i < smoothPoints.Count; i++)
1042 ep = smoothPoints[i];
1043 if (serie.animation.CheckDetailBreak(ep, isYAxis))
break;
1044 if ((isYAxis && ep.y <= rdPos.y) || (!isYAxis && ep.x <= rdPos.x))
continue;
1045 if (rdPos == Vector3.zero)
1053 var tp = isYAxis ?
new Vector3(rdPos.x, ep.y) : new Vector3(ep.x, rdPos.y);
1054 Internal_CheckClipAndDrawTriangle(vh, rdPos, tp, ep, areaToColor, areaToColor, areaColor, serie.clip,
grid);
1058 DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero);
1064 sp = smoothPoints[0];
1065 for (
int i = 1; i < smoothPoints.Count; i++)
1067 ep = smoothPoints[i];
1068 if (serie.animation.CheckDetailBreak(ep, isYAxis))
break;
1069 if (rdPos == Vector3.zero)
1075 if ((isYAxis && ep.y > rdPos.y) || (!isYAxis && ep.x > rdPos.x))
1077 var tp = isYAxis ?
new Vector3(rdPos.x, sp.y) : new Vector3(sp.x, rdPos.y);
1078 Internal_CheckClipAndDrawTriangle(vh, sp, rdPos, tp, areaColor, areaToColor, areaToColor, serie.clip,
grid);
1081 if (rdPos != Vector3.zero) DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero);
1084 sp = smoothDownPoints[0];
1086 for (
int i = 1; i < smoothDownPoints.Count; i++)
1088 ep = smoothDownPoints[i];
1089 if (serie.animation.CheckDetailBreak(ep, isYAxis))
break;
1090 if ((isYAxis && ep.y < luPos.y) || (!isYAxis && ep.x < luPos.x))
continue;
1091 if (luPos == Vector3.zero)
1099 var tp = isYAxis ?
new Vector3(luPos.x, ep.y) : new Vector3(ep.x, luPos.y);
1100 Internal_CheckClipAndDrawTriangle(vh, ep, luPos, tp, areaColor, areaToColor, areaToColor, serie.clip,
grid);
1104 DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero);
1111 stPos1 = isDown ? upPos2 : dnPos;
1112 stPos2 = isDown ? dnPos : upPos2;
1114 lastIsDown = isDown;
1118 private bool TryAddToList(
bool isTurnBack,
bool isYAxis, List<Vector3> list, Vector3 lastPos, Vector3 pos,
bool ignoreClose =
false)
1120 if (ChartHelper.IsZeroVector(pos))
return false;
1126 else if (!ChartHelper.IsZeroVector(lastPos) && IsInRightOrUpNotCheckZero(isYAxis, pos, lastPos))
1130 else if (list.Count <= 0)
1137 var end = list[list.Count - 1];
1138 if (IsInRightOrUpNotCheckZero(isYAxis, end, pos) && (!ignoreClose || !WasTooClose(isYAxis, end, pos, ignoreClose)))
1147 private void CheckLineGradientColor(Vector3 cp, LineStyle lineStyle, Axis axis, Color32 defaultLineColor, ref Color32 lineColor)
1149 if (VisualMapHelper.IsNeedGradient(visualMap))
1150 lineColor = VisualMapHelper.GetLineGradientColor(visualMap, cp,
this, axis, defaultLineColor);
1151 else if (lineStyle.IsNeedGradient())
1152 lineColor = VisualMapHelper.GetLineStyleGradientColor(lineStyle, cp,
this, axis, defaultLineColor);
1155 private bool IsInRightOrUp(
bool isYAxis, Vector3 lp, Vector3 rp)
1157 return ChartHelper.IsZeroVector(lp) || ((isYAxis && rp.y > lp.y) || (!isYAxis && rp.x > lp.x));
1160 private bool IsInRightOrUpNotCheckZero(
bool isYAxis, Vector3 lp, Vector3 rp)
1162 return (isYAxis && rp.y > lp.y) || (!isYAxis && rp.x > lp.x);
1165 private bool WasTooClose(
bool isYAxis, Vector3 lp, Vector3 rp,
bool ignore)
1167 if (ignore)
return false;
1168 if (lp == Vector3.zero || rp == Vector3.zero)
return false;
1169 if (isYAxis)
return Mathf.Abs(rp.y - lp.y) < 1f;
1170 else return Mathf.Abs(rp.x - lp.x) < 1f;
1173 private void DrawPolygonToZero(VertexHelper vh, Vector3 sp, Vector3 ep, Axis axis, Vector3 zeroPos,
1174 Color32 areaColor, Color32 areaToColor, Vector3 areaDiff,
bool clip =
false)
1177 var
grid = GetAxisGridOrDefault(axis);
1178 var lineWidth = axis.axisLine.GetWidth(m_Theme.axis.lineWidth);
1181 var isLessthan0 = (sp.x < zeroPos.x || ep.x < zeroPos.x);
1182 diff = isLessthan0 ? -lineWidth : lineWidth;
1183 areaColor = GetYLerpColor(areaColor, areaToColor, sp,
grid);
1184 if (isLessthan0) areaDiff = -areaDiff;
1185 Internal_CheckClipAndDrawPolygon(vh,
new Vector3(zeroPos.x + diff, sp.y),
new Vector3(zeroPos.x + diff, ep.y),
1186 ep + areaDiff, sp + areaDiff, areaToColor, areaColor, clip,
grid);
1190 var isLessthan0 = (sp.y < zeroPos.y || ep.y < zeroPos.y);
1191 diff = isLessthan0 ? -lineWidth : lineWidth;
1192 areaColor = GetXLerpColor(areaColor, areaToColor, sp,
grid);
1193 if (isLessthan0) areaDiff = -areaDiff;
1196 Internal_CheckClipAndDrawPolygon(vh, ep + areaDiff, sp + areaDiff,
new Vector3(sp.x, zeroPos.y + diff),
1197 new Vector3(ep.x, zeroPos.y + diff), areaColor, areaToColor, clip,
grid);
1201 Internal_CheckClipAndDrawPolygon(vh, sp + areaDiff, ep + areaDiff,
new Vector3(ep.x, zeroPos.y + diff),
1202 new Vector3(sp.x, zeroPos.y + diff), areaColor, areaToColor, clip,
grid);
1207 private List<Vector3> posList =
new List<Vector3>();
1208 private bool DrawOtherLine(VertexHelper vh, Serie serie, Axis axis, Vector3 lp,
1209 Vector3 np,
int dataIndex, Color32 lineColor, Color32 areaColor,
1210 Color32 areaToColor, Vector3 zeroPos)
1214 bool isYAxis = axis is YAxis;
1215 var lineWidth = serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
1217 switch (serie.lineType)
1220 UGL.DrawDashLine(vh, lp, np, lineWidth, lineColor, lineColor, 0, 0, posList);
1223 UGL.DrawDotLine(vh, lp, np, lineWidth, lineColor, lineColor, 0, 0, posList);
1226 UGL.DrawDashDotLine(vh, lp, np, lineWidth, lineColor, 0, 0, 0, posList);
1229 UGL.DrawDashDotDotLine(vh, lp, np, lineWidth, lineColor, 0, 0, 0, posList);
1232 if (serie.areaStyle.show && !isYAxis && posList.Count > 0)
1235 var value = serie.GetSerieData(dataIndex).data[1];
1236 for (
int i = 0; i < posList.Count; i++)
1239 var start =
new Vector3(lp.x, value > 0 ? (lp.y - lineWidth) : (lp.y + lineWidth));
1240 var end =
new Vector3(np.x, value > 0 ? (np.y - lineWidth) : (np.y + lineWidth));
1241 DrawPolygonToZero(vh, start, end, axis, zeroPos, areaColor, areaToColor, Vector3.zero);
1248 private List<Vector3> bezierPoints =
new List<Vector3>();
1249 private Vector3 smoothStartPosUp, smoothStartPosDn;
1250 private bool DrawSmoothLine(VertexHelper vh, Serie serie, Axis xAxis, Vector3 lp,
1251 Vector3 np, Vector3 llp, Vector3 nnp,
int dataIndex, Color32 lineColor, Color32 areaColor,
1252 Color32 areaToColor,
bool isStack, Vector3 zeroPos,
int startIndex = 0)
1254 var defaultLineColor = lineColor;
1255 bool isYAxis = xAxis is YAxis;
1256 var isTurnBack = IsInRightOrUp(isYAxis, np, lp);
1257 var lineWidth = serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
1258 var smoothPoints = serie.GetUpSmoothList(dataIndex);
1259 var smoothDownPoints = serie.GetDownSmoothList(dataIndex);
1260 var lastSmoothPoint = Vector3.zero;
1261 var lastSmoothDownPoint = Vector3.zero;
1262 var
grid = GetSerieGridOrDefault(serie);
1263 if (dataIndex > startIndex)
1265 lastSmoothPoint = ChartHelper.GetLastPoint(serie.GetUpSmoothList(dataIndex - 1));
1266 lastSmoothDownPoint = ChartHelper.GetLastPoint(serie.GetDownSmoothList(dataIndex - 1));
1267 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, lastSmoothPoint,
true);
1268 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, lastSmoothDownPoint,
true);
1270 if (isYAxis) ChartHelper.GetBezierListVertical(ref bezierPoints, lp, np, settings.lineSmoothness, settings.lineSmoothStyle);
1271 else ChartHelper.GetBezierList(ref bezierPoints, lp, np, llp, nnp, settings.lineSmoothness, settings.lineSmoothStyle);
1274 if (serie.lineType ==
LineType.SmoothDash)
1276 for (
int i = 0; i < bezierPoints.Count - 2; i += 2)
1278 start = bezierPoints[i];
1279 to = bezierPoints[i + 1];
1280 CheckLineGradientColor(start, serie.lineStyle, xAxis, defaultLineColor, ref lineColor);
1281 Internal_CheckClipAndDrawLine(vh, start, to, lineWidth, lineColor, serie.clip,
grid);
1285 start = bezierPoints[0];
1287 var dir = bezierPoints[1] - start;
1288 var dir1v = Vector3.Cross(dir, Vector3.forward).normalized * (isYAxis ? -1 : 1);
1289 var diff = dir1v * lineWidth;
1290 var startUp = start - diff;
1291 var startDn = start + diff;
1292 var startAreaDn = Vector3.zero;
1293 var startAreaUp = Vector3.zero;
1296 bool isFinish =
true;
1297 if (dataIndex > startIndex + 1)
1299 if (smoothStartPosDn != Vector3.zero && smoothStartPosUp != Vector3.zero)
1301 if (!serie.animation.IsInFadeOut())
1303 CheckLineGradientColor(lp, serie.lineStyle, xAxis, defaultLineColor, ref lineColor);
1304 Internal_CheckClipAndDrawTriangle(vh, smoothStartPosUp, startUp, lp, lineColor, serie.clip,
grid);
1305 Internal_CheckClipAndDrawTriangle(vh, smoothStartPosDn, startDn, lp, lineColor, serie.clip,
grid);
1306 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, smoothStartPosUp,
false);
1307 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, smoothStartPosDn,
false);
1313 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, startUp,
false);
1314 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, startDn,
false);
1316 var bezierPointsCount = bezierPoints.Count;
1317 for (
int k = 1; k < bezierPointsCount; k++)
1319 var isEndPos = k == bezierPointsCount - 1;
1320 to = bezierPoints[k];
1321 if (serie.animation.CheckDetailBreak(to, isYAxis))
1327 dir1v = Vector3.Cross(dir, Vector3.forward).normalized * (isYAxis ? -1 : 1);
1328 diff = dir1v * lineWidth;
1331 CheckLineGradientColor(to, serie.lineStyle, xAxis, defaultLineColor, ref lineColor);
1332 if (isYAxis) Internal_CheckClipAndDrawPolygon(vh, startDn, toDn, toUp, startUp, lineColor, serie.clip,
grid);
1333 else Internal_CheckClipAndDrawPolygon(vh, startUp, toUp, toDn, startDn, lineColor, serie.clip,
grid);
1334 TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, toUp,
true);
1335 TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, toDn,
true);
1338 smoothStartPosUp = toUp;
1339 smoothStartPosDn = toDn;
1345 if (serie.areaStyle.show && (serie.index == 0 || !isStack))
1347 if (smoothDownPoints.Count > 0)
1349 start = smoothDownPoints[0];
1350 for (
int i = 1; i < smoothDownPoints.Count; i++)
1352 to = smoothDownPoints[i];
1353 if (IsInRightOrUp(!isYAxis, zeroPos, to))
1355 DrawPolygonToZero(vh, start, to, xAxis, zeroPos, areaColor, areaToColor, Vector3.zero);
1360 if (smoothPoints.Count > 0)
1362 start = smoothPoints[smoothPoints.Count - 1];
1363 for (
int i = smoothPoints.Count - 1; i >= 0; i--)
1365 to = smoothPoints[i];
1366 if (!IsInRightOrUp(!isYAxis, zeroPos, to))
1368 DrawPolygonToZero(vh, to, start, xAxis, zeroPos, areaColor, areaToColor, Vector3.zero);
1375 if (serie.areaStyle.show)
1377 var lastSerie = SeriesHelper.GetLastStackSerie(m_Series, serie);
1378 if (lastSerie !=
null)
1380 var lastSmoothPoints = lastSerie.GetUpSmoothList(dataIndex);
1381 DrawStackArea(vh, serie, xAxis, smoothDownPoints, lastSmoothPoints, areaColor, areaToColor);
1387 private bool IsAllLessthen0(
bool isYAxis, Vector3 zeroPos, Vector3 start, Vector3 to)
1389 if (isYAxis)
return start.x < zeroPos.x && to.x < zeroPos.x;
1390 else return start.y < zeroPos.y && to.y < zeroPos.y;
1393 private Vector3 GetLastSmoothPos(List<Vector3> list,
bool isYAxis)
1395 var count = list.Count;
1396 if (count <= 0)
return Vector3.zero;
1397 var pos = list[count - 1];
1398 for (
int i = count - 2; i > count - 4 && i > 0; i--)
1402 if (list[i].y > pos.y) pos = list[i];
1406 if (list[i].x > pos.x) pos = list[i];
1412 private void DrawStackArea(VertexHelper vh, Serie serie, Axis axis, List<Vector3> smoothPoints,
1413 List<Vector3> lastSmoothPoints, Color32 areaColor, Color32 areaToColor)
1415 if (!serie.areaStyle.show || lastSmoothPoints.Count <= 0)
return;
1417 var isYAxis = axis is YAxis;
1420 start = smoothPoints[0];
1421 var sourAreaColor = areaColor;
1422 var
grid = GetAxisGridOrDefault(axis);
1423 for (
int k = 1; k < smoothPoints.Count; k++)
1425 to = smoothPoints[k];
1426 if (!IsInRightOrUp(isYAxis, start, to))
continue;
1427 if (serie.animation.CheckDetailBreak(to, isYAxis))
break;
1429 if (isYAxis) areaColor = GetYLerpColor(sourAreaColor, areaToColor, to,
grid);
1430 else areaColor = GetXLerpColor(sourAreaColor, areaToColor, to,
grid);
1431 if (k == smoothPoints.Count - 1)
1433 if (k < lastSmoothPoints.Count - 1)
1435 tnp = lastSmoothPoints[lastCount - 1];
1436 Internal_CheckClipAndDrawTriangle(vh, start, to, tnp, areaColor, areaColor, areaToColor, serie.clip,
grid);
1437 while (lastCount < lastSmoothPoints.Count)
1439 tlp = lastSmoothPoints[lastCount];
1440 if (serie.animation.CheckDetailBreak(tlp, isYAxis))
break;
1441 Internal_CheckClipAndDrawTriangle(vh, tnp, to, tlp, areaToColor, areaColor, areaToColor, serie.clip,
grid);
1449 if (lastCount >= lastSmoothPoints.Count)
1451 tlp = lastSmoothPoints[lastSmoothPoints.Count - 1];
1452 if (serie.animation.CheckDetailBreak(tlp, isYAxis))
break;
1453 Internal_CheckClipAndDrawTriangle(vh, to, start, tlp, areaColor, areaColor, areaToColor, serie.clip,
grid);
1457 tnp = lastSmoothPoints[lastCount];
1458 var diff = isYAxis ? tnp.y - to.y : tnp.x - to.x;
1459 if (Math.Abs(diff) < 1)
1461 tlp = lastSmoothPoints[lastCount - 1];
1462 if (serie.animation.CheckDetailBreak(tlp, isYAxis))
break;
1463 Internal_CheckClipAndDrawPolygon(vh, start, to, tnp, tlp, areaColor, areaToColor, serie.clip,
grid);
1470 tnp = lastSmoothPoints[lastCount - 1];
1471 Internal_CheckClipAndDrawTriangle(vh, start, to, tnp, areaColor, areaColor, areaToColor, serie.clip,
grid);
1472 while (diff < 0 && lastCount < lastSmoothPoints.Count)
1474 tlp = lastSmoothPoints[lastCount];
1475 if (serie.animation.CheckDetailBreak(tlp, isYAxis))
break;
1476 Internal_CheckClipAndDrawTriangle(vh, tnp, to, tlp, areaToColor, areaColor, areaToColor, serie.clip,
grid);
1478 diff = isYAxis ? tlp.y - to.y : tlp.x - to.x;
1484 tlp = lastSmoothPoints[lastCount - 1];
1485 if (serie.animation.CheckDetailBreak(tlp, isYAxis))
break;
1486 Internal_CheckClipAndDrawTriangle(vh, start, to, tlp, areaColor, areaColor, areaToColor, serie.clip,
grid);
1491 if (lastCount < lastSmoothPoints.Count)
1493 var p1 = lastSmoothPoints[lastCount - 1];
1494 var p2 = lastSmoothPoints[lastSmoothPoints.Count - 1];
1495 if (!serie.animation.CheckDetailBreak(p1, isYAxis) && !serie.animation.CheckDetailBreak(p2, isYAxis))
1497 Internal_CheckClipAndDrawTriangle(vh, p1, start, p2, areaToColor, areaColor, areaToColor, serie.clip,
grid);
1502 private List<Vector3> linePointList =
new List<Vector3>();
1503 private bool DrawStepLine(VertexHelper vh, Serie serie, Axis axis, Vector3 lp, Vector3 np,
1504 Vector3 nnp,
int dataIndex, Color32 lineColor, Color32 areaColor, Color32 areaToColor, Vector3 zeroPos)
1506 bool isYAxis = axis is YAxis;
1507 float lineWidth = serie.lineStyle.GetWidth(m_Theme.serie.lineWidth);
1508 Vector3 start, end, middle, middleZero, middle1, middle2;
1509 Vector3 sp, ep, diff1, diff2;
1510 var areaDiff = isYAxis ? Vector3.left * lineWidth : Vector3.down * lineWidth;
1511 var
grid = GetAxisGridOrDefault(axis);
1512 switch (serie.lineType)
1515 middle = isYAxis ?
new Vector3(np.x, lp.y) : new Vector3(lp.x, np.y);
1516 middleZero = isYAxis ?
new Vector3(zeroPos.x, middle.y) : new Vector3(middle.x, zeroPos.y);
1517 diff1 = (middle - lp).normalized * lineWidth;
1518 diff2 = (np - middle).normalized * lineWidth;
1519 start = dataIndex == 1 ? lp : lp + diff1;
1520 end = nnp != np ? np - diff2 : np;
1522 if (Vector3.Distance(lp, middle) > 2 * lineWidth)
1524 ChartHelper.GetPointList(ref linePointList, start, middle - diff1, settings.lineSegmentDistance);
1525 sp = linePointList[0];
1526 for (
int i = 1; i < linePointList.Count; i++)
1528 ep = linePointList[i];
1529 if (serie.animation.CheckDetailBreak(ep, isYAxis))
return false;
1530 Internal_CheckClipAndDrawLine(vh, sp, ep, lineWidth, lineColor, serie.clip,
grid);
1533 Internal_CheckClipAndDrawPolygon(vh, middle, lineWidth, lineColor, serie.clip,
true,
grid);
1537 if (dataIndex == 1) Internal_CheckClipAndDrawPolygon(vh, lp, lineWidth, lineColor, serie.clip,
true,
grid);
1538 Internal_CheckClipAndDrawLine(vh, lp + diff1, middle + diff1, lineWidth, lineColor, serie.clip,
grid);
1540 if (serie.areaStyle.show)
1542 if (Vector3.Dot(middle - lp, middleZero - middle) >= 0)
1544 DrawPolygonToZero(vh, middle - diff2, middle + diff2, axis, zeroPos, areaColor, areaToColor, areaDiff);
1546 else if (dataIndex == 1)
1548 DrawPolygonToZero(vh, lp - diff2, lp + diff2, axis, zeroPos, areaColor, areaToColor, Vector3.zero);
1552 ChartHelper.GetPointList(ref linePointList, middle + diff2, end, settings.lineSegmentDistance);
1553 sp = linePointList[0];
1554 for (
int i = 1; i < linePointList.Count; i++)
1556 ep = linePointList[i];
1557 if (serie.animation.CheckDetailBreak(ep, isYAxis))
return false;
1558 Internal_CheckClipAndDrawLine(vh, sp, ep, lineWidth, lineColor, serie.clip,
grid);
1559 if (serie.areaStyle.show)
1561 DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, areaDiff);
1568 if (serie.animation.CheckDetailBreak(np, isYAxis))
return false;
1569 Internal_CheckClipAndDrawPolygon(vh, np, lineWidth, lineColor, serie.clip,
true,
grid);
1570 bool flag = ((isYAxis && nnp.x > np.x && np.x > zeroPos.x) || (!isYAxis && nnp.y > np.y && np.y > zeroPos.y));
1571 if (serie.areaStyle.show && flag)
1573 DrawPolygonToZero(vh, np - diff2, np + diff2, axis, zeroPos, areaColor, areaToColor, areaDiff);
1578 middle1 = isYAxis ?
new Vector2(lp.x, (lp.y + np.y) / 2) : new Vector2((lp.x + np.x) / 2, lp.y);
1579 middle2 = isYAxis ?
new Vector2(np.x, (lp.y + np.y) / 2) : new Vector2((lp.x + np.x) / 2, np.y);
1580 middleZero = isYAxis ?
new Vector3(zeroPos.x, middle1.y) : new Vector3(middle1.x, zeroPos.y);
1581 diff1 = (middle1 - lp).normalized * lineWidth;
1582 diff2 = (middle2 - middle1).normalized * lineWidth;
1584 start = dataIndex == 1 ? lp : lp + diff1;
1585 end = nnp != np ? np - diff2 : np;
1587 if (Vector3.Distance(lp, middle1) > 2 * lineWidth)
1589 ChartHelper.GetPointList(ref linePointList, start, middle1 - diff1, settings.lineSegmentDistance);
1590 sp = linePointList[0];
1591 for (
int i = 1; i < linePointList.Count; i++)
1593 ep = linePointList[i];
1594 if (serie.animation.CheckDetailBreak(ep, isYAxis))
return false;
1595 Internal_CheckClipAndDrawLine(vh, sp, ep, lineWidth, lineColor, serie.clip,
grid);
1596 if (serie.areaStyle.show)
1598 DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, areaDiff);
1602 if (serie.animation.CheckDetailBreak(middle1, isYAxis))
return false;
1603 Internal_CheckClipAndDrawPolygon(vh, middle1, lineWidth, lineColor, serie.clip,
true,
grid);
1604 if (serie.areaStyle.show && Vector3.Dot(middleZero - middle1, middle2 - middle1) <= 0)
1606 DrawPolygonToZero(vh, middle1 - diff1, middle1 + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff);
1611 if (dataIndex == 1) Internal_CheckClipAndDrawPolygon(vh, lp, lineWidth, lineColor, serie.clip,
true,
grid);
1612 Internal_CheckClipAndDrawLine(vh, lp + diff1, middle1 + diff1, lineWidth, lineColor, serie.clip,
grid);
1616 if (Vector3.Distance(middle1, middle2) > 2 * lineWidth)
1618 ChartHelper.GetPointList(ref linePointList, middle1 + diff2, middle2 - diff2, settings.lineSegmentDistance);
1619 sp = linePointList[0];
1620 for (
int i = 1; i < linePointList.Count; i++)
1622 ep = linePointList[i];
1623 Internal_CheckClipAndDrawLine(vh, sp, ep, lineWidth, lineColor, serie.clip,
grid);
1626 Internal_CheckClipAndDrawPolygon(vh, middle2, lineWidth, lineColor, serie.clip,
true,
grid);
1627 if (serie.areaStyle.show && Vector3.Dot(middleZero - middle2, middle2 - middle1) >= 0)
1629 DrawPolygonToZero(vh, middle2 - diff1, middle2 + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff);
1634 Internal_CheckClipAndDrawLine(vh, middle1 + diff2, middle2 + diff2, lineWidth, lineColor, serie.clip,
grid);
1637 if (Vector3.Distance(middle2, np) > 2 * lineWidth)
1639 ChartHelper.GetPointList(ref linePointList, middle2 + diff1, np - diff1, settings.lineSegmentDistance);
1640 sp = linePointList[0];
1641 for (
int i = 1; i < linePointList.Count; i++)
1643 ep = linePointList[i];
1644 if (serie.animation.CheckDetailBreak(ep, isYAxis))
return false;
1645 Internal_CheckClipAndDrawLine(vh, sp, ep, lineWidth, lineColor, serie.clip,
grid);
1646 if (serie.areaStyle.show)
1648 DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, areaDiff);
1652 if (serie.animation.CheckDetailBreak(np, isYAxis))
return false;
1653 Internal_CheckClipAndDrawPolygon(vh, np, lineWidth, lineColor, serie.clip,
true,
grid);
1654 if (serie.areaStyle.show)
1656 DrawPolygonToZero(vh, np - diff1, np + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff);
1661 Internal_CheckClipAndDrawLine(vh, middle1 + diff1, middle1 + diff1, lineWidth, lineColor, serie.clip,
grid);
1665 middle = isYAxis ?
new Vector3(lp.x, np.y) : new Vector3(np.x, lp.y);
1666 middleZero = isYAxis ?
new Vector3(zeroPos.x, middle.y) : new Vector3(middle.x, zeroPos.y);
1667 diff1 = (middle - lp).normalized * lineWidth;
1668 diff2 = (np - middle).normalized * lineWidth;
1669 start = dataIndex == 1 ? lp : lp + diff1;
1670 end = nnp != np ? np - diff2 : np;
1672 if (Vector3.Distance(lp, middle) > 2 * lineWidth)
1674 ChartHelper.GetPointList(ref linePointList, start, middle - diff1, settings.lineSegmentDistance);
1675 sp = linePointList[0];
1676 for (
int i = 1; i < linePointList.Count; i++)
1678 ep = linePointList[i];
1679 if (serie.animation.CheckDetailBreak(ep, isYAxis))
return false;
1680 Internal_CheckClipAndDrawLine(vh, sp, ep, lineWidth, lineColor, serie.clip,
grid);
1681 if (serie.areaStyle.show)
1683 DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, areaDiff);
1687 if (serie.animation.CheckDetailBreak(middle, isYAxis))
return false;
1688 Internal_CheckClipAndDrawPolygon(vh, middle, lineWidth, lineColor, serie.clip,
true,
grid);
1689 if (serie.areaStyle.show && Vector3.Dot(np - middle, middleZero - middle) <= 0)
1691 DrawPolygonToZero(vh, middle - diff1, middle + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff);
1696 if (dataIndex == 1) Internal_CheckClipAndDrawPolygon(vh, lp, lineWidth, lineColor, serie.clip,
true,
grid);
1697 Internal_CheckClipAndDrawLine(vh, lp + diff1, middle + diff1, lineWidth, lineColor, serie.clip,
grid);
1700 if (Vector3.Distance(middle, np) > 2 * lineWidth)
1702 ChartHelper.GetPointList(ref linePointList, middle + diff2, end, settings.lineSegmentDistance);
1703 sp = linePointList[0];
1704 for (
int i = 1; i < linePointList.Count; i++)
1706 ep = linePointList[i];
1707 Internal_CheckClipAndDrawLine(vh, sp, ep, lineWidth, lineColor, serie.clip,
grid);
1710 if (nnp != np) Internal_CheckClipAndDrawPolygon(vh, np, lineWidth, lineColor, serie.clip,
true,
grid);
1714 Internal_CheckClipAndDrawLine(vh, middle + diff2, np + diff2, lineWidth, lineColor, serie.clip,
grid);
1716 bool flag2 = ((isYAxis && middle.x > np.x && np.x > zeroPos.x) || (!isYAxis && middle.y > np.y && np.y > zeroPos.y));
1717 if (serie.areaStyle.show && flag2)
1719 DrawPolygonToZero(vh, np - diff1, np + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff);