improve radar chart

This commit is contained in:
monitor1394
2021-09-12 15:01:40 +08:00
parent 64d0b047b3
commit b261ef0573
10 changed files with 132 additions and 16 deletions

View File

@@ -40,6 +40,7 @@
## master
* (2021.09.08) Improved `RadarChart`
* (2021.09.07) Fixed bug where `label` does not disappear at the end of `PieChart` fade animation #168
* (2021.09.06) Fixed bug where `GaugeChart` changing `splitNumber` with code does not refresh `label` #167

View File

@@ -40,6 +40,7 @@
## master
* (2021.09.08) 完善`RadarChart`
* (2021.09.07) 修复`PieChart`渐出动画结束时`label`没有消失的问题 #168
* (2021.09.06) 修复`GaugeChart`用代码改变`splitNumber`不会刷新`label`的问题 #167

View File

@@ -176,6 +176,9 @@
* `ceilRate`最大最小值向上取整的倍率。默认为0时自动计算。
* `splitNumber`:分割段数。默认为 `5`
* `isAxisTooltip`是否Tooltip显示轴线上的所有数据。只对Mutiple类型的Radar有效。
* `outRangeColor`:数值超出范围时显示的颜色。
* `connectCenter`:数值是否连线到中心点。
* `lineGradient`:数值线段是否渐变。
* `splitLine`:分割线条 [AxisSplitLine](#AxisSplitLine)。
* `splitArea`:分割区域 [AxisSplitArea](#AxisSplitArea)。
* `indicator`:是否显示指示器。
@@ -187,6 +190,7 @@
* `name`:指示器名称。
* `max`:指示器的最大值,默认为 0 无限制。
* `min`:指示器的最小值,默认为 0 无限制。
* `range`:指示器的正常值范围,当数值超出这个范围时显示`Radar``outRangeColor`颜色。
* `textStyle`:文本样式 [TextStyle](#TextStyle)。
## `TextLimit`

View File

@@ -176,7 +176,10 @@ Radar coordinate conponnet for radar charts.
* `center`: the center of radar chart. The `center[0]` is the x-coordinate, and the `center[1]` is the y-coordinate. When value between 0 and 1 represents a percentage relative to the chart.[default:[0.5f,0.4f]].
* `ceilRate`: The ratio of maximum and minimum values rounded upward. The default is 0, which is automatically calculated.[default:0].
* `splitNumber`: Segments of indicator axis.[default:5].
* `splitNumber`: Tooltip displays all the data on the axis.[default:false].
* `isAxisTooltip`: Tooltip displays all the data on the axis.[default:false].
* `outRangeColor`: The color displayed when data out of range.[default:red]
* `connectCenter`: Whether serie data connect to radar center with line.[default:false]
* `lineGradient`: Whether need gradient for data line..[default:true]
* `splitLine`: The split line style of radar [AxisSplitLine](#AxisSplitLine).
* `splitArea`: The split area style of radar [AxisSplitArea](#AxisSplitArea).
* `indicator`: Whether to show indicator.
@@ -190,6 +193,7 @@ Indicator of radar chart, which is used to assign multiple variables(dimensions)
* `name`: The name of indicator.
* `max`: The maximum value of indicator, with default value of 0, but we recommend to set it manually.
* `min`: The minimum value of indicator, with default value of 0.
* `min`: Normal range. When the value is outside this range, the display color is automatically changed.
* `textStyle`: The text style of indicator [TextStyle](#TextStyle).
## `TextLimit`

View File

@@ -28,6 +28,9 @@ namespace XCharts
PropertyField(prop, "m_SplitNumber");
PropertyField(prop, "m_CeilRate");
PropertyField(prop, "m_IsAxisTooltip");
PropertyField(prop, "m_OutRangeColor");
PropertyField(prop, "m_ConnectCenter");
PropertyField(prop, "m_LineGradient");
PropertyField(prop, "m_AxisLine");
PropertyField(prop, "m_SplitLine");
PropertyField(prop, "m_SplitArea");
@@ -50,6 +53,7 @@ namespace XCharts
PropertyField(prop, "m_Name");
PropertyField(prop, "m_Min");
PropertyField(prop, "m_Max");
PropertyTwoFiled(prop, "m_Range");
PropertyField(prop, "m_TextStyle");
--EditorGUI.indentLevel;
}

View File

@@ -56,6 +56,7 @@ namespace XCharts
[SerializeField] private string m_Name;
[SerializeField] private double m_Max;
[SerializeField] private double m_Min;
[SerializeField] private double[] m_Range = new double[2] { 0, 0 };
[SerializeField] private TextStyle m_TextStyle = new TextStyle();
/// <summary>
@@ -83,6 +84,24 @@ namespace XCharts
/// 指示器的文本组件。
/// </summary>
public Text text { get; set; }
/// <summary>
/// Normal range. When the value is outside this range, the display color is automatically changed.
/// 正常值范围。当数值不在这个范围时,会自动变更显示颜色。
/// </summary>
public double[] range
{
get { return m_Range; }
set { if (value != null && value.Length == 2) { m_Range = value; } }
}
public bool IsInRange(double value)
{
if (m_Range == null || m_Range.Length < 2) return true;
if (m_Range[0] != 0 || m_Range[1] != 0)
return value >= m_Range[0] && value <= m_Range[1];
else
return true;
}
}
[SerializeField] private bool m_Show;
[SerializeField] private Shape m_Shape;
@@ -97,6 +116,9 @@ namespace XCharts
[SerializeField] private float m_IndicatorGap = 10;
[SerializeField] private int m_CeilRate = 0;
[SerializeField] private bool m_IsAxisTooltip;
[SerializeField] private Color32 m_OutRangeColor = Color.red;
[SerializeField] private bool m_ConnectCenter = false;
[SerializeField] private bool m_LineGradient = true;
[SerializeField] private List<Indicator> m_IndicatorList = new List<Indicator>();
/// <summary>
/// [default:true]
@@ -214,6 +236,33 @@ namespace XCharts
set { if (PropertyUtil.SetStruct(ref m_PositionType, value)) SetAllDirty(); }
}
/// <summary>
/// The color displayed when data out of range.
/// 数值超出范围时显示的颜色。
/// </summary>
public Color32 outRangeColor
{
get { return m_OutRangeColor; }
set { if (PropertyUtil.SetStruct(ref m_OutRangeColor, value)) SetAllDirty(); }
}
/// <summary>
/// Whether serie data connect to radar center with line.
/// 数值是否连线到中心点。
/// </summary>
public bool connectCenter
{
get { return m_ConnectCenter; }
set { if (PropertyUtil.SetStruct(ref m_ConnectCenter, value)) SetAllDirty(); }
}
/// <summary>
/// Whether need gradient for data line.
/// 数值线段是否需要渐变。
/// </summary>
public bool lineGradient
{
get { return m_LineGradient; }
set { if (PropertyUtil.SetStruct(ref m_LineGradient, value)) SetAllDirty(); }
}
/// <summary>
/// the indicator list.
/// 指示器列表。
/// </summary>
@@ -276,6 +325,12 @@ namespace XCharts
return true;
}
public bool IsInIndicatorRange(int index, double value)
{
var indicator = GetIndicator(index);
return indicator == null ? true : indicator.IsInRange(value);
}
public double GetIndicatorMin(int index)
{
if (index >= 0 && index < m_IndicatorList.Count)

View File

@@ -520,7 +520,7 @@ namespace XCharts
var theme = chart.theme.axis;
var lineColor = ChartHelper.IsClearColor(data.lineStyle.color) ? serieColor : data.lineStyle.color;
var lineWidth = data.lineStyle.width == 0 ? theme.lineWidth : data.lineStyle.width;
ChartDrawer.DrawLineStyle(vh, data.lineStyle, sp, ep, lineColor, lineWidth, LineStyle.Type.Dashed);
ChartDrawer.DrawLineStyle(vh, data.lineStyle, sp, ep, lineWidth, LineStyle.Type.Dashed, lineColor, lineColor);
if (data.startSymbol != null && data.startSymbol.show)
{
DrawMarkLineSymbol(vh, data.startSymbol, serie, grid, chart.theme, sp, sp, lineColor);

View File

@@ -439,6 +439,8 @@ namespace XCharts
var startPoint = Vector3.zero;
var toPoint = Vector3.zero;
var firstPoint = Vector3.zero;
var lastColor = ColorUtil.clearColor32;
var firstColor = ColorUtil.clearColor32;
var radar = chart.radars[serie.radarIndex];
var indicatorNum = radar.indicatorList.Count;
@@ -503,8 +505,10 @@ namespace XCharts
var value = serieData.GetCurrData(1, dataChangeDuration);
if (serieData.IsDataChanged()) dataChanging = true;
if (max == 0)
{
max = serie.runtimeDataMax;
if (!radar.IsInIndicatorRange(j, serieData.GetData(1)))
{
lineColor = radar.outRangeColor;
}
var radius = (float)(max < 0 ? radar.runtimeDataRadius - radar.runtimeDataRadius * value / max
: radar.runtimeDataRadius * value / max);
@@ -515,6 +519,8 @@ namespace XCharts
startPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle),
p.y + radius * Mathf.Cos(currAngle));
firstPoint = startPoint;
lastColor = lineColor;
firstColor = lineColor;
}
else
{
@@ -526,22 +532,28 @@ namespace XCharts
}
if (serie.lineStyle.show)
{
ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, toPoint, lineColor,
chart.theme.serie.lineWidth, LineStyle.Type.Solid);
if (radar.connectCenter)
ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, centerPos,
chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor);
ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, toPoint, chart.theme.serie.lineWidth,
LineStyle.Type.Solid, radar.lineGradient ? lastColor : lineColor, lineColor);
}
startPoint = toPoint;
lastColor = lineColor;
}
serieData.labelPosition = startPoint;
pointList.Add(startPoint);
if (serie.areaStyle.show && j == endIndex)
{
UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor);
}
if (serie.lineStyle.show && j == endIndex)
{
ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, firstPoint, lineColor,
chart.theme.serie.lineWidth, LineStyle.Type.Solid);
if (radar.connectCenter)
ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, centerPos,
chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor);
ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, firstPoint, chart.theme.serie.lineWidth,
LineStyle.Type.Solid, lineColor, radar.lineGradient ? firstColor : lineColor);
}
}
if (serie.symbol.show && serie.symbol.type != SerieSymbolType.None)
@@ -560,6 +572,11 @@ namespace XCharts
var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieIndex, isHighlight);
var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight);
var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight);
if (!radar.IsInIndicatorRange(j, serieData.GetData(1)))
{
symbolColor = radar.outRangeColor;
symbolToColor = radar.outRangeColor;
}
chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, serieData.labelPosition, symbolColor,
symbolToColor, serie.symbol.gap, cornerRadius);
}

View File

@@ -88,29 +88,45 @@ namespace XCharts
break;
}
}
public static void DrawLineStyle(VertexHelper vh, LineStyle lineStyle,
Vector3 startPos, Vector3 endPos, Color32 defaultColor, float themeWidth, LineStyle.Type themeType)
public static void DrawLineStyle(VertexHelper vh, LineStyle lineStyle, Vector3 startPos, Vector3 endPos,
Color32 defaultColor, float themeWidth, LineStyle.Type themeType)
{
var type = lineStyle.GetType(themeType);
var width = lineStyle.GetWidth(themeWidth);
var color = lineStyle.GetColor(defaultColor);
DrawLineStyle(vh, type, width, startPos, endPos, color);
DrawLineStyle(vh, type, width, startPos, endPos, color, color);
}
public static void DrawLineStyle(VertexHelper vh, LineStyle lineStyle, Vector3 startPos, Vector3 endPos,
float themeWidth, LineStyle.Type themeType, Color32 defaultColor, Color32 defaultToColor)
{
var type = lineStyle.GetType(themeType);
var width = lineStyle.GetWidth(themeWidth);
var color = lineStyle.GetColor(defaultColor);
var toColor = ChartHelper.IsClearColor(defaultToColor) ? color : defaultToColor;
DrawLineStyle(vh, type, width, startPos, endPos, color, toColor);
}
public static void DrawLineStyle(VertexHelper vh, LineStyle.Type lineType, float lineWidth,
Vector3 startPos, Vector3 endPos, Color32 color)
{
DrawLineStyle(vh, lineType, lineWidth, startPos, endPos, color, color);
}
public static void DrawLineStyle(VertexHelper vh, LineStyle.Type lineType, float lineWidth,
Vector3 startPos, Vector3 endPos, Color32 color, Color32 toColor)
{
switch (lineType)
{
case LineStyle.Type.Dashed:
UGL.DrawDashLine(vh, startPos, endPos, lineWidth, color, color);
UGL.DrawDashLine(vh, startPos, endPos, lineWidth, color, toColor);
break;
case LineStyle.Type.Dotted:
UGL.DrawDotLine(vh, startPos, endPos, lineWidth, color, color);
UGL.DrawDotLine(vh, startPos, endPos, lineWidth, color, toColor);
break;
case LineStyle.Type.Solid:
UGL.DrawLine(vh, startPos, endPos, lineWidth, color);
UGL.DrawLine(vh, startPos, endPos, lineWidth, color, toColor);
break;
case LineStyle.Type.DashDot:
UGL.DrawDashDotLine(vh, startPos, endPos, lineWidth, color);

View File

@@ -55,6 +55,20 @@ namespace XUGL
/// <param name="width">线宽</param>
/// <param name="color">颜色</param>
public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color)
{
DrawLine(vh, startPoint, endPoint, width, color, color);
}
/// <summary>
/// Draw a line. 画直线
/// </summary>
/// <param name="vh"></param>
/// <param name="startPoint">起点</param>
/// <param name="endPoint">终点</param>
/// <param name="width">线宽</param>
/// <param name="color">颜色</param>
/// <param name="toColor">渐变颜色</param>
public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color, Color32 toColor)
{
if (startPoint == endPoint) return;
Vector3 v = Vector3.Cross(endPoint - startPoint, Vector3.forward).normalized * width;
@@ -65,7 +79,7 @@ namespace XUGL
for (int j = 0; j < 4; j++)
{
s_Vertex[j].color = color;
s_Vertex[j].color = j == 0 || j == 3 ? color : toColor;
s_Vertex[j].uv0 = s_ZeroVector2;
}
vh.AddUIVertexQuad(s_Vertex);