/******************************************/
/* */
/* Copyright (c) 2018 monitor1394 */
/* https://github.com/monitor1394 */
/* */
/******************************************/
using System.Text;
using UnityEngine;
namespace XCharts
{
public static class AxisHelper
{
public static float GetTickWidth(Axis axis)
{
return axis.axisTick.width != 0 ? axis.axisTick.width : axis.axisLine.width;
}
///
/// 包含箭头偏移的轴线长度
///
///
///
public static float GetAxisLineSymbolOffset(Axis axis)
{
if (axis.axisLine.show && axis.axisLine.symbol && axis.axisLine.symbolOffset > 0)
{
return axis.axisLine.symbolOffset;
}
return 0;
}
///
/// 获得分割段数
///
///
///
public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)
{
if (axis.type == Axis.AxisType.Value)
{
if (axis.interval > 0)
{
if (coordinateWid <= 0) return 0;
int num = Mathf.CeilToInt(axis.runtimeMinMaxRange / axis.interval) + 1;
int maxNum = Mathf.CeilToInt(coordinateWid / 15);
if (num > maxNum)
{
axis.interval *= 2;
num = Mathf.CeilToInt(axis.runtimeMinMaxRange / axis.interval) + 1;
}
return num;
}
else return axis.splitNumber;
}
else if (axis.type == Axis.AxisType.Log)
{
return axis.splitNumber;
}
int dataCount = axis.GetDataList(dataZoom).Count;
if (axis.splitNumber <= 0) return dataCount;
if (dataCount > 2 * axis.splitNumber || dataCount <= 0)
return axis.splitNumber;
else
return dataCount;
}
///
/// 获得分割段的宽度
///
///
///
///
public static float GetSplitWidth(Axis axis, float coordinateWidth, DataZoom dataZoom)
{
int split = GetSplitNumber(axis, coordinateWidth, dataZoom);
int segment = (axis.boundaryGap ? split : split - 1);
segment = segment <= 0 ? 1 : segment;
return coordinateWidth / segment;
}
///
/// 获得一个类目数据在坐标系中代表的宽度
///
///
///
///
public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)
{
if (dataCount < 1) dataCount = 1;
var categoryCount = axis.GetDataNumber(dataZoom);
int segment = (axis.boundaryGap ? categoryCount : categoryCount - 1);
segment = segment <= 0 ? dataCount : segment;
return coordinateWidth / segment;
}
///
/// 获得标签显示的名称
///
///
///
///
///
///
internal static string GetLabelName(Axis axis, float coordinateWidth, int index, float minValue, float maxValue,
DataZoom dataZoom, bool forcePercent)
{
int split = GetSplitNumber(axis, coordinateWidth, dataZoom);
if (axis.type == Axis.AxisType.Value)
{
if (minValue == 0 && maxValue == 0) return string.Empty;
float value = 0;
if (forcePercent) maxValue = 100;
if (axis.interval > 0)
{
if (index == split - 1) value = maxValue;
else value = minValue + index * axis.interval;
}
else
{
value = (minValue + (maxValue - minValue) * index / (split - 1));
}
if (axis.inverse)
{
value = -value;
minValue = -minValue;
maxValue = -maxValue;
}
if (forcePercent) return string.Format("{0}%", (int)value);
else return axis.axisLabel.GetFormatterContent(value, minValue, maxValue);
}
else if (axis.type == Axis.AxisType.Log)
{
float value = axis.logBaseE ? Mathf.Exp(axis.runtimeMinLogIndex + index) :
Mathf.Pow(axis.logBase, axis.runtimeMinLogIndex + index);
if (axis.inverse)
{
value = -value;
minValue = -minValue;
maxValue = -maxValue;
}
return axis.axisLabel.GetFormatterContent(value, minValue, maxValue, true);
}
var showData = axis.GetDataList(dataZoom);
int dataCount = showData.Count;
if (dataCount <= 0) return "";
if (index == split - 1 && !axis.boundaryGap)
{
return axis.axisLabel.GetFormatterContent(showData[dataCount - 1]);
}
else
{
float rate = dataCount / split;
if (rate < 1) rate = 1;
int offset = axis.boundaryGap ? (int)(rate / 2) : 0;
int newIndex = (int)(index * rate >= dataCount - 1 ?
dataCount - 1 : offset + index * rate);
return axis.axisLabel.GetFormatterContent(showData[newIndex]);
}
}
///
/// 获得分割线条数
///
///
///
internal static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom)
{
if (axis.type == Axis.AxisType.Value || axis.type == Axis.AxisType.Log)
{
int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom);
return axis.boundaryGap ? splitNum + 1 : splitNum;
}
else
{
var showData = axis.GetDataList(dataZoom);
int dataCount = showData.Count;
if (axis.splitNumber <= 0) return axis.boundaryGap ? dataCount + 1 : dataCount;
if (dataCount > 2 * axis.splitNumber || dataCount <= 0)
return axis.boundaryGap ? axis.splitNumber + 1 : axis.splitNumber;
else
return axis.boundaryGap ? dataCount + 1 : dataCount;
}
}
///
/// 获得分割段宽度
///
///
///
///
internal static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom)
{
int num = GetScaleNumber(axis, coordinateWidth, dataZoom) - 1;
if (num <= 0) num = 1;
if (axis.type == Axis.AxisType.Value && axis.interval > 0)
{
if (index == num - 1) return coordinateWidth - (num - 1) * axis.interval * coordinateWidth / axis.runtimeMinMaxRange;
else return axis.interval * coordinateWidth / axis.runtimeMinMaxRange;
}
else
{
return coordinateWidth / num;
}
}
///
/// 调整最大最小值
///
///
///
internal static void AdjustMinMaxValue(Axis axis, ref float minValue, ref float maxValue, bool needFormat)
{
if (axis.type == Axis.AxisType.Log)
{
int minSplit = 0;
int maxSplit = 0;
maxValue = ChartHelper.GetMaxLogValue(maxValue, axis.logBase, axis.logBaseE, out maxSplit);
minValue = ChartHelper.GetMinLogValue(minValue, axis.logBase, axis.logBaseE, out minSplit);
axis.splitNumber = (minSplit > 0 && maxSplit > 0) ? (maxSplit + minSplit - 1) : (maxSplit + minSplit);
return;
}
if (axis.minMaxType == Axis.AxisMinMaxType.Custom)
{
if (axis.min != 0 || axis.max != 0)
{
if (axis.inverse)
{
minValue = -axis.max;
maxValue = -axis.min;
}
else
{
minValue = axis.min;
maxValue = axis.max;
}
}
}
else
{
switch (axis.minMaxType)
{
case Axis.AxisMinMaxType.Default:
if (minValue == 0 && maxValue == 0)
{
}
else if (minValue > 0 && maxValue > 0)
{
minValue = 0;
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, axis.ceilRate) : maxValue;
}
else if (minValue < 0 && maxValue < 0)
{
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, axis.ceilRate) : minValue;
maxValue = 0;
}
else
{
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, axis.ceilRate) : minValue;
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, axis.ceilRate) : maxValue;
}
break;
case Axis.AxisMinMaxType.MinMax:
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, axis.ceilRate) : minValue;
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, axis.ceilRate) : maxValue;
break;
}
}
var tempRange = maxValue - minValue;
if (axis.runtimeMinMaxRange != tempRange)
{
axis.runtimeMinMaxRange = tempRange;
if (axis.type == Axis.AxisType.Value && axis.interval > 0)
{
axis.SetComponentDirty();
}
}
}
internal static bool NeedShowSplit(Axis axis)
{
if (!axis.show) return false;
if (axis.IsCategory() && axis.data.Count <= 0) return false;
else if (axis.IsValue() && axis.runtimeMinValue == 0 && axis.runtimeMaxValue == 0) return false;
else return true;
}
}
}