From 5ce1b539d57f8580fc67cde9b677f80018275fd6 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Sun, 29 Mar 2020 10:57:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0`itemStyle`=E7=9A=84`cornerRa?= =?UTF-8?q?dius`=E6=94=AF=E6=8C=81=E5=9C=86=E8=A7=92=E7=9F=A9=E5=BD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + Documentation/XCharts配置项手册.md | 3 +- Editor/PropertyDrawers/ItemStyleDrawer.cs | 16 +- Editor/Utility/ChartEditorHelper.cs | 75 ++++-- Runtime/Component/Sub/ItemStyle.cs | 13 +- Runtime/Component/Sub/SerieSymbol.cs | 2 +- Runtime/Helper/ItemStyleHelper.cs | 24 ++ Runtime/Helper/ItemStyleHelper.cs.meta | 11 + Runtime/Helper/SerieHelper.cs | 7 + Runtime/Internal/BaseChart.cs | 5 +- Runtime/Internal/CoordinateChart.cs | 4 +- Runtime/Internal/CoordinateChart_DrawBar.cs | 61 +++-- Runtime/Internal/CoordinateChart_DrawLine.cs | 3 +- .../Internal/CoordinateChart_DrawScatter.cs | 5 +- Runtime/RadarChart.cs | 9 +- Runtime/Utility/ChartDrawer.cs | 249 ++++++++++++++++-- 16 files changed, 412 insertions(+), 76 deletions(-) create mode 100644 Runtime/Helper/ItemStyleHelper.cs create mode 100644 Runtime/Helper/ItemStyleHelper.cs.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index 84e1bc0e..9ab3364c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 更新日志 +* (2020.03.29) 增加`itemStyle`的`cornerRadius`支持圆角矩形 * (2020.03.24) 优化`Editor`参数编辑,兼容`Unity2019.3`及以上版本 * (2020.03.24) 增加`Serie`在`inspector`上可进行调整顺序、添加和删除操作 * (2020.03.23) 修复`Title`的`textStyle`和`subTextStyle`无效的问题 diff --git a/Documentation/XCharts配置项手册.md b/Documentation/XCharts配置项手册.md index 0a8ae548..b524e3d9 100644 --- a/Documentation/XCharts配置项手册.md +++ b/Documentation/XCharts配置项手册.md @@ -745,6 +745,7 @@ * `borderWidth`:边框宽。 * `opacity`:透明度。 * `tooltipFormatter`:提示框单项的字符串模版格式器。具体配置参考`Tooltip`的`formatter`。 +* `cornerRadius`:圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。 ## `LineArrow` @@ -839,7 +840,7 @@ * `type`:标记类型。支持以下六种类型: * `EmptyCircle`:空心圆。 * `Circle`:实心圆。 - * `Rect`:正方形。 + * `Rect`:正方形。可通过设置`itemStyle`的`cornerRadius`变成圆角矩形。 * `Triangle`:三角形。 * `Diamond`:菱形。 * `None`:不显示标记。 diff --git a/Editor/PropertyDrawers/ItemStyleDrawer.cs b/Editor/PropertyDrawers/ItemStyleDrawer.cs index be3eafa3..8fe7ae34 100644 --- a/Editor/PropertyDrawers/ItemStyleDrawer.cs +++ b/Editor/PropertyDrawers/ItemStyleDrawer.cs @@ -14,7 +14,9 @@ namespace XCharts [CustomPropertyDrawer(typeof(ItemStyle), true)] public class ItemStyleDrawer : PropertyDrawer { + private int m_CornerRadius = 0; private Dictionary m_ItemStyleToggle = new Dictionary(); + private Dictionary m_CornerRadiusToggle = new Dictionary(); public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) { @@ -32,6 +34,7 @@ namespace XCharts SerializedProperty m_BorderColor = prop.FindPropertyRelative("m_BorderColor"); SerializedProperty m_Opacity = prop.FindPropertyRelative("m_Opacity"); SerializedProperty m_TooltipFormatter = prop.FindPropertyRelative("m_TooltipFormatter"); + SerializedProperty m_CornerRadius = prop.FindPropertyRelative("m_CornerRadius"); ChartEditorHelper.MakeFoldout(ref drawRect, ref m_ItemStyleToggle, prop, "Item Style", show, false); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; if (ChartEditorHelper.IsToggle(m_ItemStyleToggle, prop)) @@ -59,6 +62,12 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_TooltipFormatter); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + ChartEditorHelper.MakeFoldout(ref drawRect, ref m_CornerRadiusToggle, m_CornerRadius, "Corner Radius", null, false); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + if (ChartEditorHelper.IsToggle(m_CornerRadiusToggle, m_CornerRadius)) + { + ChartEditorHelper.MakeList(ref drawRect, ref this.m_CornerRadius, m_CornerRadius, false, false); + } --EditorGUI.indentLevel; } } @@ -68,7 +77,12 @@ namespace XCharts float height = 0; if (ChartEditorHelper.IsToggle(m_ItemStyleToggle, prop)) { - height += 12 * EditorGUIUtility.singleLineHeight + 11 * EditorGUIUtility.standardVerticalSpacing; + height += 13 * EditorGUIUtility.singleLineHeight + 12 * EditorGUIUtility.standardVerticalSpacing; + var m_CornerRadius = prop.FindPropertyRelative("m_CornerRadius"); + if (ChartEditorHelper.IsToggle(m_CornerRadiusToggle, m_CornerRadius)) + { + height += 4 * EditorGUIUtility.singleLineHeight + 3 * EditorGUIUtility.standardVerticalSpacing; + } } else { diff --git a/Editor/Utility/ChartEditorHelper.cs b/Editor/Utility/ChartEditorHelper.cs index 06e1ef3c..55edbbd8 100644 --- a/Editor/Utility/ChartEditorHelper.cs +++ b/Editor/Utility/ChartEditorHelper.cs @@ -39,6 +39,32 @@ public class ChartEditorHelper MakeTwoField(ref drawRect, rectWidth, arrayProp.GetArrayElementAtIndex(0), arrayProp.GetArrayElementAtIndex(1), name); } + public static void MakeDivideList(ref Rect drawRect, float rectWidth, SerializedProperty arrayProp, string name, int showNum) + { + while (arrayProp.arraySize < showNum) + { + arrayProp.InsertArrayElementAtIndex(arrayProp.arraySize); + } + EditorGUI.LabelField(drawRect, name); +#if UNITY_2019_3_OR_NEWER + var gap = 2; +#else + var gap = 0; +#endif + var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + gap; + var dataWidTotal = (rectWidth - (startX + INDENT_WIDTH + 1)); + EditorGUI.DrawRect(new Rect(startX, drawRect.y, dataWidTotal, drawRect.height), Color.grey); + var dataWid = dataWidTotal / showNum; + var xWid = dataWid - gap; + for (int i = 0; i < 1; i++) + { + drawRect.x = startX + i * xWid; + drawRect.width = dataWid + (EditorGUI.indentLevel - 2) * 40.5f; + EditorGUI.PropertyField(drawRect, arrayProp.GetArrayElementAtIndex(i), GUIContent.none); + } + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + } + public static void MakeTwoField(ref Rect drawRect, float rectWidth, SerializedProperty prop1, SerializedProperty prop2, string name) { EditorGUI.LabelField(drawRect, name); @@ -174,36 +200,39 @@ public class ChartEditorHelper return toggle; } - public static void MakeList(ref Rect drawRect, ref int listSize, SerializedProperty listProp, bool showOrder = false) + public static void MakeList(ref Rect drawRect, ref int listSize, SerializedProperty listProp, bool showOrder = false, bool showSize = true) { EditorGUI.indentLevel++; listSize = listProp.arraySize; - if (showOrder) + if (showSize) { - var nameWid = 15; - var temp = INDENT_WIDTH + GAP_WIDTH; - var elementRect = new Rect(drawRect.x, drawRect.y, drawRect.width - nameWid - 1, drawRect.height); - var iconRect = new Rect(drawRect.width - nameWid + temp, drawRect.y, nameWid, drawRect.height); - if (GUI.Button(iconRect, new GUIContent("+", "add"))) + if (showOrder) { - listProp.InsertArrayElementAtIndex(listProp.arraySize); + var nameWid = 15; + var temp = INDENT_WIDTH + GAP_WIDTH; + var elementRect = new Rect(drawRect.x, drawRect.y, drawRect.width - nameWid - 1, drawRect.height); + var iconRect = new Rect(drawRect.width - nameWid + temp, drawRect.y, nameWid, drawRect.height); + if (GUI.Button(iconRect, new GUIContent("+", "add"))) + { + listProp.InsertArrayElementAtIndex(listProp.arraySize); + } + listSize = listProp.arraySize; + listSize = EditorGUI.IntField(elementRect, "Size", listSize); } - listSize = listProp.arraySize; - listSize = EditorGUI.IntField(elementRect, "Size", listSize); - } - else - { - listSize = EditorGUI.IntField(drawRect, "Size", listSize); - } - if (listSize < 0) listSize = 0; - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + else + { + listSize = EditorGUI.IntField(drawRect, "Size", listSize); + } + if (listSize < 0) listSize = 0; + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - if (listSize != listProp.arraySize) - { - while (listSize > listProp.arraySize) - listProp.InsertArrayElementAtIndex(listProp.arraySize); - while (listSize < listProp.arraySize) - listProp.DeleteArrayElementAtIndex(listProp.arraySize - 1); + if (listSize != listProp.arraySize) + { + while (listSize > listProp.arraySize) + listProp.InsertArrayElementAtIndex(listProp.arraySize); + while (listSize < listProp.arraySize) + listProp.DeleteArrayElementAtIndex(listProp.arraySize - 1); + } } if (listSize > 30) { diff --git a/Runtime/Component/Sub/ItemStyle.cs b/Runtime/Component/Sub/ItemStyle.cs index 86d220ac..180f1888 100644 --- a/Runtime/Component/Sub/ItemStyle.cs +++ b/Runtime/Component/Sub/ItemStyle.cs @@ -5,7 +5,8 @@ /* */ /******************************************/ - +using System; +using System.Collections.Generic; using UnityEngine; namespace XCharts @@ -46,6 +47,7 @@ namespace XCharts [SerializeField] private Color m_BorderColor; [SerializeField] [Range(0, 1)] private float m_Opacity = 1; [SerializeField] private string m_TooltipFormatter; + [SerializeField] private float[] m_CornerRadius = new float[] { 0, 0, 0, 0 }; /// /// 是否启用。 @@ -145,6 +147,15 @@ namespace XCharts set { if (PropertyUtility.SetClass(ref m_TooltipFormatter, value)) SetVerticesDirty(); } } /// + /// The radius of rounded corner. Its unit is px. Use array to respectively specify the 4 corner radiuses((clockwise upper left, upper right, bottom right and bottom left)). + /// 圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。 + /// + public float[] cornerRadius + { + get { return m_CornerRadius; } + set { if (PropertyUtility.SetClass(ref m_CornerRadius, value, true)) SetVerticesDirty(); } + } + /// /// 实际边框宽。边框不显示时为0。 /// public float runtimeBorderWidth { get { return NeedShowBorder() ? borderWidth : 0; } } diff --git a/Runtime/Component/Sub/SerieSymbol.cs b/Runtime/Component/Sub/SerieSymbol.cs index 0acb99cd..a10eec76 100644 --- a/Runtime/Component/Sub/SerieSymbol.cs +++ b/Runtime/Component/Sub/SerieSymbol.cs @@ -25,7 +25,7 @@ namespace XCharts /// Circle, /// - /// 正方形。 + /// 正方形。可通过设置`itemStyle`的`cornerRadius`变成圆角矩形。 /// Rect, /// diff --git a/Runtime/Helper/ItemStyleHelper.cs b/Runtime/Helper/ItemStyleHelper.cs new file mode 100644 index 00000000..e18b6996 --- /dev/null +++ b/Runtime/Helper/ItemStyleHelper.cs @@ -0,0 +1,24 @@ +/******************************************/ +/* */ +/* Copyright (c) 2018 monitor1394 */ +/* https://github.com/monitor1394 */ +/* */ +/******************************************/ +using UnityEngine; +using UnityEngine.UI; + +namespace XCharts +{ + internal static class ItemStyleHelper + { + public static bool IsNeedCorner(ItemStyle itemStyle) + { + if (itemStyle.cornerRadius == null) return false; + foreach (var value in itemStyle.cornerRadius) + { + if (value != 0) return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/Runtime/Helper/ItemStyleHelper.cs.meta b/Runtime/Helper/ItemStyleHelper.cs.meta new file mode 100644 index 00000000..7bc5f0a3 --- /dev/null +++ b/Runtime/Helper/ItemStyleHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce94468fab72e4b39b53f6cf8b647d6b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Helper/SerieHelper.cs b/Runtime/Helper/SerieHelper.cs index b6dd673e..f18c81cd 100644 --- a/Runtime/Helper/SerieHelper.cs +++ b/Runtime/Helper/SerieHelper.cs @@ -233,5 +233,12 @@ namespace XCharts else if (serie.lineStyle.width != 0) return serie.lineStyle.width; else return 1; } + + public static float[] GetSymbolCornerRadius(Serie serie, SerieData serieData, bool highlight) + { + var itemStyle = GetItemStyle(serie, serieData, highlight); + if(itemStyle != null) return itemStyle.cornerRadius; + else return null; + } } } \ No newline at end of file diff --git a/Runtime/Internal/BaseChart.cs b/Runtime/Internal/BaseChart.cs index 4edb6392..259aafcd 100644 --- a/Runtime/Internal/BaseChart.cs +++ b/Runtime/Internal/BaseChart.cs @@ -727,7 +727,7 @@ namespace XCharts } protected void DrawSymbol(VertexHelper vh, SerieSymbolType type, float symbolSize, - float tickness, Vector3 pos, Color color, Color toColor, float gap) + float tickness, Vector3 pos, Color color, Color toColor, float gap, float[] cornerRadius) { var backgroundColor = m_ThemeInfo.backgroundColor; var smoothness = m_Settings.cicleSmoothness; @@ -764,7 +764,8 @@ namespace XCharts } else { - ChartDrawer.DrawPolygon(vh, pos, symbolSize, color, toColor); + //ChartDrawer.DrawPolygon(vh, pos, symbolSize, color, toColor); + ChartDrawer.DrawRoundRectangle(vh, pos, symbolSize, symbolSize, color, 0, cornerRadius); } break; case SerieSymbolType.Triangle: diff --git a/Runtime/Internal/CoordinateChart.cs b/Runtime/Internal/CoordinateChart.cs index b6069ce7..b49e3466 100644 --- a/Runtime/Internal/CoordinateChart.cs +++ b/Runtime/Internal/CoordinateChart.cs @@ -1783,11 +1783,11 @@ namespace XCharts } protected void CheckClipAndDrawSymbol(VertexHelper vh, SerieSymbolType type, float symbolSize, - float tickness, Vector3 pos, Color color, Color toColor, float gap, bool clip) + float tickness, Vector3 pos, Color color, Color toColor, float gap, bool clip,float[] cornerRadius) { if (!IsInChart(pos)) return; if (!clip || (clip && (IsInCooridate(pos)))) - DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap); + DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap,cornerRadius); } protected void CheckClipAndDrawZebraLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, diff --git a/Runtime/Internal/CoordinateChart_DrawBar.cs b/Runtime/Internal/CoordinateChart_DrawBar.cs index e5b31f2d..e7abd510 100644 --- a/Runtime/Internal/CoordinateChart_DrawBar.cs +++ b/Runtime/Internal/CoordinateChart_DrawBar.cs @@ -65,9 +65,10 @@ namespace XCharts || serie.data[i].highlighted || serie.highlighted; var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight); - var borderWidth = itemStyle.runtimeBorderWidth; + serieData.canShowLabel = true; float value = showData[i].GetCurrData(1, dataChangeDuration); + float borderWidth = value == 0 ? 0 : itemStyle.runtimeBorderWidth; if (showData[i].IsDataChanged()) dataChanging = true; float pX = seriesHig[i] + coordinateX + xAxis.runtimeZeroXOffset + yAxis.axisLine.width; float pY = coordinateY + +i * categoryWidth; @@ -192,8 +193,8 @@ namespace XCharts || serie.data[i].highlighted || serie.highlighted; var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight); - var borderWidth = itemStyle.runtimeBorderWidth; float value = serieData.GetCurrData(1, dataChangeDuration); + float borderWidth = value == 0 ? 0 : itemStyle.runtimeBorderWidth; if (serieData.IsDataChanged()) dataChanging = true; float pX = coordinateX + i * categoryWidth; float zeroY = coordinateY + yAxis.runtimeZeroYOffset; @@ -267,26 +268,54 @@ namespace XCharts var borderWidth = itemStyle.runtimeBorderWidth; if (isYAxis) { - CheckClipAndDrawPolygon(vh, plb, plt, prt, prb, areaColor, areaToColor, serie.clip); - if (borderWidth > 0) + if (serie.clip) { - var borderColor = itemStyle.borderColor; - var itemWidth = Mathf.Abs(prb.x - plt.x); - var itemHeight = Mathf.Abs(prt.y - plb.y); - var center = new Vector3((plt.x + prb.x) / 2, (prt.y + plb.y) / 2); - ChartDrawer.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, borderColor); + prb = ClampInCoordinate(prb); + plb = ClampInCoordinate(plb); + plt = ClampInCoordinate(plt); + prt = ClampInCoordinate(prt); + } + var borderColor = itemStyle.borderColor; + var itemWidth = Mathf.Abs(prb.x - plt.x); + var itemHeight = Mathf.Abs(prt.y - plb.y); + var center = new Vector3((plt.x + prb.x) / 2, (prt.y + plb.y) / 2); + if (itemWidth > 0 && itemHeight > 0) + { + if (ItemStyleHelper.IsNeedCorner(itemStyle)) + { + ChartDrawer.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, 0, itemStyle.cornerRadius); + } + else + { + CheckClipAndDrawPolygon(vh, plb, plt, prt, prb, areaColor, areaToColor, serie.clip); + } + ChartDrawer.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, borderColor, 0, itemStyle.cornerRadius); } } else { - CheckClipAndDrawPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaToColor, serie.clip); - if (borderWidth > 0) + if (serie.clip) { - var borderColor = itemStyle.borderColor; - var itemWidth = Mathf.Abs(prt.x - plb.x); - var itemHeight = Mathf.Abs(plt.y - prb.y); - var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2); - ChartDrawer.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, borderColor); + prb = ClampInCoordinate(prb); + plb = ClampInCoordinate(plb); + plt = ClampInCoordinate(plt); + prt = ClampInCoordinate(prt); + } + var borderColor = itemStyle.borderColor; + var itemWidth = Mathf.Abs(prt.x - plb.x); + var itemHeight = Mathf.Abs(plt.y - prb.y); + var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2); + if (itemWidth > 0 && itemHeight > 0) + { + if (ItemStyleHelper.IsNeedCorner(itemStyle)) + { + ChartDrawer.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, 0, itemStyle.cornerRadius); + } + else + { + CheckClipAndDrawPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaToColor, serie.clip); + } + ChartDrawer.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, borderColor, 0, itemStyle.cornerRadius); } } } diff --git a/Runtime/Internal/CoordinateChart_DrawLine.cs b/Runtime/Internal/CoordinateChart_DrawLine.cs index e95cbc3a..7a11cc8b 100644 --- a/Runtime/Internal/CoordinateChart_DrawLine.cs +++ b/Runtime/Internal/CoordinateChart_DrawLine.cs @@ -41,9 +41,10 @@ namespace XCharts var symbolColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, n, highlight); var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, n, highlight); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, highlight); + var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); symbolSize = serie.animation.GetSysmbolSize(symbolSize); CheckClipAndDrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, p, symbolColor, - symbolToColor, serie.symbol.gap, clip); + symbolToColor, serie.symbol.gap, clip, cornerRadius); } } } diff --git a/Runtime/Internal/CoordinateChart_DrawScatter.cs b/Runtime/Internal/CoordinateChart_DrawScatter.cs index ebf418d7..f2ecae6d 100644 --- a/Runtime/Internal/CoordinateChart_DrawScatter.cs +++ b/Runtime/Internal/CoordinateChart_DrawScatter.cs @@ -31,6 +31,7 @@ namespace XCharts var color = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); var toColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, highlight); + var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); float xValue = serieData.GetCurrData(0, dataChangeDuration); float yValue = serieData.GetCurrData(1, dataChangeDuration); if (serieData.IsDataChanged()) dataChanging = true; @@ -58,13 +59,13 @@ namespace XCharts { var nowSize = serie.symbol.animationSize[count]; color.a = (symbolSize - nowSize) / symbolSize; - DrawSymbol(vh, serie.symbol.type, nowSize, symbolBorder, pos, color, toColor, serie.symbol.gap); + DrawSymbol(vh, serie.symbol.type, nowSize, symbolBorder, pos, color, toColor, serie.symbol.gap, cornerRadius); } RefreshChart(); } else { - DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, pos, color, toColor, serie.symbol.gap); + DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, pos, color, toColor, serie.symbol.gap, cornerRadius); } } if (!serie.animation.IsFinish()) diff --git a/Runtime/RadarChart.cs b/Runtime/RadarChart.cs index a97054a8..269a3cf0 100644 --- a/Runtime/RadarChart.cs +++ b/Runtime/RadarChart.cs @@ -334,10 +334,11 @@ namespace XCharts var symbolColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, serieIndex, isHighlight); var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, serieIndex, isHighlight); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, isHighlight); + var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); foreach (var point in pointList) { DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, point, symbolColor, - symbolToColor, serie.symbol.gap); + symbolToColor, serie.symbol.gap, cornerRadius); } } } @@ -475,8 +476,9 @@ namespace XCharts var symbolColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, serieIndex, isHighlight); var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, serieIndex, isHighlight); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, isHighlight); + var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, serieData.labelPosition, symbolColor, - symbolToColor, serie.symbol.gap); + symbolToColor, serie.symbol.gap, cornerRadius); } } if (!serie.animation.IsFinish()) @@ -516,10 +518,11 @@ namespace XCharts var symbolColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, serieIndex, isHighlight); var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, serieIndex, isHighlight); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, isHighlight); + var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); foreach (var point in pointList) { DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, point, symbolColor, - symbolToColor, serie.symbol.gap); + symbolToColor, serie.symbol.gap, cornerRadius); } } } diff --git a/Runtime/Utility/ChartDrawer.cs b/Runtime/Utility/ChartDrawer.cs index 8fce28d4..6378aa72 100644 --- a/Runtime/Utility/ChartDrawer.cs +++ b/Runtime/Utility/ChartDrawer.cs @@ -1,3 +1,4 @@ +using System.Linq; /******************************************/ /* */ /* Copyright (c) 2018 monitor1394 */ @@ -260,34 +261,236 @@ namespace XCharts vh.AddUIVertexQuad(vertex); } - public static void DrawBorder(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight, - float borderWidth, Color32 color, float rotate = 0) + private static void InitCornerRadius(float[] cornerRadius, float width, float height, ref float brLt, + ref float brRt, ref float brRb, ref float brLb, ref bool needRound) + { + brLt = cornerRadius != null && cornerRadius.Length > 0 ? cornerRadius[0] : 0; + brRt = cornerRadius != null && cornerRadius.Length > 1 ? cornerRadius[1] : 0; + brRb = cornerRadius != null && cornerRadius.Length > 2 ? cornerRadius[2] : 0; + brLb = cornerRadius != null && cornerRadius.Length > 3 ? cornerRadius[3] : 0; + needRound = brLb != 0 || brRt != 0 || brRb != 0 || brLb != 0; + var min = Mathf.Min(width, height); + if (needRound) + { + if (brLt + brRt > width) + { + var total = brLt + brRt; + brLt = width * (brLt / total); + brRt = width * (brRt / total); + } + if (brRt + brRb > height) + { + var total = brRt + brRb; + brRt = height * (brRt / total); + brRb = height * (brRb / total); + } + if (brRb + brLb > width) + { + var total = brRb + brLb; + brRb = width * (brRb / total); + brLb = width * (brLb / total); + } + if (brLb + brLt > height) + { + var total = brLb + brLt; + brLb = height * (brLb / total); + brLt = height * (brLt / total); + } + if (brLt + brRb > height) + { + var total = brLt + brRb; + brLt = height * (brLt / total); + brRb = height * (brRb / total); + } + if (brRt + brLb > height) + { + var total = brRt + brRt; + brRt = height * (brRt / total); + brLb = height * (brLb / total); + } + } + } + + /// + /// 绘制圆角矩形 + /// + /// + /// + /// + /// + /// + /// + /// + public static void DrawRoundRectangle(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight, + Color32 color, float rotate = 0, float[] cornerRadius = null) { var halfWid = rectWidth / 2; var halfHig = rectHeight / 2; - var p1In = new Vector3(center.x - halfWid, center.y - halfHig); - var p1Ot = new Vector3(center.x - halfWid - borderWidth, center.y - halfHig - borderWidth); - var p2In = new Vector3(center.x - halfWid, center.y + halfHig); - var p2Ot = new Vector3(center.x - halfWid - borderWidth, center.y + halfHig + borderWidth); - var p3In = new Vector3(center.x + halfWid, center.y + halfHig); - var p3Ot = new Vector3(center.x + halfWid + borderWidth, center.y + halfHig + borderWidth); - var p4In = new Vector3(center.x + halfWid, center.y - halfHig); - var p4Ot = new Vector3(center.x + halfWid + borderWidth, center.y - halfHig - borderWidth); - if (rotate > 0) + float brLt = 0, brRt = 0, brRb = 0, brLb = 0; + bool needRound = false; + InitCornerRadius(cornerRadius, rectWidth, rectHeight, ref brLt, ref brRt, ref brRb, ref brLb, ref needRound); + var tempCenter = Vector3.zero; + var lbIn = new Vector3(center.x - halfWid, center.y - halfHig); + var ltIn = new Vector3(center.x - halfWid, center.y + halfHig); + var rtIn = new Vector3(center.x + halfWid, center.y + halfHig); + var rbIn = new Vector3(center.x + halfWid, center.y - halfHig); + if (needRound) { - p1In = ChartHelper.RotateRound(p1In, center, Vector3.forward, rotate); - p1Ot = ChartHelper.RotateRound(p1Ot, center, Vector3.forward, rotate); - p2In = ChartHelper.RotateRound(p2In, center, Vector3.forward, rotate); - p2Ot = ChartHelper.RotateRound(p2Ot, center, Vector3.forward, rotate); - p3In = ChartHelper.RotateRound(p3In, center, Vector3.forward, rotate); - p3Ot = ChartHelper.RotateRound(p3Ot, center, Vector3.forward, rotate); - p4In = ChartHelper.RotateRound(p4In, center, Vector3.forward, rotate); - p4Ot = ChartHelper.RotateRound(p4Ot, center, Vector3.forward, rotate); + var lbIn2 = lbIn; + var ltIn2 = ltIn; + var rtIn2 = rtIn; + var rbIn2 = rbIn; + var roundLb = lbIn; + var roundLt = ltIn; + var roundRt = rtIn; + var roundRb = rbIn; + if (brLt > 0) + { + roundLt = new Vector3(center.x - halfWid + brLt, center.y + halfHig - brLt); + DrawSector(vh, roundLt, brLt, color, color, 270, 360); + ltIn = roundLt + brLt * Vector3.left; + ltIn2 = roundLt + brLt * Vector3.up; + } + if (brRt > 0) + { + roundRt = new Vector3(center.x + halfWid - brRt, center.y + halfHig - brRt); + DrawSector(vh, roundRt, brRt, color, color, 0, 90); + rtIn = roundRt + brRt * Vector3.up; + rtIn2 = roundRt + brRt * Vector3.right; + } + if (brRb > 0) + { + roundRb = new Vector3(center.x + halfWid - brRb, center.y - halfHig + brRb); + DrawSector(vh, roundRb, brRb, color, color, 90, 180); + rbIn = roundRb + brRb * Vector3.right; + rbIn2 = roundRb + brRb * Vector3.down; + } + if (brLb > 0) + { + roundLb = new Vector3(center.x - halfWid + brLb, center.y - halfHig + brLb); + DrawSector(vh, roundLb, brLb, color, color, 180, 270); + lbIn = roundLb + brLb * Vector3.left; + lbIn2 = roundLb + brLb * Vector3.down; + } + var maxup = Mathf.Max(brLt, brRt); + DrawPolygon(vh, ltIn2, rtIn, rtIn + maxup * Vector3.down, ltIn2 + maxup * Vector3.down, color); + DrawPolygon(vh, ltIn, roundLt, roundLt + (maxup - brLt) * Vector3.down, ltIn + (maxup - brLt) * Vector3.down, color); + DrawPolygon(vh, roundRt, rtIn2, rtIn2 + (maxup - brRt) * Vector3.down, roundRt + (maxup - brRt) * Vector3.down, color); + var maxdown = Mathf.Max(brLb, brRb); + DrawPolygon(vh, lbIn2, lbIn2 + maxdown * Vector3.up, rbIn2 + maxdown * Vector3.up, rbIn2, color); + DrawPolygon(vh, lbIn, lbIn + (maxdown - brLb) * Vector3.up, roundLb + (maxdown - brLb) * Vector3.up, roundLb, color); + DrawPolygon(vh, roundRb, roundRb + (maxdown - brRb) * Vector3.up, rbIn2 + (maxdown - brRb) * Vector3.up, rbIn2, color); + var clt = new Vector3(center.x - halfWid, center.y + halfHig - maxup); + var crt = new Vector3(center.x + halfWid, center.y + halfHig - maxup); + var crb = new Vector3(center.x + halfWid, center.y - halfHig + maxdown); + var clb = new Vector3(center.x - halfWid, center.y - halfHig + maxdown); + if (clt.y > clb.y) + DrawPolygon(vh, clt, crt, crb, clb, color); + } + else + { + DrawPolygon(vh, lbIn, ltIn, rtIn, rbIn, color); + } + } + + /// + /// 绘制(圆角)边框 + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static void DrawBorder(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight, + float borderWidth, Color32 color, float rotate = 0, float[] cornerRadius = null) + { + if (borderWidth == 0 || color == Color.clear) return; + var halfWid = rectWidth / 2; + var halfHig = rectHeight / 2; + var lbIn = new Vector3(center.x - halfWid, center.y - halfHig); + var lbOt = new Vector3(center.x - halfWid - borderWidth, center.y - halfHig - borderWidth); + var ltIn = new Vector3(center.x - halfWid, center.y + halfHig); + var ltOt = new Vector3(center.x - halfWid - borderWidth, center.y + halfHig + borderWidth); + var rtIn = new Vector3(center.x + halfWid, center.y + halfHig); + var rtOt = new Vector3(center.x + halfWid + borderWidth, center.y + halfHig + borderWidth); + var rbIn = new Vector3(center.x + halfWid, center.y - halfHig); + var rbOt = new Vector3(center.x + halfWid + borderWidth, center.y - halfHig - borderWidth); + float brLt = 0, brRt = 0, brRb = 0, brLb = 0; + bool needRound = false; + InitCornerRadius(cornerRadius, rectWidth, rectHeight, ref brLt, ref brRt, ref brRb, ref brLb, ref needRound); + var tempCenter = Vector3.zero; + if (needRound) + { + var lbIn2 = lbIn; + var lbOt2 = lbOt; + var ltIn2 = ltIn; + var ltOt2 = ltOt; + var rtIn2 = rtIn; + var rtOt2 = rtOt; + var rbIn2 = rbIn; + var rbOt2 = rbOt; + if (brLt > 0) + { + tempCenter = new Vector3(center.x - halfWid + brLt, center.y + halfHig - brLt); + DrawDoughnut(vh, tempCenter, brLt, brLt + borderWidth, color, Color.clear, 2, 270, 360); + ltIn = tempCenter + brLt * Vector3.left; + ltOt = tempCenter + (brLt + borderWidth) * Vector3.left; + ltIn2 = tempCenter + brLt * Vector3.up; + ltOt2 = tempCenter + (brLt + borderWidth) * Vector3.up; + } + if (brRt > 0) + { + tempCenter = new Vector3(center.x + halfWid - brRt, center.y + halfHig - brRt); + DrawDoughnut(vh, tempCenter, brRt, brRt + borderWidth, color, Color.clear, 2, 0, 90); + rtIn = tempCenter + brRt * Vector3.up; + rtOt = tempCenter + (brRt + borderWidth) * Vector3.up; + rtIn2 = tempCenter + brRt * Vector3.right; + rtOt2 = tempCenter + (brRt + borderWidth) * Vector3.right; + } + if (brRb > 0) + { + tempCenter = new Vector3(center.x + halfWid - brRb, center.y - halfHig + brRb); + DrawDoughnut(vh, tempCenter, brRb, brRb + borderWidth, color, Color.clear, 2, 90, 180); + rbIn = tempCenter + brRb * Vector3.right; + rbOt = tempCenter + (brRb + borderWidth) * Vector3.right; + rbIn2 = tempCenter + brRb * Vector3.down; + rbOt2 = tempCenter + (brRb + borderWidth) * Vector3.down; + } + if (brLb > 0) + { + tempCenter = new Vector3(center.x - halfWid + brLb, center.y - halfHig + brLb); + DrawDoughnut(vh, tempCenter, brLb, brLb + borderWidth, color, Color.clear, 2, 180, 270); + lbIn = tempCenter + brLb * Vector3.left; + lbOt = tempCenter + (brLb + borderWidth) * Vector3.left; + lbIn2 = tempCenter + brLb * Vector3.down; + lbOt2 = tempCenter + (brLb + borderWidth) * Vector3.down; + } + DrawPolygon(vh, lbIn, lbOt, ltOt, ltIn, color); + DrawPolygon(vh, ltIn2, ltOt2, rtOt, rtIn, color); + DrawPolygon(vh, rtIn2, rtOt2, rbOt, rbIn, color); + DrawPolygon(vh, rbIn2, rbOt2, lbOt2, lbIn2, color); + } + else + { + if (rotate > 0) + { + lbIn = ChartHelper.RotateRound(lbIn, center, Vector3.forward, rotate); + lbOt = ChartHelper.RotateRound(lbOt, center, Vector3.forward, rotate); + ltIn = ChartHelper.RotateRound(ltIn, center, Vector3.forward, rotate); + ltOt = ChartHelper.RotateRound(ltOt, center, Vector3.forward, rotate); + rtIn = ChartHelper.RotateRound(rtIn, center, Vector3.forward, rotate); + rtOt = ChartHelper.RotateRound(rtOt, center, Vector3.forward, rotate); + rbIn = ChartHelper.RotateRound(rbIn, center, Vector3.forward, rotate); + rbOt = ChartHelper.RotateRound(rbOt, center, Vector3.forward, rotate); + } + DrawPolygon(vh, lbIn, lbOt, ltOt, ltIn, color); + DrawPolygon(vh, ltIn, ltOt, rtOt, rtIn, color); + DrawPolygon(vh, rtIn, rtOt, rbOt, rbIn, color); + DrawPolygon(vh, rbIn, rbOt, lbOt, lbIn, color); } - DrawPolygon(vh, p1In, p1Ot, p2Ot, p2In, color); - DrawPolygon(vh, p2In, p2Ot, p3Ot, p3In, color); - DrawPolygon(vh, p3In, p3Ot, p4Ot, p4In, color); - DrawPolygon(vh, p4In, p4Ot, p1Ot, p1In, color); } public static void DrawTriangle(VertexHelper vh, Vector3 p1,