[code] refactor the code

This commit is contained in:
monitor1394
2022-07-03 21:09:49 +08:00
parent 33fd4aa9f3
commit 197402dcb7
12 changed files with 60 additions and 67 deletions

View File

@@ -41,7 +41,6 @@ namespace XCharts.Runtime
{
var foundDot = false;
var mc = s_Regex.Matches(content);
Debug.LogError("context:" + content);
foreach (var m in mc)
{
var old = m.ToString();

View File

@@ -1,791 +0,0 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace XCharts.Runtime
{
public static partial class SerieHelper
{
public static double GetMinData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
{
double min = double.MaxValue;
var dataList = serie.GetDataList(dataZoom);
for (int i = 0; i < dataList.Count; i++)
{
var serieData = dataList[i];
if (serieData.show && serieData.data.Count > dimension)
{
var value = serieData.data[dimension];
if (value < min && !serie.IsIgnoreValue(value)) min = value;
}
}
return min == double.MaxValue ? 0 : min;
}
public static SerieData GetMinSerieData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
{
double min = double.MaxValue;
SerieData minData = null;
var dataList = serie.GetDataList(dataZoom);
for (int i = 0; i < dataList.Count; i++)
{
var serieData = dataList[i];
if (serieData.show && serieData.data.Count > dimension)
{
var value = serieData.data[dimension];
if (value < min && !serie.IsIgnoreValue(value))
{
min = value;
minData = serieData;
}
}
}
return minData;
}
public static double GetMaxData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
{
double max = double.MinValue;
var dataList = serie.GetDataList(dataZoom);
for (int i = 0; i < dataList.Count; i++)
{
var serieData = dataList[i];
if (serieData.show && serieData.data.Count > dimension)
{
var value = serieData.data[dimension];
if (value > max && !serie.IsIgnoreValue(value)) max = value;
}
}
return max == double.MinValue ? 0 : max;
}
public static SerieData GetMaxSerieData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
{
double max = double.MinValue;
SerieData maxData = null;
var dataList = serie.GetDataList(dataZoom);
for (int i = 0; i < dataList.Count; i++)
{
var serieData = dataList[i];
if (serieData.show && serieData.data.Count > dimension)
{
var value = serieData.data[dimension];
if (value > max && !serie.IsIgnoreValue(value))
{
max = value;
maxData = serieData;
}
}
}
return maxData;
}
public static double GetAverageData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
{
double total = 0;
var dataList = serie.GetDataList(dataZoom);
for (int i = 0; i < dataList.Count; i++)
{
var serieData = dataList[i];
if (serieData.show && serieData.data.Count > dimension)
{
var value = serieData.data[dimension];
if (!serie.IsIgnoreValue(value))
total += value;
}
}
return total != 0 ? total / dataList.Count : 0;
}
private static List<double> s_TempList = new List<double>();
public static double GetMedianData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
{
s_TempList.Clear();
var dataList = serie.GetDataList(dataZoom);
for (int i = 0; i < dataList.Count; i++)
{
var serieData = dataList[i];
if (serieData.show && serieData.data.Count > dimension)
{
var value = serieData.data[dimension];
if (!serie.IsIgnoreValue(value))
s_TempList.Add(value);
}
}
s_TempList.Sort();
var n = s_TempList.Count;
if (n % 2 == 0) return (s_TempList[n / 2] + s_TempList[n / 2 - 1]) / 2;
else return s_TempList[n / 2];
}
/// <summary>
/// Gets the maximum and minimum values of the specified dimension of a serie.
/// |获得系列指定维数的最大最小值。
/// </summary>
/// <param name="serie">指定系列</param>
/// <param name="dimension">指定维数</param>
/// <param name="min">最小值</param>
/// <param name="max">最大值</param>
/// <param name="dataZoom">缩放组件默认null</param>
public static void GetMinMaxData(Serie serie, int dimension, out double min, out double max,
DataZoom dataZoom = null)
{
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 && serieData.data.Count > dimension)
{
var value = serieData.data[dimension];
if (!serie.IsIgnoreValue(value))
{
if (value > max) max = value;
if (value < min) min = value;
}
}
}
}
/// <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;
}
}
}
}
}
/// <summary>
/// Whether the data for the specified dimension of serie are all 0.
/// |系列指定维数的数据是否全部为0。
/// </summary>
/// <param name="serie">系列</param>
/// <param name="dimension">指定维数</param>
/// <returns></returns>
public static bool IsAllZeroValue(Serie serie, int dimension = 1)
{
foreach (var serieData in serie.data)
{
if (serieData.GetData(dimension) != 0) return false;
}
return true;
}
/// <summary>
/// 更新运行时中心点和半径
/// </summary>
/// <param name="chartWidth"></param>
/// <param name="chartHeight"></param>
public static void UpdateCenter(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight)
{
if (serie.center.Length < 2) return;
var centerX = serie.center[0] <= 1 ? chartWidth * serie.center[0] : serie.center[0];
var centerY = serie.center[1] <= 1 ? chartHeight * serie.center[1] : serie.center[1];
serie.context.center = chartPosition + new Vector3(centerX, centerY);
var minWidth = Mathf.Min(chartWidth, chartHeight);
serie.context.insideRadius = serie.radius[0] <= 1 ? minWidth * serie.radius[0] : serie.radius[0];
serie.context.outsideRadius = serie.radius[1] <= 1 ? minWidth * serie.radius[1] : serie.radius[1];
}
public static void UpdateRect(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight)
{
if (serie.left != 0 || serie.right != 0 || serie.top != 0 || serie.bottom != 0)
{
var runtimeLeft = serie.left <= 1 ? serie.left * chartWidth : serie.left;
var runtimeBottom = serie.bottom <= 1 ? serie.bottom * chartHeight : serie.bottom;
var runtimeTop = serie.top <= 1 ? serie.top * chartHeight : serie.top;
var runtimeRight = serie.right <= 1 ? serie.right * chartWidth : serie.right;
serie.context.x = chartPosition.x + runtimeLeft;
serie.context.y = chartPosition.y + runtimeBottom;
serie.context.width = chartWidth - runtimeLeft - runtimeRight;
serie.context.height = chartHeight - runtimeTop - runtimeBottom;
serie.context.center = new Vector3(serie.context.x + serie.context.width / 2,
serie.context.y + serie.context.height / 2);
serie.context.rect = new Rect(serie.context.x, serie.context.y, serie.context.width, serie.context.height);
}
else
{
serie.context.x = chartPosition.x;
serie.context.y = chartPosition.y;
serie.context.width = chartWidth;
serie.context.height = chartHeight;
serie.context.center = chartPosition + new Vector3(chartWidth / 2, chartHeight / 2);
serie.context.rect = new Rect(serie.context.x, serie.context.y, serie.context.width, serie.context.height);
}
}
public static Color32 GetItemBackgroundColor(Serie serie, SerieData serieData, ThemeStyle theme, int index,
bool highlight, bool useDefault = true)
{
var color = ChartConst.clearColor32;
if (highlight)
{
var itemStyleEmphasis = GetItemStyleEmphasis(serie, serieData);
if (itemStyleEmphasis != null && !ChartHelper.IsClearColor(itemStyleEmphasis.backgroundColor))
{
color = itemStyleEmphasis.backgroundColor;
ChartHelper.SetColorOpacity(ref color, itemStyleEmphasis.opacity);
return color;
}
}
var itemStyle = GetItemStyle(serie, serieData);
if (!ChartHelper.IsClearColor(itemStyle.backgroundColor))
{
color = itemStyle.backgroundColor;
if (highlight) color = ChartHelper.GetHighlightColor(color);
ChartHelper.SetColorOpacity(ref color, itemStyle.opacity);
return color;
}
else if (useDefault)
{
color = theme.GetColor(index);
if (highlight) color = ChartHelper.GetHighlightColor(color);
color.a = 50;
return color;
}
return color;
}
public static Color32 GetItemColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight, bool opacity = true)
{
if (serie == null)
return ChartConst.clearColor32;
ItemStyle itemStyle = null;
if (highlight)
itemStyle = GetItemStyleEmphasis(serie, serieData);
if (itemStyle == null)
itemStyle = GetItemStyle(serie, serieData);
var color = ChartHelper.IsClearColor(itemStyle.color) ?
theme.GetColor(index) :
itemStyle.color;
if (highlight)
color = ChartHelper.GetHighlightColor(color);
if (opacity)
ChartHelper.SetColorOpacity(ref color, itemStyle.opacity);
return color;
}
public static Color32 GetItemColor0(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight, Color32 defaultColor)
{
if (serie == null)
return ChartConst.clearColor32;
ItemStyle itemStyle = null;
if (highlight)
itemStyle = GetItemStyleEmphasis(serie, serieData);
if (itemStyle == null)
itemStyle = GetItemStyle(serie, serieData);
var color = ChartHelper.IsClearColor(itemStyle.color0) ?
defaultColor :
itemStyle.color0;
if (highlight)
color = ChartHelper.GetHighlightColor(color);
ChartHelper.SetColorOpacity(ref color, itemStyle.opacity);
return color;
}
public static Color32 GetItemToColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight, bool opacity = true)
{
if (serie == null)
return ChartConst.clearColor32;
ItemStyle itemStyle = null;
if (highlight)
itemStyle = GetItemStyleEmphasis(serie, serieData);
if (itemStyle == null)
itemStyle = GetItemStyle(serie, serieData);
var color = itemStyle.toColor;
if (ChartHelper.IsClearColor(color))
{
color = ChartHelper.IsClearColor(itemStyle.color) ?
theme.GetColor(index) :
itemStyle.color;
}
if (highlight)
color = ChartHelper.GetHighlightColor(color);
if (opacity)
ChartHelper.SetColorOpacity(ref color, itemStyle.opacity);
return color;
}
public static bool IsDownPoint(Serie serie, int index)
{
var dataPoints = serie.context.dataPoints;
if (dataPoints.Count < 2) return false;
else if (index > 0 && index < dataPoints.Count - 1)
{
var lp = dataPoints[index - 1];
var np = dataPoints[index + 1];
var cp = dataPoints[index];
var dot = Vector3.Cross(np - lp, cp - np);
return dot.z < 0;
}
else if (index == 0)
{
return dataPoints[0].y < dataPoints[1].y;
}
else if (index == dataPoints.Count - 1)
{
return dataPoints[index].y < dataPoints[index - 1].y;
}
else
{
return false;
}
}
public static ItemStyle GetItemStyle(Serie serie, SerieData serieData, bool highlight = false)
{
if (highlight)
{
var style = GetItemStyleEmphasis(serie, serieData);
if (style == null) return GetItemStyle(serie, serieData, false);
else return style;
}
else if (serie.IsPerformanceMode()) return serie.itemStyle;
else if (serieData != null && serieData.itemStyle != null) return serieData.itemStyle;
else return serie.itemStyle;
}
public static ItemStyle GetItemStyleEmphasis(Serie serie, SerieData serieData)
{
if (!serie.IsPerformanceMode() && serieData != null && serieData.emphasisItemStyle != null && serieData.emphasisItemStyle.show)
return serieData.emphasisItemStyle;
else if (serie.emphasisItemStyle != null && serie.emphasisItemStyle.show) return serie.emphasisItemStyle;
else return null;
}
public static LabelStyle GetSerieLabel(Serie serie, SerieData serieData, bool highlight = false)
{
if (serieData == null) return serie.label;
if (highlight)
{
if (!serie.IsPerformanceMode() && serieData.emphasisLabel != null && serieData.emphasisLabel.show)
return serieData.emphasisLabel;
else if (serie.emphasisLabel != null && serie.emphasisLabel.show) return serie.emphasisLabel;
else return serie.label;
}
else
{
if (!serie.IsPerformanceMode() && serieData.labelStyle != null) return serieData.labelStyle;
else return serie.label;
}
}
public static LabelStyle GetSerieEmphasisLabel(Serie serie, SerieData serieData)
{
if (!serie.IsPerformanceMode() && serieData.emphasisLabel != null && serieData.emphasisLabel.show)
return serieData.emphasisLabel;
else if (serie.emphasisLabel != null && serie.emphasisLabel.show) return serie.emphasisLabel;
else return null;
}
public static LabelLine GetSerieLabelLine(Serie serie, SerieData serieData, bool highlight = false)
{
if (highlight)
{
if (!serie.IsPerformanceMode() && serieData.emphasisLabelLine != null && serieData.emphasisLabelLine.show)
return serieData.emphasisLabelLine;
else if (serie.emphasisLabelLine != null && serie.emphasisLabelLine.show) return serie.emphasisLabelLine;
else return serie.labelLine;
}
else
{
if (!serie.IsPerformanceMode() && serieData.labelLine != null) return serieData.labelLine;
else return serie.labelLine;
}
}
public static SerieSymbol GetSerieSymbol(Serie serie, SerieData serieData)
{
if (!serie.IsPerformanceMode() && serieData.symbol != null) return serieData.symbol;
else return serie.symbol;
}
public static LineStyle GetLineStyle(Serie serie, SerieData serieData)
{
if (serieData != null && serieData.lineStyle != null) return serieData.lineStyle;
else return serie.lineStyle;
}
public static AreaStyle GetAreaStyle(Serie serie, SerieData serieData)
{
if (serieData != null && serieData.areaStyle != null) return serieData.areaStyle;
else return serie.areaStyle;
}
public static TitleStyle GetTitleStyle(Serie serie, SerieData serieData)
{
if (serieData != null && serieData.titleStyle != null) return serieData.titleStyle;
else return serie.titleStyle;
}
public static Color32 GetAreaColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight)
{
Color32 color = ChartConst.clearColor32;
var areaStyle = GetAreaStyle(serie, serieData);
if (areaStyle == null || !areaStyle.show)
return color;
if (!ChartHelper.IsClearColor(areaStyle.color)) color = areaStyle.color;
else if (!ChartHelper.IsClearColor(serie.itemStyle.color)) color = serie.itemStyle.color;
else color = theme.GetColor(index);
ChartHelper.SetColorOpacity(ref color, areaStyle.opacity);
if (highlight)
{
if (!ChartHelper.IsClearColor(areaStyle.highlightColor))
color = areaStyle.highlightColor;
else
color = ChartHelper.GetHighlightColor(color);
}
return color;
}
public static Color32 GetAreaToColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight)
{
Color32 color = ChartConst.clearColor32;
var areaStyle = GetAreaStyle(serie, serieData);
if (areaStyle == null || !areaStyle.show)
return color;
if (!ChartHelper.IsClearColor(areaStyle.toColor)) color = areaStyle.toColor;
else if (!ChartHelper.IsClearColor(serie.itemStyle.toColor)) color = serie.itemStyle.toColor;
else color = theme.GetColor(index);
ChartHelper.SetColorOpacity(ref color, areaStyle.opacity);
if (highlight)
{
if (!ChartHelper.IsClearColor(areaStyle.highlightToColor))
color = areaStyle.highlightToColor;
else
color = ChartHelper.GetHighlightColor(color);
}
return color;
}
public static Color32 GetLineColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight)
{
Color32 color = ChartConst.clearColor32;
var lineStyle = GetLineStyle(serie, serieData);
if (highlight)
{
var itemStyleEmphasis = GetItemStyleEmphasis(serie, null);
if (itemStyleEmphasis != null && !ChartHelper.IsClearColor(itemStyleEmphasis.color))
{
color = itemStyleEmphasis.color;
ChartHelper.SetColorOpacity(ref color, itemStyleEmphasis.opacity);
return color;
}
}
if (!ChartHelper.IsClearColor(lineStyle.color)) color = lineStyle.color;
else if (!ChartHelper.IsClearColor(serie.itemStyle.color)) color = serie.itemStyle.GetColor();
if (ChartHelper.IsClearColor(color)) color = theme.GetColor(index);
ChartHelper.SetColorOpacity(ref color, lineStyle.opacity);
if (highlight) color = ChartHelper.GetHighlightColor(color);
return color;
}
public static float GetSymbolBorder(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight)
{
var itemStyle = GetItemStyle(serie, serieData, highlight);
if (itemStyle != null && itemStyle.borderWidth != 0) return itemStyle.borderWidth;
else return serie.lineStyle.GetWidth(theme.serie.lineWidth) * 2;
}
public static Color32 GetSymbolBorderColor(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight)
{
var itemStyle = GetItemStyle(serie, serieData, highlight);
if (itemStyle != null && !ChartHelper.IsClearColor(itemStyle.borderColor)) return itemStyle.borderColor;
else return serie.itemStyle.borderColor;
}
public static float GetSymbolBorder(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight, float defaultWidth)
{
var itemStyle = GetItemStyle(serie, serieData, highlight);
if (itemStyle != null && itemStyle.borderWidth != 0) return itemStyle.borderWidth;
else return defaultWidth;
}
public static float[] GetSymbolCornerRadius(Serie serie, SerieData serieData, bool highlight)
{
var itemStyle = GetItemStyle(serie, serieData, highlight);
if (itemStyle != null) return itemStyle.cornerRadius;
else return null;
}
public static string GetNumericFormatter(Serie serie, SerieData serieData, string defaultFormatter = null)
{
var itemStyle = SerieHelper.GetItemStyle(serie, serieData);
if (!string.IsNullOrEmpty(itemStyle.numericFormatter)) return itemStyle.numericFormatter;
else return defaultFormatter;
}
public static string GetItemFormatter(Serie serie, SerieData serieData, string defaultFormatter = null)
{
var itemStyle = SerieHelper.GetItemStyle(serie, serieData);
if (!string.IsNullOrEmpty(itemStyle.itemFormatter)) return itemStyle.itemFormatter;
else return defaultFormatter;
}
public static string GetItemMarker(Serie serie, SerieData serieData, string defaultMarker = null)
{
var itemStyle = SerieHelper.GetItemStyle(serie, serieData);
if (!string.IsNullOrEmpty(itemStyle.itemMarker)) return itemStyle.itemMarker;
else return defaultMarker;
}
/// <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);
}
}
public static void GetAllMinMaxData(Serie serie, int ceilRate = 0, DataZoom dataZoom = null)
{
double min = 0, max = 0;
GetMinMaxData(serie, 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);
}
}
private static List<SerieData> emptyFilter = new List<SerieData>();
/// <summary>
/// 根据dataZoom更新数据列表缓存
/// </summary>
/// <param name="dataZoom"></param>
public static void UpdateFilterData(Serie serie, DataZoom dataZoom)
{
if (dataZoom == null || !dataZoom.enable) return;
if (dataZoom.IsContainsXAxis(serie.xAxisIndex))
{
if (dataZoom.IsXAxisIndexValue(serie.xAxisIndex))
{
double min = 0, max = 0;
dataZoom.GetXAxisIndexValue(serie.xAxisIndex, out min, out max);
UpdateFilterData_XAxisValue(serie, dataZoom, 0, min, max);
}
else
{
UpdateFilterData_Category(serie, dataZoom);
}
}
else if (dataZoom.IsContainsYAxis(serie.yAxisIndex))
{
if (dataZoom.IsYAxisIndexValue(serie.yAxisIndex))
{
double min = 0, max = 0;
dataZoom.GetYAxisIndexValue(serie.yAxisIndex, out min, out max);
UpdateFilterData_XAxisValue(serie, dataZoom, 0, min, max);
}
else
{
UpdateFilterData_Category(serie, dataZoom);
}
}
}
private static void UpdateFilterData_XAxisValue(Serie serie, DataZoom dataZoom, int dimension, double min, double max)
{
var data = serie.data;
var startValue = min + (max - min) * dataZoom.start / 100;
var endValue = min + (max - min) * dataZoom.end / 100;
if (endValue < startValue) endValue = startValue;
if (startValue != serie.m_FilterStartValue || endValue != serie.m_FilterEndValue ||
dataZoom.minShowNum != serie.m_FilterMinShow || serie.m_NeedUpdateFilterData)
{
serie.m_FilterStartValue = startValue;
serie.m_FilterEndValue = endValue;
serie.m_FilterMinShow = dataZoom.minShowNum;
serie.m_NeedUpdateFilterData = false;
serie.m_FilterData.Clear();
foreach (var serieData in data)
{
var value = serieData.GetData(dimension);
if (value >= startValue && value <= endValue)
{
serie.m_FilterData.Add(serieData);
}
}
}
else if (endValue == 0)
{
serie.m_FilterData = emptyFilter;
}
}
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;
}
}
public static void UpdateSerieRuntimeFilterData(Serie serie, bool filterInvisible = true)
{
serie.context.sortedData.Clear();
foreach (var serieData in serie.data)
{
if (!filterInvisible || (filterInvisible && serieData.show))
serie.context.sortedData.Add(serieData);
}
switch (serie.dataSortType)
{
case SerieDataSortType.Ascending:
serie.context.sortedData.Sort(delegate(SerieData data1, SerieData data2)
{
var value1 = data1.GetData(1);
var value2 = data2.GetData(1);
if (value1 == value2) return 0;
else if (value1 > value2) return 1;
else return -1;
});
break;
case SerieDataSortType.Descending:
serie.context.sortedData.Sort(delegate(SerieData data1, SerieData data2)
{
var value1 = data1.GetData(1);
var value2 = data2.GetData(1);
if (value1 == value2) return 0;
else if (value1 > value2) return -1;
else return 1;
});
break;
case SerieDataSortType.None:
break;
}
}
public static T CloneSerie<T>(Serie serie) where T : Serie
{
var newSerie = Activator.CreateInstance<T>();
SerieHelper.CopySerie(serie, newSerie);
return newSerie;
}
public static void CopySerie(Serie oldSerie, Serie newSerie)
{
var fields = typeof(Serie).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var field in fields)
{
if (field.IsDefined(typeof(SerializeField), false))
{
var filedValue = field.GetValue(oldSerie);
if (filedValue == null) continue;
var filedType = filedValue.GetType();
if (filedType.IsClass)
field.SetValue(newSerie, ReflectionUtil.DeepCloneSerializeField(filedValue));
}
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 8c031417514104eebb5bbd60dd1f90fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,236 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
public static class SerieLabelHelper
{
public static Color GetLabelColor(Serie serie, ThemeStyle theme, int index)
{
if (serie.label != null && !ChartHelper.IsClearColor(serie.label.textStyle.color))
{
return serie.label.textStyle.color;
}
else
{
return theme.GetColor(index);
}
}
public static void ResetLabel(ChartText labelObject, LabelStyle label, ThemeStyle theme,
Color textColor, float rotate)
{
if (labelObject == null) return;
labelObject.SetColor(textColor);
labelObject.SetLocalEulerAngles(new Vector3(0, 0, rotate));
labelObject.SetFontSize(label.textStyle.GetFontSize(theme.common));
labelObject.SetFontStyle(label.textStyle.fontStyle);
}
public static bool CanShowLabel(Serie serie, SerieData serieData, LabelStyle label, int dimesion)
{
return serie.show && serieData.context.canShowLabel && !serie.IsIgnoreValue(serieData, dimesion);
}
public static string GetFormatterContent(Serie serie, SerieData serieData,
double dataValue, double dataTotal, LabelStyle serieLabel, Color color)
{
if (serieLabel == null)
{
serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
}
var numericFormatter = serieLabel == null ? "" : serieLabel.numericFormatter;
var serieName = serie.serieName;
var dataName = serieData != null ? serieData.name : null;
if (serieLabel.formatterFunction != null)
{
return serieLabel.formatterFunction(serieData.index, dataValue, null);
}
if (string.IsNullOrEmpty(serieLabel.formatter))
return ChartCached.NumberToStr(dataValue, numericFormatter);
else
{
var content = serieLabel.formatter;
FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, serie.dataCount, dataValue,
dataTotal, serieName, dataName, dataName, color, serieData);
return content;
}
}
public static void SetGaugeLabelText(Serie serie)
{
var serieData = serie.GetSerieData(0);
if (serieData == null) return;
if (serieData.labelObject == null) return;
var label = SerieHelper.GetSerieLabel(serie, serieData);
if (label == null) return;
var value = serieData.GetData(1);
var total = serie.max;
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, null, Color.clear);
serieData.labelObject.SetText(content);
serieData.labelObject.SetPosition(serie.context.center + label.offset);
if (!ChartHelper.IsClearColor(label.textStyle.color))
{
serieData.labelObject.text.SetColor(label.textStyle.color);
}
}
public static void UpdatePieLabelPosition(Serie serie, SerieData serieData)
{
if (serieData.labelObject == null) return;
var startAngle = serie.context.startAngle;
var currAngle = serieData.context.halfAngle;
var currRad = currAngle * Mathf.Deg2Rad;
var offsetRadius = serieData.context.offsetRadius;
var insideRadius = serieData.context.insideRadius;
var outsideRadius = serieData.context.outsideRadius;
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData);
switch (serieLabel.position)
{
case LabelStyle.Position.Center:
serieData.context.labelPosition = serie.context.center;
break;
case LabelStyle.Position.Inside:
var labelRadius = offsetRadius + insideRadius + (outsideRadius - insideRadius) / 2 + serieLabel.distance;
var labelCenter = new Vector2(serie.context.center.x + labelRadius * Mathf.Sin(currRad),
serie.context.center.y + labelRadius * Mathf.Cos(currRad));
serieData.context.labelPosition = labelCenter;
break;
default:
//LabelStyle.Position.Outside
if (labelLine != null && labelLine.lineType == LabelLine.LineType.HorizontalLine)
{
var radius1 = serie.context.outsideRadius;
var radius3 = insideRadius + (outsideRadius - insideRadius) / 2;
var currSin = Mathf.Sin(currRad);
var currCos = Mathf.Cos(currRad);
var pos0 = new Vector3(serie.context.center.x + radius3 * currSin, serie.context.center.y + radius3 * currCos);
if ((currAngle - startAngle) % 360 > 180)
{
currSin = Mathf.Sin((360 - currAngle) * Mathf.Deg2Rad);
currCos = Mathf.Cos((360 - currAngle) * Mathf.Deg2Rad);
}
var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos * radius3, 2)) - currSin * radius3;
r4 += labelLine.lineLength1 + labelLine.lineWidth * 4;
r4 += serieData.labelObject.text.GetPreferredWidth() / 2;
serieData.context.labelPosition = pos0 + ((currAngle - startAngle) % 360 > 180 ? Vector3.left : Vector3.right) * r4;
}
else
{
labelRadius = serie.context.outsideRadius + (labelLine == null ? 0 : labelLine.lineLength1);
labelCenter = new Vector2(serie.context.center.x + labelRadius * Mathf.Sin(currRad),
serie.context.center.y + labelRadius * Mathf.Cos(currRad));
serieData.context.labelPosition = labelCenter;
}
break;
}
}
public static void AvoidLabelOverlap(Serie serie, ComponentTheme theme)
{
if (!serie.avoidLabelOverlap) return;
var lastCheckPos = Vector3.zero;
var lastX = 0f;
var data = serie.data;
var splitCount = 0;
for (int n = 0; n < data.Count; n++)
{
var serieData = data[n];
if (serieData.context.labelPosition.x != 0 && serieData.context.labelPosition.x < serie.context.center.x)
{
splitCount = n;
break;
}
}
for (int n = 0; n < splitCount; n++)
{
CheckSerieDataLabel(serie, data[n], splitCount, false, theme, ref lastCheckPos, ref lastX);
}
lastCheckPos = Vector3.zero;
for (int n = data.Count - 1; n >= splitCount; n--)
{
CheckSerieDataLabel(serie, data[n], data.Count - splitCount, true, theme, ref lastCheckPos, ref lastX);
}
}
private static void CheckSerieDataLabel(Serie serie, SerieData serieData, int total, bool isLeft, ComponentTheme theme,
ref Vector3 lastCheckPos, ref float lastX)
{
if (!serieData.context.canShowLabel)
{
serieData.SetLabelActive(false);
return;
}
if (!serieData.show) return;
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
var isOutside = serieLabel.position == LabelStyle.Position.Outside ||
serieLabel.position == LabelStyle.Position.Default;
if (!serieLabel.show) return;
if (!isOutside) return;
var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData);
var fontSize = serieData.labelObject.GetHeight();
if (lastCheckPos == Vector3.zero)
{
lastCheckPos = serieData.context.labelPosition;
}
else if (serieData.context.labelPosition.x != 0)
{
if (lastCheckPos.y - serieData.context.labelPosition.y < fontSize)
{
var labelRadius = serie.context.outsideRadius + labelLine.lineLength1;
var y1 = lastCheckPos.y - fontSize;
var cy = serie.context.center.y;
var diff = Mathf.Abs(y1 - cy);
var diffX = labelRadius * labelRadius - diff * diff;
diffX = diffX <= 0 ? 0 : diffX;
var x1 = serie.context.center.x + Mathf.Sqrt(diffX) * (isLeft ? -1 : 1);
var newPos = new Vector3(x1, y1);
serieData.context.labelPosition = newPos;
var angle = ChartHelper.GetAngle360(Vector2.up, newPos - serie.context.center);
if (angle >= 180 && angle <= 270)
{
serieData.context.labelPosition = new Vector3(isLeft?(++lastX):(--lastX), y1);
}
else if (angle < 180 && angle >= 90)
{
serieData.context.labelPosition = new Vector3(isLeft?(++lastX):(--lastX), y1);
}
else
{
lastX = x1;
}
}
else
{
lastX = serieData.context.labelPosition.x;
}
lastCheckPos = serieData.context.labelPosition;
serieData.labelObject.SetPosition(SerieLabelHelper.GetRealLabelPosition(serie, serieData, serieLabel, labelLine));
}
}
public static Vector3 GetRealLabelPosition(Serie serie, SerieData serieData, LabelStyle label, LabelLine labelLine)
{
if (label == null || labelLine == null)
return serieData.context.labelPosition;
var isOutside = label.position == LabelStyle.Position.Outside ||
label.position == LabelStyle.Position.Default;
if (isOutside && labelLine.lineType != LabelLine.LineType.HorizontalLine)
{
var currAngle = serieData.context.halfAngle;
var offset = labelLine.lineLength2 + serieData.labelObject.GetTextWidth() / 2;
if ((currAngle - serie.context.startAngle) % 360 > 180)
return serieData.context.labelPosition + new Vector3(-offset, 0, 0);
else
return serieData.context.labelPosition + new Vector3(offset, 0, 0);
}
else
{
return serieData.context.labelPosition;
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0b81cddd3452545748563f9c6ea9be69
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,452 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
public static class SeriesHelper
{
public static bool IsLegalLegendName(string name)
{
int numName = -1;
if (int.TryParse(name, out numName))
{
if (numName >= 0 && numName < 100) return false;
}
return true;
}
public static List<string> GetLegalSerieNameList(List<Serie> series)
{
var list = new List<string>();
for (int n = 0; n < series.Count; n++)
{
var serie = series[n];
if (serie.placeHolder) continue;
if (serie.useDataNameForColor)
{
for (int i = 0; i < serie.data.Count; i++)
{
var dataName = serie.data[i].name;
if (!string.IsNullOrEmpty(dataName) && IsLegalLegendName(dataName) && !list.Contains(dataName))
list.Add(dataName);
}
}
else
{
if (!string.IsNullOrEmpty(serie.serieName) && !list.Contains(serie.serieName) && IsLegalLegendName(serie.serieName))
list.Add(serie.serieName);
}
}
return list;
}
/// <summary>
/// 获得所有系列名,不包含空名字。
/// </summary>
/// <returns></returns>
public static void UpdateSerieNameList(BaseChart chart, ref List<string> serieNameList)
{
serieNameList.Clear();
for (int n = 0; n < chart.series.Count; n++)
{
var serie = chart.series[n];
if (serie.placeHolder) continue;
if (serie.useDataNameForColor)
{
for (int i = 0; i < serie.data.Count; i++)
{
var serieData = serie.data[i];
if (serie is Pie && serie.IsIgnoreValue(serieData)) continue;
if (string.IsNullOrEmpty(serieData.name))
serieNameList.Add(ChartCached.IntToStr(i));
else if (!serieNameList.Contains(serieData.name))
serieNameList.Add(serieData.name);
}
}
else
{
if (string.IsNullOrEmpty(serie.serieName))
serieNameList.Add(ChartCached.IntToStr(n));
else if (!serieNameList.Contains(serie.serieName))
serieNameList.Add(serie.serieName);
}
}
}
public static Color GetNameColor(BaseChart chart, int index, string name)
{
Serie destSerie = null;
SerieData destSerieData = null;
var series = chart.series;
for (int n = 0; n < series.Count; n++)
{
var serie = series[n];
if (serie.placeHolder) continue;
if (serie.useDataNameForColor)
{
bool found = false;
for (int i = 0; i < serie.data.Count; i++)
{
if (name.Equals(serie.data[i].name))
{
destSerie = serie;
destSerieData = serie.data[i];
found = true;
break;
}
}
if (found) break;
}
if (name.Equals(serie.serieName))
{
destSerie = serie;
destSerieData = null;
break;
}
}
return SerieHelper.GetItemColor(destSerie, destSerieData, chart.theme, index, false);
}
/// <summary>
/// 是否有需裁剪的serie。
/// </summary>
/// <returns></returns>
public static bool IsAnyClipSerie(List<Serie> series)
{
foreach (var serie in series)
{
if (serie.clip) return true;
}
return false;
}
/// <summary>
/// 获得上一个同堆叠且显示的serie。
/// </summary>
/// <param name="serie"></param>
/// <returns></returns>
public static Serie GetLastStackSerie(List<Serie> series, Serie serie)
{
if (serie == null || string.IsNullOrEmpty(serie.stack)) return null;
for (int i = serie.index - 1; i >= 0; i--)
{
var temp = series[i];
if (temp.show && serie.stack.Equals(temp.stack)) return temp;
}
return null;
}
public static Serie GetSerieByVesselIndex(List<Serie> series, int vesselIndex)
{
foreach (var serie in series)
{
if (serie.vesselIndex == vesselIndex) return serie;
}
return null;
}
private static HashSet<string> _setForStack = new HashSet<string>();
/// <summary>
/// 是否由数据堆叠
/// </summary>
/// <returns></returns>
public static bool IsStack(List<Serie> series)
{
_setForStack.Clear();
foreach (var serie in series)
{
if (string.IsNullOrEmpty(serie.stack)) continue;
if (_setForStack.Contains(serie.stack)) return true;
_setForStack.Add(serie.stack);
}
return false;
}
/// <summary>
/// 是否堆叠
/// </summary>
/// <param name="stackName"></param>
/// <param name="type"></param>
/// <returns></returns>
public static bool IsStack<T>(List<Serie> series, string stackName) where T : Serie
{
if (string.IsNullOrEmpty(stackName)) return false;
int count = 0;
foreach (var serie in series)
{
if (serie.show && serie is T)
{
if (stackName.Equals(serie.stack)) count++;
if (count >= 2) return true;
}
}
return false;
}
/// <summary>
/// 是否时百分比堆叠
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static bool IsPercentStack<T>(List<Serie> series) where T : Serie
{
int count = 0;
bool isPercentStack = false;
foreach (var serie in series)
{
if (serie.show && serie is T)
{
if (!string.IsNullOrEmpty(serie.stack))
{
count++;
if (serie.barPercentStack) isPercentStack = true;
}
if (count >= 2 && isPercentStack) return true;
}
}
return false;
}
/// <summary>
/// 是否时百分比堆叠
/// </summary>
/// <param name="stackName"></param>
/// <param name="type"></param>
/// <returns></returns>
public static bool IsPercentStack<T>(List<Serie> series, string stackName) where T : Serie
{
if (string.IsNullOrEmpty(stackName)) return false;
int count = 0;
bool isPercentStack = false;
foreach (var serie in series)
{
if (serie.show && serie is T)
{
if (stackName.Equals(serie.stack))
{
count++;
if (serie.barPercentStack) isPercentStack = true;
}
if (count >= 2 && isPercentStack) return true;
}
}
return false;
}
private static Dictionary<string, int> sets = new Dictionary<string, int>();
/// <summary>
/// 获得堆叠系列列表
/// </summary>
/// <param name="Dictionary<int"></param>
/// <param name="stackSeries"></param>
public static void GetStackSeries(List<Serie> series, ref Dictionary<int, List<Serie>> stackSeries)
{
int count = 0;
var serieCount = series.Count;
sets.Clear();
if (stackSeries == null)
{
stackSeries = new Dictionary<int, List<Serie>>(serieCount);
}
else
{
foreach (var kv in stackSeries)
{
kv.Value.Clear();
}
}
for (int i = 0; i < serieCount; i++)
{
var serie = series[i];
serie.index = i;
if (string.IsNullOrEmpty(serie.stack))
{
if (!stackSeries.ContainsKey(count))
stackSeries[count] = new List<Serie>(serieCount);
stackSeries[count].Add(serie);
count++;
}
else
{
if (!sets.ContainsKey(serie.stack))
{
sets.Add(serie.stack, count);
if (!stackSeries.ContainsKey(count))
stackSeries[count] = new List<Serie>(serieCount);
stackSeries[count].Add(serie);
count++;
}
else
{
int stackIndex = sets[serie.stack];
stackSeries[stackIndex].Add(serie);
}
}
}
}
public static void UpdateStackDataList(List<Serie> series, Serie currSerie, DataZoom dataZoom, List<List<SerieData>> dataList)
{
dataList.Clear();
for (int i = 0; i <= currSerie.index; i++)
{
var serie = series[i];
if (serie.GetType() == currSerie.GetType() && ChartHelper.IsValueEqualsString(serie.stack, currSerie.stack))
{
dataList.Add(serie.GetDataList(dataZoom));
}
}
}
/// <summary>
/// 获得维度X的最大最小值
/// </summary>
/// <param name="dataZoom"></param>
/// <param name="axisIndex"></param>
/// <param name="minVaule"></param>
/// <param name="maxValue"></param>
public static void GetXMinMaxValue(List<Serie> series, DataZoom dataZoom, int axisIndex, bool isValueAxis,
bool inverse, out double minVaule, out double maxValue, bool isPolar = false)
{
GetMinMaxValue(series, dataZoom, axisIndex, isValueAxis, inverse, false, out minVaule, out maxValue, isPolar);
}
/// <summary>
/// 获得维度Y的最大最小值
/// </summary>
/// <param name="dataZoom"></param>
/// <param name="axisIndex"></param>
/// <param name="minVaule"></param>
/// <param name="maxValue"></param>
public static void GetYMinMaxValue(List<Serie> series, DataZoom dataZoom, int axisIndex, bool isValueAxis,
bool inverse, out double minVaule, out double maxValue, bool isPolar = false)
{
GetMinMaxValue(series, dataZoom, axisIndex, isValueAxis, inverse, true, out minVaule, out maxValue, isPolar);
}
private static Dictionary<int, List<Serie>> _stackSeriesForMinMax = new Dictionary<int, List<Serie>>();
private static Dictionary<int, double> _serieTotalValueForMinMax = new Dictionary<int, double>();
public static void GetMinMaxValue(List<Serie> series, DataZoom dataZoom, int axisIndex, bool isValueAxis,
bool inverse, bool yValue, out double minVaule, out double maxValue, bool isPolar = false)
{
double min = double.MaxValue;
double max = double.MinValue;
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(series);
if (!SeriesHelper.IsStack(series) || (isValueAxis && !yValue))
{
for (int i = 0; i < series.Count; i++)
{
var serie = series[i];
if ((isPolar && serie.polarIndex != axisIndex) ||
(!isPolar && serie.yAxisIndex != axisIndex) ||
!serie.show) continue;
var updateDuration = serie.animation.enable?serie.animation.dataChangeDuration : 0;
if (isPercentStack && SeriesHelper.IsPercentStack<Bar>(series, serie.serieName))
{
if (100 > max) max = 100;
if (0 < min) min = 0;
}
else
{
var showData = serie.GetDataList(dataZoom);
foreach (var data in showData)
{
if (serie is Candlestick)
{
var dataMin = data.GetMinData(inverse);
var dataMax = data.GetMaxData(inverse);
if (dataMax > max) max = dataMax;
if (dataMin < min) min = dataMin;
}
else
{
//var currData = data.GetData(yValue ? 1 : 0, inverse);
var currData = data.GetCurrData(yValue ? 1 : 0, updateDuration, inverse);
if (!serie.IsIgnoreValue(currData))
{
if (currData > max) max = currData;
if (currData < min) min = currData;
}
}
}
}
}
}
else
{
SeriesHelper.GetStackSeries(series, ref _stackSeriesForMinMax);
foreach (var ss in _stackSeriesForMinMax)
{
_serieTotalValueForMinMax.Clear();
for (int i = 0; i < ss.Value.Count; i++)
{
var serie = ss.Value[i];
if ((isPolar && serie.polarIndex != axisIndex) ||
(!isPolar && serie.yAxisIndex != axisIndex) ||
!serie.show) continue;
var showData = serie.GetDataList(dataZoom);
if (SeriesHelper.IsPercentStack<Bar>(series, serie.stack))
{
for (int j = 0; j < showData.Count; j++)
{
_serieTotalValueForMinMax[j] = 100;
}
}
else
{
for (int j = 0; j < showData.Count; j++)
{
if (!_serieTotalValueForMinMax.ContainsKey(j))
_serieTotalValueForMinMax[j] = 0;
double currData = 0;
if (serie is Candlestick)
{
currData = showData[j].GetMaxData(false);
}
else
{
currData = yValue ? showData[j].GetData(1) : showData[j].GetData(0);
}
if (inverse) currData = -currData;
if (!serie.IsIgnoreValue(currData))
_serieTotalValueForMinMax[j] = _serieTotalValueForMinMax[j] + currData;
}
}
}
double tmax = double.MinValue;
double tmin = double.MaxValue;
foreach (var tt in _serieTotalValueForMinMax)
{
if (tt.Value > tmax) tmax = tt.Value;
if (tt.Value < tmin) tmin = tt.Value;
}
if (tmax > max) max = tmax;
if (tmin < min) min = tmin;
}
}
if (max == double.MinValue && min == double.MaxValue)
{
minVaule = 0;
maxValue = 0;
}
else
{
minVaule = min > 1 ? Math.Floor(min) : min;
maxValue = max > 1 ? Math.Ceiling(max) : max;
}
}
public static int GetMaxSerieDataCount(List<Serie> series)
{
int max = 0;
foreach (var serie in series)
{
if (serie.dataCount > max) max = serie.dataCount;
}
return max;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 96a06a5949772464da15c44ae2ad400d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: