优化Legend的布局

This commit is contained in:
monitor1394
2020-06-09 09:24:08 +08:00
parent 2f9544b256
commit 51159db106
4 changed files with 154 additions and 246 deletions

View File

@@ -679,11 +679,6 @@ namespace XCharts
return chartPosition + m_Title.location.GetPosition(chartWidth, chartHeight); 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)] [Obsolete("Use BaseChart.RefreshLabel() instead.", true)]
public void ReinitChartLabel() { } public void ReinitChartLabel() { }

View File

@@ -188,38 +188,22 @@ namespace XCharts
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public Dictionary<string, LegendItem> buttonList { get { return m_DataBtnList; } } public Dictionary<string, LegendItem> buttonList { get { return m_DataBtnList; } }
/// <summary>
public float runtimeWidth /// 运行时图例的总宽度
{ /// </summary>
get public float runtimeWidth { get; internal set; }
{ /// <summary>
var width = 0f; /// 运行时图例的总高度
foreach (var kv in buttonList) /// </summary>
{ public float runtimeHeight { get; internal set; }
if (orient == Orient.Horizonal) /// <summary>
width += kv.Value.width + m_ItemGap; /// 多列时每列的宽度
else if (kv.Value.width > width) /// </summary>
width = kv.Value.width; public Dictionary<int, float> runtimeEachWidth { get; internal set; }
} /// <summary>
return orient == Orient.Horizonal ? width - m_ItemGap : width; /// 单列高度
} /// </summary>
} public float runtimeEachHeight { get; internal set; }
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;
}
}
/// <summary> /// <summary>
/// 一个在顶部居中显示的默认图例。 /// 一个在顶部居中显示的默认图例。
@@ -237,6 +221,7 @@ namespace XCharts
m_ItemWidth = 24.0f, m_ItemWidth = 24.0f,
m_ItemHeight = 12.0f, m_ItemHeight = 12.0f,
m_ItemGap = 10f, m_ItemGap = 10f,
runtimeEachWidth = new Dictionary<int, float>()
}; };
legend.location.top = 30; legend.location.top = 30;
legend.textStyle.offset = new Vector2(2, 0); legend.textStyle.offset = new Vector2(2, 0);

View File

@@ -332,14 +332,8 @@ namespace XCharts
private void InitLegend() private void InitLegend()
{ {
m_Legend.OnChanged(); m_Legend.OnChanged();
TextAnchor anchor = m_Legend.location.runtimeTextAnchor; var legendObject = ChartHelper.AddObject(s_LegendObjectName, transform, m_ChartMinAnchor,
Vector2 anchorMin = m_Legend.location.runtimeAnchorMin; m_ChartMaxAnchor, m_ChartPivot, new Vector2(chartWidth, chartHeight));
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();
legendObject.hideFlags = chartHideFlags; legendObject.hideFlags = chartHideFlags;
SeriesHelper.UpdateSerieNameList(m_Series, ref m_LegendRealShowName); SeriesHelper.UpdateSerieNameList(m_Series, ref m_LegendRealShowName);
List<string> datas; List<string> datas;
@@ -428,7 +422,7 @@ namespace XCharts
OnLegendButtonClick(n, m_LegendRealShowName[n], n == 0 ? true : false); 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() private void InitSerieLabel()

View File

@@ -43,9 +43,9 @@ namespace XCharts
var font = textStyle.font ? textStyle.font : themeInfo.font; var font = textStyle.font ? textStyle.font : themeInfo.font;
var contentColor = GetContentColor(legend, themeInfo, active); var contentColor = GetContentColor(legend, themeInfo, active);
var objAnchorMin = legend.location.runtimeAnchorMin; var objAnchorMin = new Vector2(0, 1);
var objAnchorMax = legend.location.runtimeAnchorMax; var objAnchorMax = new Vector2(0, 1);
var objPivot = legend.location.runtimePivot; var objPivot = new Vector2(0, 1);
var btnObj = ChartHelper.AddObject(objName, parent, objAnchorMin, objAnchorMax, objPivot, sizeDelta, i); var btnObj = ChartHelper.AddObject(objName, parent, objAnchorMin, objAnchorMax, objPivot, sizeDelta, i);
var iconObj = ChartHelper.AddObject("icon", btnObj.transform, anchorMin, anchorMax, pivot, iconSizeDelta); var iconObj = ChartHelper.AddObject("icon", btnObj.transform, anchorMin, anchorMax, pivot, iconSizeDelta);
var contentObj = ChartHelper.AddObject("content", btnObj.transform, anchorMin, anchorMax, pivot, sizeDelta); var contentObj = ChartHelper.AddObject("content", btnObj.transform, anchorMin, anchorMax, pivot, sizeDelta);
@@ -71,212 +71,146 @@ namespace XCharts
return item; 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 startX = 0f;
var startY = 0f; var startY = 0f;
var offsetX = 0f; var legendMaxWidth = chartWidth - legend.location.left - legend.location.right;
var currWidth = 0f; var legendMaxHeight = chartHeight - legend.location.top - legend.location.bottom;
var currHeight = 0f; UpdateLegendWidthAndHeight(legend, legendMaxWidth, legendMaxHeight);
var legendWidth = chartWidth - legend.location.left - legend.location.right;
var legendHeight = chartHeight - legend.location.top - legend.location.bottom;
var legendRuntimeWidth = legend.runtimeWidth; var legendRuntimeWidth = legend.runtimeWidth;
var legendRuntimeHeight = legend.runtimeHeight; var legendRuntimeHeight = legend.runtimeHeight;
switch (legend.orient) var isVertical = legend.orient == Orient.Vertical;
switch (legend.location.align)
{ {
case Orient.Vertical: case Location.Align.TopCenter:
switch (legend.location.align) startX = chartPos.x + chartWidth / 2 - legendRuntimeWidth / 2;
{ startY = chartPos.y + chartHeight - legend.location.top;
case Location.Align.TopCenter: break;
startX = legendRuntimeWidth / 2; case Location.Align.TopLeft:
foreach (var kv in legend.buttonList) startX = chartPos.x + legend.location.left;
{ startY = chartPos.y + chartHeight - legend.location.top;
var item = kv.Value; break;
if (currHeight + item.height > legendHeight) case Location.Align.TopRight:
{ startX = chartPos.x + chartWidth - legendRuntimeWidth - legend.location.right;
currHeight = 0; startY = chartPos.y + chartHeight - legend.location.top;
offsetX += legendRuntimeWidth + legend.itemGap; break;
} case Location.Align.Center:
item.SetPosition(new Vector3(-startX + item.width / 2 + offsetX, -currHeight)); startX = chartPos.x + chartWidth / 2 - legendRuntimeWidth / 2;
currHeight += item.height + legend.itemGap; startY = chartPos.y + chartHeight / 2 + legendRuntimeHeight / 2;
} break;
break; case Location.Align.CenterLeft:
case Location.Align.TopLeft: startX = chartPos.x + legend.location.left;
foreach (var kv in legend.buttonList) startY = chartPos.y + chartHeight / 2 + legendRuntimeHeight / 2;
{ break;
var item = kv.Value; case Location.Align.CenterRight:
if (currHeight + item.height > legendHeight) startX = chartPos.x + chartWidth - legendRuntimeWidth - legend.location.right;
{ startY = chartPos.y + chartHeight / 2 + legendRuntimeHeight / 2;
currHeight = 0; break;
offsetX += legendRuntimeWidth + legend.itemGap; case Location.Align.BottomCenter:
} startX = chartPos.x + chartWidth / 2 - legendRuntimeWidth / 2;
item.SetPosition(new Vector3(0 + offsetX, -currHeight)); startY = chartPos.y + legendRuntimeHeight + legend.location.bottom;
currHeight += item.height + legend.itemGap; break;
} case Location.Align.BottomLeft:
break; startX = chartPos.x + legend.location.left;
case Location.Align.TopRight: startY = chartPos.y + legendRuntimeHeight + legend.location.bottom;
foreach (var kv in legend.buttonList) break;
{ case Location.Align.BottomRight:
var item = kv.Value; startX = chartPos.x + chartWidth - legendRuntimeWidth - legend.location.right;
if (currHeight + item.height > legendHeight) startY = chartPos.y + legendRuntimeHeight + legend.location.bottom;
{ break;
currHeight = 0; }
offsetX -= legendRuntimeWidth + legend.itemGap; if (isVertical) SetVerticalItemPosition(legend, legendMaxHeight, startX, startY);
} else SetHorizonalItemPosition(legend, legendMaxWidth, startX, startY);
item.SetPosition(new Vector3(item.width - legendRuntimeWidth + offsetX, -currHeight)); }
currHeight += item.height + legend.itemGap;
}
break;
case Location.Align.Center: private static void SetVerticalItemPosition(Legend legend, float legendMaxHeight, float startX, float startY)
startX = legendRuntimeWidth / 2; {
startY = legendRuntimeHeight > legendHeight ? legendHeight / 2 : legendRuntimeHeight / 2; var currHeight = 0f;
foreach (var kv in legend.buttonList) var offsetX = 0f;
{ var row = 0;
var item = kv.Value; foreach (var kv in legend.buttonList)
if (currHeight + item.height > legendHeight) {
{ var item = kv.Value;
currHeight = 0; if (currHeight + item.height > legendMaxHeight)
offsetX += legendRuntimeWidth + legend.itemGap; {
} currHeight = 0;
item.SetPosition(new Vector3(-startX + item.width / 2 + offsetX, startY - currHeight)); offsetX += legend.runtimeEachWidth[row];
currHeight += item.height + legend.itemGap; row++;
} }
break; item.SetPosition(new Vector3(startX + offsetX, startY - currHeight));
case Location.Align.CenterLeft: currHeight += item.height + legend.itemGap;
startY = legendRuntimeHeight > legendHeight ? legendHeight / 2 : legendRuntimeHeight / 2; }
foreach (var kv in legend.buttonList) }
{ private static void SetHorizonalItemPosition(Legend legend, float legendMaxWidth, float startX, float startY)
var item = kv.Value; {
if (currHeight + item.height > legendHeight) var currWidth = 0f;
{ var offsetY = 0f;
currHeight = 0; foreach (var kv in legend.buttonList)
offsetX += legendRuntimeWidth + legend.itemGap; {
} var item = kv.Value;
item.SetPosition(new Vector3(offsetX, startY - currHeight - item.height)); if (currWidth + item.width > legendMaxWidth)
currHeight += item.height + legend.itemGap; {
} currWidth = 0;
break; offsetY += legend.runtimeEachHeight;
case Location.Align.CenterRight: }
startX = 0; item.SetPosition(new Vector3(startX + currWidth, startY - offsetY));
startY = legendRuntimeHeight > legendHeight ? legendHeight / 2 : legendRuntimeHeight / 2; currWidth += item.width + legend.itemGap;
foreach (var kv in legend.buttonList) }
{ }
var item = kv.Value;
if (currHeight + item.height > legendHeight) private static void UpdateLegendWidthAndHeight(Legend legend, float maxWidth, float maxHeight)
{ {
currHeight = 0; var width = 0f;
offsetX -= legendRuntimeWidth + legend.itemGap; var height = 0f;
} var realHeight = 0f;
item.SetPosition(new Vector3(item.width - legendRuntimeWidth + offsetX, startY - currHeight - item.height)); var realWidth = 0f;
currHeight += item.height + legend.itemGap; legend.runtimeEachWidth.Clear();
} legend.runtimeEachHeight = 0;
break; if (legend.orient == Orient.Horizonal)
case Location.Align.BottomCenter: {
startX = legendRuntimeWidth / 2; foreach (var kv in legend.buttonList)
startY = legendRuntimeHeight > legendHeight ? legendHeight : legendRuntimeHeight; {
foreach (var kv in legend.buttonList) if (width + kv.Value.width > maxWidth)
{
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)
{ {
case Location.Align.TopLeft: realWidth = width - legend.itemGap;
case Location.Align.CenterLeft: realHeight += height + legend.itemGap;
case Location.Align.BottomLeft: if (legend.runtimeEachHeight < height + legend.itemGap)
var isBottom = legend.location.align == Location.Align.BottomLeft; {
foreach (var kv in legend.buttonList) legend.runtimeEachHeight = height + legend.itemGap;
{ }
var item = kv.Value; height = 0;
if (currWidth + item.width > legendWidth) width = 0;
{
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;
} }
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;
} }
} }