graph chart引入&骑行结果弹窗
This commit is contained in:
1 parent
40d118cea3
commit
96f3644b5b
2374 files changed
+485161
-2410
No files matched your search
@@ -0,0 +1,618 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public partial class GraphChart : GraphChartBase, ICanvas
|
||||
{
|
||||
HashSet<string> mOccupiedCateogies = new HashSet<string>();
|
||||
Dictionary<string, CategoryObject> mCategoryObjects = new Dictionary<string, CategoryObject>();
|
||||
List<DoubleVector3> mTmpData = new List<DoubleVector3>();
|
||||
List<DoubleVector4> mClipped = new List<DoubleVector4>();
|
||||
List<Vector4> mTransformed = new List<Vector4>();
|
||||
List<int> mTmpToRemove = new List<int>();
|
||||
private bool SupressRealtimeGeneration = false;
|
||||
private StringBuilder mRealtimeStringBuilder = new StringBuilder();
|
||||
|
||||
/// <summary>
|
||||
/// occures when a point is clicked
|
||||
/// </summary>
|
||||
public GraphEvent LineClicked = new GraphEvent();
|
||||
/// <summary>
|
||||
/// occurs when a point is hovered
|
||||
/// </summary>
|
||||
public GraphEvent LineHovered = new GraphEvent();
|
||||
|
||||
protected void OnLineSelected(object userData)
|
||||
{
|
||||
GraphEventArgs args = userData as GraphEventArgs;
|
||||
if (LineClicked != null)
|
||||
LineClicked.Invoke(args);
|
||||
AddOccupiedCategory(args.Category, "line");
|
||||
}
|
||||
|
||||
protected void OnLineHovered(object userData)
|
||||
{
|
||||
GraphEventArgs args = userData as GraphEventArgs;
|
||||
if (LineHovered != null)
|
||||
LineHovered.Invoke(args);
|
||||
AddOccupiedCategory(args.Category, "line");
|
||||
}
|
||||
|
||||
|
||||
[SerializeField]
|
||||
private bool fitToContainer = false;
|
||||
public bool FitToContainer
|
||||
{
|
||||
get { return fitToContainer; }
|
||||
set
|
||||
{
|
||||
fitToContainer = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private ChartMagin fitMargin;
|
||||
public ChartMagin FitMargin
|
||||
{
|
||||
get { return fitMargin; }
|
||||
set
|
||||
{
|
||||
fitMargin = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
// [SerializeField]
|
||||
private bool enableBetaOptimization = false; // this features is not ready yet
|
||||
|
||||
private bool EnableBetaOptimization
|
||||
{
|
||||
get { return enableBetaOptimization; }
|
||||
set
|
||||
{
|
||||
enableBetaOptimization = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
protected override ChartMagin MarginLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return FitMargin;
|
||||
}
|
||||
}
|
||||
public override bool IsCanvas
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SupportRealtimeGeneration
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryObject
|
||||
{
|
||||
public CanvasChartMesh mItemLabels;
|
||||
public CanvasLines mLines;
|
||||
public CanvasLines mDots;
|
||||
public CanvasLines mFill;
|
||||
public Dictionary<int, string> mCahced = new Dictionary<int, string>();
|
||||
}
|
||||
|
||||
private CanvasLines CreateDataObject(GraphData.CategoryData data, GameObject rectMask)
|
||||
{
|
||||
GameObject obj = new GameObject("Lines", typeof(RectTransform));
|
||||
ChartCommon.HideObject(obj, hideHierarchy);
|
||||
obj.AddComponent<ChartItem>();
|
||||
RectTransform t = obj.GetComponent<RectTransform>();
|
||||
obj.AddComponent<CanvasRenderer>();
|
||||
|
||||
// Canvas c = obj.AddComponent<Canvas>();
|
||||
|
||||
//c.pixelPerfect = false;
|
||||
//obj.AddComponent<GraphicRaycaster>();
|
||||
|
||||
CanvasLines lines = obj.AddComponent<CanvasLines>();
|
||||
lines.maskable = true;
|
||||
|
||||
t.SetParent(rectMask.transform, false);
|
||||
t.localScale = new Vector3(1f, 1f, 1f);
|
||||
t.anchorMin = new Vector2(0f, 0f);
|
||||
t.anchorMax = new Vector2(1f, 1f);
|
||||
t.sizeDelta = new Vector2(0f, 0f);
|
||||
t.anchorMin = new Vector2(0f, 0f);
|
||||
t.anchorMax = new Vector2(0f, 0f);
|
||||
|
||||
t.anchoredPosition = Vector3.zero;
|
||||
t.localRotation = Quaternion.identity;
|
||||
return lines;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected override void ClearChart()
|
||||
{
|
||||
base.ClearChart();
|
||||
ClearBillboard();
|
||||
mActiveTexts.Clear();
|
||||
mCategoryObjects.Clear();
|
||||
ClearRealtimeIndexdata();
|
||||
}
|
||||
public override void ClearCache()
|
||||
{
|
||||
mCategoryObjects.Clear();
|
||||
}
|
||||
protected override double GetCategoryDepth(string category)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double AddRadius(double radius, double mag, double min, double max)
|
||||
{
|
||||
double size = max - min;
|
||||
double factor = size / mag;
|
||||
return factor * radius;
|
||||
}
|
||||
protected override void ViewPortionChanged()
|
||||
{
|
||||
InvalidateRealtime();
|
||||
}
|
||||
public override void GenerateRealtime()
|
||||
{
|
||||
if (SupressRealtimeGeneration)
|
||||
return;
|
||||
base.GenerateRealtime();
|
||||
|
||||
double minX = ((IInternalGraphData)Data).GetMinValue(0, false);
|
||||
double minY = ((IInternalGraphData)Data).GetMinValue(1, false);
|
||||
double maxX = ((IInternalGraphData)Data).GetMaxValue(0, false);
|
||||
double maxY = ((IInternalGraphData)Data).GetMaxValue(1, false);
|
||||
|
||||
double xScroll = GetScrollOffset(0);
|
||||
double yScroll = GetScrollOffset(1);
|
||||
double xSize = maxX - minX;
|
||||
double ySize = maxY - minY;
|
||||
double xOut = minX + xScroll + xSize;
|
||||
double yOut = minY + yScroll + ySize;
|
||||
|
||||
DoubleVector3 min = new DoubleVector3(xScroll + minX, yScroll + minY);
|
||||
DoubleVector3 max = new DoubleVector3(xOut, yOut);
|
||||
|
||||
Rect viewRect = new Rect(0f, 0f, widthRatio, heightRatio);
|
||||
|
||||
Transform parentT = transform;
|
||||
|
||||
if (mFixPosition != null)
|
||||
parentT = mFixPosition.transform;
|
||||
|
||||
ClearBillboardCategories();
|
||||
|
||||
foreach (GraphData.CategoryData data in ((IInternalGraphData)Data).Categories)
|
||||
{
|
||||
CategoryObject obj = null;
|
||||
|
||||
if (mCategoryObjects.TryGetValue(data.Name, out obj) == false)
|
||||
continue;
|
||||
|
||||
int minUpdateIndex = 0;
|
||||
if (mRealtimeUpdateIndex == true)
|
||||
{
|
||||
if (mMinimumUpdateIndex.TryGetValue(data.Name, out minUpdateIndex) == false)
|
||||
minUpdateIndex = int.MaxValue;
|
||||
}
|
||||
mClipped.Clear();
|
||||
mTmpData.Clear();
|
||||
|
||||
mTmpData.AddRange(data.getPoints());
|
||||
Rect uv;// = new Rect(0f, 0f, 1f, 1f);
|
||||
int refrenceIndex = ClipPoints(mTmpData, mClipped, out uv);
|
||||
//mClipped.AddRange(mTmpData);
|
||||
TransformPoints(mClipped, mTransformed, viewRect, min, max);
|
||||
mTmpToRemove.Clear();
|
||||
int range = refrenceIndex + mClipped.Count;
|
||||
foreach (int key in obj.mCahced.Keys)
|
||||
{
|
||||
if (key < refrenceIndex || key > range)
|
||||
mTmpToRemove.Add(key);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mTmpToRemove.Count; i++)
|
||||
obj.mCahced.Remove(mTmpToRemove[i]);
|
||||
|
||||
obj.mCahced.Remove(mTmpData.Count - 1); // never store the last point cache , it might be intepolating by the realtime feature
|
||||
|
||||
if (mTmpData.Count == 0)
|
||||
continue;
|
||||
if (mItemLabels != null && mItemLabels.isActiveAndEnabled && obj.mItemLabels != null)
|
||||
{
|
||||
Rect textRect = viewRect;
|
||||
textRect.xMin -= 1f;
|
||||
textRect.yMin -= 1f;
|
||||
textRect.xMax += 1f;
|
||||
textRect.yMax += 1f;
|
||||
|
||||
CanvasChartMesh m = obj.mItemLabels;
|
||||
m.Clear();
|
||||
|
||||
for (int i = 0; i < mTransformed.Count; i++)
|
||||
{
|
||||
if (mTransformed[i].w == 0.0)
|
||||
continue;
|
||||
Vector3 labelPos = ((Vector3)mTransformed[i]) + new Vector3(mItemLabels.Location.Breadth, mItemLabels.Seperation, mItemLabels.Location.Depth);
|
||||
if (mItemLabels.Alignment == ChartLabelAlignment.Base)
|
||||
labelPos.y -= (float)mTransformed[i].y;
|
||||
if (textRect.Contains((Vector2)(mTransformed[i])) == false)
|
||||
continue;
|
||||
string toSet = null;
|
||||
int pointIndex = i + refrenceIndex;
|
||||
if (obj.mCahced.TryGetValue(pointIndex, out toSet) == false)
|
||||
{
|
||||
DoubleVector3 pointValue = mTmpData[i + refrenceIndex];
|
||||
string xFormat = StringFromAxisFormat(pointValue, mHorizontalAxis, mItemLabels.FractionDigits,true);
|
||||
string yFormat = StringFromAxisFormat(pointValue, mVerticalAxis, mItemLabels.FractionDigits,false);
|
||||
FormatItem(mRealtimeStringBuilder, xFormat, yFormat);
|
||||
string formatted = mRealtimeStringBuilder.ToString();
|
||||
mItemLabels.TextFormat.Format(mRealtimeStringBuilder, formatted, data.Name, "");
|
||||
toSet = mRealtimeStringBuilder.ToString();
|
||||
obj.mCahced[pointIndex] = toSet;
|
||||
}
|
||||
labelPos -= new Vector3(CanvasFitOffset.x * TotalWidth, CanvasFitOffset.y * TotalHeight,0f);
|
||||
BillboardText billboard = m.AddText(this, mItemLabels.TextPrefab, parentT, mItemLabels.FontSize, mItemLabels.FontSharpness, toSet, labelPos.x, labelPos.y, labelPos.z, 0f, null);
|
||||
AddBillboardText(data.Name, i + refrenceIndex, billboard);
|
||||
}
|
||||
|
||||
m.DestoryRecycled();
|
||||
if (m.TextObjects != null)
|
||||
{
|
||||
foreach (BillboardText text in m.TextObjects)
|
||||
{
|
||||
((IInternalUse)this).InternalTextController.AddText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.mDots != null)
|
||||
{
|
||||
Rect pickRect = viewRect;
|
||||
float halfSize = (float)(data.PointSize * 0.5f);
|
||||
pickRect.xMin -= halfSize;
|
||||
pickRect.yMin -= halfSize;
|
||||
pickRect.xMax += halfSize;
|
||||
pickRect.yMax += halfSize;
|
||||
obj.mDots.SetViewRect(pickRect, uv);
|
||||
obj.mDots.ModifyLines(minUpdateIndex,mTransformed);
|
||||
obj.mDots.SetRefrenceIndex(refrenceIndex);
|
||||
}
|
||||
|
||||
if (obj.mLines != null)
|
||||
{
|
||||
float tiling = 1f;
|
||||
if (data.LineTiling.EnableTiling == true && data.LineTiling.TileFactor > 0f)
|
||||
{
|
||||
float length = 0f;
|
||||
for (int i = 1; i < mTransformed.Count; i++)
|
||||
length += (mTransformed[i - 1] - mTransformed[i]).magnitude;
|
||||
tiling = length / data.LineTiling.TileFactor;
|
||||
}
|
||||
if (tiling <= 0.0001f)
|
||||
tiling = 1f;
|
||||
obj.mLines.Tiling = tiling;
|
||||
obj.mLines.SetViewRect(viewRect, uv);
|
||||
obj.mLines.ModifyLines(minUpdateIndex,mTransformed);
|
||||
obj.mLines.SetRefrenceIndex(refrenceIndex);
|
||||
}
|
||||
|
||||
if (obj.mFill != null)
|
||||
{
|
||||
obj.mFill.SetViewRect(viewRect, uv);
|
||||
obj.mFill.ModifyLines(minUpdateIndex,mTransformed);
|
||||
obj.mFill.SetRefrenceIndex(refrenceIndex);
|
||||
}
|
||||
}
|
||||
ClearRealtimeIndexdata();
|
||||
}
|
||||
protected override bool ShouldFitCanvas { get { return true; } }
|
||||
protected override FitType FitAspectCanvas
|
||||
{
|
||||
get
|
||||
{
|
||||
return FitType.Aspect;
|
||||
}
|
||||
}
|
||||
|
||||
public override void InternalGenerateChart()
|
||||
{
|
||||
if (gameObject.activeInHierarchy == false)
|
||||
return;
|
||||
|
||||
base.InternalGenerateChart();
|
||||
|
||||
if (FitToContainer)
|
||||
{
|
||||
RectTransform trans = GetComponent<RectTransform>();
|
||||
widthRatio = trans.rect.width;
|
||||
heightRatio = trans.rect.height;
|
||||
}
|
||||
|
||||
ClearChart();
|
||||
|
||||
if (Data == null)
|
||||
return;
|
||||
|
||||
GenerateAxis(true);
|
||||
double minX = ((IInternalGraphData)Data).GetMinValue(0, false);
|
||||
double minY = ((IInternalGraphData)Data).GetMinValue(1, false);
|
||||
double maxX = ((IInternalGraphData)Data).GetMaxValue(0, false);
|
||||
double maxY = ((IInternalGraphData)Data).GetMaxValue(1, false);
|
||||
|
||||
double xScroll = GetScrollOffset(0);
|
||||
double yScroll = GetScrollOffset(1);
|
||||
double xSize = maxX - minX;
|
||||
double ySize = maxY - minY;
|
||||
double xOut = minX + xScroll + xSize;
|
||||
double yOut = minY + yScroll + ySize;
|
||||
|
||||
DoubleVector3 min = new DoubleVector3(xScroll + minX, yScroll + minY);
|
||||
DoubleVector3 max = new DoubleVector3(xOut, yOut);
|
||||
|
||||
Rect viewRect = new Rect(0f, 0f, widthRatio, heightRatio);
|
||||
|
||||
int index = 0;
|
||||
int total = ((IInternalGraphData)Data).TotalCategories + 1;
|
||||
bool edit = false;
|
||||
ClearBillboard();
|
||||
mActiveTexts.Clear();
|
||||
|
||||
GameObject mask = CreateRectMask(viewRect);
|
||||
|
||||
foreach (GraphData.CategoryData data in ((IInternalGraphData)Data).Categories)
|
||||
{
|
||||
mClipped.Clear();
|
||||
DoubleVector3[] points = data.getPoints().ToArray();
|
||||
Rect uv;
|
||||
int refrenceIndex = ClipPoints(points, mClipped, out uv);
|
||||
TransformPoints(mClipped, mTransformed, viewRect, min, max);
|
||||
|
||||
if (points.Length == 0 && ChartCommon.IsInEditMode)
|
||||
{
|
||||
edit = true;
|
||||
int tmpIndex = total - 1 - index;
|
||||
float y1 = (((float)tmpIndex) / (float)total);
|
||||
float y2 = (((float)tmpIndex + 1) / (float)total);
|
||||
|
||||
DoubleVector3 pos1 = ChartCommon.interpolateInRect(viewRect, new DoubleVector3(0f, y1, -1f)).ToDoubleVector3();
|
||||
DoubleVector3 pos2 = ChartCommon.interpolateInRect(viewRect, new DoubleVector3(0.5f, y2, -1f)).ToDoubleVector3();
|
||||
DoubleVector3 pos3 = ChartCommon.interpolateInRect(viewRect, new DoubleVector3(1f, y1, -1f)).ToDoubleVector3();
|
||||
|
||||
points = new DoubleVector3[] { pos1, pos2, pos3 };
|
||||
mTransformed.AddRange(points.Select(x => (Vector4)x.ToVector3()));
|
||||
index++;
|
||||
}
|
||||
|
||||
List<CanvasLines.LineSegement> list = new List<CanvasLines.LineSegement>();
|
||||
list.Add(new CanvasLines.LineSegement(mTransformed));
|
||||
CategoryObject categoryObj = new CategoryObject();
|
||||
|
||||
if (data.FillMaterial != null)
|
||||
{
|
||||
CanvasLines fill = CreateDataObject(data, mask);
|
||||
fill.EnableOptimization = enableBetaOptimization;
|
||||
fill.material = data.FillMaterial;
|
||||
fill.SetRefrenceIndex(refrenceIndex);
|
||||
fill.SetLines(list);
|
||||
fill.SetViewRect(viewRect, uv);
|
||||
fill.MakeFillRender(viewRect, data.StetchFill);
|
||||
categoryObj.mFill = fill;
|
||||
}
|
||||
string catName = data.Name;
|
||||
if (data.LineMaterial != null)
|
||||
{
|
||||
CanvasLines lines = CreateDataObject(data, mask);
|
||||
|
||||
float tiling = 1f;
|
||||
if (data.LineTiling.EnableTiling == true && data.LineTiling.TileFactor > 0f)
|
||||
{
|
||||
float length = 0f;
|
||||
for (int i = 1; i < mTransformed.Count; i++)
|
||||
length += (mTransformed[i - 1] - mTransformed[i]).magnitude;
|
||||
tiling = length / data.LineTiling.TileFactor;
|
||||
}
|
||||
if (tiling <= 0.0001f)
|
||||
tiling = 1f;
|
||||
lines.SetViewRect(viewRect, uv);
|
||||
lines.EnableOptimization = enableBetaOptimization;
|
||||
lines.Thickness = (float)data.LineThickness;
|
||||
lines.Tiling = tiling;
|
||||
lines.SetRefrenceIndex(refrenceIndex);
|
||||
lines.material = data.LineMaterial;
|
||||
lines.SetHoverPrefab(data.LineHoverPrefab);
|
||||
lines.SetLines(list);
|
||||
categoryObj.mLines = lines;
|
||||
lines.Hover += (idx, t, d, pos) => { Lines_Hover(catName, idx, pos); };
|
||||
lines.Click += (idx, t, d, pos) => { Lines_Clicked(catName, idx, pos); };
|
||||
lines.Leave += () => { Lines_Leave(catName); };
|
||||
}
|
||||
|
||||
//if (data.PointMaterial != null)
|
||||
//{
|
||||
CanvasLines dots = CreateDataObject(data, mask);
|
||||
categoryObj.mDots = dots;
|
||||
dots.material = data.PointMaterial;
|
||||
dots.EnableOptimization = enableBetaOptimization;
|
||||
dots.SetLines(list);
|
||||
Rect pickRect = viewRect;
|
||||
float halfSize = (float)data.PointSize * 0.5f;
|
||||
pickRect.xMin -= halfSize;
|
||||
pickRect.yMin -= halfSize;
|
||||
pickRect.xMax += halfSize;
|
||||
pickRect.yMax += halfSize;
|
||||
dots.SetViewRect(pickRect, uv);
|
||||
dots.SetRefrenceIndex(refrenceIndex);
|
||||
dots.SetHoverPrefab(data.PointHoverPrefab);
|
||||
|
||||
if (data.PointMaterial != null)
|
||||
dots.MakePointRender((float)data.PointSize);
|
||||
else
|
||||
dots.MakePointRender(0f);
|
||||
|
||||
if (mItemLabels != null && mItemLabels.isActiveAndEnabled)
|
||||
{
|
||||
CanvasChartMesh m = new CanvasChartMesh(true);
|
||||
m.RecycleText = true;
|
||||
categoryObj.mItemLabels = m;
|
||||
Rect textRect = viewRect;
|
||||
textRect.xMin -= 1f;
|
||||
textRect.yMin -= 1f;
|
||||
textRect.xMax += 1f;
|
||||
textRect.yMax += 1f;
|
||||
for (int i = 0; i < mTransformed.Count; i++)
|
||||
{
|
||||
if (mTransformed[i].w == 0f)
|
||||
continue;
|
||||
DoubleVector2 pointValue = new DoubleVector2(mTransformed[i]);
|
||||
if (textRect.Contains(pointValue.ToVector2()) == false)
|
||||
continue;
|
||||
if (edit == false)
|
||||
pointValue = Data.GetPoint(data.Name, i + refrenceIndex).ToDoubleVector2();
|
||||
string xFormat = StringFromAxisFormat(pointValue.ToDoubleVector3(), mHorizontalAxis, mItemLabels.FractionDigits,true);
|
||||
string yFormat = StringFromAxisFormat(pointValue.ToDoubleVector3(), mVerticalAxis, mItemLabels.FractionDigits,false);
|
||||
Vector3 labelPos = ((Vector3)mTransformed[i]) + new Vector3(mItemLabels.Location.Breadth, mItemLabels.Seperation, mItemLabels.Location.Depth);
|
||||
if (mItemLabels.Alignment == ChartLabelAlignment.Base)
|
||||
labelPos.y -= mTransformed[i].y;
|
||||
labelPos -= new Vector3(CanvasFitOffset.x * TotalWidth, CanvasFitOffset.y * TotalHeight,0f);
|
||||
FormatItem(mRealtimeStringBuilder, xFormat, yFormat);
|
||||
string formatted = mRealtimeStringBuilder.ToString();
|
||||
string toSet = mItemLabels.TextFormat.Format(formatted, data.Name, "");
|
||||
BillboardText billboard = m.AddText(this, mItemLabels.TextPrefab, transform, mItemLabels.FontSize, mItemLabels.FontSharpness, toSet, labelPos.x, labelPos.y, labelPos.z, 0f, null);
|
||||
// BillboardText billboard = ChartCommon.CreateBillboardText(null,mItemLabels.TextPrefab, transform, toSet, labelPos.x, labelPos.y, labelPos.z, 0f, null, hideHierarchy, mItemLabels.FontSize, mItemLabels.FontSharpness);
|
||||
TextController.AddText(billboard);
|
||||
AddBillboardText(data.Name, i + refrenceIndex, billboard);
|
||||
}
|
||||
}
|
||||
|
||||
dots.Hover += (idx,t,d, pos) => { Dots_Hover(catName, idx, pos); };
|
||||
dots.Click += (idx,t,d, pos) => { Dots_Click(catName, idx, pos); };
|
||||
dots.Leave += () => { Dots_Leave(catName); };
|
||||
mCategoryObjects[catName] = categoryObj;
|
||||
}
|
||||
}
|
||||
|
||||
private void Dots_Leave(string category)
|
||||
{
|
||||
TriggerActiveTextsOut();
|
||||
OnItemLeave(new GraphEventArgs(0,Vector3.zero,new DoubleVector2(0.0,0.0),-1f,category,"",""),"point");
|
||||
}
|
||||
|
||||
private void Lines_Leave(string category)
|
||||
{
|
||||
OnItemLeave(new GraphEventArgs(0, Vector3.zero, new DoubleVector2(0.0, 0.0), -1f, category, "", ""),"line");
|
||||
}
|
||||
|
||||
private void Dots_Click(string category,int idx, Vector2 pos)
|
||||
{
|
||||
DoubleVector3 point = Data.GetPoint(category, idx);
|
||||
Dictionary<int, BillboardText> catgoryTexts;
|
||||
BillboardText b;
|
||||
|
||||
if (mTexts.TryGetValue(category, out catgoryTexts))
|
||||
{
|
||||
if (catgoryTexts.TryGetValue(idx, out b))
|
||||
SelectActiveText(b);
|
||||
}
|
||||
string xString = StringFromAxisFormat(point, mHorizontalAxis,true);
|
||||
string yString = StringFromAxisFormat(point, mVerticalAxis,false);
|
||||
OnItemSelected(new GraphEventArgs(idx,pos, point.ToDoubleVector2(),(float)point.z, category,xString,yString));
|
||||
}
|
||||
|
||||
private void Lines_Clicked(string category,int idx,Vector2 pos)
|
||||
{
|
||||
DoubleVector3 point = Data.GetPoint(category, idx);
|
||||
string xString = StringFromAxisFormat(point, mHorizontalAxis, true);
|
||||
string yString = StringFromAxisFormat(point, mVerticalAxis, false);
|
||||
OnLineSelected(new GraphEventArgs(idx, pos, point.ToDoubleVector2(), (float)point.z, category, xString, yString));
|
||||
}
|
||||
|
||||
private void Lines_Hover(string category,int idx,Vector2 pos)
|
||||
{
|
||||
DoubleVector3 point = Data.GetPoint(category, idx);
|
||||
string xString = StringFromAxisFormat(point, mHorizontalAxis, true);
|
||||
string yString = StringFromAxisFormat(point, mVerticalAxis, false);
|
||||
OnLineHovered(new GraphEventArgs(idx, pos, point.ToDoubleVector2(), (float)point.z, category, xString, yString));
|
||||
}
|
||||
|
||||
private void Dots_Hover(string category, int idx, Vector2 pos)
|
||||
{
|
||||
DoubleVector3 point = Data.GetPoint(category, idx);
|
||||
Dictionary<int, BillboardText> catgoryTexts;
|
||||
BillboardText b;
|
||||
|
||||
if (mTexts.TryGetValue(category, out catgoryTexts))
|
||||
{
|
||||
if (catgoryTexts.TryGetValue(idx, out b))
|
||||
SelectActiveText(b);
|
||||
}
|
||||
|
||||
string xString = StringFromAxisFormat(point, mHorizontalAxis,true);
|
||||
string yString = StringFromAxisFormat(point, mVerticalAxis,false);
|
||||
OnItemHoverted(new GraphEventArgs(idx,pos, point.ToDoubleVector2(),(float)point.z, category, xString, yString));
|
||||
}
|
||||
|
||||
protected override void OnItemHoverted(object userData)
|
||||
{
|
||||
base.OnItemHoverted(userData);
|
||||
var args = userData as GraphEventArgs;
|
||||
AddOccupiedCategory(args.Category, "point");
|
||||
}
|
||||
|
||||
protected override void OnItemSelected(object userData)
|
||||
{
|
||||
base.OnItemSelected(userData);
|
||||
var args = userData as GraphEventArgs;
|
||||
AddOccupiedCategory(args.Category, "point");
|
||||
}
|
||||
void AddOccupiedCategory(string cat,string type)
|
||||
{
|
||||
mOccupiedCateogies.Add(cat + "|"+ type);
|
||||
}
|
||||
protected override void OnItemLeave(object userData,string type)
|
||||
{
|
||||
GraphEventArgs args = userData as GraphEventArgs;
|
||||
if (args == null)
|
||||
return;
|
||||
|
||||
string item = args.Category + "|" + type;
|
||||
mOccupiedCateogies.Remove(item);
|
||||
mOccupiedCateogies.RemoveWhere(x => !Data.HasCategory(x.Split('|')[0]));
|
||||
|
||||
if (mOccupiedCateogies.Count == 0)
|
||||
{
|
||||
if (NonHovered != null)
|
||||
NonHovered.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void SetAsMixedSeries()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b652978617146ea49983ac4601def914
|
||||
timeCreated: 1488381858
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,523 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// the graph chart class.
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
public abstract class GraphChartBase : ScrollableAxisChart
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("The height ratio of the chart")]
|
||||
protected float heightRatio = 300;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The width ratio of the chart")]
|
||||
protected float widthRatio = 600;
|
||||
|
||||
/// <summary>
|
||||
/// event arguments for a bar chart event
|
||||
/// </summary>
|
||||
public class GraphEventArgs
|
||||
{
|
||||
|
||||
public GraphEventArgs(int index,Vector3 position, DoubleVector2 value,float magnitude, string category,string xString,string yString)
|
||||
{
|
||||
|
||||
Position = position;
|
||||
Value = value;
|
||||
Category = category;
|
||||
XString = xString;
|
||||
YString = yString;
|
||||
Index = index;
|
||||
Magnitude = magnitude;
|
||||
}
|
||||
public float Magnitude { get; private set; }
|
||||
public int Index { get; private set; }
|
||||
public string XString { get; private set; }
|
||||
public string YString { get; private set; }
|
||||
public Vector3 Position { get; private set; }
|
||||
public DoubleVector2 Value { get; private set; }
|
||||
public string Category { get; private set; }
|
||||
public string Group { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// a graph chart event
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class GraphEvent : UnityEvent<GraphEventArgs>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// occures when a point is clicked
|
||||
/// </summary>
|
||||
public GraphEvent PointClicked = new GraphEvent();
|
||||
/// <summary>
|
||||
/// occurs when a point is hovered
|
||||
/// </summary>
|
||||
public GraphEvent PointHovered = new GraphEvent();
|
||||
/// <summary>
|
||||
/// occurs when no point is hovered any longer
|
||||
/// </summary>
|
||||
public UnityEvent NonHovered = new UnityEvent();
|
||||
|
||||
/// <summary>
|
||||
/// The height ratio of the chart
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public float HeightRatio
|
||||
{
|
||||
get { return heightRatio; }
|
||||
set
|
||||
{
|
||||
heightRatio = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The width ratio of the chart
|
||||
/// </summary>
|
||||
public float WidthRatio
|
||||
{
|
||||
get { return widthRatio; }
|
||||
set
|
||||
{
|
||||
widthRatio = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[SerializeField]
|
||||
private string itemFormat = "<?x>:<?y>";
|
||||
|
||||
public string ItemFormat
|
||||
{
|
||||
get { return itemFormat; }
|
||||
set
|
||||
{
|
||||
itemFormat = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
protected bool mRealtimeUpdateIndex = false;
|
||||
protected Dictionary<string, int> mMinimumUpdateIndex = new Dictionary<string, int>();
|
||||
/// <summary>
|
||||
/// the graph data
|
||||
/// </summary>
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
protected GraphData Data = new GraphData();
|
||||
|
||||
/// <summary>
|
||||
/// Holds the graph chart data. including values and categories
|
||||
/// </summary>
|
||||
public GraphData DataSource { get { return Data; } }
|
||||
|
||||
protected override LegenedData LegendInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
LegenedData data = new LegenedData();
|
||||
if (Data == null)
|
||||
return data;
|
||||
foreach(var cat in ((IInternalGraphData)Data).Categories)
|
||||
{
|
||||
LegenedData.LegenedItem item = new LegenedData.LegenedItem();
|
||||
item.Name = cat.Name;
|
||||
if (cat.FillMaterial != null)
|
||||
item.Material = cat.FillMaterial;
|
||||
else if (cat.LineMaterial != null)
|
||||
item.Material = cat.LineMaterial;
|
||||
else
|
||||
item.Material = cat.PointMaterial;
|
||||
data.AddLegenedItem(item);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
protected override IChartData DataLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return Data;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ClearCache();
|
||||
|
||||
private void HookEvents()
|
||||
{
|
||||
((IInternalGraphData)Data).InternalDataChanged -= GraphChart_InternalDataChanged;
|
||||
((IInternalGraphData)Data).InternalRealTimeDataChanged -= GraphChartBase_InternalRealTimeDataChanged; ;
|
||||
((IInternalGraphData)Data).InternalViewPortionChanged -= GraphChartBase_InternalViewPortionChanged;
|
||||
|
||||
((IInternalGraphData)Data).InternalViewPortionChanged += GraphChartBase_InternalViewPortionChanged;
|
||||
((IInternalGraphData)Data).InternalDataChanged += GraphChart_InternalDataChanged;
|
||||
((IInternalGraphData)Data).InternalRealTimeDataChanged += GraphChartBase_InternalRealTimeDataChanged; ;
|
||||
}
|
||||
|
||||
private void GraphChartBase_InternalViewPortionChanged(object sender, EventArgs e)
|
||||
{
|
||||
ViewPortionChanged();
|
||||
}
|
||||
|
||||
protected abstract void ViewPortionChanged();
|
||||
|
||||
private void GraphChartBase_InternalRealTimeDataChanged(int index,string category)
|
||||
{
|
||||
if (category == null) // full invalidtion
|
||||
{
|
||||
mRealtimeUpdateIndex = false;
|
||||
}
|
||||
if (mRealtimeUpdateIndex)
|
||||
{
|
||||
mRealtimeUpdateIndex = true;
|
||||
int minIndex;
|
||||
if (mMinimumUpdateIndex.TryGetValue(category, out minIndex) == false)
|
||||
minIndex = int.MaxValue;
|
||||
if (minIndex > index)
|
||||
minIndex = index;
|
||||
mMinimumUpdateIndex[category] = minIndex;
|
||||
}
|
||||
InvalidateRealtime();
|
||||
}
|
||||
|
||||
protected void ClearRealtimeIndexdata()
|
||||
{
|
||||
mMinimumUpdateIndex.Clear();
|
||||
mRealtimeUpdateIndex = true;
|
||||
}
|
||||
public override void Invalidate()
|
||||
{
|
||||
base.Invalidate();
|
||||
mRealtimeUpdateIndex = false; // trigger a full invalidation
|
||||
mMinimumUpdateIndex.Clear();
|
||||
}
|
||||
private void GraphChart_InternalDataChanged(object sender, EventArgs e)
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
if (ChartCommon.IsInEditMode == false)
|
||||
{
|
||||
HookEvents();
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
if (ChartCommon.IsInEditMode == false)
|
||||
{
|
||||
HookEvents();
|
||||
}
|
||||
Data.RestoreDataValues();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnLabelSettingChanged()
|
||||
{
|
||||
base.OnLabelSettingChanged();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnAxisValuesChanged()
|
||||
{
|
||||
base.OnAxisValuesChanged();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnLabelSettingsSet()
|
||||
{
|
||||
base.OnLabelSettingsSet();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected DoubleVector4 TransformPoint(Rect viewRect,Vector3 point ,DoubleVector2 min, DoubleVector2 range)
|
||||
{
|
||||
return ChartCommon.interpolateInRect(viewRect, new DoubleVector3((point.x - min.x) / range.x, (point.y - min.y) / range.y));
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
}
|
||||
|
||||
private void UpdateMinMax(DoubleVector3 point,ref double minX,ref double minY,ref double maxX,ref double maxY)
|
||||
{
|
||||
minX = Math.Min(minX, point.x);
|
||||
maxX = Math.Max(maxX, point.x);
|
||||
minY = Math.Min(minY, point.y);
|
||||
maxY = Math.Max(maxY, point.y);
|
||||
}
|
||||
|
||||
protected override float GetScrollingRange(int axis)
|
||||
{
|
||||
float min = (float)((IInternalGraphData)Data).GetMinValue(axis, false);
|
||||
float max = (float)((IInternalGraphData)Data).GetMaxValue(axis, false);
|
||||
return max - min;
|
||||
}
|
||||
|
||||
private Rect CreateUvRect(Rect completeRect,Rect lineRect)
|
||||
{
|
||||
if (completeRect.width < 0.0001f || completeRect.height < 0.0001f)
|
||||
return new Rect();
|
||||
if(float.IsInfinity(lineRect.xMax) || float.IsInfinity(lineRect.xMin) || float.IsInfinity(lineRect.yMin) || float.IsInfinity(lineRect.yMax))
|
||||
return new Rect();
|
||||
|
||||
float x = (lineRect.xMin - completeRect.xMin) / completeRect.width;
|
||||
float y = (lineRect.yMin - completeRect.yMin) / completeRect.height;
|
||||
|
||||
float w = lineRect.width / completeRect.width;
|
||||
float h = lineRect.height / completeRect.height;
|
||||
|
||||
return new Rect(x, y, w, h);
|
||||
}
|
||||
|
||||
protected int ClipPoints(IList<DoubleVector3> points,List<DoubleVector4> res,out Rect uv)
|
||||
{
|
||||
double minX, minY, maxX, maxY, xScroll, yScroll, xSize, ySize, xOut;
|
||||
GetScrollParams(out minX, out minY, out maxX, out maxY, out xScroll, out yScroll, out xSize, out ySize, out xOut);
|
||||
|
||||
double direction = 1.0;
|
||||
if (minX > maxX)
|
||||
direction = -1.0;
|
||||
bool prevOut = false;
|
||||
bool prevIn = false;
|
||||
|
||||
double maxXLocal = double.MinValue, minXLocal = double.MaxValue, maxYLocal = double.MinValue, minYLocal = double.MaxValue;
|
||||
minX = double.MaxValue;
|
||||
minY = double.MaxValue;
|
||||
maxX = double.MinValue;
|
||||
maxY = double.MinValue;
|
||||
int refrenceIndex = 0;
|
||||
|
||||
for(int i=0; i<points.Count; i++)
|
||||
{
|
||||
bool pOut = prevOut;
|
||||
bool pIn = prevIn;
|
||||
prevOut = false;
|
||||
prevIn = false;
|
||||
DoubleVector3 point = points[i];
|
||||
UpdateMinMax(points[i], ref minX, ref minY, ref maxX, ref maxY);
|
||||
|
||||
if (point.x* direction < xScroll* direction || point.x* direction > xOut* direction) // || point.y < yScroll || point.y > yOut)
|
||||
{
|
||||
prevOut = true;
|
||||
if (pIn)
|
||||
{
|
||||
res.Add(point.ToDoubleVector4());
|
||||
// uv = CreateUvRect(new Rect(minX, minY, maxX - minX, maxY - minY), new Rect(minXLocal, minYLocal, maxXLocal - minXLocal, maxYLocal - minYLocal));
|
||||
// return refrenceIndex;
|
||||
}
|
||||
if(pOut)
|
||||
{
|
||||
if(point.x* direction > xOut* direction && points[i-1].x* direction < xScroll* direction)
|
||||
{
|
||||
UpdateMinMax(points[i - 1], ref minXLocal, ref minYLocal, ref maxXLocal, ref maxYLocal);
|
||||
UpdateMinMax(point, ref minXLocal, ref minYLocal, ref maxXLocal, ref maxYLocal);
|
||||
res.Add(points[i - 1].ToDoubleVector4());
|
||||
res.Add(point.ToDoubleVector4());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prevIn = true;
|
||||
if (pOut)
|
||||
{
|
||||
refrenceIndex = i - 1;
|
||||
UpdateMinMax(points[i - 1], ref minXLocal, ref minYLocal, ref maxXLocal, ref maxYLocal);
|
||||
res.Add(points[i - 1].ToDoubleVector4());
|
||||
}
|
||||
UpdateMinMax(point, ref minXLocal, ref minYLocal, ref maxXLocal, ref maxYLocal);
|
||||
res.Add(point.ToDoubleVector4());
|
||||
}
|
||||
|
||||
}
|
||||
for(int i=0; i<res.Count; i++)
|
||||
{
|
||||
DoubleVector4 p = res[i];
|
||||
p.w = p.z;
|
||||
p.z = 0f;
|
||||
res[i] = p;
|
||||
}
|
||||
uv = CreateUvRect(new Rect((float)minX, (float)minY, (float)(maxX - minX), (float)(maxY - minY)), new Rect((float)minXLocal, (float)yScroll, (float)(maxXLocal - minXLocal), (float)(ySize)));
|
||||
return refrenceIndex;
|
||||
}
|
||||
|
||||
protected void TransformPoints(IList<DoubleVector3> points, Rect viewRect, DoubleVector3 min, DoubleVector3 max)
|
||||
{
|
||||
DoubleVector3 range = max - min;
|
||||
if (Math.Abs(range.x) <= 0.0001f || Math.Abs(range.y) < 0.0001f)
|
||||
return;
|
||||
double radiusMultiplier = Math.Min(viewRect.width / Math.Abs(range.x), viewRect.height / Math.Abs(range.y));
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
DoubleVector3 point = points[i];
|
||||
DoubleVector4 res = ChartCommon.interpolateInRect(viewRect, new DoubleVector3((point.x - min.x) / range.x, (point.y - min.y) / range.y));
|
||||
res.z = point.z * radiusMultiplier;
|
||||
points[i] = res.ToDoubleVector3();
|
||||
}
|
||||
}
|
||||
|
||||
protected void TransformPoints(IList<DoubleVector4> points,List<Vector4> output,Rect viewRect, DoubleVector3 min, DoubleVector3 max)
|
||||
{
|
||||
output.Clear();
|
||||
DoubleVector3 range = max - min;
|
||||
if (Math.Abs(range.x) <= 0.0001f || Math.Abs(range.y) < 0.0001f)
|
||||
return;
|
||||
double radiusMultiplier = Math.Min(viewRect.width / Math.Abs(range.x), viewRect.height / Math.Abs(range.y));
|
||||
for(int i=0; i<points.Count; i++)
|
||||
{
|
||||
DoubleVector4 point = points[i];
|
||||
DoubleVector4 res = ChartCommon.interpolateInRect(viewRect,new DoubleVector3((point.x - min.x) / range.x, (point.y - min.y) / range.y));
|
||||
res.z = 0.0;
|
||||
res.w = point.w* radiusMultiplier;
|
||||
output.Add(res.ToVector4());
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ValidateProperties()
|
||||
{
|
||||
base.ValidateProperties();
|
||||
if (heightRatio < 0f)
|
||||
heightRatio = 0f;
|
||||
if (widthRatio < 0f)
|
||||
widthRatio = 0f;
|
||||
}
|
||||
|
||||
protected override bool SupportsCategoryLabels
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool SupportsGroupLables
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool SupportsItemLabels
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override float TotalHeightLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return heightRatio;
|
||||
}
|
||||
}
|
||||
|
||||
protected override float TotalWidthLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return widthRatio;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override float TotalDepthLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool HasValues(AxisBase axis)
|
||||
{
|
||||
return true; //all axis have values in the graph chart
|
||||
}
|
||||
|
||||
protected override double MaxValue(AxisBase axis)
|
||||
{
|
||||
if (axis == null)
|
||||
return 0.0;
|
||||
if (axis == mHorizontalAxis)
|
||||
return ((IInternalGraphData)Data).GetMaxValue(0, false);
|
||||
if (axis == mVerticalAxis)
|
||||
return ((IInternalGraphData)Data).GetMaxValue(1, false);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
protected override double MinValue(AxisBase axis)
|
||||
{
|
||||
if (axis == null)
|
||||
return 0.0;
|
||||
if (axis == mHorizontalAxis)
|
||||
return ((IInternalGraphData)Data).GetMinValue(0, false);
|
||||
if (axis == mVerticalAxis)
|
||||
return ((IInternalGraphData)Data).GetMinValue(1, false);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
protected override void OnItemHoverted(object userData)
|
||||
{
|
||||
base.OnItemHoverted(userData);
|
||||
GraphEventArgs args = userData as GraphEventArgs;
|
||||
if (PointHovered != null)
|
||||
PointHovered.Invoke(args);
|
||||
|
||||
}
|
||||
StringBuilder mTmpBuilder = new StringBuilder();
|
||||
|
||||
public string FormatItem(double x, double y)
|
||||
{
|
||||
DoubleVector3 p = new DoubleVector3(x, y);
|
||||
string xFormat = StringFromAxisFormat(p, mHorizontalAxis, true);
|
||||
string yFormat = StringFromAxisFormat(p, mVerticalAxis, false);
|
||||
|
||||
FormatItem(mTmpBuilder, xFormat, yFormat);
|
||||
return mTmpBuilder.ToString();
|
||||
}
|
||||
|
||||
public string FormatItem(string x, string y)
|
||||
{
|
||||
FormatItem(mTmpBuilder, x, y);
|
||||
return mTmpBuilder.ToString();
|
||||
}
|
||||
protected void FormatItem(StringBuilder builder, string x, string y)
|
||||
{
|
||||
builder.Length = 0;
|
||||
builder.Append(itemFormat);
|
||||
builder.Replace("<?x>", x).Replace("<?y>", y).Replace("\\n", Environment.NewLine);
|
||||
}
|
||||
|
||||
protected override void OnItemSelected(object userData)
|
||||
{
|
||||
base.OnItemSelected(userData);
|
||||
GraphEventArgs args = userData as GraphEventArgs;
|
||||
if (PointClicked != null)
|
||||
PointClicked.Invoke(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d207a8aeb56b7494cbebadd75f4f6e46
|
||||
timeCreated: 1480266079
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,186 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using ChartAndGraph.Exceptions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public partial class GraphData : ScrollableChartData, IInternalGraphData
|
||||
{
|
||||
|
||||
partial void CheckExtended(ref bool result)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
public void AddCategory3DGraph(string category, PathGenerator linePrefab, Material lineMaterial, double lineThickness, MaterialTiling lineTiling, FillPathGenerator fillPrefab, Material innerFill, bool strechFill, GameObject pointPrefab, Material pointMaterial, double pointSize, double depth, bool isCurve, int segmentsPerCurve)
|
||||
{
|
||||
AddInnerCategoryGraph( category, linePrefab, lineMaterial, lineThickness, lineTiling, fillPrefab, innerFill, strechFill, pointPrefab, pointMaterial, pointSize, depth, isCurve, segmentsPerCurve);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the prefabs for a 3d graph category,
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="linePrefab"></param>
|
||||
/// <param name="fillPrefab"></param>
|
||||
/// <param name="dotPrefab"></param>
|
||||
public void Set3DCategoryPrefabs(string category, PathGenerator linePrefab, FillPathGenerator fillPrefab, GameObject dotPrefab)
|
||||
{
|
||||
if (mData.ContainsKey(category) == false)
|
||||
{
|
||||
Debug.LogWarning("Invalid category name. Make sure the category is present in the graph");
|
||||
return;
|
||||
}
|
||||
CategoryData data = (CategoryData)mData[category];
|
||||
data.LinePrefab = linePrefab;
|
||||
data.DotPrefab = dotPrefab;
|
||||
data.FillPrefab = fillPrefab;
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the depth for a 3d graph category
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="depth"></param>
|
||||
public void Set3DCategoryDepth(string category, double depth)
|
||||
{
|
||||
if (mData.ContainsKey(category) == false)
|
||||
{
|
||||
Debug.LogWarning("Invalid category name. Make sure the category is present in the graph");
|
||||
return;
|
||||
}
|
||||
if (depth < 0)
|
||||
depth = 0f;
|
||||
CategoryData data = (CategoryData)mData[category];
|
||||
data.Depth = depth;
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
public static void AddPointToCategoryWithLabelRealtime(GraphChartBase chart, string category, DateTime x, double y, double slideTime = 0, double pointSize = -1, string xLabel = null, string yLabel = null)
|
||||
{
|
||||
AddPointToCategoryWithLabelRealtime(chart, category, ChartDateUtility.DateToValue(x), y, slideTime, pointSize, xLabel, yLabel);
|
||||
}
|
||||
|
||||
public static void AddPointToCategoryWithLabelRealtime(GraphChartBase chart, string category, double x, DateTime y, double slideTime = 0, double pointSize = -1, string xLabel = null, string yLabel = null)
|
||||
{
|
||||
AddPointToCategoryWithLabelRealtime(chart, category, x, ChartDateUtility.DateToValue(y), slideTime, pointSize, xLabel, yLabel);
|
||||
}
|
||||
|
||||
public static void AddPointToCategoryWithLabelRealtime(GraphChartBase chart, string category, DateTime x, DateTime y, double slideTime = 0, double pointSize = -1, string xLabel = null, string yLabel = null)
|
||||
{
|
||||
AddPointToCategoryWithLabelRealtime(chart, category, ChartDateUtility.DateToValue(x), ChartDateUtility.DateToValue(y), slideTime, pointSize, xLabel, yLabel);
|
||||
}
|
||||
|
||||
public static void AddPointToCategoryWithLabelRealtime(GraphChartBase chart, string category, double x, double y, double slideTime = 0, double pointSize = -1, string xLabel = null, string yLabel = null)
|
||||
{
|
||||
bool invalidate = false;
|
||||
DoubleVector3 item = new DoubleVector3(x, y, 0.0);
|
||||
invalidate = chart.VectorValueToStringMap.Remove(item);
|
||||
chart.VectorValueToStringMap[item] = new KeyValuePair<string, string>(xLabel, yLabel);
|
||||
|
||||
if (invalidate)
|
||||
chart.ClearCache();
|
||||
|
||||
chart.DataSource.AddPointToCategoryRealtime(category, x, y, slideTime, pointSize);
|
||||
}
|
||||
|
||||
public void AddPointToCategoryRealtime(string category, DateTime x, DateTime y, double slideTime = 0f, double pointSize = -1f)
|
||||
{
|
||||
double xVal = ChartDateUtility.DateToValue(x);
|
||||
double yVal = ChartDateUtility.DateToValue(y);
|
||||
AddPointToCategoryRealtime(category, (double)xVal, (double)yVal, slideTime, pointSize);
|
||||
}
|
||||
|
||||
public void AddPointToCategoryRealtime(string category, DateTime x, double y, double slideTime = 0f, double pointSize = -1f)
|
||||
{
|
||||
double xVal = ChartDateUtility.DateToValue(x);
|
||||
AddPointToCategoryRealtime(category, (double)xVal, y, slideTime, pointSize);
|
||||
}
|
||||
|
||||
public void AddPointToCategoryRealtime(string category, double x, DateTime y, double slideTime = 0f, double pointSize = -1f)
|
||||
{
|
||||
double yVal = ChartDateUtility.DateToValue(y);
|
||||
AddPointToCategoryRealtime(category, x, (double)yVal, slideTime, pointSize);
|
||||
}
|
||||
public void SetCategoryArray(string category,DoubleVector3[] array,int start,int count)
|
||||
{
|
||||
if (mData.ContainsKey(category) == false)
|
||||
{
|
||||
Debug.LogWarning("Invalid category name. Make sure the category is present in the graph");
|
||||
return;
|
||||
}
|
||||
|
||||
CategoryData data = (CategoryData)mData[category];
|
||||
|
||||
if (data.IsBezierCurve == true)
|
||||
{
|
||||
Debug.LogWarning("Category is Bezier curve. set arrays is supported only for linear categories ");
|
||||
return;
|
||||
}
|
||||
|
||||
List<DoubleVector3> points = data.Data;
|
||||
points.Clear();
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
points.Add(array[start + i]);
|
||||
ModifyMinMax(data, array[start + i]);
|
||||
}
|
||||
RaiseRealtimeDataChanged(points.Count - 1, category);
|
||||
|
||||
}
|
||||
public void AddPointToCategoryRealtime(string category, double x, double y, double slideTime = 0f, double pointSize = -1f)
|
||||
{
|
||||
if (mData.ContainsKey(category) == false)
|
||||
{
|
||||
Debug.LogWarning("Invalid category name. Make sure the category is present in the graph");
|
||||
return;
|
||||
}
|
||||
|
||||
CategoryData data = (CategoryData)mData[category];
|
||||
|
||||
if (data.IsBezierCurve == true)
|
||||
{
|
||||
Debug.LogWarning("Category is Bezier curve. use AddCurveToCategory instead ");
|
||||
return;
|
||||
}
|
||||
|
||||
DoubleVector3 point = new DoubleVector3(x, y, pointSize);
|
||||
List<DoubleVector3> points = data.Data;
|
||||
|
||||
if (points.Count > 0)
|
||||
{
|
||||
if (points[points.Count - 1].x > point.x)
|
||||
{
|
||||
Debug.LogWarning("realtime points can only be added at the end of the graph");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (slideTime <= 0f || points.Count == 0)
|
||||
{
|
||||
points.Add(point);
|
||||
ModifyMinMax(data, point);
|
||||
}
|
||||
else
|
||||
{
|
||||
Slider s = new Slider(this);
|
||||
s.category = category;
|
||||
s.from = points.Count - 1;
|
||||
s.index = points.Count;
|
||||
s.StartTime = Time.time;
|
||||
s.Duration = slideTime;
|
||||
s.To = point;
|
||||
mSliders.Add(s);
|
||||
s.current = points[points.Count - 1];
|
||||
points.Add(s.current);
|
||||
}
|
||||
RaiseRealtimeDataChanged(points.Count - 1, category);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ea815ee96b07274f8c2b2b15141f7ce
|
||||
timeCreated: 1560537737
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,56 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using ChartAndGraph.Exceptions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public partial class GraphData : ScrollableChartData, IInternalGraphData
|
||||
{
|
||||
partial class Slider : BaseSlider
|
||||
{
|
||||
|
||||
public override bool Update()
|
||||
{
|
||||
BaseScrollableCategoryData baseData;
|
||||
CategoryData data;
|
||||
|
||||
if (mParent.mData.TryGetValue(category, out baseData) == false)
|
||||
return true;
|
||||
data = (CategoryData)baseData;
|
||||
if (data.IsBezierCurve)
|
||||
return false;
|
||||
List<DoubleVector3> points = data.Data;
|
||||
|
||||
if (from >= points.Count || index >= points.Count)
|
||||
return true;
|
||||
|
||||
DoubleVector3 fromPoint = points[from];
|
||||
DoubleVector3 to = To;
|
||||
double time = Time.time;
|
||||
time -= StartTime;
|
||||
|
||||
if (Duration <= 0.0001f)
|
||||
time = 1f;
|
||||
else
|
||||
{
|
||||
time /= Duration;
|
||||
Math.Max(0.0, Math.Min(time, 1.0));
|
||||
}
|
||||
DoubleVector3 v = DoubleVector3.Lerp(fromPoint, to, time);
|
||||
current = v;
|
||||
points[index] = v;
|
||||
if (time >= 1f)
|
||||
{
|
||||
mParent.ModifyMinMax(data, v);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af8e5e9ecdefca445b956f16f76d54c0
|
||||
timeCreated: 1560538967
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1591ab517b38bc043be1f05eb1fecb91
|
||||
timeCreated: 1480266079
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,493 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public class WorldSpaceGraphChart : GraphChartBase
|
||||
{
|
||||
List<DoubleVector4> mClipped = new List<DoubleVector4>();
|
||||
List<Vector4> mTransformed = new List<Vector4>();
|
||||
private StringBuilder mRealtimeStringBuilder = new StringBuilder();
|
||||
protected Dictionary<string, List<BillboardText>> m3DTexts = new Dictionary<string, List<BillboardText>>();
|
||||
private float totalDepth = 0f;
|
||||
GameObject mEmptyPointPrefab = null;
|
||||
/// <summary>
|
||||
/// If this value is set all the text in the chart will be rendered to this specific camera. otherwise text is rendered to the main camera
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("If this value is set all the text in the chart will be rendered to this specific camera. otherwise text is rendered to the main camera")]
|
||||
private Camera textCamera;
|
||||
|
||||
/// <summary>
|
||||
/// If this value is set all the text in the chart will be rendered to this specific camera. otherwise text is rendered to the main camera
|
||||
/// </summary>
|
||||
public Camera TextCamera
|
||||
{
|
||||
get { return textCamera; }
|
||||
set
|
||||
{
|
||||
textCamera = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The distance from the camera at which the text is at it's original size.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("The distance from the camera at which the text is at it's original size")]
|
||||
private float textIdleDistance = 20f;
|
||||
|
||||
/// <summary>
|
||||
/// The distance from the camera at which the text is at it's original size.
|
||||
/// </summary>
|
||||
public float TextIdleDistance
|
||||
{
|
||||
get { return textIdleDistance; }
|
||||
set
|
||||
{
|
||||
textIdleDistance = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
protected override Camera TextCameraLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return TextCamera;
|
||||
}
|
||||
}
|
||||
|
||||
protected override float TextIdleDistanceLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return TextIdleDistance;
|
||||
}
|
||||
}
|
||||
|
||||
protected override float TotalDepthLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return totalDepth;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsCanvas
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SupportRealtimeGeneration
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPropertyUpdated()
|
||||
{
|
||||
base.OnPropertyUpdated();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
private GameObject CreatePointObject(GraphData.CategoryData data)
|
||||
{
|
||||
GameObject prefab = data.DotPrefab;
|
||||
if(prefab == null)
|
||||
{
|
||||
if (mEmptyPointPrefab == null)
|
||||
mEmptyPointPrefab = (GameObject)Resources.Load("Chart And Graph/SelectHandle");
|
||||
prefab = mEmptyPointPrefab;
|
||||
}
|
||||
GameObject obj = GameObject.Instantiate(prefab);
|
||||
ChartCommon.HideObject(obj, hideHierarchy);
|
||||
if (obj.GetComponent<ChartItem>() == null)
|
||||
obj.AddComponent<ChartItem>();
|
||||
obj.transform.SetParent(transform);
|
||||
obj.transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
obj.transform.localPosition = Vector3.zero;
|
||||
obj.transform.localRotation = Quaternion.identity;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private FillPathGenerator CreateFillObject(GraphData.CategoryData data)
|
||||
{
|
||||
GameObject obj = GameObject.Instantiate(data.FillPrefab.gameObject);
|
||||
ChartCommon.HideObject(obj, hideHierarchy);
|
||||
FillPathGenerator fill = obj.GetComponent<FillPathGenerator>();
|
||||
if (obj.GetComponent<ChartItem>() == null)
|
||||
obj.AddComponent<ChartItem>();
|
||||
obj.transform.SetParent(transform);
|
||||
obj.transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
obj.transform.localPosition = Vector3.zero;
|
||||
obj.transform.localRotation = Quaternion.identity;
|
||||
return fill;
|
||||
}
|
||||
|
||||
private PathGenerator CreateLineObject(GraphData.CategoryData data)
|
||||
{
|
||||
GameObject obj = GameObject.Instantiate(data.LinePrefab.gameObject);
|
||||
ChartCommon.HideObject(obj, hideHierarchy);
|
||||
PathGenerator lines = obj.GetComponent<PathGenerator>();
|
||||
if (obj.GetComponent<ChartItem>() == null)
|
||||
obj.AddComponent<ChartItem>();
|
||||
obj.transform.SetParent(transform);
|
||||
obj.transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
obj.transform.localPosition = Vector3.zero;
|
||||
obj.transform.localRotation = Quaternion.identity;
|
||||
return lines;
|
||||
}
|
||||
|
||||
protected override void OnNonHoverted()
|
||||
{
|
||||
base.OnNonHoverted();
|
||||
foreach (BillboardText t in mActiveTexts)
|
||||
{
|
||||
if (t.UIText == null)
|
||||
continue;
|
||||
foreach (ChartItemEffect effect in t.UIText.GetComponents<ChartItemEffect>())
|
||||
effect.TriggerOut(false);
|
||||
}
|
||||
mActiveTexts.Clear();
|
||||
if (NonHovered != null)
|
||||
NonHovered.Invoke();
|
||||
}
|
||||
|
||||
protected override double GetCategoryDepth(string category)
|
||||
{
|
||||
var cat = ((IInternalGraphData)Data).Categories.Where(x => x.Name == category).FirstOrDefault();
|
||||
if (cat == null)
|
||||
return 0.0;
|
||||
return cat.Depth;
|
||||
}
|
||||
|
||||
protected override void OnItemHoverted(object userData)
|
||||
{
|
||||
base.OnItemHoverted(userData);
|
||||
GraphEventArgs args = userData as GraphEventArgs;
|
||||
if (args == null)
|
||||
return;
|
||||
foreach (BillboardText t in mActiveTexts)
|
||||
{
|
||||
if (t.UIText == null)
|
||||
continue;
|
||||
foreach (ChartItemEffect effect in t.UIText.GetComponents<ChartItemEffect>())
|
||||
effect.TriggerOut(false);
|
||||
}
|
||||
mActiveTexts.Clear();
|
||||
List<BillboardText> catgoryTexts;
|
||||
if (m3DTexts.TryGetValue(args.Category, out catgoryTexts))
|
||||
{
|
||||
if (args.Index < catgoryTexts.Count)
|
||||
{
|
||||
BillboardText b = catgoryTexts[args.Index];
|
||||
mActiveTexts.Add(b);
|
||||
GameObject t = b.UIText;
|
||||
if (t != null)
|
||||
{
|
||||
foreach (ChartItemEffect effect in t.GetComponents<ChartItemEffect>())
|
||||
effect.TriggerIn(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddBillboardText(string cat, BillboardText text)
|
||||
{
|
||||
List<BillboardText> addTo;
|
||||
if (m3DTexts.TryGetValue(cat, out addTo) == false)
|
||||
{
|
||||
addTo = new List<BillboardText>();
|
||||
m3DTexts.Add(cat, addTo);
|
||||
}
|
||||
addTo.Add(text);
|
||||
}
|
||||
|
||||
protected override void ClearChart()
|
||||
{
|
||||
base.ClearChart();
|
||||
m3DTexts.Clear();
|
||||
mActiveTexts.Clear();
|
||||
}
|
||||
|
||||
public override void ClearCache()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void GenerateRealtime()
|
||||
{
|
||||
base.GenerateRealtime();
|
||||
Debug.Log("realtime graph updates are not yet supported for 3d graphs");
|
||||
}
|
||||
|
||||
protected override void ViewPortionChanged()
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
public override void InternalGenerateChart()
|
||||
{
|
||||
if (gameObject.activeInHierarchy == false)
|
||||
return;
|
||||
base.InternalGenerateChart();
|
||||
ClearChart();
|
||||
|
||||
if (Data == null)
|
||||
return;
|
||||
|
||||
double minX = ((IInternalGraphData)Data).GetMinValue(0, false);
|
||||
double minY = ((IInternalGraphData)Data).GetMinValue(1, false);
|
||||
double maxX = ((IInternalGraphData)Data).GetMaxValue(0, false);
|
||||
double maxY = ((IInternalGraphData)Data).GetMaxValue(1, false);
|
||||
|
||||
double xScroll = GetScrollOffset(0);
|
||||
double yScroll = GetScrollOffset(1);
|
||||
double xSize = maxX - minX;
|
||||
double ySize = maxY - minY;
|
||||
double xOut = minX + xScroll + xSize;
|
||||
double yOut = minY + yScroll + ySize;
|
||||
|
||||
DoubleVector3 min = new DoubleVector3(xScroll + minX, yScroll + minY);
|
||||
DoubleVector3 max = new DoubleVector3(xOut, yOut);
|
||||
|
||||
Rect viewRect = new Rect(0f, 0f, widthRatio, heightRatio);
|
||||
|
||||
int index = 0;
|
||||
int total = ((IInternalGraphData)Data).TotalCategories + 1;
|
||||
double positiveDepth = 0f;
|
||||
double maxThickness = 0f;
|
||||
bool edit = false;
|
||||
m3DTexts.Clear();
|
||||
mActiveTexts.Clear();
|
||||
foreach (GraphData.CategoryData data in ((IInternalGraphData)Data).Categories)
|
||||
{
|
||||
mClipped.Clear();
|
||||
maxThickness = Math.Max(data.LineThickness, maxThickness);
|
||||
DoubleVector3[] points = data.getPoints().ToArray();
|
||||
Rect uv;
|
||||
int refrenceIndex = ClipPoints(points, mClipped, out uv);
|
||||
TransformPoints(mClipped, mTransformed, viewRect, min, max);
|
||||
|
||||
if (points.Length == 0 && ChartCommon.IsInEditMode)
|
||||
{
|
||||
edit = true;
|
||||
int tmpIndex = total - 1 - index;
|
||||
float y1 = (((float)tmpIndex) / (float)total);
|
||||
float y2 = (((float)tmpIndex + 1) / (float)total);
|
||||
DoubleVector3 pos1 = ChartCommon.interpolateInRect(viewRect, new DoubleVector3(0f, y1,-1f)).ToDoubleVector3();
|
||||
DoubleVector3 pos2 = ChartCommon.interpolateInRect(viewRect, new DoubleVector3(0.5f, y2, -1f)).ToDoubleVector3();
|
||||
DoubleVector3 pos3 = ChartCommon.interpolateInRect(viewRect, new DoubleVector3(1f, y1, -1f)).ToDoubleVector3();
|
||||
points = new DoubleVector3[] { pos1, pos2, pos3 };
|
||||
mTransformed.AddRange(points.Select(x => (Vector4)x.ToVector3()));
|
||||
index++;
|
||||
}
|
||||
|
||||
/*if (data.FillMaterial != null)
|
||||
{
|
||||
CanvasLines fill = CreateDataObject(data);
|
||||
fill.material = data.FillMaterial;
|
||||
fill.SetLines(list);
|
||||
fill.MakeFillRender(viewRect, data.StetchFill);
|
||||
}*/
|
||||
|
||||
if (data.Depth > 0)
|
||||
positiveDepth = Math.Max(positiveDepth, data.Depth);
|
||||
// if (data.DotPrefab != null)
|
||||
//{
|
||||
float minViewX = Math.Min(viewRect.xMin, viewRect.xMax);
|
||||
float maxViewX = Math.Max(viewRect.xMin, viewRect.xMax);
|
||||
for (int i = 0; i < mTransformed.Count; i++)
|
||||
{
|
||||
float transX = mTransformed[i].x;
|
||||
if (minViewX > transX || maxViewX < transX)
|
||||
continue;
|
||||
DoubleVector3 pointValue = points[i];
|
||||
if (edit == false)
|
||||
pointValue = Data.GetPoint(data.Name, i +refrenceIndex);
|
||||
|
||||
string xFormat = StringFromAxisFormat(pointValue, mHorizontalAxis,true);
|
||||
string yFormat = StringFromAxisFormat(pointValue, mVerticalAxis, false);
|
||||
|
||||
GraphEventArgs args = new GraphEventArgs(i, (mTransformed[i] + new Vector4(0f, 0f, (float)data.Depth)), pointValue.ToDoubleVector2(), (float)pointValue.z, data.Name, xFormat, yFormat);
|
||||
GameObject point = CreatePointObject(data);
|
||||
ChartItemEvents[] events = point.GetComponentsInChildren<ChartItemEvents>();
|
||||
|
||||
for (int j = 0; j < events.Length; ++j)
|
||||
{
|
||||
if (events[j] == null)
|
||||
continue;
|
||||
InternalItemEvents comp = (InternalItemEvents)events[j];
|
||||
comp.Parent = this;
|
||||
comp.UserData = args;
|
||||
}
|
||||
|
||||
double pointSize = mTransformed[i].w * data.PointSize;
|
||||
if (pointSize < 0f)
|
||||
pointSize = data.PointSize;
|
||||
|
||||
|
||||
|
||||
point.transform.localScale = new DoubleVector3(pointSize, pointSize, pointSize).ToVector3();
|
||||
|
||||
if (data.PointMaterial != null)
|
||||
{
|
||||
Renderer rend = point.GetComponent<Renderer>();
|
||||
if (rend != null)
|
||||
rend.material = data.PointMaterial;
|
||||
ChartMaterialController controller = point.GetComponent<ChartMaterialController>();
|
||||
if (controller != null && controller.Materials != null)
|
||||
{
|
||||
Color hover = controller.Materials.Hover;
|
||||
Color selected = controller.Materials.Selected;
|
||||
controller.Materials = new ChartDynamicMaterial(data.PointMaterial, hover, selected);
|
||||
}
|
||||
}
|
||||
|
||||
DoubleVector3 position = new DoubleVector3(mTransformed[i]);
|
||||
position.z = data.Depth;
|
||||
point.transform.localPosition = position.ToVector3();
|
||||
if (mItemLabels != null && mItemLabels.isActiveAndEnabled)
|
||||
{
|
||||
Vector3 labelPos = (new DoubleVector3(mTransformed[i]) + new DoubleVector3(mItemLabels.Location.Breadth, mItemLabels.Seperation, mItemLabels.Location.Depth + data.Depth)).ToVector3();
|
||||
if (mItemLabels.Alignment == ChartLabelAlignment.Base)
|
||||
labelPos.y -= (float)mTransformed[i].y;
|
||||
FormatItem(mRealtimeStringBuilder, xFormat, yFormat);
|
||||
string formatted = mRealtimeStringBuilder.ToString();
|
||||
string toSet = mItemLabels.TextFormat.Format(formatted, data.Name, "");
|
||||
BillboardText billboard = ChartCommon.CreateBillboardText(null,mItemLabels.TextPrefab, transform, toSet, labelPos.x, labelPos.y, labelPos.z, 0f, null, hideHierarchy, mItemLabels.FontSize, mItemLabels.FontSharpness);
|
||||
TextController.AddText(billboard);
|
||||
AddBillboardText(data.Name, billboard);
|
||||
}
|
||||
}
|
||||
//}
|
||||
for (int i = 0; i < mTransformed.Count; i++)
|
||||
{
|
||||
var t = mTransformed[i];
|
||||
t.z = 0f;
|
||||
t.w = 0f;
|
||||
mTransformed[i]= t;
|
||||
}
|
||||
Vector3[] floatPoints = mTransformed.Select(x => (Vector3)x).ToArray();
|
||||
if (floatPoints.Length >= 2)
|
||||
{
|
||||
Vector2 res;
|
||||
float maxF = Math.Max(floatPoints[0].y, floatPoints[1].y);
|
||||
float minF = Math.Min(floatPoints[0].y, floatPoints[1].y);
|
||||
float firstX = viewRect.x;
|
||||
float secondX = viewRect.x + viewRect.width;
|
||||
if(min.x >max.x)
|
||||
{
|
||||
float tmp = firstX;
|
||||
firstX = secondX;
|
||||
secondX = tmp;
|
||||
}
|
||||
if (ChartCommon.SegmentIntersection(floatPoints[0],floatPoints[1], new Vector3(firstX, maxF, 0f), new Vector3(firstX, minF, 0f),out res))
|
||||
{
|
||||
floatPoints[0] = res;
|
||||
}
|
||||
Vector3 last = floatPoints[floatPoints.Length - 1];
|
||||
Vector3 secondLast = floatPoints[floatPoints.Length - 2];
|
||||
maxF = Math.Max(last.y, secondLast.y);
|
||||
minF = Math.Min(last.y, secondLast.y);
|
||||
|
||||
if (ChartCommon.SegmentIntersection(last,secondLast, new Vector3(secondX, maxF, 0f), new Vector3(secondX, minF, 0f), out res))
|
||||
{
|
||||
floatPoints[floatPoints.Length - 1] = res;
|
||||
}
|
||||
}
|
||||
if (data.LinePrefab != null)
|
||||
{
|
||||
PathGenerator lines = CreateLineObject(data);
|
||||
// float tiling = 1f;
|
||||
|
||||
if (data.LineTiling.EnableTiling == true && data.LineTiling.TileFactor > 0f)
|
||||
{
|
||||
float length = 0f;
|
||||
for (int i = 1; i < mTransformed.Count; i++)
|
||||
length += (float)(((Vector3)mTransformed[i - 1]) - (Vector3)mTransformed[i]).magnitude;
|
||||
// tiling = length / data.LineTiling.TileFactor;
|
||||
}
|
||||
|
||||
lines.Generator(floatPoints, (float) data.LineThickness, false);
|
||||
Vector3 tmp = lines.transform.localPosition;
|
||||
tmp.z = (float)data.Depth;
|
||||
lines.transform.localPosition = tmp;
|
||||
if (data.LineMaterial != null)
|
||||
{
|
||||
Renderer rend = lines.GetComponent<Renderer>();
|
||||
if (rend != null)
|
||||
rend.material = data.LineMaterial;
|
||||
ChartMaterialController controller = lines.GetComponent<ChartMaterialController>();
|
||||
if (controller != null && controller.Materials != null)
|
||||
{
|
||||
Color hover = controller.Materials.Hover;
|
||||
Color selected = controller.Materials.Selected;
|
||||
controller.Materials = new ChartDynamicMaterial(data.LineMaterial, hover, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
totalDepth = (float)(positiveDepth + maxThickness*2f);
|
||||
|
||||
|
||||
if (data.FillPrefab != null)
|
||||
{
|
||||
FillPathGenerator fill = CreateFillObject(data);
|
||||
Vector3 tmp = fill.transform.localPosition;
|
||||
tmp.z = (float)data.Depth;
|
||||
fill.transform.localPosition = tmp;
|
||||
|
||||
if (data.LinePrefab == null || !(data.LinePrefab is SmoothPathGenerator))
|
||||
{
|
||||
fill.SetLineSmoothing(false, 0, 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
SmoothPathGenerator smooth = ((SmoothPathGenerator)data.LinePrefab);
|
||||
fill.SetLineSmoothing(true, smooth.JointSmoothing, smooth.JointSize);
|
||||
}
|
||||
|
||||
fill.SetGraphBounds(viewRect.yMin, viewRect.yMax);
|
||||
fill.SetStrechFill(data.StetchFill);
|
||||
fill.Generator(floatPoints, (float)data.LineThickness * 1.01f, false);
|
||||
|
||||
if (data.FillMaterial != null)
|
||||
{
|
||||
Renderer rend = fill.GetComponent<Renderer>();
|
||||
if (rend != null)
|
||||
rend.material = data.FillMaterial;
|
||||
ChartMaterialController controller = fill.GetComponent<ChartMaterialController>();
|
||||
|
||||
if (controller != null && controller.Materials != null)
|
||||
{
|
||||
Color hover = controller.Materials.Hover;
|
||||
Color selected = controller.Materials.Selected;
|
||||
controller.Materials = new ChartDynamicMaterial(data.FillMaterial, hover, selected);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
GenerateAxis(true);
|
||||
}
|
||||
|
||||
internal override void SetAsMixedSeries()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30f0648873004f6498323b8ab4e639fc
|
||||
timeCreated: 1488381858
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user