mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-25 10:20:10 +00:00
优化PieChart绘制表现效果#85
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
# 更新日志
|
# 更新日志
|
||||||
|
|
||||||
|
* (2020.08.15) Optimize `PieChart` drawing performance effect #85
|
||||||
* (2020.08.11) Added `LiquidChart` data change animation#83
|
* (2020.08.11) Added `LiquidChart` data change animation#83
|
||||||
* (2020.08.11) Optimize `PieChart` text stack and lead line effects#85
|
* (2020.08.11) Optimize `PieChart` text stack and lead line effects#85
|
||||||
* (2020.08.08) Optimize `LineChart` the rendering performance of dense data
|
* (2020.08.08) Optimize `LineChart` the rendering performance of dense data
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
# 更新日志
|
# 更新日志
|
||||||
|
|
||||||
|
* (2020.08.15) 优化`PieChart`绘制表现效果#85
|
||||||
* (2020.08.11) 增加`LiquidChart`数据变更动画#83
|
* (2020.08.11) 增加`LiquidChart`数据变更动画#83
|
||||||
* (2020.08.11) 优化`PieChart`文本堆叠和引线效果#85
|
* (2020.08.11) 优化`PieChart`文本堆叠和引线效果#85
|
||||||
* (2020.08.08) 优化`LineChart`密集数据的绘制表现效果
|
* (2020.08.08) 优化`LineChart`密集数据的绘制表现效果
|
||||||
@@ -231,7 +232,7 @@
|
|||||||
* (2019.08.06) 修复`serie`系列数超过调色盘颜色数时获取的颜色异常的问题
|
* (2019.08.06) 修复`serie`系列数超过调色盘颜色数时获取的颜色异常的问题
|
||||||
* (2019.08.06) 修复当`Axis`的`minMaxType`为`Custom`时`max`设置为`100`不生效的问题
|
* (2019.08.06) 修复当`Axis`的`minMaxType`为`Custom`时`max`设置为`100`不生效的问题
|
||||||
* (2019.08.04) 发布`v0.8.1`版本
|
* (2019.08.04) 发布`v0.8.1`版本
|
||||||
* (2019.08.04) 修复从Inspector中修改数据不生效的问题
|
* (2019.08.04) 修复`Inspector`中修改数据不生效的问题
|
||||||
* (2019.08.04) 发布`v0.8.0`版本
|
* (2019.08.04) 发布`v0.8.0`版本
|
||||||
* (2019.08.04) 优化`RadarChart`雷达图,增加多雷达图支持
|
* (2019.08.04) 优化`RadarChart`雷达图,增加多雷达图支持
|
||||||
* (2019.08.01) 增加代码API注释文档,整理代码
|
* (2019.08.01) 增加代码API注释文档,整理代码
|
||||||
|
|||||||
@@ -49,28 +49,25 @@ namespace XCharts
|
|||||||
protected override void DrawChart(VertexHelper vh)
|
protected override void DrawChart(VertexHelper vh)
|
||||||
{
|
{
|
||||||
base.DrawChart(vh);
|
base.DrawChart(vh);
|
||||||
int serieNameCount = -1;
|
UpdateRuntimeData();
|
||||||
bool isClickOffset = false;
|
|
||||||
bool isDataHighlight = false;
|
|
||||||
|
|
||||||
DrawLabelLine(vh);
|
DrawLabelLine(vh);
|
||||||
|
DrawPie(vh);
|
||||||
|
DrawLabelBackground(vh);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRuntimeData()
|
||||||
|
{
|
||||||
for (int i = 0; i < m_Series.Count; i++)
|
for (int i = 0; i < m_Series.Count; i++)
|
||||||
{
|
{
|
||||||
var serie = m_Series.list[i];
|
var serie = m_Series.list[i];
|
||||||
|
if (serie.type != SerieType.Pie) continue;
|
||||||
serie.index = i;
|
serie.index = i;
|
||||||
var data = serie.data;
|
var data = serie.data;
|
||||||
serie.animation.InitProgress(data.Count, 0, 360);
|
|
||||||
if (!serie.show || serie.animation.HasFadeOut())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bool isFinish = true;
|
|
||||||
if (serie.pieClickOffset) isClickOffset = true;
|
|
||||||
serie.runtimeDataMax = serie.yMax;
|
serie.runtimeDataMax = serie.yMax;
|
||||||
serie.runtimePieDataTotal = serie.yTotal;
|
serie.runtimePieDataTotal = serie.yTotal;
|
||||||
|
serie.animation.InitProgress(data.Count, 0, 360);
|
||||||
SerieHelper.UpdateCenter(serie, chartPosition, chartWidth, chartHeight);
|
SerieHelper.UpdateCenter(serie, chartPosition, chartWidth, chartHeight);
|
||||||
|
float totalDegree = 360f;
|
||||||
float totalDegree = 360;
|
|
||||||
float startDegree = 0;
|
float startDegree = 0;
|
||||||
int showdataCount = 0;
|
int showdataCount = 0;
|
||||||
foreach (var sd in serie.data)
|
foreach (var sd in serie.data)
|
||||||
@@ -78,14 +75,13 @@ namespace XCharts
|
|||||||
if (sd.show && serie.pieRoseType == RoseType.Area) showdataCount++;
|
if (sd.show && serie.pieRoseType == RoseType.Area) showdataCount++;
|
||||||
sd.canShowLabel = false;
|
sd.canShowLabel = false;
|
||||||
}
|
}
|
||||||
bool dataChanging = false;
|
|
||||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||||
bool isAllZeroValue = SerieHelper.IsAllZeroValue(serie, 1);
|
bool isAllZeroValue = SerieHelper.IsAllZeroValue(serie, 1);
|
||||||
float zeroReplaceValue = 360f / data.Count;
|
float zeroReplaceValue = totalDegree / data.Count;
|
||||||
if (isAllZeroValue)
|
if (isAllZeroValue)
|
||||||
{
|
{
|
||||||
serie.runtimeDataMax = zeroReplaceValue;
|
serie.runtimeDataMax = zeroReplaceValue;
|
||||||
serie.runtimePieDataTotal = 360f;
|
serie.runtimePieDataTotal = totalDegree;
|
||||||
}
|
}
|
||||||
for (int n = 0; n < data.Count; n++)
|
for (int n = 0; n < data.Count; n++)
|
||||||
{
|
{
|
||||||
@@ -93,13 +89,6 @@ namespace XCharts
|
|||||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.highlighted);
|
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.highlighted);
|
||||||
serieData.index = n;
|
serieData.index = n;
|
||||||
float value = isAllZeroValue ? zeroReplaceValue : serieData.GetCurrData(1, dataChangeDuration);
|
float value = isAllZeroValue ? zeroReplaceValue : serieData.GetCurrData(1, dataChangeDuration);
|
||||||
if (serieData.IsDataChanged()) dataChanging = true;
|
|
||||||
serieNameCount = m_LegendRealShowName.IndexOf(serieData.legendName);
|
|
||||||
var color = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, serieNameCount, serieData.highlighted);
|
|
||||||
var toColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, serieNameCount, serieData.highlighted);
|
|
||||||
var borderWidth = itemStyle.borderWidth;
|
|
||||||
var borderColor = itemStyle.borderColor;
|
|
||||||
|
|
||||||
serieData.runtimePieStartAngle = startDegree;
|
serieData.runtimePieStartAngle = startDegree;
|
||||||
serieData.runtimePieToAngle = startDegree;
|
serieData.runtimePieToAngle = startDegree;
|
||||||
serieData.runtimePieHalfAngle = startDegree;
|
serieData.runtimePieHalfAngle = startDegree;
|
||||||
@@ -117,7 +106,6 @@ namespace XCharts
|
|||||||
serie.runtimeOutsideRadius;
|
serie.runtimeOutsideRadius;
|
||||||
if (serieData.highlighted)
|
if (serieData.highlighted)
|
||||||
{
|
{
|
||||||
isDataHighlight = true;
|
|
||||||
serieData.runtimePieOutsideRadius += m_Settings.pieTooltipExtraRadius;
|
serieData.runtimePieOutsideRadius += m_Settings.pieTooltipExtraRadius;
|
||||||
}
|
}
|
||||||
var offset = 0f;
|
var offset = 0f;
|
||||||
@@ -125,23 +113,23 @@ namespace XCharts
|
|||||||
{
|
{
|
||||||
offset += m_Settings.pieSelectedOffset;
|
offset += m_Settings.pieSelectedOffset;
|
||||||
}
|
}
|
||||||
var halfDegree = (serieData.runtimePieToAngle - startDegree) / 2;
|
|
||||||
serieData.runtimePieHalfAngle = startDegree + halfDegree;
|
|
||||||
float currRad = serieData.runtimePieHalfAngle * Mathf.Deg2Rad;
|
|
||||||
float currSin = Mathf.Sin(currRad);
|
|
||||||
float currCos = Mathf.Cos(currRad);
|
|
||||||
var center = serie.runtimeCenterPos;
|
|
||||||
|
|
||||||
serieData.runtimePieCurrAngle = serieData.runtimePieToAngle;
|
|
||||||
serieData.runtiemPieOffsetCenter = center;
|
|
||||||
serieData.runtimePieInsideRadius = serie.runtimeInsideRadius;
|
|
||||||
if (serie.animation.CheckDetailBreak(serieData.runtimePieToAngle))
|
if (serie.animation.CheckDetailBreak(serieData.runtimePieToAngle))
|
||||||
{
|
{
|
||||||
isFinish = false;
|
|
||||||
serieData.runtimePieCurrAngle = serie.animation.GetCurrDetail();
|
serieData.runtimePieCurrAngle = serie.animation.GetCurrDetail();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serieData.runtimePieCurrAngle = serieData.runtimePieToAngle;
|
||||||
|
}
|
||||||
|
var halfDegree = (serieData.runtimePieToAngle - startDegree) / 2;
|
||||||
|
serieData.runtimePieHalfAngle = startDegree + halfDegree;
|
||||||
|
serieData.runtiemPieOffsetCenter = serie.runtimeCenterPos;
|
||||||
|
serieData.runtimePieInsideRadius = serie.runtimeInsideRadius;
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
|
var currRad = serieData.runtimePieHalfAngle * Mathf.Deg2Rad;
|
||||||
|
var currSin = Mathf.Sin(currRad);
|
||||||
|
var currCos = Mathf.Cos(currRad);
|
||||||
serieData.runtimePieOffsetRadius = 0;
|
serieData.runtimePieOffsetRadius = 0;
|
||||||
serieData.runtimePieInsideRadius -= serieData.runtimePieOffsetRadius;
|
serieData.runtimePieInsideRadius -= serieData.runtimePieOffsetRadius;
|
||||||
serieData.runtimePieOutsideRadius -= serieData.runtimePieOffsetRadius;
|
serieData.runtimePieOutsideRadius -= serieData.runtimePieOffsetRadius;
|
||||||
@@ -151,29 +139,82 @@ namespace XCharts
|
|||||||
if (serieData.runtimePieInsideRadius > 0) serieData.runtimePieInsideRadius += m_Settings.pieSelectedOffset;
|
if (serieData.runtimePieInsideRadius > 0) serieData.runtimePieInsideRadius += m_Settings.pieSelectedOffset;
|
||||||
serieData.runtimePieOutsideRadius += m_Settings.pieSelectedOffset;
|
serieData.runtimePieOutsideRadius += m_Settings.pieSelectedOffset;
|
||||||
}
|
}
|
||||||
|
serieData.runtiemPieOffsetCenter = new Vector3(serie.runtimeCenterPos.x + serieData.runtimePieOffsetRadius * currSin,
|
||||||
|
serie.runtimeCenterPos.y + serieData.runtimePieOffsetRadius * currCos);
|
||||||
|
}
|
||||||
|
serieData.canShowLabel = serieData.runtimePieCurrAngle >= serieData.runtimePieHalfAngle;
|
||||||
|
startDegree = serieData.runtimePieToAngle;
|
||||||
|
SerieLabelHelper.UpdatePieLabelPosition(serie, serieData);
|
||||||
|
}
|
||||||
|
SerieLabelHelper.AvoidLabelOverlap(serie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
serieData.runtiemPieOffsetCenter = new Vector3(center.x + serieData.runtimePieOffsetRadius * currSin,
|
private void DrawCenter(VertexHelper vh, Serie serie, ItemStyle itemStyle, float insideRadius)
|
||||||
center.y + serieData.runtimePieOffsetRadius * currCos);
|
{
|
||||||
|
if (!ChartHelper.IsClearColor(itemStyle.centerColor))
|
||||||
|
{
|
||||||
|
var radius = insideRadius - itemStyle.centerGap;
|
||||||
|
ChartDrawer.DrawCricle(vh, serie.runtimeCenterPos, radius, itemStyle.centerColor, m_Settings.cicleSmoothness);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawPie(VertexHelper vh)
|
||||||
|
{
|
||||||
|
bool isClickOffset = false;
|
||||||
|
bool isDataHighlight = false;
|
||||||
|
for (int i = 0; i < m_Series.Count; i++)
|
||||||
|
{
|
||||||
|
var serie = m_Series.list[i];
|
||||||
|
serie.index = i;
|
||||||
|
var data = serie.data;
|
||||||
|
serie.animation.InitProgress(data.Count, 0, 360);
|
||||||
|
if (!serie.show || serie.animation.HasFadeOut())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (serie.pieClickOffset) isClickOffset = true;
|
||||||
|
bool dataChanging = false;
|
||||||
|
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||||
|
bool isAllZeroValue = SerieHelper.IsAllZeroValue(serie, 1);
|
||||||
|
for (int n = 0; n < data.Count; n++)
|
||||||
|
{
|
||||||
|
var serieData = data[n];
|
||||||
|
if (!serieData.show)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.highlighted);
|
||||||
|
if (serieData.IsDataChanged()) dataChanging = true;
|
||||||
|
var serieNameCount = m_LegendRealShowName.IndexOf(serieData.legendName);
|
||||||
|
var color = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, serieNameCount, serieData.highlighted);
|
||||||
|
var toColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, serieNameCount, serieData.highlighted);
|
||||||
|
var borderWidth = itemStyle.borderWidth;
|
||||||
|
var borderColor = itemStyle.borderColor;
|
||||||
|
|
||||||
|
if (serieData.highlighted)
|
||||||
|
{
|
||||||
|
isDataHighlight = true;
|
||||||
|
}
|
||||||
|
if (serie.pieClickOffset && serieData.selected)
|
||||||
|
{
|
||||||
var drawEndDegree = serieData.runtimePieCurrAngle;
|
var drawEndDegree = serieData.runtimePieCurrAngle;
|
||||||
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
|
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
|
||||||
|
|
||||||
ChartDrawer.DrawDoughnut(vh, serieData.runtiemPieOffsetCenter, serieData.runtimePieInsideRadius,
|
ChartDrawer.DrawDoughnut(vh, serieData.runtiemPieOffsetCenter, serieData.runtimePieInsideRadius,
|
||||||
serieData.runtimePieOutsideRadius, color, toColor, Color.clear, startDegree, drawEndDegree,
|
serieData.runtimePieOutsideRadius, color, toColor, Color.clear, serieData.runtimePieStartAngle, drawEndDegree,
|
||||||
borderWidth, borderColor, serie.pieSpace / 2, m_Settings.cicleSmoothness, needRoundCap, true);
|
borderWidth, borderColor, serie.pieSpace / 2, m_Settings.cicleSmoothness, needRoundCap, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var drawEndDegree = serieData.runtimePieCurrAngle;
|
var drawEndDegree = serieData.runtimePieCurrAngle;
|
||||||
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
|
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
|
||||||
ChartDrawer.DrawDoughnut(vh, center, serieData.runtimePieInsideRadius, serieData.runtimePieOutsideRadius,
|
ChartDrawer.DrawDoughnut(vh, serie.runtimeCenterPos, serieData.runtimePieInsideRadius, serieData.runtimePieOutsideRadius,
|
||||||
color, toColor, Color.clear, startDegree, drawEndDegree, borderWidth, borderColor, serie.pieSpace / 2,
|
color, toColor, Color.clear, serieData.runtimePieStartAngle, drawEndDegree, borderWidth, borderColor, serie.pieSpace / 2,
|
||||||
m_Settings.cicleSmoothness, needRoundCap, true);
|
m_Settings.cicleSmoothness, needRoundCap, true);
|
||||||
DrawCenter(vh, serie, itemStyle, serieData.runtimePieInsideRadius);
|
DrawCenter(vh, serie, itemStyle, serieData.runtimePieInsideRadius);
|
||||||
}
|
}
|
||||||
serieData.canShowLabel = serieData.runtimePieCurrAngle >= serieData.runtimePieHalfAngle;
|
|
||||||
isDrawPie = true;
|
isDrawPie = true;
|
||||||
startDegree = serieData.runtimePieToAngle;
|
if (!serie.animation.CheckDetailBreak(serieData.runtimePieToAngle)) serie.animation.SetDataFinish(n);
|
||||||
if (isFinish) serie.animation.SetDataFinish(n);
|
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
if (!serie.animation.IsFinish())
|
if (!serie.animation.IsFinish())
|
||||||
@@ -187,19 +228,9 @@ namespace XCharts
|
|||||||
RefreshChart();
|
RefreshChart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DrawLabelBackground(vh);
|
|
||||||
raycastTarget = isClickOffset && isDataHighlight;
|
raycastTarget = isClickOffset && isDataHighlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawCenter(VertexHelper vh, Serie serie, ItemStyle itemStyle, float insideRadius)
|
|
||||||
{
|
|
||||||
if (!ChartHelper.IsClearColor(itemStyle.centerColor))
|
|
||||||
{
|
|
||||||
var radius = insideRadius - itemStyle.centerGap;
|
|
||||||
ChartDrawer.DrawCricle(vh, serie.runtimeCenterPos, radius, itemStyle.centerColor, m_Settings.cicleSmoothness);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawLabelLine(VertexHelper vh)
|
private void DrawLabelLine(VertexHelper vh)
|
||||||
{
|
{
|
||||||
foreach (var serie in m_Series.list)
|
foreach (var serie in m_Series.list)
|
||||||
@@ -347,7 +378,6 @@ namespace XCharts
|
|||||||
Color color = m_ThemeInfo.GetColor(serieNameCount);
|
Color color = m_ThemeInfo.GetColor(serieNameCount);
|
||||||
DrawLabel(serie, n, serieData, color);
|
DrawLabel(serie, n, serieData, color);
|
||||||
}
|
}
|
||||||
SerieLabelHelper.AvoidLabelOverlap(serie);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,7 +418,6 @@ namespace XCharts
|
|||||||
serieData.labelObject.label.fontSize = fontSize;
|
serieData.labelObject.label.fontSize = fontSize;
|
||||||
serieData.labelObject.label.fontStyle = fontStyle;
|
serieData.labelObject.label.fontStyle = fontStyle;
|
||||||
serieData.labelObject.SetLabelRotate(rotate);
|
serieData.labelObject.SetLabelRotate(rotate);
|
||||||
SerieLabelHelper.UpdatePieLabelPosition(serie, serieData);
|
|
||||||
if (!string.IsNullOrEmpty(serieLabel.formatter))
|
if (!string.IsNullOrEmpty(serieLabel.formatter))
|
||||||
{
|
{
|
||||||
var value = serieData.data[1];
|
var value = serieData.data[1];
|
||||||
|
|||||||
Reference in New Issue
Block a user