/// <summary>
        /// 替换字符串中的通配符,支持的通配符有{.}、{a}、{b}、{c}、{d}、{e}、{f}、{g}。
        /// </summary>
        /// <param name="content">要替换的字符串</param>
        /// <param name="dataIndex">选中的数据项serieData索引</param>
        /// <param name="numericFormatter">默认的数字格式化</param>
        /// <param name="serie">选中的serie</param>
        /// <param name="series">所有serie</param>
        /// <param name="theme">用来获取指定index的颜色</param>
        /// <param name="category">选中的类目,一般用在折线图和柱状图</param>
        /// <param name="dataZoom">dataZoom</param>
        /// <returns></returns>
        public static bool ReplaceContent(ref string content, int dataIndex, string numericFormatter, Serie serie,
                                          BaseChart chart, DataZoom dataZoom = null)
        {
            var foundDot = false;
            var mc       = s_Regex.Matches(content);

            foreach (var m in mc)
            {
                var old       = m.ToString();
                var args      = s_RegexSub.Matches(m.ToString());
                var argsCount = args.Count;
                if (argsCount <= 0)
                {
                    continue;
                }
                int  targetIndex = 0;
                char p           = GetSerieIndex(args[0].ToString(), ref targetIndex);
                if (targetIndex >= 0)
                {
                    serie = chart.GetSerie(targetIndex);
                    if (serie == null)
                    {
                        continue;
                    }
                }
                else if (serie != null)
                {
                    targetIndex = serie.index;
                }
                else
                {
                    serie       = chart.GetSerie(0);
                    targetIndex = 0;
                }
                if (serie == null)
                {
                    continue;
                }
                if (p == '.')
                {
                    var bIndex = targetIndex;
                    if (argsCount >= 2)
                    {
                        var args1Str = args[1].ToString();
                        if (s_RegexN.IsMatch(args1Str))
                        {
                            bIndex = int.Parse(args1Str);
                        }
                    }
                    content  = content.Replace(old, ChartCached.ColorToDotStr(chart.theme.GetColor(bIndex)));
                    foundDot = true;
                }
                else if (p == 'a' || p == 'A')
                {
                    if (argsCount == 1)
                    {
                        content = content.Replace(old, serie.serieName);
                    }
                }
                else if (p == 'b' || p == 'B' || p == 'e' || p == 'E')
                {
                    var bIndex = dataIndex;
                    if (argsCount >= 2)
                    {
                        var args1Str = args[1].ToString();
                        if (s_RegexN.IsMatch(args1Str))
                        {
                            bIndex = int.Parse(args1Str);
                        }
                    }
                    var needCategory = (p != 'e' && p != 'E') && (serie is Line || serie is Bar);
                    if (needCategory)
                    {
                        var category = chart.GetTooltipCategory(dataIndex, serie, dataZoom);
                        content = content.Replace(old, category);
                    }
                    else
                    {
                        var serieData = serie.GetSerieData(bIndex, dataZoom);
                        content = content.Replace(old, serieData.name);
                    }
                }
                else if (p == 'g' || p == 'G')
                {
                    content = content.Replace(old, ChartCached.NumberToStr(serie.dataCount, ""));
                }
                else if (p == 'c' || p == 'C' || p == 'd' || p == 'D' || p == 'f' || p == 'f')
                {
                    var isPercent      = p == 'd' || p == 'D';
                    var isTotal        = p == 'f' || p == 'f';
                    var bIndex         = dataIndex;
                    var dimensionIndex = -1;
                    if (argsCount >= 2)
                    {
                        var args1Str = args[1].ToString();
                        if (s_RegexFn.IsMatch(args1Str))
                        {
                            numericFormatter = args1Str;
                        }
                        else if (s_RegexN_N.IsMatch(args1Str))
                        {
                            var temp = args1Str.Split('-');
                            bIndex         = int.Parse(temp[0]);
                            dimensionIndex = int.Parse(temp[1]);
                        }
                        else if (s_RegexN.IsMatch(args1Str))
                        {
                            dimensionIndex = int.Parse(args1Str);
                        }
                        else
                        {
                            Debug.LogError("unmatch:" + args1Str);
                            continue;
                        }
                    }
                    if (argsCount >= 3)
                    {
                        numericFormatter = args[2].ToString();
                    }
                    if (dimensionIndex == -1)
                    {
                        dimensionIndex = 1;
                    }
                    if (numericFormatter == string.Empty)
                    {
                        numericFormatter = SerieHelper.GetNumericFormatter(serie, serie.GetSerieData(bIndex), "");
                    }
                    var value = serie.GetData(bIndex, dimensionIndex, dataZoom);
                    if (isPercent)
                    {
                        var total   = serie.GetDataTotal(dimensionIndex, serie.GetSerieData(bIndex));
                        var percent = total == 0 ? 0 : value / serie.yTotal * 100;
                        content = content.Replace(old, ChartCached.FloatToStr(percent, numericFormatter));
                    }
                    else if (isTotal)
                    {
                        var total = serie.GetDataTotal(dimensionIndex, serie.GetSerieData(bIndex));
                        content = content.Replace(old, ChartCached.FloatToStr(total, numericFormatter));
                    }
                    else
                    {
                        content = content.Replace(old, ChartCached.FloatToStr(value, numericFormatter));
                    }
                }
            }
            content = s_RegexNewLine.Replace(content, PH_NN);
            return(foundDot);
        }
 private float GetAxisPosition(GridCoord grid, Axis axis, DataZoom dataZoom, int dataCount, double value)
 {
     return(AxisHelper.GetAxisPosition(grid, axis, value, dataCount, dataZoom));
 }
        private Vector3 GetSinglePos(Axis xAxis, Axis yAxis, GridCoord grid, Serie serie, DataZoom dataZoom, MarkLineData data,
                                     int serieDataCount)
        {
            switch (data.type)
            {
            case MarkLineType.Min:
                var serieData = SerieHelper.GetMinSerieData(serie, data.dimension, dataZoom);
                data.runtimeValue = serieData.GetData(data.dimension);
                var pX = GetAxisPosition(grid, xAxis, dataZoom, serieDataCount, serieData.index);
                var pY = GetAxisPosition(grid, yAxis, dataZoom, serieDataCount, data.runtimeValue);
                return(new Vector3(pX, pY));

            case MarkLineType.Max:
                serieData         = SerieHelper.GetMaxSerieData(serie, data.dimension, dataZoom);
                data.runtimeValue = serieData.GetData(data.dimension);
                pX = GetAxisPosition(grid, xAxis, dataZoom, serieDataCount, serieData.index);
                pY = GetAxisPosition(grid, yAxis, dataZoom, serieDataCount, data.runtimeValue);
                return(new Vector3(pX, pY));

            case MarkLineType.None:
                if (data.zeroPosition)
                {
                    data.runtimeValue = 0;
                    return(grid.context.position);
                }
                else
                {
                    pX = data.xPosition != 0 ? grid.context.x + data.xPosition :
                         GetAxisPosition(grid, xAxis, dataZoom, serieDataCount, data.xValue);
                    pY = data.yPosition != 0 ? grid.context.y + data.yPosition :
                         GetAxisPosition(grid, yAxis, dataZoom, serieDataCount, data.yValue);
                    data.runtimeValue = data.yValue;
                    return(new Vector3(pX, pY));
                }

            default:
                return(grid.context.position);
            }
        }
        /// <summary>
        /// 获得一个类目数据在坐标系中代表的宽度
        /// </summary>
        /// <param name="coordinateWidth"></param>
        /// <param name="dataZoom"></param>
        /// <returns></returns>
        public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)
        {
            if (dataCount < 1)
            {
                dataCount = 1;
            }
            if (axis.IsValue())
            {
                return(dataCount > 1 ? coordinateWidth / (dataCount - 1) : coordinateWidth);
            }
            var categoryCount = axis.GetDataCount(dataZoom);
            int segment       = (axis.boundaryGap ? categoryCount : categoryCount - 1);

            segment = segment <= 0 ? dataCount : segment;
            if (segment <= 0)
            {
                segment = 1;
            }

            return(coordinateWidth / segment);
        }
Example #5
0
 /// <summary>
 /// 获得类目数据个数
 /// </summary>
 /// <param name="dataZoom"></param>
 /// <returns></returns>
 internal int GetDataCount(DataZoom dataZoom)
 {
     return(IsCategory() ? GetDataList(dataZoom).Count : 0);
 }
        /// <summary>
        /// 获得分割段宽度
        /// </summary>
        /// <param name="coordinateWidth"></param>
        /// <param name="dataZoom"></param>
        /// <returns></returns>
        public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)
        {
            if (index < 0)
            {
                return(0);
            }

            int num      = GetScaleNumber(axis, coordinateWidth, dataZoom);
            int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom);

            if (num <= 0)
            {
                num = 1;
            }

            if (axis.IsTime() || axis.IsValue())
            {
                var value     = axis.GetLabelValue(index);
                var lastValue = axis.GetLabelValue(index - 1);
                return(axis.context.minMaxRange == 0 ?
                       0 :
                       (float)(coordinateWidth * (value - lastValue) / axis.context.minMaxRange));
            }
            else
            {
                var data = axis.GetDataList(dataZoom);
                if (axis.IsCategory() && data.Count > 0)
                {
                    var count = axis.boundaryGap ? data.Count : data.Count - 1;
                    int tick  = count / splitNum;
                    if (count <= 0)
                    {
                        return(0);
                    }

                    var each = coordinateWidth / count;
                    if (axis.insertDataToHead)
                    {
                        var max = axis.boundaryGap ? splitNum : splitNum - 1;
                        if (index == 1)
                        {
                            if (axis.axisTick.alignWithLabel)
                            {
                                return(each * tick);
                            }
                            else
                            {
                                return(coordinateWidth - each * tick * max);
                            }
                        }
                        else
                        {
                            if (count < splitNum)
                            {
                                return(each);
                            }
                            else
                            {
                                return(each * (count / splitNum));
                            }
                        }
                    }
                    else
                    {
                        var max = axis.boundaryGap ? num - 1 : num;
                        if (index >= max)
                        {
                            if (axis.axisTick.alignWithLabel)
                            {
                                return(each * tick);
                            }
                            else
                            {
                                return(coordinateWidth - each * tick * (index - 1));
                            }
                        }
                        else
                        {
                            if (count < splitNum)
                            {
                                return(each);
                            }
                            else
                            {
                                return(each * (count / splitNum));
                            }
                        }
                    }
                }
                else
                {
                    if (splitNum <= 0)
                    {
                        return(0);
                    }
                    else
                    {
                        return(coordinateWidth / splitNum);
                    }
                }
            }
        }
        public static float GetAxisPosition(GridCoord grid, Axis axis, double value, int dataCount = 0, DataZoom dataZoom = null)
        {
            var gridHeight = axis is YAxis ? grid.context.height : grid.context.width;
            var gridXY     = axis is YAxis ? grid.context.y : grid.context.x;

            if (axis.IsCategory())
            {
                if (dataCount == 0)
                {
                    dataCount = axis.data.Count;
                }
                var   categoryIndex = (int)value;
                var   scaleWid      = AxisHelper.GetDataWidth(axis, gridHeight, dataCount, dataZoom);
                float startY        = gridXY + (axis.boundaryGap ? scaleWid / 2 : 0);
                return(startY + scaleWid * categoryIndex);
            }
            else
            {
                var yDataHig = (axis.context.minMaxRange == 0) ? 0f :
                               (float)((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight);
                return(gridXY + yDataHig);
            }
        }
        /// <summary>
        /// 获得分割段数
        /// </summary>
        /// <param name="dataZoom"></param>
        /// <returns></returns>
        public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)
        {
            if (axis.type == Axis.AxisType.Value)
            {
                return(axis.context.labelValueList.Count - 1);
            }
            else if (axis.type == Axis.AxisType.Time)
            {
                return(axis.context.labelValueList.Count);
            }
            else if (axis.type == Axis.AxisType.Log)
            {
                return(axis.splitNumber > 0 ? axis.splitNumber : 4);
            }
            else if (axis.type == Axis.AxisType.Category)
            {
                int dataCount = axis.GetDataList(dataZoom).Count;
                if (!axis.boundaryGap)
                {
                    dataCount -= 1;
                }
                if (dataCount <= 0)
                {
                    dataCount = 1;
                }

                if (axis.splitNumber <= 0)
                {
                    if (dataCount <= 10)
                    {
                        return(dataCount);
                    }
                    else
                    {
                        for (int i = 4; i < 6; i++)
                        {
                            if (dataCount % i == 0)
                            {
                                return(i);
                            }
                        }
                        return(5);
                    }
                }
                else
                {
                    if (axis.splitNumber <= 0 || axis.splitNumber > dataCount)
                    {
                        return(dataCount);
                    }
                    if (dataCount >= axis.splitNumber * 2)
                    {
                        return(axis.splitNumber);
                    }
                    else
                    {
                        return(dataCount);
                    }
                }
            }
            return(0);
        }
        /// <summary>
        /// 获得标签显示的名称
        /// </summary>
        /// <param name="index"></param>
        /// <param name="minValue"></param>
        /// <param name="maxValue"></param>
        /// <param name="dataZoom"></param>
        /// <returns></returns>
        public static string GetLabelName(Axis axis, float coordinateWidth, int index, double minValue, double maxValue,
                                          DataZoom dataZoom, bool forcePercent)
        {
            int split = GetSplitNumber(axis, coordinateWidth, dataZoom);

            if (axis.type == Axis.AxisType.Value)
            {
                if (minValue == 0 && maxValue == 0)
                {
                    maxValue = axis.max != 0 ? axis.max : 1;
                }
                double value = 0;
                if (forcePercent)
                {
                    maxValue = 100;
                }

                value = axis.GetLabelValue(index);
                if (axis.inverse)
                {
                    value    = -value;
                    minValue = -minValue;
                    maxValue = -maxValue;
                }
                if (forcePercent)
                {
                    return(string.Format("{0}%", (int)value));
                }
                else
                {
                    return(axis.axisLabel.GetFormatterContent(index, value, minValue, maxValue));
                }
            }
            else if (axis.type == Axis.AxisType.Log)
            {
                double value = axis.logBaseE ?
                               System.Math.Exp(axis.GetLogMinIndex() + index) :
                               System.Math.Pow(axis.logBase, axis.GetLogMinIndex() + index);
                if (axis.inverse)
                {
                    value    = -value;
                    minValue = -minValue;
                    maxValue = -maxValue;
                }
                return(axis.axisLabel.GetFormatterContent(index, value, minValue, maxValue, true));
            }
            else if (axis.type == Axis.AxisType.Time)
            {
                if (minValue == 0 && maxValue == 0)
                {
                    return(string.Empty);
                }
                if (index > axis.context.labelValueList.Count - 1)
                {
                    return(string.Empty);
                }

                var value = axis.GetLabelValue(index);
                return(axis.axisLabel.GetFormatterDateTime(index, value, minValue, maxValue));
            }
            var showData  = axis.GetDataList(dataZoom);
            int dataCount = showData.Count;

            if (dataCount <= 0)
            {
                return("");
            }
            int rate = axis.boundaryGap ? (dataCount / split) : (dataCount - 1) / split;

            if (rate == 0)
            {
                rate = 1;
            }
            if (axis.insertDataToHead)
            {
                if (index > 0)
                {
                    var residue  = (dataCount - 1) - split * rate;
                    var newIndex = residue + (index - 1) * rate;
                    if (newIndex < 0)
                    {
                        newIndex = 0;
                    }
                    return(axis.axisLabel.GetFormatterContent(newIndex, showData[newIndex]));
                }
                else
                {
                    if (axis.boundaryGap && coordinateWidth / dataCount > 5)
                    {
                        return(string.Empty);
                    }
                    else
                    {
                        return(axis.axisLabel.GetFormatterContent(0, showData[0]));
                    }
                }
            }
            else
            {
                int newIndex = index * rate;
                if (newIndex < dataCount)
                {
                    return(axis.axisLabel.GetFormatterContent(newIndex, showData[newIndex]));
                }
                else
                {
                    if (axis.boundaryGap && coordinateWidth / dataCount > 5)
                    {
                        return(string.Empty);
                    }
                    else
                    {
                        return(axis.axisLabel.GetFormatterContent(dataCount - 1, showData[dataCount - 1]));
                    }
                }
            }
        }
Example #10
0
        private static void UpdateFilterData_Category(Serie serie, DataZoom dataZoom)
        {
            var data  = serie.data;
            var range = Mathf.RoundToInt(data.Count * (dataZoom.end - dataZoom.start) / 100);

            if (range <= 0)
            {
                range = 1;
            }
            int start = 0, end = 0;

            if (dataZoom.context.invert)
            {
                end   = Mathf.CeilToInt(data.Count * dataZoom.end / 100);
                start = end - range;
                if (start < 0)
                {
                    start = 0;
                }
            }
            else
            {
                start = Mathf.FloorToInt(data.Count * dataZoom.start / 100);
                end   = start + range;
                if (end > data.Count)
                {
                    end = data.Count;
                }
            }
            if (start != serie.m_FilterStart || end != serie.m_FilterEnd ||
                dataZoom.minShowNum != serie.m_FilterMinShow || serie.m_NeedUpdateFilterData)
            {
                serie.m_FilterStart          = start;
                serie.m_FilterEnd            = end;
                serie.m_FilterMinShow        = dataZoom.minShowNum;
                serie.m_NeedUpdateFilterData = false;
                if (data.Count > 0)
                {
                    if (range < dataZoom.minShowNum)
                    {
                        if (dataZoom.minShowNum > data.Count)
                        {
                            range = data.Count;
                        }
                        else
                        {
                            range = dataZoom.minShowNum;
                        }
                    }
                    if (range > data.Count - start - 1)
                    {
                        start = data.Count - range - 1;
                    }
                    if (start >= 0)
                    {
                        serie.context.dataZoomStartIndex = start;
                        serie.m_FilterData = data.GetRange(start, range);
                    }
                    else
                    {
                        serie.context.dataZoomStartIndex = 0;
                        serie.m_FilterData = data;
                    }
                }
                else
                {
                    serie.context.dataZoomStartIndex = 0;
                    serie.m_FilterData = data;
                }
            }
            else if (end == 0)
            {
                serie.context.dataZoomStartIndex = 0;
                serie.m_FilterData = emptyFilter;
            }
        }
Example #11
0
        /// <summary>
        /// 获得指定维数的最大最小值
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="dataZoom"></param>
        /// <returns></returns>
        public static void UpdateMinMaxData(Serie serie, int dimension, int ceilRate = 0, DataZoom dataZoom = null)
        {
            double min = 0, max = 0;

            GetMinMaxData(serie, dimension, out min, out max, dataZoom);
            if (ceilRate < 0)
            {
                serie.context.dataMin = min;
                serie.context.dataMax = max;
            }
            else
            {
                serie.context.dataMin = ChartHelper.GetMinDivisibleValue(min, ceilRate);
                serie.context.dataMax = ChartHelper.GetMaxDivisibleValue(max, ceilRate);
            }
        }
Example #12
0
        /// <summary>
        /// Gets the maximum and minimum values of all data in the serie.
        /// |获得系列所有数据的最大最小值。
        /// </summary>
        /// <param name="serie"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <param name="dataZoom"></param>
        public static void GetMinMaxData(Serie serie, out double min, out double max, DataZoom dataZoom = null, int dimension = 0)
        {
            max = double.MinValue;
            min = double.MaxValue;
            var dataList = serie.GetDataList(dataZoom);

            for (int i = 0; i < dataList.Count; i++)
            {
                var serieData = dataList[i];
                if (serieData.show)
                {
                    var count = 0;
                    if (dimension > 0)
                    {
                        count = dimension;
                    }
                    else
                    {
                        count = serie.showDataDimension > serieData.data.Count ?
                                serieData.data.Count :
                                serie.showDataDimension;
                    }
                    for (int j = 0; j < count; j++)
                    {
                        var value = serieData.data[j];
                        if (!serie.IsIgnoreValue(value))
                        {
                            if (value > max)
                            {
                                max = value;
                            }
                            if (value < min)
                            {
                                min = value;
                            }
                        }
                    }
                }
            }
        }