diff --git a/Editor/PropertyDrawers/AxisLabelDrawer.cs b/Editor/PropertyDrawers/AxisLabelDrawer.cs index d251aed2..b520fe8c 100644 --- a/Editor/PropertyDrawers/AxisLabelDrawer.cs +++ b/Editor/PropertyDrawers/AxisLabelDrawer.cs @@ -29,6 +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"); ChartEditorHelper.MakeFoldout(ref drawRect, ref m_AxisLabelToggle, prop, "Axis Label", show, false); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; @@ -51,6 +52,8 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_Formatter); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, m_ForceENotation); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; --EditorGUI.indentLevel; } } @@ -60,7 +63,7 @@ namespace XCharts float height = 0; if (ChartEditorHelper.IsToggle(m_AxisLabelToggle, prop)) { - height += 8 * EditorGUIUtility.singleLineHeight + 7 * EditorGUIUtility.standardVerticalSpacing; + height += 9 * EditorGUIUtility.singleLineHeight + 10 * EditorGUIUtility.standardVerticalSpacing; } return height; } diff --git a/Editor/PropertyDrawers/SerieLabelDrawer.cs b/Editor/PropertyDrawers/SerieLabelDrawer.cs index 6b8a59ea..d1979dad 100644 --- a/Editor/PropertyDrawers/SerieLabelDrawer.cs +++ b/Editor/PropertyDrawers/SerieLabelDrawer.cs @@ -42,6 +42,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"); ChartEditorHelper.MakeFoldout(ref drawRect, ref m_SerieLabelToggle, prop, null, show, false); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; @@ -100,6 +101,8 @@ 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; } } @@ -109,7 +112,7 @@ namespace XCharts float height = 0; if (ChartEditorHelper.IsToggle(m_SerieLabelToggle, prop)) { - height += 22 * EditorGUIUtility.singleLineHeight + 21 * EditorGUIUtility.standardVerticalSpacing; + height += 23 * EditorGUIUtility.singleLineHeight + 22 * EditorGUIUtility.standardVerticalSpacing; } else { diff --git a/Editor/PropertyDrawers/TooltipDrawer.cs b/Editor/PropertyDrawers/TooltipDrawer.cs index 4baf9142..707b72a9 100644 --- a/Editor/PropertyDrawers/TooltipDrawer.cs +++ b/Editor/PropertyDrawers/TooltipDrawer.cs @@ -28,6 +28,7 @@ namespace XCharts SerializedProperty m_MinHeight = prop.FindPropertyRelative("m_MinHeight"); SerializedProperty m_FontSize = prop.FindPropertyRelative("m_FontSize"); SerializedProperty m_FontStyle = prop.FindPropertyRelative("m_FontStyle"); + SerializedProperty m_ForceENotation = prop.FindPropertyRelative("m_ForceENotation"); ChartEditorHelper.MakeFoldout(ref drawRect, ref m_TooltipModuleToggle, "Tooltip", show); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; @@ -49,13 +50,15 @@ namespace XCharts drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(drawRect, m_FontStyle); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, m_ForceENotation); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; } } public override float GetPropertyHeight(SerializedProperty prop, GUIContent label) { if (m_TooltipModuleToggle) - return 9 * EditorGUIUtility.singleLineHeight + 8 * EditorGUIUtility.standardVerticalSpacing; + return 10 * EditorGUIUtility.singleLineHeight + 9 * EditorGUIUtility.standardVerticalSpacing; else return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; } diff --git a/Runtime/Component/Main/Tooltip.cs b/Runtime/Component/Main/Tooltip.cs index 3b1cbd3a..d866672c 100644 --- a/Runtime/Component/Main/Tooltip.cs +++ b/Runtime/Component/Main/Tooltip.cs @@ -55,6 +55,7 @@ namespace XCharts [SerializeField] private float m_MinHeight = 0; [SerializeField] private int m_FontSize = 18; [SerializeField] private FontStyle m_FontStyle = FontStyle.Normal; + [SerializeField] private bool m_ForceENotation = false; private GameObject m_GameObject; private GameObject m_Content; @@ -114,6 +115,10 @@ namespace XCharts /// 文字的字体风格。 /// public FontStyle fontStyle { get { return m_FontStyle; } set { m_FontStyle = value; } } + /// + /// 是否强制使用科学计数法格式化显示数值。默认为false,当小数精度大于3时才采用科学计数法。 + /// + public bool forceENotation { get { return m_ForceENotation; } set { m_ForceENotation = value; } } /// /// The data index currently indicated by Tooltip. @@ -355,7 +360,7 @@ namespace XCharts { content = content.Replace("{a}", serie.name); content = content.Replace("{b}", needCategory ? category : serieData.name); - content = content.Replace("{c}", ChartCached.FloatToStr(serieData.GetData(1))); + 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; @@ -364,7 +369,7 @@ namespace XCharts } 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))); + 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; @@ -381,12 +386,12 @@ namespace XCharts public string GetFormatterContent(string serieName, string dataName, float dataValue) { if (string.IsNullOrEmpty(m_Formatter)) - return ChartCached.FloatToStr(dataValue); + 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)); + content = content.Replace("{c}", ChartCached.FloatToStr(dataValue, 0, m_ForceENotation)); content = content.Replace("\\n", "\n"); content = content.Replace("
", "\n"); return content; diff --git a/Runtime/Component/Sub/AxisLabel.cs b/Runtime/Component/Sub/AxisLabel.cs index cb03efbd..b575257b 100644 --- a/Runtime/Component/Sub/AxisLabel.cs +++ b/Runtime/Component/Sub/AxisLabel.cs @@ -26,6 +26,8 @@ namespace XCharts [SerializeField] private Color m_Color; [SerializeField] private int m_FontSize; [SerializeField] private FontStyle m_FontStyle; + [SerializeField] private bool m_ForceENotation = false; + /// /// Set this to false to prevent the axis label from appearing. @@ -72,6 +74,10 @@ namespace XCharts /// 模板变量为图例名称 {value},{value:f1} 表示取1为小数 /// public string formatter { get { return m_Formatter; } set { m_Formatter = value; } } + /// + /// 是否强制使用科学计数法格式化显示数值。默认为false,当小数精度大于3时才采用科学计数法。 + /// + public bool forceENotation { get { return m_ForceENotation; } set { m_ForceENotation = value; } } public static AxisLabel defaultAxisLabel { @@ -118,6 +124,7 @@ namespace XCharts m_Color == other.color && m_FontSize == other.fontSize && m_FontStyle == other.fontStyle && + m_ForceENotation == other.forceENotation && m_Formatter == other.formatter; } @@ -139,13 +146,22 @@ namespace XCharts } } - public string GetFormatterContent(float value) + public string GetFormatterContent(float value, float minValue, float maxValue) { if (string.IsNullOrEmpty(m_Formatter)) - if (value - (int)value == 0) + { + if (minValue >= -1 && minValue <= 1 && maxValue >= -1 && maxValue <= 1) + { + int minAcc = ChartHelper.GetFloatAccuracy(minValue); + int maxAcc = ChartHelper.GetFloatAccuracy(maxValue); + int acc = Mathf.Max(minAcc, maxAcc); + return ChartCached.FloatToStr(value, acc, m_ForceENotation); + } + else if (value - (int)value == 0) return ChartCached.IntToStr((int)value); else return ChartCached.FloatToStr(value, 1); + } else { var content = m_Formatter; diff --git a/Runtime/Component/Sub/SerieLabel.cs b/Runtime/Component/Sub/SerieLabel.cs index 9df7246c..ea1dad13 100644 --- a/Runtime/Component/Sub/SerieLabel.cs +++ b/Runtime/Component/Sub/SerieLabel.cs @@ -99,6 +99,7 @@ namespace XCharts [SerializeField] private bool m_Border = true; [SerializeField] private float m_BorderWidth = 0.5f; [SerializeField] private Color m_BorderColor = Color.grey; + [SerializeField] private bool m_ForceENotation = false; /// /// Whether the label is showed. /// 是否显示文本标签。 @@ -220,16 +221,20 @@ namespace XCharts /// 边框颜色。 /// public Color borderColor { get { return m_BorderColor; } set { m_BorderColor = value; } } + /// + /// 是否强制使用科学计数法格式化显示数值。默认为false,当小数精度大于3时才采用科学计数法。 + /// + public bool forceENotation { get { return m_ForceENotation; } set { m_ForceENotation = value; } } public string GetFormatterContent(string serieName, string dataName, float dataValue, float dataTotal = 0) { if (string.IsNullOrEmpty(m_Formatter)) - return ChartCached.FloatToStr(dataValue); + 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)); + 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)); diff --git a/Runtime/PieChart.cs b/Runtime/PieChart.cs index 2ff8fb53..50726fe5 100644 --- a/Runtime/PieChart.cs +++ b/Runtime/PieChart.cs @@ -556,7 +556,7 @@ namespace XCharts sb.Append(serie.name).Append("\n"); } sb.Append("● ") - .Append(key).Append(": ").Append(ChartCached.FloatToStr(value)); + .Append(key).Append(": ").Append(ChartCached.FloatToStr(value, 0, m_Tooltip.forceENotation)); m_Tooltip.UpdateContentText(sb.ToString()); } else diff --git a/Runtime/RadarChart.cs b/Runtime/RadarChart.cs index bc546791..75b2eea0 100644 --- a/Runtime/RadarChart.cs +++ b/Runtime/RadarChart.cs @@ -213,7 +213,7 @@ namespace XCharts int indicatorNum = radar.indicatorList.Count; var angle = 2 * Mathf.PI / indicatorNum; Vector3 p = radar.centerPos; - serie.animation.InitProgress(1,0,1); + serie.animation.InitProgress(1, 0, 1); if (!IsActive(i)) { continue; @@ -399,7 +399,7 @@ namespace XCharts } if (radar.lineStyle.show) { - ChartDrawer.DrawEmptyCricle(vh, p, outsideRadius, radar.lineStyle.width, lineColor, + ChartDrawer.DrawEmptyCricle(vh, p, outsideRadius, radar.lineStyle.width, lineColor, Color.clear, m_Settings.cicleSmoothness); } insideRadius = outsideRadius; @@ -507,7 +507,7 @@ namespace XCharts string key = radar.indicatorList[i].name; float value = serieData.GetData(i); sb.Append("\n"); - sb.AppendFormat("{0}: {1}", key, value); + sb.AppendFormat("{0}: {1}", key, ChartCached.FloatToStr(value, 0, m_Tooltip.forceENotation)); } m_Tooltip.UpdateContentText(sb.ToString()); var pos = m_Tooltip.GetContentPos(); diff --git a/Runtime/Utility/ChartCached.cs b/Runtime/Utility/ChartCached.cs index b2ff5a29..4e346935 100644 --- a/Runtime/Utility/ChartCached.cs +++ b/Runtime/Utility/ChartCached.cs @@ -13,31 +13,51 @@ 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_ValueToStr = 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 static Dictionary s_ColorToStr = new Dictionary(1000); - public static string FloatToStr(float value, int f = 0) + public static string FloatToStr(float value, int f = 0, bool forceE = false) { - if (f > 2) f = 2; Dictionary valueDic; - if (f == 1) valueDic = s_ValueToF1Str; - else if (f == 2) valueDic = s_ValueToF2Str; - else valueDic = s_ValueToStr; + 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)) { return valueDic[value]; } else { - if (f == 1) valueDic[value] = value.ToString("f1"); + if (f == 0) valueDic[value] = forceE ? value.ToString("E") : value.ToString(); + else if (f == 1) valueDic[value] = value.ToString("f1"); else if (f == 2) valueDic[value] = value.ToString("f2"); - else valueDic[value] = value.ToString(); + else valueDic[value] = (f > 3 || forceE) ? value.ToString("E1") : value.ToString(GetFn(f)); return valueDic[value]; } } + private static string GetFn(int f) + { + if (s_IntToFn.ContainsKey(f)) + { + return s_IntToFn[f]; + } + else + { + s_IntToFn[f] = "f" + f; + return s_IntToFn[f]; + } + } + public static string IntToStr(int value) { if (s_IntToStr.ContainsKey(value))