using System; using System.Collections.Generic; using UnityEngine; namespace XCharts.Runtime { public partial class BaseChart { public bool TryAddChartComponent() where T : MainComponent { return TryAddChartComponent(typeof(T)); } public bool TryAddChartComponent(Type type) { if (CanAddChartComponent(type)) { AddChartComponent(type); return true; } else { return false; } } public bool TryAddChartComponent(out T component) where T : MainComponent { var type = typeof(T); if (CanAddChartComponent(type)) { component = AddChartComponent(type) as T; return true; } else { component = null; return false; } } public T AddChartComponent() where T : MainComponent { return (T) AddChartComponent(typeof(T)); } public T AddChartComponentWhenNoExist() where T : MainComponent { if (HasChartComponent()) return null; return AddChartComponent(); } public MainComponent AddChartComponent(Type type) { if (!CanAddChartComponent(type)) { Debug.LogError("XCharts ERROR: CanAddChartComponent:" + type.Name); return null; } CheckAddRequireChartComponent(type); var component = Activator.CreateInstance(type) as MainComponent; if (component == null) { Debug.LogError("XCharts ERROR: CanAddChartComponent:" + type.Name); return null; } component.SetDefaultValue(); if (component is IUpdateRuntimeData) (component as IUpdateRuntimeData).UpdateRuntimeData(chartX, chartY, chartWidth, chartHeight); AddComponent(component); m_Components.Sort(); CreateComponentHandler(component); #if UNITY_EDITOR && UNITY_2019_1_OR_NEWER UnityEditor.EditorUtility.SetDirty(this); #endif return component; } private void AddComponent(MainComponent component) { var type = component.GetType(); m_Components.Add(component); List list; if (!m_ComponentMaps.TryGetValue(type, out list)) { list = new List(); m_ComponentMaps[type] = list; } component.index = list.Count; list.Add(component); } private void CheckAddRequireChartComponent(Type type) { if (Attribute.IsDefined(type, typeof(RequireChartComponentAttribute))) { foreach (var obj in type.GetCustomAttributes(typeof(RequireChartComponentAttribute), false)) { var attribute = obj as RequireChartComponentAttribute; if (attribute.type0 != null && !HasChartComponent(attribute.type0)) AddChartComponent(attribute.type0); if (attribute.type1 != null && !HasChartComponent(attribute.type1)) AddChartComponent(attribute.type1); if (attribute.type2 != null && !HasChartComponent(attribute.type2)) AddChartComponent(attribute.type2); } } } private void CreateComponentHandler(MainComponent component) { if (!component.GetType().IsDefined(typeof(ComponentHandlerAttribute), false)) { Debug.LogError("MainComponent no Handler:" + component.GetType()); return; } var attrubte = component.GetType().GetAttribute(); if (attrubte.handler == null) return; var handler = (MainComponentHandler) Activator.CreateInstance(attrubte.handler); handler.attribute = attrubte; handler.chart = this; handler.SetComponent(component); component.handler = handler; m_ComponentHandlers.Add(handler); } public bool RemoveChartComponent(int index = 0) where T : MainComponent { return RemoveChartComponent(typeof(T), index); } public int RemoveChartComponents() where T : MainComponent { return RemoveChartComponents(typeof(T)); } public void RemoveAllChartComponent() { m_Components.Clear(); InitComponentHandlers(); } public bool RemoveChartComponent(Type type, int index = 0) { MainComponent toRemove = null; for (int i = 0; i < m_Components.Count; i++) { if (m_Components[i].GetType() == type && m_Components[i].index == index) { toRemove = m_Components[i]; break; } } return RemoveChartComponent(toRemove); } public int RemoveChartComponents(Type type) { int count = 0; for (int i = m_Components.Count - 1; i > 0; i--) { if (m_Components[i].GetType() == type) { RemoveChartComponent(m_Components[i]); count++; } } return count; } public bool RemoveChartComponent(MainComponent component) { if (component == null) return false; if (m_Components.Remove(component)) { if (component.gameObject != null) ChartHelper.SetActive(component.gameObject, false); InitComponentHandlers(); RefreshChart(); return true; } return false; } public bool CanAddChartComponent(Type type) { if (!type.IsSubclassOf(typeof(MainComponent))) return false; if (!m_TypeListForComponent.ContainsKey(type)) return false; if (CanMultipleComponent(type)) return !HasChartComponent(type); else return true; } public bool HasChartComponent() where T : MainComponent { return HasChartComponent(typeof(T)); } public bool HasChartComponent(Type type) { foreach (var component in m_Components) { if (component == null) continue; if (component.GetType() == type) return true; } return false; } public bool CanMultipleComponent(Type type) { return Attribute.IsDefined(type, typeof(DisallowMultipleComponent)); } public int GetChartComponentNum() where T : MainComponent { return GetChartComponentNum(typeof(T)); } public int GetChartComponentNum(Type type) { List list; if (m_ComponentMaps.TryGetValue(type, out list)) return list.Count; else return 0; } public T GetChartComponent(int index = 0) where T : MainComponent { foreach (var component in m_Components) { if (component is T && component.index == index) return component as T; } return null; } public List GetChartComponents() where T : MainComponent { return m_ComponentMaps[typeof(T)]; } public T GetOrAddChartComponent() where T : MainComponent { var component = GetChartComponent(); if (component == null) return AddChartComponent(); else return component; } public bool TryGetChartComponent(out T component, int index = 0) where T : MainComponent { component = null; foreach (var com in m_Components) { if (com is T && com.index == index) { component = (T) com; return true; } } return false; } public GridCoord GetGrid(Vector2 local) { List list; if (m_ComponentMaps.TryGetValue(typeof(GridCoord), out list)) { foreach (var component in list) { var grid = component as GridCoord; if (grid.Contains(local)) return grid; } } return null; } public GridCoord GetGridOfDataZoom(DataZoom dataZoom) { GridCoord grid = null; if (dataZoom.xAxisIndexs != null && dataZoom.xAxisIndexs.Count > 0) { var xAxis = GetChartComponent(dataZoom.xAxisIndexs[0]); grid = GetChartComponent(xAxis.gridIndex); } else if (dataZoom.yAxisIndexs != null && dataZoom.yAxisIndexs.Count > 0) { var yAxis = GetChartComponent(dataZoom.yAxisIndexs[0]); grid = GetChartComponent(yAxis.gridIndex); } if (grid == null) return GetChartComponent(); else return grid; } public DataZoom GetDataZoomOfAxis(Axis axis) { foreach (var component in m_Components) { if (component is DataZoom) { var dataZoom = component as DataZoom; if (!dataZoom.enable) continue; if (dataZoom.IsContainsAxis(axis)) return dataZoom; } } return null; } public VisualMap GetVisualMapOfSerie(Serie serie) { foreach (var component in m_Components) { if (component is VisualMap) { var visualMap = component as VisualMap; if (visualMap.serieIndex == serie.index) return visualMap; } } return null; } public void GetDataZoomOfSerie(Serie serie, out DataZoom xDataZoom, out DataZoom yDataZoom) { xDataZoom = null; yDataZoom = null; if (serie == null) return; foreach (var component in m_Components) { if (component is DataZoom) { var dataZoom = component as DataZoom; if (!dataZoom.enable) continue; if (dataZoom.IsContainsXAxis(serie.xAxisIndex)) { xDataZoom = dataZoom; } if (dataZoom.IsContainsYAxis(serie.yAxisIndex)) { yDataZoom = dataZoom; } } } } /// /// reutrn true when all the show axis is `Value` type. /// |纯数值坐标轴(数值轴或对数轴)。 /// public bool IsAllAxisValue() { foreach (var component in m_Components) { if (component is Axis) { var axis = component as Axis; if (axis.show && !axis.IsValue() && !axis.IsLog() && !axis.IsTime()) return false; } } return true; } /// /// 纯类目轴。 /// public bool IsAllAxisCategory() { foreach (var component in m_Components) { if (component is Axis) { var axis = component as Axis; if (axis.show && !axis.IsCategory()) return false; } } return true; } public bool IsInAnyGrid(Vector2 local) { List list; if (m_ComponentMaps.TryGetValue(typeof(GridCoord), out list)) { foreach (var grid in list) { if ((grid as GridCoord).Contains(local)) return true; } } return false; } internal string GetTooltipCategory(int dataIndex, DataZoom dataZoom = null) { var xAxis = GetChartComponent(); var yAxis = GetChartComponent(); if (yAxis.IsCategory()) { return yAxis.GetData((int) yAxis.context.pointerValue, dataZoom); } else if (xAxis.IsCategory()) { return xAxis.GetData((int) xAxis.context.pointerValue, dataZoom); } return null; } internal string GetTooltipCategory(int dataIndex, Serie serie, DataZoom dataZoom = null) { var xAxis = GetChartComponent(serie.xAxisIndex); var yAxis = GetChartComponent(serie.yAxisIndex); if (yAxis.IsCategory()) { return yAxis.GetData((int) yAxis.context.pointerValue, dataZoom); } else if (xAxis.IsCategory()) { return xAxis.GetData((int) xAxis.context.pointerValue, dataZoom); } return null; } } }