From 2f9af18fd06ef2ae3187096758609298d3f26f10 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Thu, 22 Apr 2021 18:55:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89Chart=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/BaseChartEditor.cs | 16 +++++- Editor/PropertyDrawers/SerieDrawer.cs | 12 +++++ Editor/XChartEditor.cs | 2 +- Runtime/API/BaseChart_API.cs | 19 ++++++++ Runtime/Component/Main/Serie.cs | 54 +++++++++++++++++++++ Runtime/Component/Sub/SerieData.cs | 2 +- Runtime/Helper/FormatterHelper.cs | 12 +++-- Runtime/Helper/SerieHelper.cs | 42 ++++++++++++++++ Runtime/Internal/BaseChart.cs | 6 +-- Runtime/Internal/CoordinateChart.cs | 6 ++- Runtime/Internal/DrawSeriePie.cs | 3 +- Runtime/Internal/DrawSerieRadar.cs | 3 +- Runtime/Internal/Helper/SerieHelper.cs | 18 +------ Runtime/Internal/Helper/SerieLabelHelper.cs | 15 +++--- Runtime/Internal/Helper/TooltipHelper.cs | 7 +-- Runtime/Template/SerieTemplate.cs | 1 + Runtime/Utils/DateTimeUtil.cs | 2 +- 17 files changed, 177 insertions(+), 43 deletions(-) diff --git a/Editor/BaseChartEditor.cs b/Editor/BaseChartEditor.cs index 5ca8f65c..c547fca2 100644 --- a/Editor/BaseChartEditor.cs +++ b/Editor/BaseChartEditor.cs @@ -57,6 +57,7 @@ namespace XCharts private StringBuilder sb = new StringBuilder(); private bool m_BaseFoldout; + private bool m_CustomFoldout; protected bool m_ShowAllComponent; protected Dictionary m_Flodouts = new Dictionary(); @@ -130,7 +131,20 @@ namespace XCharts EditorGUILayout.PropertyField(m_ChartName); } BlockEnd(); - + var fileds = m_Chart.GetCustomChartInspectorShowFileds(); + if (fileds != null && fileds.Length > 0) + { + BlockStart(); + m_CustomFoldout = EditorGUILayout.Foldout(m_CustomFoldout, "Custom", true); + if (m_CustomFoldout) + { + foreach (var filed in fileds) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty(filed)); + } + } + BlockEnd(); + } BlockField(m_Theme); BlockField(m_Settings); BlockField(m_Background); diff --git a/Editor/PropertyDrawers/SerieDrawer.cs b/Editor/PropertyDrawers/SerieDrawer.cs index cd96e351..e688a0b7 100644 --- a/Editor/PropertyDrawers/SerieDrawer.cs +++ b/Editor/PropertyDrawers/SerieDrawer.cs @@ -208,6 +208,18 @@ namespace XCharts PropertyField(prop, "m_Label"); PropertyField(prop, "m_Emphasis"); break; + case SerieType.Custom: + var fileds = chart.GetCustomSerieInspectorShowFileds(); + if (fileds != null && fileds.Length > 0) + { + foreach (var filed in fileds) + { + PropertyField(prop, filed); + } + } + PropertyField(prop, "m_ItemStyle"); + PropertyField(prop, "m_Label"); + break; } PropertyField(prop, "m_Animation"); DrawData(pos, prop, serieType, ref m_DrawRect); diff --git a/Editor/XChartEditor.cs b/Editor/XChartEditor.cs index 73c990fa..22a756a0 100644 --- a/Editor/XChartEditor.cs +++ b/Editor/XChartEditor.cs @@ -56,7 +56,7 @@ namespace XCharts return name; } - private static void AddChart(string chartName) where T : BaseChart + public static void AddChart(string chartName) where T : BaseChart { var parent = GetParent(); if (parent == null) return; diff --git a/Runtime/API/BaseChart_API.cs b/Runtime/API/BaseChart_API.cs index 253b2ef4..489593a4 100644 --- a/Runtime/API/BaseChart_API.cs +++ b/Runtime/API/BaseChart_API.cs @@ -719,5 +719,24 @@ namespace XCharts { return SeriesHelper.ContainsSerie(m_Series, serieType); } + + public virtual bool AddDefaultCustomSerie(string serieName) + { + return false; + } + + public virtual string[] GetCustomSerieInspectorShowFileds() + { + return null; + } + public virtual string[] GetCustomChartInspectorShowFileds() + { + return null; + } + + public int GetLegendRealShowNameIndex(string name) + { + return m_LegendRealShowName.IndexOf(name); + } } } diff --git a/Runtime/Component/Main/Serie.cs b/Runtime/Component/Main/Serie.cs index 3811bc88..11aa390e 100644 --- a/Runtime/Component/Main/Serie.cs +++ b/Runtime/Component/Main/Serie.cs @@ -68,6 +68,10 @@ namespace XCharts /// 甘特图。甘特图的data至少包含两个数据:[start, end] /// Gantt, + /// + /// 自定义。 + /// + Custom, } /// @@ -277,6 +281,7 @@ namespace XCharts [SerializeField] private bool m_ClickOffset = true; [SerializeField] private RoseType m_RoseType = RoseType.None; + [FormerlySerializedAs("m_Gap")] [SerializeField] private float m_Space; [SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.45f }; [SerializeField] private float[] m_Radius = new float[2] { 0, 80 }; @@ -301,6 +306,10 @@ namespace XCharts [SerializeField] private float m_WaveSpeed = 5f; [SerializeField] private float m_WaveOffset = 0f; [SerializeField] private RadarType m_RadarType = RadarType.Multiple; + [SerializeField] private float m_Left; + [SerializeField] private float m_Right; + [SerializeField] private float m_Top; + [SerializeField] private float m_Bottom; [SerializeField] private List m_Data = new List(); @@ -590,6 +599,11 @@ namespace XCharts get { return m_Space; } set { if (PropertyUtil.SetStruct(ref m_Space, value)) SetVerticesDirty(); } } + public float gap + { + get { return m_Space; } + set { if (PropertyUtil.SetStruct(ref m_Space, value)) SetVerticesDirty(); } + } /// /// the center of chart. /// 中心点。 @@ -882,6 +896,42 @@ namespace XCharts set { if (PropertyUtil.SetStruct(ref m_WaveSpeed, value)) SetVerticesDirty(); } } /// + /// Distance between component and the left side of the container. + /// 组件离容器左侧的距离。 + /// + public float left + { + get { return m_Left; } + set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetAllDirty(); } + } + /// + /// Distance between component and the right side of the container. + /// 组件离容器右侧的距离。 + /// + public float right + { + get { return m_Right; } + set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetAllDirty(); } + } + /// + /// Distance between component and the top side of the container. + /// 组件离容器上侧的距离。 + /// + public float top + { + get { return m_Top; } + set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetAllDirty(); } + } + /// + /// Distance between component and the bottom side of the container. + /// 组件离容器下侧的距离。 + /// + public float bottom + { + get { return m_Bottom; } + set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetAllDirty(); } + } + /// /// 系列中的数据内容数组。SerieData可以设置1到n维数据。 /// public List data { get { return m_Data; } } @@ -981,6 +1031,10 @@ namespace XCharts public Painter runtimeCanvas { get; internal set; } internal float runtimeCheckValue { get; set; } public int runtimeGridIndex { get; internal set; } + public float runtimeX { get; internal set; } + public float runtimeY { get; internal set; } + public float runtimeWidth { get; internal set; } + public float runtimeHeight { get; internal set; } public bool nameDirty { get { return m_NameDirty; } } private void SetNameDirty() diff --git a/Runtime/Component/Sub/SerieData.cs b/Runtime/Component/Sub/SerieData.cs index ad09a74b..2eac1bc5 100644 --- a/Runtime/Component/Sub/SerieData.cs +++ b/Runtime/Component/Sub/SerieData.cs @@ -187,7 +187,7 @@ namespace XCharts /// 饼图数据项的偏移半径 /// public float runtimePieOffsetRadius { get; internal set; } - public Vector3 runtimePosition { get; internal set; } + public Vector3 runtimePosition { get; set; } /// /// 绘制区域。 /// diff --git a/Runtime/Helper/FormatterHelper.cs b/Runtime/Helper/FormatterHelper.cs index 6d982a61..ee61cb3f 100644 --- a/Runtime/Helper/FormatterHelper.cs +++ b/Runtime/Helper/FormatterHelper.cs @@ -23,8 +23,8 @@ namespace XCharts private static Regex s_RegexNewLine = new Regex(@"[\\|/]+n", RegexOptions.IgnoreCase); private static Regex s_RegexForAxisLabel = new Regex(@"{value(:[c-g|x|p|r]\d*)?}", RegexOptions.IgnoreCase); private static Regex s_RegexSubForAxisLabel = new Regex(@"(value)|([c-g|x|p|r]\d*)", RegexOptions.IgnoreCase); - private static Regex s_RegexForSerieLabel = new Regex(@"{[a-d](:[c-g|x|p|r]\d*)?}", RegexOptions.IgnoreCase); - private static Regex s_RegexSubForSerieLabel = new Regex(@"([a-d])|([c-g|x|p|r]\d*)", RegexOptions.IgnoreCase); + private static Regex s_RegexForSerieLabel = new Regex(@"{[a-d|\.](:[c-g|x|p|r]\d*)?}", RegexOptions.IgnoreCase); + private static Regex s_RegexSubForSerieLabel = new Regex(@"(\.)|([a-d])|([c-g|x|p|r]\d*)", RegexOptions.IgnoreCase); /// /// 替换字符串中的通配符,支持的通配符有{.}、{a}、{b}、{c}、{d}。 @@ -214,7 +214,7 @@ namespace XCharts } public static void ReplaceSerieLabelContent(ref string content, string numericFormatter, float value, float total, - string serieName, string dataName) + string serieName, string dataName, Color color) { var mc = s_RegexForSerieLabel.Matches(content); foreach (var m in mc) @@ -228,7 +228,11 @@ namespace XCharts { numericFormatter = args[1].ToString(); } - if (p == 'a' || p == 'A') + if (p == '.') + { + content = content.Replace(old, ChartCached.ColorToDotStr(color)); + } + else if (p == 'a' || p == 'A') { content = content.Replace(old, serieName); } diff --git a/Runtime/Helper/SerieHelper.cs b/Runtime/Helper/SerieHelper.cs index 77a5b036..8cd45d72 100644 --- a/Runtime/Helper/SerieHelper.cs +++ b/Runtime/Helper/SerieHelper.cs @@ -85,5 +85,47 @@ namespace XCharts } return true; } + + /// + /// 更新运行时中心点和半径 + /// + /// + /// + public static void UpdateCenter(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight) + { + if (serie.center.Length < 2) return; + var centerX = serie.center[0] <= 1 ? chartWidth * serie.center[0] : serie.center[0]; + var centerY = serie.center[1] <= 1 ? chartHeight * serie.center[1] : serie.center[1]; + serie.runtimeCenterPos = chartPosition + new Vector3(centerX, centerY); + var minWidth = Mathf.Min(chartWidth, chartHeight); + serie.runtimeInsideRadius = serie.radius[0] <= 1 ? minWidth * serie.radius[0] : serie.radius[0]; + serie.runtimeOutsideRadius = serie.radius[1] <= 1 ? minWidth * serie.radius[1] : serie.radius[1]; + } + + public static void UpdateRect(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight) + { + if (serie.left != 0 || serie.right != 0 || serie.top != 0 || serie.bottom != 0) + { + var runtimeLeft = serie.left <= 1 ? serie.left * chartWidth : serie.left; + var runtimeBottom = serie.bottom <= 1 ? serie.bottom * chartHeight : serie.bottom; + var runtimeTop = serie.top <= 1 ? serie.top * chartHeight : serie.top; + var runtimeRight = serie.right <= 1 ? serie.right * chartWidth : serie.right; + + serie.runtimeX = chartPosition.x + runtimeLeft; + serie.runtimeY = chartPosition.y + runtimeBottom; + serie.runtimeWidth = chartWidth - runtimeLeft - runtimeRight; + serie.runtimeHeight = chartHeight - runtimeTop - runtimeBottom; + serie.runtimeCenterPos = new Vector3(serie.runtimeX + serie.runtimeWidth / 2, + serie.runtimeY + serie.runtimeHeight / 2); + } + else + { + serie.runtimeX = chartPosition.x; + serie.runtimeY = chartPosition.y; + serie.runtimeWidth = chartWidth; + serie.runtimeHeight = chartHeight; + serie.runtimeCenterPos = chartPosition + new Vector3(chartWidth / 2, chartHeight / 2); + } + } } } \ No newline at end of file diff --git a/Runtime/Internal/BaseChart.cs b/Runtime/Internal/BaseChart.cs index c00a0307..60afacb8 100644 --- a/Runtime/Internal/BaseChart.cs +++ b/Runtime/Internal/BaseChart.cs @@ -86,7 +86,7 @@ namespace XCharts protected GameObject m_SerieLabelRoot; private Theme m_CheckTheme = 0; - private List m_DrawSeries = new List(); + protected List m_DrawSeries = new List(); protected override void InitComponent() { @@ -170,13 +170,13 @@ namespace XCharts m_Painter.Refresh(); } - internal void RefreshPainter(int index) + public void RefreshPainter(int index) { var painter = GetPainter(index); RefreshPainter(painter); } - internal void RefreshPainter(Serie serie) + public void RefreshPainter(Serie serie) { RefreshPainter(GetPainterIndexBySerie(serie)); } diff --git a/Runtime/Internal/CoordinateChart.cs b/Runtime/Internal/CoordinateChart.cs index 7df5ac91..2fbee31b 100644 --- a/Runtime/Internal/CoordinateChart.cs +++ b/Runtime/Internal/CoordinateChart.cs @@ -1697,11 +1697,13 @@ namespace XCharts if (anyPercentStack && isPercentStack) { var tempTotal = GetSameStackTotalValue(serie.stack, j); - content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, tempTotal, serieLabel); + content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, tempTotal, + serieLabel, theme.GetColor(i)); } else { - content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, serieLabel); + content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, + serieLabel, theme.GetColor(i)); } serieData.SetLabelActive(value != 0 && serieData.labelPosition != Vector3.zero); var invert = serieLabel.autoOffset diff --git a/Runtime/Internal/DrawSeriePie.cs b/Runtime/Internal/DrawSeriePie.cs index c6683e8c..e78ab63f 100644 --- a/Runtime/Internal/DrawSeriePie.cs +++ b/Runtime/Internal/DrawSeriePie.cs @@ -544,7 +544,8 @@ namespace XCharts { var value = serieData.data[1]; var total = serie.yTotal; - var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, serieLabel); + var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, + serieLabel, serieColor); if (serieData.labelObject.SetText(content)) chart.RefreshPainter(serie); } else diff --git a/Runtime/Internal/DrawSerieRadar.cs b/Runtime/Internal/DrawSerieRadar.cs index 5efc77c9..45de93e2 100644 --- a/Runtime/Internal/DrawSerieRadar.cs +++ b/Runtime/Internal/DrawSerieRadar.cs @@ -102,7 +102,8 @@ namespace XCharts SerieLabelHelper.ResetLabel(serieData.labelObject.label, serieLabel, chart.theme, i); serieData.SetLabelActive(serieData.labelPosition != Vector3.zero); serieData.labelObject.SetLabelPosition(serieLabel.offset); - var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, max, serieLabel); + var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, max, + serieLabel, Color.clear); if (serieData.labelObject.SetText(content)) { chart.RefreshPainter(serie); diff --git a/Runtime/Internal/Helper/SerieHelper.cs b/Runtime/Internal/Helper/SerieHelper.cs index 4433a1d2..0fe073bc 100644 --- a/Runtime/Internal/Helper/SerieHelper.cs +++ b/Runtime/Internal/Helper/SerieHelper.cs @@ -179,7 +179,7 @@ namespace XCharts else return null; } - internal static SerieLabel GetSerieLabel(Serie serie, SerieData serieData, bool highlight = false) + public static SerieLabel GetSerieLabel(Serie serie, SerieData serieData, bool highlight = false) { if (highlight) { @@ -272,22 +272,6 @@ namespace XCharts else return null; } - /// - /// 更新运行时中心点和半径 - /// - /// - /// - internal static void UpdateCenter(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight) - { - if (serie.center.Length < 2) return; - var centerX = serie.center[0] <= 1 ? chartWidth * serie.center[0] : serie.center[0]; - var centerY = serie.center[1] <= 1 ? chartHeight * serie.center[1] : serie.center[1]; - serie.runtimeCenterPos = chartPosition + new Vector3(centerX, centerY); - var minWidth = Mathf.Min(chartWidth, chartHeight); - serie.runtimeInsideRadius = serie.radius[0] <= 1 ? minWidth * serie.radius[0] : serie.radius[0]; - serie.runtimeOutsideRadius = serie.radius[1] <= 1 ? minWidth * serie.radius[1] : serie.radius[1]; - } - internal static string GetNumericFormatter(Serie serie, SerieData serieData) { var itemStyle = SerieHelper.GetItemStyle(serie, serieData); diff --git a/Runtime/Internal/Helper/SerieLabelHelper.cs b/Runtime/Internal/Helper/SerieLabelHelper.cs index 9cc66317..de20e4a5 100644 --- a/Runtime/Internal/Helper/SerieLabelHelper.cs +++ b/Runtime/Internal/Helper/SerieLabelHelper.cs @@ -6,11 +6,10 @@ /************************************************/ using System.Collections.Generic; using UnityEngine; -using UnityEngine.UI; namespace XCharts { - internal static class SerieLabelHelper + public static class SerieLabelHelper { public static void CheckLabel(Serie serie, ref bool m_ReinitLabel, ref bool m_UpdateLabelText) { @@ -90,7 +89,7 @@ namespace XCharts } public static string GetFormatterContent(Serie serie, SerieData serieData, - float dataValue, float dataTotal, SerieLabel serieLabel = null) + float dataValue, float dataTotal, SerieLabel serieLabel, Color color) { if (serieLabel == null) { @@ -105,7 +104,7 @@ namespace XCharts { var content = serieLabel.formatter; FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, dataValue, - dataTotal, serieName, dataName); + dataTotal, serieName, dataName, color); return content; } } @@ -117,7 +116,7 @@ namespace XCharts if (serieData.labelObject == null) return; var value = serieData.GetData(1); var total = serie.max; - var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total); + var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, null, Color.clear); serieData.labelObject.SetText(content); serieData.labelObject.SetLabelPosition(serie.runtimeCenterPos + serie.label.offset); if (!ChartHelper.IsClearColor(serie.label.textStyle.color)) @@ -141,7 +140,7 @@ namespace XCharts } var value = serieData.GetData(0); var total = serieData.GetData(1); - var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total); + var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, null, Color.clear); serieData.SetLabelActive(true); serieData.labelObject.SetText(content); serieData.labelObject.SetLabelColor(GetLabelColor(serie, theme, i)); @@ -176,7 +175,7 @@ namespace XCharts } var value = serieData.GetData(1); var total = serie.max - serie.min; - var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total); + var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, null, Color.clear); serieData.SetLabelActive(true); serieData.labelObject.SetText(content); serieData.labelObject.SetLabelColor(GetLabelColor(serie, theme, colorIndex)); @@ -295,7 +294,7 @@ namespace XCharts } } - internal static Vector3 GetRealLabelPosition(SerieData serieData, SerieLabel label) + public static Vector3 GetRealLabelPosition(SerieData serieData, SerieLabel label) { if (label.position == SerieLabel.Position.Outside && label.lineType != SerieLabel.LineType.HorizontalLine) { diff --git a/Runtime/Internal/Helper/TooltipHelper.cs b/Runtime/Internal/Helper/TooltipHelper.cs index 343024ca..dade1d1b 100644 --- a/Runtime/Internal/Helper/TooltipHelper.cs +++ b/Runtime/Internal/Helper/TooltipHelper.cs @@ -146,7 +146,8 @@ namespace XCharts else { string content = itemFormatter; - FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, value, total, serie.name, sd.name); + FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, value, total, serie.name, + sd.name, theme.GetColor(i)); sb.Append(content); } } @@ -180,10 +181,10 @@ namespace XCharts else { string content = itemFormatter2; - FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, value2, total2, serie.name, serieData.name); + FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, value2, total2, serie.name, + serieData.name, theme.GetColor(serie.index)); sb.Append(content); } - break; } } diff --git a/Runtime/Template/SerieTemplate.cs b/Runtime/Template/SerieTemplate.cs index f93a43c2..fe7fc0d1 100644 --- a/Runtime/Template/SerieTemplate.cs +++ b/Runtime/Template/SerieTemplate.cs @@ -29,6 +29,7 @@ namespace XCharts case SerieType.Ring: AddDefaultRingSerie(chart, serieName); break; case SerieType.Candlestick: AddDefaultCandlestickSerie(chart, serieName); break; case SerieType.Gantt: AddDefaultCategoryGanttSerie(chart, serieName); break; + case SerieType.Custom: chart.AddDefaultCustomSerie(serieName); break; default: Debug.LogError("AddDefaultSerie: not support serieType yet:" + serieType); break; } } diff --git a/Runtime/Utils/DateTimeUtil.cs b/Runtime/Utils/DateTimeUtil.cs index 674297f9..63ab74fb 100644 --- a/Runtime/Utils/DateTimeUtil.cs +++ b/Runtime/Utils/DateTimeUtil.cs @@ -12,7 +12,7 @@ namespace XCharts { public static class DateTimeUtil { - private static readonly DateTime k_DateTime1970 = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); + private static readonly DateTime k_DateTime1970 = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1), TimeZoneInfo.Local); public static int GetTimestamp() {