优化LineChart在峰谷差异过大时的绘制效果#64

This commit is contained in:
monitor1394
2020-06-23 12:21:27 +08:00
parent 715574b483
commit 2df883098d
2 changed files with 183 additions and 142 deletions

View File

@@ -1,6 +1,7 @@
# 更新日志 # 更新日志
* (2020.06.25) 优化`LineChart`在峰谷差异过大时的绘制效果#64
* (2020.06.18) 修复`SerieLabel`在重新添加数据时可能不显示的问题 * (2020.06.18) 修复`SerieLabel`在重新添加数据时可能不显示的问题
* (2020.06.17) 增加`SerieData`可单独设置`SerieSymbol`#66 * (2020.06.17) 增加`SerieData`可单独设置`SerieSymbol`#66
* (2020.06.17) 修复`Check For Update``Unity 2018`部分版本报错的问题#63 * (2020.06.17) 修复`Check For Update``Unity 2018`部分版本报错的问题#63

View File

@@ -640,11 +640,13 @@ namespace XCharts
} }
private Vector3 stPos1, stPos2, lastDir, lastDnPos; private Vector3 stPos1, stPos2, lastDir, lastDnPos;
private bool lastIsDown;
private bool DrawNormalLine(VertexHelper vh, Serie serie, Axis axis, Vector3 lp, private bool DrawNormalLine(VertexHelper vh, Serie serie, Axis axis, Vector3 lp,
Vector3 np, Vector3 nnp, int dataIndex, Color lineColor, Color areaColor, Color areaToColor, Vector3 np, Vector3 nnp, int dataIndex, Color lineColor, Color areaColor, Color areaToColor,
Vector3 zeroPos, int startIndex = 0) Vector3 zeroPos, int startIndex = 0)
{ {
var isSecond = dataIndex == startIndex + 1; var isSecond = dataIndex == startIndex + 1;
var isTheLastPos = np == nnp;
bool isYAxis = axis is YAxis; bool isYAxis = axis is YAxis;
var lineWidth = serie.lineStyle.width; var lineWidth = serie.lineStyle.width;
var ySmall = Mathf.Abs(lp.y - np.y) < lineWidth * 3; var ySmall = Mathf.Abs(lp.y - np.y) < lineWidth * 3;
@@ -719,16 +721,14 @@ namespace XCharts
{ {
if (!isStart) if (!isStart)
{ {
if ((isYAxis && tp1.y > lastDnPos.y) || (!isYAxis && tp1.x > lastDnPos.x) || isSecond || IsValue()) if (isSecond || IsValue() ||
(lastIsDown && ((isYAxis && tp2.y > lastDnPos.y) || (!isYAxis && tp2.x > lastDnPos.x))) ||
(!lastIsDown && ((isYAxis && tp1.y > lastDnPos.y) || (!isYAxis && tp1.x > lastDnPos.x))))
{ {
isStart = true; isStart = true;
if (stPos2 != Vector3.zero)
{
CheckClipAndDrawPolygon(vh, stPos1, tp1, tp2, stPos2, lineColor, serie.clip); CheckClipAndDrawPolygon(vh, stPos1, tp1, tp2, stPos2, lineColor, serie.clip);
} }
} }
}
else else
{ {
if (i == segment - 1) if (i == segment - 1)
@@ -755,16 +755,15 @@ namespace XCharts
} }
} }
} }
if (isYAxis) if (isYAxis)
{ {
if (tp1.y > lastDnPos.y || isSecond || IsValue()) smoothPoints.Add(tp1); if ((tp1.y < dnPos.y && tp1.y > lastDnPos.y) || IsValue()) smoothPoints.Add(tp1);
if (tp2.y < dnPos.y || IsValue()) smoothDownPoints.Add(tp2); if (tp2.y < dnPos.y || IsValue()) smoothDownPoints.Add(tp2);
} }
else else
{ {
if (tp1.x > lastDnPos.x || isSecond || IsValue()) smoothPoints.Add(tp1); if ((tp1.x < dnPos.x && tp1.x > lastDnPos.x) || isSecond || IsValue()) smoothPoints.Add(tp1);
if (tp2.x < dnPos.x || isSecond || IsValue()) smoothDownPoints.Add(tp2); if (tp2.x < dnPos.x && tp2.x > stPos2.x) smoothDownPoints.Add(tp2);
} }
} }
else else
@@ -773,12 +772,13 @@ namespace XCharts
{ {
if (!isStart) if (!isStart)
{ {
if ((isYAxis && tp2.y > lastDnPos.y) || (!isYAxis && tp2.x > lastDnPos.x) || isSecond || IsValue()) if (isSecond || IsValue() ||
(lastIsDown && ((isYAxis && tp2.y > lastDnPos.y) || (!isYAxis && tp2.x > lastDnPos.x))) ||
(!lastIsDown && ((isYAxis && tp1.y > lastDnPos.y) || (!isYAxis && tp1.x > lastDnPos.x))))
{ {
isStart = true; isStart = true;
if (stPos2 != Vector3.zero) if (stPos2 != Vector3.zero)
{ {
CheckClipAndDrawPolygon(vh, stPos1, tp1, tp2, stPos2, lineColor, serie.clip); CheckClipAndDrawPolygon(vh, stPos1, tp1, tp2, stPos2, lineColor, serie.clip);
} }
} }
@@ -797,7 +797,9 @@ namespace XCharts
else else
{ {
if ((isYAxis && tp1.y < dnPos.y) || (!isYAxis && tp1.x < dnPos.x) || IsValue()) if ((isYAxis && tp1.y < dnPos.y) || (!isYAxis && tp1.x < dnPos.x) || IsValue())
{
CheckClipAndDrawLine(vh, start, cp, serie.lineStyle.width, lineColor, serie.clip); CheckClipAndDrawLine(vh, start, cp, serie.lineStyle.width, lineColor, serie.clip);
}
else else
{ {
CheckClipAndDrawPolygon(vh, ltp1, dnPos, upPos1, ltp2, lineColor, serie.clip); CheckClipAndDrawPolygon(vh, ltp1, dnPos, upPos1, ltp2, lineColor, serie.clip);
@@ -807,16 +809,15 @@ namespace XCharts
} }
} }
} }
if (isYAxis) if (isYAxis)
{ {
if (tp1.y < dnPos.y || IsValue()) smoothPoints.Add(tp1); if ((tp1.y < dnPos.y && tp1.y > lastDnPos.y) || IsValue()) smoothPoints.Add(tp1);
if (tp2.y > lastDnPos.y || isSecond || IsValue()) smoothDownPoints.Add(tp2); if (tp2.y > lastDnPos.y || IsValue()) smoothDownPoints.Add(tp2);
} }
else else
{ {
if (tp1.x < dnPos.x || IsValue()) smoothPoints.Add(tp1); if ((tp1.x < dnPos.x && tp1.x > lastDnPos.x) || IsValue()) smoothPoints.Add(tp1);
if (tp2.x > lastDnPos.x || isSecond || IsValue()) smoothDownPoints.Add(tp2); if (tp2.x > lastDnPos.x) smoothDownPoints.Add(tp2);
} }
} }
start = cp; start = cp;
@@ -836,13 +837,22 @@ namespace XCharts
smoothPoints.Add(dnPos); smoothPoints.Add(dnPos);
if (isYAxis) if (isYAxis)
{ {
smoothDownPoints.Add(np != nnp ? upPos1 : upPos2); smoothDownPoints.Add(isTheLastPos ? upPos1 : upPos2);
smoothDownPoints.Add(np != nnp ? upPos2 : upPos1); smoothDownPoints.Add(isTheLastPos ? upPos2 : upPos1);
} }
else else
{ {
smoothDownPoints.Add(np != nnp ? upPos1 : upPos2); if (isTheLastPos)
smoothDownPoints.Add(np != nnp ? upPos2 : upPos1); {
smoothDownPoints.Add(upPos2);
if (IsInRightOrUp(isYAxis, upPos2, upPos1))
smoothDownPoints.Add(upPos1);
}
else
{
smoothDownPoints.Add(upPos1);
smoothDownPoints.Add(upPos2);
}
} }
} }
} }
@@ -861,7 +871,7 @@ namespace XCharts
var eindex = 0; var eindex = 0;
var sp = GetStartPos(points, ref sindex); var sp = GetStartPos(points, ref sindex);
var ep = GetEndPos(points, ref eindex); var ep = GetEndPos(points, ref eindex);
var cross = ChartHelper.GetIntersection(sp, ep, zeroPos, aep); var cross = ChartHelper.GetIntersection(lp, np, zeroPos, aep);
if (cross == Vector3.zero || smoothDownPoints.Count <= 3) if (cross == Vector3.zero || smoothDownPoints.Count <= 3)
{ {
sp = points[sindex]; sp = points[sindex];
@@ -875,32 +885,16 @@ namespace XCharts
} }
else else
{ {
var sp1 = smoothDownPoints[1]; var sp1 = smoothDownPoints[0];
var ep1 = smoothDownPoints[smoothDownPoints.Count - 2]; var ep1 = smoothDownPoints[smoothDownPoints.Count - 1];
var axisUpStart = zeroPos + (isYAxis ? Vector3.right : Vector3.up) * axis.axisLine.width; var axisUpStart = zeroPos + (isYAxis ? Vector3.right : Vector3.up) * axis.axisLine.width;
var axisUpEnd = axisUpStart + (isYAxis ? Vector3.up * m_CoordinateHeight : Vector3.right * m_CoordinateWidth); var axisUpEnd = axisUpStart + (isYAxis ? Vector3.up * m_CoordinateHeight : Vector3.right * m_CoordinateWidth);
var axisDownStart = zeroPos - (isYAxis ? Vector3.right : Vector3.up) * axis.axisLine.width; var axisDownStart = zeroPos - (isYAxis ? Vector3.right : Vector3.up) * axis.axisLine.width;
var axisDownEnd = axisDownStart + (isYAxis ? Vector3.up * m_CoordinateHeight : Vector3.right * m_CoordinateWidth); var axisDownEnd = axisDownStart + (isYAxis ? Vector3.up * m_CoordinateHeight : Vector3.right * m_CoordinateWidth);
var luPos = ChartHelper.GetIntersection(sp1, ep1, axisUpStart, axisUpEnd); var luPos = ChartHelper.GetIntersection(sp1, ep1, axisUpStart, axisUpEnd);
var ldPos = ChartHelper.GetIntersection(sp1, ep1, axisDownStart, axisDownEnd); sp1 = smoothPoints[0];
sp1 = smoothPoints[1];
ep1 = smoothPoints[smoothPoints.Count - 2]; ep1 = smoothPoints[smoothPoints.Count - 2];
var ruPos = ChartHelper.GetIntersection(sp1, ep1, axisUpStart, axisUpEnd);
var rdPos = ChartHelper.GetIntersection(sp1, ep1, axisDownStart, axisDownEnd); var rdPos = ChartHelper.GetIntersection(sp1, ep1, axisDownStart, axisDownEnd);
if (luPos == Vector3.zero || ldPos == Vector3.zero || ruPos == Vector3.zero || rdPos == Vector3.zero)
{
sp = points[0];
for (int i = 1; i < points.Count; i++)
{
ep = points[i];
if (serie.animation.CheckDetailBreak(ep, isYAxis)) break;
DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero);
sp = ep;
}
}
else
{
if ((isYAxis && lp.x >= zeroPos.x) || (!isYAxis && lp.y >= zeroPos.y)) if ((isYAxis && lp.x >= zeroPos.x) || (!isYAxis && lp.y >= zeroPos.y))
{ {
sp = smoothDownPoints[0]; sp = smoothDownPoints[0];
@@ -996,13 +990,31 @@ namespace XCharts
} }
} }
} }
}
stPos1 = isDown ? upPos2 : dnPos; stPos1 = isDown ? upPos2 : dnPos;
stPos2 = isDown ? dnPos : upPos2; stPos2 = isDown ? dnPos : upPos2;
lastDnPos = dnPos; lastDnPos = dnPos;
lastIsDown = isDown;
return !isBreak; return !isBreak;
} }
private bool IsInRightOrUp(bool isYAxis, bool isLastDown, Vector3 dnPos, Vector3 checkPos)
{
if ((isLastDown && ((isYAxis && checkPos.y <= dnPos.y) || (!isYAxis && checkPos.x <= dnPos.x))) ||
(!isLastDown && ((isYAxis && checkPos.y <= dnPos.y) || (!isYAxis && checkPos.x <= dnPos.x))))
{
return true;
}
else
{
return false;
}
}
private bool IsInRightOrUp(bool isYAxis, Vector3 lp, Vector3 rp)
{
return ((isYAxis && rp.y > lp.y) || (!isYAxis && rp.x > lp.x));
}
private void DrawPolygonToZero(VertexHelper vh, Vector3 sp, Vector3 ep, Axis axis, Vector3 zeroPos, private void DrawPolygonToZero(VertexHelper vh, Vector3 sp, Vector3 ep, Axis axis, Vector3 zeroPos,
Color areaColor, Color areaToColor, Vector3 areaDiff, bool clip = false) Color areaColor, Color areaToColor, Vector3 areaDiff, bool clip = false)
{ {
@@ -1107,7 +1119,9 @@ namespace XCharts
var diff = dir1v * lineWidth; var diff = dir1v * lineWidth;
var startUp = start - diff; var startUp = start - diff;
var startDn = start + diff; var startDn = start + diff;
Vector3 toUp, toDn, tnp, tlp; var startAreaDn = Vector3.zero;
var startAreaUp = Vector3.zero;
Vector3 toUp, toDn;
bool isFinish = true; bool isFinish = true;
if (dataIndex > startIndex + 1) if (dataIndex > startIndex + 1)
@@ -1126,6 +1140,8 @@ namespace XCharts
smoothDownPoints.Add(startDn); smoothDownPoints.Add(startDn);
} }
var sourAreaColor = areaColor; var sourAreaColor = areaColor;
var lastAreaDownEndPos = GetLastSmoothPos(serie.GetDownSmoothList(dataIndex - 1), isYAxis);
var lastAreaUpEndPos = GetLastSmoothPos(serie.GetUpSmoothList(dataIndex - 1), isYAxis);
for (int k = 1; k < bezierPoints.Count; k++) for (int k = 1; k < bezierPoints.Count; k++)
{ {
to = bezierPoints[k]; to = bezierPoints[k];
@@ -1150,47 +1166,46 @@ namespace XCharts
} }
if (serie.areaStyle.show && (serie.index == 0 || !isStack)) if (serie.areaStyle.show && (serie.index == 0 || !isStack))
{ {
if (k == 1 && dataIndex > startIndex + 1) var isAllLessthen0 = IsAllLessthen0(isYAxis, zeroPos, start, to);
areaColor = isYAxis ? GetYLerpColor(sourAreaColor, areaToColor, start) : GetXLerpColor(sourAreaColor, areaToColor, start);
if (startAreaDn == Vector3.zero)
{ {
startDn = smoothStartPosDn; if (IsInRightOrUp(isYAxis, lastAreaDownEndPos, startDn) && IsInRightOrUp(isYAxis, lastAreaDownEndPos, toDn))
}
if (startDn != Vector3.zero)
{ {
if (isYAxis) startAreaDn = startDn;
if (lastAreaDownEndPos != Vector3.zero && !isAllLessthen0)
{ {
if (start.x > zeroPos.x && to.x > zeroPos.x) DrawPolygonToZero(vh, lastAreaDownEndPos, startAreaDn, xAxis, zeroPos, areaColor, areaToColor, Vector3.zero);
{
tnp = new Vector3(zeroPos.x + xAxis.axisLine.width, toDn.y);
tlp = new Vector3(zeroPos.x + xAxis.axisLine.width, startDn.y);
areaColor = GetYLerpColor(sourAreaColor, areaToColor, start);
CheckClipAndDrawPolygon(vh, startDn, toDn, tnp, tlp, areaColor, areaToColor, serie.clip);
}
else if (start.x < zeroPos.x && to.x < zeroPos.x)
{
tnp = new Vector3(zeroPos.x - xAxis.axisLine.width, toUp.y);
tlp = new Vector3(zeroPos.x - xAxis.axisLine.width, startUp.y);
areaColor = GetYLerpColor(sourAreaColor, areaToColor, start);
CheckClipAndDrawPolygon(vh, tnp, tlp, startUp, toUp, areaToColor, areaColor, serie.clip);
} }
} }
else
{
if (start.y > zeroPos.y && to.y > zeroPos.y)
{
tnp = new Vector3(toDn.x, zeroPos.y + xAxis.axisLine.width);
tlp = new Vector3(startDn.x, zeroPos.y + xAxis.axisLine.width);
areaColor = GetXLerpColor(sourAreaColor, areaToColor, start);
CheckClipAndDrawPolygon(vh, startDn, toDn, tnp, tlp, areaColor, areaToColor, serie.clip);
} }
else if (start.y < zeroPos.y && to.y < zeroPos.y) if (startAreaUp == Vector3.zero)
{ {
tnp = new Vector3(toUp.x, zeroPos.y - xAxis.axisLine.width); if (IsInRightOrUp(isYAxis, lastAreaUpEndPos, startUp) && IsInRightOrUp(isYAxis, lastAreaUpEndPos, toUp))
tlp = new Vector3(startUp.x, zeroPos.y - xAxis.axisLine.width); {
areaColor = GetXLerpColor(sourAreaColor, areaToColor, start); startAreaUp = startUp;
CheckClipAndDrawPolygon(vh, tlp, tnp, toUp, startUp, areaToColor, areaColor, serie.clip); if (lastAreaUpEndPos != Vector3.zero && isAllLessthen0)
{
DrawPolygonToZero(vh, lastAreaUpEndPos, startAreaUp, xAxis, zeroPos, areaColor, areaToColor, Vector3.zero);
} }
} }
} }
if (startAreaDn != Vector3.zero)
{
if (!isAllLessthen0 && IsInRightOrUp(isYAxis, startAreaDn, toDn))
{
DrawPolygonToZero(vh, startAreaDn, toDn, xAxis, zeroPos, areaColor, areaToColor, Vector3.zero);
}
startAreaDn = toDn;
}
if (startAreaUp != Vector3.zero)
{
if (isAllLessthen0 && IsInRightOrUp(isYAxis, startAreaUp, toUp))
{
DrawPolygonToZero(vh, startAreaUp, toUp, xAxis, zeroPos, areaColor, areaToColor, Vector3.zero);
}
startAreaUp = toUp;
}
} }
start = to; start = to;
startUp = toUp; startUp = toUp;
@@ -1209,6 +1224,31 @@ namespace XCharts
return isFinish; return isFinish;
} }
private bool IsAllLessthen0(bool isYAxis, Vector3 zeroPos, Vector3 start, Vector3 to)
{
if (isYAxis) return start.x < zeroPos.x && to.x < zeroPos.x;
else return start.y < zeroPos.y && to.y < zeroPos.y;
}
private Vector3 GetLastSmoothPos(List<Vector3> list, bool isYAxis)
{
var count = list.Count;
if (count <= 0) return Vector3.zero;
var pos = list[count - 1];
for (int i = count - 2; i > count - 4 && i > 0; i--)
{
if (isYAxis)
{
if (list[i].y > pos.y) pos = list[i];
}
else
{
if (list[i].x > pos.x) pos = list[i];
}
}
return pos;
}
private void DrawStackArea(VertexHelper vh, Serie serie, Axis axis, List<Vector3> smoothPoints, private void DrawStackArea(VertexHelper vh, Serie serie, Axis axis, List<Vector3> smoothPoints,
List<Vector3> lastSmoothPoints, Color lineColor, Color areaColor, Color areaToColor) List<Vector3> lastSmoothPoints, Color lineColor, Color areaColor, Color areaToColor)
{ {