654 lines
27 KiB
C#
654 lines
27 KiB
C#
#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 bool negativeFill = false;
|
|
public bool NegativeFill
|
|
{
|
|
get { return negativeFill; }
|
|
set
|
|
{
|
|
negativeFill = 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, (DoubleVector3, string)> mCahced = new Dictionary<int, (DoubleVector3, string)>();
|
|
}
|
|
void CenterObject(GameObject obj,RectTransform parent)
|
|
{
|
|
RectTransform t = obj.GetComponent<RectTransform>();
|
|
t.SetParent(parent.transform, false);
|
|
t.localScale = new Vector3(1f, 1f, 1f);
|
|
t.anchorMin = new Vector2(0f, 0f);
|
|
t.anchorMax = new Vector2(0f, 0f);
|
|
t.sizeDelta = parent.sizeDelta;
|
|
t.anchoredPosition = Vector3.zero;
|
|
t.localRotation = Quaternion.identity;
|
|
}
|
|
private CanvasLines CreateDataObject(GraphData.CategoryData data, GameObject rectMask,bool mask)
|
|
{
|
|
GameObject obj = new GameObject("Lines", typeof(RectTransform));
|
|
ChartCommon.HideObject(obj, hideHierarchy);
|
|
obj.AddComponent<ChartItem>();
|
|
|
|
var rend = obj.AddComponent<CanvasRenderer>();
|
|
rend.cullTransparentMesh = false;
|
|
|
|
CenterObject(obj,rectMask.GetComponent<RectTransform>());
|
|
// Canvas c = obj.AddComponent<Canvas>();
|
|
|
|
//c.pixelPerfect = false;
|
|
//obj.AddComponent<GraphicRaycaster>();
|
|
CanvasLines lines = obj.AddComponent<CanvasLines>();
|
|
lines.maskable = true;
|
|
|
|
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
|
|
obj.mCahced.Remove(mTmpData.Count - 2); // 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;
|
|
(DoubleVector3, string) toSet;
|
|
int pointIndex = i + refrenceIndex;
|
|
if (obj.mCahced.TryGetValue(pointIndex, out toSet) == false || toSet.Item1!= mTmpData[i + refrenceIndex])
|
|
{
|
|
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.Item2 = 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.Item2, 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)
|
|
{
|
|
float zero = (float)((-min.y / (max.y - min.y)) * viewRect.height);
|
|
if (negativeFill == false)
|
|
zero = 0f;
|
|
obj.mFill.SetFillZero(zero);
|
|
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,true);
|
|
fill.EnableOptimization = enableBetaOptimization;
|
|
fill.material = data.FillMaterial;
|
|
fill.SetRefrenceIndex(refrenceIndex);
|
|
fill.SetLines(list);
|
|
fill.SetViewRect(viewRect, uv);
|
|
float zero = (float) ((-min.y / (max.y - min.y)) * viewRect.height);
|
|
if (negativeFill == false)
|
|
zero = 0f;
|
|
fill.MakeFillRender(viewRect, zero, data.StetchFill,true);
|
|
categoryObj.mFill = fill;
|
|
}
|
|
string catName = data.Name;
|
|
if (data.LineMaterial != null)
|
|
{
|
|
CanvasLines lines = CreateDataObject(data, mask,true);
|
|
|
|
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, false);
|
|
if (data.MaskPoints == false)
|
|
dots.transform.SetParent(transform, true);
|
|
//else
|
|
//{
|
|
// dots.transform.SetParent(transform, true);
|
|
// var rectTransform = dots.GetComponent<RectTransform>();
|
|
// rectTransform.anchorMin = new Vector2(0f, 0f);
|
|
// rectTransform.anchorMax = new Vector2(0f, 0f);
|
|
// rectTransform.pivot = new Vector2(0f, 1f);
|
|
// rectTransform.sizeDelta = viewRect.size;
|
|
// rectTransform.anchoredPosition = new Vector2(0f, 0f);// viewRect.size.y);
|
|
//}
|
|
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);
|
|
if(data.MaskPoints)
|
|
dots.ClipRect = null;
|
|
else
|
|
dots.ClipRect = viewRect;
|
|
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();
|
|
}
|
|
}
|
|
}
|