From 51159db106d7d7bf2a811841cab47a7beafa48fa Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Tue, 9 Jun 2020 09:24:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96Legend=E7=9A=84=E5=B8=83?= =?UTF-8?q?=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Runtime/API/BaseChart_API.cs | 5 - Runtime/Component/Main/Legend.cs | 49 ++-- Runtime/Internal/BaseChart.cs | 12 +- Runtime/Internal/Helper/LegendHelper.cs | 334 ++++++++++-------------- 4 files changed, 154 insertions(+), 246 deletions(-) diff --git a/Runtime/API/BaseChart_API.cs b/Runtime/API/BaseChart_API.cs index adf5d7cc..89be504f 100644 --- a/Runtime/API/BaseChart_API.cs +++ b/Runtime/API/BaseChart_API.cs @@ -679,11 +679,6 @@ namespace XCharts return chartPosition + m_Title.location.GetPosition(chartWidth, chartHeight); } - public Vector3 GetLegendPosition() - { - return chartPosition + m_Legend.location.GetPosition(chartWidth, chartHeight); - } - [Obsolete("Use BaseChart.RefreshLabel() instead.", true)] public void ReinitChartLabel() { } diff --git a/Runtime/Component/Main/Legend.cs b/Runtime/Component/Main/Legend.cs index 7f27dc3b..9d5ab334 100644 --- a/Runtime/Component/Main/Legend.cs +++ b/Runtime/Component/Main/Legend.cs @@ -188,38 +188,22 @@ namespace XCharts /// /// public Dictionary buttonList { get { return m_DataBtnList; } } - - public float runtimeWidth - { - get - { - var width = 0f; - foreach (var kv in buttonList) - { - if (orient == Orient.Horizonal) - width += kv.Value.width + m_ItemGap; - else if (kv.Value.width > width) - width = kv.Value.width; - } - return orient == Orient.Horizonal ? width - m_ItemGap : width; - } - } - - public float runtimeHeight - { - get - { - var height = 0f; - foreach (var kv in buttonList) - { - if (orient == Orient.Vertical) - height += kv.Value.height + m_ItemGap; - else if (kv.Value.height > height) - height = kv.Value.height; - } - return orient == Orient.Vertical ? height - m_ItemGap : height; - } - } + /// + /// 运行时图例的总宽度 + /// + public float runtimeWidth { get; internal set; } + /// + /// 运行时图例的总高度 + /// + public float runtimeHeight { get; internal set; } + /// + /// 多列时每列的宽度 + /// + public Dictionary runtimeEachWidth { get; internal set; } + /// + /// 单列高度 + /// + public float runtimeEachHeight { get; internal set; } /// /// 一个在顶部居中显示的默认图例。 @@ -237,6 +221,7 @@ namespace XCharts m_ItemWidth = 24.0f, m_ItemHeight = 12.0f, m_ItemGap = 10f, + runtimeEachWidth = new Dictionary() }; legend.location.top = 30; legend.textStyle.offset = new Vector2(2, 0); diff --git a/Runtime/Internal/BaseChart.cs b/Runtime/Internal/BaseChart.cs index e871ac33..193591f1 100644 --- a/Runtime/Internal/BaseChart.cs +++ b/Runtime/Internal/BaseChart.cs @@ -332,14 +332,8 @@ namespace XCharts private void InitLegend() { m_Legend.OnChanged(); - TextAnchor anchor = m_Legend.location.runtimeTextAnchor; - Vector2 anchorMin = m_Legend.location.runtimeAnchorMin; - Vector2 anchorMax = m_Legend.location.runtimeAnchorMax; - Vector2 pivot = m_Legend.location.runtimePivot; - - var legendObject = ChartHelper.AddObject(s_LegendObjectName, transform, anchorMin, anchorMax, - pivot, new Vector2(chartWidth, chartHeight)); - legendObject.transform.localPosition = GetLegendPosition(); + var legendObject = ChartHelper.AddObject(s_LegendObjectName, transform, m_ChartMinAnchor, + m_ChartMaxAnchor, m_ChartPivot, new Vector2(chartWidth, chartHeight)); legendObject.hideFlags = chartHideFlags; SeriesHelper.UpdateSerieNameList(m_Series, ref m_LegendRealShowName); List datas; @@ -428,7 +422,7 @@ namespace XCharts OnLegendButtonClick(n, m_LegendRealShowName[n], n == 0 ? true : false); } } - LegendHelper.ResetItemPosition(m_Legend, m_ChartWidth, m_ChartHeight); + LegendHelper.ResetItemPosition(m_Legend, m_ChartPosition, m_ChartWidth, m_ChartHeight); } private void InitSerieLabel() diff --git a/Runtime/Internal/Helper/LegendHelper.cs b/Runtime/Internal/Helper/LegendHelper.cs index f93eedf1..1d76617c 100644 --- a/Runtime/Internal/Helper/LegendHelper.cs +++ b/Runtime/Internal/Helper/LegendHelper.cs @@ -43,9 +43,9 @@ namespace XCharts var font = textStyle.font ? textStyle.font : themeInfo.font; var contentColor = GetContentColor(legend, themeInfo, active); - var objAnchorMin = legend.location.runtimeAnchorMin; - var objAnchorMax = legend.location.runtimeAnchorMax; - var objPivot = legend.location.runtimePivot; + var objAnchorMin = new Vector2(0, 1); + var objAnchorMax = new Vector2(0, 1); + var objPivot = new Vector2(0, 1); var btnObj = ChartHelper.AddObject(objName, parent, objAnchorMin, objAnchorMax, objPivot, sizeDelta, i); var iconObj = ChartHelper.AddObject("icon", btnObj.transform, anchorMin, anchorMax, pivot, iconSizeDelta); var contentObj = ChartHelper.AddObject("content", btnObj.transform, anchorMin, anchorMax, pivot, sizeDelta); @@ -71,212 +71,146 @@ namespace XCharts return item; } - public static void ResetItemPosition(Legend legend, float chartWidth, float chartHeight) + public static void ResetItemPosition(Legend legend, Vector3 chartPos, float chartWidth, float chartHeight) { var startX = 0f; var startY = 0f; - var offsetX = 0f; - var currWidth = 0f; - var currHeight = 0f; - var legendWidth = chartWidth - legend.location.left - legend.location.right; - var legendHeight = chartHeight - legend.location.top - legend.location.bottom; + var legendMaxWidth = chartWidth - legend.location.left - legend.location.right; + var legendMaxHeight = chartHeight - legend.location.top - legend.location.bottom; + UpdateLegendWidthAndHeight(legend, legendMaxWidth, legendMaxHeight); var legendRuntimeWidth = legend.runtimeWidth; var legendRuntimeHeight = legend.runtimeHeight; - switch (legend.orient) + var isVertical = legend.orient == Orient.Vertical; + switch (legend.location.align) { - case Orient.Vertical: - switch (legend.location.align) - { - case Location.Align.TopCenter: - startX = legendRuntimeWidth / 2; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendHeight) - { - currHeight = 0; - offsetX += legendRuntimeWidth + legend.itemGap; - } - item.SetPosition(new Vector3(-startX + item.width / 2 + offsetX, -currHeight)); - currHeight += item.height + legend.itemGap; - } - break; - case Location.Align.TopLeft: - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendHeight) - { - currHeight = 0; - offsetX += legendRuntimeWidth + legend.itemGap; - } - item.SetPosition(new Vector3(0 + offsetX, -currHeight)); - currHeight += item.height + legend.itemGap; - } - break; - case Location.Align.TopRight: - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendHeight) - { - currHeight = 0; - offsetX -= legendRuntimeWidth + legend.itemGap; - } - item.SetPosition(new Vector3(item.width - legendRuntimeWidth + offsetX, -currHeight)); - currHeight += item.height + legend.itemGap; - } - break; + case Location.Align.TopCenter: + startX = chartPos.x + chartWidth / 2 - legendRuntimeWidth / 2; + startY = chartPos.y + chartHeight - legend.location.top; + break; + case Location.Align.TopLeft: + startX = chartPos.x + legend.location.left; + startY = chartPos.y + chartHeight - legend.location.top; + break; + case Location.Align.TopRight: + startX = chartPos.x + chartWidth - legendRuntimeWidth - legend.location.right; + startY = chartPos.y + chartHeight - legend.location.top; + break; + case Location.Align.Center: + startX = chartPos.x + chartWidth / 2 - legendRuntimeWidth / 2; + startY = chartPos.y + chartHeight / 2 + legendRuntimeHeight / 2; + break; + case Location.Align.CenterLeft: + startX = chartPos.x + legend.location.left; + startY = chartPos.y + chartHeight / 2 + legendRuntimeHeight / 2; + break; + case Location.Align.CenterRight: + startX = chartPos.x + chartWidth - legendRuntimeWidth - legend.location.right; + startY = chartPos.y + chartHeight / 2 + legendRuntimeHeight / 2; + break; + case Location.Align.BottomCenter: + startX = chartPos.x + chartWidth / 2 - legendRuntimeWidth / 2; + startY = chartPos.y + legendRuntimeHeight + legend.location.bottom; + break; + case Location.Align.BottomLeft: + startX = chartPos.x + legend.location.left; + startY = chartPos.y + legendRuntimeHeight + legend.location.bottom; + break; + case Location.Align.BottomRight: + startX = chartPos.x + chartWidth - legendRuntimeWidth - legend.location.right; + startY = chartPos.y + legendRuntimeHeight + legend.location.bottom; + break; + } + if (isVertical) SetVerticalItemPosition(legend, legendMaxHeight, startX, startY); + else SetHorizonalItemPosition(legend, legendMaxWidth, startX, startY); + } - case Location.Align.Center: - startX = legendRuntimeWidth / 2; - startY = legendRuntimeHeight > legendHeight ? legendHeight / 2 : legendRuntimeHeight / 2; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendHeight) - { - currHeight = 0; - offsetX += legendRuntimeWidth + legend.itemGap; - } - item.SetPosition(new Vector3(-startX + item.width / 2 + offsetX, startY - currHeight)); - currHeight += item.height + legend.itemGap; - } - break; - case Location.Align.CenterLeft: - startY = legendRuntimeHeight > legendHeight ? legendHeight / 2 : legendRuntimeHeight / 2; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendHeight) - { - currHeight = 0; - offsetX += legendRuntimeWidth + legend.itemGap; - } - item.SetPosition(new Vector3(offsetX, startY - currHeight - item.height)); - currHeight += item.height + legend.itemGap; - } - break; - case Location.Align.CenterRight: - startX = 0; - startY = legendRuntimeHeight > legendHeight ? legendHeight / 2 : legendRuntimeHeight / 2; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendHeight) - { - currHeight = 0; - offsetX -= legendRuntimeWidth + legend.itemGap; - } - item.SetPosition(new Vector3(item.width - legendRuntimeWidth + offsetX, startY - currHeight - item.height)); - currHeight += item.height + legend.itemGap; - } - break; - case Location.Align.BottomCenter: - startX = legendRuntimeWidth / 2; - startY = legendRuntimeHeight > legendHeight ? legendHeight : legendRuntimeHeight; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendHeight) - { - currHeight = 0; - offsetX += legendRuntimeWidth + legend.itemGap; - } - item.SetPosition(new Vector3(-startX + item.width / 2 + offsetX, startY - currHeight - item.height)); - currHeight += item.height + legend.itemGap; - } - break; - case Location.Align.BottomLeft: - startX = 0; - startY = legendRuntimeHeight > legendHeight ? legendHeight : legendRuntimeHeight; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendHeight) - { - currHeight = 0; - offsetX += legendRuntimeWidth + legend.itemGap; - } - item.SetPosition(new Vector3(startX + offsetX, startY - currHeight - item.height)); - currHeight += item.height + legend.itemGap; - } - break; - case Location.Align.BottomRight: - startX = 0; - startY = legendRuntimeHeight > legendHeight ? legendHeight : legendRuntimeHeight; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendHeight) - { - currHeight = 0; - offsetX -= legendRuntimeWidth + legend.itemGap; - } - item.SetPosition(new Vector3(item.width - legendRuntimeWidth + offsetX, startY - currHeight - item.height)); - currHeight += item.height + legend.itemGap; - } - break; - } - break; - case Orient.Horizonal: - switch (legend.location.align) + private static void SetVerticalItemPosition(Legend legend, float legendMaxHeight, float startX, float startY) + { + var currHeight = 0f; + var offsetX = 0f; + var row = 0; + foreach (var kv in legend.buttonList) + { + var item = kv.Value; + if (currHeight + item.height > legendMaxHeight) + { + currHeight = 0; + offsetX += legend.runtimeEachWidth[row]; + row++; + } + item.SetPosition(new Vector3(startX + offsetX, startY - currHeight)); + currHeight += item.height + legend.itemGap; + } + } + private static void SetHorizonalItemPosition(Legend legend, float legendMaxWidth, float startX, float startY) + { + var currWidth = 0f; + var offsetY = 0f; + foreach (var kv in legend.buttonList) + { + var item = kv.Value; + if (currWidth + item.width > legendMaxWidth) + { + currWidth = 0; + offsetY += legend.runtimeEachHeight; + } + item.SetPosition(new Vector3(startX + currWidth, startY - offsetY)); + currWidth += item.width + legend.itemGap; + } + } + + private static void UpdateLegendWidthAndHeight(Legend legend, float maxWidth, float maxHeight) + { + var width = 0f; + var height = 0f; + var realHeight = 0f; + var realWidth = 0f; + legend.runtimeEachWidth.Clear(); + legend.runtimeEachHeight = 0; + if (legend.orient == Orient.Horizonal) + { + foreach (var kv in legend.buttonList) + { + if (width + kv.Value.width > maxWidth) { - case Location.Align.TopLeft: - case Location.Align.CenterLeft: - case Location.Align.BottomLeft: - var isBottom = legend.location.align == Location.Align.BottomLeft; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currWidth + item.width > legendWidth) - { - currWidth = 0f; - if (isBottom) currHeight += legend.itemGap + item.height; - else currHeight -= legend.itemGap + item.height; - } - item.SetPosition(new Vector3(currWidth, currHeight)); - currWidth += item.width + legend.itemGap; - } - break; - case Location.Align.TopCenter: - case Location.Align.Center: - case Location.Align.BottomCenter: - isBottom = legend.location.align == Location.Align.BottomCenter; - startX = legendRuntimeWidth > legendWidth ? legendWidth / 2 : legendRuntimeWidth / 2; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currWidth + item.width > legendWidth) - { - currWidth = 0f; - if (isBottom) currHeight += legend.itemGap + item.height; - else currHeight -= legend.itemGap + item.height; - } - item.SetPosition(new Vector3(-startX + item.width / 2 + currWidth, currHeight)); - currWidth += item.width + legend.itemGap; - } - break; - case Location.Align.TopRight: - case Location.Align.CenterRight: - case Location.Align.BottomRight: - isBottom = legend.location.align == Location.Align.BottomRight; - startX = legendRuntimeWidth > legendWidth ? -legendWidth : -legendRuntimeWidth; - foreach (var kv in legend.buttonList) - { - var item = kv.Value; - if (currWidth + item.width > legendWidth) - { - currWidth = 0f; - if (isBottom) currHeight += legend.itemGap + item.height; - else currHeight -= legend.itemGap + item.height; - } - item.SetPosition(new Vector3(startX + currWidth + item.width, currHeight)); - currWidth += item.width + legend.itemGap; - } - break; + realWidth = width - legend.itemGap; + realHeight += height + legend.itemGap; + if (legend.runtimeEachHeight < height + legend.itemGap) + { + legend.runtimeEachHeight = height + legend.itemGap; + } + height = 0; + width = 0; } - break; + width += kv.Value.width + legend.itemGap; + if (kv.Value.height > height) + height = kv.Value.height; + } + width -= legend.itemGap; + legend.runtimeHeight = realHeight + height; + legend.runtimeWidth = realWidth > 0 ? realWidth : width; + } + else + { + var row = 0; + foreach (var kv in legend.buttonList) + { + if (height + kv.Value.height > maxHeight) + { + realHeight = height - legend.itemGap; + realWidth += width + legend.itemGap; + legend.runtimeEachWidth[row] = width + legend.itemGap; + row++; + height = 0; + width = 0; + } + height += kv.Value.height + legend.itemGap; + if (kv.Value.width > width) + width = kv.Value.width; + } + height -= legend.itemGap; + legend.runtimeHeight = realHeight > 0 ? realHeight : height; + legend.runtimeWidth = realWidth + width; } }