Unity+XCharts设置曲线最大最小值,使得曲线居中显示

主要是配合XCharts使用,可使曲线更好的展示,有两个功能一个是排序,一个是设置曲线最佳位置
1、排序Sort,对曲线的某个Serie进行排序,有升序和降序
在这里插入图片描述

2、设置最值AxisMinMax,可选择单个轴或者所有轴,一个是对某个Serie计算最值,一个是对所有的Serie计算最值
在这里插入图片描述
3、源码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using XCharts;

public enum SortType
{
    Up,
    Down,
}

public enum AxisType
{
    X,
    Y,
    Axis
}

public class XChartAxis : MonoBehaviour
{
    public SerieType type = SerieType.Line;
    private LineChart lineChart;
    private void Awake()
    {
        lineChart = GetComponent<LineChart>();
    }

    /// <summary>
    /// 坐标轴最大最小值(满足SerieType的曲线一根曲线)
    /// </summary>
    /// <param name="_serieIndex"></param>
    /// <param name="_type"></param>
    public void AxisMinMax(int _serieIndex = 0, AxisType _type = AxisType.Axis)
    {
        if (lineChart == null)
        {
            lineChart = GetComponent<LineChart>();
        }

        Serie serie = lineChart.series.list[_serieIndex];
        switch (_type)
        {
            case AxisType.X:
                SetX(GetMinX(serie), GetMaxX(serie));
                break;
            case AxisType.Y:
                SetX(GetMinY(serie), GetMaxY(serie));
                break;
            case AxisType.Axis:
                SetX(GetMinX(serie), GetMaxX(serie));
                SetY(GetMinY(serie), GetMaxY(serie));
                break;
        }
    }

    /// <summary>
    /// 坐标轴最大最小值(所有是SerieType的曲线)
    /// </summary>
    /// <param name="_type"></param>
    public void AxisMinMax(AxisType _type = AxisType.Axis)
    {
        if (lineChart == null)
        {
            lineChart = GetComponent<LineChart>();
        }

        List<float> minXList = new List<float>();
        List<float> maxXList = new List<float>();
        List<float> minYList = new List<float>();
        List<float> maxYList = new List<float>();
        foreach (var item in lineChart.series.list)
        {
            switch (_type)
            {
                case AxisType.X:
                    minXList.Add(GetMinX(item));
                    maxXList.Add(GetMaxX(item));
                    break;
                case AxisType.Y:
                    minYList.Add(GetMinY(item));
                    maxYList.Add(GetMaxY(item));
                    break;
                case AxisType.Axis:
                    minXList.Add(GetMinX(item));
                    maxXList.Add(GetMaxX(item));
                    minYList.Add(GetMinY(item));
                    maxYList.Add(GetMaxY(item));
                    break;
            }
        }

        switch (_type)
        {
            case AxisType.X:
                SetX(minXList.Min(), maxXList.Max());
                break;
            case AxisType.Y:
                SetX(minYList.Min(), maxYList.Max());
                break;
            case AxisType.Axis:
                SetX(minXList.Min(), maxXList.Max());
                SetY(minYList.Min(), maxYList.Max());
                break;
        }
    }

    /// <summary>
    /// 设置x坐标最值
    /// </summary>
    /// <param name="_serie"></param>
    /// <param name="_serieIndex"></param>
    private void SetX(float _min, float _max)
    {
        lineChart.xAxis0.minMaxType = Axis.AxisMinMaxType.Custom;
        float axisMin = 0, axisMax = 0;
        //float min = _serie.data.Select(_data => _data.data[0]).ToList().Min();
        //float max = _serie.data.Select(_data => _data.data[0]).ToList().Max();
        AxesMinMax(_min, _max, ref axisMin, ref axisMax);
        lineChart.xAxis0.min = axisMin;
        lineChart.xAxis0.max = axisMax;
        //lineChart.xAxes[_serieIndex].splitNumber = (int)(axisMax - axisMin) / (int)Mathf.Pow(10, maxCount - 1) *2/ 5;
    }
    /// <summary>
    /// 设置y坐标最值
    /// </summary>
    /// <param name="_serie"></param>
    /// <param name="_serieIndex"></param>
    private void SetY( float _min, float _max)
    {
        lineChart.yAxis0.minMaxType = Axis.AxisMinMaxType.Custom;
        float axisMin = 0, axisMax = 0;
        //float min = _serie.data.Select(_data => _data.data[1]).ToList().Min();
        //float max = _serie.data.Select(_data => _data.data[1]).ToList().Max();
        AxesMinMax(_min, _max, ref axisMin, ref axisMax);
        lineChart.yAxis0.min = axisMin;
        lineChart.yAxis0.max = axisMax;
    }

    /// <summary>
    /// x最小值
    /// </summary>
    /// <param name="_serie"></param>
    /// <returns></returns>
    private float GetMinX(Serie _serie)
    {
        return _serie.data.Select(_data => _data.data[0]).ToList().Min();
    }
    /// <summary>
    /// x最大值
    /// </summary>
    /// <param name="_serie"></param>
    /// <returns></returns>
    private float GetMaxX(Serie _serie)
    {
        return _serie.data.Select(_data => _data.data[0]).ToList().Max();
    }
    /// <summary>
    /// y最小值
    /// </summary>
    /// <param name="_serie"></param>
    /// <returns></returns>
    private float GetMinY(Serie _serie)
    {
        return _serie.data.Select(_data => _data.data[1]).ToList().Min();
    }
    /// <summary>
    /// y最大值
    /// </summary>
    /// <param name="_serie"></param>
    /// <returns></returns>
    private float GetMaxY(Serie _serie)
    {
        return _serie.data.Select(_data => _data.data[1]).ToList().Max();
    }

    /// <summary>
    /// 值一共有几位有效位(整数)
    /// </summary>
    /// <param name="_value"></param>
    /// <returns></returns>
    private int ValueCount(int _value)
    {
        if (_value < 1)
        {
            return 0;
        }
        return Mathf.FloorToInt(Mathf.Log10(_value)) + 1;
    }

    /// <summary>
    /// 特殊情况,计算最小值
    /// </summary>
    /// <param name="_value"></param>
    /// <returns></returns>
    private float ValueMin(float _value)
    {
        int _index = 0;
        string vStrValue = _value.ToString().Split('.')[1];
        for (int index = 0; index < vStrValue.Length; index++)
        {
            if (vStrValue[index].ToString() != "0")
            {
                _index = index + 1;
                break;
            }
        }
        return float.Parse(_value.ToString("F" + _index.ToString()));
    }

    /// <summary>
    /// 特殊情况,计算最大值
    /// </summary>
    /// <param name="_value"></param>
    /// <returns></returns>
    private float ValueMax(float _value)
    {
        int _index = 0;
        string vStrValue = _value.ToString().Split('.')[1];
        for (int index = 0; index < vStrValue.Length; index++)
        {
            if (vStrValue[index].ToString() != "0")
            {
                _index = index + 1;
                break;
            }
        }
        _value = (int)(_value * Mathf.Pow(10, _index)) * (1.0f / Mathf.Pow(10, _index))+ (1.0f / Mathf.Pow(10, _index));
        return _value;
    }

    /// <summary>
    /// 计算坐标的最值
    /// </summary>
    /// <param name="_min"></param>
    /// <param name="_max"></param>
    /// <param name="_axisMin"></param>
    /// <param name="_axisMax"></param>
    private void AxesMinMax(float _min, float _max, ref float _axisMin, ref float _axisMax)
    {
        if (_min > 0 && _min < 1 && _max > 0 && _max < 1)
        {
            if (Mathf.Abs(_max - _min) > 0.3f)//表示0-1之前值分布广
            {
                _axisMin = 0;
                _axisMax = ValueMax(_max);
            }
            else
            {
                _axisMin = ValueMin(_min);
                _axisMax = ValueMax(_max);
            }
        }
        else
        {
            int minCount = ValueCount((int)_min);
            switch (minCount)
            {
                case 0:
                    _axisMin = 0;
                    break;
                case 1:
                    _axisMin = (int)_min;
                    break;
                default:
                    float _minValue = Mathf.Pow(10, minCount - 1) * 0.5f;
                    while (_min > (_axisMin + _minValue))
                    {
                        _axisMin += _minValue;
                    }
                    break;
            }
            int maxCount = ValueCount((int)_max);
            switch (maxCount)
            {
                case 1:
                    if ((int)_max == 0)
                        _axisMax = _max;
                    else
                        _axisMax = (int)_max + 1;
                    break;
                default:
                    float _maxValue = Mathf.Pow(10, maxCount - 1) * 0.5f;
                    while (_max > _axisMax)
                    {
                        _axisMax += _maxValue;
                    }
                    break;
            }
        }
    }

    private int SplitNumber(int _value)
    {
        int split = 0;
        int _count = ValueCount(_value);
        switch (_count)
        {
            case 0: split = 5; break;
            case 1: split = _value; break;
            case 2: break;//2   13
            default:
                break;
        }
        return 0;
    }

    /// <summary>
    /// 排序
    /// </summary>
    /// <param name="_serieIndex"></param>
    /// <param name="_type"></param>
    public void Sort(int _serieIndex = 0, SortType _type = SortType.Up)
    {
        if (lineChart == null)
        {
            lineChart = GetComponent<LineChart>();
        }

        Serie serie = lineChart.series.list[_serieIndex];
        List<Vector2> datas = new List<Vector2>();
        for (int index = 0; index < serie.dataCount; index++)
        {
            datas.Add(new Vector2(serie.data[index].data[0], serie.data[index].data[1]));
        }

        switch (_type)
        {
            case SortType.Up:
                // 按照 x 坐标进行升序排序
                datas = datas.OrderBy(v => v.x).ToList();
                break;
            case SortType.Down:
                // 按照 x 坐标进行降序排序
                datas = datas.OrderByDescending(v => v.x).ToList();
                break;
        }
        serie.ClearData();
        for (int index = 0; index < datas.Count; index++)
        {
            serie.AddXYData(datas[index].x, datas[index].y);
        }
    }
}

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值