mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-30 05:08:48 +00:00
优化LineChart的密集数据的曲线效果
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,7 @@ namespace XCharts
|
|||||||
public int threshold { get { return m_Threshold; } set { m_Threshold = value; } }
|
public int threshold { get { return m_Threshold; } set { m_Threshold = value; } }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The milliseconds delay before updating the first animation.
|
/// The milliseconds delay before updating the first animation.
|
||||||
/// 动画延时。
|
/// 动画延时(毫秒)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value></value>
|
/// <value></value>
|
||||||
public int delay { get { return m_Delay; } set { m_Delay = value; if (m_Delay < 0) m_Delay = 0; } }
|
public int delay { get { return m_Delay; } set { m_Delay = value; if (m_Delay < 0) m_Delay = 0; } }
|
||||||
|
|||||||
@@ -679,7 +679,6 @@ namespace XCharts
|
|||||||
m_Series.GetYMinMaxValue(m_DataZoom, axisIndex, out tempMinValue, out tempMaxValue);
|
m_Series.GetYMinMaxValue(m_DataZoom, axisIndex, out tempMinValue, out tempMaxValue);
|
||||||
}
|
}
|
||||||
axis.AdjustMinMaxValue(ref tempMinValue, ref tempMaxValue);
|
axis.AdjustMinMaxValue(ref tempMinValue, ref tempMaxValue);
|
||||||
|
|
||||||
if (tempMinValue != axis.minValue || tempMaxValue != axis.maxValue)
|
if (tempMinValue != axis.minValue || tempMaxValue != axis.maxValue)
|
||||||
{
|
{
|
||||||
axis.minValue = tempMinValue;
|
axis.minValue = tempMinValue;
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ namespace XCharts
|
|||||||
Color lineColor = serie.GetLineColor(m_ThemeInfo, serieIndex, false);
|
Color lineColor = serie.GetLineColor(m_ThemeInfo, serieIndex, false);
|
||||||
Color areaColor = serie.GetAreaColor(m_ThemeInfo, serieIndex, false);
|
Color areaColor = serie.GetAreaColor(m_ThemeInfo, serieIndex, false);
|
||||||
Color areaToColor = serie.GetAreaToColor(m_ThemeInfo, serieIndex, false);
|
Color areaToColor = serie.GetAreaToColor(m_ThemeInfo, serieIndex, false);
|
||||||
Vector3 lp = Vector3.zero, np = Vector3.zero, nnp = Vector3.zero;
|
Vector3 lp = Vector3.zero, np = Vector3.zero, llp = Vector3.zero, nnp = Vector3.zero;
|
||||||
var yAxis = m_YAxises[serie.axisIndex];
|
var yAxis = m_YAxises[serie.axisIndex];
|
||||||
var xAxis = m_XAxises[serie.axisIndex];
|
var xAxis = m_XAxises[serie.axisIndex];
|
||||||
var zeroPos = new Vector3(coordinateX, coordinateY + yAxis.zeroYOffset);
|
var zeroPos = new Vector3(coordinateX, coordinateY + yAxis.zeroYOffset);
|
||||||
@@ -204,7 +204,9 @@ namespace XCharts
|
|||||||
isFinish = DrawNormalLine(vh, serieIndex, serie, xAxis, lp, np, nnp, i, lineColor, areaColor, areaToColor, zeroPos);
|
isFinish = DrawNormalLine(vh, serieIndex, serie, xAxis, lp, np, nnp, i, lineColor, areaColor, areaToColor, zeroPos);
|
||||||
break;
|
break;
|
||||||
case LineType.Smooth:
|
case LineType.Smooth:
|
||||||
isFinish = DrawSmoothLine(vh, serieIndex, serie, xAxis, lp, np, i, lineColor, areaColor, areaToColor, isStack, zeroPos);
|
llp = i > 1 ? serie.dataPoints[i - 2] : lp;
|
||||||
|
nnp = i < serie.dataPoints.Count - 1 ? serie.dataPoints[i + 1] : np;
|
||||||
|
isFinish = DrawSmoothLine(vh, serieIndex, serie, xAxis, lp, np, llp, nnp, i, lineColor, areaColor, areaToColor, isStack, zeroPos);
|
||||||
break;
|
break;
|
||||||
case LineType.StepStart:
|
case LineType.StepStart:
|
||||||
case LineType.StepMiddle:
|
case LineType.StepMiddle:
|
||||||
@@ -235,7 +237,8 @@ namespace XCharts
|
|||||||
if (!serie.animation.IsFinish())
|
if (!serie.animation.IsFinish())
|
||||||
{
|
{
|
||||||
float duration = serie.animation.duration > 0 ? (float)serie.animation.duration / 1000 : 1;
|
float duration = serie.animation.duration > 0 ? (float)serie.animation.duration / 1000 : 1;
|
||||||
float speed = (totalDetailProgress - dataCount * serie.lineStyle.width * 0.5f) / duration;
|
float speed = totalDetailProgress / duration;
|
||||||
|
Debug.LogError("speed:"+speed);
|
||||||
float symbolSpeed = serie.symbol.size / duration;
|
float symbolSpeed = serie.symbol.size / duration;
|
||||||
serie.animation.CheckProgress(Time.deltaTime * speed);
|
serie.animation.CheckProgress(Time.deltaTime * speed);
|
||||||
serie.animation.CheckSymbol(Time.deltaTime * symbolSpeed, serie.symbol.size);
|
serie.animation.CheckSymbol(Time.deltaTime * symbolSpeed, serie.symbol.size);
|
||||||
@@ -243,17 +246,25 @@ namespace XCharts
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float GetDetailProgress(Serie serie, Axis axis, Vector3 lp, Vector3 np, bool fine)
|
private float GetDetailProgress(Serie serie, Axis axis, Vector3 lp, Vector3 np, Vector3 llp, Vector3 nnp, bool fine)
|
||||||
{
|
{
|
||||||
var isYAxis = axis is YAxis;
|
var isYAxis = axis is YAxis;
|
||||||
float progress = 0;
|
float progress = 0;
|
||||||
switch (serie.lineType)
|
switch (serie.lineType)
|
||||||
{
|
{
|
||||||
case LineType.Normal:
|
case LineType.Normal:
|
||||||
progress = Vector3.Distance(lp, np) / 3f - 1;
|
var lineWidth = serie.lineStyle.width;
|
||||||
|
if ((isYAxis && Mathf.Abs(lp.y - np.y) < lineWidth * 3) || (!isYAxis && Mathf.Abs(lp.x - np.x) < lineWidth * 3))
|
||||||
|
{
|
||||||
|
progress = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
progress = Vector3.Distance(lp, np) / 3f - 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LineType.Smooth:
|
case LineType.Smooth:
|
||||||
ChartHelper.GetBezierList(ref bezierPoints, lp, np, fine, lineSmoothStyle);
|
ChartHelper.GetBezierList(ref bezierPoints, null, lp, np, llp, nnp, serie.lineStyle.width, fine, lineSmoothStyle);
|
||||||
if (bezierPoints.Count > 0) progress = bezierPoints.Count - 1;
|
if (bezierPoints.Count > 0) progress = bezierPoints.Count - 1;
|
||||||
break;
|
break;
|
||||||
case LineType.StepStart:
|
case LineType.StepStart:
|
||||||
@@ -305,6 +316,7 @@ namespace XCharts
|
|||||||
var showData = serie.GetDataList(m_DataZoom);
|
var showData = serie.GetDataList(m_DataZoom);
|
||||||
Vector3 lp = Vector3.zero;
|
Vector3 lp = Vector3.zero;
|
||||||
Vector3 np = Vector3.zero;
|
Vector3 np = Vector3.zero;
|
||||||
|
Vector3 llp = Vector3.zero;
|
||||||
Vector3 nnp = Vector3.zero;
|
Vector3 nnp = Vector3.zero;
|
||||||
Color lineColor = serie.GetLineColor(m_ThemeInfo, serieIndex, false);
|
Color lineColor = serie.GetLineColor(m_ThemeInfo, serieIndex, false);
|
||||||
Color areaColor = serie.GetAreaColor(m_ThemeInfo, serieIndex, false);
|
Color areaColor = serie.GetAreaColor(m_ThemeInfo, serieIndex, false);
|
||||||
@@ -362,7 +374,9 @@ namespace XCharts
|
|||||||
isFinish = DrawNormalLine(vh, serieIndex, serie, yAxis, lp, np, nnp, i, lineColor, areaColor, areaToColor, zeroPos);
|
isFinish = DrawNormalLine(vh, serieIndex, serie, yAxis, lp, np, nnp, i, lineColor, areaColor, areaToColor, zeroPos);
|
||||||
break;
|
break;
|
||||||
case LineType.Smooth:
|
case LineType.Smooth:
|
||||||
isFinish = DrawSmoothLine(vh, serieIndex, serie, yAxis, lp, np, i, lineColor, areaColor, areaToColor, isStack, zeroPos);
|
llp = i > 1 ? serie.dataPoints[i - 2] : lp;
|
||||||
|
nnp = i < serie.dataPoints.Count - 1 ? serie.dataPoints[i + 1] : np;
|
||||||
|
isFinish = DrawSmoothLine(vh, serieIndex, serie, yAxis, lp, np, llp, nnp, i, lineColor, areaColor, areaToColor, isStack, zeroPos);
|
||||||
break;
|
break;
|
||||||
case LineType.StepStart:
|
case LineType.StepStart:
|
||||||
case LineType.StepMiddle:
|
case LineType.StepMiddle:
|
||||||
@@ -406,6 +420,18 @@ namespace XCharts
|
|||||||
Vector3 np, Vector3 nnp, int dataIndex, Color lineColor, Color areaColor, Color areaToColor, Vector3 zeroPos)
|
Vector3 np, Vector3 nnp, int dataIndex, Color lineColor, Color areaColor, Color areaToColor, Vector3 zeroPos)
|
||||||
{
|
{
|
||||||
bool isYAxis = axis is YAxis;
|
bool isYAxis = axis is YAxis;
|
||||||
|
var lineWidth = serie.lineStyle.width;
|
||||||
|
if ((isYAxis && Mathf.Abs(lp.y - np.y) < lineWidth * 3) || (!isYAxis && Mathf.Abs(lp.x - np.x) < lineWidth * 3))
|
||||||
|
{
|
||||||
|
if (serie.animation.CheckDetailBreak(np, isYAxis)) return false;
|
||||||
|
ChartHelper.DrawLine(vh, lp, np, serie.lineStyle.width, lineColor);
|
||||||
|
if (serie.areaStyle.show)
|
||||||
|
{
|
||||||
|
DrawPolygonToZero(vh, lp, np, axis, zeroPos, areaColor, areaToColor, Vector3.zero);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var lastSerie = m_Series.GetLastStackSerie(serie);
|
var lastSerie = m_Series.GetLastStackSerie(serie);
|
||||||
Vector3 dnPos, upPos1, upPos2, dir1v, dir2v;
|
Vector3 dnPos, upPos1, upPos2, dir1v, dir2v;
|
||||||
bool isDown;
|
bool isDown;
|
||||||
@@ -448,6 +474,7 @@ namespace XCharts
|
|||||||
var fine = m_Series.IsAnyGradientSerie(serie.stack);
|
var fine = m_Series.IsAnyGradientSerie(serie.stack);
|
||||||
var tick = fine ? 3f : 3f; // 3f:30f
|
var tick = fine ? 3f : 3f; // 3f:30f
|
||||||
int segment = (int)(dist / tick);
|
int segment = (int)(dist / tick);
|
||||||
|
if (segment <= 3) segment = (int)(dist / lineWidth);
|
||||||
smoothPoints.Clear();
|
smoothPoints.Clear();
|
||||||
smoothDownPoints.Clear();
|
smoothDownPoints.Clear();
|
||||||
smoothPoints.Add(stPos1);
|
smoothPoints.Add(stPos1);
|
||||||
@@ -770,8 +797,10 @@ namespace XCharts
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<Vector3> bezierPoints = new List<Vector3>();
|
private List<Vector3> bezierPoints = new List<Vector3>();
|
||||||
|
private Vector3 smoothStartPosUp, smoothStartPosDn;
|
||||||
private bool DrawSmoothLine(VertexHelper vh, int serieIndex, Serie serie, Axis xAxis, Vector3 lp,
|
private bool DrawSmoothLine(VertexHelper vh, int serieIndex, Serie serie, Axis xAxis, Vector3 lp,
|
||||||
Vector3 np, int dataIndex, Color lineColor, Color areaColor, Color areaToColor, bool isStack, Vector3 zeroPos)
|
Vector3 np, Vector3 llp, Vector3 nnp, int dataIndex, Color lineColor, Color areaColor,
|
||||||
|
Color areaToColor, bool isStack, Vector3 zeroPos)
|
||||||
{
|
{
|
||||||
bool isYAxis = xAxis is YAxis;
|
bool isYAxis = xAxis is YAxis;
|
||||||
var lineWidth = serie.lineStyle.width;
|
var lineWidth = serie.lineStyle.width;
|
||||||
@@ -780,19 +809,25 @@ namespace XCharts
|
|||||||
var fine = isStack && m_Series.IsAnyGradientSerie(serie.stack);
|
var fine = isStack && m_Series.IsAnyGradientSerie(serie.stack);
|
||||||
|
|
||||||
if (isYAxis) ChartHelper.GetBezierListVertical(ref bezierPoints, lp, np, fine, lineSmoothStyle);
|
if (isYAxis) ChartHelper.GetBezierListVertical(ref bezierPoints, lp, np, fine, lineSmoothStyle);
|
||||||
else ChartHelper.GetBezierList(ref bezierPoints, lp, np, fine, lineSmoothStyle);
|
else ChartHelper.GetBezierList(ref bezierPoints, vh, lp, np, llp, nnp, serie.lineStyle.width, fine, lineSmoothStyle);
|
||||||
|
|
||||||
Vector3 start, to;
|
Vector3 start, to;
|
||||||
start = bezierPoints[0];
|
start = bezierPoints[0];
|
||||||
|
|
||||||
var dir = bezierPoints[1] - start;
|
var dir = bezierPoints[1] - start;
|
||||||
var dir1v = Vector3.Cross(dir, Vector3.forward).normalized;
|
var dir1v = Vector3.Cross(dir, Vector3.forward).normalized * (isYAxis ? -1 : 1);
|
||||||
var startUp = start + (isYAxis ? Vector3.right : Vector3.up) * lineWidth;
|
var diff = dir1v * lineWidth;
|
||||||
var startDn = start - (isYAxis ? Vector3.right : Vector3.up) * lineWidth;
|
var startUp = start - diff;
|
||||||
|
var startDn = start + diff;
|
||||||
Vector3 toUp, toDn, tnp, tlp;
|
Vector3 toUp, toDn, tnp, tlp;
|
||||||
smoothPoints.Add(startUp);
|
smoothPoints.Add(startUp);
|
||||||
smoothDownPoints.Add(startDn);
|
smoothDownPoints.Add(startDn);
|
||||||
bool isFinish = true;
|
bool isFinish = true;
|
||||||
|
if (dataIndex > 1)
|
||||||
|
{
|
||||||
|
ChartHelper.DrawTriangle(vh, smoothStartPosUp, startUp, lp, lineColor);
|
||||||
|
ChartHelper.DrawTriangle(vh, smoothStartPosDn, startDn, lp, lineColor);
|
||||||
|
}
|
||||||
for (int k = 1; k < bezierPoints.Count; k++)
|
for (int k = 1; k < bezierPoints.Count; k++)
|
||||||
{
|
{
|
||||||
to = bezierPoints[k];
|
to = bezierPoints[k];
|
||||||
@@ -802,26 +837,19 @@ namespace XCharts
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dir = to - start;
|
dir = to - start;
|
||||||
if (k < bezierPoints.Count - 1)
|
dir1v = Vector3.Cross(dir, Vector3.forward).normalized * (isYAxis ? -1 : 1);
|
||||||
{
|
diff = dir1v * lineWidth;
|
||||||
dir1v = Vector3.Cross(dir, Vector3.forward).normalized * (isYAxis ? -1 : 1);
|
toUp = to - diff;
|
||||||
var diff = dir1v * lineWidth;
|
toDn = to + diff;
|
||||||
toUp = to - diff;
|
if (isYAxis) ChartHelper.DrawPolygon(vh, startDn, toDn, toUp, startUp, lineColor);
|
||||||
toDn = to + diff;
|
else ChartHelper.DrawPolygon(vh, startUp, toUp, toDn, startDn, lineColor);
|
||||||
if (isYAxis) ChartHelper.DrawPolygon(vh, startDn, toDn, toUp, startUp, lineColor);
|
|
||||||
else ChartHelper.DrawPolygon(vh, startUp, toUp, toDn, startDn, lineColor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
toUp = to + (isYAxis ? Vector3.right : Vector3.up) * lineWidth;
|
|
||||||
toDn = to - (isYAxis ? Vector3.right : Vector3.up) * lineWidth;
|
|
||||||
if (isYAxis) ChartHelper.DrawPolygon(vh, toDn, toUp, startUp, startDn, lineColor);
|
|
||||||
else ChartHelper.DrawPolygon(vh, startUp, toUp, toDn, startDn, lineColor);
|
|
||||||
}
|
|
||||||
smoothPoints.Add(toUp);
|
smoothPoints.Add(toUp);
|
||||||
smoothDownPoints.Add(toDn);
|
smoothDownPoints.Add(toDn);
|
||||||
|
if (k == bezierPoints.Count - 1)
|
||||||
|
{
|
||||||
|
smoothStartPosUp = toUp;
|
||||||
|
smoothStartPosDn = toDn;
|
||||||
|
}
|
||||||
if (serie.areaStyle.show && (serieIndex == 0 || !isStack))
|
if (serie.areaStyle.show && (serieIndex == 0 || !isStack))
|
||||||
{
|
{
|
||||||
if (isYAxis)
|
if (isYAxis)
|
||||||
|
|||||||
@@ -191,7 +191,8 @@ namespace XCharts
|
|||||||
return tooltipObj;
|
return tooltipObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameObject AddIcon(string name,Transform parent,float width,float height){
|
public static GameObject AddIcon(string name, Transform parent, float width, float height)
|
||||||
|
{
|
||||||
var anchorMax = new Vector2(0.5f, 0.5f);
|
var anchorMax = new Vector2(0.5f, 0.5f);
|
||||||
var anchorMin = new Vector2(0.5f, 0.5f);
|
var anchorMin = new Vector2(0.5f, 0.5f);
|
||||||
var pivot = new Vector2(0.5f, 0.5f);
|
var pivot = new Vector2(0.5f, 0.5f);
|
||||||
@@ -502,15 +503,28 @@ namespace XCharts
|
|||||||
posList.Add(ep);
|
posList.Add(ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GetBezierList(ref List<Vector3> posList, Vector3 sp, Vector3 ep, bool fine, float k = 2.0f)
|
public static void GetBezierList(ref List<Vector3> posList, VertexHelper vh, Vector3 sp, Vector3 ep,
|
||||||
|
Vector3 lsp, Vector3 nep, float lineWidth, bool fine, float k = 2.0f)
|
||||||
{
|
{
|
||||||
Vector3 dir = (ep - sp).normalized;
|
float dist = Mathf.Abs(sp.x - ep.x);
|
||||||
float dist = Vector3.Distance(sp, ep);
|
Vector3 cp1, cp2;
|
||||||
Vector3 cp1 = sp + dist / k * dir * 1;
|
var dir = (ep - sp).normalized;
|
||||||
Vector3 cp2 = sp + dist / k * dir * (k - 1);
|
var diff = dist / k;
|
||||||
cp1.y = sp.y;
|
if (lsp == sp)
|
||||||
cp2.y = ep.y;
|
{
|
||||||
|
cp1 = sp + dist / k * dir * 1;
|
||||||
|
cp1.y = sp.y;
|
||||||
|
cp1 = sp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cp1 = sp + (ep - lsp).normalized * diff;
|
||||||
|
}
|
||||||
|
if (nep == ep) cp2 = ep;
|
||||||
|
else cp2 = ep - (nep - sp).normalized * diff;
|
||||||
int segment = (int)(dist / (fine ? 3f : 7f));
|
int segment = (int)(dist / (fine ? 3f : 7f));
|
||||||
|
if (segment < 1) segment = (int)(dist / 0.5f);
|
||||||
|
if (segment < 4) segment = 4;
|
||||||
GetBezierList2(ref posList, sp, ep, segment, cp1, cp2);
|
GetBezierList2(ref posList, sp, ep, segment, cp1, cp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ QQ交流群:XCharts交流群(202030963)
|
|||||||
|
|
||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
|
* (2019.09.26)优化`LineChart`的密集数据的曲线效果
|
||||||
* (2019.09.25)优化`SerieData`的自定义图标不与`SerieLabel`关联,可单独控制是否显示
|
* (2019.09.25)优化`SerieData`的自定义图标不与`SerieLabel`关联,可单独控制是否显示
|
||||||
* (2019.09.24)增加`SerieData`的自定义图标相关配置支持
|
* (2019.09.24)增加`SerieData`的自定义图标相关配置支持
|
||||||
* (2019.09.23)增加`Formatter`配置`Axis`的`AxisLabel`的格式化输出
|
* (2019.09.23)增加`Formatter`配置`Axis`的`AxisLabel`的格式化输出
|
||||||
|
|||||||
Reference in New Issue
Block a user