#define Graph_And_Chart_PRO using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace ChartAndGraph { public abstract class ScrollableChartData : IChartData, IMixedSeriesProxy { protected List mSliders = new List(); protected Dictionary mData = new Dictionary(); protected event EventHandler DataChanged; protected event EventHandler ViewPortionChanged; protected event Action RealtimeDataChanged; protected bool mSuspendEvents = false; [SerializeField] private double automaticVerticalViewGap = 0f; /// /// call this to suspend chart redrawing while updating the data of the chart /// public void StartBatch() { mSuspendEvents = true; } /// /// call this after StartBatch , this will apply all the changed made between the StartBatch call to this call /// public void EndBatch() { mSuspendEvents = false; RaiseDataChanged(); } /// set this to true to automatically detect the horizontal size of the graph chart /// public double AutomaticVerticallViewGap { get { return automaticVerticalViewGap; } set { automaticVerticalViewGap = value; RestoreDataValues(); RaiseViewPortionChanged(); } } /// /// set this to true to automatically detect the horizontal size of the graph chart /// [SerializeField] private bool automaticVerticallView = true; /// /// set this to true to automatically detect the horizontal size of the graph chart /// public bool AutomaticVerticallView { get { return automaticVerticallView; } set { automaticVerticallView = value; RestoreDataValues(); RaiseViewPortionChanged(); } } [SerializeField] private double automaticcHorizontaViewGap = 0f; /// set this to true to automatically detect the horizontal size of the graph chart /// public double AutomaticcHorizontaViewGap { get { return automaticcHorizontaViewGap; } set { automaticcHorizontaViewGap = value; RestoreDataValues(); RaiseViewPortionChanged(); } } /// /// set this to true to automatically detect the horizontal size of the graph chart /// [SerializeField] private bool automaticHorizontalView = true; /// /// set this to true to automatically detect the horizontal size of the graph chart /// public bool AutomaticHorizontalView { get { return automaticHorizontalView; } set { automaticHorizontalView = value; RestoreDataValues(); RaiseViewPortionChanged(); } } [SerializeField] private double horizontalViewSize = 100; /// /// Mannualy set the horizontal view size. /// public double HorizontalViewSize { get { return horizontalViewSize; } set { horizontalViewSize = value; RaiseViewPortionChanged(); } } [SerializeField] private double horizontalViewOrigin = 0; /// /// Mannualy set the horizontal view origin. /// public double HorizontalViewOrigin { get { return horizontalViewOrigin; } set { horizontalViewOrigin = value; RaiseViewPortionChanged(); } } [SerializeField] private double verticalViewSize = 100; /// /// Mannualy set the horizontal view size. /// public double VerticalViewSize { get { return verticalViewSize; } set { verticalViewSize = value; RaiseViewPortionChanged(); } } /// /// clears all graph data /// public void Clear() { mSliders.Clear(); mData.Clear(); RaiseDataChanged(); } [SerializeField] private double verticalViewOrigin = 0; /// /// Mannualy set the horizontal view origin. /// public double VerticalViewOrigin { get { return verticalViewOrigin; } set { verticalViewOrigin = value; RaiseViewPortionChanged(); } } public virtual void Update() { //bool updated = mSliders.Count > 0; mSliders.RemoveAll(x => { bool res = x.Update(); // if(res == false) // { RaiseRealtimeDataChanged(x.MinIndex,x.Category); // } return res; }); } /// /// returns true if the data contains a category by the given name /// /// /// public bool HasCategory(string category) { return mData.ContainsKey(category); } protected void ModifyMinMax(BaseScrollableCategoryData data, DoubleVector3 point) { if (data.MaxRadius.HasValue == false || data.MaxRadius.Value < point.z) data.MaxRadius = point.z; if (data.MaxX.HasValue == false || data.MaxX.Value < point.x) data.MaxX = point.x; if (data.MinX.HasValue == false || data.MinX.Value > point.x) data.MinX = point.x; if (data.MaxY.HasValue == false || data.MaxY.Value < point.y) data.MaxY = point.y; if (data.MinY.HasValue == false || data.MinY.Value > point.y) data.MinY = point.y; } public double GetMaxYValue() { return GetMaxValue(1, true); } public double GetMaxXValue() { return GetMaxValue(0, true); } public double GetMinYValue() { return GetMinValue(1, true); } public double GetMinXValue() { return GetMinValue(0, true); } public virtual double GetMaxValue(int axis, bool dataValue) { if (dataValue == false) { if (axis == 0 && automaticHorizontalView == false) { double axisAdd = horizontalViewSize; if (Math.Abs(axisAdd) < 0.0001f) { if (axisAdd < 0) axisAdd = -0.0001f; else axisAdd = 0.0001f; } return HorizontalViewOrigin + axisAdd; } if (axis == 1 && AutomaticVerticallView == false) { double axisAdd = verticalViewSize; if (Math.Abs(axisAdd) < 0.0001f) { if (axisAdd < 0) axisAdd = -0.0001f; else axisAdd = 0.0001f; } return VerticalViewOrigin + axisAdd; } } double? res = null; double add = 0; foreach (BaseScrollableCategoryData cat in mData.Values) { if (cat.Enabled == false) continue; if (cat.MaxRadius.HasValue && add < cat.MaxRadius) add = cat.MaxRadius.Value; if (axis == 0) { if (res.HasValue == false || (cat.MaxX.HasValue && res.Value < cat.MaxX)) res = cat.MaxX; } else { if (res.HasValue == false || (cat.MaxY.HasValue && res.Value < cat.MaxY)) res = cat.MaxY; } } for(int i=0; i cat.MinX)) res = cat.MinX; } else { if (res.HasValue == false || (cat.MinY.HasValue && res.Value > cat.MinY)) res = cat.MinY; } } for (int i = 0; i < mSliders.Count; i++) { BaseSlider s = mSliders[i]; if (axis == 0) res = ChartCommon.Min(res, s.Max.x); else res = ChartCommon.Min(res, s.Max.y); } if (res.HasValue == false) return 0.0; double max = GetMaxValue(axis, dataValue); if (max == res.Value) { if (res.Value == 0.0) return -10.0f; return 0.0; } double gap = (axis == 0) ? automaticcHorizontaViewGap : automaticVerticalViewGap; return res.Value - add - gap; } protected void RaiseRealtimeDataChanged(int index,string category) { if (mSuspendEvents) return; if (RealtimeDataChanged != null) RealtimeDataChanged(index, category); } protected void RaiseViewPortionChanged() { if (mSuspendEvents) return; if (ViewPortionChanged != null) ViewPortionChanged(this, EventArgs.Empty); } protected void RaiseDataChanged() { if (mSuspendEvents) return; if (DataChanged != null) DataChanged(this, EventArgs.Empty); } public void RestoreDataValues() { if (automaticHorizontalView) RestoreDataValues(0); if (AutomaticVerticallView) RestoreDataValues(1); } public void RestoreDataValues(int axis) { if (axis == 0) { double maxH = GetMaxValue(0, true); double minH = GetMinValue(0, true); horizontalViewOrigin = minH; horizontalViewSize = maxH - minH; } else { double maxV = GetMaxValue(1, true); double minV = GetMinValue(1, true); verticalViewOrigin = minV; verticalViewSize = maxV - minV; } } /// /// clears the specified category from any data /// /// protected abstract void InnerClearCategory(string category); /// /// Adds a new category based on a BaseScrollableCategoryData object /// /// /// /// protected abstract bool AddCategory(string category, BaseScrollableCategoryData data); protected abstract void AppendDatum(string category, MixedSeriesGenericValue value); protected abstract void AppendDatum(string category, IList value); /// /// instanciates a new category object with default settings. returns nulls if not supported /// /// public abstract BaseScrollableCategoryData GetDefaultCategory(); public abstract void OnAfterDeserialize(); public abstract void OnBeforeSerialize(); bool IMixedSeriesProxy.AddCategory(string category, BaseScrollableCategoryData data) { return AddCategory(category, data); } bool IMixedSeriesProxy.HasCategory(string catgeory) { return mData.ContainsKey(catgeory); } void IMixedSeriesProxy.ClearCategory(string category) { InnerClearCategory(category); } void IMixedSeriesProxy.AppendDatum(string category, MixedSeriesGenericValue value) { AppendDatum(category, value); } void IMixedSeriesProxy.AppendDatum(string category, IList value) { AppendDatum(category, value); } } }