From b01c2e4338a453ebd8ab96e6e311795bb88bdfd6 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 29 Aug 2022 21:09:27 +0800 Subject: [PATCH] [improve][CandlestickChart] improve large data rendering --- CHANGELOG.md | 1 + .../Serie/Candlestick/CandlestickHandler.cs | 58 +++++++++-------- .../SimplifiedCandlestickHandler.cs | 64 ++++++++++--------- Runtime/Serie/SerieData.cs | 17 +++++ Runtime/Serie/SeriesHelper.cs | 15 +++-- 5 files changed, 94 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 653c567b..5a53a262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ ## master +* (2022.08.29) 优化`CandlestickChart`大量数据绘制 * (2022.08.28) 修复`LineChart`在堆叠和自定义Y轴范围的情况下显示不正常的问题 * (2022.08.26) 增加`Legend`新图标类型`Candlestick` * (2022.08.26) 优化`CandlestickChart`表现,调整相关的`AddData()`接口参数 diff --git a/Runtime/Serie/Candlestick/CandlestickHandler.cs b/Runtime/Serie/Candlestick/CandlestickHandler.cs index 3fe8b247..9c98e21b 100644 --- a/Runtime/Serie/Candlestick/CandlestickHandler.cs +++ b/Runtime/Serie/Candlestick/CandlestickHandler.cs @@ -105,6 +105,7 @@ namespace XCharts.Runtime var isYAxis = false; serie.containerIndex = grid.index; serie.containterInstanceId = grid.instanceId; + var intensive = grid.context.width / (maxCount - serie.minShow) < 0.6f; for (int i = serie.minShow; i < maxCount; i++) { var serieData = showData[i]; @@ -170,37 +171,44 @@ namespace XCharts.Runtime var heighPos = new Vector3(center.x, zeroY + (float) ((heighest - minCut) / valueTotal * grid.context.height)); var openCenterPos = new Vector3(center.x, prb.y); var closeCenterPos = new Vector3(center.x, prt.y); - if (barWidth > 2f * borderWidth) + if (intensive) { - if (itemWidth > 0 && itemHeight > 0) + UGL.DrawLine(vh, lowPos, heighPos, borderWidth, borderColor); + } + else + { + if (barWidth > 2f * borderWidth) { - if (itemStyle.IsNeedCorner()) + if (itemWidth > 0 && itemHeight > 0) { - UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, + if (itemStyle.IsNeedCorner()) + { + UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, + itemStyle.cornerRadius, isYAxis, 0.5f); + } + else + { + chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, + serie.clip, grid); + } + UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, itemStyle.cornerRadius, isYAxis, 0.5f); } - else - { - chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, - serie.clip, grid); - } - UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, - itemStyle.cornerRadius, isYAxis, 0.5f); } - } - else - { - UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); - } - if (isRise) - { - UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); - } - else - { - UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); + else + { + UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); + } + if (isRise) + { + UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); + UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); + } + else + { + UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); + UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); + } } } if (!serie.animation.IsFinish()) diff --git a/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs b/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs index c10380b7..c6066a42 100644 --- a/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs +++ b/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs @@ -106,7 +106,7 @@ namespace XCharts.Runtime var itemStyle = serie.itemStyle; serie.containerIndex = grid.index; serie.containterInstanceId = grid.instanceId; - + var intensive = grid.context.width / (maxCount - serie.minShow) < 0.6f; for (int i = serie.minShow; i < maxCount; i++) { var serieData = showData[i]; @@ -170,39 +170,45 @@ namespace XCharts.Runtime var heighPos = new Vector3(center.x, zeroY + (float) ((heighest - minCut) / valueTotal * grid.context.height)); var openCenterPos = new Vector3(center.x, prb.y); var closeCenterPos = new Vector3(center.x, prt.y); - if (barWidth > 2f * borderWidth) + if (intensive) { - if (itemWidth > 0 && itemHeight > 0) - { - if (itemStyle.IsNeedCorner()) - { - UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, - itemStyle.cornerRadius, isYAxis, 0.5f); - } - else - { - chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, - serie.clip, grid); - } - UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, - itemStyle.cornerRadius, isYAxis, 0.5f); - } - if (isRise) - { - UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); - } - else - { - UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); - } + UGL.DrawLine(vh, lowPos, heighPos, borderWidth, borderColor); } else { - UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); + if (barWidth > 2f * borderWidth) + { + if (itemWidth > 0 && itemHeight > 0) + { + if (itemStyle.IsNeedCorner()) + { + UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, + itemStyle.cornerRadius, isYAxis, 0.5f); + } + else + { + chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, + serie.clip, grid); + } + UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, + itemStyle.cornerRadius, isYAxis, 0.5f); + } + if (isRise) + { + UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); + UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); + } + else + { + UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); + UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); + } + } + else + { + UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); + } } - } if (!serie.animation.IsFinish()) { diff --git a/Runtime/Serie/SerieData.cs b/Runtime/Serie/SerieData.cs index bd43a936..0b0e10bd 100644 --- a/Runtime/Serie/SerieData.cs +++ b/Runtime/Serie/SerieData.cs @@ -478,6 +478,23 @@ namespace XCharts.Runtime return temp; } + public void GetMinMaxData(int startDimensionIndex, bool inverse, out double min, out double max) + { + if (m_Data.Count == 0) + { + min = 0; + max = 0; + } + min = double.MaxValue; + max = double.MinValue; + for (int i = startDimensionIndex; i < m_Data.Count; i++) + { + var value = GetData(i, inverse); + if (value < min) min = value; + if (value > max) max = value; + } + } + public double GetTotalData() { var total = 0d; diff --git a/Runtime/Serie/SeriesHelper.cs b/Runtime/Serie/SeriesHelper.cs index a4fd0e6e..3e969355 100644 --- a/Runtime/Serie/SeriesHelper.cs +++ b/Runtime/Serie/SeriesHelper.cs @@ -344,19 +344,20 @@ namespace XCharts.Runtime else { var showData = serie.GetDataList(dataZoom); - foreach (var data in showData) + if (serie is Candlestick || serie is SimplifiedCandlestick) { - - if (serie is Candlestick) + foreach (var data in showData) { - var dataMin = data.GetMinData(inverse); - var dataMax = data.GetMaxData(inverse); + double dataMin, dataMax; + data.GetMinMaxData(1, inverse, out dataMin, out dataMax); if (dataMax > max) max = dataMax; if (dataMin < min) min = dataMin; } - else + } + else + { + foreach (var data in showData) { - //var currData = data.GetData(yValue ? 1 : 0, inverse); var currData = data.GetCurrData(yValue ? 1 : 0, updateDuration, inverse); if (!serie.IsIgnoreValue(currData)) {