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;