diff --git a/Editor/MainComponents/AxisEditor.cs b/Editor/MainComponents/AxisEditor.cs index ea4612c6..a62d29cb 100644 --- a/Editor/MainComponents/AxisEditor.cs +++ b/Editor/MainComponents/AxisEditor.cs @@ -179,6 +179,7 @@ namespace XCharts.Editor { ++EditorGUI.indentLevel; PropertyField(prop, "m_Name"); + PropertyField(prop, "m_Formatter"); PropertyField(prop, "m_Location"); PropertyField(prop, "m_TextStyle"); --EditorGUI.indentLevel; diff --git a/Editor/MainComponents/RadarCoordEditor.cs b/Editor/MainComponents/RadarCoordEditor.cs index 23538832..15eae902 100644 --- a/Editor/MainComponents/RadarCoordEditor.cs +++ b/Editor/MainComponents/RadarCoordEditor.cs @@ -21,6 +21,7 @@ namespace XCharts.Editor PropertyField("m_ConnectCenter"); PropertyField("m_LineGradient"); PropertyField("m_AxisLine"); + PropertyField("m_AxisName"); PropertyField("m_SplitLine"); PropertyField("m_SplitArea"); PropertyField("m_IndicatorList"); @@ -42,7 +43,6 @@ namespace XCharts.Editor PropertyField(prop, "m_Min"); PropertyField(prop, "m_Max"); PropertyTwoFiled(prop, "m_Range"); - PropertyField(prop, "m_TextStyle"); --EditorGUI.indentLevel; } } diff --git a/Editor/Series/SerieEditor.cs b/Editor/Series/SerieEditor.cs index 3b5879a7..633dd1f7 100644 --- a/Editor/Series/SerieEditor.cs +++ b/Editor/Series/SerieEditor.cs @@ -199,13 +199,15 @@ namespace XCharts.Editor var m_ItemStyle = serieData.FindPropertyRelative("m_ItemStyles"); var m_Emphasis = serieData.FindPropertyRelative("m_Emphases"); var m_Symbol = serieData.FindPropertyRelative("m_Symbols"); + var m_LineStyle = serieData.FindPropertyRelative("m_LineStyles"); + var m_AreaStyle = serieData.FindPropertyRelative("m_AreaStyles"); PropertyField(sereName); PropertyField(selected); PropertyField(m_Ignore); var componentNum = m_IconStyle.arraySize + m_Label.arraySize + m_ItemStyle.arraySize + m_Emphasis.arraySize - + m_Symbol.arraySize; + + m_Symbol.arraySize + m_LineStyle.arraySize + m_AreaStyle.arraySize; var title = "Component"; if (componentNum == 0) title += " (None)"; m_DataComponentFoldout = ChartEditorHelper.DrawHeader(title, m_DataComponentFoldout, false, null, null, @@ -229,6 +231,14 @@ namespace XCharts.Editor { serie.GetSerieData(index).GetOrAddComponent(); }, m_Symbol.arraySize == 0), + new HeaderMenuInfo("Add LineStyle", () => + { + serie.GetSerieData(index).GetOrAddComponent(); + }, m_LineStyle.arraySize == 0), + new HeaderMenuInfo("Add AreaStyle", () => + { + serie.GetSerieData(index).GetOrAddComponent(); + }, m_AreaStyle.arraySize == 0), new HeaderMenuInfo("Remove ItemStyle", () => { serie.GetSerieData(index).RemoveComponent(); @@ -249,10 +259,18 @@ namespace XCharts.Editor { serie.GetSerieData(index).RemoveComponent(); }, m_Symbol.arraySize > 0), + new HeaderMenuInfo("Remove LineStyle", () => + { + serie.GetSerieData(index).RemoveComponent(); + }, m_LineStyle.arraySize > 0), + new HeaderMenuInfo("Remove AreaStyle", () => + { + serie.GetSerieData(index).RemoveComponent(); + }, m_AreaStyle.arraySize > 0), new HeaderMenuInfo("Remove All", () => { serie.GetSerieData(index).RemoveAllComponent(); - }, m_Symbol.arraySize > 0)); + }, componentNum > 0)); if (m_DataComponentFoldout) { if (m_IconStyle.arraySize > 0) @@ -265,6 +283,10 @@ namespace XCharts.Editor PropertyField(m_Emphasis.GetArrayElementAtIndex(0)); if (m_Symbol.arraySize > 0) PropertyField(m_Symbol.GetArrayElementAtIndex(0)); + if (m_LineStyle.arraySize > 0) + PropertyField(m_LineStyle.GetArrayElementAtIndex(0)); + if (m_AreaStyle.arraySize > 0) + PropertyField(m_AreaStyle.GetArrayElementAtIndex(0)); } EditorGUI.indentLevel--; } diff --git a/Runtime/Chart/HeatmapChart.cs b/Runtime/Chart/HeatmapChart.cs index 4bfea84d..11310462 100644 --- a/Runtime/Chart/HeatmapChart.cs +++ b/Runtime/Chart/HeatmapChart.cs @@ -20,9 +20,7 @@ namespace XCharts tooltip.trigger = Tooltip.Trigger.Axis; var grid = GetOrAddChartComponent(); - grid.left = 100; - grid.right = 60; - grid.bottom = 60; + grid.left = 0.12f; var xAxis = GetOrAddChartComponent(); xAxis.type = Axis.AxisType.Category; diff --git a/Runtime/Component/Axis/AxisName.cs b/Runtime/Component/Axis/AxisName.cs index 5f917968..c3b89d4b 100644 --- a/Runtime/Component/Axis/AxisName.cs +++ b/Runtime/Component/Axis/AxisName.cs @@ -23,6 +23,7 @@ namespace XCharts } [SerializeField] private bool m_Show; [SerializeField] private string m_Name; + [SerializeField] private string m_Formatter; [SerializeField] private Location m_Location; [SerializeField] private TextStyle m_TextStyle = new TextStyle(); @@ -45,6 +46,15 @@ namespace XCharts set { if (PropertyUtil.SetClass(ref m_Name, value)) SetComponentDirty(); } } /// + /// The formatter of indicator's name. + /// 指示器名称显示的格式器。可用在雷达图。 + /// + public string formatter + { + get { return m_Formatter; } + set { if (PropertyUtil.SetClass(ref m_Formatter, value)) SetComponentDirty(); } + } + /// /// Location of axis name. /// 坐标轴名称显示位置。 /// diff --git a/Runtime/Component/Child/AreaStyle.cs b/Runtime/Component/Child/AreaStyle.cs index 9323dec1..f5ec73aa 100644 --- a/Runtime/Component/Child/AreaStyle.cs +++ b/Runtime/Component/Child/AreaStyle.cs @@ -9,7 +9,7 @@ namespace XCharts /// 区域填充样式。 /// [System.Serializable] - public class AreaStyle : ChildComponent, ISerieExtraComponent + public class AreaStyle : ChildComponent, ISerieExtraComponent, ISerieDataComponent { /// /// Origin position of area. diff --git a/Runtime/Component/Child/LineStyle.cs b/Runtime/Component/Child/LineStyle.cs index 5fbfd112..e8001517 100644 --- a/Runtime/Component/Child/LineStyle.cs +++ b/Runtime/Component/Child/LineStyle.cs @@ -11,7 +11,7 @@ namespace XCharts /// toColor,toColor2可设置水平方向的渐变,如需要设置垂直方向的渐变,可使用VisualMap。 /// [System.Serializable] - public class LineStyle : ChildComponent + public class LineStyle : ChildComponent, ISerieDataComponent { /// /// 线的类型。 diff --git a/Runtime/Component/Legend/LegendHandler.cs b/Runtime/Component/Legend/LegendHandler.cs index 5e251580..44bca0b5 100644 --- a/Runtime/Component/Legend/LegendHandler.cs +++ b/Runtime/Component/Legend/LegendHandler.cs @@ -42,7 +42,7 @@ namespace XCharts private void InitLegend(Legend legend) { - legend.painter = null; // legend component does not need to paint + legend.painter = null; legend.refreshComponent = delegate () { legend.OnChanged(); @@ -55,9 +55,10 @@ namespace XCharts if (legend.show && legend.data.Count > 0) { datas = new List(); - for (int i = 0; i < chart.m_LegendRealShowName.Count; i++) + foreach (var data in legend.data) { - if (legend.data.Contains(chart.m_LegendRealShowName[i])) datas.Add(chart.m_LegendRealShowName[i]); + if (chart.m_LegendRealShowName.Contains(data) || chart.IsSerieName(data)) + datas.Add(data); } } else @@ -130,13 +131,6 @@ namespace XCharts chart.OnLegendButtonExit(index, selectedName); }); } - if (legend.selectedMode == Legend.SelectedMode.Single) - { - for (int n = 0; n < chart.m_LegendRealShowName.Count; n++) - { - chart.OnLegendButtonClick(n, chart.m_LegendRealShowName[n], n == 0 ? true : false); - } - } LegendHelper.ResetItemPosition(legend, chart.chartPosition, chart.chartWidth, chart.chartHeight); }; legend.refreshComponent(); diff --git a/Runtime/Component/Mark/MarkAreaHandler.cs b/Runtime/Component/Mark/MarkAreaHandler.cs index c4ee3500..4dfb21a6 100644 --- a/Runtime/Component/Mark/MarkAreaHandler.cs +++ b/Runtime/Component/Mark/MarkAreaHandler.cs @@ -71,7 +71,7 @@ namespace XCharts UpdateRuntimeData(markArea); var colorIndex = chart.GetLegendRealShowNameIndex(serie.serieName); - var serieColor = SerieHelper.GetLineColor(serie, chart.theme, colorIndex, false); + var serieColor = SerieHelper.GetLineColor(serie, null, chart.theme, colorIndex, false); var areaColor = markArea.itemStyle.GetColor(serieColor); UGL.DrawRectangle(vh, markArea.runtimeRect, areaColor, areaColor); } diff --git a/Runtime/Component/Mark/MarkLineHandler.cs b/Runtime/Component/Mark/MarkLineHandler.cs index b05a9801..219323de 100644 --- a/Runtime/Component/Mark/MarkLineHandler.cs +++ b/Runtime/Component/Mark/MarkLineHandler.cs @@ -104,7 +104,7 @@ namespace XCharts var sp = Vector3.zero; var ep = Vector3.zero; var colorIndex = chart.GetLegendRealShowNameIndex(serie.serieName); - var serieColor = SerieHelper.GetLineColor(serie, chart.theme, colorIndex, false); + var serieColor = SerieHelper.GetLineColor(serie, null, chart.theme, colorIndex, false); animation.InitProgress(0, 1f); ResetTempMarkLineGroupData(markLine); if (m_TempGroupData.Count > 0) diff --git a/Runtime/Component/Radar/RadarCoord.cs b/Runtime/Component/Radar/RadarCoord.cs index cd154435..04e04e8c 100644 --- a/Runtime/Component/Radar/RadarCoord.cs +++ b/Runtime/Component/Radar/RadarCoord.cs @@ -51,7 +51,6 @@ namespace XCharts [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(); /// /// The name of indicator. @@ -69,11 +68,6 @@ namespace XCharts /// public double min { get { return m_Min; } set { m_Min = value; } } /// - /// the style of text. - /// 文本样式。 - /// - public TextStyle textStyle { get { return m_TextStyle; } set { m_TextStyle = value; } } - /// /// the text conponent of indicator. /// 指示器的文本组件。 /// @@ -103,6 +97,7 @@ namespace XCharts [SerializeField] private int m_SplitNumber = 5; [SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.5f }; [SerializeField] private AxisLine m_AxisLine = AxisLine.defaultAxisLine; + [SerializeField] private AxisName m_AxisName = AxisName.defaultAxisName; [SerializeField] private AxisSplitLine m_SplitLine = AxisSplitLine.defaultSplitLine; [SerializeField] private AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea; [SerializeField] private bool m_Indicator = true; @@ -171,6 +166,15 @@ namespace XCharts set { if (PropertyUtil.SetClass(ref m_AxisLine, value, true)) SetAllDirty(); } } /// + /// Name options for radar indicators. + /// 雷达图每个指示器名称的配置项。 + /// + public AxisName axisName + { + get { return m_AxisName; } + set { if (PropertyUtil.SetClass(ref m_AxisName, value, true)) SetAllDirty(); } + } + /// /// split line. /// 分割线。 /// @@ -288,6 +292,8 @@ namespace XCharts center[1] = 0.4f; splitLine.show = true; splitArea.show = true; + axisName.show = true; + axisName.name = null; } private bool IsEqualsIndicatorList(List indicators1, List indicators2) @@ -410,5 +416,31 @@ namespace XCharts { indicatorList.Clear(); } + + public string GetFormatterIndicatorContent(int indicatorIndex) + { + var indicator = GetIndicator(indicatorIndex); + if (indicator == null) + return string.Empty; + else + return GetFormatterIndicatorContent(indicator.name); + } + + public string GetFormatterIndicatorContent(string indicatorName) + { + if (string.IsNullOrEmpty(indicatorName)) + return indicatorName; + + if (string.IsNullOrEmpty(m_AxisName.formatter)) + { + return indicatorName; + } + else + { + var content = m_AxisName.formatter; + FormatterHelper.ReplaceAxisLabelContent(ref content, indicatorName); + return content; + } + } } } \ No newline at end of file diff --git a/Runtime/Component/Radar/RadarCoordHandler.cs b/Runtime/Component/Radar/RadarCoordHandler.cs index ccf6bc27..dbf51c96 100644 --- a/Runtime/Component/Radar/RadarCoordHandler.cs +++ b/Runtime/Component/Radar/RadarCoordHandler.cs @@ -40,23 +40,32 @@ namespace XCharts radar.painter = chart.GetPainter(radar.index); radar.refreshComponent = delegate () { - ChartHelper.HideAllObject(chart.transform, INDICATOR_TEXT + "_" + radar.index); radar.UpdateRadarCenter(chart.chartPosition, chart.chartWidth, chart.chartHeight); + var radarObject = ChartHelper.AddObject("Radar" + radar.index, chart.transform, chart.chartMinAnchor, + chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); + radar.gameObject = radarObject; + radar.gameObject.hideFlags = chart.chartHideFlags; + var textStyle = radar.axisName.textStyle; + ChartHelper.HideAllObject(radarObject.transform, INDICATOR_TEXT); for (int i = 0; i < radar.indicatorList.Count; i++) { var indicator = radar.indicatorList[i]; var pos = radar.GetIndicatorPosition(i); - var textStyle = indicator.textStyle; - var objName = INDICATOR_TEXT + "_" + radar.index + "_" + i; - var txt = ChartHelper.AddTextObject(objName, chart.transform, new Vector2(0.5f, 0.5f), - new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(txtWid, txtHig), - textStyle, chart.theme.axis); - txt.gameObject.hideFlags = chart.chartHideFlags; - txt.SetAlignment(textStyle.GetAlignment(TextAnchor.MiddleCenter)); - txt.SetText(radar.indicatorList[i].name); - txt.SetActive(radar.indicator); + var objName = INDICATOR_TEXT + "_" + i; + + var labelGameObject = ChartHelper.AddObject(objName, radarObject.transform, new Vector2(0.5f, 0.5f), + new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(txtWid, txtHig)); + var label = ChartHelper.GetOrAddComponent(labelGameObject); + label.label = ChartHelper.AddTextObject("Text", label.gameObject.transform, new Vector2(0.5f, 0.5f), + new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(txtWid, txtHig), textStyle, chart.theme.common); + label.SetAutoSize(true); + label.label.SetAlignment(textStyle.GetAlignment(TextAnchor.MiddleCenter)); + label.SetText(radar.GetFormatterIndicatorContent(i)); + label.SetActive(radar.indicator); + label.color = textStyle.backgroundColor; + var offset = new Vector3(textStyle.offset.x, textStyle.offset.y); - AxisHelper.AdjustCircleLabelPos(txt, pos, radar.context.center, txtHig, offset); + AxisHelper.AdjustCircleLabelPos(label, pos, radar.context.center, txtHig, offset); } chart.RefreshBasePainter(); }; diff --git a/Runtime/Component/Title/TitleStyle.cs b/Runtime/Component/Title/TitleStyle.cs index 86fae29b..c68b06c5 100644 --- a/Runtime/Component/Title/TitleStyle.cs +++ b/Runtime/Component/Title/TitleStyle.cs @@ -13,7 +13,6 @@ namespace XCharts public class TitleStyle : ChildComponent { [SerializeField] private bool m_Show; - [FormerlySerializedAs("m_textStyle")] [SerializeField] private TextStyle m_TextStyle = new TextStyle(); /// diff --git a/Runtime/Component/Tooltip/TooltipHandler.cs b/Runtime/Component/Tooltip/TooltipHandler.cs index 01fac8fb..12be4b79 100644 --- a/Runtime/Component/Tooltip/TooltipHandler.cs +++ b/Runtime/Component/Tooltip/TooltipHandler.cs @@ -357,7 +357,7 @@ namespace XCharts { var serie = series[i]; serie.context.isTriggerByAxis = isTriggerByAxis; - if (isTriggerByAxis) + if (isTriggerByAxis && dataIndex >= 0) serie.context.pointerItemDataIndex = dataIndex; serie.handler.UpdateTooltipSerieParams(dataIndex, showCategory, category, tooltip.marker, tooltip.itemFormatter, tooltip.numericFormatter, diff --git a/Runtime/Helper/SerieHelper.cs b/Runtime/Helper/SerieHelper.cs index efb40bc3..ab671d65 100644 --- a/Runtime/Helper/SerieHelper.cs +++ b/Runtime/Helper/SerieHelper.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Reflection; -using System.Text; using UnityEngine; namespace XCharts @@ -453,7 +452,7 @@ namespace XCharts public static IconStyle GetIconStyle(Serie serie, SerieData serieData) { - if (serieData.iconStyle != null) return serieData.iconStyle; + if (serieData != null && serieData.iconStyle != null) return serieData.iconStyle; else return serie.iconStyle; } @@ -463,55 +462,62 @@ namespace XCharts else return serie.symbol; } - public static Color32 GetAreaColor(Serie serie, ThemeStyle theme, int index, bool highlight) + public static LineStyle GetLineStyle(Serie serie, SerieData serieData) + { + if (serieData != null && serieData.lineStyle != null) return serieData.lineStyle; + else return serie.lineStyle; + } + + public static AreaStyle GetAreaStyle(Serie serie, SerieData serieData) + { + if (serieData != null && serieData.areaStyle != null) return serieData.areaStyle; + else return serie.areaStyle; + } + + public static Color32 GetAreaColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight) { Color32 color = ChartConst.clearColor32; - var areaStyle = serie.areaStyle; + var areaStyle = GetAreaStyle(serie, serieData); if (areaStyle == null || !areaStyle.show) return color; - + if (!ChartHelper.IsClearColor(areaStyle.color)) color = areaStyle.color; + else if (!ChartHelper.IsClearColor(serie.itemStyle.color)) color = serie.itemStyle.color; + else color = theme.GetColor(index); + ChartHelper.SetColorOpacity(ref color, areaStyle.opacity); if (highlight) { if (!ChartHelper.IsClearColor(areaStyle.highlightColor)) color = areaStyle.highlightColor; else color = ChartHelper.GetHighlightColor(color); - ChartHelper.SetColorOpacity(ref color, areaStyle.opacity); - return color; } - if (!ChartHelper.IsClearColor(areaStyle.color)) color = areaStyle.color; - else if (!ChartHelper.IsClearColor(serie.itemStyle.color)) color = serie.itemStyle.color; - else color = theme.GetColor(index); - ChartHelper.SetColorOpacity(ref color, areaStyle.opacity); return color; } - public static Color32 GetAreaToColor(Serie serie, ThemeStyle theme, int index, bool highlight) + public static Color32 GetAreaToColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight) { Color32 color = ChartConst.clearColor32; - var areaStyle = serie.areaStyle; + var areaStyle = GetAreaStyle(serie, serieData); if (areaStyle == null || !areaStyle.show) return color; - if (!ChartHelper.IsClearColor(areaStyle.toColor)) + if (!ChartHelper.IsClearColor(areaStyle.toColor)) color = areaStyle.toColor; + else if (!ChartHelper.IsClearColor(serie.itemStyle.toColor)) color = serie.itemStyle.toColor; + else color = theme.GetColor(index); + ChartHelper.SetColorOpacity(ref color, areaStyle.opacity); + if (highlight) { - color = areaStyle.toColor; - if (highlight) - { - if (!ChartHelper.IsClearColor(areaStyle.highlightToColor)) color = areaStyle.highlightToColor; - else color = ChartHelper.GetHighlightColor(color); - } - ChartHelper.SetColorOpacity(ref color, areaStyle.opacity); - return color; - } - else - { - return GetAreaColor(serie, theme, index, highlight); + if (!ChartHelper.IsClearColor(areaStyle.highlightToColor)) + color = areaStyle.highlightToColor; + else + color = ChartHelper.GetHighlightColor(color); } + return color; } - public static Color32 GetLineColor(Serie serie, ThemeStyle theme, int index, bool highlight) + public static Color32 GetLineColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight) { Color32 color = ChartConst.clearColor32; + var lineStyle = GetLineStyle(serie, serieData); if (highlight) { var itemStyleEmphasis = GetItemStyleEmphasis(serie, null); @@ -522,13 +528,10 @@ namespace XCharts return color; } } - if (!ChartHelper.IsClearColor(serie.lineStyle.color)) color = serie.lineStyle.GetColor(); + if (!ChartHelper.IsClearColor(lineStyle.color)) color = lineStyle.color; else if (!ChartHelper.IsClearColor(serie.itemStyle.color)) color = serie.itemStyle.GetColor(); - if (ChartHelper.IsClearColor(color)) - { - color = theme.GetColor(index); - ChartHelper.SetColorOpacity(ref color, serie.lineStyle.opacity); - } + if (ChartHelper.IsClearColor(color)) color = theme.GetColor(index); + ChartHelper.SetColorOpacity(ref color, lineStyle.opacity); if (highlight) color = ChartHelper.GetHighlightColor(color); return color; } @@ -781,7 +784,11 @@ namespace XCharts { if (field.IsDefined(typeof(SerializeField), false)) { - field.SetValue(newSerie, field.GetValue(oldSerie)); + var filedValue = field.GetValue(oldSerie); + if (filedValue == null) continue; + var filedType = filedValue.GetType(); + if (filedType.IsClass) + field.SetValue(newSerie, ReflectionUtil.DeepCloneSerializeField(filedValue)); } } } diff --git a/Runtime/Helper/SeriesHelper.cs b/Runtime/Helper/SeriesHelper.cs index bd727319..f115b660 100644 --- a/Runtime/Helper/SeriesHelper.cs +++ b/Runtime/Helper/SeriesHelper.cs @@ -99,14 +99,11 @@ namespace XCharts } if (found) break; } - else + if (name.Equals(serie.serieName)) { - if (name.Equals(serie.serieName)) - { - destSerie = serie; - destSerieData = null; - break; - } + destSerie = serie; + destSerieData = null; + break; } } return SerieHelper.GetItemColor(destSerie, destSerieData, chart.theme, index, false); diff --git a/Runtime/Internal/BaseChart.Serie.cs b/Runtime/Internal/BaseChart.Serie.cs index 60725599..0fb1d938 100644 --- a/Runtime/Internal/BaseChart.Serie.cs +++ b/Runtime/Internal/BaseChart.Serie.cs @@ -792,6 +792,7 @@ namespace XCharts var handler = (SerieHandler)Activator.CreateInstance(attribute.handler); handler.attribute = attribute; handler.chart = this; + handler.defaultDimension = 1; handler.SetSerie(serie); serie.handler = handler; m_SerieHandlers.Add(handler); @@ -841,5 +842,17 @@ namespace XCharts { return "serie" + m_Series.Count; } + + public bool IsSerieName(string name) + { + if (string.IsNullOrEmpty(name)) + return false; + foreach (var serie in m_Series) + { + if (name.Equals(serie.serieName)) + return true; + } + return false; + } } } diff --git a/Runtime/Internal/Utilities/ChartHelper.cs b/Runtime/Internal/Utilities/ChartHelper.cs index 172f3f87..8329f5b0 100644 --- a/Runtime/Internal/Utilities/ChartHelper.cs +++ b/Runtime/Internal/Utilities/ChartHelper.cs @@ -359,25 +359,6 @@ namespace XCharts } #endif - internal static GameObject AddTooltipContent(string name, Transform parent, TextStyle textStyle, - ThemeStyle theme) - { - var anchorMax = new Vector2(0, 1); - var anchorMin = new Vector2(0, 1); - var pivot = new Vector2(0, 1); - var sizeDelta = new Vector2(100, 100); - GameObject tooltipObj = AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta); - var img = GetOrAddComponent(tooltipObj); - img.color = Color.black; - var txt = AddTextObject("Text", tooltipObj.transform, anchorMin, anchorMax, pivot, sizeDelta, - textStyle, theme.tooltip); - txt.SetAlignment(textStyle.GetAlignment(TextAnchor.UpperLeft)); - txt.SetText("Text"); - txt.SetLocalPosition(new Vector2(3, -3)); - tooltipObj.transform.localPosition = Vector3.zero; - return tooltipObj; - } - internal static Painter AddPainterObject(string name, Transform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 sizeDelta, HideFlags hideFlags, int siblingIndex) { diff --git a/Runtime/Serie/Heatmap/Heatmap.cs b/Runtime/Serie/Heatmap/Heatmap.cs index d5b3a58d..5be5cc9d 100644 --- a/Runtime/Serie/Heatmap/Heatmap.cs +++ b/Runtime/Serie/Heatmap/Heatmap.cs @@ -17,7 +17,7 @@ namespace XCharts serie.itemStyle.show = true; serie.itemStyle.borderWidth = 1; serie.itemStyle.borderColor = Color.clear; - + var emphasis = serie.AddExtraComponent(); emphasis.show = true; emphasis.itemStyle.show = true; diff --git a/Runtime/Serie/Heatmap/HeatmapHandler.cs b/Runtime/Serie/Heatmap/HeatmapHandler.cs index bcbbcdd6..6a5e2720 100644 --- a/Runtime/Serie/Heatmap/HeatmapHandler.cs +++ b/Runtime/Serie/Heatmap/HeatmapHandler.cs @@ -9,6 +9,10 @@ namespace XCharts [UnityEngine.Scripting.Preserve] internal sealed class HeatmapHandler : SerieHandler { + private GridCoord m_SerieGrid; + + public override int defaultDimension { get { return 2; } } + public override void Update() { base.Update(); @@ -33,14 +37,21 @@ namespace XCharts if (serieData == null) return; + if (string.IsNullOrEmpty(category)) + { + var xAxis = chart.GetChartComponent(serie.xAxisIndex); + if (xAxis != null) + category = xAxis.GetData((int)serieData.GetData(0)); + } + title = serie.serieName; var param = serie.context.param; param.serieName = serie.serieName; param.serieIndex = serie.index; - param.dimension = 2; + param.dimension = defaultDimension; param.serieData = serieData; - param.color = chart.theme.GetColor(serie.index); + param.color = serieData.context.color; param.marker = SerieHelper.GetItemMarker(serie, serieData, marker); param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); @@ -48,40 +59,67 @@ namespace XCharts param.columns.Add(param.marker); param.columns.Add(category); - param.columns.Add(ChartCached.NumberToStr(serieData.GetData(2), param.numericFormatter)); + param.columns.Add(ChartCached.NumberToStr(serieData.GetData(defaultDimension), param.numericFormatter)); paramList.Add(param); } private void UpdateSerieContext() { - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - - if (!chart.isPointerInChart) + if (m_SerieGrid == null) return; - var grid = chart.GetChartComponent(serie.containerIndex); - if (grid == null) - return; - - if (!grid.IsPointerEnter()) - return; - - foreach (var serieData in serie.data) + var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter; + var needInteract = false; + if (!needCheck) { - if (serieData.context.rect.Contains(chart.pointerPos)) + if (m_LastCheckContextFlag != needCheck) + { + m_LastCheckContextFlag = needCheck; + serie.context.pointerItemDataIndex = -1; + serie.context.pointerEnter = false; + foreach (var serieData in serie.data) + { + serieData.context.highlight = false; + } + chart.RefreshPainter(serie); + } + return; + } + m_LastCheckContextFlag = needCheck; + if (m_LegendEnter) + { + serie.context.pointerEnter = true; + foreach (var serieData in serie.data) { - serie.context.pointerItemDataIndex = serieData.index; - serie.context.pointerEnter = true; serieData.context.highlight = true; - chart.RefreshTopPainter(); } - else + } + else + { + serie.context.pointerItemDataIndex = -1; + serie.context.pointerEnter = false; + var count = 0; + foreach (var serieData in serie.data) { - serieData.context.highlight = false; + if (!needInteract && serieData.context.rect.Contains(chart.pointerPos)) + { + serie.context.pointerItemDataIndex = serieData.index; + serie.context.pointerEnter = true; + serieData.context.highlight = true; + needInteract = true; + } + else + { + serieData.context.highlight = false; + } + count++; } } + if (needInteract) + { + chart.RefreshPainter(serie); + } } private void DrawHeatmapSerie(VertexHelper vh, int colorIndex, Heatmap serie) @@ -89,21 +127,20 @@ namespace XCharts if (serie.animation.HasFadeOut()) return; XAxis xAxis; YAxis yAxis; - GridCoord grid; if (!chart.TryGetChartComponent(out xAxis, serie.xAxisIndex)) return; if (!chart.TryGetChartComponent(out yAxis, serie.yAxisIndex)) return; - if (!chart.TryGetChartComponent(out grid, xAxis.gridIndex)) return; + m_SerieGrid = chart.GetChartComponent(xAxis.gridIndex); xAxis.boundaryGap = true; yAxis.boundaryGap = true; var visualMap = chart.GetVisualMapOfSerie(serie); var emphasis = serie.emphasis; var xCount = xAxis.data.Count; var yCount = yAxis.data.Count; - var xWidth = grid.context.width / xCount; - var yWidth = grid.context.height / yCount; + var xWidth = m_SerieGrid.context.width / xCount; + var yWidth = m_SerieGrid.context.height / yCount; - var zeroX = grid.context.x; - var zeroY = grid.context.y; + var zeroX = m_SerieGrid.context.x; + var zeroY = m_SerieGrid.context.y; var dataList = serie.GetDataList(); var rangeMin = visualMap.rangeMin; var rangeMax = visualMap.rangeMax; @@ -111,69 +148,83 @@ namespace XCharts var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0; var rectWid = xWidth - 2 * borderWidth; var rectHig = yWidth - 2 * borderWidth; - var borderColor = serie.itemStyle.opacity > 0 ? serie.itemStyle.borderColor : ChartConst.clearColor32; + + var borderColor = serie.itemStyle.opacity > 0 + ? serie.itemStyle.borderColor + : ChartConst.clearColor32; borderColor.a = (byte)(borderColor.a * serie.itemStyle.opacity); - var borderToColor = serie.itemStyle.opacity > 0 ? serie.itemStyle.borderToColor : ChartConst.clearColor32; + + var borderToColor = serie.itemStyle.opacity > 0 + ? serie.itemStyle.borderToColor + : ChartConst.clearColor32; borderToColor.a = (byte)(borderToColor.a * serie.itemStyle.opacity); + serie.context.dataPoints.Clear(); serie.animation.InitProgress(0, xCount); var animationIndex = serie.animation.GetCurrIndex(); var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); var dataChanging = false; - serie.containerIndex = grid.index; - serie.containterInstanceId = grid.instanceId; - for (int i = 0; i < xCount; i++) + serie.containerIndex = m_SerieGrid.index; + serie.containterInstanceId = m_SerieGrid.instanceId; + for (int n = 0; n < serie.dataCount; n++) { - for (int j = 0; j < yCount; j++) + var serieData = serie.data[n]; + serieData.index = n; + var i = (int)serieData.GetData(0); + var j = (int)serieData.GetData(1); + var dimension = VisualMapHelper.GetDimension(visualMap, serieData.data.Count); + if (serie.IsIgnoreValue(serieData, dimension)) { - var dataIndex = i * yCount + j; - if (dataIndex >= dataList.Count) continue; - var serieData = dataList[dataIndex]; - var dimension = VisualMapHelper.GetDimension(visualMap, serieData.data.Count); - serieData.index = dataIndex; - if (serie.IsIgnoreIndex(dataIndex, dimension)) - { - serie.context.dataPoints.Add(Vector3.zero); - continue; - } - var value = serieData.GetCurrData(dimension, dataChangeDuration, yAxis.inverse, - yAxis.context.minValue, yAxis.context.maxValue); - if (serieData.IsDataChanged()) dataChanging = true; - var pos = new Vector3(zeroX + (i + (xAxis.boundaryGap ? 0.5f : 0)) * xWidth, - zeroY + (j + (yAxis.boundaryGap ? 0.5f : 0)) * yWidth); - serie.context.dataPoints.Add(pos); - serieData.context.canShowLabel = false; - serieData.context.rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); - if (value == 0) continue; - if ((value < rangeMin && rangeMin != visualMap.min) - || (value > rangeMax && rangeMax != visualMap.max)) - { - continue; - } - if (!visualMap.IsInSelectedValue(value)) continue; - color = visualMap.GetColor(value); - if (animationIndex >= 0 && i > animationIndex) continue; - serieData.context.canShowLabel = true; - var highlight = (serieData.context.highlight) - || visualMap.context.pointerIndex > 0; - - UGL.DrawRectangle(vh, pos, rectWid / 2, rectHig / 2, color); - if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) - { - UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderToColor); - } - if (visualMap.hoverLink && highlight && emphasis != null && emphasis.show - && emphasis.itemStyle.borderWidth > 0) - { - var emphasisBorderWidth = emphasis.itemStyle.borderWidth; - var emphasisBorderColor = emphasis.itemStyle.opacity > 0 - ? emphasis.itemStyle.borderColor : ChartConst.clearColor32; - var emphasisBorderToColor = emphasis.itemStyle.opacity > 0 - ? emphasis.itemStyle.borderToColor : ChartConst.clearColor32; - UGL.DrawBorder(vh, pos, rectWid, rectHig, emphasisBorderWidth, emphasisBorderColor, - emphasisBorderToColor); - } + serie.context.dataPoints.Add(Vector3.zero); + continue; } + var value = serieData.GetCurrData(dimension, dataChangeDuration, yAxis.inverse, + yAxis.context.minValue, yAxis.context.maxValue); + if (serieData.IsDataChanged()) dataChanging = true; + var pos = new Vector3(zeroX + (i + (xAxis.boundaryGap ? 0.5f : 0)) * xWidth, + zeroY + (j + (yAxis.boundaryGap ? 0.5f : 0)) * yWidth); + serie.context.dataPoints.Add(pos); + serieData.context.position = pos; + + serieData.context.canShowLabel = false; + serieData.context.rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); + if (value == 0) continue; + if ((value < rangeMin && rangeMin != visualMap.min) + || (value > rangeMax && rangeMax != visualMap.max)) + { + continue; + } + if (!visualMap.IsInSelectedValue(value)) continue; + if (animationIndex >= 0 && i > animationIndex) continue; + color = visualMap.GetColor(value); + if (serieData.context.highlight) + color = ChartHelper.GetHighlightColor(color); + + serieData.context.canShowLabel = true; + serieData.context.color = color; + + var highlight = (serieData.context.highlight) + || visualMap.context.pointerIndex > 0; + + //UGL.DrawRectangle(vh, pos, rectWid / 2, rectHig / 2, color); + UGL.DrawRectangle(vh, serieData.context.rect, color); + + if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) + { + UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderToColor); + } + if (visualMap.hoverLink && highlight && emphasis != null && emphasis.show + && emphasis.itemStyle.borderWidth > 0) + { + var emphasisBorderWidth = emphasis.itemStyle.borderWidth; + var emphasisBorderColor = emphasis.itemStyle.opacity > 0 + ? emphasis.itemStyle.borderColor : ChartConst.clearColor32; + var emphasisBorderToColor = emphasis.itemStyle.opacity > 0 + ? emphasis.itemStyle.borderToColor : ChartConst.clearColor32; + UGL.DrawBorder(vh, pos, rectWid, rectHig, emphasisBorderWidth, emphasisBorderColor, + emphasisBorderToColor); + } + } if (!serie.animation.IsFinish()) { diff --git a/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Runtime/Serie/Line/LineHandler.GridCoord.cs index 47993dee..1156b348 100644 --- a/Runtime/Serie/Line/LineHandler.GridCoord.cs +++ b/Runtime/Serie/Line/LineHandler.GridCoord.cs @@ -253,7 +253,7 @@ namespace XCharts if (serie.context.dataPoints.Count < 2) return; - var lineColor = SerieHelper.GetLineColor(serie, chart.theme, serie.index, false); + var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.index, false); var startPos = Vector3.zero; var arrowPos = Vector3.zero; var lineArrow = serie.lineArrow.arrow; diff --git a/Runtime/Serie/Line/LineHandler.PolarCoord.cs b/Runtime/Serie/Line/LineHandler.PolarCoord.cs index 696fc6ec..f68e707b 100644 --- a/Runtime/Serie/Line/LineHandler.PolarCoord.cs +++ b/Runtime/Serie/Line/LineHandler.PolarCoord.cs @@ -33,7 +33,7 @@ namespace XCharts var firstSerieData = datas[0]; var startPos = GetPolarPos(m_Polar, m_AngleAxis, firstSerieData, min, max, radius); var nextPos = Vector3.zero; - var lineColor = SerieHelper.GetLineColor(serie, chart.theme, serie.index, serie.highlight); + var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.index, serie.highlight); var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); var currDetailProgress = 0f; var totalDetailProgress = datas.Count; diff --git a/Runtime/Serie/Line/LineHelper.cs b/Runtime/Serie/Line/LineHelper.cs index 9b291f16..4d6ecb6b 100644 --- a/Runtime/Serie/Line/LineHelper.cs +++ b/Runtime/Serie/Line/LineHelper.cs @@ -28,8 +28,8 @@ namespace XCharts if (serie.areaStyle == null || !serie.areaStyle.show) return; - var srcAreaColor = SerieHelper.GetAreaColor(serie, theme, serie.context.colorIndex, false); - var srcAreaToColor = SerieHelper.GetAreaToColor(serie, theme, serie.context.colorIndex, false); + var srcAreaColor = SerieHelper.GetAreaColor(serie, null, theme, serie.context.colorIndex, false); + var srcAreaToColor = SerieHelper.GetAreaToColor(serie, null, theme, serie.context.colorIndex, false); var gridXY = (isY ? grid.context.x : grid.context.y); if (lastStackSerie == null) { @@ -247,7 +247,7 @@ namespace XCharts var isLineStyleGradient = serie.lineStyle.IsNeedGradient(); //var highlight = serie.highlight || serie.context.pointerEnter; - var lineColor = SerieHelper.GetLineColor(serie, theme, serie.context.colorIndex, false); + var lineColor = SerieHelper.GetLineColor(serie, null, theme, serie.context.colorIndex, false); var lastDataIsIgnore = datas[0].isIgnoreBreak; for (int i = 1; i < dataCount; i++) diff --git a/Runtime/Serie/Parallel/ParallelHandler.cs b/Runtime/Serie/Parallel/ParallelHandler.cs index 064cb0b5..397ec835 100644 --- a/Runtime/Serie/Parallel/ParallelHandler.cs +++ b/Runtime/Serie/Parallel/ParallelHandler.cs @@ -42,7 +42,7 @@ namespace XCharts var animationIndex = serie.animation.GetCurrIndex(); var isHorizonal = parallel.orient == Orient.Horizonal; - var lineColor = SerieHelper.GetLineColor(serie, chart.theme, colorIndex, false); + var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, colorIndex, false); var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); float currDetailProgress = !isHorizonal diff --git a/Runtime/Serie/Radar/RadarHandler.cs b/Runtime/Serie/Radar/RadarHandler.cs index c1fceccb..118a41db 100644 --- a/Runtime/Serie/Radar/RadarHandler.cs +++ b/Runtime/Serie/Radar/RadarHandler.cs @@ -83,34 +83,10 @@ namespace XCharts } } - public override void OnLegendButtonClick(int index, string legendName, bool show) - { - if (!serie.IsLegendName(legendName)) - return; - LegendHelper.CheckDataShow(serie, legendName, show); - chart.UpdateLegendColor(legendName, show); - chart.RefreshPainter(serie); - } - - public override void OnLegendButtonEnter(int index, string legendName) - { - if (!serie.IsLegendName(legendName)) - return; - LegendHelper.CheckDataHighlighted(serie, legendName, true); - chart.RefreshPainter(serie); - } - - public override void OnLegendButtonExit(int index, string legendName) - { - if (!serie.IsLegendName(legendName)) - return; - LegendHelper.CheckDataHighlighted(serie, legendName, false); - chart.RefreshPainter(serie); - } - private void UpdateSerieContext() { - var needCheck = m_LegendEnter || (chart.isPointerInChart && m_RadarCoord.IsPointerEnter()); + var needCheck = m_LegendEnter + || (chart.isPointerInChart && (m_RadarCoord != null && m_RadarCoord.IsPointerEnter())); var needInteract = false; var needHideAll = false; if (!needCheck) @@ -182,8 +158,6 @@ namespace XCharts serie.containerIndex = m_RadarCoord.index; serie.containterInstanceId = m_RadarCoord.instanceId; - var areaStyle = serie.areaStyle; - var startPoint = Vector3.zero; var toPoint = Vector3.zero; var firstPoint = Vector3.zero; @@ -208,25 +182,39 @@ namespace XCharts { continue; } + var lineStyle = SerieHelper.GetLineStyle(serie, serieData); + var areaStyle = SerieHelper.GetAreaStyle(serie, serieData); + var symbol = SerieHelper.GetSerieSymbol(serie, serieData); var isHighlight = serieData.context.highlight; - var areaColor = SerieHelper.GetAreaColor(serie, chart.theme, j, isHighlight); - var areaToColor = SerieHelper.GetAreaToColor(serie, chart.theme, j, isHighlight); - var lineColor = SerieHelper.GetLineColor(serie, chart.theme, j, isHighlight); - var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); + var colorIndex = chart.GetLegendRealShowNameIndex(serieData.name); + var areaColor = SerieHelper.GetAreaColor(serie, serieData, chart.theme, colorIndex, isHighlight); + var areaToColor = SerieHelper.GetAreaToColor(serie, serieData, chart.theme, colorIndex, isHighlight); + var lineColor = SerieHelper.GetLineColor(serie, serieData, chart.theme, colorIndex, isHighlight); + var lineWidth = lineStyle.GetWidth(chart.theme.serie.lineWidth); int dataCount = m_RadarCoord.indicatorList.Count; serieData.context.dataPoints.Clear(); for (int n = 0; n < dataCount; n++) { if (n >= serieData.data.Count) break; + var min = m_RadarCoord.GetIndicatorMin(n); var max = m_RadarCoord.GetIndicatorMax(n); var value = serieData.GetCurrData(n, dataChangeDuration); if (serieData.IsDataChanged()) dataChanging = true; if (max == 0) { - max = serie.context.dataMax; + if (serie.data.Count > 1) + { + SerieHelper.GetMinMaxData(serie, n, out min, out max); + min = ChartHelper.GetMinDivisibleValue(min, 0); + max = ChartHelper.GetMaxDivisibleValue(max, 0); + if (min > 0) min = 0; + } + else + { + max = serie.context.dataMax; + } } - var radius = (float)(max < 0 ? m_RadarCoord.context.dataRadius - m_RadarCoord.context.dataRadius * value / max - : m_RadarCoord.context.dataRadius * value / max); + var radius = (float)(m_RadarCoord.context.dataRadius * (value - min) / (max - min)); var currAngle = (n + (m_RadarCoord.positionType == RadarCoord.PositionType.Between ? 0.5f : 0)) * angle; radius *= rate; if (n == 0) @@ -243,9 +231,9 @@ namespace XCharts { UGL.DrawTriangle(vh, startPoint, toPoint, centerPos, areaColor, areaColor, areaToColor); } - if (serie.lineStyle.show) + if (lineStyle.show) { - ChartDrawer.DrawLineStyle(vh, serie.lineStyle.type, lineWidth, startPoint, toPoint, lineColor); + ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, toPoint, lineColor); } startPoint = toPoint; } @@ -255,23 +243,23 @@ namespace XCharts { UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor); } - if (serie.lineStyle.show) + if (lineStyle.show) { - ChartDrawer.DrawLineStyle(vh, serie.lineStyle.type, lineWidth, startPoint, firstPoint, lineColor); + ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, firstPoint, lineColor); } - if (serie.symbol.show && serie.symbol.type != SymbolType.None) + if (symbol.show && symbol.type != SymbolType.None) { for (int m = 0; m < serieData.context.dataPoints.Count; m++) { var point = serieData.context.dataPoints[m]; var symbolSize = isHighlight - ? serie.symbol.GetSelectedSize(null, chart.theme.serie.lineSymbolSelectedSize) - : serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize); + ? symbol.GetSelectedSize(null, chart.theme.serie.lineSymbolSelectedSize) + : symbol.GetSize(null, chart.theme.serie.lineSymbolSize); if (!serieData.interact.TryGetValue(ref symbolSize, ref interacting)) { symbolSize = isHighlight - ? serie.symbol.GetSelectedSize(serieData.data, symbolSize) - : serie.symbol.GetSize(serieData.data, symbolSize); + ? symbol.GetSelectedSize(serieData.data, symbolSize) + : symbol.GetSize(serieData.data, symbolSize); serieData.interact.SetValue(ref interacting, symbolSize); symbolSize = serie.animation.GetSysmbolSize(symbolSize); } @@ -281,8 +269,8 @@ namespace XCharts var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight); var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, chart.theme, isHighlight); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); - chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, point, symbolColor, - symbolToColor, symbolEmptyColor, borderColor, serie.symbol.gap, cornerRadius); + chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, point, symbolColor, + symbolToColor, symbolEmptyColor, borderColor, symbol.gap, cornerRadius); } } } @@ -335,13 +323,16 @@ namespace XCharts serieData.context.labelPosition = Vector3.zero; continue; } + var lineStyle = SerieHelper.GetLineStyle(serie, serieData); + var areaStyle = SerieHelper.GetAreaStyle(serie, serieData); var isHighlight = serie.context.pointerEnter; - var areaColor = SerieHelper.GetAreaColor(serie, chart.theme, j, isHighlight); - var areaToColor = SerieHelper.GetAreaToColor(serie, chart.theme, j, isHighlight); - var lineColor = SerieHelper.GetLineColor(serie, chart.theme, j, isHighlight); + var areaColor = SerieHelper.GetAreaColor(serie, serieData, chart.theme, j, isHighlight); + var areaToColor = SerieHelper.GetAreaToColor(serie, serieData, chart.theme, j, isHighlight); + var lineColor = SerieHelper.GetLineColor(serie, serieData, chart.theme, j, isHighlight); int dataCount = radar.indicatorList.Count; var index = serieData.index; var p = radar.context.center; + var min = radar.GetIndicatorMin(index); var max = radar.GetIndicatorMax(index); var value = serieData.GetCurrData(1, dataChangeDuration); if (serieData.IsDataChanged()) dataChanging = true; @@ -369,16 +360,16 @@ namespace XCharts { toPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle), p.y + radius * Mathf.Cos(currAngle)); - if (serie.areaStyle.show) + if (areaStyle != null && areaStyle.show) { UGL.DrawTriangle(vh, startPoint, toPoint, p, areaColor, areaColor, areaToColor); } - if (serie.lineStyle.show) + if (lineStyle.show) { if (radar.connectCenter) - ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, centerPos, + ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos, chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor); - ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, toPoint, chart.theme.serie.lineWidth, + ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, toPoint, chart.theme.serie.lineWidth, LineStyle.Type.Solid, radar.lineGradient ? lastColor : lineColor, lineColor); } startPoint = toPoint; @@ -387,16 +378,16 @@ namespace XCharts serieData.context.position = startPoint; serieData.context.labelPosition = startPoint; - if (serie.areaStyle.show && j == endIndex) + if (areaStyle != null && areaStyle.show && j == endIndex) { UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor); } - if (serie.lineStyle.show && j == endIndex) + if (lineStyle.show && j == endIndex) { if (radar.connectCenter) - ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, centerPos, + ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos, chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor); - ChartDrawer.DrawLineStyle(vh, serie.lineStyle, startPoint, firstPoint, chart.theme.serie.lineWidth, + ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, firstPoint, chart.theme.serie.lineWidth, LineStyle.Type.Solid, lineColor, radar.lineGradient ? firstColor : lineColor); } } diff --git a/Runtime/Serie/Serie.cs b/Runtime/Serie/Serie.cs index 1dc86160..ad309008 100644 --- a/Runtime/Serie/Serie.cs +++ b/Runtime/Serie/Serie.cs @@ -1617,7 +1617,7 @@ namespace XCharts { if (useDataNameForColor) { - return IsSerieDataLegendName(legendName); + return IsSerieDataLegendName(legendName) || IsSerieLegendName(legendName); } else { diff --git a/Runtime/Serie/SerieData.cs b/Runtime/Serie/SerieData.cs index 70b9b7e3..be3c55ed 100644 --- a/Runtime/Serie/SerieData.cs +++ b/Runtime/Serie/SerieData.cs @@ -23,6 +23,8 @@ namespace XCharts [SerializeField] private List m_Emphases = new List(); [SerializeField] private List m_Symbols = new List(); [SerializeField] private List m_IconStyles = new List(); + [SerializeField] private List m_LineStyles = new List(); + [SerializeField] private List m_AreaStyles = new List(); [SerializeField] private List m_Data = new List(); [SerializeField] private List m_Children = new List(); @@ -77,6 +79,8 @@ namespace XCharts /// 单个数据项的标记设置。 /// public SymbolStyle symbol { get { return m_Symbols.Count > 0 ? m_Symbols[0] : null; } } + public LineStyle lineStyle { get { return m_LineStyles.Count > 0 ? m_LineStyles[0] : null; } } + public AreaStyle areaStyle { get { return m_AreaStyles.Count > 0 ? m_AreaStyles[0] : null; } } /// /// 是否忽略数据。当为 true 时,数据不进行绘制。 /// @@ -124,6 +128,8 @@ namespace XCharts m_ItemStyles.Clear(); m_Emphases.Clear(); m_Symbols.Clear(); + m_LineStyles.Clear(); + m_AreaStyles.Clear(); } public T GetOrAddComponent() where T : ChildComponent @@ -165,6 +171,18 @@ namespace XCharts m_Symbols.Add(new SymbolStyle() { show = true }); return m_Symbols[0] as T; } + else if (type == typeof(LineStyle)) + { + if (m_LineStyles.Count == 0) + m_LineStyles.Add(new LineStyle() { show = true }); + return m_LineStyles[0] as T; + } + else if (type == typeof(AreaStyle)) + { + if (m_AreaStyles.Count == 0) + m_AreaStyles.Add(new AreaStyle() { show = true }); + return m_AreaStyles[0] as T; + } else { throw new System.Exception("SerieData not support component:" + type); @@ -179,6 +197,8 @@ namespace XCharts m_LabelLines.Clear(); m_Symbols.Clear(); m_Emphases.Clear(); + m_LineStyles.Clear(); + m_AreaStyles.Clear(); } public void RemoveComponent() where T : ISerieDataComponent @@ -196,6 +216,10 @@ namespace XCharts m_Emphases.Clear(); else if (type == typeof(SymbolStyle)) m_Symbols.Clear(); + else if (type == typeof(LineStyle)) + m_LineStyles.Clear(); + else if (type == typeof(AreaStyle)) + m_AreaStyles.Clear(); else throw new System.Exception("SerieData not support component:" + type); } diff --git a/Runtime/Serie/SerieHandler.cs b/Runtime/Serie/SerieHandler.cs index 1f93869f..957cb3ce 100644 --- a/Runtime/Serie/SerieHandler.cs +++ b/Runtime/Serie/SerieHandler.cs @@ -11,6 +11,7 @@ namespace XCharts { public BaseChart chart { get; internal set; } public SerieHandlerAttribute attribute { get; internal set; } + public virtual int defaultDimension { get; internal set; } public virtual void InitComponent() { } public virtual void RemoveComponent() { } @@ -62,6 +63,8 @@ namespace XCharts m_NeedInitComponent = true; } + + public override void Update() { if (m_NeedInitComponent) @@ -124,7 +127,13 @@ namespace XCharts public override void OnLegendButtonClick(int index, string legendName, bool show) { - if (serie.IsLegendName(legendName)) + if (serie.useDataNameForColor && serie.IsSerieDataLegendName(legendName)) + { + LegendHelper.CheckDataShow(serie, legendName, show); + chart.UpdateLegendColor(legendName, show); + chart.RefreshPainter(serie); + } + else if (serie.IsLegendName(legendName)) { chart.SetSerieActive(serie, show); chart.RefreshPainter(serie); @@ -133,7 +142,12 @@ namespace XCharts public override void OnLegendButtonEnter(int index, string legendName) { - if (serie.IsLegendName(legendName)) + if (serie.useDataNameForColor && serie.IsSerieDataLegendName(legendName)) + { + LegendHelper.CheckDataHighlighted(serie, legendName, true); + chart.RefreshPainter(serie); + } + else if (serie.IsLegendName(legendName)) { m_LegendEnter = true; chart.RefreshPainter(serie); @@ -142,7 +156,12 @@ namespace XCharts public override void OnLegendButtonExit(int index, string legendName) { - if (serie.IsLegendName(legendName)) + if (serie.useDataNameForColor && serie.IsSerieDataLegendName(legendName)) + { + LegendHelper.CheckDataHighlighted(serie, legendName, false); + chart.RefreshPainter(serie); + } + else if (serie.IsLegendName(legendName)) { m_LegendEnter = false; chart.RefreshPainter(serie); @@ -272,7 +291,7 @@ namespace XCharts var emphasisLabel = SerieHelper.GetSerieEmphasisLabel(serie, serieData); var isHighlight = (serieData.context.highlight && emphasisLabel != null && emphasisLabel.show); var iconStyle = SerieHelper.GetIconStyle(serie, serieData); - var isIgnore = serie.IsIgnoreIndex(serieData.index); + var isIgnore = serie.IsIgnoreIndex(serieData.index, defaultDimension); var currLabel = isHighlight && emphasisLabel != null ? emphasisLabel : serieLabel; serieData.labelObject.SetPosition(serieData.context.position); @@ -286,7 +305,7 @@ namespace XCharts { var content = serie.useDataNameForColor && string.IsNullOrEmpty(currLabel.formatter) ? serieData.name - : SerieLabelHelper.GetFormatterContent(serie, serieData, serieData.GetData(1), total, + : SerieLabelHelper.GetFormatterContent(serie, serieData, serieData.GetData(defaultDimension), total, currLabel, chart.theme.GetColor(colorIndex)); var invert = currLabel.autoOffset diff --git a/Runtime/Utilities/ReflectionUtil.cs b/Runtime/Utilities/ReflectionUtil.cs index f71319ab..ca2c2ee4 100644 --- a/Runtime/Utilities/ReflectionUtil.cs +++ b/Runtime/Utilities/ReflectionUtil.cs @@ -1,6 +1,9 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.Reflection; +using UnityEngine; namespace XCharts { @@ -44,5 +47,76 @@ namespace XCharts callback((T)item); } } + + public static object DeepCloneSerializeField(object obj) + { + if (obj == null) + return null; + + var type = obj.GetType(); + if (type.IsValueType || type == typeof(string)) + { + return obj; + } + else if (type.IsArray) + { + var elementType = Type.GetType(type.FullName.Replace("[]", string.Empty)); + var array = obj as Array; + var copied = Array.CreateInstance(elementType, array.Length); + for (int i = 0; i < array.Length; i++) + copied.SetValue(DeepCloneSerializeField(array.GetValue(i)), i); + return Convert.ChangeType(copied, obj.GetType()); + } + else if (type.IsClass) + { + object returnObj; + var listObj = obj as IList; + if (listObj != null) + { + var properties = type.GetProperties(); + var customList = typeof(List<>).MakeGenericType((properties[properties.Length - 1]).PropertyType); + returnObj = (IList)Activator.CreateInstance(customList); + var list = (IList)returnObj; + foreach (var item in ((IList)obj)) + { + if (item == null) + continue; + list.Add(DeepCloneSerializeField(item)); + } + } + else + { + try + { + returnObj = Activator.CreateInstance(type); + } + catch + { + return null; + } + var fileds = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + for (int i = 0; i < fileds.Length; i++) + { + var field = fileds[i]; + if (!field.IsDefined(typeof(SerializeField), false)) + continue; + var filedValue = field.GetValue(obj); + if (filedValue == null) + { + field.SetValue(returnObj, filedValue); + } + else + { + field.SetValue(returnObj, DeepCloneSerializeField(filedValue)); + } + } + } + return returnObj; + } + else + { + throw new ArgumentException("DeepCloneSerializeField: Unknown type:" + type + "," + obj); + } + } } } \ No newline at end of file