mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-25 18:30:14 +00:00
[optimize][pie] avoid label overlap (#56)
This commit is contained in:
@@ -54,6 +54,7 @@
|
|||||||
|
|
||||||
## master
|
## master
|
||||||
|
|
||||||
|
* (2022.06.28) 优化`Pie`设置`avoidLabelOverlap`时的文本表现 (#56)
|
||||||
* (2022.06.25) 优化`Line`的平滑曲线表现 (#169)
|
* (2022.06.25) 优化`Line`的平滑曲线表现 (#169)
|
||||||
* (2022.06.25) 修复`DataZoom`开启时`Tooltip`显示数据不一致的问题 (#203)
|
* (2022.06.25) 修复`DataZoom`开启时`Tooltip`显示数据不一致的问题 (#203)
|
||||||
* (2022.06.25) 修复`Toolip`在类目轴无数据时绘制异常的问题 (#204)
|
* (2022.06.25) 修复`Toolip`在类目轴无数据时绘制异常的问题 (#204)
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ namespace XCharts.Runtime
|
|||||||
public class Padding : ChildComponent
|
public class Padding : ChildComponent
|
||||||
{
|
{
|
||||||
[SerializeField] protected bool m_Show = true;
|
[SerializeField] protected bool m_Show = true;
|
||||||
[SerializeField] protected float m_Top = 2;
|
[SerializeField] protected float m_Top = 0;
|
||||||
[SerializeField] protected float m_Right = 4;
|
[SerializeField] protected float m_Right = 2f;
|
||||||
[SerializeField] protected float m_Left = 4;
|
[SerializeField] protected float m_Left = 2f;
|
||||||
[SerializeField] protected float m_Bottom = 2;
|
[SerializeField] protected float m_Bottom = 0;
|
||||||
|
|
||||||
public Padding() { }
|
public Padding() { }
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ namespace XCharts.Runtime
|
|||||||
/// {d:0.##} indicates that a formatted string with a value specified separately is 0.## (used for percentage, reserved 2 valid digits while avoiding the situation similar to "100.00%" when using f2 ).</br>
|
/// {d:0.##} indicates that a formatted string with a value specified separately is 0.## (used for percentage, reserved 2 valid digits while avoiding the situation similar to "100.00%" when using f2 ).</br>
|
||||||
/// Example: "{a}, {c}", "{a1}, {c1: f1}", "{a1}, {c1:0: f1}", "{a1} : {c1:1-1: f1}"</br>
|
/// Example: "{a}, {c}", "{a1}, {c1: f1}", "{a1}, {c1:0: f1}", "{a1} : {c1:1-1: f1}"</br>
|
||||||
/// |提示框单个serie或数据项内容的字符串模版格式器。支持用 \n 换行。
|
/// |提示框单个serie或数据项内容的字符串模版格式器。支持用 \n 换行。
|
||||||
/// 模板变量有{.}、{a}、{b}、{c}、{d}、{e}。</br>
|
/// 模板变量有{.}、{a}、{b}、{c}、{d}、{e}、{f}。</br>
|
||||||
/// {.}为当前所指示或index为0的serie的对应颜色的圆点。</br>
|
/// {.}为当前所指示或index为0的serie的对应颜色的圆点。</br>
|
||||||
/// {a}为当前所指示或index为0的serie的系列名name。</br>
|
/// {a}为当前所指示或index为0的serie的系列名name。</br>
|
||||||
/// {b}为当前所指示或index为0的serie的数据项serieData的name,或者类目值(如折线图的X轴)。</br>
|
/// {b}为当前所指示或index为0的serie的数据项serieData的name,或者类目值(如折线图的X轴)。</br>
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ namespace XCharts.Runtime
|
|||||||
{
|
{
|
||||||
if (!serie.avoidLabelOverlap) return;
|
if (!serie.avoidLabelOverlap) return;
|
||||||
var lastCheckPos = Vector3.zero;
|
var lastCheckPos = Vector3.zero;
|
||||||
|
var lastX = 0f;
|
||||||
var data = serie.data;
|
var data = serie.data;
|
||||||
var splitCount = 0;
|
var splitCount = 0;
|
||||||
for (int n = 0; n < data.Count; n++)
|
for (int n = 0; n < data.Count; n++)
|
||||||
@@ -143,19 +144,20 @@ namespace XCharts.Runtime
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int n = 0; n < splitCount; n++)
|
for (int n = 0; n < splitCount; n++)
|
||||||
{
|
{
|
||||||
CheckSerieDataLabel(serie, data[n], false, theme, ref lastCheckPos);
|
CheckSerieDataLabel(serie, data[n], splitCount, false, theme, ref lastCheckPos, ref lastX);
|
||||||
}
|
}
|
||||||
lastCheckPos = Vector3.zero;
|
lastCheckPos = Vector3.zero;
|
||||||
for (int n = data.Count - 1; n >= splitCount; n--)
|
for (int n = data.Count - 1; n >= splitCount; n--)
|
||||||
{
|
{
|
||||||
CheckSerieDataLabel(serie, data[n], true, theme, ref lastCheckPos);
|
CheckSerieDataLabel(serie, data[n], data.Count - splitCount, true, theme, ref lastCheckPos, ref lastX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CheckSerieDataLabel(Serie serie, SerieData serieData, bool isLeft, ComponentTheme theme,
|
private static void CheckSerieDataLabel(Serie serie, SerieData serieData, int total, bool isLeft, ComponentTheme theme,
|
||||||
ref Vector3 lastCheckPos)
|
ref Vector3 lastCheckPos, ref float lastX)
|
||||||
{
|
{
|
||||||
if (!serieData.context.canShowLabel)
|
if (!serieData.context.canShowLabel)
|
||||||
{
|
{
|
||||||
@@ -164,12 +166,12 @@ namespace XCharts.Runtime
|
|||||||
}
|
}
|
||||||
if (!serieData.show) return;
|
if (!serieData.show) return;
|
||||||
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
||||||
var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData);
|
|
||||||
var fontSize = serieLabel.textStyle.GetFontSize(theme);
|
|
||||||
var isOutside = serieLabel.position == LabelStyle.Position.Outside ||
|
var isOutside = serieLabel.position == LabelStyle.Position.Outside ||
|
||||||
serieLabel.position == LabelStyle.Position.Default;
|
serieLabel.position == LabelStyle.Position.Default;
|
||||||
if (!serieLabel.show) return;
|
if (!serieLabel.show) return;
|
||||||
if (!isOutside) return;
|
if (!isOutside) return;
|
||||||
|
var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData);
|
||||||
|
var fontSize = serieData.labelObject.GetHeight();
|
||||||
if (lastCheckPos == Vector3.zero)
|
if (lastCheckPos == Vector3.zero)
|
||||||
{
|
{
|
||||||
lastCheckPos = serieData.context.labelPosition;
|
lastCheckPos = serieData.context.labelPosition;
|
||||||
@@ -185,7 +187,25 @@ namespace XCharts.Runtime
|
|||||||
var diffX = labelRadius * labelRadius - diff * diff;
|
var diffX = labelRadius * labelRadius - diff * diff;
|
||||||
diffX = diffX <= 0 ? 0 : diffX;
|
diffX = diffX <= 0 ? 0 : diffX;
|
||||||
var x1 = serie.context.center.x + Mathf.Sqrt(diffX) * (isLeft ? -1 : 1);
|
var x1 = serie.context.center.x + Mathf.Sqrt(diffX) * (isLeft ? -1 : 1);
|
||||||
serieData.context.labelPosition = new Vector3(x1, y1);
|
var newPos = new Vector3(x1, y1);
|
||||||
|
serieData.context.labelPosition = newPos;
|
||||||
|
var angle = ChartHelper.GetAngle360(Vector2.up, newPos - serie.context.center);
|
||||||
|
if (angle >= 180 && angle <= 270)
|
||||||
|
{
|
||||||
|
serieData.context.labelPosition = new Vector3(isLeft?(++lastX):(--lastX), y1);
|
||||||
|
}
|
||||||
|
else if (angle < 180 && angle >= 90)
|
||||||
|
{
|
||||||
|
serieData.context.labelPosition = new Vector3(isLeft?(++lastX):(--lastX), y1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastX = x1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastX = serieData.context.labelPosition.x;
|
||||||
}
|
}
|
||||||
lastCheckPos = serieData.context.labelPosition;
|
lastCheckPos = serieData.context.labelPosition;
|
||||||
serieData.labelObject.SetPosition(SerieLabelHelper.GetRealLabelPosition(serie, serieData, serieLabel, labelLine));
|
serieData.labelObject.SetPosition(SerieLabelHelper.GetRealLabelPosition(serie, serieData, serieLabel, labelLine));
|
||||||
|
|||||||
@@ -15,11 +15,22 @@ namespace XCharts.Runtime
|
|||||||
UpdateSerieContext();
|
UpdateSerieContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void DrawBase(VertexHelper vh)
|
||||||
|
{
|
||||||
|
UpdateRuntimeData(serie);
|
||||||
|
DrawPieLabelLine(vh, serie, false);
|
||||||
|
}
|
||||||
|
|
||||||
public override void DrawSerie(VertexHelper vh)
|
public override void DrawSerie(VertexHelper vh)
|
||||||
{
|
{
|
||||||
UpdateRuntimeData(serie);
|
UpdateRuntimeData(serie);
|
||||||
DrawPieLabelLine(vh, serie);
|
|
||||||
DrawPie(vh, serie);
|
DrawPie(vh, serie);
|
||||||
|
chart.RefreshBasePainter();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawUpper(VertexHelper vh)
|
||||||
|
{
|
||||||
|
DrawPieLabelLine(vh, serie, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||||
@@ -390,11 +401,13 @@ namespace XCharts.Runtime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawPieLabelLine(VertexHelper vh, Serie serie)
|
private void DrawPieLabelLine(VertexHelper vh, Serie serie, bool drawHightlight)
|
||||||
{
|
{
|
||||||
foreach (var serieData in serie.data)
|
foreach (var serieData in serie.data)
|
||||||
{
|
{
|
||||||
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
||||||
|
if (drawHightlight && !serieData.context.highlight) continue;
|
||||||
|
if (!drawHightlight && serieData.context.highlight) continue;
|
||||||
if (SerieLabelHelper.CanShowLabel(serie, serieData, serieLabel, 1))
|
if (SerieLabelHelper.CanShowLabel(serie, serieData, serieLabel, 1))
|
||||||
{
|
{
|
||||||
int colorIndex = chart.m_LegendRealShowName.IndexOf(serieData.name);
|
int colorIndex = chart.m_LegendRealShowName.IndexOf(serieData.name);
|
||||||
@@ -435,7 +448,7 @@ namespace XCharts.Runtime
|
|||||||
var pos2 = serieData.context.labelPosition;
|
var pos2 = serieData.context.labelPosition;
|
||||||
if (pos2.x == 0)
|
if (pos2.x == 0)
|
||||||
{
|
{
|
||||||
pos2 = new Vector3(center.x + radius2 * currSin, center.y + radius2 * currCos);
|
//pos2 = new Vector3(center.x + radius2 * currSin, center.y + radius2 * currCos);
|
||||||
}
|
}
|
||||||
Vector3 pos4, pos6;
|
Vector3 pos4, pos6;
|
||||||
var horizontalLineCircleRadius = labelLine.lineWidth * 4f;
|
var horizontalLineCircleRadius = labelLine.lineWidth * 4f;
|
||||||
@@ -476,19 +489,27 @@ namespace XCharts.Runtime
|
|||||||
var pos5X = (currAngle - startAngle) % 360 > 180 ?
|
var pos5X = (currAngle - startAngle) % 360 > 180 ?
|
||||||
pos2.x - labelLine.lineLength2 : pos2.x + labelLine.lineLength2;
|
pos2.x - labelLine.lineLength2 : pos2.x + labelLine.lineLength2;
|
||||||
var pos5 = new Vector3(pos5X, pos2.y);
|
var pos5 = new Vector3(pos5X, pos2.y);
|
||||||
switch (labelLine.lineType)
|
var angle = Vector3.Angle(pos1 - center, pos2 - pos1);
|
||||||
|
if (angle > 15)
|
||||||
{
|
{
|
||||||
case LabelLine.LineType.BrokenLine:
|
UGL.DrawLine(vh, pos1, pos5, labelLine.lineWidth, color);
|
||||||
UGL.DrawLine(vh, pos1, pos2, pos5, labelLine.lineWidth, color);
|
}
|
||||||
break;
|
else
|
||||||
case LabelLine.LineType.Curves:
|
{
|
||||||
UGL.DrawCurves(vh, pos1, pos5, pos1, pos2, labelLine.lineWidth, color,
|
switch (labelLine.lineType)
|
||||||
chart.settings.lineSmoothness);
|
{
|
||||||
break;
|
case LabelLine.LineType.BrokenLine:
|
||||||
case LabelLine.LineType.HorizontalLine:
|
UGL.DrawLine(vh, pos1, pos2, pos5, labelLine.lineWidth, color);
|
||||||
UGL.DrawCricle(vh, pos0, horizontalLineCircleRadius, color);
|
break;
|
||||||
UGL.DrawLine(vh, pos6, pos4, labelLine.lineWidth, color);
|
case LabelLine.LineType.Curves:
|
||||||
break;
|
UGL.DrawCurves(vh, pos1, pos5, pos1, pos2, labelLine.lineWidth, color,
|
||||||
|
chart.settings.lineSmoothness);
|
||||||
|
break;
|
||||||
|
case LabelLine.LineType.HorizontalLine:
|
||||||
|
UGL.DrawCricle(vh, pos0, horizontalLineCircleRadius, color);
|
||||||
|
UGL.DrawLine(vh, pos6, pos4, labelLine.lineWidth, color);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user