mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-16 13:30:10 +00:00
316 lines
14 KiB
C#
316 lines
14 KiB
C#
/************************************************/
|
|
/* */
|
|
/* Copyright (c) 2018 - 2021 monitor1394 */
|
|
/* https://github.com/monitor1394 */
|
|
/* */
|
|
/************************************************/
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace XCharts
|
|
{
|
|
internal static class SerieLabelHelper
|
|
{
|
|
public static void CheckLabel(Serie serie, ref bool m_ReinitLabel, ref bool m_UpdateLabelText)
|
|
{
|
|
switch (serie.type)
|
|
{
|
|
case SerieType.Gauge:
|
|
case SerieType.Ring:
|
|
var serieData = serie.GetSerieData(0);
|
|
if (serieData != null)
|
|
{
|
|
if (serie.label.show && serie.show)
|
|
{
|
|
if (serieData.labelObject != null)
|
|
{
|
|
serieData.SetLabelActive(true);
|
|
m_UpdateLabelText = true;
|
|
}
|
|
else
|
|
{
|
|
m_ReinitLabel = true;
|
|
}
|
|
}
|
|
else if (serieData.labelObject != null)
|
|
{
|
|
serieData.SetLabelActive(false);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
public static void UpdateLabelText(Series series, ChartTheme theme, List<string> legendRealShowName)
|
|
{
|
|
foreach (var serie in series.list)
|
|
{
|
|
if (!serie.label.show) continue;
|
|
var colorIndex = legendRealShowName.IndexOf(serie.name);
|
|
switch (serie.type)
|
|
{
|
|
case SerieType.Gauge:
|
|
SetGaugeLabelText(serie);
|
|
break;
|
|
case SerieType.Ring:
|
|
SetRingLabelText(serie, theme);
|
|
break;
|
|
case SerieType.Liquid:
|
|
SetLiquidLabelText(serie, theme, colorIndex);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Color GetLabelColor(Serie serie, ChartTheme theme, int index)
|
|
{
|
|
if (!ChartHelper.IsClearColor(serie.label.textStyle.color))
|
|
{
|
|
return serie.label.textStyle.color;
|
|
}
|
|
else
|
|
{
|
|
return theme.GetColor(index);
|
|
}
|
|
}
|
|
|
|
public static void ResetLabel(SerieData serieData, SerieLabel label, ChartTheme theme, int colorIndex)
|
|
{
|
|
if (serieData.labelObject == null) return;
|
|
if (serieData.labelObject.label == null) return;
|
|
serieData.labelObject.label.SetColor(!ChartHelper.IsClearColor(label.textStyle.color) ? label.textStyle.color :
|
|
(Color)theme.GetColor(colorIndex));
|
|
serieData.labelObject.label.SetFontSize(label.textStyle.GetFontSize(theme.common));
|
|
serieData.labelObject.label.SetFontStyle(label.textStyle.fontStyle);
|
|
}
|
|
|
|
public static bool CanShowLabel(Serie serie, SerieData serieData, SerieLabel label, int dimesion)
|
|
{
|
|
return serie.show && serieData.canShowLabel && !serie.IsIgnoreValue(serieData.GetData(dimesion));
|
|
}
|
|
|
|
public static string GetFormatterContent(Serie serie, SerieData serieData,
|
|
float dataValue, float dataTotal, SerieLabel serieLabel = null)
|
|
{
|
|
if (serieLabel == null)
|
|
{
|
|
serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
|
}
|
|
var numericFormatter = serieLabel == null ? serie.label.numericFormatter : serieLabel.numericFormatter;
|
|
var serieName = serie.name;
|
|
var dataName = serieData != null ? serieData.name : null;
|
|
if (string.IsNullOrEmpty(serieLabel.formatter))
|
|
return ChartCached.NumberToStr(dataValue, numericFormatter);
|
|
else
|
|
{
|
|
var content = serieLabel.formatter;
|
|
FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, dataValue,
|
|
dataTotal, serieName, dataName);
|
|
return content;
|
|
}
|
|
}
|
|
|
|
public static void SetGaugeLabelText(Serie serie)
|
|
{
|
|
var serieData = serie.GetSerieData(0);
|
|
if (serieData == null) return;
|
|
if (serieData.labelObject == null) return;
|
|
var value = serieData.GetData(1);
|
|
var total = serie.max;
|
|
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total);
|
|
serieData.labelObject.SetText(content);
|
|
serieData.labelObject.SetLabelPosition(serie.runtimeCenterPos + serie.label.offset);
|
|
if (!ChartHelper.IsClearColor(serie.label.textStyle.color))
|
|
{
|
|
serieData.labelObject.label.SetColor(serie.label.textStyle.color);
|
|
}
|
|
}
|
|
|
|
public static void SetRingLabelText(Serie serie, ChartTheme theme)
|
|
{
|
|
for (int i = 0; i < serie.dataCount; i++)
|
|
{
|
|
var serieData = serie.data[i];
|
|
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData, serieData.highlighted);
|
|
if (serieLabel.show && serieData.labelObject != null)
|
|
{
|
|
if (!serie.show || !serieData.show)
|
|
{
|
|
serieData.SetLabelActive(false);
|
|
continue;
|
|
}
|
|
var value = serieData.GetData(0);
|
|
var total = serieData.GetData(1);
|
|
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total);
|
|
serieData.SetLabelActive(true);
|
|
serieData.labelObject.SetText(content);
|
|
serieData.labelObject.SetLabelColor(GetLabelColor(serie, theme, i));
|
|
|
|
if (serie.label.position == SerieLabel.Position.Bottom)
|
|
{
|
|
var labelWidth = serieData.GetLabelWidth();
|
|
if (serie.clockwise)
|
|
serieData.labelObject.SetLabelPosition(serieData.labelPosition - new Vector3(labelWidth / 2, 0));
|
|
else
|
|
serieData.labelObject.SetLabelPosition(serieData.labelPosition + new Vector3(labelWidth / 2, 0));
|
|
}
|
|
else
|
|
{
|
|
serieData.labelObject.SetLabelPosition(serieData.labelPosition);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void SetLiquidLabelText(Serie serie, ChartTheme theme, int colorIndex)
|
|
{
|
|
var serieData = serie.GetSerieData(0);
|
|
if (serieData == null) return;
|
|
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData, serieData.highlighted);
|
|
if (serieLabel.show && serieData.labelObject != null)
|
|
{
|
|
if (!serie.show || !serieData.show)
|
|
{
|
|
serieData.SetLabelActive(false);
|
|
return;
|
|
}
|
|
var value = serieData.GetData(1);
|
|
var total = serie.max - serie.min;
|
|
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total);
|
|
serieData.SetLabelActive(true);
|
|
serieData.labelObject.SetText(content);
|
|
serieData.labelObject.SetLabelColor(GetLabelColor(serie, theme, colorIndex));
|
|
serieData.labelObject.SetLabelPosition(serieData.labelPosition + serieLabel.offset);
|
|
}
|
|
}
|
|
|
|
public static void UpdatePieLabelPosition(Serie serie, SerieData serieData)
|
|
{
|
|
if (serieData.labelObject == null) return;
|
|
var currAngle = serieData.runtimePieHalfAngle;
|
|
var currRad = currAngle * Mathf.Deg2Rad;
|
|
var offsetRadius = serieData.runtimePieOffsetRadius;
|
|
var insideRadius = serieData.runtimePieInsideRadius;
|
|
var outsideRadius = serieData.runtimePieOutsideRadius;
|
|
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
|
switch (serieLabel.position)
|
|
{
|
|
case SerieLabel.Position.Center:
|
|
serieData.labelPosition = serie.runtimeCenterPos;
|
|
break;
|
|
case SerieLabel.Position.Inside:
|
|
var labelRadius = offsetRadius + insideRadius + (outsideRadius - insideRadius) / 2;
|
|
var labelCenter = new Vector2(serie.runtimeCenterPos.x + labelRadius * Mathf.Sin(currRad),
|
|
serie.runtimeCenterPos.y + labelRadius * Mathf.Cos(currRad));
|
|
serieData.labelPosition = labelCenter;
|
|
break;
|
|
case SerieLabel.Position.Outside:
|
|
if (serieLabel.lineType == SerieLabel.LineType.HorizontalLine)
|
|
{
|
|
var radius1 = serie.runtimeOutsideRadius;
|
|
var radius3 = insideRadius + (outsideRadius - insideRadius) / 2;
|
|
var currSin = Mathf.Sin(currRad);
|
|
var currCos = Mathf.Cos(currRad);
|
|
var pos0 = new Vector3(serie.runtimeCenterPos.x + radius3 * currSin, serie.runtimeCenterPos.y + radius3 * currCos);
|
|
if (currAngle > 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 += serieLabel.lineLength1 + serieLabel.lineWidth * 4;
|
|
r4 += serieData.labelObject.label.GetPreferredWidth() / 2;
|
|
serieData.labelPosition = pos0 + (currAngle > 180 ? Vector3.left : Vector3.right) * r4;
|
|
}
|
|
else
|
|
{
|
|
labelRadius = serie.runtimeOutsideRadius + serieLabel.lineLength1;
|
|
labelCenter = new Vector2(serie.runtimeCenterPos.x + labelRadius * Mathf.Sin(currRad),
|
|
serie.runtimeCenterPos.y + labelRadius * Mathf.Cos(currRad));
|
|
serieData.labelPosition = labelCenter;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
internal static void AvoidLabelOverlap(Serie serie)
|
|
{
|
|
if (!serie.avoidLabelOverlap) return;
|
|
var lastCheckPos = Vector3.zero;
|
|
var data = serie.data;
|
|
var splitCount = 0;
|
|
for (int n = 0; n < data.Count; n++)
|
|
{
|
|
var serieData = data[n];
|
|
if (serieData.labelPosition.x != 0 && serieData.labelPosition.x < serie.runtimeCenterPos.x)
|
|
{
|
|
splitCount = n;
|
|
break;
|
|
}
|
|
}
|
|
for (int n = 0; n < splitCount; n++)
|
|
{
|
|
var serieData = data[n];
|
|
CheckSerieDataLabel(serie, serieData, false, ref lastCheckPos);
|
|
}
|
|
lastCheckPos = Vector3.zero;
|
|
for (int n = data.Count - 1; n >= splitCount; n--)
|
|
{
|
|
var serieData = data[n];
|
|
CheckSerieDataLabel(serie, serieData, true, ref lastCheckPos);
|
|
}
|
|
}
|
|
|
|
private static void CheckSerieDataLabel(Serie serie, SerieData serieData, bool isLeft, ref Vector3 lastCheckPos)
|
|
{
|
|
if (!serieData.canShowLabel)
|
|
{
|
|
serieData.SetLabelActive(false);
|
|
return;
|
|
}
|
|
if (!serieData.show) return;
|
|
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
|
if (!serieLabel.show) return;
|
|
if (serieLabel.position != SerieLabel.Position.Outside) return;
|
|
if (lastCheckPos == Vector3.zero)
|
|
{
|
|
lastCheckPos = serieData.labelPosition;
|
|
}
|
|
else if (serieData.labelPosition.x != 0)
|
|
{
|
|
float hig = serieLabel.textStyle.fontSize;
|
|
if (lastCheckPos.y - serieData.labelPosition.y < hig)
|
|
{
|
|
var labelRadius = serie.runtimeOutsideRadius + serieLabel.lineLength1;
|
|
var y1 = lastCheckPos.y - hig;
|
|
var cy = serie.runtimeCenterPos.y;
|
|
var diff = Mathf.Abs(y1 - cy);
|
|
var diffX = labelRadius * labelRadius - diff * diff;
|
|
diffX = diffX <= 0 ? 0 : diffX;
|
|
var x1 = serie.runtimeCenterPos.x + Mathf.Sqrt(diffX) * (isLeft ? -1 : 1);
|
|
serieData.labelPosition = new Vector3(x1, y1);
|
|
}
|
|
lastCheckPos = serieData.labelPosition;
|
|
serieData.labelObject.SetPosition(SerieLabelHelper.GetRealLabelPosition(serieData, serieLabel));
|
|
}
|
|
}
|
|
|
|
internal static Vector3 GetRealLabelPosition(SerieData serieData, SerieLabel label)
|
|
{
|
|
if (label.position == SerieLabel.Position.Outside && label.lineType != SerieLabel.LineType.HorizontalLine)
|
|
{
|
|
var currAngle = serieData.runtimePieHalfAngle;
|
|
var offset = label.lineLength2 + serieData.labelObject.GetLabelWidth() / 2;
|
|
if (currAngle > 180)
|
|
return serieData.labelPosition + new Vector3(-offset, 0, 0);
|
|
else
|
|
return serieData.labelPosition + new Vector3(offset, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
return serieData.labelPosition;
|
|
}
|
|
}
|
|
}
|
|
} |