重构Legend图例,改变样式,增加自定义图标等设置

This commit is contained in:
monitor1394
2020-02-26 22:52:57 +08:00
parent 8c1cc28776
commit 5cf7b5d571
22 changed files with 197836 additions and 73324 deletions

View File

@@ -1,6 +1,7 @@
# 更新日志
* (2020.02.26) 重构`Legend`图例,改变样式,增加自定义图标等设置
* (2020.02.23) 增加`BaseChart.AnimationFadeOut()`渐出动画,重构动画系统
* (2020.02.13) 增加`BaseChart.RefreshTooltip()`接口立即重新初始化`Tooltip`组件
* (2020.02.13) 增加`Tooltip``textStyle`参数配置内容文本样式,去掉`fontSize``fontStyle`参数

View File

@@ -118,12 +118,14 @@
* `Horizonal`:水平。
* `Vertical`:垂直。
* `location`:图例的显示位置 [Location](#Location)。
* `itemWidth`每个图例项的宽度。
* `itemHeight`每个图例项的高度。
* `itemWidth`图例标记的图形宽度。
* `itemHeight`图例标记的图形高度。
* `itemGap`:图例每项之间的间隔。横向布局时为水平间隔,纵向布局时为纵向间隔。
* `itemFontSize`:图例项的字体大小
* `itemAutoColor`:图例标记的图形是否自动匹配颜色
* `formatter`:图例内容字符串模版格式器。支持用 `\n` 换行。模板变量为图例名称 `{name}`
* `data`:图例的数据数组。数组项通常为一个字符串,每一项代表一个系列的 `name`(如果是饼图,也可以是饼图单个数据的 `name`)。如果 `data` 没有被指定,会自动从当前系列中获取。指定 `data` 时里面的数据项和 `serie` 匹配时才会生效。
* `icons`:自定义的图例标记图形。
* `textStyle`:图例的内容文本样式 [TextStyle](#TextStyle)。
相关接口:
@@ -169,6 +171,8 @@
* `rotate`:旋转。
* `offset`:偏移。
* `color`:颜色。
* `backgroundColor`:背景颜色。
* `font`:字体。
* `fontSize`:字体大小。
* `fontStyle`:字体风格。
* `lineSpacing`:行间距。

View File

@@ -14,7 +14,9 @@ namespace XCharts
public class LegendDrawer : PropertyDrawer
{
private bool m_DataFoldout = false;
private bool m_IconsFoldout = false;
private int m_DataSize = 0;
private int m_IconsSize = 0;
private bool m_ShowJsonDataArea = false;
private string m_JsonDataAreaText;
private bool m_LegendModuleToggle = false;
@@ -30,9 +32,11 @@ namespace XCharts
SerializedProperty itemWidth = prop.FindPropertyRelative("m_ItemWidth");
SerializedProperty itemHeight = prop.FindPropertyRelative("m_ItemHeight");
SerializedProperty itemGap = prop.FindPropertyRelative("m_ItemGap");
SerializedProperty itemFontSize = prop.FindPropertyRelative("m_ItemFontSize");
SerializedProperty m_ItemAutoColor = prop.FindPropertyRelative("m_ItemAutoColor");
SerializedProperty m_Formatter = prop.FindPropertyRelative("m_Formatter");
SerializedProperty m_Data = prop.FindPropertyRelative("m_Data");
SerializedProperty m_Icons = prop.FindPropertyRelative("m_Icons");
SerializedProperty m_TextStyle = prop.FindPropertyRelative("m_TextStyle");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_LegendModuleToggle, "Legend", show);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
@@ -45,7 +49,7 @@ namespace XCharts
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, itemGap);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, itemFontSize);
EditorGUI.PropertyField(drawRect, m_ItemAutoColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SelectedMode);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
@@ -57,12 +61,20 @@ namespace XCharts
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
drawRect.width = EditorGUIUtility.labelWidth + 10;
m_DataFoldout = EditorGUI.Foldout(drawRect, m_DataFoldout, "Data");
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_ShowJsonDataArea, ref m_JsonDataAreaText, prop,pos.width);
ChartEditorHelper.MakeJsonData(ref drawRect, ref m_ShowJsonDataArea, ref m_JsonDataAreaText, prop, pos.width);
drawRect.width = pos.width;
if (m_DataFoldout)
{
ChartEditorHelper.MakeList(ref drawRect, ref m_DataSize, m_Data);
}
m_IconsFoldout = EditorGUI.Foldout(drawRect, m_IconsFoldout, "Icons");
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_IconsFoldout)
{
ChartEditorHelper.MakeList(ref drawRect, ref m_IconsSize, m_Icons);
}
EditorGUI.PropertyField(drawRect, m_TextStyle);
drawRect.y += EditorGUI.GetPropertyHeight(m_TextStyle);
--EditorGUI.indentLevel;
}
}
@@ -73,7 +85,7 @@ namespace XCharts
if (m_LegendModuleToggle)
{
SerializedProperty location = prop.FindPropertyRelative("m_Location");
height += 7 * EditorGUIUtility.singleLineHeight + 6 * EditorGUIUtility.standardVerticalSpacing;
height += 8 * EditorGUIUtility.singleLineHeight + 7 * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(location);
height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_DataFoldout)
@@ -83,6 +95,14 @@ namespace XCharts
height += num * EditorGUIUtility.singleLineHeight + (num - 1) * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUIUtility.standardVerticalSpacing;
}
if (m_IconsFoldout)
{
SerializedProperty m_Icons = prop.FindPropertyRelative("m_Icons");
int num = m_Icons.arraySize + 1;
height += num * EditorGUIUtility.singleLineHeight + (num - 1) * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUIUtility.standardVerticalSpacing;
}
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_TextStyle"));
}
if (m_ShowJsonDataArea)
{

View File

@@ -20,8 +20,10 @@ namespace XCharts
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty m_Font = prop.FindPropertyRelative("m_Font");
SerializedProperty m_Rotate = prop.FindPropertyRelative("m_Rotate");
SerializedProperty m_Color = prop.FindPropertyRelative("m_Color");
SerializedProperty m_BackgroundColor = prop.FindPropertyRelative("m_BackgroundColor");
SerializedProperty m_FontSize = prop.FindPropertyRelative("m_FontSize");
SerializedProperty m_FontStyle = prop.FindPropertyRelative("m_FontStyle");
SerializedProperty m_Offset = prop.FindPropertyRelative("m_Offset");
@@ -31,12 +33,16 @@ namespace XCharts
if (ChartEditorHelper.IsToggle(m_TextStyleToggle, prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Font);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Rotate);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Offset);
drawRect.y += EditorGUI.GetPropertyHeight(m_Offset);
EditorGUI.PropertyField(drawRect, m_Color);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_BackgroundColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_FontSize);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_FontStyle);
@@ -52,7 +58,7 @@ namespace XCharts
float height = 0;
if (ChartEditorHelper.IsToggle(m_TextStyleToggle, prop))
{
height += 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing;
height += 8 * EditorGUIUtility.singleLineHeight + 7 * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Offset"));
}
else

View File

@@ -21,7 +21,7 @@ namespace XCharts
/// <summary>
/// The theme info.
/// </summary>
public ThemeInfo themeInfo { get { return m_ThemeInfo; } }
public ThemeInfo themeInfo { get { return m_ThemeInfo; } set { m_ThemeInfo = value; } }
/// <summary>
/// The title setting of chart.
/// 标题组件
@@ -402,9 +402,19 @@ namespace XCharts
var serie = m_Series.GetSerie(serieIndex);
if (serie != null && !string.IsNullOrEmpty(serie.name))
{
var legendIndex = m_LegendRealShowName.IndexOf(serie.name);
var bgColor1 = active ? m_ThemeInfo.GetColor(legendIndex) : m_ThemeInfo.legendUnableColor;
m_Legend.UpdateButtonColor(serie.name, bgColor1);
UpdateLegendColor(serie.name, active);
}
}
protected virtual void UpdateLegendColor(string legendName, bool active)
{
var legendIndex = m_LegendRealShowName.IndexOf(legendName);
if (legendIndex >= 0)
{
var iconColor = LegendHelper.GetIconColor(legend, legendIndex, m_ThemeInfo, active);
var contentColor = LegendHelper.GetContentColor(legend, m_ThemeInfo, active);
m_Legend.UpdateButtonColor(legendName, iconColor);
m_Legend.UpdateContentColor(legendName, contentColor);
}
}

View File

@@ -43,14 +43,16 @@ namespace XCharts
[SerializeField] private SelectedMode m_SelectedMode;
[SerializeField] private Orient m_Orient = Orient.Horizonal;
[SerializeField] private Location m_Location = Location.defaultRight;
[SerializeField] private float m_ItemWidth = 50.0f;
[SerializeField] private float m_ItemHeight = 20.0f;
[SerializeField] private float m_ItemGap = 5;
[SerializeField] private int m_ItemFontSize = 18;
[SerializeField] private float m_ItemWidth = 24.0f;
[SerializeField] private float m_ItemHeight = 12.0f;
[SerializeField] private float m_ItemGap = 10f;
[SerializeField] private bool m_ItemAutoColor = true;
[SerializeField] private string m_Formatter;
[SerializeField] private TextStyle m_TextStyle = new TextStyle(18);
[SerializeField] private List<string> m_Data = new List<string>();
[SerializeField] private List<Sprite> m_Icons = new List<Sprite>();
private Dictionary<string, Button> m_DataBtnList = new Dictionary<string, Button>();
private Dictionary<string, LegendItem> m_DataBtnList = new Dictionary<string, LegendItem>();
/// <summary>
/// Whether to show legend component.
@@ -74,13 +76,13 @@ namespace XCharts
/// </summary>
public Location location { get { return m_Location; } set { m_Location = value; } }
/// <summary>
/// the width of legend item.
/// 每个图例项的宽度。
/// Image width of legend symbol.
/// 图例标记的图形宽度。
/// </summary>
public float itemWidth { get { return m_ItemWidth; } set { m_ItemWidth = value; } }
/// <summary>
/// the height of legend item.
/// 每个图例项的高度。
/// Image height of legend symbol.
/// 图例标记的图形高度。
/// </summary>
public float itemHeight { get { return m_ItemHeight; } set { m_ItemHeight = value; } }
/// <summary>
@@ -89,16 +91,21 @@ namespace XCharts
/// </summary>
public float itemGap { get { return m_ItemGap; } set { m_ItemGap = value; } }
/// <summary>
/// font size of item text.
/// 图例项的字体大小
/// Whether the legend symbol matches the color automatically.
/// 图例标记的图形是否自动匹配颜色
/// </summary>
public int itemFontSize { get { return m_ItemFontSize; } set { m_ItemFontSize = value; } }
public bool itemAutoColor { get { return m_ItemAutoColor; } set { m_ItemAutoColor = value; } }
/// <summary>
/// 图例内容字符串模版格式器。支持用 \n 换行。
/// 模板变量为图例名称 {name}
/// </summary>
public string formatter { get { return m_Formatter; } set { m_Formatter = value; } }
/// <summary>
/// the style of text.
/// 文本样式。
/// </summary>
public TextStyle textStyle { get { return m_TextStyle; } set { m_TextStyle = value; } }
/// <summary>
/// Data array of legend. An array item is usually a name representing string. (If it is a pie chart,
/// it could also be the name of a single data in the pie chart) of a series.
/// If data is not specified, it will be auto collected from series.
@@ -107,11 +114,47 @@ namespace XCharts
/// </summary>
public List<string> data { get { return m_Data; } }
/// <summary>
/// 自定义的图例标记图形。
/// </summary>
public List<Sprite> icons { get { return m_Icons; } }
/// <summary>
/// the button list of legend.
/// 图例按钮列表。
/// </summary>
/// <value></value>
public Dictionary<string, Button> buttonList { get { return m_DataBtnList; } }
public Dictionary<string, LegendItem> 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;
}
}
/// <summary>
/// 一个在顶部居中显示的默认图例。
@@ -126,12 +169,13 @@ namespace XCharts
m_SelectedMode = SelectedMode.Multiple,
m_Orient = Orient.Horizonal,
m_Location = Location.defaultTop,
m_ItemWidth = 60.0f,
m_ItemHeight = 20.0f,
m_ItemGap = 5,
m_ItemFontSize = 16
m_ItemWidth = 24.0f,
m_ItemHeight = 12.0f,
m_ItemGap = 10f,
};
legend.location.top = 30;
legend.textStyle.offset = new Vector2(2, 0);
legend.textStyle.fontSize = 18;
return legend;
}
}
@@ -144,9 +188,10 @@ namespace XCharts
m_ItemWidth = legend.itemWidth;
m_ItemHeight = legend.itemHeight;
m_ItemGap = legend.itemGap;
m_ItemFontSize = legend.itemFontSize;
m_Data.Clear();
foreach (var d in legend.data) m_Data.Add(d);
itemAutoColor = legend.itemAutoColor;
m_TextStyle.Copy(legend.textStyle);
ChartHelper.CopyList<string>(m_Data, legend.data);
ChartHelper.CopyList<Sprite>(m_Icons, legend.icons);
}
public override bool Equals(object obj)
@@ -178,8 +223,10 @@ namespace XCharts
itemWidth == other.itemWidth &&
itemHeight == other.itemHeight &&
itemGap == other.itemGap &&
itemFontSize == other.itemFontSize &&
ChartHelper.IsValueEqualsList<string>(m_Data, other.data);
itemAutoColor == other.itemAutoColor &&
textStyle.Equals(other.textStyle) &&
ChartHelper.IsValueEqualsList<string>(m_Data, other.data) &&
ChartHelper.IsValueEqualsList<Sprite>(m_Icons, other.icons);
}
public static bool operator ==(Legend left, Legend right)
@@ -285,13 +332,11 @@ namespace XCharts
/// <param name="name"></param>
/// <param name="btn"></param>
/// <param name="total"></param>
public void SetButton(string name, Button btn, int total)
public void SetButton(string name, LegendItem item, int total)
{
m_DataBtnList[name] = item;
int index = m_DataBtnList.Values.Count;
btn.transform.localPosition = GetButtonLocationPosition(total, index);
m_DataBtnList[name] = btn;
btn.gameObject.SetActive(show);
btn.GetComponentInChildren<Text>().text = name;
item.SetActive(show);
}
/// <summary>
@@ -303,7 +348,27 @@ namespace XCharts
{
if (m_DataBtnList.ContainsKey(name))
{
m_DataBtnList[name].GetComponent<Image>().color = color;
m_DataBtnList[name].SetIconColor(color);
}
}
public void UpdateContentColor(string name, Color color)
{
if (m_DataBtnList.ContainsKey(name))
{
m_DataBtnList[name].SetContentColor(color);
}
}
public Sprite GetIcon(int index)
{
if (index >= 0 && index < m_Icons.Count)
{
return m_Icons[index];
}
else
{
return null;
}
}
@@ -314,63 +379,7 @@ namespace XCharts
{
m_Location.OnChanged();
}
/// <summary>
/// 根据图例的布局和位置类型获得具体位置
/// </summary>
/// <param name="size"></param>
/// <param name="index"></param>
/// <returns></returns>
private Vector2 GetButtonLocationPosition(int size, int index)
{
switch (m_Orient)
{
case Orient.Vertical:
switch (m_Location.align)
{
case Location.Align.TopCenter:
case Location.Align.TopLeft:
case Location.Align.TopRight:
return new Vector2(0, -index * (itemHeight + itemGap));
case Location.Align.Center:
case Location.Align.CenterLeft:
case Location.Align.CenterRight:
float totalHeight = size * itemHeight + (size - 1) * itemGap;
float startY = totalHeight / 2;
return new Vector2(0, startY - index * (itemHeight + itemGap));
case Location.Align.BottomCenter:
case Location.Align.BottomLeft:
case Location.Align.BottomRight:
return new Vector2(0, (size - index - 1) * (itemHeight + itemGap));
}
return Vector2.zero;
case Orient.Horizonal:
switch (m_Location.align)
{
case Location.Align.TopLeft:
case Location.Align.CenterLeft:
case Location.Align.BottomLeft:
return new Vector2(index * (itemWidth + itemGap), 0);
case Location.Align.TopCenter:
case Location.Align.Center:
case Location.Align.BottomCenter:
float totalWidth = size * itemWidth + (size - 1) * itemGap;
float startX = totalWidth / 2;
return new Vector2(-startX + itemWidth / 2 + index * (itemWidth + itemGap), 0);
case Location.Align.TopRight:
case Location.Align.CenterRight:
case Location.Align.BottomRight:
return new Vector2(-(size - index - 1) * (itemWidth + itemGap), 0);
}
return Vector2.zero;
}
return Vector2.zero;
}
/// <summary>
/// 从json字符串解析数据json格式如['邮件营销','联盟广告','视频广告','直接访问','搜索引擎']
/// </summary>

View File

@@ -207,7 +207,7 @@ namespace XCharts
var radar = new Radar
{
m_Shape = Shape.Polygon,
m_Radius = 0.4f,
m_Radius = 0.35f,
m_SplitNumber = 5,
m_Indicator = true,
m_IndicatorList = new List<Indicator>(5){
@@ -219,7 +219,7 @@ namespace XCharts
}
};
radar.center[0] = 0.5f;
radar.center[1] = 0.45f;
radar.center[1] = 0.4f;
radar.splitLine.show = true;
radar.splitArea.show = true;
radar.splitLine.lineStyle.width = 0.6f;

View File

@@ -501,6 +501,10 @@ namespace XCharts
/// </summary>
public int showDataDimension { get { return m_ShowDataDimension; } }
/// <summary>
/// 在Editor的inpsector上是否显示name参数
/// </summary>
public bool showDataName { get { return m_ShowDataName; } set { m_ShowDataName = value; } }
/// <summary>
/// If clip the overflow on the coordinate system.
/// 是否裁剪超出坐标系部分的图形。
/// </summary>

View File

@@ -615,6 +615,8 @@ namespace XCharts
if (serie != null)
{
serie.show = active;
serie.animation.Reset();
if (active) serie.animation.FadeIn();
}
}

View File

@@ -132,6 +132,8 @@ namespace XCharts
get { return m_CustomLegendTextColor != Color.clear ? m_CustomLegendTextColor : m_LegendTextColor; }
set { m_CustomLegendTextColor = value; }
}
public Color32 defaultLegendTextColor{get{return m_LegendTextColor;}set{m_LegendTextColor=value;}}
/// <summary>
/// the legend unable text color.
/// 图例变为不可用时的按钮颜色。
@@ -391,7 +393,7 @@ namespace XCharts
m_LegendUnableColor = GetColor("#cccccc"),
m_TitleTextColor = GetColor("#514D4D"),
m_TitleSubTextColor = GetColor("#514D4D"),
m_LegendTextColor = GetColor("#eee"),
m_LegendTextColor = GetColor("#514D4D"),
m_AxisTextColor = GetColor("#514D4D"),
m_AxisLineColor = GetColor("#514D4D"),
m_AxisSplitLineColor = GetColor("#51515120"),

View File

@@ -1,4 +1,3 @@
using System.Threading;
/******************************************/
/* */
/* Copyright (c) 2018 monitor1394 */
@@ -18,12 +17,18 @@ namespace XCharts
[Serializable]
public class TextStyle : SubComponent, IEquatable<TextStyle>
{
[SerializeField] private Font m_Font;
[SerializeField] private float m_Rotate = 0;
[SerializeField] private Vector2 m_Offset = Vector2.zero;
[SerializeField] private Color m_Color = Color.clear;
[SerializeField] private Color m_BackgroundColor = Color.clear;
[SerializeField] private int m_FontSize = 18;
[SerializeField] private FontStyle m_FontStyle = FontStyle.Normal;
[SerializeField] private float m_LineSpacing = 1;
[SerializeField] private float m_LineSpacing = 1f;
[SerializeField] private float m_PaddingLeft = 0f;
[SerializeField] private float m_PaddingRight = 0f;
[SerializeField] private float m_PaddingTop = 0f;
[SerializeField] private float m_PaddingBottom = 0f;
/// <summary>
/// Rotation of text.
@@ -44,6 +49,16 @@ namespace XCharts
/// </summary>
public Color color { get { return m_Color; } set { m_Color = value; } }
/// <summary>
/// the color of text.
/// 文本的背景颜色。
/// </summary>
public Color backgroundColor { get { return m_BackgroundColor; } set { m_BackgroundColor = value; } }
/// <summary>
/// the font of text.
/// 文本字体
/// </summary>
public Font font { get { return m_Font; } set { m_Font = value; } }
/// <summary>
/// font size.
/// 文本字体大小。
/// </summary>
@@ -94,6 +109,7 @@ namespace XCharts
this.fontSize = style.fontSize;
this.fontStyle = style.fontStyle;
this.color = style.color;
this.backgroundColor = style.backgroundColor;
this.rotate = style.rotate;
this.offset = style.offset;
this.lineSpacing = style.lineSpacing;
@@ -104,6 +120,7 @@ namespace XCharts
var textStyle = new TextStyle();
textStyle.rotate = rotate;
textStyle.color = color;
textStyle.backgroundColor = backgroundColor;
textStyle.fontSize = fontSize;
textStyle.fontStyle = fontStyle;
textStyle.offset = offset;
@@ -138,6 +155,7 @@ namespace XCharts
fontStyle == other.fontStyle &&
offset == other.offset &&
lineSpacing == other.lineSpacing &&
ChartHelper.IsValueEqualsColor(m_BackgroundColor, other.backgroundColor) &&
ChartHelper.IsValueEqualsColor(m_Color, other.color);
}

View File

@@ -0,0 +1,220 @@
/******************************************/
/* */
/* Copyright (c) 2018 monitor1394 */
/* https://github.com/monitor1394 */
/* */
/******************************************/
using UnityEngine;
using UnityEngine.UI;
namespace XCharts
{
internal static class LegendHelper
{
public static Color GetContentColor(Legend legend, ThemeInfo themeInfo, bool active)
{
var textStyle = legend.textStyle;
if (active) return textStyle.color != Color.clear ? textStyle.color : (Color)themeInfo.legendTextColor;
else return (Color)themeInfo.legendUnableColor;
}
public static Color GetIconColor(Legend legend, int readIndex, ThemeInfo themeInfo, bool active)
{
if (active)
{
if (legend.itemAutoColor || legend.GetIcon(readIndex) == null)
return (Color)themeInfo.GetColor(readIndex);
else
return Color.white;
}
else return (Color)themeInfo.legendUnableColor;
}
public static LegendItem AddLegendItem(Legend legend, int i, string legendName, Transform parent, ThemeInfo themeInfo,
string content, Color itemColor, bool active)
{
var objName = i + "_" + legendName;
var anchorMin = new Vector2(0, 0.5f);
var anchorMax = new Vector2(0, 0.5f);
var pivot = new Vector2(0, 0.5f);
var sizeDelta = new Vector2(100, 30);
var iconSizeDelta = new Vector2(legend.itemWidth, legend.itemHeight);
var textStyle = legend.textStyle;
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 btnObj = ChartHelper.AddObject(objName, parent, objAnchorMin, objAnchorMax, objPivot, sizeDelta);
var iconObj = ChartHelper.AddObject("icon", btnObj.transform, anchorMin, anchorMax, pivot, iconSizeDelta);
var contentObj = ChartHelper.AddObject("content", btnObj.transform, anchorMin, anchorMax, pivot, sizeDelta);
var img = ChartHelper.GetOrAddComponent<Image>(btnObj);
img.color = Color.clear;
ChartHelper.GetOrAddComponent<Button>(btnObj);
ChartHelper.GetOrAddComponent<Image>(iconObj);
ChartHelper.GetOrAddComponent<Image>(contentObj);
Text txt = ChartHelper.AddTextObject("Text", contentObj.transform, font, contentColor,
TextAnchor.MiddleLeft, anchorMin, anchorMax, pivot, sizeDelta, textStyle.fontSize,
textStyle.rotate, textStyle.fontStyle, textStyle.lineSpacing);
var item = new LegendItem();
item.index = i;
item.name = objName;
item.legendName = legendName;
item.SetObject(btnObj);
item.SetIconSize(legend.itemWidth, legend.itemHeight);
item.SetIconColor(itemColor);
item.SetIconImage(legend.GetIcon(i));
item.SetContentPosition(textStyle.offsetv3);
item.SetContent(content);
item.SetContentBackgroundColor(textStyle.backgroundColor);
return item;
}
public static void ResetItemPosition(Legend legend)
{
var startX = 0f;
var startY = 0f;
var currWidth = 0f;
var currHeight = 0f;
switch (legend.orient)
{
case Orient.Vertical:
switch (legend.location.align)
{
case Location.Align.TopCenter:
startX = legend.runtimeWidth / 2;
currHeight = 0f;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(-startX + item.width / 2, -currHeight));
currHeight += item.height + legend.itemGap;
}
break;
case Location.Align.TopLeft:
currHeight = 0f;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(0, -currHeight));
currHeight += item.height + legend.itemGap;
}
break;
case Location.Align.TopRight:
currHeight = 0f;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(item.width - legend.runtimeWidth, -currHeight));
currHeight += item.height + legend.itemGap;
}
break;
case Location.Align.Center:
startX = legend.runtimeWidth / 2;
currHeight = legend.runtimeHeight;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(-startX + item.width / 2, currHeight - item.height));
currHeight -= item.height + legend.itemGap;
}
break;
case Location.Align.CenterLeft:
currHeight = legend.runtimeHeight;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(0, currHeight - item.height));
currHeight -= item.height + legend.itemGap;
}
break;
case Location.Align.CenterRight:
currHeight = legend.runtimeHeight;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(item.width - legend.runtimeWidth, currHeight - item.height));
currHeight -= item.height + legend.itemGap;
}
break;
case Location.Align.BottomCenter:
startX = legend.runtimeWidth / 2;
currHeight = legend.runtimeHeight;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(-startX + item.width / 2, currHeight - item.height));
currHeight -= item.height + legend.itemGap;
}
break;
case Location.Align.BottomLeft:
currHeight = legend.runtimeHeight;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(0, currHeight - item.height));
currHeight -= item.height + legend.itemGap;
}
break;
case Location.Align.BottomRight:
currHeight = legend.runtimeHeight;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(item.width - legend.runtimeWidth, currHeight - item.height));
currHeight -= item.height + legend.itemGap;
}
break;
}
break;
case Orient.Horizonal:
switch (legend.location.align)
{
case Location.Align.TopLeft:
case Location.Align.CenterLeft:
case Location.Align.BottomLeft:
currWidth = 0f;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(currWidth, 0));
currWidth += item.width + legend.itemGap;
}
break;
case Location.Align.TopCenter:
case Location.Align.Center:
case Location.Align.BottomCenter:
startX = legend.runtimeWidth / 2;
currWidth = 0f;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(-startX + item.width / 2 + currWidth, 0));
currWidth += item.width + legend.itemGap;
}
break;
case Location.Align.TopRight:
case Location.Align.CenterRight:
case Location.Align.BottomRight:
startX = -legend.runtimeWidth;
currWidth = 0f;
foreach (var kv in legend.buttonList)
{
var item = kv.Value;
item.SetPosition(new Vector3(startX + currWidth + item.width, 0));
currWidth += item.width + legend.itemGap;
}
break;
break;
}
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 928a0ea2a67c74bdcad4f252830a7592
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -235,21 +235,18 @@ namespace XCharts
string legendName = m_Legend.GetFormatterContent(datas[i]);
var readIndex = m_LegendRealShowName.IndexOf(datas[i]);
var objName = s_LegendObjectName + "_" + i + "_" + datas[i];
Button btn = ChartHelper.AddButtonObject(objName, legendObject.transform,
m_ThemeInfo.font, m_Legend.itemFontSize, m_ThemeInfo.legendTextColor, anchor,
anchorMin, anchorMax, pivot, new Vector2(m_Legend.itemWidth, m_Legend.itemHeight), 1);
var bgColor = IsActiveByLegend(datas[i]) ?
m_ThemeInfo.GetColor(readIndex) : m_ThemeInfo.legendUnableColor;
m_Legend.SetButton(legendName, btn, totalLegend);
m_Legend.UpdateButtonColor(legendName, bgColor);
btn.GetComponentInChildren<Text>().text = legendName;
ChartHelper.ClearEventListener(btn.gameObject);
ChartHelper.AddEventListener(btn.gameObject, EventTriggerType.PointerDown, (data) =>
var active = IsActiveByLegend(datas[i]);
var bgColor = LegendHelper.GetIconColor(m_Legend, readIndex, themeInfo, active);
var item = LegendHelper.AddLegendItem(m_Legend, i, datas[i], legendObject.transform, m_ThemeInfo,
legendName, bgColor, active);
m_Legend.SetButton(legendName, item, totalLegend);
ChartHelper.ClearEventListener(item.button.gameObject);
ChartHelper.AddEventListener(item.button.gameObject, EventTriggerType.PointerDown, (data) =>
{
if (data.selectedObject == null || m_Legend.selectedMode == Legend.SelectedMode.None) return;
var temp = data.selectedObject.name.Split('_');
string selectedName = temp[2];
int clickedIndex = int.Parse(temp[1]);
string selectedName = temp[1];
int clickedIndex = int.Parse(temp[0]);
if (m_Legend.selectedMode == Legend.SelectedMode.Multiple)
{
OnLegendButtonClick(clickedIndex, selectedName, !IsActiveByLegend(selectedName));
@@ -266,27 +263,27 @@ namespace XCharts
for (int n = 0; n < btnList.Length; n++)
{
temp = btnList[n].name.Split('_');
selectedName = temp[2];
var index = int.Parse(temp[1]);
selectedName = btnList[n].legendName;
var index = btnList[n].index;
OnLegendButtonClick(n, selectedName, index == clickedIndex ? true : false);
}
}
}
});
ChartHelper.AddEventListener(btn.gameObject, EventTriggerType.PointerEnter, (data) =>
ChartHelper.AddEventListener(item.button.gameObject, EventTriggerType.PointerEnter, (data) =>
{
if (btn == null) return;
var temp = btn.name.Split('_');
string selectedName = temp[2];
int index = int.Parse(temp[1]);
if (item.button == null) return;
var temp = item.button.name.Split('_');
string selectedName = temp[1];
int index = int.Parse(temp[0]);
OnLegendButtonEnter(index, selectedName);
});
ChartHelper.AddEventListener(btn.gameObject, EventTriggerType.PointerExit, (data) =>
ChartHelper.AddEventListener(item.button.gameObject, EventTriggerType.PointerExit, (data) =>
{
if (btn == null) return;
var temp = btn.name.Split('_');
string selectedName = temp[2];
int index = int.Parse(temp[1]);
if (item.button == null) return;
var temp = item.button.name.Split('_');
string selectedName = temp[1];
int index = int.Parse(temp[0]);
OnLegendButtonExit(index, selectedName);
});
}
@@ -297,6 +294,7 @@ namespace XCharts
OnLegendButtonClick(n, m_LegendRealShowName[n], n == 0 ? true : false);
}
}
LegendHelper.ResetItemPosition(m_Legend);
}
private void InitSerieLabel()

View File

@@ -0,0 +1,190 @@
/******************************************/
/* */
/* Copyright (c) 2018 monitor1394 */
/* https://github.com/monitor1394 */
/* */
/******************************************/
using System;
using UnityEngine;
using UnityEngine.UI;
namespace XCharts
{
public class LegendItem
{
private int m_Index;
private string m_Name;
private string m_LegendName;
private GameObject m_GameObject;
private Button m_Button;
private Image m_Icon;
private Text m_Text;
private Image m_TextBackground;
private RectTransform m_Rect;
private RectTransform m_IconRect;
private RectTransform m_TextRect;
private RectTransform m_TextBackgroundRect;
private float m_Gap = 0f;
private float m_LabelPaddingLeftRight = 0f;
private float m_LabelPaddingTopBottom = 0f;
private bool m_LabelAutoSize = true;
public int index { get { return m_Index; } set { m_Index = value; } }
public string name { get { return m_Name; } set { m_Name = value; } }
public string legendName { get { return m_LegendName; } set { m_LegendName = value; } }
public GameObject gameObject { get { return m_GameObject; } }
public Button button { get { return m_Button; } }
public float width
{
get
{
if (m_IconRect && m_TextBackgroundRect)
{
return m_IconRect.sizeDelta.x + m_Gap + m_TextBackgroundRect.sizeDelta.x;
}
else
{
return 0;
}
}
}
public float height
{
get
{
if (m_IconRect && m_TextBackgroundRect)
{
return Mathf.Max(m_IconRect.sizeDelta.y, m_TextBackgroundRect.sizeDelta.y);
}
else
{
return 0;
}
}
}
public void SetObject(GameObject obj)
{
m_GameObject = obj;
m_Button = obj.GetComponent<Button>();
m_Rect = obj.GetComponent<RectTransform>();
m_Icon = obj.transform.Find("icon").gameObject.GetComponent<Image>();
m_TextBackground = obj.transform.Find("content").gameObject.GetComponent<Image>();
m_Text = obj.transform.Find("content/Text").gameObject.GetComponent<Text>();
m_IconRect = m_Icon.gameObject.GetComponent<RectTransform>();
m_TextRect = m_Text.gameObject.GetComponent<RectTransform>();
m_TextBackgroundRect = m_TextBackground.gameObject.GetComponent<RectTransform>();
}
public void SetButton(Button button)
{
m_Button = button;
}
public void SetIcon(Image icon)
{
m_Icon = icon;
}
public void SetText(Text text)
{
m_Text = text;
}
public void SetTextBackground(Image image)
{
m_TextBackground = image;
}
public void SetIconSize(float width, float height)
{
if (m_IconRect)
{
m_IconRect.sizeDelta = new Vector2(width, height);
}
}
public void SetIconColor(Color color)
{
if (m_Icon)
{
m_Icon.color = color;
}
}
public void SetIconImage(Sprite image)
{
if (m_Icon)
{
m_Icon.sprite = image;
}
}
public void SetContentColor(Color color)
{
if (m_Text)
{
m_Text.color = color;
}
}
public void SetContentBackgroundColor(Color color)
{
if (m_TextBackground)
{
m_TextBackground.color = color;
}
}
public void SetContentPosition(Vector3 offset)
{
m_Gap = offset.x;
if (m_TextBackgroundRect)
{
var posX = m_IconRect.sizeDelta.x + offset.x;
m_TextBackgroundRect.anchoredPosition3D = new Vector3(posX, offset.y, 0);
}
}
public bool SetContent(string content)
{
if (m_Text && !m_Text.text.Equals(content))
{
m_Text.text = content;
if (m_LabelAutoSize)
{
var newSize = string.IsNullOrEmpty(content) ? Vector2.zero :
new Vector2(m_Text.preferredWidth, m_Text.preferredHeight);
var sizeChange = newSize.x != m_TextRect.sizeDelta.x || newSize.y != m_TextRect.sizeDelta.y;
if (sizeChange)
{
m_TextRect.sizeDelta = newSize;
m_TextRect.anchoredPosition3D = new Vector3(m_LabelPaddingLeftRight, 0);
m_TextBackgroundRect.sizeDelta = new Vector2(m_Text.preferredWidth + m_LabelPaddingLeftRight * 2,
m_Text.preferredHeight + m_LabelPaddingTopBottom * 2 - 4);
m_Rect.sizeDelta = new Vector3(width, height);
}
return sizeChange;
}
}
return false;
}
public void SetPosition(Vector3 position)
{
if (m_GameObject)
{
m_GameObject.transform.localPosition = position;
}
}
public void SetActive(bool active)
{
if (m_GameObject)
{
m_GameObject.SetActive(active);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3452002928282423f988cd5c5ecf318a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -32,6 +32,7 @@ namespace XCharts
{
base.Reset();
m_Title.text = "PieChart";
m_Legend.show = true;
RemoveData();
AddSerie(SerieType.Pie, "serie1");
AddData(0, 70, "pie1");
@@ -484,9 +485,8 @@ namespace XCharts
protected override void OnLegendButtonClick(int index, string legendName, bool show)
{
bool active = CheckDataShow(legendName, show);
var bgColor1 = active ? m_ThemeInfo.GetColor(index) : m_ThemeInfo.legendUnableColor;
m_Legend.UpdateButtonColor(legendName, bgColor1);
CheckDataShow(legendName, show);
UpdateLegendColor(legendName, show);
RefreshChart();
}

View File

@@ -26,9 +26,8 @@ namespace XCharts
protected override void OnLegendButtonClick(int index, string legendName, bool show)
{
bool active = CheckDataShow(legendName, show);
var bgColor1 = active ? m_ThemeInfo.GetColor(index) : m_ThemeInfo.legendUnableColor;
m_Legend.UpdateButtonColor(legendName, bgColor1);
CheckDataShow(legendName, show);
UpdateLegendColor(legendName, show);
RefreshChart();
}
@@ -69,12 +68,13 @@ namespace XCharts
serie.symbol.type = SerieSymbolType.EmptyCircle;
serie.symbol.size = 4;
serie.symbol.selectedSize = 6;
serie.showDataName = true;
List<float> data = new List<float>();
for (int i = 0; i < 5; i++)
{
data.Add(Random.Range(20, 90));
}
AddData(0, data);
AddData(0, data, "legendName");
}
#endif

View File

@@ -158,6 +158,7 @@ namespace XCharts
rect.anchorMin = anchorMin;
rect.anchorMax = anchorMax;
rect.pivot = pivot;
rect.anchoredPosition3D = Vector3.zero;
return obj;
}
@@ -269,7 +270,6 @@ namespace XCharts
return labelObj;
}
public static void GetPointList(ref List<Vector3> posList, Vector3 sp, Vector3 ep, float k = 30f)
{
Vector3 dir = (ep - sp).normalized;
@@ -396,11 +396,30 @@ namespace XCharts
if (list1.Count != list2.Count) return false;
for (int i = 0; i < list1.Count; i++)
{
if (!list1[i].Equals(list2[i])) return false;
if (list1[i] == null && list2[i] == null) { }
else
{
if (list1[i] != null)
{
if (!list1[i].Equals(list2[i])) return false;
}
else
{
if (!list2[i].Equals(list1[i])) return false;
}
}
}
return true;
}
public static bool CopyList<T>(List<T> toList, List<T> fromList)
{
if (toList == null || fromList == null) return false;
toList.Clear();
foreach (var item in fromList) toList.Add(item);
return true;
}
public static List<float> ParseFloatFromString(string jsonData)
{
List<float> list = new List<float>();

View File

@@ -25,7 +25,7 @@ namespace XCharts
public class XChartsMgr : MonoBehaviour
{
public const string version = "1.2.0";
public const int date = 20200223;
public const int date = 20200226;
[SerializeField] private string m_NowVersion;
[SerializeField] private string m_NewVersion;

View File

@@ -67,6 +67,18 @@ namespace XChartsDemo
InitModuleButton();
}
void ResetParam()
{
var charts = transform.GetComponentsInChildren<BaseChart>();
foreach (var chart in charts)
{
chart.themeInfo.defaultLegendTextColor = ThemeInfo.GetColor("#514D4D");
chart.legend.itemWidth = 20f;
chart.legend.itemHeight = 10f;
chart.legend.textStyle.fontSize = 16;
}
}
void Update()
{
#if UNITY_EDITOR

File diff suppressed because it is too large Load Diff