private void DrawYAxisIndicator(VertexHelper vh, Tooltip tooltip, GridCoord grid)
        {
            var yAxes     = chart.GetChartComponents <YAxis>();
            var lineType  = tooltip.lineStyle.GetType(chart.theme.tooltip.lineType);
            var lineWidth = tooltip.lineStyle.GetWidth(chart.theme.tooltip.lineWidth);

            foreach (var component in yAxes)
            {
                var yAxis = component as YAxis;
                if (yAxis.gridIndex == grid.index)
                {
                    if (double.IsInfinity(yAxis.context.pointerValue))
                    {
                        continue;
                    }
                    var   dataZoom   = chart.GetDataZoomOfAxis(yAxis);
                    int   dataCount  = chart.series.Count > 0 ? chart.series[0].GetDataList(dataZoom).Count : 0;
                    float splitWidth = AxisHelper.GetDataWidth(yAxis, grid.context.height, dataCount, dataZoom);
                    switch (tooltip.type)
                    {
                    case Tooltip.Type.Corss:
                    case Tooltip.Type.Line:
                        float pY = (float)(grid.context.y + yAxis.context.pointerValue * splitWidth +
                                           (yAxis.boundaryGap ? splitWidth / 2 : 0));
                        Vector2 sp        = new Vector2(grid.context.x, pY);
                        Vector2 ep        = new Vector2(grid.context.x + grid.context.width, pY);
                        var     lineColor = TooltipHelper.GetLineColor(tooltip, chart.theme);
                        ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
                        if (tooltip.type == Tooltip.Type.Corss)
                        {
                            sp = new Vector2(chart.pointerPos.x, grid.context.y);
                            ep = new Vector2(chart.pointerPos.x, grid.context.y + grid.context.height);
                            ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
                        }
                        break;

                    case Tooltip.Type.Shadow:
                        if (yAxis.IsCategory())
                        {
                            float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth;
                            float pX = grid.context.x + grid.context.width;
                            pY = (float)(grid.context.y + splitWidth * yAxis.context.pointerValue -
                                         (yAxis.boundaryGap ? 0 : splitWidth / 2));
                            Vector3 p1 = new Vector3(grid.context.x, pY);
                            Vector3 p2 = new Vector3(grid.context.x, pY + tooltipSplitWid);
                            Vector3 p3 = new Vector3(pX, pY + tooltipSplitWid);
                            Vector3 p4 = new Vector3(pX, pY);
                            UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, chart.theme.tooltip.areaColor);
                        }
                        break;
                    }
                }
            }
        }
        private void DrawPolygonRadar(VertexHelper vh, RadarCoord radar)
        {
            float   insideRadius = 0, outsideRadius = 0;
            float   block = radar.context.radius / radar.splitNumber;
            int     indicatorNum = radar.indicatorList.Count;
            Vector3 p1, p2, p3, p4;
            Vector3 p              = radar.context.center;
            float   angle          = 2 * Mathf.PI / indicatorNum;
            var     lineColor      = radar.axisLine.GetColor(chart.theme.axis.splitLineColor);
            var     lineWidth      = radar.axisLine.GetWidth(chart.theme.axis.lineWidth);
            var     lineType       = radar.axisLine.GetType(chart.theme.axis.lineType);
            var     splitLineColor = radar.splitLine.GetColor(chart.theme.axis.splitLineColor);
            var     splitLineWidth = radar.splitLine.GetWidth(chart.theme.axis.splitLineWidth);
            var     splitLineType  = radar.splitLine.GetType(chart.theme.axis.splitLineType);

            for (int i = 0; i < radar.splitNumber; i++)
            {
                var color = radar.splitArea.GetColor(i, chart.theme.axis);
                outsideRadius = insideRadius + block;
                p1            = new Vector3(p.x + insideRadius * Mathf.Sin(0), p.y + insideRadius * Mathf.Cos(0));
                p2            = new Vector3(p.x + outsideRadius * Mathf.Sin(0), p.y + outsideRadius * Mathf.Cos(0));
                for (int j = 0; j <= indicatorNum; j++)
                {
                    float currAngle = j * angle;
                    p3 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle),
                                     p.y + outsideRadius * Mathf.Cos(currAngle));
                    p4 = new Vector3(p.x + insideRadius * Mathf.Sin(currAngle),
                                     p.y + insideRadius * Mathf.Cos(currAngle));
                    if (radar.splitArea.show)
                    {
                        UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, color);
                    }
                    if (radar.splitLine.NeedShow(i))
                    {
                        ChartDrawer.DrawLineStyle(vh, splitLineType, splitLineWidth, p2, p3, splitLineColor);
                    }
                    p1 = p4;
                    p2 = p3;
                }
                insideRadius = outsideRadius;
            }
            if (radar.axisLine.show)
            {
                for (int j = 0; j <= indicatorNum; j++)
                {
                    float currAngle = j * angle;
                    p3 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle),
                                     p.y + outsideRadius * Mathf.Cos(currAngle));
                    ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, p, p3, lineColor);
                }
            }
        }
        public void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize, float tickness,
                               Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, Color32 borderColor,
                               float gap, float[] cornerRadius, Vector3 startPos)
        {
            var backgroundColor = GetChartBackgroundColor();

            if (ChartHelper.IsClearColor(emptyColor))
            {
                emptyColor = backgroundColor;
            }
            var smoothness = settings.cicleSmoothness;

            ChartDrawer.DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap,
                                   cornerRadius, emptyColor, backgroundColor, borderColor, smoothness, startPos);
        }
        private void DrawCricleRadar(VertexHelper vh, RadarCoord radar)
        {
            float   insideRadius = 0, outsideRadius = 0;
            float   block        = radar.context.radius / radar.splitNumber;
            int     indicatorNum = radar.indicatorList.Count;
            Vector3 p            = radar.context.center;
            Vector3 p1;
            float   angle          = 2 * Mathf.PI / indicatorNum;
            var     lineColor      = radar.axisLine.GetColor(chart.theme.axis.splitLineColor);
            var     lineWidth      = radar.axisLine.GetWidth(chart.theme.axis.lineWidth);
            var     lineType       = radar.axisLine.GetType(chart.theme.axis.lineType);
            var     splitLineColor = radar.splitLine.GetColor(chart.theme.axis.splitLineColor);
            var     splitLineWidth = radar.splitLine.GetWidth(chart.theme.axis.splitLineWidth);

            for (int i = 0; i < radar.splitNumber; i++)
            {
                var color = radar.splitArea.GetColor(i, chart.theme.axis);
                outsideRadius = insideRadius + block;
                if (radar.splitArea.show)
                {
                    UGL.DrawDoughnut(vh, p, insideRadius, outsideRadius, color, Color.clear,
                                     0, 360, chart.settings.cicleSmoothness);
                }
                if (radar.splitLine.show)
                {
                    UGL.DrawEmptyCricle(vh, p, outsideRadius, splitLineWidth, splitLineColor,
                                        Color.clear, chart.settings.cicleSmoothness);
                }
                insideRadius = outsideRadius;
            }
            if (radar.axisLine.show)
            {
                for (int j = 0; j <= indicatorNum; j++)
                {
                    float currAngle = j * angle;
                    p1 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle),
                                     p.y + outsideRadius * Mathf.Cos(currAngle));
                    ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, p, p1, lineColor);
                }
            }
        }
        private void DrawPolarIndicator(VertexHelper vh, Tooltip tooltip, PolarCoord m_Polar)
        {
            if (tooltip.context.angle < 0)
            {
                return;
            }
            var theme        = chart.theme;
            var m_AngleAxis  = ComponentHelper.GetAngleAxis(chart.components, m_Polar.index);
            var lineColor    = TooltipHelper.GetLineColor(tooltip, theme);
            var lineType     = tooltip.lineStyle.GetType(theme.tooltip.lineType);
            var lineWidth    = tooltip.lineStyle.GetWidth(theme.tooltip.lineWidth);
            var cenPos       = m_Polar.context.center;
            var radius       = m_Polar.context.radius;
            var sp           = m_Polar.context.center;
            var tooltipAngle = m_AngleAxis.GetValueAngle(tooltip.context.angle);

            var ep = ChartHelper.GetPos(sp, radius, tooltipAngle, true);

            switch (tooltip.type)
            {
            case Tooltip.Type.Corss:
                ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
                var dist = Vector2.Distance(chart.pointerPos, cenPos);
                if (dist > radius)
                {
                    dist = radius;
                }
                var outsideRaidus = dist + tooltip.lineStyle.GetWidth(theme.tooltip.lineWidth) * 2;
                UGL.DrawDoughnut(vh, cenPos, dist, outsideRaidus, lineColor, Color.clear);
                break;

            case Tooltip.Type.Line:
                ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
                break;

            case Tooltip.Type.Shadow:
                UGL.DrawSector(vh, cenPos, radius, lineColor, tooltipAngle - 2, tooltipAngle + 2, chart.settings.cicleSmoothness);
                break;
            }
        }
        private void DrawSingleRadar(VertexHelper vh)
        {
            var radar = chart.GetChartComponent <RadarCoord>(serie.radarIndex);

            if (radar == null)
            {
                return;
            }

            var indicatorNum = radar.indicatorList.Count;
            var angle        = 2 * Mathf.PI / indicatorNum;
            var centerPos    = radar.context.center;

            serie.animation.InitProgress(0, 1);
            serie.context.dataPoints.Clear();
            if (!serie.show || serie.animation.HasFadeOut())
            {
                return;
            }
            var startPoint = Vector3.zero;
            var toPoint    = Vector3.zero;
            var firstPoint = Vector3.zero;
            var lastColor  = ColorUtil.clearColor32;
            var firstColor = ColorUtil.clearColor32;

            var rate               = serie.animation.GetCurrRate();
            var dataChanging       = false;
            var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
            var startIndex         = GetStartShowIndex(serie);
            var endIndex           = GetEndShowIndex(serie);

            SerieHelper.UpdateMinMaxData(serie, 1, radar.ceilRate);
            for (int j = 0; j < serie.data.Count; j++)
            {
                var serieData = serie.data[j];
                serieData.index = j;
                string dataName = serieData.name;

                if (!serieData.show)
                {
                    serieData.context.labelPosition = Vector3.zero;
                    continue;
                }
                var lineStyle   = SerieHelper.GetLineStyle(serie, serieData);
                var areaStyle   = SerieHelper.GetAreaStyle(serie, serieData);
                var isHighlight = serie.context.pointerEnter;
                var areaColor   = SerieHelper.GetAreaColor(serie, serieData, chart.theme, j, isHighlight);
                var areaToColor = SerieHelper.GetAreaToColor(serie, serieData, chart.theme, j, isHighlight);
                var lineColor   = SerieHelper.GetLineColor(serie, serieData, chart.theme, j, isHighlight);
                int dataCount   = radar.indicatorList.Count;
                var index       = serieData.index;
                var p           = radar.context.center;
                var max         = radar.GetIndicatorMax(index);
                var value       = serieData.GetCurrData(1, dataChangeDuration);
                if (serieData.IsDataChanged())
                {
                    dataChanging = true;
                }
                if (max == 0)
                {
                    max = serie.context.dataMax;
                }
                if (!radar.IsInIndicatorRange(j, serieData.GetData(1)))
                {
                    lineColor = radar.outRangeColor;
                }
                var radius = (float)(max < 0 ? radar.context.dataRadius - radar.context.dataRadius * value / max :
                                     radar.context.dataRadius * value / max);
                var currAngle = (index + (radar.positionType == RadarCoord.PositionType.Between ? 0.5f : 0)) * angle;
                radius *= rate;
                if (index == startIndex)
                {
                    startPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle),
                                             p.y + radius * Mathf.Cos(currAngle));
                    firstPoint = startPoint;
                    lastColor  = lineColor;
                    firstColor = lineColor;
                }
                else
                {
                    toPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle),
                                          p.y + radius * Mathf.Cos(currAngle));
                    if (areaStyle != null && areaStyle.show)
                    {
                        UGL.DrawTriangle(vh, startPoint, toPoint, p, areaColor, areaColor, areaToColor);
                    }
                    if (lineStyle.show)
                    {
                        if (radar.connectCenter)
                        {
                            ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos,
                                                      chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor);
                        }
                        ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, toPoint, chart.theme.serie.lineWidth,
                                                  LineStyle.Type.Solid, radar.lineGradient ? lastColor : lineColor, lineColor);
                    }
                    startPoint = toPoint;
                    lastColor  = lineColor;
                }
                serieData.context.position      = startPoint;
                serieData.context.labelPosition = startPoint;

                if (areaStyle != null && areaStyle.show && j == endIndex)
                {
                    UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor);
                }
                if (lineStyle.show && j == endIndex)
                {
                    if (radar.connectCenter)
                    {
                        ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos,
                                                  chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor);
                    }
                    ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, firstPoint, chart.theme.serie.lineWidth,
                                              LineStyle.Type.Solid, lineColor, radar.lineGradient ? firstColor : lineColor);
                }
            }
            if (serie.symbol.show && serie.symbol.type != SymbolType.None)
            {
                for (int j = 0; j < serie.data.Count; j++)
                {
                    var serieData = serie.data[j];
                    if (!serieData.show)
                    {
                        continue;
                    }
                    var isHighlight = serie.highlight || serieData.context.highlight || serie.context.pointerEnter;
                    var serieIndex  = serieData.index;
                    var symbolSize  = isHighlight ?
                                      serie.symbol.GetSelectedSize(serieData.data, chart.theme.serie.lineSymbolSelectedSize) :
                                      serie.symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize);
                    var symbolColor      = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieIndex, isHighlight);
                    var symbolToColor    = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieIndex, isHighlight);
                    var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, serieIndex, isHighlight, false);
                    var symbolBorder     = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight);
                    var borderColor      = SerieHelper.GetSymbolBorderColor(serie, serieData, chart.theme, isHighlight);
                    var cornerRadius     = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight);
                    if (!radar.IsInIndicatorRange(j, serieData.GetData(1)))
                    {
                        symbolColor   = radar.outRangeColor;
                        symbolToColor = radar.outRangeColor;
                    }
                    chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, serieData.context.labelPosition, symbolColor,
                                     symbolToColor, symbolEmptyColor, borderColor, serie.symbol.gap, cornerRadius);
                }
            }
            if (!serie.animation.IsFinish())
            {
                serie.animation.CheckProgress(1);
                chart.RefreshPainter(serie);
            }
            if (dataChanging)
            {
                chart.RefreshPainter(serie);
            }
        }
        private void DrawMutipleRadar(VertexHelper vh)
        {
            if (!serie.show)
            {
                return;
            }
            m_RadarCoord = chart.GetChartComponent <RadarCoord>(serie.radarIndex);
            if (m_RadarCoord == null)
            {
                return;
            }

            serie.containerIndex       = m_RadarCoord.index;
            serie.containterInstanceId = m_RadarCoord.instanceId;

            var startPoint   = Vector3.zero;
            var toPoint      = Vector3.zero;
            var firstPoint   = Vector3.zero;
            var indicatorNum = m_RadarCoord.indicatorList.Count;
            var angle        = 2 * Mathf.PI / indicatorNum;
            var centerPos    = m_RadarCoord.context.center;

            serie.animation.InitProgress(0, 1);
            if (!serie.show || serie.animation.HasFadeOut())
            {
                return;
            }
            var rate               = serie.animation.GetCurrRate();
            var dataChanging       = false;
            var interacting        = false;
            var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();

            SerieHelper.GetAllMinMaxData(serie, m_RadarCoord.ceilRate);
            for (int j = 0; j < serie.data.Count; j++)
            {
                var    serieData = serie.data[j];
                string dataName  = serieData.name;
                if (!serieData.show)
                {
                    continue;
                }
                var lineStyle   = SerieHelper.GetLineStyle(serie, serieData);
                var areaStyle   = SerieHelper.GetAreaStyle(serie, serieData);
                var symbol      = SerieHelper.GetSerieSymbol(serie, serieData);
                var isHighlight = serieData.context.highlight;
                var colorIndex  = chart.GetLegendRealShowNameIndex(serieData.legendName);
                var areaColor   = SerieHelper.GetAreaColor(serie, serieData, chart.theme, colorIndex, isHighlight);
                var areaToColor = SerieHelper.GetAreaToColor(serie, serieData, chart.theme, colorIndex, isHighlight);
                var lineColor   = SerieHelper.GetLineColor(serie, serieData, chart.theme, colorIndex, isHighlight);
                var lineWidth   = lineStyle.GetWidth(chart.theme.serie.lineWidth);
                int dataCount   = m_RadarCoord.indicatorList.Count;
                serieData.context.dataPoints.Clear();
                for (int n = 0; n < dataCount; n++)
                {
                    if (n >= serieData.data.Count)
                    {
                        break;
                    }
                    var min   = m_RadarCoord.GetIndicatorMin(n);
                    var max   = m_RadarCoord.GetIndicatorMax(n);
                    var value = serieData.GetCurrData(n, dataChangeDuration);
                    if (serieData.IsDataChanged())
                    {
                        dataChanging = true;
                    }
                    if (max == 0)
                    {
                        if (serie.data.Count > 1)
                        {
                            SerieHelper.GetMinMaxData(serie, n, out min, out max);
                            min = ChartHelper.GetMinDivisibleValue(min, 0);
                            max = ChartHelper.GetMaxDivisibleValue(max, 0);
                            if (min > 0)
                            {
                                min = 0;
                            }
                        }
                        else
                        {
                            max = serie.context.dataMax;
                        }
                    }
                    var radius    = (float)(m_RadarCoord.context.dataRadius * (value - min) / (max - min));
                    var currAngle = (n + (m_RadarCoord.positionType == RadarCoord.PositionType.Between ? 0.5f : 0)) * angle;
                    radius *= rate;
                    if (n == 0)
                    {
                        startPoint = new Vector3(centerPos.x + radius * Mathf.Sin(currAngle),
                                                 centerPos.y + radius * Mathf.Cos(currAngle));
                        firstPoint = startPoint;
                    }
                    else
                    {
                        toPoint = new Vector3(centerPos.x + radius * Mathf.Sin(currAngle),
                                              centerPos.y + radius * Mathf.Cos(currAngle));
                        if (areaStyle != null && areaStyle.show)
                        {
                            UGL.DrawTriangle(vh, startPoint, toPoint, centerPos, areaColor, areaColor, areaToColor);
                        }
                        if (lineStyle.show)
                        {
                            ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, toPoint, lineColor);
                        }
                        startPoint = toPoint;
                    }
                    serieData.context.dataPoints.Add(startPoint);
                }
                if (areaStyle != null && areaStyle.show)
                {
                    UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor);
                }
                if (lineStyle.show)
                {
                    ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, firstPoint, lineColor);
                }
                if (symbol.show && symbol.type != SymbolType.None)
                {
                    for (int m = 0; m < serieData.context.dataPoints.Count; m++)
                    {
                        var point      = serieData.context.dataPoints[m];
                        var symbolSize = isHighlight ?
                                         symbol.GetSelectedSize(null, chart.theme.serie.lineSymbolSelectedSize) :
                                         symbol.GetSize(null, chart.theme.serie.lineSymbolSize);
                        if (!serieData.interact.TryGetValue(ref symbolSize, ref interacting))
                        {
                            symbolSize = isHighlight ?
                                         symbol.GetSelectedSize(serieData.data, symbolSize) :
                                         symbol.GetSize(serieData.data, symbolSize);
                            serieData.interact.SetValue(ref interacting, symbolSize);
                            symbolSize = serie.animation.GetSysmbolSize(symbolSize);
                        }
                        var symbolColor      = SerieHelper.GetItemColor(serie, serieData, chart.theme, j, isHighlight);
                        var symbolToColor    = SerieHelper.GetItemToColor(serie, serieData, chart.theme, j, isHighlight);
                        var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, j, isHighlight, false);
                        var symbolBorder     = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight);
                        var borderColor      = SerieHelper.GetSymbolBorderColor(serie, serieData, chart.theme, isHighlight);
                        var cornerRadius     = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight);
                        chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, point, symbolColor,
                                         symbolToColor, symbolEmptyColor, borderColor, symbol.gap, cornerRadius);
                    }
                }
            }
            if (!serie.animation.IsFinish())
            {
                serie.animation.CheckProgress(1);
                chart.RefreshPainter(serie);
            }
            if (dataChanging || interacting)
            {
                chart.RefreshPainter(serie);
            }
        }