增加PieLabelLinelineEndX的支持

This commit is contained in:
monitor1394
2023-08-08 13:24:37 +08:00
parent 0d1d2460a0
commit 5356e2304c
7 changed files with 256 additions and 282 deletions

View File

@@ -81,8 +81,8 @@ namespace XCharts.Runtime
set { if (PropertyUtil.SetStruct(ref m_LineColor, value)) SetVerticesDirty(); }
}
/// <summary>
/// the angle of visual guild line.
/// |视觉引导线的固定角度。对折线和曲线有效。
/// the angle of visual guild line. Valid for broken line and curve line. Invalid in Pie.
/// |视觉引导线的固定角度。对折线和曲线有效。在Pie中无效。
/// </summary>
public float lineAngle
{

View File

@@ -71,167 +71,6 @@ namespace XCharts.Runtime
}
}
public static void UpdatePieLabelPosition(Serie serie, SerieData serieData)
{
if (serieData.labelObject == null) return;
var startAngle = serie.context.startAngle;
var currAngle = serieData.context.halfAngle;
var currRad = currAngle * Mathf.Deg2Rad;
var offsetRadius = serieData.context.offsetRadius;
var insideRadius = serieData.context.insideRadius;
var outsideRadius = serieData.context.outsideRadius;
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData);
var center = serieData.context.offsetCenter;
var interact = false;
serieData.interact.TryGetValueAndColor(ref outsideRadius, ref center, ref interact, serie.animation.GetInteractionDuration());
switch (serieLabel.position)
{
case LabelStyle.Position.Center:
serieData.context.labelPosition = serie.context.center;
break;
case LabelStyle.Position.Inside:
var labelRadius = offsetRadius + insideRadius + (outsideRadius - insideRadius) / 2 + serieLabel.distance;
var labelCenter = new Vector2(center.x + labelRadius * Mathf.Sin(currRad),
center.y + labelRadius * Mathf.Cos(currRad));
serieData.context.labelPosition = labelCenter;
break;
default:
//LabelStyle.Position.Outside
if (labelLine != null && labelLine.lineType == LabelLine.LineType.HorizontalLine)
{
var radius1 = serie.context.outsideRadius;
var radius3 = insideRadius + (outsideRadius - insideRadius) / 2;
var currSin = Mathf.Sin(currRad);
var currCos = Mathf.Cos(currRad);
var pos0 = new Vector3(center.x + radius3 * currSin, center.y + radius3 * currCos);
if ((currAngle - startAngle) % 360 > 180)
{
currSin = Mathf.Sin((360 - currAngle) * Mathf.Deg2Rad);
currCos = Mathf.Cos((360 - currAngle) * Mathf.Deg2Rad);
}
var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos * radius3, 2)) - currSin * radius3;
r4 += labelLine.lineLength1 + labelLine.lineWidth * 4;
r4 += serieData.labelObject.text.GetPreferredWidth() / 2;
serieData.context.labelPosition = pos0 + ((currAngle - startAngle) % 360 > 180 ? Vector3.left : Vector3.right) * r4;
}
else
{
labelRadius = serie.context.outsideRadius + (labelLine == null ? 0 : labelLine.lineLength1);
labelCenter = new Vector2(center.x + labelRadius * Mathf.Sin(currRad),
center.y + labelRadius * Mathf.Cos(currRad));
serieData.context.labelPosition = labelCenter;
}
break;
}
}
public static void AvoidLabelOverlap(Serie serie, ComponentTheme theme)
{
if (!serie.avoidLabelOverlap) return;
var lastCheckPos = Vector3.zero;
var lastX = 0f;
var data = serie.data;
var splitCount = 0;
for (int n = 0; n < data.Count; n++)
{
var serieData = data[n];
if (serieData.context.labelPosition.x != 0 && serieData.context.labelPosition.x < serie.context.center.x)
{
splitCount = n;
break;
}
}
for (int n = 0; n < splitCount; n++)
{
CheckSerieDataLabel(serie, data[n], splitCount, false, theme, ref lastCheckPos, ref lastX);
}
lastCheckPos = Vector3.zero;
for (int n = data.Count - 1; n >= splitCount; n--)
{
CheckSerieDataLabel(serie, data[n], data.Count - splitCount, true, theme, ref lastCheckPos, ref lastX);
}
}
private static void CheckSerieDataLabel(Serie serie, SerieData serieData, int total, bool isLeft, ComponentTheme theme,
ref Vector3 lastCheckPos, ref float lastX)
{
if (!serieData.context.canShowLabel)
{
serieData.SetLabelActive(false);
return;
}
if (!serieData.show) return;
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
if (serieLabel == null) return;
var isOutside = serieLabel.position == LabelStyle.Position.Outside ||
serieLabel.position == LabelStyle.Position.Default;
if (!serieLabel.show) return;
if (!isOutside) return;
var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData);
var fontSize = serieData.labelObject.GetHeight();
if (lastCheckPos == Vector3.zero)
{
lastCheckPos = serieData.context.labelPosition;
}
else if (serieData.context.labelPosition.x != 0)
{
if (lastCheckPos.y - serieData.context.labelPosition.y < fontSize)
{
var labelRadius = serie.context.outsideRadius + labelLine.lineLength1;
var y1 = lastCheckPos.y - fontSize;
var cy = serie.context.center.y;
var diff = Mathf.Abs(y1 - cy);
var diffX = labelRadius * labelRadius - diff * diff;
diffX = diffX <= 0 ? 0 : diffX;
var x1 = serie.context.center.x + Mathf.Sqrt(diffX) * (isLeft ? -1 : 1);
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;
serieData.labelObject.SetPosition(SerieLabelHelper.GetRealLabelPosition(serie, serieData, serieLabel, labelLine));
}
}
public static Vector3 GetRealLabelPosition(Serie serie, SerieData serieData, LabelStyle label, LabelLine labelLine)
{
if (label == null || labelLine == null)
return serieData.context.labelPosition;
var isOutside = label.position == LabelStyle.Position.Outside ||
label.position == LabelStyle.Position.Default;
if (isOutside && labelLine.lineType != LabelLine.LineType.HorizontalLine)
{
var currAngle = serieData.context.halfAngle;
var offset = labelLine.lineLength2 + serieData.labelObject.GetTextWidth() / 2;
var angle = (currAngle - serie.context.startAngle) % 360;
var isLeft = angle > 180 || (angle == 0 && serieData.context.startAngle > 0);
if (isLeft)
return serieData.context.labelPosition + new Vector3(-offset, 0, 0);
else
return serieData.context.labelPosition + new Vector3(offset, 0, 0);
}
else
{
return serieData.context.labelPosition;
}
}
}
}