using ChartAndGraph; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace Assets.Scenes.Ride.Scripts { public class ChartDataSourceScript:MonoBehaviour, IComparer { public string Category = "Player 2"; public int DownSampleToPoints = 100; List mData = new List(); // the data held by the chart double pageSize = 2f; double currentPagePosition = 0.0; double currentZoom = 0f; GraphChartBase graph; double mCurrentPageSizeFactor = double.NegativeInfinity; private void Start() { graph = GetComponent(); } bool VerifySorted(List data) { if (data == null) return true; for (int i = 1; i < data.Count; i++) { if (data[i].x < data[i - 1].x) return false; } return true; } void LoadWithoutDownSampling(int start, int end) { for (int i = start; i < end; i++) // load the data { graph.DataSource.AddPointToCategory("Player 2", mData[i].x, mData[i].y); } } public int total; void LoadWithDownSampling(int start, int end) { total = end - start; if (DownSampleToPoints >= total) { graph.DataSource.HorizontalViewSize = total; LoadWithoutDownSampling(start, end); return; } double sampleCount = ((double)total) / (double)DownSampleToPoints; // graph.DataSource.AddPointToCategory(Category, mData[start].x, mData[start].y); for (int i = 0; i < DownSampleToPoints; i++) { int fractionStart = start + (int)(i * sampleCount); // the first point with a fraction int fractionEnd = start + (int)((i + 1) * sampleCount); // the first point with a fraction fractionEnd = Math.Min(fractionEnd, mData.Count - 1); double x = 0, y = 0; double divide = 0.0; for (int j = fractionStart; j < fractionEnd; j++) // avarge the poins { x += mData[j].x; y += mData[j].y; divide++; } if (divide > 0.0) { x /= divide; y /= divide; graph.DataSource.AddPointToCategory("Player 2", x, y); } else Debug.Log("error"); } // graph.DataSource.AddPointToCategory(Category, mData[last].x, mData[last].y); } int FindClosestIndex(double position) // if you want to know what is index is currently displayed . use binary search to find it { //NOTE :: this method assumes your data is sorted !!! int res = mData.BinarySearch(new DoubleVector2(position, 0.0), this); if (res >= 0) return res; return ~res; } double PageSizeFactor { get { return pageSize * graph.DataSource.HorizontalViewSize; } } void findPointsForPage(double position, out int start, out int end) // given a page position , find the right most and left most indices in the data for that page. { int index = FindClosestIndex(position); // use binary search to find the closest position to the current scroll point double endPosition = position + PageSizeFactor; double startPosition = position - PageSizeFactor; //starting from the current index , we find the page boundries for (start = index; start > 0; start--) { if (mData[start].x < startPosition) // take the first point that is out of the page. so the graph doesn't break at the edge break; } for (end = index; end < mData.Count; end++) { if (mData[end].x > endPosition) // take the first point that is out of the page break; } } void LoadPage(double pagePosition) { if (graph != null) { Debug.Log("Loading page :" + pagePosition); graph.DataSource.StartBatch(); // call start batch graph.DataSource.HorizontalViewOrigin = 0; int start, end; findPointsForPage(pagePosition, out start, out end); // get the page edges graph.DataSource.ClearCategory("Player 2"); // clear the cateogry if (DownSampleToPoints <= 0) LoadWithoutDownSampling(start, end); else LoadWithDownSampling(start, end); graph.DataSource.EndBatch(); graph.HorizontalScrolling = pagePosition; } currentPagePosition = pagePosition; } public void SetData(List data) { if (data == null) data = new List(); // set up an empty list instead of null if (VerifySorted(data) == false) { Debug.LogWarning("The data used with large data feed must be sorted acoording to the x value, aborting operation"); return; } mData = data; LoadPage(currentPagePosition); // load the page at position 0 } public void SetDataSource(double[] data) { graph = GetComponent(); List source = new List(); for (int i = 0; i < data.Length; i++) // initialize with random data { source.Add(new DoubleVector2(i, data[i])); } SetData(source); } public int Compare(DoubleVector2 x, DoubleVector2 y) { if (x.x < y.x) return -1; if (x.x > y.x) return 1; return 0; } public void Update() { if (graph != null) { //check the scrolling position of the graph. if we are past the view size , load a new page double pageStartThreshold = currentPagePosition - mCurrentPageSizeFactor; double pageEndThreshold = currentPagePosition + mCurrentPageSizeFactor - graph.DataSource.HorizontalViewSize; if (graph.HorizontalScrolling < pageStartThreshold || graph.HorizontalScrolling > pageEndThreshold || currentZoom >= graph.DataSource.HorizontalViewSize * 2f) { currentZoom = graph.DataSource.HorizontalViewSize; mCurrentPageSizeFactor = PageSizeFactor * 0.9f; LoadPage(graph.HorizontalScrolling); } } } } }