It is mainly used with XCharts to better display the curve. It has two functions: one is sorting, and the other is setting the best position of the curve.
1. Sort Sort, which sorts a certain Serie of the curve, in ascending and descending order.
2. Set the maximum value AxisMinMax, you can select a single axis or all axes, one is to calculate the maximum value for a certain Serie, and the other is to calculate the maximum value for all Serie
3. Source code
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);
}
}
}