From db36d6878829cfae404d92283015bc9f795d59ba Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Sat, 21 Dec 2019 20:12:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0`Tooltip`=E7=9A=84=E5=8D=95?= =?UTF-8?q?=E4=B8=AA=E6=95=B0=E6=8D=AE=E9=A1=B9=E5=92=8C=E6=A0=87=E9=A2=98?= =?UTF-8?q?=E7=9A=84=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=A8=A1=E7=89=88=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/XCharts/CHANGELOG.md | 1 + .../Documentation/XCharts配置项手册.md | 4 +- .../Editor/PropertyDrawers/TooltipDrawer.cs | 8 +- .../Runtime/Component/Main/DataZoom.cs | 5 + .../XCharts/Runtime/Component/Main/Tooltip.cs | 109 +++++++++++++++--- .../Runtime/Internal/CoordinateChart.cs | 2 +- Assets/XCharts/Runtime/PieChart.cs | 2 +- Assets/XCharts/Runtime/Utility/ChartHelper.cs | 1 + 8 files changed, 112 insertions(+), 20 deletions(-) diff --git a/Assets/XCharts/CHANGELOG.md b/Assets/XCharts/CHANGELOG.md index 6a61bcc2..bfe99043 100644 --- a/Assets/XCharts/CHANGELOG.md +++ b/Assets/XCharts/CHANGELOG.md @@ -1,6 +1,7 @@ # 更新日志 +* (2019.12.21) 增加`Tooltip`的单个数据项和标题的字符串模版格式器 * (2019.12.21) 增加`DataZoom`的最小显示数据个数`minShowNum` * (2019.12.20) 增加`Demo40_Radar.cs`雷达图代码操作`Demo` * (2019.12.20) 添加`RadarChart`相关API接口 diff --git a/Assets/XCharts/Documentation/XCharts配置项手册.md b/Assets/XCharts/Documentation/XCharts配置项手册.md index d621e404..5cb61093 100644 --- a/Assets/XCharts/Documentation/XCharts配置项手册.md +++ b/Assets/XCharts/Documentation/XCharts配置项手册.md @@ -175,11 +175,13 @@ * `Shadow`:阴影指示器。 * `None`:无指示器。 * `Corss`:十字准星指示器。坐标轴显示Label和交叉线。 -* `formatter`:提示框内容字符串模版格式器。支持用 `\n` 或 `
` 换行。其中变量 `{a}`, `{b}`, `{c}`, `{d}` 在不同图表类型下代表数据含义为: +* `formatter`:提示框内容字符串模版格式器。支持用 `\n` 或 `
` 换行。当`formatter`不为空时,优先使用`formatter`,否则使用`itemFormatter`。示例:`{a}:{c}`,`{a1}:{c1:f1}`。其中变量 `{a}`, `{b}`, `{c}`, `{d}` 在不同图表类型下代表数据含义为: * 折线(区域)图、柱状(条形)图、K线图 : `{a}`(系列名称),`{b}`(类目值),`{c}`(数值), `{d}`(无)。 * 散点图(气泡)图 : `{a}`(系列名称),`{b}`(数据名称),`{c}`(数值数组), `{d}`(无)。 * 地图 : `{a}`(系列名称),`{b}`(区域名称),`{c}`(合并数值), `{d}`(无)。 * 饼图、仪表盘、漏斗图: `{a}`(系列名称),`{b}`(数据项名称),`{c}`(数值), `{d}`(百分比)。 +* `titleFormatter`:提示框标题内容的字符串模版格式器。支持用 `\n` 或 `
` 换行。仅当`itemFormatter`生效时才有效。 +* `itemFormatter`:提示框单个`serie`或数据项内容的字符串模版格式器。支持用 `\n` 或 `
` 换行。当`formatter`不为空时,优先使用`formatter`,否则使用`itemFormatter`。 * `fixedWidth`:固定宽度。当同时设置 `fixedWidth` 和 `minWidth` 时,`fixedWidth` 比 `minWidth` 优先级高。 * `fixedHeight`:固定高度。当同时设置 `fixedHeight` 和 `minHeight` 时,`fixedHeight` 比 `minHeight` 优先级高。 * `minWidth`:最小宽度。当同时设置 `fixedWidth` 和 `minWidth` 时,`fixedWidth` 比 `minWidth` 优先级高。 diff --git a/Assets/XCharts/Editor/PropertyDrawers/TooltipDrawer.cs b/Assets/XCharts/Editor/PropertyDrawers/TooltipDrawer.cs index 707b72a9..8e0e5595 100644 --- a/Assets/XCharts/Editor/PropertyDrawers/TooltipDrawer.cs +++ b/Assets/XCharts/Editor/PropertyDrawers/TooltipDrawer.cs @@ -22,6 +22,8 @@ namespace XCharts SerializedProperty show = prop.FindPropertyRelative("m_Show"); SerializedProperty type = prop.FindPropertyRelative("m_Type"); SerializedProperty m_Formatter = prop.FindPropertyRelative("m_Formatter"); + SerializedProperty m_TitleFormatter = prop.FindPropertyRelative("m_TitleFormatter"); + SerializedProperty m_ItemFormatter = prop.FindPropertyRelative("m_ItemFormatter"); SerializedProperty m_FixedWidth = prop.FindPropertyRelative("m_FixedWidth"); SerializedProperty m_FixedHeight = prop.FindPropertyRelative("m_FixedHeight"); SerializedProperty m_MinWidth = prop.FindPropertyRelative("m_MinWidth"); @@ -38,6 +40,10 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_Formatter); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, m_TitleFormatter); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, m_ItemFormatter); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_FixedWidth); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_FixedHeight); @@ -58,7 +64,7 @@ namespace XCharts public override float GetPropertyHeight(SerializedProperty prop, GUIContent label) { if (m_TooltipModuleToggle) - return 10 * EditorGUIUtility.singleLineHeight + 9 * EditorGUIUtility.standardVerticalSpacing; + return 12 * EditorGUIUtility.singleLineHeight + 11 * EditorGUIUtility.standardVerticalSpacing; else return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; } diff --git a/Assets/XCharts/Runtime/Component/Main/DataZoom.cs b/Assets/XCharts/Runtime/Component/Main/DataZoom.cs index dfa5f33a..f89de927 100644 --- a/Assets/XCharts/Runtime/Component/Main/DataZoom.cs +++ b/Assets/XCharts/Runtime/Component/Main/DataZoom.cs @@ -80,6 +80,7 @@ namespace XCharts [SerializeField] private float m_End; [SerializeField] private float m_StartValue; [SerializeField] private float m_EndValue; + [SerializeField] private int m_MinShowNum = 1; [Range(1f, 20f)] [SerializeField] private float m_ScrollSensitivity = 1.1f; [SerializeField] private int m_FontSize = 18; @@ -187,6 +188,10 @@ namespace XCharts set { m_End = value; if (m_End < 0) m_End = 0; if (m_End > 100) m_End = 100; } } /// + /// 最小显示数据个数。当DataZoom放大到最大时,最小显示的数据个数。 + /// + public int minShowNum { get { return m_MinShowNum; } set { m_MinShowNum = value; } } + /// /// The sensitivity of dataZoom scroll. /// The larger the number, the more sensitive it is. /// default:10 diff --git a/Assets/XCharts/Runtime/Component/Main/Tooltip.cs b/Assets/XCharts/Runtime/Component/Main/Tooltip.cs index 0a0a7a69..5b778aa7 100644 --- a/Assets/XCharts/Runtime/Component/Main/Tooltip.cs +++ b/Assets/XCharts/Runtime/Component/Main/Tooltip.cs @@ -49,6 +49,8 @@ namespace XCharts [SerializeField] private bool m_Show; [SerializeField] private Type m_Type; [SerializeField] private string m_Formatter; + [SerializeField] private string m_ItemFormatter; + [SerializeField] private string m_TitleFormatter; [SerializeField] private float m_FixedWidth = 0; [SerializeField] private float m_FixedHeight = 0; [SerializeField] private float m_MinWidth = 0; @@ -75,7 +77,33 @@ namespace XCharts /// public Type type { get { return m_Type; } set { m_Type = value; } } /// - /// 提示框内容字符串模版格式器。支持用 \n 或 "
" 换行。 + /// 提示框总内容的字符串模版格式器。支持用 \n 或 "
" 换行。当formatter不为空时,优先使用formatter,否则使用itemFormatter。 + /// 模板变量有 {a}, {b},{c},{d},{e},分别表示系列名,数据名,数据值等。{a0},{b1},c{1}等可指定serie。 + /// 其中变量{a}, {b}, {c}, {d}在不同图表类型下代表数据含义为: + /// + /// 折线(区域)图、柱状(条形)图、K线图 : {a}(系列名称),{b}(类目值),{c}(数值), {d}(无)。 + /// 散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)。 + /// 地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)。 + /// 饼图、仪表盘、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)。 + /// + /// 示例:"{a}:{c}","{a1}:{c1:f1}" + ///
+ public string formatter { get { return m_Formatter; } set { m_Formatter = value; } } + /// + /// 提示框标题内容的字符串模版格式器。支持用 \n 或 "
" 换行。仅当itemFormatter生效时才有效。 + /// 模板变量有 {a}, {b},{c},{d},{e},分别表示系列名,数据名,数据值等。{a0},{b1},c{1}等可指定serie。 + /// 其中变量{a}, {b}, {c}, {d}在不同图表类型下代表数据含义为: + /// + /// 折线(区域)图、柱状(条形)图、K线图 : {a}(系列名称),{b}(类目值),{c}(数值), {d}(无)。 + /// 散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)。 + /// 地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)。 + /// 饼图、仪表盘、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)。 + /// + /// 示例:"{a}:{c}","{a1}:{c1:f1}" + ///
+ public string titleFormatter { get { return m_TitleFormatter; } set { m_TitleFormatter = value; } } + /// + /// 提示框单个serie或数据项内容的字符串模版格式器。支持用 \n 或 "
" 换行。当formatter不为空时,优先使用formatter,否则使用itemFormatter。 /// 模板变量有 {a}, {b},{c},{d},{e},分别表示系列名,数据名,数据值等。 /// 其中变量{a}, {b}, {c}, {d}在不同图表类型下代表数据含义为: /// @@ -84,11 +112,10 @@ namespace XCharts /// 地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)。 /// 饼图、仪表盘、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)。 /// + /// 示例:"{a}:{c}","{a}:{c:f1}" ///
- /// - /// 示例:“{a}:{c}” - /// - public string formatter { get { return m_Formatter; } set { m_Formatter = value; } } + public string itemFormatter { get { return m_ItemFormatter; } set { m_ItemFormatter = value; } } + /// /// 固定宽度。比 minWidth 优先。 /// @@ -341,11 +368,68 @@ namespace XCharts return runtimeDataIndex[0] == index || runtimeDataIndex[1] == index; } + public bool IsNoFormatter() + { + return string.IsNullOrEmpty(m_Formatter) && string.IsNullOrEmpty(m_ItemFormatter); + } + internal string GetFormatterContent(int dataIndex, Series series, string category, DataZoom dataZoom = null) { if (string.IsNullOrEmpty(m_Formatter)) { - return ""; + if (string.IsNullOrEmpty(m_ItemFormatter)) return ""; + else + { + var sb = ChartHelper.sb; + var title = m_TitleFormatter; + var formatTitle = !string.IsNullOrEmpty(title); + var needCategory = false; + var first = true; + sb.Length = 0; + for (int i = 0; i < series.Count; i++) + { + var serie = series.GetSerie(i); + var serieData = serie.GetSerieData(dataIndex, dataZoom); + var percent = serieData.GetData(1) / serie.yTotal * 100; + needCategory = needCategory || (serie.type == SerieType.Line || serie.type == SerieType.Bar); + if (serie.show) + { + string content = m_ItemFormatter; + content = content.Replace("{a}", serie.name); + content = content.Replace("{b}", needCategory ? category : serieData.name); + content = content.Replace("{c}", ChartCached.FloatToStr(serieData.GetData(1), 0, m_ForceENotation)); + content = content.Replace("{d}", ChartCached.FloatToStr(percent, 1)); + if (!first) sb.Append("\n"); + sb.Append(content); + first = false; + } + if (formatTitle) + { + if (i == 0) + { + title = title.Replace("{a}", serie.name); + title = title.Replace("{b}", needCategory ? category : serieData.name); + title = title.Replace("{c}", ChartCached.FloatToStr(serieData.GetData(1), 0, m_ForceENotation)); + title = title.Replace("{d}", ChartCached.FloatToStr(percent, 1)); + } + title = title.Replace("{a" + i + "}", serie.name); + title = title.Replace("{b" + i + "}", needCategory ? category : serieData.name); + title = title.Replace("{c" + i + "}", ChartCached.FloatToStr(serieData.GetData(1), 0, m_ForceENotation)); + title = title.Replace("{d" + i + "}", ChartCached.FloatToStr(percent, 1)); + } + } + if (string.IsNullOrEmpty(title)) + { + if (needCategory) return category + "\n" + sb.ToString(); + else return sb.ToString(); + } + else + { + title = title.Replace("\\n", "\n"); + title = title.Replace("
", "\n"); + return title + "\n" + sb.ToString(); + } + } } else { @@ -357,25 +441,18 @@ namespace XCharts { var needCategory = serie.type == SerieType.Line || serie.type == SerieType.Bar; var serieData = serie.GetSerieData(dataIndex, dataZoom); + var percent = serieData.GetData(1) / serie.yTotal * 100; if (i == 0) { content = content.Replace("{a}", serie.name); content = content.Replace("{b}", needCategory ? category : serieData.name); content = content.Replace("{c}", ChartCached.FloatToStr(serieData.GetData(1), 0, m_ForceENotation)); - //if (serie.type == SerieType.Pie) - { - var percent = serieData.GetData(1) / serie.yTotal * 100; - content = content.Replace("{d}", ChartCached.FloatToStr(percent, 1)); - } + content = content.Replace("{d}", ChartCached.FloatToStr(percent, 1)); } content = content.Replace("{a" + i + "}", serie.name); content = content.Replace("{b" + i + "}", needCategory ? category : serieData.name); content = content.Replace("{c" + i + "}", ChartCached.FloatToStr(serieData.GetData(1), 0, m_ForceENotation)); - //if (serie.type == SerieType.Pie) - { - var percent = serieData.GetData(1) / serie.yTotal * 100; - content = content.Replace("{d" + i + "}", ChartCached.FloatToStr(percent, 1)); - } + content = content.Replace("{d" + i + "}", ChartCached.FloatToStr(percent, 1)); } } content = content.Replace("\\n", "\n"); diff --git a/Assets/XCharts/Runtime/Internal/CoordinateChart.cs b/Assets/XCharts/Runtime/Internal/CoordinateChart.cs index a0666bcc..6462128b 100644 --- a/Assets/XCharts/Runtime/Internal/CoordinateChart.cs +++ b/Assets/XCharts/Runtime/Internal/CoordinateChart.cs @@ -300,7 +300,7 @@ namespace XCharts return; } - if (string.IsNullOrEmpty(tooltip.formatter)) + if (tooltip.IsNoFormatter()) { sb.Length = 0; if (!isCartesian) diff --git a/Assets/XCharts/Runtime/PieChart.cs b/Assets/XCharts/Runtime/PieChart.cs index 60851616..2f958f74 100644 --- a/Assets/XCharts/Runtime/PieChart.cs +++ b/Assets/XCharts/Runtime/PieChart.cs @@ -579,7 +579,7 @@ namespace XCharts int index = m_Tooltip.runtimeDataIndex[serie.index]; if (index < 0) continue; showTooltip = true; - if (string.IsNullOrEmpty(tooltip.formatter)) + if (tooltip.IsNoFormatter()) { string key = serie.data[index].name; if (string.IsNullOrEmpty(key)) key = m_Legend.GetData(index); diff --git a/Assets/XCharts/Runtime/Utility/ChartHelper.cs b/Assets/XCharts/Runtime/Utility/ChartHelper.cs index 0e791c45..8b8fb886 100644 --- a/Assets/XCharts/Runtime/Utility/ChartHelper.cs +++ b/Assets/XCharts/Runtime/Utility/ChartHelper.cs @@ -22,6 +22,7 @@ namespace XCharts { private static StringBuilder s_Builder = new StringBuilder(); + public static StringBuilder sb { get { return s_Builder; } } public static string Cancat(string str1, string str2) { s_Builder.Length = 0;