mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-28 12:08:46 +00:00
优化图表性能
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
@@ -19,6 +20,9 @@ namespace XCharts.Runtime
|
||||
private float m_DataZoomLastEndIndex;
|
||||
private float m_LastStart;
|
||||
private float m_LastEnd;
|
||||
private List<double> _sampleSumPrefixCache;
|
||||
private int _sampleSumPrefixMaxCount = 0;
|
||||
private bool _sampleSumPrefixInverse = false;
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
@@ -593,11 +597,30 @@ namespace XCharts.Runtime
|
||||
var animationDuration = serie.animation.GetChangeDuration();
|
||||
var dataAddDuration = serie.animation.GetAdditionDuration();
|
||||
var unscaledTime = serie.animation.unscaledTime;
|
||||
var useCurrentData = false;
|
||||
List<double> sampleSumPrefix = null;
|
||||
if (serie.animation.enable)
|
||||
{
|
||||
useCurrentData = DataHelper.IsAnyDataChanged(ref showData, serie.minShow, maxCount);
|
||||
dataChanging = useCurrentData;
|
||||
}
|
||||
if (!useCurrentData && rate > 1 &&
|
||||
(serie.sampleType == SampleType.Sum || serie.sampleType == SampleType.Average))
|
||||
{
|
||||
if (_sampleSumPrefixCache == null || _sampleSumPrefixMaxCount != maxCount || _sampleSumPrefixInverse != axis.inverse)
|
||||
{
|
||||
_sampleSumPrefixCache = DataHelper.BuildSampleSumPrefix(ref showData, maxCount, axis.inverse);
|
||||
_sampleSumPrefixMaxCount = maxCount;
|
||||
_sampleSumPrefixInverse = axis.inverse;
|
||||
}
|
||||
sampleSumPrefix = _sampleSumPrefixCache;
|
||||
}
|
||||
|
||||
for (int i = 0; i < maxCount; i += rate)
|
||||
for (int i = serie.minShow; i < maxCount; i += rate)
|
||||
{
|
||||
double value = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow, maxCount, totalAverage, i,
|
||||
dataAddDuration, animationDuration, ref dataChanging, axis, unscaledTime);
|
||||
dataAddDuration, animationDuration, ref dataChanging, axis, unscaledTime,
|
||||
useCurrentData, false, sampleSumPrefix);
|
||||
float pX = dataZoom.context.x + i * scaleWid;
|
||||
float dataHig = (float)((maxValue - minValue) == 0 ? 0 :
|
||||
(value - minValue) / (maxValue - minValue) * dataZoom.context.height);
|
||||
@@ -685,11 +708,30 @@ namespace XCharts.Runtime
|
||||
var animationDuration = serie.animation.GetChangeDuration();
|
||||
var dataAddDuration = serie.animation.GetAdditionDuration();
|
||||
var unscaledTime = serie.animation.unscaledTime;
|
||||
var useCurrentData = false;
|
||||
List<double> sampleSumPrefix = null;
|
||||
if (serie.animation.enable)
|
||||
{
|
||||
useCurrentData = DataHelper.IsAnyDataChanged(ref showData, serie.minShow, maxCount);
|
||||
dataChanging = useCurrentData;
|
||||
}
|
||||
if (!useCurrentData && rate > 1 &&
|
||||
(serie.sampleType == SampleType.Sum || serie.sampleType == SampleType.Average))
|
||||
{
|
||||
if (_sampleSumPrefixCache == null || _sampleSumPrefixMaxCount != maxCount || _sampleSumPrefixInverse != axis.inverse)
|
||||
{
|
||||
_sampleSumPrefixCache = DataHelper.BuildSampleSumPrefix(ref showData, maxCount, axis.inverse);
|
||||
_sampleSumPrefixMaxCount = maxCount;
|
||||
_sampleSumPrefixInverse = axis.inverse;
|
||||
}
|
||||
sampleSumPrefix = _sampleSumPrefixCache;
|
||||
}
|
||||
|
||||
for (int i = 0; i < maxCount; i += rate)
|
||||
for (int i = serie.minShow; i < maxCount; i += rate)
|
||||
{
|
||||
double value = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow, maxCount, totalAverage, i,
|
||||
dataAddDuration, animationDuration, ref dataChanging, axis, unscaledTime);
|
||||
dataAddDuration, animationDuration, ref dataChanging, axis, unscaledTime,
|
||||
useCurrentData, false, sampleSumPrefix);
|
||||
float pY = dataZoom.context.y + i * scaleWid;
|
||||
float dataHig = (maxValue - minValue) == 0 ? 0 :
|
||||
(float)((value - minValue) / (maxValue - minValue) * dataZoom.context.width);
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace XCharts.Runtime
|
||||
internal sealed class TooltipHandler : MainComponentHandler<Tooltip>
|
||||
{
|
||||
private Dictionary<string, ChartLabel> m_IndicatorLabels = new Dictionary<string, ChartLabel>();
|
||||
private Dictionary<Serie, Dictionary<int, List<SerieData>>> m_SortedAxisDataCache =
|
||||
new Dictionary<Serie, Dictionary<int, List<SerieData>>>();
|
||||
private GameObject m_LabelRoot;
|
||||
private ISerieContainer m_PointerContainer;
|
||||
|
||||
@@ -451,29 +453,116 @@ namespace XCharts.Runtime
|
||||
|
||||
private void GetSerieDataIndexByAxis(Serie serie, Axis axis, GridCoord grid, int dimension = 0)
|
||||
{
|
||||
var currValue = 0d;
|
||||
var lastValue = 0d;
|
||||
var nextValue = 0d;
|
||||
var axisValue = axis.context.pointerValue;
|
||||
var isTimeAxis = axis.IsTime();
|
||||
var dataCount = serie.dataCount;
|
||||
var themeSymbolSize = chart.theme.serie.scatterSymbolSize;
|
||||
var data = serie.data;
|
||||
if (!isTimeAxis)// || serie.useSortData)
|
||||
serie.context.pointerAxisDataIndexs.Clear();
|
||||
|
||||
if (axis.IsTime())
|
||||
{
|
||||
serie.context.sortedData.Clear();
|
||||
for (int i = 0; i < dataCount; i++)
|
||||
FindSerieDataIndexByAxisLinear(serie, axis, axisValue, dimension);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sortedData = GetSortedAxisData(serie, dimension);
|
||||
var nearestIndex = GetNearestSerieDataIndex(sortedData, axisValue, dimension, axis.context.tickValue);
|
||||
if (nearestIndex >= 0)
|
||||
serie.context.pointerAxisDataIndexs.Add(nearestIndex);
|
||||
}
|
||||
|
||||
if (serie.context.pointerAxisDataIndexs.Count > 0)
|
||||
{
|
||||
var index = serie.context.pointerAxisDataIndexs[0];
|
||||
serie.context.pointerItemDataIndex = index;
|
||||
axis.context.axisTooltipValue = serie.GetSerieData(index).GetData(dimension);
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
axis.context.axisTooltipValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private List<SerieData> GetSortedAxisData(Serie serie, int dimension)
|
||||
{
|
||||
Dictionary<int, List<SerieData>> dimensionCache;
|
||||
if (!m_SortedAxisDataCache.TryGetValue(serie, out dimensionCache))
|
||||
{
|
||||
dimensionCache = new Dictionary<int, List<SerieData>>();
|
||||
m_SortedAxisDataCache[serie] = dimensionCache;
|
||||
}
|
||||
|
||||
List<SerieData> sortedData;
|
||||
if (!dimensionCache.TryGetValue(dimension, out sortedData))
|
||||
{
|
||||
sortedData = new List<SerieData>();
|
||||
dimensionCache[dimension] = sortedData;
|
||||
}
|
||||
|
||||
if (serie.dataDirty || sortedData.Count != serie.dataCount)
|
||||
{
|
||||
sortedData.Clear();
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
serie.context.sortedData.Add(serieData);
|
||||
sortedData.Add(serie.data[i]);
|
||||
}
|
||||
serie.context.sortedData.Sort(delegate (SerieData a, SerieData b)
|
||||
sortedData.Sort(delegate (SerieData a, SerieData b)
|
||||
{
|
||||
return a.GetData(dimension).CompareTo(b.GetData(dimension));
|
||||
});
|
||||
data = serie.context.sortedData;
|
||||
}
|
||||
serie.context.pointerAxisDataIndexs.Clear();
|
||||
return sortedData;
|
||||
}
|
||||
|
||||
private int GetNearestSerieDataIndex(List<SerieData> sortedData, double axisValue, int dimension, double tickValue)
|
||||
{
|
||||
var dataCount = sortedData.Count;
|
||||
if (dataCount <= 0) return -1;
|
||||
|
||||
if (dataCount == 1)
|
||||
{
|
||||
var currValue = sortedData[0].GetData(dimension);
|
||||
var diff = tickValue * 0.5f;
|
||||
return axisValue >= currValue - diff && axisValue <= currValue + diff
|
||||
? sortedData[0].index
|
||||
: -1;
|
||||
}
|
||||
|
||||
var firstValue = sortedData[0].GetData(dimension);
|
||||
var secondValue = sortedData[1].GetData(dimension);
|
||||
if (axisValue <= firstValue + (secondValue - firstValue) / 2)
|
||||
return sortedData[0].index;
|
||||
|
||||
var lastValue = sortedData[dataCount - 1].GetData(dimension);
|
||||
var beforeLastValue = sortedData[dataCount - 2].GetData(dimension);
|
||||
if (axisValue > beforeLastValue + (lastValue - beforeLastValue) / 2)
|
||||
return sortedData[dataCount - 1].index;
|
||||
|
||||
var low = 1;
|
||||
var high = dataCount - 2;
|
||||
while (low <= high)
|
||||
{
|
||||
var mid = (low + high) / 2;
|
||||
var prevValue = sortedData[mid - 1].GetData(dimension);
|
||||
var currValue = sortedData[mid].GetData(dimension);
|
||||
var nextValue = sortedData[mid + 1].GetData(dimension);
|
||||
var leftBound = currValue - (currValue - prevValue) / 2;
|
||||
var rightBound = currValue + (nextValue - currValue) / 2;
|
||||
if (axisValue > leftBound && axisValue <= rightBound)
|
||||
return sortedData[mid].index;
|
||||
if (axisValue <= leftBound)
|
||||
high = mid - 1;
|
||||
else
|
||||
low = mid + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void FindSerieDataIndexByAxisLinear(Serie serie, Axis axis, double axisValue, int dimension)
|
||||
{
|
||||
var currValue = 0d;
|
||||
var lastValue = 0d;
|
||||
var nextValue = 0d;
|
||||
var dataCount = serie.dataCount;
|
||||
var data = serie.data;
|
||||
for (int i = 0; i < dataCount; i++)
|
||||
{
|
||||
var serieData = data[i];
|
||||
@@ -518,17 +607,6 @@ namespace XCharts.Runtime
|
||||
}
|
||||
lastValue = currValue;
|
||||
}
|
||||
if (serie.context.pointerAxisDataIndexs.Count > 0)
|
||||
{
|
||||
var index = serie.context.pointerAxisDataIndexs[0];
|
||||
serie.context.pointerItemDataIndex = index;
|
||||
axis.context.axisTooltipValue = serie.GetSerieData(index).GetData(dimension);
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
axis.context.axisTooltipValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetSerieDataIndexByItem(Serie serie, Axis axis, GridCoord grid, int dimension = 0)
|
||||
|
||||
Reference in New Issue
Block a user