diff --git a/Assets/XCharts/CHANGELOG.md b/Assets/XCharts/CHANGELOG.md index 60472e62..ba2dd34f 100644 --- a/Assets/XCharts/CHANGELOG.md +++ b/Assets/XCharts/CHANGELOG.md @@ -1,6 +1,7 @@ # 更新日志 +* (2020.04.28) 增加`numericFormatter`参数可配置数值格式化显示,去掉`forceENotation`参数 * (2020.04.28) 增加`自由锚点`支持,任意对齐方式 * (2020.04.23) 优化`ScatterChart`的`Tooltip`显示效果 * (2020.04.23) 增加`Tooltip`的`formatter`对`{.}`、`{c:0}`、`{c1:1}`的支持 diff --git a/Assets/XCharts/Documentation/XCharts配置项手册.md b/Assets/XCharts/Documentation/XCharts配置项手册.md index 417064f7..5abcc049 100644 --- a/Assets/XCharts/Documentation/XCharts配置项手册.md +++ b/Assets/XCharts/Documentation/XCharts配置项手册.md @@ -190,13 +190,14 @@ * `Shadow`:阴影指示器。 * `None`:无指示器。 * `Corss`:十字准星指示器。坐标轴显示Label和交叉线。 -* `formatter`:提示框内容字符串模版格式器。支持用 `\n` 或 `
` 换行。当`formatter`不为空时,优先使用`formatter`,否则使用`itemFormatter`。示例:`{a}:{c}`,`{a1}:{c1:f1}`。其中`{.}`表示带动态颜色的圆点;`{c:0}`、`{c1:1}`表示索引为0、1的serie的数据项的第0、第1个数据;其它变量 `{a}`, `{b}`, `{c}`, `{d}` 在不同图表类型下代表数据含义为: +* `formatter`:提示框内容字符串模版格式器。支持用 `\n` 或 `
` 换行。当`formatter`不为空时,优先使用`formatter`,否则使用`itemFormatter`。示例:`{a}:{c}`,`{a1}:{c1}`。其中`{.}`表示带动态颜色的圆点;`{c:0}`、`{c1:1}`表示索引为0、1的serie的数据项的第0、第1个数据;其它变量 `{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`。 +* `numericFormatter`:标准数字格式字符串。用于将数值格式化显示为字符串。使用`Axx`的形式:`A`是格式说明符的单字符,支持`C`货币、`D`十进制、`E`指数、`F`顶点数、`G`常规、`N`数字、`P`百分比、`R`往返过程、`X`十六进制等九种。`xx`是精度说明,从`0`-`99`。 * `fixedWidth`:固定宽度。当同时设置 `fixedWidth` 和 `minWidth` 时,`fixedWidth` 比 `minWidth` 优先级高。 * `fixedHeight`:固定高度。当同时设置 `fixedHeight` 和 `minHeight` 时,`fixedHeight` 比 `minHeight` 优先级高。 * `minWidth`:最小宽度。当同时设置 `fixedWidth` 和 `minWidth` 时,`fixedWidth` 比 `minWidth` 优先级高。 @@ -204,7 +205,6 @@ * `paddingLeftRight`:文字和边框的左右边距。 * `paddingTopBottom`:文字和边框的上下边距。 * `backgroundImage`:提示框的背景图。 -* `forceENotation`:是否强制使用科学计数法格式化显示数值。默认为false,当小数精度大于3时才采用科学计数法。 * `ignoreDataDefaultContent`:被忽略数据的默认显示字符信息。 * `lineStyle`:指示器线条样式 [LineStyle](#LineStyle)。 * `textStyle`:显示内容文本样式 [TextStyle](#TextStyle)。 @@ -682,8 +682,8 @@ * `color`:刻度标签文字的颜色,默认取主题Theme的axisTextColor。 * `fontSize`:文字的字体大小。 * `fontStyle`:文字字体的风格。 -* `formatter`:图例内容字符串模版格式器。支持用 \n 换行。模板变量为图例名称 {value},支持{value:f0},{value:f1},{value:f2}。 -* `forceENotation`:是否强制使用科学计数法格式化显示数值。默认为false,当小数精度大于3时才采用科学计数法。 +* `formatter`:图例内容字符串模版格式器。支持用 \n 换行。模板变量为图例名称 {value},数值格式化通过`numericFormatter`。 +* `numericFormatter`:标准数字格式字符串。用于将数值格式化显示为字符串。使用`Axx`的形式:`A`是格式说明符的单字符,支持`C`货币、`D`十进制、`E`指数、`F`顶点数、`G`常规、`N`数字、`P`百分比、`R`往返过程、`X`十六进制等九种。`xx`是精度说明,从`0`-`99`。 * `showAsPositiveNumber`:将负数数值显示为正数。一般和`Serie`的`showAsPositiveNumber`配合使用。 * `onZero`:刻度标签显示在0刻度上。 * `textLimit`:文本自适应 [TextLimit](#TextLimit)。只在类目轴中有效。 @@ -751,6 +751,7 @@ * `borderWidth`:边框宽。 * `opacity`:透明度。 * `tooltipFormatter`:提示框单项的字符串模版格式器。具体配置参考`Tooltip`的`formatter`。 +* `numericFormatter`:标准数字格式字符串。用于将数值格式化显示为字符串。使用`Axx`的形式:`A`是格式说明符的单字符,支持`C`货币、`D`十进制、`E`指数、`F`顶点数、`G`常规、`N`数字、`P`百分比、`R`往返过程、`X`十六进制等九种。`xx`是精度说明,从`0`-`99`。此字段优先于`SerieLabel`和`Tooltip`的`numericFormatter`。 * `cornerRadius`:圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。 ## `LineArrow` @@ -816,7 +817,8 @@ * `Center`:在中心位置(折线图,柱状图,饼图)。 * `Top`:顶部(柱状图)。 * `Bottom`:底部(柱状图)。 -* `formatter`:标签内容字符串模版格式器。支持用 `\n` 换行。模板变量有:`{a}`:系列名;`{b}`:数据名;`{c}`:数据值;`{d}`:百分比。示例:`{b}:{c:f1}`。 +* `formatter`:标签内容字符串模版格式器。支持用 `\n` 换行。模板变量有:`{a}`:系列名;`{b}`:数据名;`{c}`:数据值;`{d}`:百分比。示例:`{b}:{c}`。 +* `numericFormatter`:标准数字格式字符串。用于将数值格式化显示为字符串。使用`Axx`的形式:`A`是格式说明符的单字符,支持`C`货币、`D`十进制、`E`指数、`F`顶点数、`G`常规、`N`数字、`P`百分比、`R`往返过程、`X`十六进制等九种。`xx`是精度说明,从`0`-`99`。 * `offset`:距离图形元素的偏移。 * `color`:自定义文字颜色,默认和系列的颜色一致。 * `backgroundColor`:标签的背景色,默认无颜色。 @@ -839,7 +841,6 @@ * `border`:是否显示边框。 * `borderWidth`:边框宽度。 * `borderColor`:边框颜色。 -* `forceENotation`:是否强制使用科学计数法格式化显示数值。默认为false,当小数精度大于3时才采用科学计数法。 ## `SerieSymbol` diff --git a/Assets/XCharts/Editor/PropertyDrawers/AxisLabelDrawer.cs b/Assets/XCharts/Editor/PropertyDrawers/AxisLabelDrawer.cs index f1745f16..017325ce 100644 --- a/Assets/XCharts/Editor/PropertyDrawers/AxisLabelDrawer.cs +++ b/Assets/XCharts/Editor/PropertyDrawers/AxisLabelDrawer.cs @@ -29,7 +29,7 @@ namespace XCharts SerializedProperty m_Color = prop.FindPropertyRelative("m_Color"); SerializedProperty m_FontSize = prop.FindPropertyRelative("m_FontSize"); SerializedProperty m_FontStyle = prop.FindPropertyRelative("m_FontStyle"); - SerializedProperty m_ForceENotation = prop.FindPropertyRelative("m_ForceENotation"); + SerializedProperty m_NumericFormatter = prop.FindPropertyRelative("m_NumericFormatter"); SerializedProperty m_ShowAsPositiveNumber = prop.FindPropertyRelative("m_ShowAsPositiveNumber"); SerializedProperty m_OnZero = prop.FindPropertyRelative("m_OnZero"); SerializedProperty m_TextLimit = prop.FindPropertyRelative("m_TextLimit"); @@ -57,7 +57,7 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_Formatter); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - EditorGUI.PropertyField(drawRect, m_ForceENotation); + EditorGUI.PropertyField(drawRect, m_NumericFormatter); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_ShowAsPositiveNumber); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; diff --git a/Assets/XCharts/Editor/PropertyDrawers/ItemStyleDrawer.cs b/Assets/XCharts/Editor/PropertyDrawers/ItemStyleDrawer.cs index 8fe7ae34..d2c4c9d9 100644 --- a/Assets/XCharts/Editor/PropertyDrawers/ItemStyleDrawer.cs +++ b/Assets/XCharts/Editor/PropertyDrawers/ItemStyleDrawer.cs @@ -34,6 +34,7 @@ namespace XCharts SerializedProperty m_BorderColor = prop.FindPropertyRelative("m_BorderColor"); SerializedProperty m_Opacity = prop.FindPropertyRelative("m_Opacity"); SerializedProperty m_TooltipFormatter = prop.FindPropertyRelative("m_TooltipFormatter"); + SerializedProperty m_NumericFormatter = prop.FindPropertyRelative("m_NumericFormatter"); SerializedProperty m_CornerRadius = prop.FindPropertyRelative("m_CornerRadius"); ChartEditorHelper.MakeFoldout(ref drawRect, ref m_ItemStyleToggle, prop, "Item Style", show, false); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; @@ -62,6 +63,8 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_TooltipFormatter); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, m_NumericFormatter); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; ChartEditorHelper.MakeFoldout(ref drawRect, ref m_CornerRadiusToggle, m_CornerRadius, "Corner Radius", null, false); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; if (ChartEditorHelper.IsToggle(m_CornerRadiusToggle, m_CornerRadius)) @@ -77,7 +80,7 @@ namespace XCharts float height = 0; if (ChartEditorHelper.IsToggle(m_ItemStyleToggle, prop)) { - height += 13 * EditorGUIUtility.singleLineHeight + 12 * EditorGUIUtility.standardVerticalSpacing; + height += 14 * EditorGUIUtility.singleLineHeight + 13 * EditorGUIUtility.standardVerticalSpacing; var m_CornerRadius = prop.FindPropertyRelative("m_CornerRadius"); if (ChartEditorHelper.IsToggle(m_CornerRadiusToggle, m_CornerRadius)) { diff --git a/Assets/XCharts/Editor/PropertyDrawers/SerieLabelDrawer.cs b/Assets/XCharts/Editor/PropertyDrawers/SerieLabelDrawer.cs index 608a115e..ea03ed8e 100644 --- a/Assets/XCharts/Editor/PropertyDrawers/SerieLabelDrawer.cs +++ b/Assets/XCharts/Editor/PropertyDrawers/SerieLabelDrawer.cs @@ -43,7 +43,7 @@ namespace XCharts SerializedProperty m_Border = prop.FindPropertyRelative("m_Border"); SerializedProperty m_BorderWidth = prop.FindPropertyRelative("m_BorderWidth"); SerializedProperty m_BorderColor = prop.FindPropertyRelative("m_BorderColor"); - SerializedProperty m_ForceENotation = prop.FindPropertyRelative("m_ForceENotation"); + SerializedProperty m_NumericFormatter = prop.FindPropertyRelative("m_NumericFormatter"); ChartEditorHelper.MakeFoldout(ref drawRect, ref m_SerieLabelToggle, prop, null, show, false); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; @@ -60,7 +60,8 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_Formatter); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - + EditorGUI.PropertyField(drawRect, m_NumericFormatter); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_Color); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_BackgroundColor); @@ -97,8 +98,6 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_LineLength2); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - EditorGUI.PropertyField(drawRect, m_ForceENotation); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; --EditorGUI.indentLevel; } } diff --git a/Assets/XCharts/Editor/PropertyDrawers/TooltipDrawer.cs b/Assets/XCharts/Editor/PropertyDrawers/TooltipDrawer.cs index c3a7c47f..f3409ee7 100644 --- a/Assets/XCharts/Editor/PropertyDrawers/TooltipDrawer.cs +++ b/Assets/XCharts/Editor/PropertyDrawers/TooltipDrawer.cs @@ -28,7 +28,7 @@ namespace XCharts SerializedProperty m_FixedHeight = prop.FindPropertyRelative("m_FixedHeight"); SerializedProperty m_MinWidth = prop.FindPropertyRelative("m_MinWidth"); SerializedProperty m_MinHeight = prop.FindPropertyRelative("m_MinHeight"); - SerializedProperty m_ForceENotation = prop.FindPropertyRelative("m_ForceENotation"); + SerializedProperty m_NumericFormatter = prop.FindPropertyRelative("m_NumericFormatter"); SerializedProperty m_PaddingLeftRight = prop.FindPropertyRelative("m_PaddingLeftRight"); SerializedProperty m_PaddingTopBottom = prop.FindPropertyRelative("m_PaddingTopBottom"); SerializedProperty m_BackgroundImage = prop.FindPropertyRelative("m_BackgroundImage"); @@ -49,6 +49,8 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_ItemFormatter); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, m_NumericFormatter); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_FixedWidth); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_FixedHeight); @@ -63,8 +65,6 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_BackgroundImage); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - EditorGUI.PropertyField(drawRect, m_ForceENotation); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_IgnoreDataDefaultContent); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_LineStyle); diff --git a/Assets/XCharts/Runtime/Component/Main/Tooltip.cs b/Assets/XCharts/Runtime/Component/Main/Tooltip.cs index dd77133e..d7ce1cf8 100644 --- a/Assets/XCharts/Runtime/Component/Main/Tooltip.cs +++ b/Assets/XCharts/Runtime/Component/Main/Tooltip.cs @@ -59,7 +59,7 @@ namespace XCharts [SerializeField] private float m_FixedHeight = 0; [SerializeField] private float m_MinWidth = 0; [SerializeField] private float m_MinHeight = 0; - [SerializeField] private bool m_ForceENotation = false; + [SerializeField] private string m_NumericFormatter = ""; [SerializeField] private float m_PaddingLeftRight = 5f; [SerializeField] private float m_PaddingTopBottom = 5f; [SerializeField] private string m_IgnoreDataDefaultContent = "-"; @@ -156,9 +156,17 @@ namespace XCharts [Obsolete("Use Tooltip.textStyle.fontStyle instead.", true)] public FontStyle fontStyle { get; set; } /// - /// 是否强制使用科学计数法格式化显示数值。默认为false,当小数精度大于3时才采用科学计数法。 + /// Standard numeric format strings. + /// 标准数字格式字符串。用于将数值格式化显示为字符串。 + /// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 + /// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings /// - public bool forceENotation { get { return m_ForceENotation; } set { m_ForceENotation = value; } } + /// + public string numericFormatter + { + get { return m_NumericFormatter; } + set { if (PropertyUtility.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); } + } /// /// the text padding of left and right. defaut:5. /// 左右边距。 @@ -483,7 +491,5 @@ namespace XCharts } return false; } - - } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Sub/AxisLabel.cs b/Assets/XCharts/Runtime/Component/Sub/AxisLabel.cs index e96a7888..260f5cde 100644 --- a/Assets/XCharts/Runtime/Component/Sub/AxisLabel.cs +++ b/Assets/XCharts/Runtime/Component/Sub/AxisLabel.cs @@ -27,7 +27,7 @@ namespace XCharts [SerializeField] private Color m_Color; [SerializeField] private int m_FontSize; [SerializeField] private FontStyle m_FontStyle; - [SerializeField] private bool m_ForceENotation = false; + [SerializeField] private string m_NumericFormatter = ""; [SerializeField] private bool m_ShowAsPositiveNumber = false; [SerializeField] private bool m_OnZero = false; [SerializeField] private TextLimit m_TextLimit = new TextLimit(); @@ -106,20 +106,25 @@ namespace XCharts } /// /// 图例内容字符串模版格式器。支持用 \n 换行。 - /// 模板变量为图例名称 {value},支持{value:f0},{value:f1},{value:f2} + /// 模板变量为图例名称 {value}。 /// public string formatter { get { return m_Formatter; } set { if (PropertyUtility.SetClass(ref m_Formatter, value)) SetComponentDirty(); } } + /// - /// 是否强制使用科学计数法格式化显示数值。默认为false,当小数精度大于3时才采用科学计数法。 + /// Standard numeric format strings. + /// 标准数字格式字符串。用于将数值格式化显示为字符串。 + /// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 + /// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings /// - public bool forceENotation + /// + public string numericFormatter { - get { return m_ForceENotation; } - set { if (PropertyUtility.SetStruct(ref m_ForceENotation, value)) SetComponentDirty(); } + get { return m_NumericFormatter; } + set { if (PropertyUtility.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); } } /// @@ -186,7 +191,7 @@ namespace XCharts axisLable.margin = margin; axisLable.color = color; axisLable.fontSize = fontSize; - axisLable.forceENotation = forceENotation; + axisLable.numericFormatter = numericFormatter; axisLable.textLimit = textLimit.Clone(); return axisLable; } @@ -201,7 +206,7 @@ namespace XCharts margin = axisLable.margin; color = axisLable.color; fontSize = axisLable.fontSize; - forceENotation = axisLable.forceENotation; + numericFormatter = axisLable.numericFormatter; textLimit.Copy(axisLable.textLimit); } @@ -236,10 +241,7 @@ namespace XCharts { if (isLog) { - if (value - (int)value == 0) - return ChartCached.IntToStr((int)value); - else - return ChartCached.FloatToStr(value); + return ChartCached.NumberToStr(value, numericFormatter); } if (minValue >= -1 && minValue <= 1 && maxValue >= -1 && maxValue <= 1) { @@ -247,12 +249,9 @@ namespace XCharts int maxAcc = ChartHelper.GetFloatAccuracy(maxValue); int curAcc = ChartHelper.GetFloatAccuracy(value); int acc = Mathf.Max(Mathf.Max(minAcc, maxAcc), curAcc); - return ChartCached.FloatToStr(value, acc, m_ForceENotation); + return ChartCached.FloatToStr(value, numericFormatter, acc); } - else if (value - (int)value == 0) - return ChartCached.IntToStr((int)value); - else - return ChartCached.FloatToStr(value, 1); + return ChartCached.NumberToStr(value, numericFormatter); } else if (m_Formatter.Contains("{value")) { @@ -260,15 +259,15 @@ namespace XCharts if (content.Contains("{value:f0}")) content = m_Formatter.Replace("{value:f0}", ChartCached.IntToStr((int)value)); if (content.Contains("{value:f2}")) - content = m_Formatter.Replace("{value:f2}", ChartCached.FloatToStr(value, 2)); + content = m_Formatter.Replace("{value:f2}", ChartCached.FloatToStr(value, string.Empty, 2)); else if (content.Contains("{value:f1}")) - content = m_Formatter.Replace("{value:f1}", ChartCached.FloatToStr(value, 1)); + content = m_Formatter.Replace("{value:f1}", ChartCached.FloatToStr(value, string.Empty, 1)); else if (content.Contains("{value}")) { if (value - (int)value == 0) content = m_Formatter.Replace("{value}", ChartCached.IntToStr((int)value)); else - content = m_Formatter.Replace("{value}", ChartCached.FloatToStr(value, 1)); + content = m_Formatter.Replace("{value}", ChartCached.FloatToStr(value, string.Empty, 1)); } content = content.Replace("\\n", "\n"); diff --git a/Assets/XCharts/Runtime/Component/Sub/ItemStyle.cs b/Assets/XCharts/Runtime/Component/Sub/ItemStyle.cs index 180f1888..cd0a8cf2 100644 --- a/Assets/XCharts/Runtime/Component/Sub/ItemStyle.cs +++ b/Assets/XCharts/Runtime/Component/Sub/ItemStyle.cs @@ -47,6 +47,7 @@ namespace XCharts [SerializeField] private Color m_BorderColor; [SerializeField] [Range(0, 1)] private float m_Opacity = 1; [SerializeField] private string m_TooltipFormatter; + [SerializeField] private string m_NumericFormatter = ""; [SerializeField] private float[] m_CornerRadius = new float[] { 0, 0, 0, 0 }; /// @@ -147,6 +148,18 @@ namespace XCharts set { if (PropertyUtility.SetClass(ref m_TooltipFormatter, value)) SetVerticesDirty(); } } /// + /// Standard numeric format strings. + /// 标准数字格式字符串。用于将数值格式化显示为字符串。 + /// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 + /// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings + /// + /// + public string numericFormatter + { + get { return m_NumericFormatter; } + set { if (PropertyUtility.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); } + } + /// /// The radius of rounded corner. Its unit is px. Use array to respectively specify the 4 corner radiuses((clockwise upper left, upper right, bottom right and bottom left)). /// 圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。 /// diff --git a/Assets/XCharts/Runtime/Component/Sub/SerieLabel.cs b/Assets/XCharts/Runtime/Component/Sub/SerieLabel.cs index fc870126..0b9e70ae 100644 --- a/Assets/XCharts/Runtime/Component/Sub/SerieLabel.cs +++ b/Assets/XCharts/Runtime/Component/Sub/SerieLabel.cs @@ -101,7 +101,7 @@ namespace XCharts [SerializeField] private bool m_Border = false; [SerializeField] private float m_BorderWidth = 0.5f; [SerializeField] private Color m_BorderColor = Color.grey; - [SerializeField] private bool m_ForceENotation = false; + [SerializeField] private string m_NumericFormatter = ""; /// /// Whether the label is showed. @@ -321,38 +321,16 @@ namespace XCharts set { if (PropertyUtility.SetStruct(ref m_BorderColor, value)) SetVerticesDirty(); } } /// - /// 是否强制使用科学计数法格式化显示数值。默认为false,当小数精度大于3时才采用科学计数法。 + /// Standard numeric format strings. + /// 标准数字格式字符串。用于将数值格式化显示为字符串。 + /// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 + /// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings /// - public bool forceENotation + /// + public string numericFormatter { - get { return m_ForceENotation; } - set { if (PropertyUtility.SetStruct(ref m_ForceENotation, value)) SetVerticesDirty(); } - } - - public string GetFormatterContent(string serieName, string dataName, float dataValue, float dataTotal = 0) - { - if (string.IsNullOrEmpty(m_Formatter)) - return ChartCached.FloatToStr(dataValue, 0, m_ForceENotation); - else - { - var content = m_Formatter.Replace("{a}", serieName); - content = content.Replace("{b}", dataName); - content = content.Replace("{c}", ChartCached.FloatToStr(dataValue, 0, m_ForceENotation)); - content = content.Replace("{c:f0}", ChartCached.IntToStr((int)Mathf.Round(dataValue))); - content = content.Replace("{c:f1}", ChartCached.FloatToStr(dataValue, 1)); - content = content.Replace("{c:f2}", ChartCached.FloatToStr(dataValue, 2)); - if (dataTotal > 0) - { - var percent = dataValue / dataTotal * 100; - content = content.Replace("{d}", ChartCached.FloatToStr(percent, 1)); - content = content.Replace("{d:f0}", ChartCached.IntToStr((int)Mathf.Round(percent))); - content = content.Replace("{d:f1}", ChartCached.FloatToStr(percent, 1)); - content = content.Replace("{d:f2}", ChartCached.FloatToStr(percent, 2)); - } - content = content.Replace("\\n", "\n"); - content = content.Replace("
", "\n"); - return content; - } + get { return m_NumericFormatter; } + set { if (PropertyUtility.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); } } } } diff --git a/Assets/XCharts/Runtime/GaugeChart.cs b/Assets/XCharts/Runtime/GaugeChart.cs index 074cf8b8..5b236136 100644 --- a/Assets/XCharts/Runtime/GaugeChart.cs +++ b/Assets/XCharts/Runtime/GaugeChart.cs @@ -316,7 +316,6 @@ namespace XCharts var diffValue = totalValue / count; var radius = serie.runtimeInsideRadius - serie.gaugeAxis.axisLabel.margin; var serieData = serie.GetSerieData(0); - var dataName = serieData != null ? serieData.name : null; var customLabelText = serie.gaugeAxis.axisLabelText; for (int j = 0; j <= count; j++) { @@ -324,7 +323,7 @@ namespace XCharts var value = serie.min + j * diffValue; var pos = ChartHelper.GetPosition(serie.runtimeCenterPos, angle, radius); var text = customLabelText != null && j < customLabelText.Count ? customLabelText[j] : - serie.gaugeAxis.axisLabel.GetFormatterContent(serie.name, dataName, value, totalValue); + SerieLabelHelper.GetFormatterContent(serie, serieData, value, totalValue, serie.gaugeAxis.axisLabel); serie.gaugeAxis.SetLabelObjectText(j, text); serie.gaugeAxis.SetLabelObjectPosition(j, pos); } diff --git a/Assets/XCharts/Runtime/HeatmapChart.cs b/Assets/XCharts/Runtime/HeatmapChart.cs index c2ed085e..c3c0a815 100644 --- a/Assets/XCharts/Runtime/HeatmapChart.cs +++ b/Assets/XCharts/Runtime/HeatmapChart.cs @@ -111,11 +111,11 @@ namespace XCharts .Append(key).Append(!string.IsNullOrEmpty(key) ? "\n" : "") .Append("● ") .Append(xAxis.data[(int)xData]).Append(": ") - .Append(ChartCached.FloatToStr(value)); + .Append(ChartCached.FloatToStr(value, string.Empty)); } } } - TooltipHelper.SetContentAndPosition(tooltip,sb.ToString().Trim(),chartRect); + TooltipHelper.SetContentAndPosition(tooltip, sb.ToString().Trim(), chartRect); m_Tooltip.SetActive(true); for (int i = 0; i < m_XAxises.Count; i++) diff --git a/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs b/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs index 8625b112..d5800864 100644 --- a/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs +++ b/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs @@ -70,8 +70,6 @@ namespace XCharts } } - - public static void ResetLabel(SerieData serieData, SerieLabel label, ThemeInfo themeInfo, int colorIndex) { if (serieData.labelText) @@ -83,6 +81,47 @@ namespace XCharts } } + public static string GetFormatterContent(Serie serie, SerieData serieData, + float dataValue, float dataTotal, SerieLabel serieLabel = null) + { + if (serieLabel == null) + { + serieLabel = SerieHelper.GetSerieLabel(serie, serieData); + } + var numericFormatter = GetLabelNumericFormatter(serie, serieData); + var serieName = serie.name; + var dataName = serieData != null ? serieData.name : null; + if (string.IsNullOrEmpty(serieLabel.formatter)) + return ChartCached.NumberToStr(dataValue, numericFormatter); + else + { + var content = serieLabel.formatter.Replace("{a}", serieName); + content = content.Replace("{b}", dataName); + content = content.Replace("{c}", ChartCached.NumberToStr(dataValue, numericFormatter)); + content = content.Replace("{c:f0}", ChartCached.IntToStr((int)Mathf.Round(dataValue))); + content = content.Replace("{c:f1}", ChartCached.FloatToStr(dataValue, string.Empty, 1)); + content = content.Replace("{c:f2}", ChartCached.FloatToStr(dataValue, string.Empty, 2)); + if (dataTotal > 0) + { + var percent = dataValue / dataTotal * 100; + content = content.Replace("{d}", ChartCached.NumberToStr(percent, numericFormatter)); + content = content.Replace("{d:f0}", ChartCached.IntToStr((int)Mathf.Round(percent))); + content = content.Replace("{d:f1}", ChartCached.FloatToStr(percent, string.Empty, 1)); + content = content.Replace("{d:f2}", ChartCached.FloatToStr(percent, string.Empty, 2)); + } + content = content.Replace("\\n", "\n"); + content = content.Replace("
", "\n"); + return content; + } + } + + private static string GetLabelNumericFormatter(Serie serie, SerieData serieData) + { + var itemStyle = SerieHelper.GetItemStyle(serie, serieData); + if (!string.IsNullOrEmpty(itemStyle.numericFormatter)) return itemStyle.numericFormatter; + else return serie.label.numericFormatter; + } + private static void SetGaugeLabelText(Serie serie) { @@ -93,7 +132,7 @@ namespace XCharts { var value = serieData.GetData(1); var total = serie.max; - var content = serie.label.GetFormatterContent(serie.name, serieData.name, value, total); + var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total); serieData.SetLabelText(content); serieData.SetLabelPosition(serie.runtimeCenterPos + serie.label.offset); if (serie.label.color != Color.clear) @@ -109,7 +148,7 @@ namespace XCharts for (int i = 0; i < serie.dataCount; i++) { var serieData = serie.data[i]; - var serieLabel = SerieHelper.GetSerieLabel(serie,serieData,serieData.highlighted); + var serieLabel = SerieHelper.GetSerieLabel(serie, serieData, serieData.highlighted); if (serieLabel.show && serieData.IsInitLabel()) { if (!serie.show || !serieData.show) @@ -119,7 +158,7 @@ namespace XCharts } var value = serieData.GetData(0); var total = serieData.GetData(1); - var content = serie.label.GetFormatterContent(serie.name, serieData.name, value, total); + var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total); serieData.SetLabelActive(true); serieData.SetLabelText(content); serieData.SetLabelColor(GetLabelColor(serie, themeInfo, i)); diff --git a/Assets/XCharts/Runtime/Helper/TooltipHelper.cs b/Assets/XCharts/Runtime/Helper/TooltipHelper.cs index 0426fb35..9c7bd851 100644 --- a/Assets/XCharts/Runtime/Helper/TooltipHelper.cs +++ b/Assets/XCharts/Runtime/Helper/TooltipHelper.cs @@ -41,14 +41,15 @@ namespace XCharts { var dataIndex = dataIndexList[i]; var serieData = serie.GetSerieData(dataIndex); + var numericFormatter = GetItemNumericFormatter(tooltip, serie, serieData); float xValue, yValue; serie.GetXYData(dataIndex, null, out xValue, out yValue); sb.Append("● "); if (!string.IsNullOrEmpty(serieData.name)) sb.Append(serieData.name).Append(": "); - sb.AppendFormat("({0},{1})", ChartCached.FloatToStr(xValue, 0, tooltip.forceENotation), - ChartCached.FloatToStr(yValue, 0, tooltip.forceENotation)); + sb.AppendFormat("({0},{1})", ChartCached.FloatToStr(xValue, numericFormatter), + ChartCached.FloatToStr(yValue, numericFormatter)); if (i != dataIndexList.Count - 1) { sb.Append("\n"); @@ -61,8 +62,10 @@ namespace XCharts ThemeInfo themeInfo) { string key = serie.data[index].name; + var serieData = serie.GetSerieData(index); + var numericFormatter = GetItemNumericFormatter(tooltip, serie, serieData); - float value = serie.data[index].data[1]; + float value = serieData.GetData(1); sb.Length = 0; if (!string.IsNullOrEmpty(serie.name)) { @@ -71,23 +74,24 @@ namespace XCharts sb.Append("● "); if (!string.IsNullOrEmpty(key)) sb.Append(key).Append(": "); - sb.Append(ChartCached.FloatToStr(value, 0, tooltip.forceENotation)); + sb.Append(ChartCached.FloatToStr(value, numericFormatter)); } private static void InitRingTooltip(ref StringBuilder sb, Tooltip tooltip, Serie serie, int index, ThemeInfo themeInfo) { var serieData = serie.GetSerieData(index); + var numericFormatter = GetItemNumericFormatter(tooltip, serie, serieData); float value = serieData.GetFirstData(); sb.Length = 0; if (!string.IsNullOrEmpty(serieData.name)) { sb.Append("● ") - .Append(serieData.name).Append(": ").Append(ChartCached.FloatToStr(value, 0, tooltip.forceENotation)); + .Append(serieData.name).Append(": ").Append(ChartCached.FloatToStr(value, numericFormatter)); } else { - sb.Append(ChartCached.FloatToStr(value, 0, tooltip.forceENotation)); + sb.Append(ChartCached.FloatToStr(value, numericFormatter)); } } @@ -96,6 +100,7 @@ namespace XCharts { var dataIndex = tooltip.runtimeDataIndex[1]; var serieData = serie.GetSerieData(dataIndex); + var numericFormatter = GetItemNumericFormatter(tooltip, serie, serieData); switch (serie.radarType) { case RadarType.Multiple: @@ -105,7 +110,7 @@ namespace XCharts string key = radar.indicatorList[i].name; float value = serieData.GetData(i); if ((i == 0 && !string.IsNullOrEmpty(serieData.name)) || i > 0) sb.Append(PH_NN); - sb.AppendFormat("{0}: {1}", key, ChartCached.FloatToStr(value, 0, tooltip.forceENotation)); + sb.AppendFormat("{0}: {1}", key, ChartCached.FloatToStr(value, numericFormatter)); } break; case RadarType.Single: @@ -115,7 +120,7 @@ namespace XCharts { key2 = radar.indicatorList[dataIndex].name; } - sb.AppendFormat("{0}: {1}", key2, ChartCached.FloatToStr(value2, 0, tooltip.forceENotation)); + sb.AppendFormat("{0}: {1}", key2, ChartCached.FloatToStr(value2, numericFormatter)); break; } } @@ -127,20 +132,21 @@ namespace XCharts float xValue, yValue; serie.GetXYData(index, dataZoom, out xValue, out yValue); var isIngore = serie.IsIgnorePoint(index); + var serieData = serie.GetSerieData(index, dataZoom); + var numericFormatter = GetItemNumericFormatter(tooltip, serie, serieData); if (isCartesian) { - var serieData = serie.GetSerieData(index, dataZoom); if (serieData != null && serieData.highlighted) { sb.Append(key).Append(!string.IsNullOrEmpty(key) ? " : " : ""); - sb.Append("[").Append(ChartCached.FloatToStr(xValue, 0, tooltip.forceENotation)).Append(",") - .Append(ChartCached.FloatToStr(yValue, 0, tooltip.forceENotation)).Append("]"); + sb.Append("[").Append(ChartCached.FloatToStr(xValue, numericFormatter)).Append(",") + .Append(ChartCached.FloatToStr(yValue, numericFormatter)).Append("]"); } } else { var valueTxt = isIngore ? tooltip.ignoreDataDefaultContent : - ChartCached.FloatToStr(yValue, 0, tooltip.forceENotation); + ChartCached.FloatToStr(yValue, numericFormatter); sb.Append("● ") .Append(key).Append(!string.IsNullOrEmpty(key) ? " : " : "") .Append(valueTxt); @@ -175,7 +181,8 @@ namespace XCharts } } - public static void SetContentAndPosition(Tooltip tooltip,string content,Rect chartRect){ + public static void SetContentAndPosition(Tooltip tooltip, string content, Rect chartRect) + { tooltip.UpdateContentText(content); var pos = tooltip.GetContentPos(); if (pos.x + tooltip.runtimeWidth > chartRect.x + chartRect.width) @@ -210,6 +217,7 @@ namespace XCharts { isScatter = true; var itemFormatter = GetItemFormatter(tooltip, serie, null); + var numericFormatter = GetItemNumericFormatter(tooltip, serie, null); if (string.IsNullOrEmpty(itemFormatter)) { if (!first) sb.Append(PH_NN); @@ -238,7 +246,7 @@ namespace XCharts } for (int n = 0; n < serieData.data.Count; n++) { - var valueStr = ChartCached.FloatToStr(serieData.GetData(n), 0, tooltip.forceENotation); + var valueStr = ChartCached.FloatToStr(serieData.GetData(n), numericFormatter); Replace(ref content, GetPHCC(n), i, valueStr, true); } if (!foundDot) @@ -254,15 +262,16 @@ namespace XCharts var serieData = serie.GetSerieData(dataIndex, dataZoom); if (serieData == null) continue; var itemFormatter = GetItemFormatter(tooltip, serie, serieData); + var numericFormatter = GetItemNumericFormatter(tooltip, serie, serieData); var percent = serieData.GetData(1) / serie.yTotal * 100; needCategory = needCategory || (serie.type == SerieType.Line || serie.type == SerieType.Bar); if (formatTitle) { - var valueStr = ChartCached.FloatToStr(serieData.GetData(1), 0, tooltip.forceENotation); + var valueStr = ChartCached.FloatToStr(serieData.GetData(1), numericFormatter); Replace(ref title, PH_A, i, serie.name, true); Replace(ref title, PH_B, i, needCategory ? category : serieData.name, true); Replace(ref title, PH_C, i, valueStr, true); - Replace(ref title, PH_D, i, ChartCached.FloatToStr(percent, 1), true); + Replace(ref title, PH_D, i, ChartCached.FloatToStr(percent, string.Empty, 1), true); } if (serie.show) { @@ -274,14 +283,14 @@ namespace XCharts continue; } string content = itemFormatter; - var valueStr = ChartCached.FloatToStr(serieData.GetData(1), 0, tooltip.forceENotation); + var valueStr = ChartCached.FloatToStr(serieData.GetData(1), numericFormatter); Replace(ref content, PH_A, i, serie.name, true); Replace(ref content, PH_B, i, needCategory ? category : serieData.name, true); Replace(ref content, PH_C, i, valueStr, true); - Replace(ref content, PH_D, i, ChartCached.FloatToStr(percent, 1), true); + Replace(ref content, PH_D, i, ChartCached.FloatToStr(percent, string.Empty, 1), true); for (int n = 0; n < serieData.data.Count; n++) { - valueStr = ChartCached.FloatToStr(serieData.GetData(n), 0, tooltip.forceENotation); + valueStr = ChartCached.FloatToStr(serieData.GetData(n), numericFormatter); Replace(ref content, GetPHCC(n), i, valueStr, true); } if (!first) sb.Append(PH_NN); @@ -317,15 +326,16 @@ namespace XCharts { var needCategory = serie.type == SerieType.Line || serie.type == SerieType.Bar; var serieData = serie.GetSerieData(dataIndex, dataZoom); + var numericFormatter = GetItemNumericFormatter(tooltip, serie, serieData); var percent = serieData.GetData(1) / serie.yTotal * 100; Replace(ref content, PH_A, i, serie.name); Replace(ref content, PH_B, i, needCategory ? category : serieData.name); - Replace(ref content, PH_C, i, ChartCached.FloatToStr(serieData.GetData(1), 0, tooltip.forceENotation)); - Replace(ref content, PH_D, i, ChartCached.FloatToStr(percent, 1)); + Replace(ref content, PH_C, i, ChartCached.FloatToStr(serieData.GetData(1), numericFormatter)); + Replace(ref content, PH_D, i, ChartCached.FloatToStr(percent, string.Empty, 1)); Replace(ref content, PH_I, i, ChartCached.ColorToDotStr(themeInfo.GetColor(i))); for (int n = 0; n < serieData.data.Count; n++) { - var valueStr = ChartCached.FloatToStr(serieData.GetData(n), 0, tooltip.forceENotation); + var valueStr = ChartCached.FloatToStr(serieData.GetData(n), numericFormatter); if (i == 0) Replace(ref content, GetPHCC(n), i, valueStr, true); Replace(ref content, GetPHCC(i, n), i, valueStr, true); } @@ -401,6 +411,13 @@ namespace XCharts else return tooltip.itemFormatter; } + private static string GetItemNumericFormatter(Tooltip tooltip, Serie serie, SerieData serieData) + { + var itemStyle = SerieHelper.GetItemStyle(serie, serieData); + if (!string.IsNullOrEmpty(itemStyle.numericFormatter)) return itemStyle.numericFormatter; + else return tooltip.numericFormatter; + } + public static Color GetLineColor(Tooltip tooltip, ThemeInfo theme) { var lineStyle = tooltip.lineStyle; diff --git a/Assets/XCharts/Runtime/Internal/CoordinateChart.cs b/Assets/XCharts/Runtime/Internal/CoordinateChart.cs index 55222974..96e96d4a 100644 --- a/Assets/XCharts/Runtime/Internal/CoordinateChart.cs +++ b/Assets/XCharts/Runtime/Internal/CoordinateChart.cs @@ -434,7 +434,7 @@ namespace XCharts var diff = axisIndex > 0 ? -axis.axisLabel.fontSize - axis.axisLabel.margin - 3.5f : axis.axisLabel.margin / 2 + 1; if (axis.IsValue()) { - labelText = ChartCached.FloatToStr(m_Tooltip.runtimeXValues[axisIndex], 2); + labelText = ChartCached.NumberToStr(m_Tooltip.runtimeXValues[axisIndex], axis.axisLabel.numericFormatter); labelPos = new Vector2(m_Tooltip.runtimePointerPos.x, posY - diff); } else @@ -452,7 +452,7 @@ namespace XCharts var diff = axisIndex > 0 ? -axis.axisLabel.margin + 3 : axis.axisLabel.margin - 3; if (axis.IsValue()) { - labelText = ChartCached.FloatToStr(m_Tooltip.runtimeYValues[axisIndex], 2); + labelText = ChartCached.NumberToStr(m_Tooltip.runtimeYValues[axisIndex], axis.axisLabel.numericFormatter); labelPos = new Vector2(posX - diff, m_Tooltip.runtimePointerPos.y); } else @@ -1480,11 +1480,11 @@ namespace XCharts if (anyPercentStack && isPercentStack) { var tempTotal = GetSameStackTotalValue(serie.stack, j); - content = serieLabel.GetFormatterContent(serie.name, serieData.name, value, tempTotal); + content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, tempTotal, serieLabel); } else { - content = serieLabel.GetFormatterContent(serie.name, serieData.name, value, total); + content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, serieLabel); } serieData.SetLabelActive(value != 0 && serieData.labelPosition != Vector3.zero); var invert = serie.type == SerieType.Line && SerieHelper.IsDownPoint(serie, j) && !serie.areaStyle.show; diff --git a/Assets/XCharts/Runtime/PieChart.cs b/Assets/XCharts/Runtime/PieChart.cs index 42345a06..348be4e2 100644 --- a/Assets/XCharts/Runtime/PieChart.cs +++ b/Assets/XCharts/Runtime/PieChart.cs @@ -400,7 +400,7 @@ namespace XCharts { var value = serieData.data[1]; var total = serie.yTotal; - var content = serieLabel.GetFormatterContent(serie.name, serieData.name, value, total); + var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, serieLabel); if (serieData.SetLabelText(content)) RefreshChart(); } else diff --git a/Assets/XCharts/Runtime/RadarChart.cs b/Assets/XCharts/Runtime/RadarChart.cs index 5539c7d0..1a43641d 100644 --- a/Assets/XCharts/Runtime/RadarChart.cs +++ b/Assets/XCharts/Runtime/RadarChart.cs @@ -747,7 +747,7 @@ namespace XCharts SerieLabelHelper.ResetLabel(serieData, serieLabel, themeInfo, i); serieData.SetLabelActive(serieData.labelPosition != Vector3.zero); serieData.SetLabelPosition(serieLabel.offset); - var content = serieLabel.GetFormatterContent(serie.name, serieData.name, value, max); + var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, max, serieLabel); if (serieData.SetLabelText(content)) RefreshChart(); } else diff --git a/Assets/XCharts/Runtime/ScatterChart.cs b/Assets/XCharts/Runtime/ScatterChart.cs index 3b8d9af5..0fcdacd9 100644 --- a/Assets/XCharts/Runtime/ScatterChart.cs +++ b/Assets/XCharts/Runtime/ScatterChart.cs @@ -70,7 +70,6 @@ namespace XCharts base.CheckTootipArea(local); m_Tooltip.ClearSerieDataIndex(); bool selected = false; - var localv3 = new Vector3(local.x, local.y); foreach (var serie in m_Series.list) { if (!serie.show) continue; diff --git a/Assets/XCharts/Runtime/Utility/ChartCached.cs b/Assets/XCharts/Runtime/Utility/ChartCached.cs index 6d83e4c9..dadb47c1 100644 --- a/Assets/XCharts/Runtime/Utility/ChartCached.cs +++ b/Assets/XCharts/Runtime/Utility/ChartCached.cs @@ -6,72 +6,80 @@ /******************************************/ using System.Collections.Generic; +using System.Globalization; using UnityEngine; namespace XCharts { public static class ChartCached { - private static Dictionary s_ValueToF1Str = new Dictionary(1000); - private static Dictionary s_ValueToE1Str = new Dictionary(1000); - private static Dictionary s_ValueToF2Str = new Dictionary(1000); - private static Dictionary s_ValueToE2Str = new Dictionary(1000); - private static Dictionary s_ValueToFnStr = new Dictionary(1000); - private static Dictionary s_ValueToEnStr = new Dictionary(1000); - private static Dictionary s_ValueToFStr = new Dictionary(1000); - private static Dictionary s_ValueToEStr = new Dictionary(1000); - private static Dictionary s_IntToStr = new Dictionary(1000); - private static Dictionary s_IntToFn = new Dictionary(20); + private const string NUMERIC_FORMATTER_D = "D"; + private const string NUMERIC_FORMATTER_d = "d"; + private const string NUMERIC_FORMATTER_X = "X"; + private const string NUMERIC_FORMATTER_x = "x"; + private static CultureInfo ci = new CultureInfo("en-us");// "en-us", "zh-cn", "ar-iq", "de-de" private static Dictionary s_ColorToStr = new Dictionary(100); private static Dictionary s_SerieLabelName = new Dictionary(1000); private static Dictionary s_AxisLabelName = new Dictionary(1000); private static Dictionary s_ColorDotStr = new Dictionary(100); - public static string FloatToStr(float value, int f = 0, bool forceE = false) + private static Dictionary> s_NumberToStr = new Dictionary>(); + private static Dictionary> s_PrecisionToStr = new Dictionary>(); + + public static string FloatToStr(float value, string numericFormatter = "F", int precision = 0) { - Dictionary valueDic; - if (f == 0) valueDic = forceE ? s_ValueToEStr : s_ValueToFStr; - if (f == 1) valueDic = forceE ? s_ValueToE1Str : s_ValueToF1Str; - else if (f == 2) valueDic = forceE ? s_ValueToE2Str : s_ValueToF2Str; - else valueDic = forceE ? s_ValueToEnStr : s_ValueToFnStr; - if (valueDic.ContainsKey(value)) + if (precision > 0 && numericFormatter.Length == 1) { - return valueDic[value]; + if (!s_PrecisionToStr.ContainsKey(precision)) + { + s_PrecisionToStr[precision] = new Dictionary(); + } + if (!s_PrecisionToStr[precision].ContainsKey(numericFormatter)) + { + s_PrecisionToStr[precision][numericFormatter] = numericFormatter + precision; + } + return NumberToStr(value, s_PrecisionToStr[precision][numericFormatter]); } else { - if (f == 0) valueDic[value] = forceE ? value.ToString("E0") : value.ToString(); - else if (f == 1) valueDic[value] = forceE ? value.ToString("E1") : value.ToString("f1"); - else if (f == 2) valueDic[value] = forceE ? value.ToString("E2") : value.ToString("f2"); - else valueDic[value] = (f > 3 || forceE) ? value.ToString("E0") : value.ToString(GetFn(f)); - return valueDic[value]; + return NumberToStr(value, numericFormatter); } } - private static string GetFn(int f) + public static string NumberToStr(float value, string formatter) { - if (s_IntToFn.ContainsKey(f)) + if (!s_NumberToStr.ContainsKey(value)) { - return s_IntToFn[f]; + s_NumberToStr[value] = new Dictionary(); } - else + if (!s_NumberToStr[value].ContainsKey(formatter)) { - s_IntToFn[f] = "f" + f; - return s_IntToFn[f]; + if (string.IsNullOrEmpty(formatter)) + { + if (value - (int)value == 0) + s_NumberToStr[value][formatter] = ((int)value).ToString(); + else + s_NumberToStr[value][formatter] = value.ToString(); + } + else if (formatter.StartsWith(NUMERIC_FORMATTER_D) + || formatter.StartsWith(NUMERIC_FORMATTER_d) + || formatter.StartsWith(NUMERIC_FORMATTER_X) + || formatter.StartsWith(NUMERIC_FORMATTER_x) + ) + { + s_NumberToStr[value][formatter] = ((int)value).ToString(formatter, ci); + } + else + { + s_NumberToStr[value][formatter] = value.ToString(formatter, ci); + } } + return s_NumberToStr[value][formatter]; } - public static string IntToStr(int value) + public static string IntToStr(int value, string numericFormatter = "") { - if (s_IntToStr.ContainsKey(value)) - { - return s_IntToStr[value]; - } - else - { - s_IntToStr[value] = value.ToString(); - return s_IntToStr[value]; - } + return NumberToStr(value, numericFormatter); } public static string ColorToStr(Color color)