public Vector3 GetOffset(float radius)
        {
            var x = ChartHelper.GetActualValue(m_Offset.x, radius);
            var y = ChartHelper.GetActualValue(m_Offset.y, radius);
            var z = ChartHelper.GetActualValue(m_Offset.z, radius);

            return(new Vector3(x, y, z));
        }
        public float GetSerieTotalGap <T>(float categoryWidth, float gap, int index) where T : Serie
        {
            if (index <= 0)
            {
                return(0);
            }
            var total             = 0f;
            var count             = 0;
            var totalRealBarCount = GetSerieBarRealCount <T>();

            barStackSet.Clear();
            for (int i = 0; i < m_Series.Count; i++)
            {
                var serie = m_Series[i];
                if (!serie.show)
                {
                    continue;
                }
                if (serie is T)
                {
                    if (!string.IsNullOrEmpty(serie.stack))
                    {
                        if (barStackSet.Contains(serie.stack))
                        {
                            continue;
                        }
                        barStackSet.Add(serie.stack);
                    }
                    var width = GetStackBarWidth <T>(categoryWidth, serie, totalRealBarCount);
                    if (gap == -1)
                    {
                        if (width > total)
                        {
                            total = width;
                        }
                    }
                    else
                    {
                        total += width + ChartHelper.GetActualValue(gap, width);
                    }
                    if (count + 1 >= index)
                    {
                        break;
                    }
                    else
                    {
                        count++;
                    }
                }
            }
            return(total);
        }
        public float GetSerieTotalWidth <T>(float categoryWidth, float gap, int realBarCount) where T : Serie
        {
            float total   = 0;
            float lastGap = 0;

            barStackSet.Clear();
            for (int i = 0; i < m_Series.Count; i++)
            {
                var serie = m_Series[i];
                if (!serie.show)
                {
                    continue;
                }
                if (serie is T)
                {
                    if (!string.IsNullOrEmpty(serie.stack))
                    {
                        if (barStackSet.Contains(serie.stack))
                        {
                            continue;
                        }
                        barStackSet.Add(serie.stack);
                    }
                    var width = GetStackBarWidth <T>(categoryWidth, serie, realBarCount);
                    if (gap == -1)
                    {
                        if (width > total)
                        {
                            total = width;
                        }
                    }
                    else
                    {
                        lastGap = ChartHelper.GetActualValue(gap, width);
                        total  += width;
                        total  += lastGap;
                    }
                }
            }
            if (total > 0 && gap != -1)
            {
                total -= lastGap;
            }
            return(total);
        }
        private float GetStackBarWidth <T>(float categoryWidth, Serie now, int realBarCount) where T : Serie
        {
            if (string.IsNullOrEmpty(now.stack))
            {
                return(now.GetBarWidth(categoryWidth, realBarCount));
            }
            float barWidth = 0;

            for (int i = 0; i < m_Series.Count; i++)
            {
                var serie = m_Series[i];
                if ((serie is T) &&
                    serie.show && now.stack.Equals(serie.stack))
                {
                    if (serie.barWidth > barWidth)
                    {
                        barWidth = serie.barWidth;
                    }
                }
            }
            if (barWidth == 0)
            {
                var width = ChartHelper.GetActualValue(0.6f, categoryWidth);
                if (realBarCount == 0)
                {
                    return(width < 1 ? categoryWidth : width);
                }
                else
                {
                    return(width / realBarCount);
                }
            }
            else
            {
                return(ChartHelper.GetActualValue(barWidth, categoryWidth));
            }
        }
        private void UpdateRuntimeData(Serie serie)
        {
            var data = serie.data;

            serie.context.dataMax    = serie.yMax;
            serie.context.startAngle = GetStartAngle(serie);
            var runtimePieDataTotal = serie.yTotal;

            SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight);
            float startDegree      = serie.context.startAngle;
            float totalDegree      = 0;
            float zeroReplaceValue = 0;
            int   showdataCount    = 0;

            foreach (var sd in serie.data)
            {
                if (sd.show && serie.pieRoseType == RoseType.Area)
                {
                    showdataCount++;
                }
                sd.context.canShowLabel = false;
            }
            float dataChangeDuration      = serie.animation.GetUpdateAnimationDuration();
            bool  isAllZeroValue          = SerieHelper.IsAllZeroValue(serie, 1);
            var   dataTotalFilterMinAngle = runtimePieDataTotal;

            if (isAllZeroValue)
            {
                totalDegree             = 360;
                zeroReplaceValue        = totalDegree / data.Count;
                serie.context.dataMax   = zeroReplaceValue;
                runtimePieDataTotal     = 360;
                dataTotalFilterMinAngle = 360;
            }
            else
            {
                dataTotalFilterMinAngle = GetTotalAngle(serie, runtimePieDataTotal, ref totalDegree);
            }
            for (int n = 0; n < data.Count; n++)
            {
                var serieData = data[n];
                serieData.index = n;
                var value = isAllZeroValue ? zeroReplaceValue : serieData.GetCurrData(1, dataChangeDuration);
                serieData.context.startAngle   = startDegree;
                serieData.context.toAngle      = startDegree;
                serieData.context.halfAngle    = startDegree;
                serieData.context.currentAngle = startDegree;
                if (!serieData.show)
                {
                    continue;
                }
                float degree = serie.pieRoseType == RoseType.Area ?
                               (totalDegree / showdataCount) :
                               (float)(totalDegree * value / dataTotalFilterMinAngle);
                if (serie.minAngle > 0 && degree < serie.minAngle)
                {
                    degree = serie.minAngle;
                }
                serieData.context.toAngle = startDegree + degree;
                if (serieData.radius > 0)
                {
                    serieData.context.outsideRadius = ChartHelper.GetActualValue(serieData.radius, Mathf.Min(chart.chartWidth, chart.chartHeight));
                }
                else
                {
                    serieData.context.outsideRadius = serie.pieRoseType > 0 ?
                                                      serie.context.insideRadius + (float)((serie.context.outsideRadius - serie.context.insideRadius) * value / serie.context.dataMax) :
                                                      serie.context.outsideRadius;
                }
                if (serieData.context.highlight)
                {
                    serieData.context.outsideRadius += chart.theme.serie.pieTooltipExtraRadius;
                }
                var offset = 0f;
                if (serie.pieClickOffset && serieData.selected)
                {
                    offset += chart.theme.serie.pieSelectedOffset;
                }
                if (serie.animation.CheckDetailBreak(serieData.context.toAngle))
                {
                    serieData.context.currentAngle = serie.animation.GetCurrDetail();
                }
                else
                {
                    serieData.context.currentAngle = serieData.context.toAngle;
                }
                var halfDegree = (serieData.context.toAngle - startDegree) / 2;
                serieData.context.halfAngle    = startDegree + halfDegree;
                serieData.context.offsetCenter = serie.context.center;
                serieData.context.insideRadius = serie.context.insideRadius;
                if (offset > 0)
                {
                    var currRad = serieData.context.halfAngle * Mathf.Deg2Rad;
                    var currSin = Mathf.Sin(currRad);
                    var currCos = Mathf.Cos(currRad);
                    serieData.context.offsetRadius   = 0;
                    serieData.context.insideRadius  -= serieData.context.offsetRadius;
                    serieData.context.outsideRadius -= serieData.context.offsetRadius;
                    if (serie.pieClickOffset && serieData.selected)
                    {
                        serieData.context.offsetRadius += chart.theme.serie.pieSelectedOffset;
                        if (serieData.context.insideRadius > 0)
                        {
                            serieData.context.insideRadius += chart.theme.serie.pieSelectedOffset;
                        }
                        serieData.context.outsideRadius += chart.theme.serie.pieSelectedOffset;
                    }
                    serieData.context.offsetCenter = new Vector3(
                        serie.context.center.x + serieData.context.offsetRadius * currSin,
                        serie.context.center.y + serieData.context.offsetRadius * currCos);
                }
                serieData.context.canShowLabel = serieData.context.currentAngle >= serieData.context.halfAngle;
                startDegree = serieData.context.toAngle;
                SerieLabelHelper.UpdatePieLabelPosition(serie, serieData);
            }
            SerieLabelHelper.AvoidLabelOverlap(serie, chart.theme.common);
        }