diff --git a/Editor/ChildComponents/LabelLineDrawer.cs b/Editor/ChildComponents/LabelLineDrawer.cs index 566fbdf4..3888cbef 100644 --- a/Editor/ChildComponents/LabelLineDrawer.cs +++ b/Editor/ChildComponents/LabelLineDrawer.cs @@ -17,10 +17,13 @@ namespace XCharts.Editor ++EditorGUI.indentLevel; PropertyField(prop, "m_LineType"); PropertyField(prop, "m_LineColor"); + PropertyField(prop, "m_LineAngle"); PropertyField(prop, "m_LineWidth"); PropertyField(prop, "m_LineGap"); PropertyField(prop, "m_LineLength1"); PropertyField(prop, "m_LineLength2"); + PropertyField(prop, "m_StartSymbol"); + PropertyField(prop, "m_EndSymbol"); --EditorGUI.indentLevel; } } diff --git a/Editor/ChildComponents/SerieDataBaseInfoDrawer.cs b/Editor/ChildComponents/SerieDataBaseInfoDrawer.cs new file mode 100644 index 00000000..87673c5f --- /dev/null +++ b/Editor/ChildComponents/SerieDataBaseInfoDrawer.cs @@ -0,0 +1,25 @@ + +using UnityEditor; +using UnityEngine; +using XCharts.Runtime; + +namespace XCharts.Editor +{ + [CustomPropertyDrawer(typeof(SerieDataBaseInfo), true)] + public class SerieDataBaseInfoDrawer : BasePropertyDrawer + { + public override string ClassName { get { return "BaseInfo"; } } + public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) + { + base.OnGUI(pos, prop, label); + if (MakeComponentFoldout(prop, "m_Show", false)) + { + ++EditorGUI.indentLevel; + PropertyField(prop, "m_Ignore"); + PropertyField(prop, "m_Selected"); + PropertyField(prop, "m_Radius"); + --EditorGUI.indentLevel; + } + } + } +} \ No newline at end of file diff --git a/Editor/ChildComponents/SerieDataBaseInfoDrawer.cs.meta b/Editor/ChildComponents/SerieDataBaseInfoDrawer.cs.meta new file mode 100644 index 00000000..fac13527 --- /dev/null +++ b/Editor/ChildComponents/SerieDataBaseInfoDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 418b81a68e59a4572ab57787b5362d5a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ChildComponents/SerieSymbolDrawer.cs b/Editor/ChildComponents/SerieSymbolDrawer.cs new file mode 100644 index 00000000..dac474db --- /dev/null +++ b/Editor/ChildComponents/SerieSymbolDrawer.cs @@ -0,0 +1,53 @@ + +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +using XCharts.Runtime; + +namespace XCharts.Editor +{ + [CustomPropertyDrawer(typeof(SerieSymbol), true)] + public class SerieSymbolDrawer : BasePropertyDrawer + { + public override string ClassName { get { return "Symbol"; } } + public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) + { + base.OnGUI(pos, prop, label); + if (MakeComponentFoldout(prop, "m_Show", true)) + { + ++EditorGUI.indentLevel; + var type = (SymbolType)prop.FindPropertyRelative("m_Type").enumValueIndex; + PropertyField(prop, "m_Type"); + if (type == SymbolType.Custom) + { + PropertyField(prop, "m_Image"); + PropertyField(prop, "m_ImageType"); + PropertyField(prop, "m_Width"); + // PropertyField(prop, "m_Height"); + // PropertyField(prop, "m_Offset"); + } + PropertyField(prop, "m_Gap"); + PropertyField(prop, "m_SizeType"); + switch ((SymbolSizeType)prop.FindPropertyRelative("m_SizeType").enumValueIndex) + { + case SymbolSizeType.Custom: + PropertyField(prop, "m_Size"); + PropertyField(prop, "m_SelectedSize"); + break; + case SymbolSizeType.FromData: + PropertyField(prop, "m_DataIndex"); + PropertyField(prop, "m_DataScale"); + PropertyField(prop, "m_SelectedDataScale"); + break; + case SymbolSizeType.Function: + break; + } + PropertyField(prop, "m_StartIndex"); + PropertyField(prop, "m_Interval"); + PropertyField(prop, "m_ForceShowLast"); + PropertyField(prop, "m_Repeat"); + --EditorGUI.indentLevel; + } + } + } +} \ No newline at end of file diff --git a/Editor/ChildComponents/SerieSymbolDrawer.cs.meta b/Editor/ChildComponents/SerieSymbolDrawer.cs.meta new file mode 100644 index 00000000..f780f989 --- /dev/null +++ b/Editor/ChildComponents/SerieSymbolDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a164822bc0fd4e5291f00c5a4ee86f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ChildComponents/SymbolStyleDrawer.cs b/Editor/ChildComponents/SymbolStyleDrawer.cs index ed4855d1..fcd854bc 100644 --- a/Editor/ChildComponents/SymbolStyleDrawer.cs +++ b/Editor/ChildComponents/SymbolStyleDrawer.cs @@ -23,29 +23,12 @@ namespace XCharts.Editor PropertyField(prop, "m_Image"); PropertyField(prop, "m_ImageType"); PropertyField(prop, "m_Width"); - // PropertyField(prop, "m_Height"); + PropertyField(prop, "m_Height"); // PropertyField(prop, "m_Offset"); } + PropertyField(prop, "m_Color"); + PropertyField(prop, "m_Size"); PropertyField(prop, "m_Gap"); - PropertyField(prop, "m_SizeType"); - switch ((SymbolSizeType)prop.FindPropertyRelative("m_SizeType").enumValueIndex) - { - case SymbolSizeType.Custom: - PropertyField(prop, "m_Size"); - PropertyField(prop, "m_SelectedSize"); - break; - case SymbolSizeType.FromData: - PropertyField(prop, "m_DataIndex"); - PropertyField(prop, "m_DataScale"); - PropertyField(prop, "m_SelectedDataScale"); - break; - case SymbolSizeType.Function: - break; - } - PropertyField(prop, "m_StartIndex"); - PropertyField(prop, "m_Interval"); - PropertyField(prop, "m_ForceShowLast"); - PropertyField(prop, "m_Repeat"); --EditorGUI.indentLevel; } } diff --git a/Editor/Series/SerieEditor.cs b/Editor/Series/SerieEditor.cs index b914381b..2d7fbda9 100644 --- a/Editor/Series/SerieEditor.cs +++ b/Editor/Series/SerieEditor.cs @@ -195,6 +195,7 @@ namespace XCharts.Editor var m_Id = serieData.FindPropertyRelative("m_Id"); var m_ParentId = serieData.FindPropertyRelative("m_ParentId"); + var m_BaseInfo = serieData.FindPropertyRelative("m_BaseInfos"); var m_Label = serieData.FindPropertyRelative("m_Labels"); var m_ItemStyle = serieData.FindPropertyRelative("m_ItemStyles"); var m_Emphasis = serieData.FindPropertyRelative("m_Emphases"); @@ -207,11 +208,15 @@ namespace XCharts.Editor PropertyField(m_Id); PropertyField(m_ParentId); - var componentNum = m_Label.arraySize + m_ItemStyle.arraySize + m_Emphasis.arraySize + var componentNum = m_BaseInfo.arraySize + m_Label.arraySize + m_ItemStyle.arraySize + m_Emphasis.arraySize + m_Symbol.arraySize + m_LineStyle.arraySize + m_AreaStyle.arraySize; var title = "Component"; if (componentNum == 0) title += " (None)"; m_DataComponentFoldout = ChartEditorHelper.DrawHeader(title, m_DataComponentFoldout, false, null, null, + new HeaderMenuInfo("Add BaseInfo", () => + { + serie.GetSerieData(index).GetOrAddComponent(); + }, m_BaseInfo.arraySize == 0), new HeaderMenuInfo("Add ItemStyle", () => { serie.GetSerieData(index).GetOrAddComponent(); @@ -226,7 +231,7 @@ namespace XCharts.Editor }, m_Emphasis.arraySize == 0), new HeaderMenuInfo("Add Symbol", () => { - serie.GetSerieData(index).GetOrAddComponent(); + serie.GetSerieData(index).GetOrAddComponent(); }, m_Symbol.arraySize == 0), new HeaderMenuInfo("Add LineStyle", () => { @@ -240,6 +245,10 @@ namespace XCharts.Editor { serie.GetSerieData(index).GetOrAddComponent(); }, m_TitleStyle.arraySize == 0), + new HeaderMenuInfo("Remove BaseInfo", () => + { + serie.GetSerieData(index).RemoveComponent(); + }, m_BaseInfo.arraySize > 0), new HeaderMenuInfo("Remove ItemStyle", () => { serie.GetSerieData(index).RemoveComponent(); @@ -254,7 +263,7 @@ namespace XCharts.Editor }, m_Emphasis.arraySize > 0), new HeaderMenuInfo("Remove Symbol", () => { - serie.GetSerieData(index).RemoveComponent(); + serie.GetSerieData(index).RemoveComponent(); }, m_Symbol.arraySize > 0), new HeaderMenuInfo("Remove LineStyle", () => { @@ -274,6 +283,8 @@ namespace XCharts.Editor }, componentNum > 0)); if (m_DataComponentFoldout) { + if (m_BaseInfo.arraySize > 0) + PropertyField(m_BaseInfo.GetArrayElementAtIndex(0)); if (m_Label.arraySize > 0) PropertyField(m_Label.GetArrayElementAtIndex(0)); if (m_ItemStyle.arraySize > 0) diff --git a/Editor/Windows/PraseExternalDataEditor.cs b/Editor/Windows/PraseExternalDataEditor.cs index 06c68c84..f2d861cb 100644 --- a/Editor/Windows/PraseExternalDataEditor.cs +++ b/Editor/Windows/PraseExternalDataEditor.cs @@ -194,7 +194,8 @@ namespace XCharts.Editor else if (a.StartsWith("selected:")) { string selected = a.Substring(9, a.Length - 9); - serieData.selected = bool.Parse(selected); + var baseInfo = serieData.GetOrAddComponent(); + baseInfo.selected = bool.Parse(selected); } } serie.AddSerieData(serieData); diff --git a/Examples/Runtime/Example30_PieChart.cs b/Examples/Runtime/Example30_PieChart.cs index e6a9434d..216a7ac8 100644 --- a/Examples/Runtime/Example30_PieChart.cs +++ b/Examples/Runtime/Example30_PieChart.cs @@ -62,7 +62,7 @@ namespace XCharts.Example legend.orient = Orient.Vertical; chart.RemoveData(); - serie = chart.AddSerie( "访问来源"); + serie = chart.AddSerie("访问来源"); serie.radius[0] = 0; serie.radius[1] = 110; serie.center[0] = 0.5f; @@ -118,12 +118,12 @@ namespace XCharts.Example chart.RefreshChart(); yield return new WaitForSeconds(1); - serie.data[0].selected = true; + serie.data[0].GetOrAddComponent().selected = true; chart.RefreshChart(); yield return new WaitForSeconds(1); serie.gap = 0f; - serie.data[0].selected = false; + serie.data[0].GetOrAddComponent().selected = false; chart.RefreshChart(); yield return new WaitForSeconds(1); } @@ -132,7 +132,7 @@ namespace XCharts.Example { chart.GetChartComponent().subText = "多图组合"; - serie1 = chart.AddSerie<Pie>( "访问来源2"); + serie1 = chart.AddSerie<Pie>("访问来源2"); chart.AddData(1, 335, "直达"); chart.AddData(1, 679, "营销广告"); chart.AddData(1, 1548, "搜索引擎"); diff --git a/Examples/Runtime/Example_Component.cs b/Examples/Runtime/Example_Component.cs index 7af0da8a..195d63f3 100644 --- a/Examples/Runtime/Example_Component.cs +++ b/Examples/Runtime/Example_Component.cs @@ -29,7 +29,8 @@ namespace XCharts.Example var serieData = chart.AddData(0, 20); //var serieData = serie1.GetSerieData(0); - serieData.radius = 10; + var baseInfo = serieData.GetOrAddComponent<SerieDataBaseInfo>(); + baseInfo.radius = 10; var itemStyle = serieData.GetOrAddComponent<ItemStyle>(); itemStyle.color = Color.blue; } diff --git a/Runtime/Component/Child/LabelLine.cs b/Runtime/Component/Child/LabelLine.cs index f2d5b4f4..13ebe802 100644 --- a/Runtime/Component/Child/LabelLine.cs +++ b/Runtime/Component/Child/LabelLine.cs @@ -4,6 +4,9 @@ using UnityEngine; namespace XCharts.Runtime { + /// <summary> + /// 标签的引导线 + /// </summary> [System.Serializable] public class LabelLine : ChildComponent, ISerieExtraComponent, ISerieDataComponent { @@ -29,16 +32,20 @@ namespace XCharts.Runtime [SerializeField] private bool m_Show = true; [SerializeField] private LineType m_LineType = LineType.BrokenLine; [SerializeField] private Color32 m_LineColor = ChartConst.clearColor32; + [SerializeField] private float m_LineAngle = 0; [SerializeField] private float m_LineWidth = 1.0f; [SerializeField] private float m_LineGap = 1.0f; [SerializeField] private float m_LineLength1 = 25f; [SerializeField] private float m_LineLength2 = 15f; + [SerializeField] private SymbolStyle m_StartSymbol = new SymbolStyle() { type = SymbolType.Circle, size = 3 }; + [SerializeField] private SymbolStyle m_EndSymbol = new SymbolStyle() { type = SymbolType.Circle, size = 3 }; public void Reset() { m_Show = false; m_LineType = LineType.BrokenLine; m_LineColor = Color.clear; + m_LineAngle = 0; m_LineWidth = 1.0f; m_LineGap = 1.0f; m_LineLength1 = 25f; @@ -73,6 +80,15 @@ namespace XCharts.Runtime set { if (PropertyUtil.SetStruct(ref m_LineColor, value)) SetVerticesDirty(); } } /// <summary> + /// the angle of visual guild line. + /// |视觉引导线的固定角度。对折线和曲线有效。 + /// </summary> + public float lineAngle + { + get { return m_LineAngle; } + set { if (PropertyUtil.SetStruct(ref m_LineAngle, value)) SetVerticesDirty(); } + } + /// <summary> /// the width of visual guild line. /// |视觉引导线的宽度。 /// </summary> @@ -108,5 +124,23 @@ namespace XCharts.Runtime get { return m_LineLength2; } set { if (PropertyUtil.SetStruct(ref m_LineLength2, value)) SetVerticesDirty(); } } + /// <summary> + /// The symbol of the start point of labelline. + /// |起始点的图形标记。 + /// </summary> + public SymbolStyle startSymbol + { + get { return m_StartSymbol; } + set { if (PropertyUtil.SetClass(ref m_StartSymbol, value)) SetVerticesDirty(); } + } + /// <summary> + /// The symbol of the end point of labelline. + /// |结束点的图形标记。 + /// </summary> + public SymbolStyle endSymbol + { + get { return m_EndSymbol; } + set { if (PropertyUtil.SetClass(ref m_EndSymbol, value)) SetVerticesDirty(); } + } } } diff --git a/Runtime/Component/Child/LabelStyle.cs b/Runtime/Component/Child/LabelStyle.cs index ef0e3b41..f204c198 100644 --- a/Runtime/Component/Child/LabelStyle.cs +++ b/Runtime/Component/Child/LabelStyle.cs @@ -244,7 +244,12 @@ namespace XCharts.Runtime public bool IsInside() { - return position == Position.Inside || position == Position.Center; + return m_Position == Position.Inside || m_Position == Position.Center; + } + + public bool IsDefaultPosition(Position position) + { + return m_Position == Position.Default || m_Position == position; } public bool IsAutoSize() diff --git a/Runtime/Component/Child/SerieDataBaseInfo.cs b/Runtime/Component/Child/SerieDataBaseInfo.cs new file mode 100644 index 00000000..9bf780a9 --- /dev/null +++ b/Runtime/Component/Child/SerieDataBaseInfo.cs @@ -0,0 +1,33 @@ +using UnityEngine; + +namespace XCharts.Runtime +{ + /// <summary> + /// 数据项的其他基础数据。 + /// </summary> + [System.Serializable] + public class SerieDataBaseInfo : ChildComponent, ISerieDataComponent + { + [SerializeField] private bool m_Ignore = false; + [SerializeField] private bool m_Selected; + [SerializeField] private float m_Radius; + + /// <summary> + /// 是否忽略数据。当为 true 时,数据不进行绘制。 + /// </summary> + public bool ignore + { + get { return m_Ignore; } + set { if (PropertyUtil.SetStruct(ref m_Ignore, value)) SetVerticesDirty(); } + } + /// <summary> + /// 自定义半径。可用在饼图中自定义某个数据项的半径。 + /// </summary> + public float radius { get { return m_Radius; } set { m_Radius = value; } } + /// <summary> + /// Whether the data item is selected. + /// |该数据项是否被选中。 + /// </summary> + public bool selected { get { return m_Selected; } set { m_Selected = value; } } + } +} \ No newline at end of file diff --git a/Runtime/Component/Child/SerieDataBaseInfo.cs.meta b/Runtime/Component/Child/SerieDataBaseInfo.cs.meta new file mode 100644 index 00000000..a311a0e1 --- /dev/null +++ b/Runtime/Component/Child/SerieDataBaseInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6d8757fbd847419aaed450e020e827c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Component/Child/SerieSymbl.cs b/Runtime/Component/Child/SerieSymbl.cs new file mode 100644 index 00000000..4062d684 --- /dev/null +++ b/Runtime/Component/Child/SerieSymbl.cs @@ -0,0 +1,242 @@ + +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace XCharts.Runtime +{ + /// <summary> + /// The way to get serie symbol size. + /// |获取标记图形大小的方式。 + /// </summary> + public enum SymbolSizeType + { + /// <summary> + /// Specify constant for symbol size. + /// |自定义大小。 + /// </summary> + Custom, + /// <summary> + /// Specify the dataIndex and dataScale to calculate symbol size. + /// |通过 dataIndex 从数据中获取,再乘以一个比例系数 dataScale 。 + /// </summary> + FromData, + /// <summary> + /// Specify function for symbol size. + /// |通过委托函数获取。 + /// </summary> + Function, + } + + /// <summary> + /// 系列数据项的标记的图形 + /// </summary> + [System.Serializable] + public class SerieSymbol : SymbolStyle, ISerieDataComponent + { + [SerializeField] private SymbolSizeType m_SizeType = SymbolSizeType.Custom; + [SerializeField] private float m_SelectedSize = 0f; + [SerializeField] private int m_DataIndex = 1; + [SerializeField] private float m_DataScale = 1; + [SerializeField] private float m_SelectedDataScale = 1.5f; + [SerializeField] private SymbolSizeFunction m_SizeFunction; + [SerializeField] private SymbolSizeFunction m_SelectedSizeFunction; + [SerializeField] private int m_StartIndex; + [SerializeField] private int m_Interval; + [SerializeField] private bool m_ForceShowLast = false; + [SerializeField] private bool m_Repeat = false; + + public override void Reset() + { + base.Reset(); + m_SizeType = SymbolSizeType.Custom; + m_SelectedSize = 0f; + m_DataIndex = 1; + m_DataScale = 1; + m_SelectedDataScale = 1.5f; + m_SizeFunction = null; + m_SelectedSizeFunction = null; + m_StartIndex = 0; + m_Interval = 0; + m_ForceShowLast = false; + m_Repeat = false; + } + + /// <summary> + /// the type of symbol size. + /// |标记图形的大小获取方式。 + /// </summary> + public SymbolSizeType sizeType + { + get { return m_SizeType; } + set { if (PropertyUtil.SetStruct(ref m_SizeType, value)) SetVerticesDirty(); } + } + /// <summary> + /// the size of selected symbol. + /// |被选中的标记的大小。 + /// </summary> + public float selectedSize + { + get { return m_SelectedSize; } + set { if (PropertyUtil.SetStruct(ref m_SelectedSize, value)) SetVerticesDirty(); } + } + /// <summary> + /// whitch data index is when the sizeType assined as FromData. + /// |当sizeType指定为FromData时,指定的数据源索引。 + /// </summary> + public int dataIndex + { + get { return m_DataIndex; } + set { if (PropertyUtil.SetStruct(ref m_DataIndex, value)) SetVerticesDirty(); } + } + /// <summary> + /// the scale of data when sizeType assined as FromData. + /// |当sizeType指定为FromData时,指定的倍数系数。 + /// </summary> + public float dataScale + { + get { return m_DataScale; } + set { if (PropertyUtil.SetStruct(ref m_DataScale, value)) SetVerticesDirty(); } + } + /// <summary> + /// the scale of selected data when sizeType assined as FromData. + /// |当sizeType指定为FromData时,指定的高亮倍数系数。 + /// </summary> + public float selectedDataScale + { + get { return m_SelectedDataScale; } + set { if (PropertyUtil.SetStruct(ref m_SelectedDataScale, value)) SetVerticesDirty(); } + } + /// <summary> + /// the function of size when sizeType assined as Function. + /// |当sizeType指定为Function时,指定的委托函数。 + /// </summary> + public SymbolSizeFunction sizeFunction + { + get { return m_SizeFunction; } + set { if (PropertyUtil.SetClass(ref m_SizeFunction, value)) SetVerticesDirty(); } + } + /// <summary> + /// the function of size when sizeType assined as Function. + /// |当sizeType指定为Function时,指定的高亮委托函数。 + /// </summary> + public SymbolSizeFunction selectedSizeFunction + { + get { return m_SelectedSizeFunction; } + set { if (PropertyUtil.SetClass(ref m_SelectedSizeFunction, value)) SetVerticesDirty(); } + } + /// <summary> + /// the index start to show symbol. + /// |开始显示图形标记的索引。 + /// </summary> + public int startIndex + { + get { return m_StartIndex; } + set { if (PropertyUtil.SetStruct(ref m_StartIndex, value)) SetVerticesDirty(); } + } + /// <summary> + /// the interval of show symbol. + /// |显示图形标记的间隔。0表示显示所有标签,1表示隔一个隔显示一个标签,以此类推。 + /// </summary> + public int interval + { + get { return m_Interval; } + set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetVerticesDirty(); } + } + /// <summary> + /// whether to show the last symbol. + /// |是否强制显示最后一个图形标记。 + /// </summary> + public bool forceShowLast + { + get { return m_ForceShowLast; } + set { if (PropertyUtil.SetStruct(ref m_ForceShowLast, value)) SetVerticesDirty(); } + } + /// <summary> + /// 图形是否重复。 + /// </summary> + public bool repeat + { + get { return m_Repeat; } + set { if (PropertyUtil.SetStruct(ref m_Repeat, value)) SetAllDirty(); } + } + /// <summary> + /// 根据指定的sizeType获得标记的大小 + /// </summary> + /// <param name="data"></param> + /// <returns></returns> + public float GetSize(List<double> data, float themeSize) + { + switch (m_SizeType) + { + case SymbolSizeType.Custom: + return size == 0 ? themeSize : size; + case SymbolSizeType.FromData: + if (data != null && dataIndex >= 0 && dataIndex < data.Count) + { + return (float)data[dataIndex] * m_DataScale; + } + else + { + return size == 0 ? themeSize : size; + } + case SymbolSizeType.Function: + if (data != null && sizeFunction != null) return sizeFunction(data); + else return size == 0 ? themeSize : size; + default: return size == 0 ? themeSize : size; + } + } + + /// <summary> + /// 根据sizeType获得高亮时的标记大小 + /// </summary> + /// <param name="data"></param> + /// <returns></returns> + public float GetSelectedSize(List<double> data, float themeSelectedSize) + { + switch (m_SizeType) + { + case SymbolSizeType.Custom: + + return selectedSize == 0 ? themeSelectedSize : selectedSize; + + case SymbolSizeType.FromData: + + if (data != null && dataIndex >= 0 && dataIndex < data.Count) + { + return (float)data[dataIndex] * m_SelectedDataScale; + } + else + { + return selectedSize == 0 ? themeSelectedSize : selectedSize; + } + + case SymbolSizeType.Function: + + if (data != null && selectedSizeFunction != null) + return selectedSizeFunction(data); + else + return selectedSize == 0 ? themeSelectedSize : selectedSize; + + default: return selectedSize == 0 ? themeSelectedSize : selectedSize; + } + } + + public bool ShowSymbol(int dataIndex, int dataCount) + { + if (!show) + return false; + + if (dataIndex < startIndex) + return false; + + if (m_Interval <= 0) + return true; + + if (m_ForceShowLast && dataIndex == dataCount - 1) + return true; + + return (dataIndex - startIndex) % (m_Interval + 1) == 0; + } + } +} diff --git a/Runtime/Component/Child/SerieSymbl.cs.meta b/Runtime/Component/Child/SerieSymbl.cs.meta new file mode 100644 index 00000000..ccbf5333 --- /dev/null +++ b/Runtime/Component/Child/SerieSymbl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd2852f4c46ae4dbd8c105e62dcce9a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Component/Child/SymbolStyle.cs b/Runtime/Component/Child/SymbolStyle.cs index 349f377c..c37d8815 100644 --- a/Runtime/Component/Child/SymbolStyle.cs +++ b/Runtime/Component/Child/SymbolStyle.cs @@ -61,75 +61,31 @@ namespace XCharts.Runtime EmptyArrow } - /// <summary> - /// The way to get serie symbol size. - /// |获取标记图形大小的方式。 - /// </summary> - public enum SymbolSizeType - { - /// <summary> - /// Specify constant for symbol size. - /// |自定义大小。 - /// </summary> - Custom, - /// <summary> - /// Specify the dataIndex and dataScale to calculate symbol size. - /// |通过 dataIndex 从数据中获取,再乘以一个比例系数 dataScale 。 - /// </summary> - FromData, - /// <summary> - /// Specify function for symbol size. - /// |通过委托函数获取。 - /// </summary> - Function, - } - /// <summary> /// 系列数据项的标记的图形 /// </summary> [System.Serializable] - public class SymbolStyle : ChildComponent, ISerieDataComponent + public class SymbolStyle : ChildComponent { - [SerializeField] private bool m_Show = true; - [SerializeField] private SymbolType m_Type = SymbolType.EmptyCircle; - [SerializeField] private SymbolSizeType m_SizeType = SymbolSizeType.Custom; - [SerializeField] private float m_Size = 0f; - [SerializeField] private float m_SelectedSize = 0f; - [SerializeField] private int m_DataIndex = 1; - [SerializeField] private float m_DataScale = 1; - [SerializeField] private float m_SelectedDataScale = 1.5f; - [SerializeField] private SymbolSizeFunction m_SizeFunction; - [SerializeField] private SymbolSizeFunction m_SelectedSizeFunction; - [SerializeField] private int m_StartIndex; - [SerializeField] private int m_Interval; - [SerializeField] private bool m_ForceShowLast = false; - [SerializeField] private float m_Gap = 0; - [SerializeField] private float m_Width = 0f; - [SerializeField] private float m_Height = 0f; - [SerializeField] private bool m_Repeat = false; - [SerializeField] private Vector2 m_Offset = Vector2.zero; - [SerializeField] private Sprite m_Image; - [SerializeField] private Image.Type m_ImageType; + [SerializeField] protected bool m_Show = true; + [SerializeField] protected SymbolType m_Type = SymbolType.EmptyCircle; + [SerializeField] protected float m_Size = 0f; + [SerializeField] protected float m_Gap = 0; + [SerializeField] protected float m_Width = 0f; + [SerializeField] protected float m_Height = 0f; + [SerializeField] protected Vector2 m_Offset = Vector2.zero; + [SerializeField] protected Sprite m_Image; + [SerializeField] protected Image.Type m_ImageType; + [SerializeField] protected Color32 m_Color; - public void Reset() + public virtual void Reset() { m_Show = false; m_Type = SymbolType.EmptyCircle; - m_SizeType = SymbolSizeType.Custom; m_Size = 0f; - m_SelectedSize = 0f; - m_DataIndex = 1; - m_DataScale = 1; - m_SelectedDataScale = 1.5f; - m_SizeFunction = null; - m_SelectedSizeFunction = null; - m_StartIndex = 0; - m_Interval = 0; - m_ForceShowLast = false; m_Gap = 0; m_Width = 0f; m_Height = 0f; - m_Repeat = false; m_Offset = Vector2.zero; m_Image = null; m_ImageType = Image.Type.Simple; @@ -154,15 +110,6 @@ namespace XCharts.Runtime set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); } } /// <summary> - /// the type of symbol size. - /// |标记图形的大小获取方式。 - /// </summary> - public SymbolSizeType sizeType - { - get { return m_SizeType; } - set { if (PropertyUtil.SetStruct(ref m_SizeType, value)) SetVerticesDirty(); } - } - /// <summary> /// the size of symbol. /// |标记的大小。 /// </summary> @@ -172,87 +119,6 @@ namespace XCharts.Runtime set { if (PropertyUtil.SetStruct(ref m_Size, value)) SetVerticesDirty(); } } /// <summary> - /// the size of selected symbol. - /// |被选中的标记的大小。 - /// </summary> - public float selectedSize - { - get { return m_SelectedSize; } - set { if (PropertyUtil.SetStruct(ref m_SelectedSize, value)) SetVerticesDirty(); } - } - /// <summary> - /// whitch data index is when the sizeType assined as FromData. - /// |当sizeType指定为FromData时,指定的数据源索引。 - /// </summary> - public int dataIndex - { - get { return m_DataIndex; } - set { if (PropertyUtil.SetStruct(ref m_DataIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// the scale of data when sizeType assined as FromData. - /// |当sizeType指定为FromData时,指定的倍数系数。 - /// </summary> - public float dataScale - { - get { return m_DataScale; } - set { if (PropertyUtil.SetStruct(ref m_DataScale, value)) SetVerticesDirty(); } - } - /// <summary> - /// the scale of selected data when sizeType assined as FromData. - /// |当sizeType指定为FromData时,指定的高亮倍数系数。 - /// </summary> - public float selectedDataScale - { - get { return m_SelectedDataScale; } - set { if (PropertyUtil.SetStruct(ref m_SelectedDataScale, value)) SetVerticesDirty(); } - } - /// <summary> - /// the function of size when sizeType assined as Function. - /// |当sizeType指定为Function时,指定的委托函数。 - /// </summary> - public SymbolSizeFunction sizeFunction - { - get { return m_SizeFunction; } - set { if (PropertyUtil.SetClass(ref m_SizeFunction, value)) SetVerticesDirty(); } - } - /// <summary> - /// the function of size when sizeType assined as Function. - /// |当sizeType指定为Function时,指定的高亮委托函数。 - /// </summary> - public SymbolSizeFunction selectedSizeFunction - { - get { return m_SelectedSizeFunction; } - set { if (PropertyUtil.SetClass(ref m_SelectedSizeFunction, value)) SetVerticesDirty(); } - } - /// <summary> - /// the index start to show symbol. - /// |开始显示图形标记的索引。 - /// </summary> - public int startIndex - { - get { return m_StartIndex; } - set { if (PropertyUtil.SetStruct(ref m_StartIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// the interval of show symbol. - /// |显示图形标记的间隔。0表示显示所有标签,1表示隔一个隔显示一个标签,以此类推。 - /// </summary> - public int interval - { - get { return m_Interval; } - set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetVerticesDirty(); } - } - /// <summary> - /// whether to show the last symbol. - /// |是否强制显示最后一个图形标记。 - /// </summary> - public bool forceShowLast - { - get { return m_ForceShowLast; } - set { if (PropertyUtil.SetStruct(ref m_ForceShowLast, value)) SetVerticesDirty(); } - } - /// <summary> /// the gap of symbol and line segment. /// |图形标记和线条的间隙距离。 /// </summary> @@ -278,14 +144,6 @@ namespace XCharts.Runtime set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetAllDirty(); } } /// <summary> - /// 图形是否重复。 - /// </summary> - public bool repeat - { - get { return m_Repeat; } - set { if (PropertyUtil.SetStruct(ref m_Repeat, value)) SetAllDirty(); } - } - /// <summary> /// 自定义的标记图形。 /// </summary> public Sprite image @@ -306,6 +164,14 @@ namespace XCharts.Runtime get { return m_Offset; } set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetAllDirty(); } } + /// <summary> + /// 图形的颜色。 + /// </summary> + public Color32 color + { + get { return m_Color; } + set { if (PropertyUtil.SetStruct(ref m_Color, value)) SetAllDirty(); } + } public Vector3 offset3 { get { return new Vector3(m_Offset.x, m_Offset.y, 0); } } private List<float> m_AnimationSize = new List<float>() { 0, 5, 10 }; /// <summary> @@ -313,84 +179,11 @@ namespace XCharts.Runtime /// |带有涟漪特效动画的散点图的动画参数。 /// </summary> public List<float> animationSize { get { return m_AnimationSize; } } + - /// <summary> - /// 根据指定的sizeType获得标记的大小 - /// </summary> - /// <param name="data"></param> - /// <returns></returns> - public float GetSize(List<double> data, float themeSize) + public Color32 GetColor(Color32 defaultColor) { - switch (m_SizeType) - { - case SymbolSizeType.Custom: - return size == 0 ? themeSize : size; - case SymbolSizeType.FromData: - if (data != null && dataIndex >= 0 && dataIndex < data.Count) - { - return (float)data[dataIndex] * m_DataScale; - } - else - { - return size == 0 ? themeSize : size; - } - case SymbolSizeType.Function: - if (data != null && sizeFunction != null) return sizeFunction(data); - else return size == 0 ? themeSize : size; - default: return size == 0 ? themeSize : size; - } - } - - /// <summary> - /// 根据sizeType获得高亮时的标记大小 - /// </summary> - /// <param name="data"></param> - /// <returns></returns> - public float GetSelectedSize(List<double> data, float themeSelectedSize) - { - switch (m_SizeType) - { - case SymbolSizeType.Custom: - - return selectedSize == 0 ? themeSelectedSize : selectedSize; - - case SymbolSizeType.FromData: - - if (data != null && dataIndex >= 0 && dataIndex < data.Count) - { - return (float)data[dataIndex] * m_SelectedDataScale; - } - else - { - return selectedSize == 0 ? themeSelectedSize : selectedSize; - } - - case SymbolSizeType.Function: - - if (data != null && selectedSizeFunction != null) - return selectedSizeFunction(data); - else - return selectedSize == 0 ? themeSelectedSize : selectedSize; - - default: return selectedSize == 0 ? themeSelectedSize : selectedSize; - } - } - - public bool ShowSymbol(int dataIndex, int dataCount) - { - if (!show) - return false; - - if (dataIndex < startIndex) - return false; - - if (m_Interval <= 0) - return true; - - if (m_ForceShowLast && dataIndex == dataCount - 1) - return true; - - return (dataIndex - startIndex) % (m_Interval + 1) == 0; + return ChartHelper.IsClearColor(m_Color) ? defaultColor : m_Color; } } } diff --git a/Runtime/Component/Mark/MarkLineHandler.cs b/Runtime/Component/Mark/MarkLineHandler.cs index ac101863..3b02319e 100644 --- a/Runtime/Component/Mark/MarkLineHandler.cs +++ b/Runtime/Component/Mark/MarkLineHandler.cs @@ -242,11 +242,10 @@ namespace XCharts.Runtime private void DrawMarkLineSymbol(VertexHelper vh, SymbolStyle symbol, Serie serie, GridCoord grid, ThemeStyle theme, Vector3 pos, Vector3 startPos, Color32 lineColor) { - var symbolSize = symbol.GetSize(null, theme.serie.lineSymbolSize); var tickness = SerieHelper.GetSymbolBorder(serie, null, theme, false); var borderColor = SerieHelper.GetSymbolBorderColor(serie, null, theme, false); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, null, false); - chart.DrawClipSymbol(vh, symbol.type, symbolSize, tickness, pos, lineColor, lineColor, + chart.DrawClipSymbol(vh, symbol.type, symbol.size, tickness, pos, lineColor, lineColor, ColorUtil.clearColor32, borderColor, symbol.gap, true, cornerRadius, grid, startPos); } diff --git a/Runtime/Helper/SerieHelper.cs b/Runtime/Helper/SerieHelper.cs index 3fcdc237..3f875f9b 100644 --- a/Runtime/Helper/SerieHelper.cs +++ b/Runtime/Helper/SerieHelper.cs @@ -432,7 +432,7 @@ namespace XCharts.Runtime } } - public static SymbolStyle GetSerieSymbol(Serie serie, SerieData serieData) + public static SerieSymbol GetSerieSymbol(Serie serie, SerieData serieData) { if (!serie.IsPerformanceMode() && serieData.symbol != null) return serieData.symbol; else return serie.symbol; diff --git a/Runtime/Internal/Pools/ObjectPool.cs b/Runtime/Internal/Pools/ObjectPool.cs index 4bc31dc8..7c59b82b 100644 --- a/Runtime/Internal/Pools/ObjectPool.cs +++ b/Runtime/Internal/Pools/ObjectPool.cs @@ -5,7 +5,7 @@ using UnityEngine.Events; namespace XCharts.Runtime { - internal class ObjectPool<T> where T : new() + public class ObjectPool<T> where T : new() { private readonly bool m_NewIfEmpty = true; private readonly Stack<T> m_Stack = new Stack<T>(); diff --git a/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Runtime/Serie/Line/LineHandler.GridCoord.cs index e0a83cfd..226e69c1 100644 --- a/Runtime/Serie/Line/LineHandler.GridCoord.cs +++ b/Runtime/Serie/Line/LineHandler.GridCoord.cs @@ -16,6 +16,22 @@ namespace XCharts.Runtime private GridCoord m_SerieGrid; private float m_LastLineWidth = 0f; + public override Vector3 GetSerieDataLabelOffset(SerieData serieData, LabelStyle label) + { + var invert = label.autoOffset + && SerieHelper.IsDownPoint(serie, serieData.index) + && (serie.areaStyle == null || !serie.areaStyle.show); + if (invert) + { + var offset = label.GetOffset(serie.context.insideRadius); + return new Vector3(offset.x, -offset.y, offset.z); + } + else + { + return label.GetOffset(serie.context.insideRadius); + } + } + private void UpdateSerieGridContext() { if (m_SerieGrid == null) diff --git a/Runtime/Serie/Pie/PieHandler.cs b/Runtime/Serie/Pie/PieHandler.cs index 2aaaedab..00a912c1 100644 --- a/Runtime/Serie/Pie/PieHandler.cs +++ b/Runtime/Serie/Pie/PieHandler.cs @@ -77,8 +77,8 @@ namespace XCharts.Runtime refresh = true; for (int j = 0; j < serie.data.Count; j++) { - if (j == index) serie.data[j].selected = !serie.data[j].selected; - else serie.data[j].selected = false; + if (j == index) serie.data[j].context.selected = !serie.data[j].context.selected; + else serie.data[j].context.selected = false; } if (chart.onPointerClickPie != null) { @@ -406,8 +406,7 @@ namespace XCharts.Runtime var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData); if (serieLabel != null && serieLabel.show && labelLine != null && labelLine.show - && (serieLabel.position == LabelStyle.Position.Outside - || serieLabel.position == LabelStyle.Position.Default)) + && (serieLabel.IsDefaultPosition(LabelStyle.Position.Outside))) { var insideRadius = serieData.context.insideRadius; var outSideRadius = serieData.context.outsideRadius; diff --git a/Runtime/Serie/Serie.cs b/Runtime/Serie/Serie.cs index 3e4864e3..0774405b 100644 --- a/Runtime/Serie/Serie.cs +++ b/Runtime/Serie/Serie.cs @@ -230,7 +230,7 @@ namespace XCharts.Runtime [SerializeField] private bool m_InsertDataToHead; [SerializeField] private LineStyle m_LineStyle = new LineStyle(); - [SerializeField] private SymbolStyle m_Symbol = new SymbolStyle(); + [SerializeField] private SerieSymbol m_Symbol = new SerieSymbol(); [SerializeField] private AnimationStyle m_Animation = new AnimationStyle(); [SerializeField] private ItemStyle m_ItemStyle = new ItemStyle(); [SerializeField] private List<SerieData> m_Data = new List<SerieData>(); @@ -396,7 +396,7 @@ namespace XCharts.Runtime /// the symbol of serie data item. /// |标记的图形。 /// </summary> - public SymbolStyle symbol + public SerieSymbol symbol { get { return m_Symbol; } set { if (PropertyUtil.SetClass(ref m_Symbol, value, true)) SetVerticesDirty(); } @@ -1586,7 +1586,8 @@ namespace XCharts.Runtime public bool IsIgnoreValue(SerieData serieData, int dimension = 1) { - if (serieData.ignore) return true; + if (serieData.baseInfo != null && serieData.baseInfo.ignore) + return true; return IsIgnoreValue(serieData.GetData(dimension)); } diff --git a/Runtime/Serie/SerieData.cs b/Runtime/Serie/SerieData.cs index a08cd5a4..e475c93a 100644 --- a/Runtime/Serie/SerieData.cs +++ b/Runtime/Serie/SerieData.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using UnityEngine; +using XUGL; namespace XCharts.Runtime { @@ -16,11 +17,12 @@ namespace XCharts.Runtime [SerializeField] private string m_Name; [SerializeField] private string m_Id; [SerializeField] private string m_ParentId; + [SerializeField] private List<SerieDataBaseInfo> m_BaseInfos = new List<SerieDataBaseInfo>(); [SerializeField] private List<ItemStyle> m_ItemStyles = new List<ItemStyle>(); [SerializeField] private List<LabelStyle> m_Labels = new List<LabelStyle>(); [SerializeField] private List<LabelLine> m_LabelLines = new List<LabelLine>(); [SerializeField] private List<Emphasis> m_Emphases = new List<Emphasis>(); - [SerializeField] private List<SymbolStyle> m_Symbols = new List<SymbolStyle>(); + [SerializeField] private List<SerieSymbol> m_Symbols = new List<SerieSymbol>(); [SerializeField] private List<LineStyle> m_LineStyles = new List<LineStyle>(); [SerializeField] private List<AreaStyle> m_AreaStyles = new List<AreaStyle>(); [SerializeField] private List<TitleStyle> m_TitleStyles = new List<TitleStyle>(); @@ -28,9 +30,7 @@ namespace XCharts.Runtime [NonSerialized] public SerieDataContext context = new SerieDataContext(); [NonSerialized] public InteractData interact = new InteractData(); - [NonSerialized] private bool m_Ignore = false; - [NonSerialized] private bool m_Selected; - [NonSerialized] private float m_Radius; + public ChartLabel labelObject { get; set; } public ChartLabel titleObject { get; set; } @@ -52,15 +52,8 @@ namespace XCharts.Runtime /// </summary> /// <value></value> public string legendName { get { return string.IsNullOrEmpty(name) ? ChartCached.IntToStr(index) : name; } } - /// <summary> - /// 自定义半径。可用在饼图中自定义某个数据项的半径。 - /// </summary> - public float radius { get { return m_Radius; } set { m_Radius = value; } } - /// <summary> - /// Whether the data item is selected. - /// |该数据项是否被选中。 - /// </summary> - public bool selected { get { return m_Selected; } set { m_Selected = value; } } + + public SerieDataBaseInfo baseInfo { get { return m_BaseInfos.Count > 0 ? m_BaseInfos[0] : null; } } /// <summary> /// 单个数据项的标签设置。 /// </summary> @@ -77,18 +70,11 @@ namespace XCharts.Runtime /// <summary> /// 单个数据项的标记设置。 /// </summary> - public SymbolStyle symbol { get { return m_Symbols.Count > 0 ? m_Symbols[0] : null; } } + public SerieSymbol symbol { get { return m_Symbols.Count > 0 ? m_Symbols[0] : null; } } public LineStyle lineStyle { get { return m_LineStyles.Count > 0 ? m_LineStyles[0] : null; } } public AreaStyle areaStyle { get { return m_AreaStyles.Count > 0 ? m_AreaStyles[0] : null; } } public TitleStyle titleStyle { get { return m_TitleStyles.Count > 0 ? m_TitleStyles[0] : null; } } - /// <summary> - /// 是否忽略数据。当为 true 时,数据不进行绘制。 - /// </summary> - public bool ignore - { - get { return m_Ignore; } - set { if (PropertyUtil.SetStruct(ref m_Ignore, value)) SetVerticesDirty(); } - } + /// <summary> /// An arbitrary dimension data list of data item. /// |可指定任意维数的数值列表。 @@ -99,6 +85,8 @@ namespace XCharts.Runtime /// |该数据项是否要显示。 /// </summary> public bool show { get { return m_Show; } set { m_Show = value; } } + public float radius { get { return baseInfo != null ? baseInfo.radius : 0; } } + public bool selected { get { return (baseInfo != null && baseInfo.selected) || context.selected; } } private List<double> m_PreviousData = new List<double>(); private List<float> m_DataUpdateTime = new List<float>(); @@ -110,6 +98,7 @@ namespace XCharts.Runtime get { return m_VertsDirty + || (baseInfo != null && baseInfo.vertsDirty) || (labelLine != null && labelLine.vertsDirty) || (itemStyle != null && itemStyle.vertsDirty) || (symbol != null && symbol.vertsDirty) @@ -122,6 +111,7 @@ namespace XCharts.Runtime get { return m_ComponentDirty + || (baseInfo != null && baseInfo.componentDirty) || (labelStyle != null && labelStyle.componentDirty) || (labelLine != null && labelLine.componentDirty) || (titleStyle != null && titleStyle.componentDirty) @@ -132,6 +122,7 @@ namespace XCharts.Runtime public override void ClearVerticesDirty() { base.ClearVerticesDirty(); + if (baseInfo != null) baseInfo.ClearVerticesDirty(); if (labelLine != null) labelLine.ClearVerticesDirty(); if (itemStyle != null) itemStyle.ClearVerticesDirty(); if (lineStyle != null) lineStyle.ClearVerticesDirty(); @@ -144,6 +135,7 @@ namespace XCharts.Runtime public override void ClearComponentDirty() { base.ClearComponentDirty(); + if (baseInfo != null) baseInfo.ClearComponentDirty(); if (labelLine != null) labelLine.ClearComponentDirty(); if (itemStyle != null) itemStyle.ClearComponentDirty(); if (lineStyle != null) lineStyle.ClearComponentDirty(); @@ -161,14 +153,13 @@ namespace XCharts.Runtime labelObject = null; m_Name = string.Empty; m_Show = true; - m_Selected = false; - m_Radius = 0; context.Reset(); interact.Reset(); m_Data.Clear(); m_PreviousData.Clear(); m_DataUpdateTime.Clear(); m_DataUpdateFlag.Clear(); + m_BaseInfos.Clear(); m_Labels.Clear(); m_LabelLines.Clear(); m_ItemStyles.Clear(); @@ -188,6 +179,12 @@ namespace XCharts.Runtime m_ItemStyles.Add(new ItemStyle() { show = true }); return m_ItemStyles[0] as T; } + else if (type == typeof(SerieDataBaseInfo)) + { + if (m_BaseInfos.Count == 0) + m_BaseInfos.Add(new SerieDataBaseInfo() { }); + return m_BaseInfos[0] as T; + } else if (type == typeof(LabelStyle)) { if (m_Labels.Count == 0) @@ -206,10 +203,10 @@ namespace XCharts.Runtime m_Emphases.Add(new Emphasis() { show = true }); return m_Emphases[0] as T; } - else if (type == typeof(SymbolStyle)) + else if (type == typeof(SerieSymbol)) { if (m_Symbols.Count == 0) - m_Symbols.Add(new SymbolStyle() { show = true }); + m_Symbols.Add(new SerieSymbol() { show = true }); return m_Symbols[0] as T; } else if (type == typeof(LineStyle)) @@ -238,6 +235,7 @@ namespace XCharts.Runtime public void RemoveAllComponent() { + m_BaseInfos.Clear(); m_ItemStyles.Clear(); m_Labels.Clear(); m_LabelLines.Clear(); @@ -253,13 +251,15 @@ namespace XCharts.Runtime var type = typeof(T); if (type == typeof(ItemStyle)) m_ItemStyles.Clear(); + else if (type == typeof(SerieDataBaseInfo)) + m_BaseInfos.Clear(); else if (type == typeof(LabelStyle)) m_Labels.Clear(); else if (type == typeof(LabelLine)) m_LabelLines.Clear(); else if (type == typeof(Emphasis)) m_Emphases.Clear(); - else if (type == typeof(SymbolStyle)) + else if (type == typeof(SerieSymbol)) m_Symbols.Clear(); else if (type == typeof(LineStyle)) m_LineStyles.Clear(); @@ -482,18 +482,7 @@ namespace XCharts.Runtime public bool IsInPolygon(Vector2 p) { - if (m_PolygonPoints.Count == 0) return false; - var inside = false; - var j = m_PolygonPoints.Count - 1; - for (int i = 0; i < m_PolygonPoints.Count; j = i++) - { - var pi = m_PolygonPoints[i]; - var pj = m_PolygonPoints[j]; - if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) && - (p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x)) - inside = !inside; - } - return inside; + return UGLHelper.IsPointInPolygon(p, m_PolygonPoints); } } } diff --git a/Runtime/Serie/SerieDataContext.cs b/Runtime/Serie/SerieDataContext.cs index fea5bac3..17ca5aba 100644 --- a/Runtime/Serie/SerieDataContext.cs +++ b/Runtime/Serie/SerieDataContext.cs @@ -48,6 +48,7 @@ namespace XCharts.Runtime public double area; public float angle; public Vector3 offsetCenter; + public Vector3 areaCenter; public float stackHeight; public bool isClip; public bool canShowLabel = true; @@ -57,6 +58,7 @@ namespace XCharts.Runtime /// |该数据项是否被高亮,一般由鼠标悬停或图例悬停触发高亮。 /// </summary> public bool highlight; + public bool selected; public void Reset() { diff --git a/Runtime/Serie/SerieHandler.cs b/Runtime/Serie/SerieHandler.cs index 1a0e5225..81cbffa1 100644 --- a/Runtime/Serie/SerieHandler.cs +++ b/Runtime/Serie/SerieHandler.cs @@ -395,15 +395,9 @@ namespace XCharts.Runtime private void UpdateLabelPosition(SerieData serieData, LabelStyle currLabel) { - var isNeedInvertPositionSerie = serie is Line; - var invert = currLabel.autoOffset - && isNeedInvertPositionSerie - && SerieHelper.IsDownPoint(serie, serieData.index) - && (serie.areaStyle == null || !serie.areaStyle.show); var labelPosition = GetSerieDataLabelPosition(serieData, currLabel); - var offset = currLabel.GetOffset(serie.context.insideRadius); - serieData.labelObject.SetPosition(labelPosition - + (invert ? -offset : offset)); + var offset = GetSerieDataLabelOffset(serieData, currLabel); + serieData.labelObject.SetPosition(labelPosition + offset); } public virtual Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label) @@ -411,6 +405,11 @@ namespace XCharts.Runtime return serieData.context.position; } + public virtual Vector3 GetSerieDataLabelOffset(SerieData serieData, LabelStyle label) + { + return label.GetOffset(serie.context.insideRadius); + } + public virtual Vector3 GetSerieDataTitlePosition(SerieData serieData, TitleStyle titleStyle) { return serieData.context.position; diff --git a/Runtime/XUGL/UGLHelper.cs b/Runtime/XUGL/UGLHelper.cs index 922783a3..da775b82 100644 --- a/Runtime/XUGL/UGLHelper.cs +++ b/Runtime/XUGL/UGLHelper.cs @@ -355,5 +355,36 @@ namespace XUGL var c3 = dire3.x * dire1.y - dire3.y * dire1.x; return c1 * c2 >= 0 && c1 * c3 >= 0; } + + public static bool IsPointInPolygon(Vector3 p, List<Vector3> polyons) + { + if (polyons.Count == 0) return false; + var inside = false; + var j = polyons.Count - 1; + for (int i = 0; i < polyons.Count; j = i++) + { + var pi = polyons[i]; + var pj = polyons[j]; + if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) && + (p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x)) + inside = !inside; + } + return inside; + } + public static bool IsPointInPolygon(Vector3 p, List<Vector2> polyons) + { + if (polyons.Count == 0) return false; + var inside = false; + var j = polyons.Count - 1; + for (int i = 0; i < polyons.Count; j = i++) + { + var pi = polyons[i]; + var pj = polyons[j]; + if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) && + (p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x)) + inside = !inside; + } + return inside; + } } } \ No newline at end of file