diff --git a/Editor/MainComponents/RadarCoordEditor.cs b/Editor/MainComponents/RadarCoordEditor.cs
index 752ec816..2d5b9b40 100644
--- a/Editor/MainComponents/RadarCoordEditor.cs
+++ b/Editor/MainComponents/RadarCoordEditor.cs
@@ -24,7 +24,7 @@ namespace XCharts.Editor
PropertyField("m_AxisName");
PropertyField("m_SplitLine");
PropertyField("m_SplitArea");
- PropertyField("m_IndicatorList");
+ PropertyListField("m_IndicatorList");
--EditorGUI.indentLevel;
}
}
diff --git a/Editor/Series/RadarEditor.cs b/Editor/Series/RadarEditor.cs
index aedf9832..969c7436 100644
--- a/Editor/Series/RadarEditor.cs
+++ b/Editor/Series/RadarEditor.cs
@@ -9,6 +9,7 @@ namespace XCharts.Editor
{
PropertyField("m_RadarType");
PropertyField("m_RadarIndex");
+ PropertyField("m_Smooth");
PropertyField("m_Symbol");
PropertyField("m_LineStyle");
diff --git a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs
index 630a0612..4e295923 100644
--- a/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs
+++ b/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs
@@ -32,7 +32,7 @@ namespace XCharts.Runtime
if (!polar.context.isPointerEnter)
{
- axis.context.pointerValue = double.PositiveInfinity;
+ axis.context.pointerValue = double.NaN;
return;
}
diff --git a/Runtime/Component/Tooltip/TooltipHandler.cs b/Runtime/Component/Tooltip/TooltipHandler.cs
index e06b11cc..67bac520 100644
--- a/Runtime/Component/Tooltip/TooltipHandler.cs
+++ b/Runtime/Component/Tooltip/TooltipHandler.cs
@@ -180,7 +180,7 @@ namespace XCharts.Runtime
private void SetTooltipIndicatorLabel(Tooltip tooltip, Axis axis, ChartLabel label)
{
if (label == null) return;
- if (double.IsPositiveInfinity(axis.context.pointerValue)) return;
+ if (double.IsNaN(axis.context.pointerValue)) return;
label.SetActive(true);
label.SetTextActive(true);
label.SetPosition(axis.context.pointerLabelPosition);
diff --git a/Runtime/Internal/Attributes/SinceAttribute.cs b/Runtime/Internal/Attributes/SinceAttribute.cs
index 958d5ad2..1e3499e9 100644
--- a/Runtime/Internal/Attributes/SinceAttribute.cs
+++ b/Runtime/Internal/Attributes/SinceAttribute.cs
@@ -2,7 +2,7 @@ using System;
namespace XCharts.Runtime
{
- [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
+ [AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class Since : Attribute
{
public readonly string version;
diff --git a/Runtime/Serie/Parallel/ParallelHandler.cs b/Runtime/Serie/Parallel/ParallelHandler.cs
index 38a64534..c56c4d41 100644
--- a/Runtime/Serie/Parallel/ParallelHandler.cs
+++ b/Runtime/Serie/Parallel/ParallelHandler.cs
@@ -21,8 +21,7 @@ namespace XCharts.Runtime
DrawParallelSerie(vh, serie);
}
- private void UpdateSerieContext()
- { }
+ private void UpdateSerieContext() { }
private void DrawParallelSerie(VertexHelper vh, Parallel serie)
{
@@ -116,7 +115,10 @@ namespace XCharts.Runtime
lp = pos;
}
if (isSmooth)
- UGL.DrawCurves(vh, m_Points, lineWidth, lineColor, chart.settings.lineSmoothness, currProgress, isHorizonal);
+ UGL.DrawCurves(vh, m_Points, lineWidth, lineColor,
+ chart.settings.lineSmoothStyle,
+ chart.settings.lineSmoothness,
+ UGL.Direction.XAxis, currProgress, isHorizonal);
else
UGL.DrawLine(vh, m_Points, lineWidth, lineColor, isSmooth);
}
diff --git a/Runtime/Serie/Radar/Radar.cs b/Runtime/Serie/Radar/Radar.cs
index 8af45a95..dc44ec02 100644
--- a/Runtime/Serie/Radar/Radar.cs
+++ b/Runtime/Serie/Radar/Radar.cs
@@ -11,9 +11,21 @@ namespace XCharts.Runtime
[SerieDataExtraField()]
public class Radar : Serie, INeedSerieContainer
{
+ [SerializeField][Since("3.2.0")] private bool m_Smooth = false;
+
+ ///
+ /// Whether use smooth curve.
+ /// |是否平滑曲线。平滑曲线时不支持区域填充颜色。
+ ///
+ public bool smooth
+ {
+ get { return m_Smooth; }
+ set { if (PropertyUtil.SetStruct(ref m_Smooth, value)) { SetVerticesDirty(); } }
+ }
+
public int containerIndex { get; internal set; }
public int containterInstanceId { get; internal set; }
- public override bool useDataNameForColor { get { return true; } }
+ public override bool useDataNameForColor { get { return radarType == RadarType.Multiple; } }
public override bool multiDimensionLabel { get { return radarType == RadarType.Multiple; } }
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
diff --git a/Runtime/Serie/Radar/RadarHandler.cs b/Runtime/Serie/Radar/RadarHandler.cs
index 374455db..5bda0afb 100644
--- a/Runtime/Serie/Radar/RadarHandler.cs
+++ b/Runtime/Serie/Radar/RadarHandler.cs
@@ -262,11 +262,11 @@ namespace XCharts.Runtime
{
toPoint = new Vector3(centerPos.x + radius * Mathf.Sin(currAngle),
centerPos.y + radius * Mathf.Cos(currAngle));
- if (areaStyle != null && areaStyle.show)
+ if (areaStyle != null && areaStyle.show && !serie.smooth)
{
UGL.DrawTriangle(vh, startPoint, toPoint, centerPos, areaColor, areaColor, areaToColor);
}
- if (lineStyle.show)
+ if (lineStyle.show && !serie.smooth)
{
ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, toPoint, lineColor);
}
@@ -274,14 +274,24 @@ namespace XCharts.Runtime
}
serieData.context.dataPoints.Add(startPoint);
}
- if (areaStyle != null && areaStyle.show)
+ if (areaStyle != null && areaStyle.show && !serie.smooth)
{
UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor);
}
- if (lineStyle.show)
+ if (lineStyle.show && !serie.smooth)
{
ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, firstPoint, lineColor);
}
+
+ if (serie.smooth)
+ {
+ UGL.DrawCurves(vh, serieData.context.dataPoints, lineWidth, lineColor,
+ chart.settings.lineSmoothStyle,
+ chart.settings.lineSmoothness,
+ UGL.Direction.Random,
+ float.NaN, true);
+ }
+
if (symbol.show && symbol.type != SymbolType.None)
{
for (int m = 0; m < serieData.context.dataPoints.Count; m++)
@@ -394,11 +404,11 @@ namespace XCharts.Runtime
{
toPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle),
p.y + radius * Mathf.Cos(currAngle));
- if (areaStyle != null && areaStyle.show)
+ if (areaStyle != null && areaStyle.show && !serie.smooth)
{
UGL.DrawTriangle(vh, startPoint, toPoint, p, areaColor, areaColor, areaToColor);
}
- if (lineStyle.show)
+ if (lineStyle.show && !serie.smooth)
{
if (radar.connectCenter)
ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos,
@@ -409,14 +419,15 @@ namespace XCharts.Runtime
startPoint = toPoint;
lastColor = lineColor;
}
+ serie.context.dataPoints.Add(startPoint);
serieData.context.position = startPoint;
serieData.context.labelPosition = startPoint;
- if (areaStyle != null && areaStyle.show && j == endIndex)
+ if (areaStyle != null && areaStyle.show && j == endIndex && !serie.smooth)
{
UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor);
}
- if (lineStyle.show && j == endIndex)
+ if (lineStyle.show && j == endIndex && !serie.smooth)
{
if (radar.connectCenter)
ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos,
@@ -425,6 +436,16 @@ namespace XCharts.Runtime
LineStyle.Type.Solid, lineColor, radar.lineGradient ? firstColor : lineColor);
}
}
+ if (serie.smooth)
+ {
+ var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth);
+ var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.context.colorIndex, false);
+ UGL.DrawCurves(vh, serie.context.dataPoints, lineWidth, lineColor,
+ chart.settings.lineSmoothStyle,
+ chart.settings.lineSmoothness,
+ UGL.Direction.Random,
+ float.NaN, true);
+ }
if (serie.symbol.show && serie.symbol.type != SymbolType.None)
{
for (int j = 0; j < serie.data.Count; j++)
diff --git a/Runtime/XUGL/UGL.cs b/Runtime/XUGL/UGL.cs
index b260a52e..595342f3 100644
--- a/Runtime/XUGL/UGL.cs
+++ b/Runtime/XUGL/UGL.cs
@@ -10,6 +10,24 @@ namespace XUGL
///
public static class UGL
{
+ ///
+ /// 曲线方向
+ ///
+ public enum Direction
+ {
+ ///
+ /// 沿X轴方向
+ ///
+ XAxis,
+ ///
+ /// 沿Y轴方向
+ ///
+ YAxis,
+ ///
+ /// 随机无序的。如一个闭合的环状曲线。
+ ///
+ Random
+ }
private static readonly Color32 s_ClearColor32 = new Color32(0, 0, 0, 0);
private static readonly Vector2 s_ZeroVector2 = Vector2.zero;
private static UIVertex[] s_Vertex = new UIVertex[4];
@@ -134,7 +152,7 @@ namespace XUGL
}
else if (smooth)
{
- DrawCurves(vh, points, width, color, 2);
+ DrawCurves(vh, points, width, color, 2, 2, Direction.XAxis, float.NaN, closepath);
}
else
{
@@ -1752,42 +1770,67 @@ namespace XUGL
/// 曲线宽
/// 曲线颜色
public static void DrawCurves(VertexHelper vh, Vector3 sp, Vector3 ep, Vector3 cp1, Vector3 cp2,
- float lineWidth, Color32 lineColor, float smoothness)
+ float lineWidth, Color32 lineColor, float smoothness, Direction dire = Direction.XAxis)
{
var dist = Vector3.Distance(sp, ep);
var segment = (int) (dist / (smoothness <= 0 ? 2f : smoothness));
UGLHelper.GetBezierList2(ref s_CurvesPosList, sp, ep, segment, cp1, cp2);
- DrawCurvesInternal(vh, s_CurvesPosList, lineWidth, lineColor);
+ DrawCurvesInternal(vh, s_CurvesPosList, lineWidth, lineColor, dire);
}
+ ///
+ /// 画贝塞尔曲线
+ ///
+ ///
+ /// 坐标点列表
+ /// 曲线宽
+ /// 曲线颜色
+ /// 曲线样式
+ /// 平滑度
+ /// 曲线方向
+ /// 当前绘制进度
+ /// 曲线是否闭合
public static void DrawCurves(VertexHelper vh, List points, float width, Color32 color,
- float smoothness, float currProgress = float.PositiveInfinity, bool isYAxis = false)
+ float smoothStyle, float smoothness, Direction dire, float currProgress = float.NaN,
+ bool closed = false)
{
- for (int i = 0; i < points.Count - 1; i++)
+ var count = points.Count;
+ var size = (closed?count : count - 1);
+ if (closed)
+ dire = Direction.Random;
+ for (int i = 0; i < size; i++)
{
var sp = points[i];
- var ep = points[i + 1];
- var lsp = i > 0 ? points[i - 1] : sp;
- var nep = i < points.Count - 2 ? points[i + 2] : ep;
+ var ep = closed?(i == size - 1 ? points[0] : points[i + 1]) : points[i + 1];
+ var lsp = i > 0 ? points[i - 1] : (closed?points[count - 1] : sp);
+ var nep = i < points.Count - 2 ? points[i + 2] : (closed?points[(i + 2) % count] : ep);
var smoothness2 = smoothness;
- if (currProgress != float.PositiveInfinity)
+ if (currProgress != float.NaN)
{
- if (isYAxis)
- smoothness2 = ep.y <= currProgress ? smoothness : smoothness * 0.5f;
- else
- smoothness2 = ep.x <= currProgress ? smoothness : smoothness * 0.5f;
+ switch (dire)
+ {
+ case Direction.XAxis:
+ smoothness2 = ep.x <= currProgress ? smoothness : smoothness * 0.5f;
+ break;
+ case Direction.YAxis:
+ smoothness2 = ep.y <= currProgress ? smoothness : smoothness * 0.5f;
+ break;
+ case Direction.Random:
+ smoothness2 = smoothness * 0.5f;
+ break;
+ }
}
- if (isYAxis)
- UGLHelper.GetBezierListVertical(ref s_CurvesPosList, sp, ep, smoothness2);
+ if (dire == Direction.YAxis)
+ UGLHelper.GetBezierListVertical(ref s_CurvesPosList, sp, ep, smoothness2, smoothStyle);
else
- UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness2);
+ UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness2, smoothStyle);
- DrawCurvesInternal(vh, s_CurvesPosList, width, color, currProgress, isYAxis);
+ DrawCurvesInternal(vh, s_CurvesPosList, width, color, dire, currProgress);
}
}
private static void DrawCurvesInternal(VertexHelper vh, List curvesPosList, float lineWidth,
- Color32 lineColor, float currProgress = float.PositiveInfinity, bool isYAxis = false)
+ Color32 lineColor, Direction dire, float currProgress = float.NaN)
{
if (curvesPosList.Count > 1)
{
@@ -1805,11 +1848,11 @@ namespace XUGL
for (int i = 1; i < curvesPosList.Count; i++)
{
to = curvesPosList[i];
- if (currProgress != float.PositiveInfinity)
+ if (currProgress != float.NaN)
{
- if (isYAxis && to.y > currProgress)
+ if (dire == Direction.YAxis && to.y > currProgress)
break;
- if (!isYAxis && to.x > currProgress)
+ if (dire == Direction.XAxis && to.x > currProgress)
break;
}
diff --git a/Runtime/XUGL/UGLHelper.cs b/Runtime/XUGL/UGLHelper.cs
index 2f7166cb..4076b525 100644
--- a/Runtime/XUGL/UGLHelper.cs
+++ b/Runtime/XUGL/UGLHelper.cs
@@ -110,22 +110,21 @@ namespace XUGL
public static void GetBezierList(ref List posList, Vector3 sp, Vector3 ep,
Vector3 lsp, Vector3 nep, float smoothness = 2f, float k = 2.0f, bool limit = false)
{
- float dist = Mathf.Abs(sp.x - ep.x);
+ var dist = Vector3.Distance(sp, ep);
Vector3 cp1, cp2;
var dir = (ep - sp).normalized;
var diff = dist / k;
if (lsp == sp)
{
- cp1 = sp + dist / k * dir * 1;
- cp1.y = sp.y;
- cp1 = sp;
+ cp1 = sp + (nep - ep).normalized * diff;
+ if (limit)
+ cp1.y = sp.y;
}
else
{
cp1 = sp + (ep - lsp).normalized * diff;
if (limit)
cp1.y = sp.y;
-
}
if (nep == ep)
{
@@ -137,7 +136,6 @@ namespace XUGL
if (limit)
cp2.y = ep.y;
}
- dist = Vector3.Distance(sp, ep);
int segment = (int) (dist / (smoothness <= 0 ? 2f : smoothness));
if (segment < 1) segment = (int) (dist / 0.5f);
if (segment < 4) segment = 4;