diff --git a/CHANGELOG.md b/CHANGELOG.md index 30ddd524..198bbb91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 更新日志 +* (2020.05.31) 优化`Background`组件的生效条件,需要有单独的父节点(升级前需要自己处理旧的背景节点) * (2020.05.30) 优化`PieChart`支持设置`ignoreValue`不显示指定数据 * (2020.05.30) 修复`RadarChart`为`Circle`时不绘制`SplitArea`的问题 * (2020.05.30) 优化`RadarChart`在设置`max`为`0`时可自动刷新最大值 diff --git a/Documentation/XCharts配置项手册.md b/Documentation/XCharts配置项手册.md index 02bea3b4..2ec55283 100644 --- a/Documentation/XCharts配置项手册.md +++ b/Documentation/XCharts配置项手册.md @@ -346,13 +346,14 @@ ## `Background` 背景组件。 -由于框架的局限性,背景组件在`chart`受上层布局控制时不适用。因为背景组件节点和`chart`节点是同一级的。 -自动布局下的一种解决方案是,可以将`chart`节点再包一层`parent`。 -背景组件的开启需要通过接口来开启:`BaseChart.EnableBackground(bool flag)` +由于框架的局限性,背景组件使用有以下两个限制: +1:`chart`的父节点不能有布局控制类组件。 +2:`chart`的父节点只能有当前`chart`一个子节点。 +背景组件的开启需要通过接口来开启:`BaseChart.EnableBackground(bool flag)`。 相关参数: -* `show`:是否显示启用背景组件。注意背景组件在`chart`受上层布局控制时不适用。 +* `show`:是否显示启用背景组件。但能否激活背景组件还要受其他条件限制。 * `image`:背景图。 * `imageType`:背景图填充类型。 * `imageColor`背景图颜色。默认`white`。 diff --git a/Documentation/XCharts问答.md b/Documentation/XCharts问答.md index 26e33f21..339c4b15 100644 --- a/Documentation/XCharts问答.md +++ b/Documentation/XCharts问答.md @@ -28,6 +28,7 @@ [QA 22:如何做成预设?](#如何做成预设) [QA 23:如何在图表上画点画线等自定义内容?](#如何在图表上画点画线等自定义内容) [QA 24:如何实现心电图类似的数据移动效果?](#如何实现心电图类似的数据移动效果) +[QA 25:如何使用背景组件?有什么条件限制?](#如何使用背景组件?有什么条件限制) ## 如何调整坐标轴与背景的边距 @@ -125,6 +126,11 @@ 答:参考Example目录下的`Example_Dynamic.cs`。主要通过设置`maxCache`参数实现。axis和serie都设置相同的maxCache。maxCache可固定数据个数,当数据超过设定时会先删除第一个在添加新数据,实现数据移动效果。 +## 如何使用背景组件?有什么条件限制 + +答:设置background组件的show为true,但不一定就能激活背景组件。由于框架的局限性,背景组件有两个前提条件:一是图表的父节点不能用布局控制,因为背景组件和图表的节点关系是并行的,用了布局控制背景组件的位置就无法控制。二是图表的父节点只能有图表自己一个子节点,这是方便管理背景组件节点的需要,要不然并行关系的原因,容易错乱对不上。另外,调整图表的层级关系时最好先隐藏背景组件,这是会自动删除关联的背景组件节点。 + + [返回首页](https://github.com/monitor1394/unity-ugui-XCharts) [XChartsAPI接口](XChartsAPI.md) [XCharts配置项手册](XCharts配置项手册.md) diff --git a/Editor/BaseChartEditor.cs b/Editor/BaseChartEditor.cs index c6c4bd31..a184b107 100644 --- a/Editor/BaseChartEditor.cs +++ b/Editor/BaseChartEditor.cs @@ -7,6 +7,7 @@ using UnityEditor; using UnityEngine; +using System.Text; namespace XCharts { @@ -38,6 +39,7 @@ namespace XCharts private int m_SeriesSize; private Vector2 scrollPos; private bool m_CheckWarning = false; + private StringBuilder sb = new StringBuilder(); protected virtual void OnEnable() { @@ -90,7 +92,9 @@ namespace XCharts var m_Show = m_Background.FindPropertyRelative("m_Show"); if (m_Show.boolValue && !m_Target.CanShowBackgroundComponent()) { - EditorGUILayout.HelpBox("can't show background component:chart is control by LayoutGroup.", MessageType.Warning); + var msg = "The background component cannot be activated because chart is controlled by LayoutGroup," + + " or its parent have more than one child."; + EditorGUILayout.HelpBox(msg, MessageType.Error); } EditorGUILayout.PropertyField(m_Title, true); EditorGUILayout.PropertyField(m_Legend, true); @@ -112,7 +116,7 @@ namespace XCharts private void CheckWarning() { - if (GUILayout.Button("Check Update ")) + if (GUILayout.Button("Check XCharts Update ")) { CheckVersionEditor.ShowWindow(); } @@ -129,19 +133,19 @@ namespace XCharts m_CheckWarning = false; } EditorGUILayout.EndHorizontal(); - EditorGUILayout.LabelField("version:" + XChartsMgr.Instance.nowVersion); + sb.Length = 0; + sb.AppendFormat("version:{0}", XChartsMgr.Instance.nowVersion); if (!string.IsNullOrEmpty(m_Target.warningInfo)) { - var infos = m_Target.warningInfo.Split('\n'); - foreach (var info in infos) - { - EditorGUILayout.LabelField(info); - } + sb.AppendLine(); + sb.Append(XChartsMgr.Instance.nowVersion); } else { - EditorGUILayout.LabelField("Perfect! No warning!"); + sb.AppendLine(); + sb.Append("Perfect! No warning!"); } + EditorGUILayout.HelpBox(sb.ToString(), MessageType.Warning); } else { diff --git a/Editor/PropertyDrawers/SerieDrawer.cs b/Editor/PropertyDrawers/SerieDrawer.cs index 26b7875f..1293b02e 100644 --- a/Editor/PropertyDrawers/SerieDrawer.cs +++ b/Editor/PropertyDrawers/SerieDrawer.cs @@ -413,7 +413,10 @@ namespace XCharts if (fieldCount <= 1) { while (2 > data.arraySize) + { data.InsertArrayElementAtIndex(data.arraySize); + data.GetArrayElementAtIndex(data.arraySize - 1).floatValue = 0; + } SerializedProperty element = data.GetArrayElementAtIndex(1); if (showSelected) { @@ -449,6 +452,7 @@ namespace XCharts while (i > data.arraySize - 1) { data.InsertArrayElementAtIndex(data.arraySize); + data.GetArrayElementAtIndex(data.arraySize - 1).floatValue = 0; } drawRect.x = startX + i * xWid; drawRect.width = dataWid + 40; diff --git a/Runtime/API/BaseChart_API.cs b/Runtime/API/BaseChart_API.cs index 71303053..4f4e0325 100644 --- a/Runtime/API/BaseChart_API.cs +++ b/Runtime/API/BaseChart_API.cs @@ -101,6 +101,7 @@ namespace XCharts /// 警告信息。 /// public string warningInfo { get; protected set; } + public bool isControlledByLayout { get { return m_IsControlledByLayout; } } /// /// 强制开启鼠标事件检测。 /// @@ -733,7 +734,7 @@ namespace XCharts /// public bool CanShowBackgroundComponent() { - return !m_IsControlledByLayout; + return !m_IsControlledByLayout && m_Background.runtimeActive; } /// @@ -744,7 +745,9 @@ namespace XCharts { if (flag && !CanShowBackgroundComponent()) { - Debug.LogError("can't show background component:chart is controlled by LayoutGroup."); + var msg = "The background component cannot be activated because chart is controlled by LayoutGroup," + + " or its parent have more than one child."; + Debug.LogError(msg); return; } m_Background.show = flag; diff --git a/Runtime/Component/Main/Background.cs b/Runtime/Component/Main/Background.cs index c324f837..3d849cb8 100644 --- a/Runtime/Component/Main/Background.cs +++ b/Runtime/Component/Main/Background.cs @@ -14,9 +14,9 @@ namespace XCharts { /// /// 背景组件。 - /// 由于框架的局限性,背景组件在chart受上层布局控制时不适用。因为背景组件节点和chart节点是同一级的。 - /// 自动布局下的一种解决方案是,可以将chart节点再包一层parent。 - /// 要处理这个问题底层框架要大改了,目前暂时不打算改。 + /// 由于框架的局限性,背景组件使用有以下两个限制: + /// 1:chart的父节点不能有布局控制类组件。 + /// 2:chart的父节点只能有当前chart一个子节点。 /// 背景组件的开启需要通过接口来开启:BaseChart.EnableBackground(bool flag) /// [Serializable] @@ -33,7 +33,7 @@ namespace XCharts [SerializeField] private bool m_HideThemeBackgroundColor = true; /// - /// 是否启用背景组件。注意背景组件在chart受上层布局控制时不适用。 + /// 是否启用背景组件。但能否激活背景组件还要受其他条件限制。 /// public bool show { @@ -112,6 +112,11 @@ namespace XCharts set { if (PropertyUtility.SetStruct(ref m_HideThemeBackgroundColor, value)) SetVerticesDirty(); } } + /// + /// 是否已激活 + /// + public bool runtimeActive{get;internal set;} + public static Background defaultBackground { get diff --git a/Runtime/Helper/CheckHelper.cs b/Runtime/Helper/CheckHelper.cs index f1100f2d..2dc8dd5c 100644 --- a/Runtime/Helper/CheckHelper.cs +++ b/Runtime/Helper/CheckHelper.cs @@ -109,6 +109,14 @@ namespace XCharts sb.AppendFormat("warning:serie {0} itemStyle->opacity is 0\n", serie.index); if (serie.itemStyle.borderWidth != 0 && IsColorAlphaZero(serie.itemStyle.borderColor)) sb.AppendFormat("warning:serie {0} itemStyle->borderColor alpha is 0\n", serie.index); + if (serie.dataCount > 0) + { + var dataCount = serie.GetSerieData(0).data.Count; + if (serie.showDataDimension != dataCount) + { + sb.AppendFormat("warning:serie {0} serieData.data.count[{1}] not match showDataDimension[{2}]\n", serie.index, dataCount, serie.showDataDimension); + } + } switch (serie.type) { case SerieType.Line: @@ -132,7 +140,6 @@ namespace XCharts if (serie.symbol.type == SerieSymbolType.None) sb.AppendFormat("warning:symbol type is None"); break; - } } } diff --git a/Runtime/Internal/BaseChart.cs b/Runtime/Internal/BaseChart.cs index ed79e2a2..eb2ecaf6 100644 --- a/Runtime/Internal/BaseChart.cs +++ b/Runtime/Internal/BaseChart.cs @@ -258,15 +258,35 @@ namespace XCharts private void InitBackground() { - if (!m_Background.show || m_IsControlledByLayout) + int childCount = transform.parent.childCount; + if (childCount > 2) m_Background.runtimeActive = false; + else if (childCount == 1) m_Background.runtimeActive = true; + else { - if (m_BackgroundRoot) + m_Background.runtimeActive = false; + for (int i = 0; i < childCount; i++) { - m_BackgroundRoot.SetActive(false); + if (transform.parent.GetChild(i).name.StartsWith(s_BackgroundObjectName)) + { + m_Background.runtimeActive = true; + break; + } } + } + if (!m_Background.runtimeActive || m_IsControlledByLayout) + { + //find old gameobject and delete + var objName = s_BackgroundObjectName + GetInstanceID(); + ChartHelper.DestoryGameObject(transform.parent, objName); + ChartHelper.DestoryGameObject(m_BackgroundRoot); return; } - var backgroundName = s_BackgroundObjectName + GetInstanceID(); + if (!m_Background.show) + { + ChartHelper.DestoryGameObject(m_BackgroundRoot); + return; + } + var backgroundName = s_BackgroundObjectName; m_BackgroundRoot = ChartHelper.AddObject(backgroundName, transform.parent, m_ChartMinAnchor, m_ChartMaxAnchor, m_ChartPivot, m_ChartSizeDelta); m_BackgroundRoot.hideFlags = chartHideFlags; @@ -777,14 +797,14 @@ namespace XCharts Vector3 p2 = new Vector3(chartX + chartWidth, chartY + chartHeight); Vector3 p3 = new Vector3(chartX + chartWidth, chartY); Vector3 p4 = new Vector3(chartX, chartY); - var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background, m_IsControlledByLayout); + var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background); ChartDrawer.DrawPolygon(vh, p1, p2, p3, p4, backgroundColor); } public void DrawSymbol(VertexHelper vh, SerieSymbolType type, float symbolSize, float tickness, Vector3 pos, Color color, Color toColor, float gap, float[] cornerRadius) { - var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background, m_IsControlledByLayout); + var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background); var smoothness = m_Settings.cicleSmoothness; ChartDrawer.DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap, cornerRadius, backgroundColor, smoothness); diff --git a/Runtime/Internal/CoordinateChart.cs b/Runtime/Internal/CoordinateChart.cs index 506caf0a..41fed855 100644 --- a/Runtime/Internal/CoordinateChart.cs +++ b/Runtime/Internal/CoordinateChart.cs @@ -156,9 +156,8 @@ namespace XCharts var cp2 = new Vector3(m_CoordinateX - yLineDiff, cpty); var cp3 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, cpty); var cp4 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, m_CoordinateY - xLineDiff); - var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background, m_IsControlledByLayout); + var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background); ChartDrawer.DrawPolygon(vh, cp1, cp2, cp3, cp4, backgroundColor); - } else { @@ -173,7 +172,7 @@ namespace XCharts var yLineDiff = yAxis0.axisLine.width; var xSplitDiff = xAxis0.splitLine.lineStyle.width; var ySplitDiff = yAxis0.splitLine.lineStyle.width; - var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background, m_IsControlledByLayout); + var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background); var lp1 = new Vector3(m_ChartX, m_ChartY); var lp2 = new Vector3(m_ChartX, m_ChartY + chartHeight); var lp3 = new Vector3(m_CoordinateX - yLineDiff, m_ChartY + chartHeight); diff --git a/Runtime/Internal/Helper/ThemeHelper.cs b/Runtime/Internal/Helper/ThemeHelper.cs index b44519e3..471a186a 100644 --- a/Runtime/Internal/Helper/ThemeHelper.cs +++ b/Runtime/Internal/Helper/ThemeHelper.cs @@ -11,9 +11,9 @@ namespace XCharts { internal static class ThemeHelper { - public static Color GetBackgroundColor(ThemeInfo themeInfo, Background background, bool m_IsControlledByLayout) + public static Color GetBackgroundColor(ThemeInfo themeInfo, Background background) { - if (!m_IsControlledByLayout && background.show && background.hideThemeBackgroundColor) return Color.clear; + if (background.show && background.runtimeActive && background.hideThemeBackgroundColor) return Color.clear; else return themeInfo.backgroundColor; } } diff --git a/Runtime/Utility/ChartHelper.cs b/Runtime/Utility/ChartHelper.cs index 24002497..2775e7ab 100644 --- a/Runtime/Utility/ChartHelper.cs +++ b/Runtime/Utility/ChartHelper.cs @@ -112,6 +112,21 @@ namespace XCharts } } + public static void DestoryGameObject(Transform parent, string childName) + { + if (parent == null) return; + var go = parent.Find(childName); + if (go != null) + { + GameObject.DestroyImmediate(go.gameObject); + } + } + + public static void DestoryGameObject(GameObject go) + { + if (go != null) GameObject.DestroyImmediate(go); + } + public static string GetFullName(Transform transform) { string name = transform.name;