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,75 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// base class for some chart datasources
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public abstract class AbstractChartData
|
||||
{
|
||||
protected class Slider
|
||||
{
|
||||
public string category;
|
||||
public string group;
|
||||
public double from;
|
||||
public double to;
|
||||
public float startTime;
|
||||
public float totalTime;
|
||||
public float timeScale = 1f;
|
||||
public AnimationCurve curve;
|
||||
|
||||
public bool UpdateSlider(AbstractChartData data)
|
||||
{
|
||||
float time = Time.time;
|
||||
float elasped = time - startTime;
|
||||
elasped *= timeScale;
|
||||
if (elasped > totalTime)
|
||||
{
|
||||
data.SetValueInternal(category, group, to);
|
||||
return true;
|
||||
}
|
||||
float factor = elasped / totalTime;
|
||||
if (curve != null)
|
||||
factor = curve.Evaluate(factor);
|
||||
double newValue = from * (1.0 - factor) + to * factor;
|
||||
data.SetValueInternal(category, group, newValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Slider> mSliders = new List<Slider>();
|
||||
|
||||
protected void RemoveSliderForGroup(string group)
|
||||
{
|
||||
mSliders.RemoveAll(x => { return x.group == group; });
|
||||
}
|
||||
|
||||
protected void RemoveSliderForCategory(string category)
|
||||
{
|
||||
mSliders.RemoveAll(x => { return x.category == category; });
|
||||
}
|
||||
|
||||
protected void RemoveSlider(string category,string group)
|
||||
{
|
||||
mSliders.RemoveAll(x=> { return x.category == category && x.group == group; });
|
||||
}
|
||||
|
||||
bool DoSlider(Slider s)
|
||||
{
|
||||
return s.UpdateSlider(this);
|
||||
}
|
||||
|
||||
protected void UpdateSliders()
|
||||
{
|
||||
mSliders.RemoveAll(DoSlider);
|
||||
}
|
||||
|
||||
protected abstract void SetValueInternal(string column, string row, double value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac05131a8f94e364795b93d46ca41bb2
|
||||
timeCreated: 1480003631
|
||||
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: 99b21cf8e1d2af7499093362c052374a
|
||||
timeCreated: 1471942061
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92451bac0b7be6043863fed0a49875d9
|
||||
folderAsset: yes
|
||||
timeCreated: 1560597121
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public class CanvasAttribute :Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac18aa2c7926afe44930ef269d844e0c
|
||||
timeCreated: 1479124371
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
|
||||
public class ChartFillerEditorAttribute : Attribute
|
||||
{
|
||||
public GraphDataFiller.DataType ShowForType;
|
||||
public ChartFillerEditorAttribute(GraphDataFiller.DataType type)
|
||||
{
|
||||
ShowForType = type;
|
||||
}
|
||||
public BarDataFiller.DataType ShowForBarType;
|
||||
public ChartFillerEditorAttribute(BarDataFiller.DataType type)
|
||||
{
|
||||
ShowForBarType = type;
|
||||
}
|
||||
|
||||
public RadarDataFiller.DataType ShowForRadarType;
|
||||
public ChartFillerEditorAttribute(RadarDataFiller.DataType type)
|
||||
{
|
||||
ShowForRadarType = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a260abf3570275488c42177ee1fc458
|
||||
timeCreated: 1536697084
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public class NonCanvasAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b871f42477dcab14f93bce1895ffc9cf
|
||||
timeCreated: 1479124371
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public class SimpleAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd5be9d4f47a8a54c8d210060b356de8
|
||||
timeCreated: 1479124371
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 933231935de983c419d9763bda4d697d
|
||||
folderAsset: yes
|
||||
timeCreated: 1560548194
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// this class holds a float value that can be either set mannualy or be set automatically by an external class
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct AutoFloat
|
||||
{
|
||||
/// <summary>
|
||||
/// true if the value is automatic
|
||||
/// </summary>
|
||||
public bool Automatic;
|
||||
/// <summary>
|
||||
/// the mannual value , this is only relevant if Automatic == false
|
||||
/// </summary>
|
||||
public float Value;
|
||||
|
||||
/// <summary>
|
||||
/// creats a new instance of AutoFloat
|
||||
/// </summary>
|
||||
/// <param name="automatic"></param>
|
||||
/// <param name="value"></param>
|
||||
public AutoFloat(bool automatic,float value)
|
||||
{
|
||||
Automatic = automatic;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if(obj is AutoFloat)
|
||||
{
|
||||
AutoFloat cast = (AutoFloat)obj;
|
||||
if (cast.Automatic == true && Automatic == true)
|
||||
return true;
|
||||
if (cast.Automatic == false && Automatic == false && cast.Value == Value)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (Automatic == true)
|
||||
return Automatic.GetHashCode();
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6595b44672cf1b468860d62030e1c4d
|
||||
timeCreated: 1479209594
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,602 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// base class for all axis monobehaviours. This class contains paramets for defining chart axis
|
||||
/// </summary>
|
||||
public abstract class AxisBase : ChartSettingItemBase, ISerializationCallbackReceiver
|
||||
{
|
||||
#pragma warning disable 0414
|
||||
/// <summary>
|
||||
/// used internally by the axis inspector
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private bool SimpleView = true;
|
||||
#pragma warning restore 0414
|
||||
/// <summary>
|
||||
/// the format of the axis labels. This can be either a number, time or date time. If the selected value is either DateTime or Time , user ChartDateUtillity to convert dates to double values that can be set to the chart.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("the format of the axis labels. This can be either a number, time or date time. If the selected value is either DateTime or Time , user ChartDateUtillity to convert dates to double values that can be set to the graph")]
|
||||
private AxisFormat format;
|
||||
|
||||
/// <summary>
|
||||
/// the format of the axis labels. This can be either a number, time or date time. If the selected value is either DateTime or Time , user ChartDateUtillity to convert dates to double values that can be set to the chart.
|
||||
/// </summary>
|
||||
public AxisFormat Format
|
||||
{
|
||||
get { return format; }
|
||||
set
|
||||
{
|
||||
format = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the depth of the axis reltive to the chart position
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("the depth of the axis reltive to the chart position")]
|
||||
private AutoFloat depth;
|
||||
public AutoFloat Depth
|
||||
{
|
||||
get { return depth; }
|
||||
set { depth = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The main divisions of the chart axis")]
|
||||
[FormerlySerializedAs("MainDivisions")]
|
||||
private ChartMainDivisionInfo mainDivisions = new ChartMainDivisionInfo();
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The sub divisions of each main division")]
|
||||
[FormerlySerializedAs("SubDivisions")]
|
||||
private ChartSubDivisionInfo subDivisions = new ChartSubDivisionInfo();
|
||||
|
||||
|
||||
private Dictionary<double, string> mFormats = new Dictionary<double, string>();
|
||||
private List<double> mTmpToRemove = new List<double>();
|
||||
/// <summary>
|
||||
/// the main division properies for this axis
|
||||
/// </summary>
|
||||
public ChartMainDivisionInfo MainDivisions { get { return mainDivisions; } }
|
||||
/// <summary>
|
||||
/// the sub division properies for this axis
|
||||
/// </summary>
|
||||
public ChartDivisionInfo SubDivisions { get { return subDivisions; } }
|
||||
public void ClearFormats()
|
||||
{
|
||||
mFormats.Clear();
|
||||
}
|
||||
public AxisBase()
|
||||
{
|
||||
AddInnerItems();
|
||||
}
|
||||
private void AddInnerItems()
|
||||
{
|
||||
AddInnerItem(MainDivisions);
|
||||
AddInnerItem(SubDivisions);
|
||||
}
|
||||
/// <summary>
|
||||
/// used internally to hold data required for updating the axis lables
|
||||
/// </summary>
|
||||
internal class TextData
|
||||
{
|
||||
public ChartDivisionInfo info;
|
||||
public float interp;
|
||||
public int fractionDigits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// checks that all properies of this instance have valid values. This method is used internally and should not be called
|
||||
/// </summary>
|
||||
public void ValidateProperties()
|
||||
{
|
||||
mainDivisions.ValidateProperites();
|
||||
subDivisions.ValidateProperites();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// retrieves the begining and end division of the chart
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="orientation"></param>
|
||||
/// <param name="total"></param>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
private void GetStartEnd(AnyChart parent, ChartOrientation orientation, float total, out float start, out float end)
|
||||
{
|
||||
start = 0;
|
||||
end = total;
|
||||
// if ((orientation == ChartOrientation.Horizontal) ? parent.Frame.Left.Visible : parent.Frame.Bottom.Visible)
|
||||
// ++start;
|
||||
// if ((orientation == ChartOrientation.Horizontal) ? parent.Frame.Right.Visible : parent.Frame.Top.Visible)
|
||||
// --end;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the uv of a chart mesh based on the current length and offset
|
||||
/// </summary>
|
||||
/// <param name="mesh"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <param name="offset"></param>
|
||||
private void SetMeshUv(IChartMesh mesh, float length,float offset)
|
||||
{
|
||||
if (length < 0)
|
||||
offset -= length;
|
||||
mesh.Length = length;
|
||||
mesh.Offset = offset;
|
||||
}
|
||||
|
||||
private void DrawDivisions(double scrollOffset, AnyChart parent, Transform parentTransform, ChartDivisionInfo info, IChartMesh mesh, int group, ChartOrientation orientation, double gap, bool oppositeSide, double mainGap)
|
||||
{
|
||||
//scrollOffset = -scrollOffset;
|
||||
double parentSize = (orientation == ChartOrientation.Vertical) ? ((IInternalUse)parent).InternalTotalHeight : ((IInternalUse)parent).InternalTotalWidth;
|
||||
DoubleVector3 startPosition, lengthDirection, advanceDirection;
|
||||
GetDirectionVectors(parent, info, orientation, 0f, oppositeSide, out startPosition, out lengthDirection, out advanceDirection);
|
||||
double markDepth = ChartCommon.GetAutoDepth(parent, orientation, info);
|
||||
double length = ChartCommon.GetAutoLength(parent, orientation, info);
|
||||
double backLength = (orientation == ChartOrientation.Vertical) ? ((IInternalUse)parent).InternalTotalWidth : ((IInternalUse)parent).InternalTotalHeight;
|
||||
|
||||
if (info.MarkBackLength.Automatic == false)
|
||||
backLength = info.MarkBackLength.Value;
|
||||
|
||||
double totaluv = Math.Abs(length);
|
||||
if (backLength != 0 && markDepth > 0)
|
||||
totaluv += Math.Abs(backLength) + Math.Abs(markDepth);
|
||||
|
||||
DoubleVector3 halfThickness = advanceDirection * (info.MarkThickness * 0.5f);
|
||||
// if (scrollOffset != 0f)
|
||||
// last--;
|
||||
|
||||
bool hasValues = ((IInternalUse)parent).InternalHasValues(this);
|
||||
double maxValue = ((IInternalUse)parent).InternalMaxValue(this);
|
||||
double minValue = ((IInternalUse)parent).InternalMinValue(this);
|
||||
double range = maxValue - minValue;
|
||||
|
||||
float AutoAxisDepth = Depth.Value;
|
||||
// float scrollFactor = (scrollOffset / (float)(maxValue - minValue));
|
||||
//scrollOffset = scrollFactor * parentSize;
|
||||
|
||||
if (Depth.Automatic)
|
||||
{
|
||||
AutoAxisDepth = (float)((((IInternalUse)parent).InternalTotalDepth) - markDepth);
|
||||
}
|
||||
|
||||
double startValue = (scrollOffset + minValue);
|
||||
double endValue = (scrollOffset + maxValue) + double.Epsilon;
|
||||
double direction = 1.0;
|
||||
Func<double, double> ValueToPosition = x => ((x - startValue) / range) * parentSize;
|
||||
if (startValue > endValue)
|
||||
{
|
||||
direction = -1.0;
|
||||
//ValueToPosition = x => (1.0- ((x - startValue) / range)) * parentSize;
|
||||
}
|
||||
gap = Math.Abs(gap);
|
||||
double fraction = gap - (scrollOffset - Math.Floor((scrollOffset / gap) - double.Epsilon) * gap);
|
||||
double mainfraction = -1f;
|
||||
double currentMain = 0f;
|
||||
|
||||
if (mainGap > 0f)
|
||||
{
|
||||
mainfraction = mainGap - (scrollOffset - Math.Floor((scrollOffset / mainGap) - double.Epsilon) * mainGap);
|
||||
currentMain = (scrollOffset + minValue + mainfraction);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
mTmpToRemove.Clear();
|
||||
double startRange = startValue + fraction;
|
||||
foreach (double key in mFormats.Keys)
|
||||
{
|
||||
if (key* direction > endValue* direction || key* direction < startRange* direction)
|
||||
mTmpToRemove.Add(key);
|
||||
}
|
||||
for(int k=0; k<mTmpToRemove.Count; k++)
|
||||
mFormats.Remove(mTmpToRemove[k]);
|
||||
for (double current = startRange; direction*current <= direction*endValue; current += gap*direction)
|
||||
{
|
||||
|
||||
++i;
|
||||
if (i > 3000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (mainGap > 0.0)
|
||||
{
|
||||
if(Math.Abs(current - currentMain) < 0.00001)
|
||||
{
|
||||
currentMain += mainGap;
|
||||
continue;
|
||||
}
|
||||
if(current > currentMain)
|
||||
{
|
||||
currentMain += mainGap;
|
||||
}
|
||||
}
|
||||
|
||||
double offset = ValueToPosition(current);
|
||||
if (offset < 0 || offset > parentSize)
|
||||
continue;
|
||||
DoubleVector3 start = startPosition + advanceDirection * offset;
|
||||
DoubleVector3 size = halfThickness + length * lengthDirection;
|
||||
start -= halfThickness;
|
||||
//size += halfThickness;
|
||||
float uvoffset = 0f;
|
||||
|
||||
Rect r = ChartCommon.FixRect(new Rect((float)start.x, (float)start.y, (float)size.x, (float)size.y));
|
||||
|
||||
SetMeshUv(mesh, (float)(-length / totaluv), uvoffset);
|
||||
uvoffset += Math.Abs(mesh.Length);
|
||||
|
||||
mesh.AddXYRect(r, group, AutoAxisDepth);
|
||||
if (hasValues)
|
||||
{
|
||||
double val = Math.Round(current*1000.0)/1000.0;
|
||||
string toSet = "";
|
||||
double keyVal = val;// (int)Math.Round(val);
|
||||
var dic = (orientation == ChartOrientation.Horizontal) ? parent.HorizontalValueToStringMap : parent.VerticalValueToStringMap;
|
||||
if (!(Math.Abs(val - keyVal) < 0.001 && dic.TryGetValue(keyVal, out toSet)))
|
||||
{
|
||||
if (mFormats.TryGetValue(val, out toSet) == false)
|
||||
{
|
||||
if (format == AxisFormat.Number)
|
||||
toSet = ChartAdancedSettings.Instance.FormatFractionDigits(info.FractionDigits, val, parent.CustomNumberFormat);
|
||||
else
|
||||
{
|
||||
DateTime date = ChartDateUtility.ValueToDate(val);
|
||||
if (format == AxisFormat.DateTime)
|
||||
toSet = ChartDateUtility.DateToDateTimeString(date, parent.CustomDateTimeFormat);
|
||||
else
|
||||
{
|
||||
if (format == AxisFormat.Date)
|
||||
toSet = ChartDateUtility.DateToDateString(date);
|
||||
else
|
||||
toSet = ChartDateUtility.DateToTimeString(date);
|
||||
}
|
||||
}
|
||||
toSet = info.TextPrefix + toSet + info.TextSuffix;
|
||||
mFormats[val] = toSet;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
toSet = info.TextPrefix + toSet + info.TextSuffix;
|
||||
}
|
||||
|
||||
|
||||
DoubleVector3 textPos = new DoubleVector3(start.x, start.y);
|
||||
textPos += lengthDirection * info.TextSeperation;
|
||||
TextData userData = new TextData();
|
||||
userData.interp = (float)(offset/parentSize);
|
||||
userData.info = info;
|
||||
userData.fractionDigits = info.FractionDigits;
|
||||
mesh.AddText(parent, info.TextPrefab, parentTransform, info.FontSize, info.FontSharpness, toSet, (float)textPos.x, (float)textPos.y, AutoAxisDepth + info.TextDepth, 0f, userData);
|
||||
}
|
||||
|
||||
if (markDepth > 0)
|
||||
{
|
||||
if (orientation == ChartOrientation.Horizontal)
|
||||
{
|
||||
SetMeshUv(mesh,(float)( markDepth / totaluv), uvoffset);
|
||||
r = ChartCommon.FixRect(new Rect((float)start.x, AutoAxisDepth, (float)size.x, (float)markDepth));
|
||||
mesh.AddXZRect(r, group, (float)start.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMeshUv(mesh,(float) (-markDepth / totaluv), uvoffset);
|
||||
r = ChartCommon.FixRect(new Rect((float)start.y, AutoAxisDepth, (float)size.y, (float)markDepth));
|
||||
mesh.AddYZRect(r, group, (float)start.x);
|
||||
}
|
||||
|
||||
uvoffset += Math.Abs(mesh.Length);
|
||||
|
||||
if (backLength != 0)
|
||||
{
|
||||
SetMeshUv(mesh, (float)(backLength / totaluv), uvoffset);
|
||||
uvoffset += Math.Abs(mesh.Length);
|
||||
DoubleVector3 backSize = halfThickness + backLength * lengthDirection;
|
||||
Rect backR = ChartCommon.FixRect(new Rect((float)start.x, (float)start.y, (float)backSize.x, (float)backSize.y));
|
||||
mesh.AddXYRect(backR, group, (float)(AutoAxisDepth + markDepth));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Debug.Log("start");
|
||||
// Debug.Log(mFormats.Count);
|
||||
// Debug.Log(cached);
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// used internally to draw the division of the axis into a chart mesh
|
||||
// /// </summary>
|
||||
// /// <param name="parent"></param>
|
||||
// /// <param name="parentTransform"></param>
|
||||
// /// <param name="info"></param>
|
||||
// /// <param name="mesh"></param>
|
||||
// /// <param name="group"></param>
|
||||
// /// <param name="orientation"></param>
|
||||
// /// <param name="totalDivisions"></param>
|
||||
// /// <param name="oppositeSide"></param>
|
||||
// /// <param name="skip"></param>
|
||||
// private void DrawDivisions(float scrollOffset,AnyChart parent, Transform parentTransform, ChartDivisionInfo info, IChartMesh mesh, int group, ChartOrientation orientation, float totalDivisions, bool oppositeSide, int skip)
|
||||
// {
|
||||
// //scrollOffset = -scrollOffset;
|
||||
// float parentSize = (orientation == ChartOrientation.Vertical) ? ((IInternalUse)parent).InternalTotalHeight : ((IInternalUse)parent).InternalTotalWidth;
|
||||
// Vector2 startPosition, lengthDirection, advanceDirection;
|
||||
// GetDirectionVectors(parent, info, orientation, 0f, oppositeSide, out startPosition, out lengthDirection, out advanceDirection);
|
||||
// float markDepth = ChartCommon.GetAutoDepth(parent, orientation, info);
|
||||
// float length = ChartCommon.GetAutoLength(parent, orientation, info);
|
||||
// float backLength = (orientation == ChartOrientation.Vertical) ? ((IInternalUse)parent).InternalTotalWidth : ((IInternalUse)parent).InternalTotalHeight;
|
||||
|
||||
// if (info.MarkBackLength.Automatic == false)
|
||||
// backLength = info.MarkBackLength.Value;
|
||||
|
||||
// float totaluv = Math.Abs(length);
|
||||
// if (backLength != 0 && markDepth > 0)
|
||||
// totaluv += Math.Abs(backLength) + Math.Abs(markDepth);
|
||||
|
||||
// Vector2 halfThickness = advanceDirection * (info.MarkThickness * 0.5f);
|
||||
// // if (scrollOffset != 0f)
|
||||
// // last--;
|
||||
|
||||
// bool hasValues = ((IInternalUse)parent).InternalHasValues(this);
|
||||
// double maxValue = ((IInternalUse)parent).InternalMaxValue(this);
|
||||
// double minValue = ((IInternalUse)parent).InternalMinValue(this);
|
||||
// ChartMainDivisionInfo main = info as ChartMainDivisionInfo;
|
||||
|
||||
// float divisionComplement = 0f;
|
||||
// float divisionOffsetComplement = 0f;
|
||||
// if (main != null)
|
||||
// {
|
||||
// if(main.Messure == ChartDivisionInfo.DivisionMessure.DataUnits)
|
||||
// {
|
||||
// if (main.UnitsPerDivision <= 0.0001f)
|
||||
// return;
|
||||
// float range = (float)(maxValue - minValue);
|
||||
// totalDivisions = (range / main.UnitsPerDivision) + 1;
|
||||
// divisionComplement = (float)(1f - (main.UnitsPerDivision - Math.Truncate(main.UnitsPerDivision))) / range;
|
||||
// divisionOffsetComplement = (divisionComplement) * parentSize;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// float first, last;
|
||||
// GetStartEnd(parent, orientation, totalDivisions, out first, out last);
|
||||
|
||||
// float AutoAxisDepth = Depth.Value;
|
||||
// float scrollFactor = (scrollOffset / (float)(maxValue - minValue));
|
||||
// scrollOffset = scrollFactor * parentSize;
|
||||
|
||||
// if (Depth.Automatic)
|
||||
// {
|
||||
// AutoAxisDepth = (((IInternalUse)parent).InternalTotalDepth) - markDepth;
|
||||
// }
|
||||
|
||||
// float floorLast = Mathf.Floor(last);
|
||||
// for (float i = first; i < floorLast; i++)
|
||||
// {
|
||||
// if (skip != -1 && ((int)i) % skip == 0)
|
||||
// continue;
|
||||
// float factor = ((float)i) / (float)(totalDivisions - 1);
|
||||
// float offset = -scrollOffset + factor * parentSize;
|
||||
// if (scrollOffset != 0f)
|
||||
// {
|
||||
// float prevOffs = offset;
|
||||
// offset = offset - Mathf.Floor((offset / parentSize)) * parentSize;
|
||||
//// Debug.Log("prev " + prevOffs);
|
||||
//// Debug.Log("offs " + offset);
|
||||
// if (offset < prevOffs)
|
||||
// {
|
||||
// offset -= divisionOffsetComplement;
|
||||
// }
|
||||
// }
|
||||
// if (offset < 0f)
|
||||
// continue;
|
||||
// Vector2 start = startPosition + advanceDirection * offset;
|
||||
// Vector2 size = halfThickness + length * lengthDirection;
|
||||
// start -= halfThickness;
|
||||
// //size += halfThickness;
|
||||
// float uvoffset = 0f;
|
||||
|
||||
// Rect r = ChartCommon.FixRect(new Rect(start.x, start.y, size.x, size.y));
|
||||
|
||||
// SetMeshUv(mesh, -length / totaluv, uvoffset);
|
||||
// uvoffset += Math.Abs(mesh.Length);
|
||||
|
||||
// mesh.AddXYRect(r, group, AutoAxisDepth);
|
||||
|
||||
// if (hasValues)
|
||||
// {
|
||||
// float valFactor = -scrollFactor + factor;
|
||||
// if (scrollOffset != 0f)
|
||||
// {
|
||||
// float prevFact = valFactor;
|
||||
// valFactor -= Mathf.Floor(valFactor);
|
||||
// if(valFactor < prevFact)
|
||||
// {
|
||||
// valFactor -= divisionComplement;
|
||||
// }
|
||||
// }
|
||||
// //valFactor += scrollFactor;
|
||||
// double offsetPos = (maxValue - minValue) * valFactor;
|
||||
// double scroll = minValue + ((maxValue - minValue) * scrollFactor);
|
||||
// double val = scroll + offsetPos;
|
||||
// string toSet = "";
|
||||
// if (format == AxisFormat.Number)
|
||||
// toSet = ChartAdancedSettings.Instance.FormatFractionDigits(info.FractionDigits, (float)val);
|
||||
// else
|
||||
// {
|
||||
// DateTime date = ChartDateUtility.ValueToDate(val);
|
||||
// if (format == AxisFormat.DateTime)
|
||||
// toSet = ChartDateUtility.DateToDateTimeString(date);
|
||||
// else
|
||||
// {
|
||||
// if (format == AxisFormat.Date)
|
||||
// toSet = ChartDateUtility.DateToDateString(date);
|
||||
// else
|
||||
// toSet = ChartDateUtility.DateToTimeString(date);
|
||||
// }
|
||||
// }
|
||||
|
||||
// toSet = info.TextPrefix + toSet + info.TextSuffix;
|
||||
// Vector2 textPos = new Vector2(start.x, start.y);
|
||||
// textPos += lengthDirection * info.TextSeperation;
|
||||
// TextData userData = new TextData();
|
||||
// userData.interp = factor;
|
||||
// userData.info = info;
|
||||
// userData.fractionDigits = info.FractionDigits;
|
||||
// mesh.AddText(parent, info.TextPrefab, parentTransform, info.FontSize, info.FontSharpness, toSet, textPos.x, textPos.y, AutoAxisDepth + info.TextDepth,0f, userData);
|
||||
// }
|
||||
|
||||
// if (markDepth > 0)
|
||||
// {
|
||||
// if (orientation == ChartOrientation.Horizontal)
|
||||
// {
|
||||
// SetMeshUv(mesh, markDepth / totaluv, uvoffset);
|
||||
// r = ChartCommon.FixRect(new Rect(start.x, AutoAxisDepth, size.x, markDepth));
|
||||
// mesh.AddXZRect(r, group, start.y);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// SetMeshUv(mesh, -markDepth / totaluv, uvoffset);
|
||||
// r = ChartCommon.FixRect(new Rect(start.y, AutoAxisDepth, size.y, markDepth));
|
||||
// mesh.AddYZRect(r, group, start.x);
|
||||
// }
|
||||
|
||||
// uvoffset += Math.Abs(mesh.Length);
|
||||
|
||||
// if (backLength != 0)
|
||||
// {
|
||||
// SetMeshUv(mesh, backLength / totaluv, uvoffset);
|
||||
// uvoffset += Math.Abs(mesh.Length);
|
||||
// Vector2 backSize = halfThickness + backLength * lengthDirection;
|
||||
// Rect backR = ChartCommon.FixRect(new Rect(start.x, start.y, backSize.x, backSize.y));
|
||||
// mesh.AddXYRect(backR, group, AutoAxisDepth + markDepth);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// used internally to determine drawing direction of the each chart division
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="info"></param>
|
||||
/// <param name="orientation"></param>
|
||||
/// <param name="oppositeSide"></param>
|
||||
/// <param name="startPosition"></param>
|
||||
/// <param name="lengthDirection"></param>
|
||||
/// <param name="advanceDirection"></param>
|
||||
private void GetDirectionVectors(AnyChart parent, ChartDivisionInfo info, ChartOrientation orientation,float scrollOffset, bool oppositeSide, out DoubleVector3 startPosition, out DoubleVector3 lengthDirection, out DoubleVector3 advanceDirection)
|
||||
{
|
||||
if (orientation == ChartOrientation.Horizontal)
|
||||
{
|
||||
advanceDirection = new DoubleVector3(1f, 0f);
|
||||
if (oppositeSide)
|
||||
{
|
||||
startPosition = new DoubleVector3(scrollOffset, ((IInternalUse)parent).InternalTotalHeight);
|
||||
lengthDirection = new DoubleVector3(0f, -1f);
|
||||
return;
|
||||
}
|
||||
startPosition = new DoubleVector3(0f, 0f);
|
||||
lengthDirection = new DoubleVector3(0f, 1f);
|
||||
return;
|
||||
}
|
||||
advanceDirection = new DoubleVector3(0f, 1f);
|
||||
if (oppositeSide)
|
||||
{
|
||||
startPosition = new DoubleVector3(0f, 0f);
|
||||
lengthDirection = new DoubleVector3(1f, 0f);
|
||||
return;
|
||||
}
|
||||
startPosition = new DoubleVector3(((IInternalUse)parent).InternalTotalWidth, scrollOffset);
|
||||
lengthDirection = new DoubleVector3(-1f, 0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// used internally , adds the axis sub divisions to the chart mesh
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="parentTransform"></param>
|
||||
/// <param name="mesh"></param>
|
||||
/// <param name="orientation"></param>
|
||||
internal void AddSubdivisionToChartMesh(double scrollOffset,AnyChart parent, Transform parentTransform, IChartMesh mesh, ChartOrientation orientation)
|
||||
{
|
||||
int total = SubDivisions.Total;
|
||||
if (total <= 1) // no need for more
|
||||
return;
|
||||
double maxValue = ((IInternalUse)parent).InternalMaxValue(this);
|
||||
double minValue = ((IInternalUse)parent).InternalMinValue(this);
|
||||
double range = maxValue - minValue;
|
||||
double? gap = GetMainGap(parent, range);
|
||||
if (gap.HasValue == false)
|
||||
return;
|
||||
double subGap = gap.Value / (total);
|
||||
mesh.Tile = ChartCommon.GetTiling(SubDivisions.MaterialTiling);
|
||||
if ((SubDivisions.Alignment & ChartDivisionAligment.Opposite) == ChartDivisionAligment.Opposite)
|
||||
DrawDivisions(scrollOffset,parent, parentTransform, SubDivisions, mesh, 0, orientation, subGap, false, gap.Value);
|
||||
if ((SubDivisions.Alignment & ChartDivisionAligment.Standard) == ChartDivisionAligment.Standard)
|
||||
DrawDivisions(scrollOffset,parent, parentTransform, SubDivisions, mesh, 0, orientation, subGap, true, gap.Value);
|
||||
}
|
||||
|
||||
double? GetMainGap(AnyChart parent, double range)
|
||||
{
|
||||
double gap = ((ChartMainDivisionInfo)MainDivisions).UnitsPerDivision;
|
||||
if (((ChartMainDivisionInfo)MainDivisions).Messure == ChartDivisionInfo.DivisionMessure.TotalDivisions)
|
||||
{
|
||||
int total = ((ChartMainDivisionInfo)MainDivisions).Total;
|
||||
if (total <= 0)
|
||||
return null;
|
||||
gap = (range / (double)(total));
|
||||
}
|
||||
return gap;
|
||||
}
|
||||
/// <summary>
|
||||
/// used internally , adds the axis main divisions to the chart mesh
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="parentTransform"></param>
|
||||
/// <param name="mesh"></param>
|
||||
/// <param name="orientation"></param>
|
||||
|
||||
internal void AddMainDivisionToChartMesh(double scrollOffset,AnyChart parent, Transform parentTransform, IChartMesh mesh, ChartOrientation orientation)
|
||||
{
|
||||
double maxValue = ((IInternalUse)parent).InternalMaxValue(this);
|
||||
double minValue = ((IInternalUse)parent).InternalMinValue(this);
|
||||
double range = maxValue - minValue;
|
||||
double? gap = GetMainGap(parent, range);
|
||||
if (gap.HasValue == false)
|
||||
return;
|
||||
mesh.Tile = ChartCommon.GetTiling(MainDivisions.MaterialTiling);
|
||||
if ((MainDivisions.Alignment & ChartDivisionAligment.Opposite) == ChartDivisionAligment.Opposite)
|
||||
DrawDivisions(scrollOffset,parent, parentTransform, MainDivisions, mesh, 0, orientation,gap.Value, false, -1);
|
||||
if ((MainDivisions.Alignment & ChartDivisionAligment.Standard) == ChartDivisionAligment.Standard)
|
||||
DrawDivisions(scrollOffset,parent, parentTransform, MainDivisions, mesh, 0, orientation, gap.Value, true, -1);
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
AddInnerItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae8b4348f222b8246983af20f8444169
|
||||
timeCreated: 1479124371
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,31 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration for the format of axis label data.
|
||||
/// </summary>
|
||||
public enum AxisFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// format the labels as floating point numbers
|
||||
/// </summary>
|
||||
Number,
|
||||
/// <summary>
|
||||
/// format the labels as time of day
|
||||
/// </summary>
|
||||
Time,
|
||||
/// <summary>
|
||||
/// format the labels as date only
|
||||
/// </summary>
|
||||
Date,
|
||||
/// <summary>
|
||||
/// format the labels as date and time
|
||||
/// </summary>
|
||||
DateTime,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a65b5ecb37567ff4f92e31c7b6438605
|
||||
timeCreated: 1480864086
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
namespace ChartAndGraph.Axis
|
||||
{
|
||||
public partial class AxisGenerator : MonoBehaviour,IAxisGenerator
|
||||
{
|
||||
partial void InnerFixLabels(AnyChart parent);
|
||||
partial void InnerSetAxis(double scrollOffset, AnyChart parent, AxisBase axis, ChartOrientation axisOrientation, bool isSubDivisions);
|
||||
|
||||
public void FixLabels(AnyChart parent)
|
||||
{
|
||||
InnerFixLabels(parent);
|
||||
}
|
||||
|
||||
public void SetAxis(double scrollOffset, AnyChart parent, AxisBase axis, ChartOrientation axisOrientation, bool isSubDivisions)
|
||||
{
|
||||
InnerSetAxis(scrollOffset, parent, axis, axisOrientation, isSubDivisions);
|
||||
}
|
||||
|
||||
public UnityEngine.Object This()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public GameObject GetGameObject()
|
||||
{
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d784632ef29d0444c8a7273ffbb24ab1
|
||||
timeCreated: 1560543419
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,195 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph.Axis
|
||||
{
|
||||
/// <summary>
|
||||
/// generates an axis mesh from an AxisBase settings instance.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(MeshRenderer))]
|
||||
[RequireComponent(typeof(MeshFilter))]
|
||||
[ExecuteInEditMode]
|
||||
partial class AxisGenerator
|
||||
{
|
||||
MeshRenderer mRenderer;
|
||||
MeshFilter mFilter;
|
||||
Mesh mCleanMesh;
|
||||
List<BillboardText> mTexts;
|
||||
AxisBase mAxis;
|
||||
Material mDispose;
|
||||
Material mMaterial;
|
||||
float mTiling=1f;
|
||||
WorldSpaceChartMesh mMesh;
|
||||
Mesh mCreated;
|
||||
double mScroll = 0f;
|
||||
AnyChart mParent = null;
|
||||
ChartOrientation mOrientation = ChartOrientation.Vertical;
|
||||
bool mIsSubDivision = false;
|
||||
void Start()
|
||||
{
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
ChartCommon.CleanMesh(null, ref mCleanMesh);
|
||||
ChartCommon.SafeDestroy(mDispose);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// fix the labels after the axis data is updated
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
partial void InnerFixLabels(AnyChart parent)
|
||||
{
|
||||
if (mAxis == null)
|
||||
return;
|
||||
if(((ChartMainDivisionInfo) mAxis.MainDivisions).Messure == ChartDivisionInfo.DivisionMessure.DataUnits)
|
||||
{
|
||||
SetAxis(mScroll, mParent, mAxis, mOrientation, mIsSubDivision);
|
||||
return;
|
||||
}
|
||||
for(int i=0; i<mTexts.Count; i++)
|
||||
{
|
||||
BillboardText text = mTexts[i];
|
||||
double min = ((IInternalUse)parent).InternalMinValue(mAxis);
|
||||
double max = ((IInternalUse)parent).InternalMaxValue(mAxis);
|
||||
if (text.UserData is AxisBase.TextData)
|
||||
{
|
||||
AxisBase.TextData data = (AxisBase.TextData)text.UserData;
|
||||
double newVal = min * (1.0 - (double)data.interp) + max * (double)data.interp;
|
||||
string toSet = "";
|
||||
if (mAxis.Format == AxisFormat.Number)
|
||||
toSet = ChartAdancedSettings.Instance.FormatFractionDigits(data.fractionDigits, (float)newVal,parent.CustomNumberFormat);
|
||||
else
|
||||
{
|
||||
DateTime date = ChartDateUtility.ValueToDate(newVal);
|
||||
if (mAxis.Format == AxisFormat.DateTime)
|
||||
toSet = ChartDateUtility.DateToDateTimeString(date,mParent.CustomDateTimeFormat);
|
||||
else
|
||||
{
|
||||
if (mAxis.Format == AxisFormat.Date)
|
||||
toSet = ChartDateUtility.DateToDateString(date);
|
||||
else
|
||||
toSet = ChartDateUtility.DateToTimeString(date);
|
||||
}
|
||||
|
||||
}
|
||||
toSet = data.info.TextPrefix + toSet + data.info.TextSuffix;
|
||||
ChartCommon.UpdateTextParams(text.UIText, toSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// used internally to get the tiling for a chart axis division
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="orientation"></param>
|
||||
/// <param name="inf"></param>
|
||||
/// <returns></returns>
|
||||
float GetTiling(AnyChart parent, ChartOrientation orientation, ChartDivisionInfo inf)
|
||||
{
|
||||
MaterialTiling tiling = inf.MaterialTiling;
|
||||
if (tiling.EnableTiling == false || tiling.TileFactor <= 0f)
|
||||
return 1f;
|
||||
float length = Math.Abs(ChartCommon.GetAutoLength(parent, orientation, inf));
|
||||
float backLength = ChartCommon.GetAutoLength(parent, orientation);
|
||||
float depth = ChartCommon.GetAutoDepth(parent, orientation, inf);
|
||||
if (inf.MarkBackLength.Automatic == false)
|
||||
backLength = inf.MarkBackLength.Value;
|
||||
if (backLength != 0 && depth > 0)
|
||||
length += Math.Abs(backLength) + Math.Abs(depth);
|
||||
return length / tiling.TileFactor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the axis settings. Calling this method will cause the axisgenerator to create the axis mesh
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="axis"></param>
|
||||
/// <param name="axisOrientation"></param>
|
||||
/// <param name="isSubDivisions"></param>
|
||||
partial void InnerSetAxis(double scrollOffset, AnyChart parent, AxisBase axis, ChartOrientation axisOrientation, bool isSubDivisions)
|
||||
{
|
||||
mScroll = scrollOffset;
|
||||
mParent = parent;
|
||||
mAxis = axis;
|
||||
mOrientation = axisOrientation;
|
||||
mIsSubDivision = isSubDivisions;
|
||||
if (mMesh == null)
|
||||
{
|
||||
mMesh = new WorldSpaceChartMesh(2);
|
||||
mMesh.RecycleText = true;
|
||||
}
|
||||
|
||||
mMesh.Clear();
|
||||
mMesh.Orientation = axisOrientation;
|
||||
mAxis = axis;
|
||||
|
||||
if (isSubDivisions)
|
||||
axis.AddSubdivisionToChartMesh(scrollOffset,parent, transform, mMesh, axisOrientation);
|
||||
else
|
||||
axis.AddMainDivisionToChartMesh(scrollOffset,parent, transform, mMesh, axisOrientation);
|
||||
|
||||
if (mMesh.TextObjects != null)
|
||||
{
|
||||
foreach (BillboardText text in mMesh.TextObjects)
|
||||
{
|
||||
((IInternalUse)parent).InternalTextController.AddText(text);
|
||||
}
|
||||
}
|
||||
mTexts = mMesh.CurrentTextObjects;
|
||||
|
||||
Mesh newMesh = mMesh.Generate(mCreated);
|
||||
mCreated = newMesh;
|
||||
newMesh.hideFlags = HideFlags.DontSave;
|
||||
if (mFilter == null)
|
||||
mFilter = GetComponent<MeshFilter>();
|
||||
mFilter.sharedMesh = newMesh;
|
||||
MeshCollider collider = GetComponent<MeshCollider>();
|
||||
if (collider != null)
|
||||
collider.sharedMesh = newMesh;
|
||||
ChartCommon.CleanMesh(newMesh, ref mCleanMesh);
|
||||
|
||||
MeshRenderer renderer = GetComponent<MeshRenderer>();
|
||||
if(renderer != null)
|
||||
{
|
||||
Material m = mAxis.MainDivisions.Material;
|
||||
float tiling = GetTiling(parent, axisOrientation, mAxis.MainDivisions);
|
||||
if (isSubDivisions)
|
||||
{
|
||||
m = mAxis.SubDivisions.Material;
|
||||
tiling = GetTiling(parent, axisOrientation, mAxis.SubDivisions) ;
|
||||
}
|
||||
mMaterial = m;
|
||||
if (m != null)
|
||||
{
|
||||
ChartCommon.SafeDestroy(mDispose);
|
||||
mDispose = new Material(m);
|
||||
mDispose.hideFlags = HideFlags.DontSave;
|
||||
renderer.sharedMaterial = mDispose;
|
||||
mTiling = tiling;
|
||||
if (mDispose.HasProperty("_ChartTiling"))
|
||||
mDispose.SetFloat("_ChartTiling", mTiling);
|
||||
}
|
||||
}
|
||||
mMesh.DestoryRecycled();
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (mMaterial != null && mDispose != null && mDispose.HasProperty("_ChartTiling"))
|
||||
{
|
||||
if (mDispose != mMaterial)
|
||||
mDispose.CopyPropertiesFromMaterial(mMaterial);
|
||||
mDispose.SetFloat("_ChartTiling", mTiling);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bfad3f1e4ea9a644bbd41612e6342ef
|
||||
timeCreated: 1472984373
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,227 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ChartAndGraph.Axis
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates an axis mesh for a canvas chart
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
[ExecuteInEditMode]
|
||||
class CanvasAxisGenerator : Image, IAxisGenerator
|
||||
{
|
||||
MeshRenderer mRenderer;
|
||||
MeshFilter mFilter;
|
||||
Mesh mCleanMesh;
|
||||
List<BillboardText> mTexts;
|
||||
AxisBase mAxis;
|
||||
AnyChart mParent;
|
||||
ChartOrientation mOrientation;
|
||||
bool mIsSubDivisions;
|
||||
Material mDispose = null;
|
||||
Material mMaterial;
|
||||
CanvasChartMesh mMesh = null;
|
||||
float mTiling = 1f;
|
||||
double mScrollOffset;
|
||||
#if (!UNITY_5_2_0) && (!UNITY_5_2_1)
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
base.OnPopulateMesh(vh);
|
||||
vh.Clear();
|
||||
if (mAxis == null || mParent == null)
|
||||
return;
|
||||
CanvasChartMesh mesh = new CanvasChartMesh(vh);
|
||||
AddToCanvasChartMesh(mesh);
|
||||
}
|
||||
#endif
|
||||
|
||||
private void AddToCanvasChartMesh(CanvasChartMesh mesh)
|
||||
{
|
||||
mesh.Orientation = mOrientation;
|
||||
if (mIsSubDivisions)
|
||||
mAxis.AddSubdivisionToChartMesh(mScrollOffset,mParent, transform, mesh, mOrientation);
|
||||
else
|
||||
mAxis.AddMainDivisionToChartMesh(mScrollOffset,mParent, transform, mesh, mOrientation);
|
||||
}
|
||||
|
||||
#pragma warning disable 0672
|
||||
|
||||
protected override void OnPopulateMesh(Mesh m)
|
||||
{
|
||||
m.Clear();
|
||||
if (mAxis == null || mParent == null)
|
||||
return;
|
||||
WorldSpaceChartMesh mesh = new WorldSpaceChartMesh(true);
|
||||
mesh.Orientation = mOrientation;
|
||||
if(mIsSubDivisions)
|
||||
mAxis.AddMainDivisionToChartMesh(mScrollOffset,mParent, transform, mesh, mOrientation);
|
||||
else
|
||||
mAxis.AddSubdivisionToChartMesh(mScrollOffset,mParent, transform, mesh, mOrientation);
|
||||
mesh.ApplyToMesh(m);
|
||||
}
|
||||
#pragma warning restore 0672
|
||||
|
||||
public void FixLabels(AnyChart parent)
|
||||
{
|
||||
if (mAxis == null)
|
||||
return;
|
||||
if (((ChartMainDivisionInfo)mAxis.MainDivisions).Messure == ChartDivisionInfo.DivisionMessure.DataUnits)
|
||||
{
|
||||
SetAxis(mScrollOffset, mParent, mAxis, mOrientation, mIsSubDivisions);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < mTexts.Count; i++)
|
||||
{
|
||||
BillboardText text = mTexts[i];
|
||||
double min = ((IInternalUse)parent).InternalMinValue(mAxis);
|
||||
double max = ((IInternalUse)parent).InternalMaxValue(mAxis);
|
||||
if (text.UserData is AxisBase.TextData)
|
||||
{
|
||||
AxisBase.TextData data = (AxisBase.TextData)text.UserData;
|
||||
double newVal = min * (1.0 - (double)data.interp) + max * (double)data.interp;
|
||||
string toSet = "";
|
||||
if (mAxis.Format == AxisFormat.Number)
|
||||
toSet = ChartAdancedSettings.Instance.FormatFractionDigits(data.fractionDigits, (float)newVal,parent.CustomNumberFormat);
|
||||
else
|
||||
{
|
||||
DateTime date = ChartDateUtility.ValueToDate(newVal);
|
||||
if (mAxis.Format == AxisFormat.DateTime)
|
||||
toSet = ChartDateUtility.DateToDateTimeString(date,parent.CustomDateTimeFormat);
|
||||
else
|
||||
{
|
||||
if (mAxis.Format == AxisFormat.Date)
|
||||
toSet = ChartDateUtility.DateToDateString(date);
|
||||
else
|
||||
toSet = ChartDateUtility.DateToTimeString(date);
|
||||
}
|
||||
|
||||
}
|
||||
toSet = data.info.TextPrefix + toSet + data.info.TextSuffix;
|
||||
ChartCommon.UpdateTextParams(text.UIText, toSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateMaterial()
|
||||
{
|
||||
base.UpdateMaterial();
|
||||
if (material == null)
|
||||
return;
|
||||
if (material.mainTexture != null)
|
||||
canvasRenderer.SetTexture(material.mainTexture);
|
||||
canvasRenderer.SetColor(Color.white);
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
if (mDispose != null)
|
||||
ChartCommon.SafeDestroy(mDispose);
|
||||
}
|
||||
|
||||
float GetTiling(MaterialTiling tiling)
|
||||
{
|
||||
if (tiling.EnableTiling == false || tiling.TileFactor <= 0f)
|
||||
return 1f;
|
||||
ChartDivisionInfo inf = mAxis.MainDivisions;
|
||||
if (mIsSubDivisions)
|
||||
inf = mAxis.SubDivisions;
|
||||
float length = ChartCommon.GetAutoLength(mParent, mOrientation, inf);
|
||||
return length / tiling.TileFactor;
|
||||
}
|
||||
|
||||
public void SetAxis(double scrollOffset,AnyChart parent, AxisBase axis, ChartOrientation axisOrientation,bool isSubDivisions)
|
||||
{
|
||||
mScrollOffset = scrollOffset;
|
||||
raycastTarget = false;
|
||||
color = Color.white;
|
||||
mAxis = axis;
|
||||
mParent = parent;
|
||||
mIsSubDivisions = isSubDivisions;
|
||||
mOrientation = axisOrientation;
|
||||
|
||||
if (mMesh == null)
|
||||
{
|
||||
mMesh = new CanvasChartMesh(true);
|
||||
mMesh.RecycleText = true;
|
||||
}
|
||||
mMesh.Clear();
|
||||
|
||||
if (isSubDivisions)
|
||||
mAxis.AddMainDivisionToChartMesh(mScrollOffset,mParent, transform, mMesh, mOrientation);
|
||||
else
|
||||
mAxis.AddSubdivisionToChartMesh(mScrollOffset,mParent, transform, mMesh, mOrientation);
|
||||
|
||||
mTexts = mMesh.CurrentTextObjects;
|
||||
if (mMesh.TextObjects != null)
|
||||
{
|
||||
foreach (BillboardText text in mMesh.TextObjects)
|
||||
{
|
||||
((IInternalUse)parent).InternalTextController.AddText(text);
|
||||
}
|
||||
}
|
||||
|
||||
canvasRenderer.materialCount = 1;
|
||||
if (mDispose != null)
|
||||
ChartCommon.SafeDestroy(mDispose);
|
||||
|
||||
float tiling = 1f;
|
||||
if (!isSubDivisions)
|
||||
{
|
||||
if (axis.SubDivisions.Material != null)
|
||||
{
|
||||
mMaterial = axis.SubDivisions.Material;
|
||||
mDispose = new Material(mMaterial);
|
||||
mDispose.hideFlags = HideFlags.DontSave;
|
||||
material = mDispose;
|
||||
tiling = GetTiling(axis.SubDivisions.MaterialTiling);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.MainDivisions.Material != null)
|
||||
{
|
||||
mMaterial = axis.MainDivisions.Material;
|
||||
mDispose = new Material(mMaterial);
|
||||
mDispose.hideFlags = HideFlags.DontSave;
|
||||
material = mDispose;
|
||||
tiling = GetTiling(axis.MainDivisions.MaterialTiling);
|
||||
}
|
||||
}
|
||||
mTiling = tiling;
|
||||
if(mDispose != null)
|
||||
{
|
||||
if (mDispose.HasProperty("_ChartTiling"))
|
||||
mDispose.SetFloat("_ChartTiling", tiling);
|
||||
}
|
||||
SetAllDirty();
|
||||
Rebuild(CanvasUpdate.PreRender);
|
||||
mMesh.DestoryRecycled();
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (mMaterial != null && mDispose != null && mDispose.HasProperty("_ChartTiling"))
|
||||
{
|
||||
if (mDispose != mMaterial)
|
||||
mDispose.CopyPropertiesFromMaterial(mMaterial);
|
||||
mDispose.SetFloat("_ChartTiling", mTiling);
|
||||
}
|
||||
}
|
||||
|
||||
public GameObject GetGameObject()
|
||||
{
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
public UnityEngine.Object This()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d05bb511ff55104f930cb9d1c27c8d7
|
||||
timeCreated: 1478793256
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,423 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// holds settings for an axis division.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ChartDivisionInfo : IInternalSettings
|
||||
{
|
||||
public enum DivisionMessure
|
||||
{
|
||||
TotalDivisions,
|
||||
DataUnits
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// validates all properties of this instance. (check if they have correct values)
|
||||
/// </summary>
|
||||
public void ValidateProperites()
|
||||
{
|
||||
if (total < 0)
|
||||
total = 0;
|
||||
fontSharpness = Mathf.Clamp(fontSharpness, 1f, 3f);
|
||||
fontSize = Mathf.Max(fontSize, 0);
|
||||
fractionDigits = Mathf.Clamp(fractionDigits, 0, 7);
|
||||
markThickness = Mathf.Max(markThickness, 0f);
|
||||
materialTiling.TileFactor = Mathf.Max(materialTiling.TileFactor, 0f);
|
||||
textPrefix = (textPrefix == null) ? "" : textPrefix;
|
||||
textSuffix = (textSuffix == null) ? "" : textSuffix;
|
||||
}
|
||||
|
||||
protected virtual float ValidateTotal(float total)
|
||||
{
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// total division lines
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Canvas, NonCanvas]
|
||||
[Tooltip("messure used to create divisions")]
|
||||
protected DivisionMessure messure = DivisionMessure.TotalDivisions;
|
||||
|
||||
/// <summary>
|
||||
/// data units per each division in the chart
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Canvas, NonCanvas]
|
||||
[Tooltip("data units per division")]
|
||||
protected float unitsPerDivision;
|
||||
|
||||
/// <summary>
|
||||
/// total division lines
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Canvas, NonCanvas]
|
||||
[Tooltip("total division lines")]
|
||||
private int total = 3;
|
||||
|
||||
/// <summary>
|
||||
/// total division lines
|
||||
/// </summary>
|
||||
public int Total
|
||||
{
|
||||
get { return total; }
|
||||
set
|
||||
{
|
||||
total = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Material for the line of the division
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Canvas, NonCanvas]
|
||||
[Tooltip("Material for the line of the division")]
|
||||
private Material material;
|
||||
|
||||
/// <summary>
|
||||
/// Material for the division lines
|
||||
/// </summary>
|
||||
public Material Material
|
||||
{
|
||||
get { return material; }
|
||||
set
|
||||
{
|
||||
material = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Material tiling for the division lines. Use this to strech or tile the material along the line
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Canvas, NonCanvas]
|
||||
[Tooltip("Material tiling for the division lines. Use this to strech or tile the material along the line")]
|
||||
private MaterialTiling materialTiling = new MaterialTiling(false, 100f);
|
||||
|
||||
/// <summary>
|
||||
/// Material tiling for the division lines. Use this to strech or tile the material along the line
|
||||
/// </summary>
|
||||
public MaterialTiling MaterialTiling
|
||||
{
|
||||
get {return materialTiling;}
|
||||
set
|
||||
{
|
||||
materialTiling = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The length of the far side of the division lines. This is used only by 3d chart when MarkDepth >0
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Simple, NonCanvas]
|
||||
[Tooltip("The length of the far side of the division lines. This is used only by 3d chart when MarkDepth >0")]
|
||||
private AutoFloat markBackLength = new AutoFloat(true, 0.5f);
|
||||
/// <summary>
|
||||
/// The length of the far side of the division lines. This is used only by 3d charts when MarkDepth >0
|
||||
/// </summary>
|
||||
public AutoFloat MarkBackLength
|
||||
{
|
||||
get { return markBackLength; }
|
||||
set
|
||||
{
|
||||
markBackLength = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The length of the the division lines.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Simple, Canvas, NonCanvas]
|
||||
[Tooltip("The length of the the division lines.")]
|
||||
private AutoFloat markLength = new AutoFloat(true,0.5f);
|
||||
/// <summary>
|
||||
/// The length of the the division lines.
|
||||
/// </summary>
|
||||
public AutoFloat MarkLength
|
||||
{
|
||||
get { return markLength; }
|
||||
set
|
||||
{
|
||||
markLength = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the depth of the division line. This is used by 3d charts only
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Simple, NonCanvas]
|
||||
private AutoFloat markDepth = new AutoFloat(true,0.5f);
|
||||
public AutoFloat MarkDepth
|
||||
{
|
||||
get { return markDepth; }
|
||||
set
|
||||
{
|
||||
markDepth = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the thickness of the division lines
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Simple, Canvas, NonCanvas]
|
||||
[Tooltip("the thickness of the division lines")]
|
||||
private float markThickness = 0.1f;
|
||||
|
||||
/// <summary>
|
||||
/// the thickness of the division lines
|
||||
/// </summary>
|
||||
public float MarkThickness
|
||||
{
|
||||
get { return markThickness; }
|
||||
set
|
||||
{
|
||||
markThickness = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A prefab for the division labels
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Simple,Canvas, NonCanvas]
|
||||
[Tooltip("A prefab for the division labels")]
|
||||
private MonoBehaviour textPrefab;
|
||||
/// <summary>
|
||||
/// A prefab for the division labels
|
||||
/// </summary>
|
||||
public MonoBehaviour TextPrefab
|
||||
{
|
||||
get { return textPrefab; }
|
||||
set
|
||||
{
|
||||
textPrefab = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// prefix for the axis labels
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Simple,Canvas,NonCanvas]
|
||||
[Tooltip("prefix for the axis labels")]
|
||||
private string textPrefix;
|
||||
|
||||
/// <summary>
|
||||
/// prefix for the axis labels
|
||||
/// </summary>
|
||||
public string TextPrefix
|
||||
{
|
||||
get { return textPrefix; }
|
||||
set
|
||||
{
|
||||
textPrefix = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// suffix for the axis labels
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Simple, Canvas, NonCanvas]
|
||||
[Tooltip("suffix for the axis labels")]
|
||||
private string textSuffix;
|
||||
/// <summary>
|
||||
/// suffix for the axis labels
|
||||
/// </summary>
|
||||
public string TextSuffix
|
||||
{
|
||||
get { return textSuffix; }
|
||||
set
|
||||
{
|
||||
textSuffix = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the number of fraction digits in the division labels.
|
||||
/// </summary>
|
||||
[Range(0,7)]
|
||||
[Simple, Canvas, NonCanvas]
|
||||
[SerializeField]
|
||||
[Tooltip("the number of fraction digits in text labels")]
|
||||
private int fractionDigits = 2;
|
||||
/// <summary>
|
||||
/// the number of fraction digits in text labels.
|
||||
/// </summary>
|
||||
public int FractionDigits
|
||||
{
|
||||
get { return fractionDigits; }
|
||||
set
|
||||
{
|
||||
fractionDigits = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Label font size
|
||||
/// </summary>
|
||||
[Simple,Canvas, NonCanvas]
|
||||
[SerializeField]
|
||||
[Tooltip("Label font size")]
|
||||
private int fontSize = 12;
|
||||
/// <summary>
|
||||
/// Label font size
|
||||
/// </summary>
|
||||
public int FontSize
|
||||
{
|
||||
get { return fontSize; }
|
||||
set
|
||||
{
|
||||
fontSize = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// makes the labels sharper if they are blurry
|
||||
/// </summary>
|
||||
[Range(1f,3f)]
|
||||
[Simple, Canvas, NonCanvas]
|
||||
[Tooltip("makes the labels sharper if they are blurry")]
|
||||
[SerializeField]
|
||||
private float fontSharpness = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// makes the labels sharper if they are blurry
|
||||
/// </summary>
|
||||
public float FontSharpness
|
||||
{
|
||||
get { return fontSharpness; }
|
||||
set
|
||||
{
|
||||
fontSharpness = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// depth seperation the division lables. used by 3d charts only
|
||||
/// </summary>
|
||||
[Simple, NonCanvas]
|
||||
[SerializeField]
|
||||
[Tooltip("depth seperation the division lables")]
|
||||
private float textDepth;
|
||||
|
||||
/// <summary>
|
||||
/// depth seperation the division lables.used by 3d charts only
|
||||
/// </summary>
|
||||
public float TextDepth
|
||||
{
|
||||
get { return textDepth; }
|
||||
set
|
||||
{
|
||||
textDepth = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// breadth seperation for the division labels
|
||||
/// </summary>
|
||||
[Simple, Canvas,NonCanvas]
|
||||
[SerializeField]
|
||||
[Tooltip("breadth seperation for the division labels")]
|
||||
private float textSeperation;
|
||||
|
||||
/// <summary>
|
||||
/// breadth seperation for the division labels
|
||||
/// </summary>
|
||||
public float TextSeperation
|
||||
{
|
||||
get { return textSeperation; }
|
||||
set
|
||||
{
|
||||
textSeperation = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alignment of the division lables
|
||||
/// </summary>
|
||||
[Simple, Canvas, NonCanvas]
|
||||
[SerializeField]
|
||||
[Tooltip("Alignment of the division lables")]
|
||||
private ChartDivisionAligment alignment = ChartDivisionAligment.Standard;
|
||||
|
||||
/// <summary>
|
||||
/// Alignment of the division lables
|
||||
/// </summary>
|
||||
public ChartDivisionAligment Alignment
|
||||
{
|
||||
get { return alignment; }
|
||||
set
|
||||
{
|
||||
alignment = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable 0067
|
||||
private event EventHandler OnDataUpdate;
|
||||
#pragma warning restore 0067
|
||||
private event EventHandler OnDataChanged;
|
||||
|
||||
protected virtual void RaiseOnChanged()
|
||||
{
|
||||
if (OnDataChanged != null)
|
||||
OnDataChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#region Intenal Use
|
||||
event EventHandler IInternalSettings.InternalOnDataUpdate
|
||||
{
|
||||
add
|
||||
{
|
||||
OnDataUpdate += value;
|
||||
}
|
||||
|
||||
remove
|
||||
{
|
||||
OnDataUpdate -= value;
|
||||
}
|
||||
}
|
||||
|
||||
event EventHandler IInternalSettings.InternalOnDataChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
OnDataChanged += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
OnDataChanged -= value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 359f85bed13b139458429a9181677dc1
|
||||
timeCreated: 1478832101
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using ChartAndGraph;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
[Serializable]
|
||||
public class ChartMainDivisionInfo : ChartDivisionInfo
|
||||
{
|
||||
public DivisionMessure Messure
|
||||
{
|
||||
get { return messure; }
|
||||
set
|
||||
{
|
||||
messure = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public float UnitsPerDivision
|
||||
{
|
||||
get { return unitsPerDivision; }
|
||||
set
|
||||
{
|
||||
unitsPerDivision = value;
|
||||
RaiseOnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9deba227f79698e41bdd30467581bec3
|
||||
timeCreated: 1497092384
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// holds settings for an axis division.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
class ChartSubDivisionInfo : ChartDivisionInfo
|
||||
{
|
||||
protected override float ValidateTotal(float total)
|
||||
{
|
||||
return Mathf.Round(total);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b560179d771be94991a4686a1e7fc94
|
||||
timeCreated: 1496763003
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// defines a horizontal axis for the chart componenet attached to the same object
|
||||
/// </summary>
|
||||
public class HorizontalAxis : AxisBase
|
||||
{
|
||||
protected override Action<IInternalUse, bool> Assign
|
||||
{
|
||||
get
|
||||
{
|
||||
return (x, clear) =>
|
||||
{
|
||||
if (clear)
|
||||
{
|
||||
if (x.HorizontalAxis == this)
|
||||
x.HorizontalAxis = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x.HorizontalAxis != this)
|
||||
x.HorizontalAxis = this;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08395b16192f9114e8ad4953e48f90bd
|
||||
timeCreated: 1479132481
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph.Axis
|
||||
{
|
||||
/// <summary>
|
||||
/// Axis generator functionallity that is not dependant on the diminetion of the chart
|
||||
/// </summary>
|
||||
public interface IAxisGenerator
|
||||
{
|
||||
UnityEngine.Object This();
|
||||
GameObject GetGameObject();
|
||||
void FixLabels(AnyChart parent);
|
||||
void SetAxis(double scrollOffset,AnyChart parent, AxisBase axis, ChartOrientation axisOrientation, bool isSubDivisions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be5483351106eff4e872930ec406b3ea
|
||||
timeCreated: 1478793461
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// defines a vertical axis for the chart componenet attached to the same object
|
||||
/// </summary>
|
||||
public class VerticalAxis : AxisBase
|
||||
{
|
||||
protected override Action<IInternalUse, bool> Assign
|
||||
{
|
||||
get
|
||||
{
|
||||
return (x, clear) =>
|
||||
{
|
||||
if (clear)
|
||||
{
|
||||
if (x.VerticalAxis == this)
|
||||
x.VerticalAxis = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x.VerticalAxis != this)
|
||||
x.VerticalAxis = this;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7598682dc3bb9174d9546fe226cab95a
|
||||
timeCreated: 1479132481
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public abstract class AxisChart : AnyChart
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0d908c90a583d74a8aeb06991f84a58
|
||||
timeCreated: 1480253096
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d75b86172e1e709448c4be48ed625af7
|
||||
folderAsset: yes
|
||||
timeCreated: 1560535493
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public partial class BarChart
|
||||
{
|
||||
partial void StackedStage1(ref float elevation, double prevIntep)
|
||||
{
|
||||
if (Stacked)
|
||||
elevation = (float)prevIntep * HeightRatio;
|
||||
}
|
||||
|
||||
partial void StackedStage2(ref double prevIntep, double interp)
|
||||
{
|
||||
if (Stacked)
|
||||
prevIntep = interp;
|
||||
}
|
||||
partial void StackedStage3(ref double interp, double amount, double min, double total)
|
||||
{
|
||||
if (Stacked)
|
||||
{
|
||||
interp = (amount - min) / total;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95fd0ed42f0ce34459cd9abe796dbbce
|
||||
timeCreated: 1560592679
|
||||
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: 5bcc7a36d1f7adf46a882749324dca81
|
||||
timeCreated: 1472816162
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using ChartAndGraph;
|
||||
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(CanvasBarChart))]
|
||||
public class BarContentFitter : MonoBehaviour
|
||||
{
|
||||
public float RatioAxisMarign = 1f;
|
||||
public float FixedBarSize = 30f;
|
||||
public float RatioGroupSeperation = 5f;
|
||||
public float RatioBarSeperation = 2f;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
}
|
||||
|
||||
void OnValidate()
|
||||
{
|
||||
var bar = GetComponent<BarChart>();
|
||||
bar.Invalidate();
|
||||
}
|
||||
|
||||
public virtual void Match()
|
||||
{
|
||||
var rect = GetComponent<RectTransform>();
|
||||
var totalWidth = rect.rect.width;
|
||||
var bar = GetComponent<CanvasBarChart>();
|
||||
int columnCount = bar.DataSource.TotalCategories;
|
||||
int rowCount = bar.DataSource.TotalGroups;
|
||||
|
||||
int rowLimit = rowCount - 1;
|
||||
double barGroupSeprationSize = RatioBarSeperation * (columnCount - 1);
|
||||
double barGroupSize = barGroupSeprationSize;// + RatioBarSize;
|
||||
double totalSize = RatioGroupSeperation * rowLimit;
|
||||
double baseSize = totalSize + 2* RatioAxisMarign + barGroupSize;
|
||||
|
||||
double factor = totalWidth / baseSize;
|
||||
|
||||
bar.HeightRatio = rect.rect.height;
|
||||
bar.AxisSeperation = (float)(RatioAxisMarign * factor);
|
||||
bar.BarSeperation = (float)(RatioBarSeperation * factor);
|
||||
bar.GroupSeperation = (float)(RatioGroupSeperation * factor);
|
||||
bar.BarSize = FixedBarSize;// (float)(RatioBarSize * factor);
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9cd0887944b07804e8103d5070b1cf3b
|
||||
timeCreated: 1579111521
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,586 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using ChartAndGraph.DataSource;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using ChartAndGraph.Exceptions;
|
||||
using System.Linq;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// data source for bar charts
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class BarData : AbstractChartData,IInternalBarData, IChartData
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
class CategoryData
|
||||
{
|
||||
public string Name;
|
||||
public ChartDynamicMaterial Materials;
|
||||
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class DataEntry
|
||||
{
|
||||
public string GroupName;
|
||||
public string ColumnName;
|
||||
public double Amount;
|
||||
}
|
||||
|
||||
private ChartSparseDataSource mDataSource = new ChartSparseDataSource();
|
||||
ChartSparseDataSource IInternalBarData.InternalDataSource { get { return mDataSource; } }
|
||||
[SerializeField]
|
||||
private CategoryData[] mCategories = new CategoryData[0];
|
||||
[SerializeField]
|
||||
private string[] mGroups = new string[0];
|
||||
[SerializeField]
|
||||
private DataEntry[] mData = new DataEntry[0];
|
||||
|
||||
|
||||
public event Action ProperyUpdated;
|
||||
|
||||
protected void RaisePropertyUpdated()
|
||||
{
|
||||
if (ProperyUpdated != null)
|
||||
ProperyUpdated();
|
||||
}
|
||||
/// <summary>
|
||||
/// the number of categories in the data source
|
||||
/// </summary>
|
||||
public int TotalCategories { get { return mDataSource.Columns.Count; } }
|
||||
/// <summary>
|
||||
/// the number of groups in the data source
|
||||
/// </summary>
|
||||
public int TotalGroups { get { return mDataSource.Rows.Count; } }
|
||||
/// <summary>
|
||||
/// set this to true to automatically detect the highest bar value int the chart. This value will be used to scale all other bars
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private bool automaticMaxValue = true;
|
||||
|
||||
public void Update()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// renames a category. throw an exception on error
|
||||
/// </summary>
|
||||
/// <param name="prevName"></param>
|
||||
/// <param name="newName"></param>
|
||||
public void RenameCategory(string prevName,string newName)
|
||||
{
|
||||
mDataSource.Columns[prevName].Name = newName;
|
||||
RaisePropertyUpdated();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// renames a group. throw an exception on error
|
||||
/// </summary>
|
||||
/// <param name="prevName"></param>
|
||||
/// <param name="newName"></param>
|
||||
public void RenameGroup(string prevName,string newName)
|
||||
{
|
||||
mDataSource.Rows[prevName].Name = newName;
|
||||
RaisePropertyUpdated();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// set this to true to automatically detect the highest bar value int the chart. This value will be used to scale all other bars
|
||||
/// </summary>
|
||||
public bool AutomaticMaxValue
|
||||
{
|
||||
get { return automaticMaxValue; }
|
||||
set
|
||||
{
|
||||
automaticMaxValue = value;
|
||||
RaisePropertyUpdated();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Mannualy set the maximum value , all bars will be scaled based on this value. If a bar value is larger than this value it will be clamped
|
||||
/// Note: set AutomaticMaxValue to false in order to use this field
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private double maxValue = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Mannualy set the maximum value , all bars will be scaled based on this value. If a bar value is larger than this value it will be clamped
|
||||
/// Note: set AutomaticMaxValue to false in order to use this field
|
||||
/// </summary>
|
||||
public double MaxValue
|
||||
{
|
||||
get { return maxValue; }
|
||||
set
|
||||
{
|
||||
maxValue = value;
|
||||
RaisePropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasGroup(string groupName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var row = mDataSource.Rows[groupName];
|
||||
if (row != null)
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool HasCategory(string category)
|
||||
{
|
||||
try
|
||||
{
|
||||
var col = mDataSource.Columns[category];
|
||||
if (col != null)
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// set this to true to automatically detect the lowest bar value int the chart. This value will be used to scale all other bars
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private bool automaticMinValue = false;
|
||||
|
||||
/// <summary>
|
||||
/// set this to true to automatically detect the lowest bar value int the chart. This value will be used to scale all other bars
|
||||
/// </summary>
|
||||
public bool AutomaticMinValue
|
||||
{
|
||||
get { return automaticMinValue; }
|
||||
set
|
||||
{
|
||||
automaticMinValue = value;
|
||||
RaisePropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mannualy set the minimum value , all bars will be scaled based on this value. If a bar value is larger than this value it will be clamped
|
||||
/// Note: set AutomaticMinValue to false in order to use this field
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private double minValue = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Mannualy set the minimum value , all bars will be scaled based on this value. If a bar value is larger than this value it will be clamped
|
||||
/// Note: set AutomaticMinValue to false in order to use this field
|
||||
/// </summary>
|
||||
public double MinValue
|
||||
{
|
||||
get { return minValue; }
|
||||
set
|
||||
{
|
||||
minValue = value;
|
||||
RaisePropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
void IInternalBarData.Update()
|
||||
{
|
||||
UpdateSliders();
|
||||
}
|
||||
/// <summary>
|
||||
/// call this to suspend chart redrawing while updating the data of the chart
|
||||
/// </summary>
|
||||
public void StartBatch()
|
||||
{
|
||||
mDataSource.SuspendEvents = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// call this after StartBatch , this will apply all the changed made between the StartBatch call to this call
|
||||
/// </summary>
|
||||
public void EndBatch()
|
||||
{
|
||||
mDataSource.SuspendEvents = false;
|
||||
}
|
||||
|
||||
public double GetMinValue()
|
||||
{
|
||||
double min = MinValue;
|
||||
double? rawMin = mDataSource.getRawMinValue();
|
||||
|
||||
if (AutomaticMinValue && rawMin.HasValue)
|
||||
min = rawMin.Value;
|
||||
return min;
|
||||
}
|
||||
|
||||
public double GetMaxValue()
|
||||
{
|
||||
double max = MaxValue;
|
||||
double? rawMax = mDataSource.getRawMaxValue();
|
||||
|
||||
if (AutomaticMaxValue && rawMax.HasValue)
|
||||
max = rawMax.Value;
|
||||
return max;
|
||||
|
||||
}
|
||||
|
||||
public string GetCategoryName(int index)
|
||||
{
|
||||
return mDataSource.Columns[index].Name;
|
||||
}
|
||||
|
||||
public string GetGroupName(int index)
|
||||
{
|
||||
return mDataSource.Rows[index].Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// used intenally , do not call
|
||||
/// </summary>
|
||||
/// <param name="cats"></param>
|
||||
public object[] StoreAllCategoriesinOrder()
|
||||
{
|
||||
return mCategories.ToArray();
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
int totalColumns = mDataSource.Columns.Count;
|
||||
mCategories = new CategoryData[totalColumns];
|
||||
for (int i = 0; i < totalColumns; i++)
|
||||
{
|
||||
CategoryData data = new CategoryData();
|
||||
data.Name = mDataSource.Columns[i].Name;
|
||||
data.Materials = mDataSource.Columns[i].Material;
|
||||
mCategories[i] = data;
|
||||
}
|
||||
int totalRows = mDataSource.Rows.Count;
|
||||
mGroups = new string[totalRows];
|
||||
for(int i=0; i< totalRows; i++)
|
||||
mGroups[i] = mDataSource.Rows[i].Name;
|
||||
|
||||
double[,] raw = mDataSource.getRawData();
|
||||
int current = 0;
|
||||
mData = new DataEntry[raw.GetLength(0) * raw.GetLength(1)];
|
||||
for (int i = 0; i < raw.GetLength(0); ++i)
|
||||
{
|
||||
for (int j = 0; j < raw.GetLength(1); ++j)
|
||||
{
|
||||
DataEntry entry = new DataEntry();
|
||||
entry.ColumnName = mDataSource.Columns[j].Name;
|
||||
entry.GroupName = mDataSource.Rows[i].Name;
|
||||
entry.Amount = raw[i, j];
|
||||
mData[current++] = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
mDataSource = new ChartSparseDataSource();
|
||||
mDataSource.SuspendEvents = true;
|
||||
mDataSource.Clear();
|
||||
if (mCategories == null)
|
||||
mCategories = new CategoryData[0];
|
||||
if (mGroups == null)
|
||||
mGroups = new string[0];
|
||||
if (mData == null)
|
||||
mData = new DataEntry[0];
|
||||
for (int i = 0; i < mCategories.Length; i++)
|
||||
{
|
||||
AddCategory(mCategories[i].Name, mCategories[i].Materials);
|
||||
}
|
||||
for (int i = 0; i < mGroups.Length; i++)
|
||||
AddGroup(mGroups[i]);
|
||||
|
||||
for(int i=0; i< mData.Length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
DataEntry entry = mData[i];
|
||||
mDataSource.SetValue(entry.ColumnName, entry.GroupName, entry.Amount);
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
mDataSource.SuspendEvents = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new category to the bar chart. Each category has it's own material and name.
|
||||
/// Note: you must also have at least one group on the bar chart
|
||||
/// Example: you can set the categories to "Player 1","Player 2","Player 3" and the groups to "Gold","Wood","Oil","Total"
|
||||
/// in order to compare the resources the players have gather during a level
|
||||
/// </summary>
|
||||
/// <param name="name">the name of the category</param>
|
||||
/// <param name="material">the material of the category</param>
|
||||
public void AddCategory(string name, Material material)
|
||||
{
|
||||
AddCategory(name, new ChartDynamicMaterial(material));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// clears all groups in the bar chart
|
||||
/// </summary>
|
||||
public void ClearGroups()
|
||||
{
|
||||
string[] groups = mDataSource.Rows.Select(x => x.Name).ToArray();
|
||||
foreach(string s in groups)
|
||||
{
|
||||
RemoveGroup(s);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets all values to the value parameted
|
||||
/// </summary>
|
||||
public void ClearValues(double value = 0.0)
|
||||
{
|
||||
string[] catgories = mDataSource.Columns.Select(x => x.Name).ToArray();
|
||||
string[] groups = mDataSource.Rows.Select(x => x.Name).ToArray();
|
||||
foreach (string g in groups)
|
||||
{
|
||||
foreach (string c in catgories)
|
||||
{
|
||||
SetValue(c, g, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// clears alll categories in the bar chart
|
||||
/// </summary>
|
||||
public void ClearCategories()
|
||||
{
|
||||
string[] catgories = mDataSource.Columns.Select(x => x.Name).ToArray();
|
||||
foreach (string s in catgories)
|
||||
{
|
||||
RemoveCategory(s);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new category to the bar chart. Each category has it's own material and name.
|
||||
/// Note: you must also add groups to the bar data.
|
||||
/// Example: you can set the chart categories to be "Player 1","Player 2","Player 3" in order to compare player achivments
|
||||
/// </summary>
|
||||
/// <param name="name">the name of the category</param>
|
||||
/// <param name="material">the dynamic material of the category. dynamic materials allows setting the material for different events</param>
|
||||
public void AddCategory(string name, ChartDynamicMaterial material,int position)
|
||||
{
|
||||
ChartDataColumn column = new ChartDataColumn(name);
|
||||
column.Material = material;
|
||||
mDataSource.mColumns.Insert(position,column);
|
||||
}
|
||||
/// <summary>
|
||||
/// moves the category to a new position
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="newPosition"></param>
|
||||
public void MoveCategory(string name,int newPosition)
|
||||
{
|
||||
mDataSource.mColumns.Move(name, newPosition);
|
||||
}
|
||||
|
||||
public void SwitchCategoryPositions(string firstCategory,string secondCategory)
|
||||
{
|
||||
mDataSource.mColumns.SwitchPositions(firstCategory, secondCategory);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a new category to the bar chart. Each category has it's own material and name.
|
||||
/// Note: you must also add groups to the bar data.
|
||||
/// Example: you can set the chart categories to be "Player 1","Player 2","Player 3" in order to compare player achivments
|
||||
/// </summary>
|
||||
/// <param name="name">the name of the category</param>
|
||||
/// <param name="material">the dynamic material of the category. dynamic materials allows setting the material for different events</param>
|
||||
public void AddCategory(string name, ChartDynamicMaterial material)
|
||||
{
|
||||
ChartDataColumn column = new ChartDataColumn(name);
|
||||
column.Material = material;
|
||||
mDataSource.mColumns.Add(column);
|
||||
}
|
||||
|
||||
public void SetCategoryIndex(string name,int index)
|
||||
{
|
||||
ChartDataColumn col = mDataSource.mColumns[name];
|
||||
double[] values = new double[TotalGroups];
|
||||
for(int i=0; i<TotalGroups; i++)
|
||||
{
|
||||
string g = GetGroupName(i);
|
||||
values[i] = GetValue(name, g);
|
||||
}
|
||||
|
||||
mDataSource.Columns.Remove(col);
|
||||
mDataSource.Columns.Insert(index, col);
|
||||
for (int i = 0; i < TotalGroups; i++)
|
||||
{
|
||||
string g = GetGroupName(i);
|
||||
SetValue(name, g, values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the material for the specified category
|
||||
/// </summary>
|
||||
/// <param name="category">the name of the category</param>
|
||||
/// <param name="material">the material of the category</param>
|
||||
public void SetMaterial(string category,Material material)
|
||||
{
|
||||
SetMaterial(category, new ChartDynamicMaterial(material));
|
||||
}
|
||||
|
||||
internal ChartDynamicMaterial GetMaterial(string category)
|
||||
{
|
||||
return mDataSource.Columns[category].Material;
|
||||
}
|
||||
/// <summary>
|
||||
/// sets the material for the specified category
|
||||
/// </summary>
|
||||
/// <param name="category">the name of the category</param>
|
||||
/// <param name="material">the dynamic material of the category. dynamic materials allows setting the material for different events</param>
|
||||
public void SetMaterial(string category,ChartDynamicMaterial material)
|
||||
{
|
||||
mDataSource.Columns[category].Material = material;
|
||||
RaisePropertyUpdated();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// removes a category from the bar chart
|
||||
/// </summary>
|
||||
/// <param name="name">the name of the category to remove</param>
|
||||
public void RemoveCategory(string name)
|
||||
{
|
||||
ChartDataColumn column = mDataSource.Columns[name];
|
||||
RemoveSliderForCategory(name);
|
||||
mDataSource.Columns.Remove(column);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// removes a group from the bar chart
|
||||
/// </summary>
|
||||
/// <param name="name">the name of the group to remove</param>
|
||||
public void RemoveGroup(string name)
|
||||
{
|
||||
ChartDataRow row = mDataSource.Rows[name];
|
||||
RemoveSliderForGroup(name);
|
||||
mDataSource.Rows.Remove(row);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a group to the bar chart. Each group holds a double value for each category.
|
||||
/// Note: you must also add at least one category to the bar chart
|
||||
/// Example: you can set the categories to "Player 1","Player 2","Player 3" and the groups to "Gold","Wood","Oil","Total"
|
||||
/// in order to compare the resources the players have gather during a level
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public void AddGroup(string name)
|
||||
{
|
||||
mDataSource.Rows.Add(new ChartDataRow(name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gets the value for the specified group and category
|
||||
/// </summary>
|
||||
/// <param name="category">the category name</param>
|
||||
/// <param name="group">the group name</param>
|
||||
/// <returns></returns>
|
||||
public double GetValue(string category,string group)
|
||||
{
|
||||
return mDataSource.GetValue(category, group);
|
||||
}
|
||||
|
||||
public bool CheckAnimationEnded(float time, AnimationCurve curve)
|
||||
{
|
||||
if (curve.length == 0)
|
||||
return true;
|
||||
return time > curve.keys[curve.length - 1].time;
|
||||
}
|
||||
|
||||
private void FixEaseFunction(AnimationCurve curve)
|
||||
{
|
||||
curve.postWrapMode = WrapMode.Once;
|
||||
curve.preWrapMode = WrapMode.Once;
|
||||
}
|
||||
public void RestoreCategory(string name,object obj)
|
||||
{
|
||||
var cat = (CategoryData)obj;
|
||||
SetMaterial(name, cat.Materials);
|
||||
}
|
||||
public void SlideValue(string category, string group, double slideTo,float totalTime, AnimationCurve curve)
|
||||
{
|
||||
try
|
||||
{
|
||||
RemoveSlider(category, group);
|
||||
curve.postWrapMode = WrapMode.Once;
|
||||
curve.preWrapMode = WrapMode.Once;
|
||||
float time = 0f;
|
||||
if (curve.length > 0)
|
||||
time = curve.keys[curve.length - 1].time;
|
||||
Slider s = new Slider();
|
||||
s.category = category;
|
||||
s.group = group;
|
||||
s.from = GetValue(category, group);
|
||||
s.to = slideTo;
|
||||
s.startTime = Time.time;
|
||||
s.timeScale = time / totalTime;
|
||||
s.totalTime = time;
|
||||
s.curve = curve;
|
||||
mSliders.Add(s);
|
||||
}
|
||||
catch (ChartException e)
|
||||
{
|
||||
Debug.LogWarning(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void SlideValue(string category,string group,double slideTo,float time)
|
||||
{
|
||||
try
|
||||
{
|
||||
RemoveSlider(category, group);
|
||||
Slider s = new Slider();
|
||||
s.category = category;
|
||||
s.group = group;
|
||||
s.from = GetValue(category, group);
|
||||
s.to = slideTo;
|
||||
s.startTime = Time.time;
|
||||
s.totalTime = time;
|
||||
mSliders.Add(s);
|
||||
}
|
||||
catch (ChartException e)
|
||||
{
|
||||
Debug.LogWarning(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the value for the specified group and category
|
||||
/// </summary>
|
||||
/// <param name="category">the category name</param>
|
||||
/// <param name="group">the group name</param>
|
||||
/// <param name="amount">the value fo the bar</param>
|
||||
public void SetValue(string category,string group,double amount)
|
||||
{
|
||||
RemoveSlider(category, group);
|
||||
SetValueInternal(category, group, amount);
|
||||
}
|
||||
protected override void SetValueInternal(string category, string group, double amount)
|
||||
{
|
||||
try
|
||||
{
|
||||
mDataSource.SetValue(category, group, amount);
|
||||
}
|
||||
catch (ChartException e)
|
||||
{
|
||||
Debug.LogWarning(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83cafb2eb9779f3468aad148987eb4bc
|
||||
timeCreated: 1473966108
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public abstract class BarGenerator : MonoBehaviour, IBarGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// generates a bar within the specified rect. The rect is in local coordinates
|
||||
/// </summary>
|
||||
/// <param name="rect">A rect that specifies the bounds of the bar. the rect is in local coordinates</param>
|
||||
/// <param name="normalizedSize">a value between 0 to 1 representing the size of the rect relative to the size of the chart</param>
|
||||
public abstract void Generate(float normalizedSize,float scale);
|
||||
/// <summary>
|
||||
/// clears the bar the was generated be the Generate method.
|
||||
/// </summary>
|
||||
public abstract void Clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe88eea2abcbbb0439344abc5d2f6a1b
|
||||
timeCreated: 1472816163
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
class BarInfo : MonoBehaviour
|
||||
{
|
||||
internal BarChart.BarObject BarObject {get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// gets the item label for this bar, or null if no item label is assigned to it
|
||||
/// </summary>
|
||||
public GameObject ItemLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BarObject == null)
|
||||
return null;
|
||||
if (BarObject.ItemLabel == null)
|
||||
return null;
|
||||
return BarObject.ItemLabel.UIText;
|
||||
}
|
||||
}
|
||||
|
||||
public GameObject CategoryLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BarObject == null)
|
||||
return null;
|
||||
if (BarObject.CategoryLabel == null)
|
||||
return null;
|
||||
return BarObject.CategoryLabel.UIText;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gets the value of the bar
|
||||
/// </summary>
|
||||
public double Value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BarObject == null)
|
||||
return 0.0;
|
||||
return BarObject.Value;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// gets the category of the bar
|
||||
/// </summary>
|
||||
public string Category
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BarObject == null)
|
||||
return "";
|
||||
return BarObject.Category;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gets the group of the bar
|
||||
/// </summary>
|
||||
public string Group
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BarObject == null)
|
||||
return "";
|
||||
return BarObject.Group;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77680f04204076142818a77ae4c9a124
|
||||
timeCreated: 1478381852
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public enum BarMaterialFit
|
||||
{
|
||||
/// <summary>
|
||||
/// Stretch the material along the bar.
|
||||
/// </summary>
|
||||
Stretch,
|
||||
/// <summary>
|
||||
/// If the bar is small , the material will be cut to match it's size. If the bar is at maximum size , all the material will be visible
|
||||
/// </summary>
|
||||
Trim
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3acd3aa78306f2145b6a366a02c3daa6
|
||||
timeCreated: 1472816161
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,232 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains functionallity for generating 3d and 2d bar meshes
|
||||
/// </summary
|
||||
class BarMesh
|
||||
{
|
||||
private static Mesh m2DStrechMesh;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A lazy loaded 2d stretch mesh. This mesh is always the same
|
||||
/// </summary>
|
||||
public static Mesh StrechMesh2D
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m2DStrechMesh == null)
|
||||
m2DStrechMesh = Generate2DMesh(1.0f);
|
||||
return m2DStrechMesh;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// updates the uv of a mesh generated with Generate2DMesh
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
/// <param name="maxV"></param>
|
||||
public static void Update2DMeshUv(Mesh m,float maxV)
|
||||
{
|
||||
Vector2[] uv = m.uv;
|
||||
uv[4] = uv[0] = new Vector2(0f, 0f);
|
||||
uv[5] = uv[1] = new Vector2(1f, 0f);
|
||||
uv[6] = uv[2] = new Vector2(1f, maxV);
|
||||
uv[7] = uv[3] = new Vector2(0f, maxV);
|
||||
m.uv = uv;
|
||||
}
|
||||
/// <summary>
|
||||
/// generates a 2d bar mesh with the specified maximum V coord. (used with trim material fit)
|
||||
/// </summary>
|
||||
/// <param name="maxV"></param>
|
||||
/// <returns></returns>
|
||||
public static Mesh Generate2DMesh(float maxV)
|
||||
{
|
||||
Vector3[] vertices = new Vector3[8];
|
||||
Vector2[] uv = new Vector2[8];
|
||||
int[] tringles = new int[12];
|
||||
|
||||
vertices[4] = vertices[0] = new Vector3(-0.5f, 0f, 0f);
|
||||
vertices[5] = vertices[1] = new Vector3(0.5f, 0f, 0f);
|
||||
vertices[6] = vertices[2] = new Vector3(0.5f, 1f, 0f);
|
||||
vertices[7] = vertices[3] = new Vector3(-0.5f, 1f, 0f);
|
||||
|
||||
uv[4] = uv[0] = new Vector2(0f, 0f);
|
||||
uv[5] = uv[1] = new Vector2(1f, 0f);
|
||||
uv[6] = uv[2] = new Vector2(1f, maxV);
|
||||
uv[7] = uv[3] = new Vector2(0f, maxV);
|
||||
|
||||
WriteRect(tringles, 0, 1, 2, 0, 3, false);
|
||||
WriteRect(tringles, 2, 5, 6, 4, 7, true);
|
||||
|
||||
Mesh mesh = new Mesh();
|
||||
mesh.hideFlags = HideFlags.DontSave;
|
||||
mesh.vertices = vertices;
|
||||
mesh.uv = uv;
|
||||
mesh.triangles = tringles;
|
||||
mesh.RecalculateNormals();
|
||||
return mesh;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a single rectangle to the tringles array
|
||||
/// </summary>
|
||||
/// <param name="tringles"></param>
|
||||
/// <param name="tringleIndex">this value is multiplied by 3 in order to find the real array index</param>
|
||||
/// <param name="a"> index of the first vertex</param>
|
||||
/// <param name="b"> index of the second vertex</param>
|
||||
/// <param name="c"> index of the third vertex</param>
|
||||
/// <param name="d"> index of the forth vertex</param>
|
||||
static void WriteRect(int[] tringles,int tringleIndex,int a,int b,int c,int d,bool flip)
|
||||
{
|
||||
if (flip)
|
||||
{
|
||||
WriteTringle(tringles, tringleIndex++, a, b, c);
|
||||
WriteTringle(tringles, tringleIndex, d, c, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteTringle(tringles, tringleIndex++, c, b, a);
|
||||
WriteTringle(tringles, tringleIndex, b, c, d);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a single tringle to the tringle array
|
||||
/// </summary>
|
||||
/// <param name="tringles"></param>
|
||||
/// <param name="tringleIndex">this value is multiplied by 3 in order to find the real array index</param>
|
||||
/// <param name="a">index of the first vertex</param>
|
||||
/// <param name="b">index of the second vertex</param>
|
||||
/// <param name="c">index of the third vertex</param>
|
||||
static void WriteTringle(int[] tringles,int tringleIndex,int a,int b,int c)
|
||||
{
|
||||
int index = tringleIndex*3;
|
||||
tringles[index++] = a;
|
||||
tringles[index++] = b;
|
||||
tringles[index++] = c;
|
||||
}
|
||||
private static Mesh m3DStretchMesh;
|
||||
|
||||
/// <summary>
|
||||
/// A lazy loaded 3d stretch mesh. This mesh is always the same
|
||||
/// </summary>
|
||||
public static Mesh StrechMesh3D
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m3DStretchMesh == null)
|
||||
m3DStretchMesh = Generate3DMesh(1.0f);
|
||||
return m3DStretchMesh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// updates the uv of a mesh created with Generate3DMesh
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
/// <param name="maxV"></param>
|
||||
public static void Update3DMeshUv(Mesh m, float maxV)
|
||||
{
|
||||
Vector2[] uv = m.uv;
|
||||
uv[0] = new Vector2(0f, 0f);
|
||||
uv[1] = new Vector2(1f, 0f);
|
||||
uv[2] = new Vector2(1f, maxV);
|
||||
uv[3] = new Vector2(0f, maxV);
|
||||
|
||||
uv[4] = new Vector2(1f, 0f);
|
||||
uv[5] = new Vector2(0f, 0f);
|
||||
uv[6] = new Vector2(0f, maxV);
|
||||
uv[7] = new Vector2(1f, maxV);
|
||||
|
||||
uv[8] = new Vector2(0f, 0f);
|
||||
uv[9] = new Vector2(1f, 0f);
|
||||
uv[10] = new Vector2(1f, 1f);
|
||||
uv[11] = new Vector2(0f, 1f);
|
||||
|
||||
uv[12] = new Vector2(1f, 0f);
|
||||
uv[13] = new Vector2(0f, 0f);
|
||||
uv[14] = new Vector2(0f, 1f);
|
||||
uv[15] = new Vector2(1f, 1f); m.uv = uv;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// generates a 3d bar mesh with the specified maximum V coord. (used with trim material fit)
|
||||
/// </summary>
|
||||
/// <param name="maxV"></param>
|
||||
/// <returns></returns>
|
||||
public static Mesh Generate3DMesh(float maxV)
|
||||
{
|
||||
Vector3[] vertices = new Vector3[16];
|
||||
Vector2[] uv = new Vector2[16];
|
||||
int[] tringles = new int[36];
|
||||
|
||||
vertices[0] = new Vector3(-0.5f, 0f, -0.5f);
|
||||
vertices[1] = new Vector3(0.5f, 0f, -0.5f);
|
||||
vertices[2] = new Vector3(0.5f, 1f, -0.5f);
|
||||
vertices[3] = new Vector3(-0.5f, 1f, -0.5f);
|
||||
|
||||
vertices[4] = new Vector3(-0.5f, 0f, 0.5f);
|
||||
vertices[5] = new Vector3(0.5f, 0f, 0.5f);
|
||||
vertices[6] = new Vector3(0.5f, 1f, 0.5f);
|
||||
vertices[7] = new Vector3(-0.5f, 1f, 0.5f);
|
||||
|
||||
vertices[8] = new Vector3(-0.5f, 0f, -0.5f);
|
||||
vertices[9] = new Vector3(0.5f, 0f, -0.5f);
|
||||
vertices[10] = new Vector3(0.5f, 1f, -0.5f);
|
||||
vertices[11] = new Vector3(-0.5f, 1f, -0.5f);
|
||||
|
||||
vertices[12] = new Vector3(-0.5f, 0f, 0.5f);
|
||||
vertices[13] = new Vector3(0.5f, 0f, 0.5f);
|
||||
vertices[14] = new Vector3(0.5f, 1f, 0.5f);
|
||||
vertices[15] = new Vector3(-0.5f, 1f, 0.5f);
|
||||
|
||||
uv[0] = new Vector2(0f, 0f);
|
||||
uv[1] = new Vector2(1f, 0f);
|
||||
uv[2] = new Vector2(1f, maxV);
|
||||
uv[3] = new Vector2(0f, maxV);
|
||||
|
||||
uv[4] = new Vector2(1f, 0f);
|
||||
uv[5] = new Vector2(0f, 0f);
|
||||
uv[6] = new Vector2(0f, maxV);
|
||||
uv[7] = new Vector2(1f, maxV);
|
||||
|
||||
uv[8] = new Vector2(0f, 0f);
|
||||
uv[9] = new Vector2(1f, 0f);
|
||||
uv[10] = new Vector2(1f, 1f);
|
||||
uv[11] = new Vector2(0f, 1f);
|
||||
|
||||
uv[12] = new Vector2(1f, 0f);
|
||||
uv[13] = new Vector2(0f, 0f);
|
||||
uv[14] = new Vector2(0f, 1f);
|
||||
uv[15] = new Vector2(1f, 1f);
|
||||
|
||||
WriteRect(tringles, 0, 1, 2, 0, 3, false);
|
||||
WriteRect(tringles, 2, 5, 6, 4, 7, true);
|
||||
|
||||
WriteRect(tringles, 4, 8, 9, 12, 13, true);
|
||||
WriteRect(tringles, 6, 10, 11, 14, 15, true);
|
||||
|
||||
WriteRect(tringles, 8, 6, 5, 2, 1, true);
|
||||
WriteRect(tringles, 10, 7, 4, 3, 0, false);
|
||||
|
||||
Mesh mesh = new Mesh();
|
||||
mesh.hideFlags = HideFlags.DontSave;
|
||||
mesh.vertices = vertices;
|
||||
mesh.uv = uv;
|
||||
mesh.triangles = tringles;
|
||||
mesh.RecalculateNormals();
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78e63bbfee62a1f4db007c2147bd8177
|
||||
timeCreated: 1472893291
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using UnityEngine;
|
||||
|
||||
//namespace ChartAndGraph
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// This class contains functionallity for generating 3d and 2d bar meshes
|
||||
// /// </summary
|
||||
// partial class BarMesh
|
||||
// {
|
||||
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2901fb0eecf53045ae83755f482ad62
|
||||
timeCreated: 1560535998
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,106 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
[RequireComponent(typeof(MeshRenderer))]
|
||||
[RequireComponent(typeof(MeshFilter))]
|
||||
class BarMeshGenerator : BarGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the dimention of the generated mesh. can be either 2d or 3d
|
||||
/// </summary>
|
||||
public MeshDimention MeshDimention = MeshDimention._2D;
|
||||
/// <summary>
|
||||
/// Sets the way materials are fit to the bar mesh
|
||||
/// </summary>
|
||||
public BarMaterialFit MaterialFit = BarMaterialFit.Stretch;
|
||||
/// <summary>
|
||||
/// Contains a mesh that was generate for this object only and should be destoryed once the object is cleaned
|
||||
/// </summary>
|
||||
Mesh mCleanMesh = null;
|
||||
/// <summary>
|
||||
/// the mesh filter for this object
|
||||
/// </summary>
|
||||
MeshFilter mFilter;
|
||||
|
||||
MeshDimention mCurrentDimention;
|
||||
BarMaterialFit mCurrentMaterialFit;
|
||||
|
||||
private bool EnsureMeshFilter()
|
||||
{
|
||||
if (mFilter == null)
|
||||
mFilter = GetComponent<MeshFilter>();
|
||||
if (mFilter == null)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="rect"></param>
|
||||
/// <param name="normalizedSize"></param>
|
||||
public override void Generate(float normalizedSize,float scale)
|
||||
{
|
||||
if (EnsureMeshFilter() == false) // No mesh filter attached
|
||||
return;
|
||||
|
||||
if(mFilter.sharedMesh != null)
|
||||
{
|
||||
if(MaterialFit == BarMaterialFit.Trim && mCurrentMaterialFit == BarMaterialFit.Trim)
|
||||
{
|
||||
if(MeshDimention == mCurrentDimention)
|
||||
{
|
||||
if (MeshDimention == ChartAndGraph.MeshDimention._2D)
|
||||
BarMesh.Update2DMeshUv(mFilter.sharedMesh, normalizedSize);
|
||||
else
|
||||
BarMesh.Update3DMeshUv(mFilter.sharedMesh, normalizedSize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
mCurrentDimention = MeshDimention;
|
||||
mCurrentMaterialFit = MaterialFit;
|
||||
if(MaterialFit == BarMaterialFit.Stretch)
|
||||
{
|
||||
if (MeshDimention == ChartAndGraph.MeshDimention._2D)
|
||||
mFilter.sharedMesh = BarMesh.StrechMesh2D;
|
||||
else
|
||||
mFilter.sharedMesh = BarMesh.StrechMesh3D;
|
||||
ChartCommon.CleanMesh(null, ref mCleanMesh);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MaterialFit == BarMaterialFit.Trim)
|
||||
{
|
||||
Mesh newMesh = null;
|
||||
if (MeshDimention == ChartAndGraph.MeshDimention._2D)
|
||||
newMesh = BarMesh.Generate2DMesh(normalizedSize);
|
||||
else
|
||||
newMesh = BarMesh.Generate3DMesh(normalizedSize);
|
||||
mFilter.sharedMesh = newMesh;
|
||||
ChartCommon.CleanMesh(newMesh, ref mCleanMesh);
|
||||
}
|
||||
else
|
||||
return; // should not happen ever
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
ChartCommon.CleanMesh(null, ref mCleanMesh);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bff5a247b0442474daa4fc07d33bdeab
|
||||
timeCreated: 1472816163
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,317 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public class CanvasBarChart : BarChart, ICanvas
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The seperation between the axis and the chart bars.
|
||||
/// </summary>
|
||||
[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();
|
||||
}
|
||||
}
|
||||
protected override ChartMagin MarginLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return fitMargin;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
/// <summary>
|
||||
/// prefab for the bar elements of the chart. must be the size of one unit with a pivot at the middle bottom
|
||||
/// </summary>
|
||||
[Tooltip("Prefab for the bar elements of the chart. must be the size of one unit with a pivot at the middle bottom")]
|
||||
private CanvasRenderer barPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// prefab for the bar elements of the chart. must be the size of one unit with a pivot at the middle bottom
|
||||
/// </summary>
|
||||
public CanvasRenderer BarPrefab
|
||||
{
|
||||
get { return barPrefab; }
|
||||
set
|
||||
{
|
||||
barPrefab = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsCanvas
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The seperation between the axis and the chart bars.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("The seperation between the axis and the chart bars")]
|
||||
private float axisSeperation = 20f;
|
||||
protected override float TotalDepthLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The seperation between the axis and the chart bars.
|
||||
/// </summary>
|
||||
public float AxisSeperation
|
||||
{
|
||||
get { return axisSeperation; }
|
||||
set
|
||||
{
|
||||
axisSeperation = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// seperation between bar of the same group
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("seperation between bar of the same group")]
|
||||
private float barSeperation = 45f;
|
||||
|
||||
/// <summary>
|
||||
/// seperation between bars of the same group.
|
||||
/// </summary>
|
||||
public float BarSeperation
|
||||
{
|
||||
get { return barSeperation; }
|
||||
set
|
||||
{
|
||||
barSeperation = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// seperation between bar groups
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("seperation between bar groups")]
|
||||
private float groupSeperation = 220f;
|
||||
|
||||
/// <summary>
|
||||
/// The seperation between bar groups.
|
||||
/// <summary>
|
||||
public float GroupSeperation
|
||||
{
|
||||
get { return groupSeperation; }
|
||||
set
|
||||
{
|
||||
groupSeperation = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
public override bool SupportRealtimeGeneration
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// the width of each bar in the chart
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("the width of each bar in the chart")]
|
||||
private float barSize = 20f;
|
||||
|
||||
/// <summary>
|
||||
/// the width of each bar in the chart
|
||||
/// </summary>
|
||||
public float BarSize
|
||||
{
|
||||
get { return barSize; }
|
||||
set
|
||||
{
|
||||
barSize = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
protected override ChartOrientedSize AxisSeperationLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ChartOrientedSize(AxisSeperation);
|
||||
}
|
||||
}
|
||||
|
||||
protected override ChartOrientedSize BarSeperationLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ChartOrientedSize(BarSeperation);
|
||||
}
|
||||
}
|
||||
|
||||
protected override ChartOrientedSize GroupSeperationLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ChartOrientedSize(GroupSeperation);
|
||||
}
|
||||
}
|
||||
|
||||
protected override ChartOrientedSize BarSizeLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ChartOrientedSize(BarSize);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetBarSize(GameObject bar, Vector3 size,float elevation)
|
||||
{
|
||||
RectTransform rect = bar.GetComponent<RectTransform>();
|
||||
|
||||
if (rect != null)
|
||||
{
|
||||
float ySize = size.y;
|
||||
float yAnchor = 0f;
|
||||
if (ySize < 0)
|
||||
{
|
||||
ySize = -ySize;
|
||||
yAnchor = 1;
|
||||
}
|
||||
rect.pivot = new Vector2(0.5f, yAnchor);
|
||||
rect.sizeDelta = new Vector2(size.x, ySize);
|
||||
Vector2 v = rect.localPosition;
|
||||
v.y = elevation;
|
||||
rect.localPosition = v;
|
||||
}
|
||||
else
|
||||
base.SetBarSize(bar, size,elevation);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
}
|
||||
//protected override Vector3 CanvasFitOffset
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return new Vector3();
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("")]
|
||||
private FitType barFitType = FitType.Aspect;
|
||||
|
||||
/// <summary>
|
||||
/// the width of each bar in the chart
|
||||
/// </summary
|
||||
public FitType BarFitType
|
||||
{
|
||||
get { return barFitType; }
|
||||
set
|
||||
{
|
||||
barFitType = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("")]
|
||||
private FitAlign barFitAlign = FitAlign.CenterXCenterY;
|
||||
|
||||
/// <summary>
|
||||
/// the width of each bar in the chart
|
||||
/// </summary
|
||||
public FitAlign BarFitAlign
|
||||
{
|
||||
get { return barFitAlign; }
|
||||
set
|
||||
{
|
||||
barFitAlign = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override FitType FitAspectCanvas { get { return BarFitType; } }
|
||||
protected override FitAlign FitAlignCanvas { get { return BarFitAlign; } }
|
||||
[ContextMenu("Refresh chart")]
|
||||
public override void InternalGenerateChart()
|
||||
{
|
||||
RectTransform trans = GetComponent<RectTransform>();
|
||||
|
||||
if (FitToContainer)
|
||||
{
|
||||
float width = MessureWidth();
|
||||
heightRatio = width * (trans.rect.size.y / trans.rect.size.x);
|
||||
}
|
||||
|
||||
base.InternalGenerateChart();
|
||||
//if (TextController != null && TextController.gameObject)
|
||||
// TextController.gameObject.transform.SetAsLastSibling();
|
||||
//float widthScale = trans.rect.size.x / TotalWidth;
|
||||
//float heightScale = trans.rect.size.y / HeightRatio;
|
||||
//GameObject fixPosition = new GameObject();
|
||||
//ChartCommon.HideObject(fixPosition, hideHierarchy);
|
||||
//fixPosition.AddComponent<ChartItem>();
|
||||
//fixPosition.transform.position = transform.position;
|
||||
//while (gameObject.transform.childCount > 0)
|
||||
// transform.GetChild(0).SetParent(fixPosition.transform, false);
|
||||
//fixPosition.transform.SetParent(transform, false);
|
||||
//fixPosition.transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
//float uniformScale = Math.Min(widthScale, heightScale);
|
||||
//fixPosition.transform.localScale = new Vector3(uniformScale, uniformScale, uniformScale);
|
||||
//fixPosition.transform.localPosition = new Vector3(-TotalWidth * uniformScale * 0.5f, -HeightRatio * uniformScale * 0.5f, 0f);
|
||||
}
|
||||
|
||||
protected override GameObject BarPrefabLink
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BarPrefab == null)
|
||||
return null;
|
||||
return BarPrefab.gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: acb1d1c592b0c794d8bff6d0a590986e
|
||||
timeCreated: 1478565292
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
interface IBarGenerator
|
||||
{
|
||||
void Generate(float normalizedSize,float scale);
|
||||
void Clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 890470d3be0138e408ab56d25c63b82f
|
||||
timeCreated: 1499880160
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,234 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChartAndGraph.Axis;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public class WorldSpaceBarChart : BarChart
|
||||
{
|
||||
/// <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();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsCanvas
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/// <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();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// prefab for all the bar elements of the chart. must be one unit size and with a bottom middle pivot
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("prefab for all the bar elements of the chart. must be one unit size and with a bottom middle pivot")]
|
||||
private GameObject barPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// prefab for all the bar elements of the chart. must be one unit size and with a bottom middle pivot
|
||||
/// </summary>
|
||||
public GameObject BarPrefab
|
||||
{
|
||||
get
|
||||
{
|
||||
return barPrefab;
|
||||
}
|
||||
set
|
||||
{
|
||||
barPrefab = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The seperation between the axis and the chart bars.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("The seperation between the axis and the chart bars")]
|
||||
private ChartOrientedSize AxisSeperation = new ChartOrientedSize();
|
||||
|
||||
/// <summary>
|
||||
/// The seperation between the axis and the chart bars
|
||||
/// </summary>
|
||||
public ChartOrientedSize axisSeperation
|
||||
{
|
||||
get { return AxisSeperation; }
|
||||
set
|
||||
{
|
||||
AxisSeperation = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The seperation between bars of the same group.
|
||||
/// Use cases:
|
||||
/// 1. set the depth to 0 to make each group look more 2d.
|
||||
/// 2. set the breadth to 0 to make align the bars of each group along the z axis
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("The seperation between bars of the same group")]
|
||||
private ChartOrientedSize barSeperation = new ChartOrientedSize();
|
||||
|
||||
/// <summary>
|
||||
/// The seperation between bars of the same group.
|
||||
/// Use cases:
|
||||
/// 1. set the depth to 0 to make each group look more 2d.
|
||||
/// 2. set the breadth to 0 to make align the bars of each group along the z axis
|
||||
/// </summary>
|
||||
public ChartOrientedSize BarSeperation
|
||||
{
|
||||
get { return barSeperation; }
|
||||
set
|
||||
{
|
||||
barSeperation = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The seperation between bar groups.
|
||||
/// Use cases:
|
||||
/// 1.set the depth to 0 for a more 2d look.
|
||||
/// 2.set the breadth to 0 to align the groups on the z axis
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("seperation between bar groups")]
|
||||
private ChartOrientedSize groupSeperation = new ChartOrientedSize();
|
||||
|
||||
/// <summary>
|
||||
/// The seperation between bar groups.
|
||||
/// Use cases:
|
||||
/// 1.set the depth to 0 for a more 2d look.
|
||||
/// 2.set the breadth to 0 to align the groups on the z axis
|
||||
/// <summary>
|
||||
public ChartOrientedSize GroupSeperation
|
||||
{
|
||||
get { return groupSeperation; }
|
||||
set
|
||||
{
|
||||
groupSeperation = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// the size of each bar in the chart
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
[Tooltip("the size of each bar in the chart")]
|
||||
private ChartOrientedSize barSize = new ChartOrientedSize(1f, 1f);
|
||||
/// <summary>
|
||||
/// the size of each bar in the chart
|
||||
/// </summary>
|
||||
public ChartOrientedSize BarSize
|
||||
{
|
||||
get { return barSize; }
|
||||
set
|
||||
{
|
||||
barSize = value;
|
||||
OnPropertyUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
protected override ChartOrientedSize AxisSeperationLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return AxisSeperation;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ChartOrientedSize BarSeperationLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return BarSeperation;
|
||||
}
|
||||
}
|
||||
protected override ChartOrientedSize GroupSeperationLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return GroupSeperation;
|
||||
}
|
||||
}
|
||||
protected override ChartOrientedSize BarSizeLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return BarSize;
|
||||
}
|
||||
}
|
||||
protected override Camera TextCameraLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return TextCamera;
|
||||
}
|
||||
}
|
||||
|
||||
protected override float TextIdleDistanceLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return TextIdleDistance;
|
||||
}
|
||||
}
|
||||
|
||||
protected override GameObject BarPrefabLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return BarPrefab;
|
||||
}
|
||||
}
|
||||
protected override void ValidateProperties()
|
||||
{
|
||||
base.ValidateProperties();
|
||||
if (barSize.Breadth < 0f)
|
||||
barSize.Breadth = 0f;
|
||||
if (barSize.Depth < 0f)
|
||||
barSize.Depth = 0f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82d167234d2aa7746a9618de50700879
|
||||
timeCreated: 1478712963
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6d8003a874f2984da46256c53994d40
|
||||
folderAsset: yes
|
||||
timeCreated: 1560587177
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public partial class CanvasLines
|
||||
{
|
||||
|
||||
partial void ProcesssPoint(ref Vector4 point, ref float halfSize)
|
||||
{
|
||||
if (point.w >= 0f)
|
||||
halfSize = point.w * 0.5f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7d6641167b28744f8a0bacf68f32e4b
|
||||
timeCreated: 1560587181
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,911 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// this class is used internally in order to draw lines, line fill and line points into a mesh
|
||||
/// </summary>
|
||||
public partial class CanvasLines : EventHandlingGraphic
|
||||
{
|
||||
/// <summary>
|
||||
/// thickness of the lines being drawn
|
||||
/// </summary>
|
||||
public float Thickness = 2f;
|
||||
|
||||
float innerTile = 1f;
|
||||
int mMinModifyIndex = 0;
|
||||
/// <summary>
|
||||
/// Tiling value for the graphic. The tiliing is the total length of the lines being drawn. It is set by the parent graph
|
||||
/// </summary>
|
||||
public float Tiling
|
||||
{
|
||||
get { return innerTile; }
|
||||
set
|
||||
{
|
||||
innerTile = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// true if this graphic is in fill render mode (drawing the inner fill of a line graph)
|
||||
/// </summary>
|
||||
bool mFillRender = false;
|
||||
/// <summary>
|
||||
/// true if this graph is in point drawing render mode
|
||||
/// </summary>
|
||||
bool mPointRender = false;
|
||||
/// <summary>
|
||||
/// for point render mode , sets the point size
|
||||
/// </summary>
|
||||
float mPointSize = 5f;
|
||||
/// <summary>
|
||||
/// for fill render mode , this sets the boundries of the fill. (so the bottom of the fill matches the bottom of the graph)
|
||||
/// </summary>
|
||||
Rect mFillRect;
|
||||
/// <summary>
|
||||
/// if true , the Y of the fill is stretched
|
||||
/// </summary>
|
||||
bool mStretchY;
|
||||
/// <summary>
|
||||
/// The material for the graphic object
|
||||
/// </summary>
|
||||
Material mCachedMaterial;
|
||||
/// <summary>
|
||||
/// list of lines for the line object , this will be used to render either dots , fill or lines depending on the render mode
|
||||
/// </summary>
|
||||
List<LineSegement> mLines;
|
||||
/// <summary>
|
||||
/// bounding box for the value of mLines, used for event handling
|
||||
/// </summary>
|
||||
float mMinX, mMinY, mMaxX, mMaxY;
|
||||
|
||||
/// <summary>
|
||||
/// Sets point render mode
|
||||
/// </summary>
|
||||
/// <param name="pointSize"></param>
|
||||
public void MakePointRender(float pointSize)
|
||||
{
|
||||
mPointSize = pointSize;
|
||||
mPointRender = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets inner fill render mode
|
||||
/// </summary>
|
||||
/// <param name="fillRect"></param>
|
||||
/// <param name="stretchY"></param>
|
||||
public void MakeFillRender(Rect fillRect, bool stretchY)
|
||||
{
|
||||
mFillRect = fillRect;
|
||||
mFillRender = true;
|
||||
mStretchY = stretchY;
|
||||
}
|
||||
|
||||
UIVertex[] mTmpVerts = new UIVertex[4];
|
||||
/// <summary>
|
||||
/// holds line data and pre cacultates normal and speration
|
||||
/// </summary>
|
||||
internal struct Line
|
||||
{
|
||||
public Line(Vector3 from, Vector3 to, float halfThickness, bool hasNext, bool hasPrev) : this()
|
||||
{
|
||||
|
||||
Vector3 diff = (to - from);
|
||||
float magDec = 0;
|
||||
if (hasNext)
|
||||
magDec += halfThickness;
|
||||
if (hasPrev)
|
||||
magDec += halfThickness;
|
||||
Mag = diff.magnitude - magDec * 2;
|
||||
Degenerated = false;
|
||||
if (Mag <= 0)
|
||||
Degenerated = true;
|
||||
Dir = diff.normalized;
|
||||
Vector3 add = halfThickness * 2 * Dir;
|
||||
if (hasPrev)
|
||||
from += add;
|
||||
if (hasNext)
|
||||
to -= add;
|
||||
From = from;
|
||||
To = to;
|
||||
Normal = new Vector3(Dir.y, -Dir.x, Dir.z); // this part calculates the line inset and points based on thichkness
|
||||
P1 = From + Normal * halfThickness;
|
||||
P2 = from - Normal * halfThickness;
|
||||
P3 = to + Normal * halfThickness;
|
||||
P4 = to - Normal * halfThickness;
|
||||
}
|
||||
|
||||
public bool Degenerated { get; private set; }
|
||||
public Vector3 P1 { get; private set; }
|
||||
public Vector3 P2 { get; private set; }
|
||||
public Vector3 P3 { get; private set; }
|
||||
public Vector3 P4 { get; private set; }
|
||||
|
||||
public Vector3 From { get; private set; }
|
||||
public Vector3 To { get; private set; }
|
||||
public Vector3 Dir { get; private set; }
|
||||
public float Mag { get; private set; }
|
||||
public Vector3 Normal { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// represents one line segemenet.
|
||||
/// </summary>
|
||||
internal class LineSegement
|
||||
{
|
||||
List<Vector4> mLines = new List<Vector4>();
|
||||
|
||||
public LineSegement(IList<Vector3> lines)
|
||||
{
|
||||
mLines.AddRange(lines.Select(x=>new Vector4(x.x,x.y,x.z,-1f)));
|
||||
}
|
||||
|
||||
public LineSegement(IList<Vector4> lines)
|
||||
{
|
||||
mLines.AddRange(lines);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reset the value of the linesSegment to the specified list
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
public void ModifiyLines(List<Vector4> v)
|
||||
{
|
||||
mLines.Clear();
|
||||
mLines.AddRange(v);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The total amount of points in this line segmenet
|
||||
/// </summary>
|
||||
public int PointCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mLines == null)
|
||||
return 0;
|
||||
return mLines.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Line count is point count minus one. Since all dots have to be connected
|
||||
/// </summary>
|
||||
public int LineCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mLines == null)
|
||||
return 0;
|
||||
if (mLines.Count < 2)
|
||||
return 0;
|
||||
return mLines.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a point
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public Vector4 getPoint(int index)
|
||||
{
|
||||
Vector4 p = mLines[index];
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gets the line at the specified index.index Must be below LineCount
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="from"></param>
|
||||
/// <param name="to"></param>
|
||||
public void GetLine(int index, out Vector3 from, out Vector3 to)
|
||||
{
|
||||
from = mLines[index];
|
||||
to = mLines[index + 1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gets the line at the specified index.index Must be below LineCount. if the line has a previous or a next line an inset is calculated for better visual aperance
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="from"></param>
|
||||
/// <param name="to"></param>
|
||||
public Line GetLine(int index, float halfThickness, bool hasPrev, bool hasNext)
|
||||
{
|
||||
Vector3 from = mLines[index];
|
||||
Vector3 to = mLines[index + 1];
|
||||
return new Line(from, to, halfThickness, false, false);
|
||||
}
|
||||
public double GetLineMag(int index)
|
||||
{
|
||||
return (mLines[index] - mLines[index + 1]).magnitude;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CanvasLines()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// finds the minimum and maximum values of the currently set data
|
||||
/// </summary>
|
||||
void FindBoundingValues()
|
||||
{
|
||||
mMinX = float.PositiveInfinity;
|
||||
mMinY = float.PositiveInfinity;
|
||||
mMaxX = float.NegativeInfinity;
|
||||
mMaxY = float.NegativeInfinity;
|
||||
// this part finds the bounding box of the lines
|
||||
if (mLines != null)
|
||||
{
|
||||
for (int i = 0; i < mLines.Count; i++)
|
||||
{
|
||||
LineSegement seg = mLines[i];
|
||||
int totalPoints = seg.PointCount;
|
||||
for (int j = 0; j < totalPoints; j++)
|
||||
{
|
||||
Vector3 point = seg.getPoint(j);
|
||||
mMinX = Mathf.Min(mMinX, point.x);
|
||||
mMinY = Mathf.Min(mMinY, point.y);
|
||||
mMaxX = Mathf.Max(mMaxX, point.x);
|
||||
mMaxY = Mathf.Max(mMaxY, point.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void ModifyLines(int minModifyIndex,List<Vector4> lines)
|
||||
{
|
||||
if (mLines.Count == 0)
|
||||
{
|
||||
mLines.Add(new LineSegement(lines.ToArray()));
|
||||
return;
|
||||
}
|
||||
|
||||
mMinModifyIndex = minModifyIndex;
|
||||
FindBoundingValues();
|
||||
mLines[0].ModifiyLines(lines);
|
||||
SetVerticesDirty(); // clear previous animations
|
||||
Rebuild(CanvasUpdate.PostLayout);
|
||||
RefreshInputs();
|
||||
}
|
||||
public bool EnableOptimization { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// sets the lines for this renderer
|
||||
/// </summary>
|
||||
/// <param name="lines"></param>
|
||||
internal void SetLines(List<LineSegement> lines)
|
||||
{
|
||||
mLines = lines;
|
||||
FindBoundingValues();
|
||||
mMinModifyIndex = 0;
|
||||
SetAllDirty();
|
||||
ClearEvents(); // clear previous animations
|
||||
if(EnableOptimization)
|
||||
Rebuild(CanvasUpdate.PostLayout);
|
||||
else
|
||||
Rebuild(CanvasUpdate.PreRender);
|
||||
}
|
||||
|
||||
protected override void UpdateMaterial()
|
||||
{
|
||||
base.UpdateMaterial();
|
||||
canvasRenderer.SetTexture(material.mainTexture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// this method inflate one point in a line with the specified distantce. This enable the graphic to control the thickness of lines
|
||||
/// </summary>
|
||||
/// <param name="point"></param>
|
||||
/// <param name="dir"></param>
|
||||
/// <param name="normal"></param>
|
||||
/// <param name="dist"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="z"></param>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="p2"></param>
|
||||
void GetSide(Vector3 point, Vector3 dir,Vector3 normal,float dist,float size,float z,out Vector3 p1,out Vector3 p2)
|
||||
{
|
||||
point.z = z;
|
||||
point += dir * dist;
|
||||
normal *= size;
|
||||
p1 = point + normal;
|
||||
p2 = point - normal;
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
ChartCommon.SafeDestroy(mCachedMaterial);
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overriding the default implementation to support materials with _ChartTiling property. This is used to tile texture along the graphic lines
|
||||
/// </summary>
|
||||
public override Material material
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.material;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
ChartCommon.SafeDestroy(mCachedMaterial);
|
||||
if (value == null)
|
||||
{
|
||||
mCachedMaterial = null;
|
||||
base.material = null;
|
||||
return;
|
||||
}
|
||||
mCachedMaterial = new Material(value);
|
||||
mCachedMaterial.hideFlags = HideFlags.DontSave;
|
||||
if (mCachedMaterial.HasProperty("_ChartTiling"))
|
||||
mCachedMaterial.SetFloat("_ChartTiling", Tiling);
|
||||
base.material = mCachedMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector2 Min
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2(mMinX, mMinY);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector2 Max
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2(mMaxX, mMaxY);
|
||||
}
|
||||
}
|
||||
|
||||
protected override float MouseInThreshold
|
||||
{
|
||||
get
|
||||
{
|
||||
return Mathf.Max(Thickness, mPointSize) + Sensitivity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the transform of the hover object based on the data in this graphic
|
||||
/// </summary>
|
||||
/// <param name="hover"></param>
|
||||
/// <param name="index"></param>
|
||||
protected override void SetUpHoverObject(ChartItemEffect hover, int index, int type,object data)
|
||||
{
|
||||
if (hover == null)
|
||||
return;
|
||||
if (mLines == null || mLines.Count == 0)
|
||||
return;
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
if (mPointRender)
|
||||
{
|
||||
if (index >= mLines[0].PointCount)
|
||||
return;
|
||||
Vector4 point = mLines[0].getPoint(index);
|
||||
RectTransform transform = hover.GetComponent<RectTransform>();
|
||||
transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
float size = mPointSize;
|
||||
if (point.w >= 0f)
|
||||
size = point.w;
|
||||
transform.sizeDelta = new Vector2(size, size);
|
||||
transform.anchoredPosition3D = new Vector3(point.x, point.y, 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index >= mLines[0].LineCount)
|
||||
return;
|
||||
Vector3 from;
|
||||
Vector3 to;
|
||||
mLines[0].GetLine(index, out from, out to);
|
||||
|
||||
if (ViewRect.HasValue)
|
||||
{
|
||||
Vector2 vFrom = from;
|
||||
Vector2 vTo = to;
|
||||
TrimLine(ViewRect.Value, ref vFrom, ref vTo);
|
||||
from = new Vector3(vFrom.x, vFrom.y, from.z);
|
||||
to = new Vector3(vTo.x, vTo.y, to.z);
|
||||
}
|
||||
|
||||
Vector3 dir = (to - from);
|
||||
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
|
||||
RectTransform transform = hover.GetComponent<RectTransform>();
|
||||
transform.sizeDelta = new Vector2(dir.magnitude, Thickness);
|
||||
transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
transform.localRotation = Quaternion.Euler(0f, 0f, angle);
|
||||
Vector3 point = (from + to) * 0.5f;
|
||||
transform.anchoredPosition3D = new Vector3(point.x, point.y, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Pick(Vector3 mouse, out int pickedIndex, out int pickedType, out object selectionData)
|
||||
{
|
||||
if (mPointRender)
|
||||
PickDot(mouse, out pickedType, out pickedIndex,out selectionData);
|
||||
else
|
||||
PickLine(mouse, out pickedType, out pickedIndex, out selectionData);
|
||||
if (pickedIndex >= 0)
|
||||
pickedIndex += refrenceIndex;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
Material mat = material;
|
||||
if (mCachedMaterial != null && mat != null && mCachedMaterial.HasProperty("_ChartTiling"))
|
||||
{
|
||||
if (mCachedMaterial != mat)
|
||||
mCachedMaterial.CopyPropertiesFromMaterial(mat);
|
||||
mCachedMaterial.SetFloat("_ChartTiling", Tiling);
|
||||
}
|
||||
}
|
||||
partial void ProcesssPoint(ref Vector4 point, ref float halfSize);
|
||||
IEnumerable<UIVertex> getDotVeritces()
|
||||
{
|
||||
if (mLines == null)
|
||||
yield break;
|
||||
float z = 0f;
|
||||
float halfSize = mPointSize * 0.5f;
|
||||
for (int i = 0; i < mLines.Count; ++i)
|
||||
{
|
||||
LineSegement seg = mLines[i];
|
||||
int total = seg.PointCount;
|
||||
for (int j = mMinModifyIndex; j < total; ++j)
|
||||
{
|
||||
Vector4 magPoint = seg.getPoint(j);
|
||||
if (magPoint.w == 0f)
|
||||
continue;
|
||||
|
||||
Vector3 point = (Vector3)magPoint;
|
||||
halfSize = mPointSize * 0.5f;
|
||||
ProcesssPoint(ref magPoint, ref halfSize);
|
||||
Vector3 p1 = point + new Vector3(-halfSize, -halfSize, 0f);
|
||||
Vector3 p2 = point + new Vector3(halfSize, -halfSize, 0f);
|
||||
Vector3 p3 = point + new Vector3(-halfSize, halfSize, 0f);
|
||||
Vector3 p4 = point + new Vector3(halfSize, halfSize, 0f);
|
||||
Vector2 uv1 = new Vector2(0f, 0f);
|
||||
Vector2 uv2 = new Vector2(1f, 0f);
|
||||
Vector2 uv3 = new Vector2(0f, 1f);
|
||||
Vector2 uv4 = new Vector2(1f, 1f);
|
||||
|
||||
UIVertex v1 = ChartCommon.CreateVertex(p1, uv1, z);
|
||||
UIVertex v2 = ChartCommon.CreateVertex(p2, uv2, z);
|
||||
UIVertex v3 = ChartCommon.CreateVertex(p3, uv3, z);
|
||||
UIVertex v4 = ChartCommon.CreateVertex(p4, uv4, z);
|
||||
|
||||
yield return v1;
|
||||
yield return v2;
|
||||
yield return v3;
|
||||
yield return v4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 TransformUv(Vector2 uv)
|
||||
{
|
||||
return uv;
|
||||
//if (mUvRect.HasValue == false)
|
||||
// return uv;
|
||||
//Rect r = mUvRect.Value;
|
||||
//float x = r.x + uv.x * r.width;
|
||||
//float y = r.y + uv.y * r.height;
|
||||
//return new Vector2(x, y);
|
||||
}
|
||||
|
||||
IEnumerable<UIVertex> getFillVeritces()
|
||||
{
|
||||
if (mLines == null)
|
||||
yield break;
|
||||
float z = 0f;
|
||||
for (int i = 0; i < mLines.Count; ++i)
|
||||
{
|
||||
LineSegement seg = mLines[i];
|
||||
int totalLines = seg.LineCount;
|
||||
for (int j = mMinModifyIndex; j < totalLines; ++j)
|
||||
{
|
||||
Vector3 from;
|
||||
Vector3 to;
|
||||
seg.GetLine(j,out from, out to);
|
||||
|
||||
Vector2 toTrim = to;
|
||||
Vector2 fromTrim = from;
|
||||
TrimItem(mFillRect.xMin, mFillRect.yMin, mFillRect.xMax, mFillRect.yMin, true, false, ref fromTrim, ref toTrim);
|
||||
to = new Vector3(toTrim.x, toTrim.y, to.z);
|
||||
from = new Vector3(fromTrim.x, fromTrim.y, from.z);
|
||||
Vector3 fromBottom = from;
|
||||
Vector3 toBottom = to;
|
||||
|
||||
fromBottom.y = mFillRect.yMin;
|
||||
toBottom.y = mFillRect.yMin;
|
||||
|
||||
float fromV = 1f;
|
||||
float toV = 1f;
|
||||
|
||||
if (mStretchY == false)
|
||||
{
|
||||
fromV = Mathf.Abs((from.y - mFillRect.yMin) / mFillRect.height);
|
||||
toV = Mathf.Abs((to.y - mFillRect.yMin) / mFillRect.height);
|
||||
}
|
||||
|
||||
float fromU = ((from.x - mFillRect.xMin) / mFillRect.width);
|
||||
float toU = ((to.x - mFillRect.xMin) / mFillRect.width);
|
||||
Vector2 uv1 = TransformUv(new Vector2(fromU, fromV));
|
||||
Vector2 uv2 = TransformUv(new Vector2(toU, toV));
|
||||
Vector2 uv3 = TransformUv(new Vector2(fromU, 0f));
|
||||
Vector2 uv4 = TransformUv(new Vector2(toU, 0f));
|
||||
|
||||
UIVertex v1 = ChartCommon.CreateVertex(from, uv1, z);
|
||||
UIVertex v2 = ChartCommon.CreateVertex(to, uv2, z);
|
||||
UIVertex v3 = ChartCommon.CreateVertex(fromBottom, uv3, z);
|
||||
UIVertex v4 = ChartCommon.CreateVertex(toBottom, uv4, z);
|
||||
|
||||
yield return v1;
|
||||
yield return v2;
|
||||
yield return v3;
|
||||
yield return v4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<UIVertex> getLineVertices()
|
||||
{
|
||||
if (mLines == null)
|
||||
yield break;
|
||||
float halfThickness = Thickness * 0.5f;
|
||||
float z = 0f;
|
||||
|
||||
for (int i = 0; i < mLines.Count; ++i)
|
||||
{
|
||||
LineSegement seg = mLines[i];
|
||||
int totalLines = seg.LineCount;
|
||||
Line? peek = null;
|
||||
Line? prev = null;
|
||||
float tileUv = 0f;
|
||||
float totalUv = 0f;
|
||||
for (int j = mMinModifyIndex; j < totalLines; ++j)
|
||||
totalUv += (float)seg.GetLineMag(j);
|
||||
for (int j = mMinModifyIndex; j < totalLines; ++j)
|
||||
{
|
||||
Line line;
|
||||
bool hasNext = j + 1 < totalLines;
|
||||
if (peek.HasValue)
|
||||
line = peek.Value;
|
||||
else
|
||||
line = seg.GetLine(j, halfThickness, prev.HasValue, hasNext);
|
||||
peek = null;
|
||||
if (j + 1 < totalLines)
|
||||
peek = seg.GetLine(j + 1, halfThickness, true, j + 2 < totalLines);
|
||||
|
||||
Vector3 p1 = line.P1;
|
||||
Vector3 p2 = line.P2;
|
||||
Vector3 p3 = line.P3;
|
||||
Vector3 p4 = line.P4;
|
||||
|
||||
Vector2 uv1 = new Vector2(tileUv * Tiling, 0f);
|
||||
Vector2 uv2 = new Vector2(tileUv * Tiling, 1f);
|
||||
tileUv += line.Mag / totalUv;
|
||||
|
||||
Vector2 uv3 = new Vector2(tileUv * Tiling, 0f);
|
||||
Vector2 uv4 = new Vector2(tileUv * Tiling, 1f);
|
||||
|
||||
UIVertex v1 = ChartCommon.CreateVertex(p1, uv1, z);
|
||||
UIVertex v2 = ChartCommon.CreateVertex(p2, uv2, z);
|
||||
UIVertex v3 = ChartCommon.CreateVertex(p3, uv3, z);
|
||||
UIVertex v4 = ChartCommon.CreateVertex(p4, uv4, z);
|
||||
|
||||
yield return v1;
|
||||
yield return v2;
|
||||
yield return v3;
|
||||
yield return v4;
|
||||
|
||||
if (peek.HasValue)
|
||||
{
|
||||
float myZ = z + 0.2f;
|
||||
Vector3 a1, a2;
|
||||
GetSide(line.To, line.Dir, line.Normal, halfThickness * 0.5f, halfThickness * 0.6f, v3.position.z, out a1, out a2);
|
||||
yield return v3;
|
||||
yield return v4;
|
||||
yield return ChartCommon.CreateVertex(a1, v3.uv0, myZ);
|
||||
yield return ChartCommon.CreateVertex(a2, v4.uv0, myZ);
|
||||
}
|
||||
if (prev.HasValue)
|
||||
{
|
||||
float myZ = z + 0.2f;
|
||||
Vector3 a1, a2;
|
||||
GetSide(line.From, -line.Dir, line.Normal, halfThickness * 0.5f, halfThickness * 0.6f, v1.position.z, out a1, out a2);
|
||||
yield return ChartCommon.CreateVertex(a1, v1.uv0, myZ);
|
||||
yield return ChartCommon.CreateVertex(a2, v2.uv0, myZ);
|
||||
yield return v1;
|
||||
yield return v2;
|
||||
}
|
||||
//z -= 0.05f;
|
||||
prev = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<UIVertex> getVerices()
|
||||
{
|
||||
IEnumerable<UIVertex> vertices;
|
||||
if (mPointRender)
|
||||
vertices = getDotVeritces();
|
||||
else
|
||||
{
|
||||
if (mFillRender)
|
||||
vertices = getFillVeritces();
|
||||
else
|
||||
vertices = getLineVertices();
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
|
||||
Mesh mVHMesh;
|
||||
List<Vector3> mPositions = new List<Vector3>();
|
||||
List<Vector2> mUvs = new List<Vector2>();
|
||||
List<int> mTringles = new List<int>();
|
||||
|
||||
void WriteTo<T> (List<T> list,int index,T val)
|
||||
{
|
||||
if (list.Count == index)
|
||||
list.Add(val);
|
||||
else
|
||||
list[index] = val;
|
||||
}
|
||||
|
||||
protected override void UpdateGeometry()
|
||||
{
|
||||
|
||||
if (EnableOptimization == false)
|
||||
{
|
||||
mMinModifyIndex = 0;
|
||||
base.UpdateGeometry();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mVHMesh == null)
|
||||
mVHMesh = new Mesh();
|
||||
if (mMinModifyIndex == int.MaxValue)
|
||||
mMinModifyIndex = mPositions.Count;
|
||||
if (mMinModifyIndex <= 0)
|
||||
{
|
||||
mMinModifyIndex = 0;
|
||||
mPositions.Clear();
|
||||
mUvs.Clear();
|
||||
mTringles.Clear();
|
||||
foreach (UIVertex v in getVerices())
|
||||
{
|
||||
mPositions.Add(v.position);
|
||||
mUvs.Add(v.uv0);
|
||||
}
|
||||
int quads = (mPositions.Count / 4) ;
|
||||
int baseIndex = 0;
|
||||
for (int i = 0; i < quads; i++)
|
||||
{
|
||||
|
||||
mTringles.Add(baseIndex);
|
||||
mTringles.Add(baseIndex + 1);
|
||||
mTringles.Add(baseIndex + 3);
|
||||
|
||||
mTringles.Add(baseIndex + 3);
|
||||
mTringles.Add(baseIndex + 2);
|
||||
mTringles.Add(baseIndex);
|
||||
baseIndex += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Debug.Log("adding");
|
||||
int total = 0;
|
||||
int index = mMinModifyIndex;
|
||||
foreach (UIVertex v in getVerices())
|
||||
{
|
||||
// Debug.Log("extra");
|
||||
WriteTo<Vector3>(mPositions, index, v.position);
|
||||
WriteTo<Vector2>(mUvs, index, v.uv0);
|
||||
total++;
|
||||
}
|
||||
int quads = total / 4;
|
||||
for (int i = 0; i < quads; i++)
|
||||
{
|
||||
// Debug.Log("extra tring");
|
||||
mTringles.Add(0);
|
||||
mTringles.Add(1);
|
||||
mTringles.Add(3);
|
||||
|
||||
mTringles.Add(3);
|
||||
mTringles.Add(2);
|
||||
mTringles.Add(0);
|
||||
}
|
||||
}
|
||||
mVHMesh.Clear();
|
||||
mVHMesh.SetVertices(mPositions);
|
||||
mVHMesh.SetUVs(0, mUvs);
|
||||
mVHMesh.SetTriangles(mTringles, 0);
|
||||
//at the end
|
||||
mMinModifyIndex = int.MaxValue;
|
||||
GetComponent<CanvasRenderer>().SetMesh(mVHMesh);
|
||||
}
|
||||
|
||||
#if (!UNITY_5_2_0) && (!UNITY_5_2_1)
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
base.OnPopulateMesh(vh);
|
||||
vh.Clear();
|
||||
int vPos = 0;
|
||||
foreach (UIVertex v in getVerices())
|
||||
{
|
||||
mTmpVerts[vPos++] = v;
|
||||
if (vPos == 4)
|
||||
{
|
||||
UIVertex tmp = mTmpVerts[2];
|
||||
mTmpVerts[2] = mTmpVerts[3];
|
||||
mTmpVerts[3] = tmp;
|
||||
vPos = 0;
|
||||
vh.AddUIVertexQuad(mTmpVerts);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#pragma warning disable 0672
|
||||
#if !UNITY_2017_1_OR_NEWER
|
||||
/// <summary>
|
||||
/// A chart mesh used for populating the
|
||||
/// </summary>
|
||||
WorldSpaceChartMesh mMesh = null;
|
||||
protected override void OnPopulateMesh(Mesh m)
|
||||
{
|
||||
if (mMesh == null)
|
||||
mMesh = new WorldSpaceChartMesh(1);
|
||||
else
|
||||
mMesh.Clear();
|
||||
int vPos = 0;
|
||||
mMinModifyIndex = 0; // not supported here
|
||||
foreach (UIVertex v in getVerices())
|
||||
{
|
||||
mTmpVerts[vPos++] = v;
|
||||
if (vPos == 4)
|
||||
{
|
||||
vPos = 0;
|
||||
mMesh.AddQuad(mTmpVerts[0], mTmpVerts[1], mTmpVerts[2], mTmpVerts[3]);
|
||||
}
|
||||
}
|
||||
|
||||
mMesh.ApplyToMesh(m);
|
||||
}
|
||||
#endif
|
||||
void PickLine(Vector3 mouse, out int segment, out int line, out object selectionData)
|
||||
{
|
||||
float minDist = Mathf.Infinity;
|
||||
segment = -1;
|
||||
line = -1;
|
||||
selectionData = null;
|
||||
if (mLines == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < mLines.Count; ++i)
|
||||
{
|
||||
LineSegement seg = mLines[i];
|
||||
int total = seg.LineCount;
|
||||
for (int j = 0; j < total; ++j)
|
||||
{
|
||||
Vector3 from;
|
||||
Vector3 to;
|
||||
seg.GetLine(j, out from, out to);
|
||||
float dist = ChartCommon.SegmentPointSqrDistance(from,to,mouse);
|
||||
if (dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
segment = i;
|
||||
line = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
float thresh = (Thickness + Sensitivity);
|
||||
|
||||
if ((ViewRect.HasValue && !ViewRect.Value.Contains(mouse)) || minDist > thresh * thresh)
|
||||
{
|
||||
segment = -1;
|
||||
line = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void PickDot(Vector3 mouse, out int segment , out int point, out object selectionData)
|
||||
{
|
||||
float minDist = Mathf.Infinity;
|
||||
segment = -1;
|
||||
point = -1;
|
||||
selectionData = null;
|
||||
if (mLines == null)
|
||||
return;
|
||||
float mag = mPointSize;
|
||||
for (int i = 0; i < mLines.Count; ++i)
|
||||
{
|
||||
LineSegement seg = mLines[i];
|
||||
int total = seg.PointCount;
|
||||
for (int j = 0; j < total; ++j)
|
||||
{
|
||||
Vector4 p = seg.getPoint(j);
|
||||
if (p.w == 0f)
|
||||
continue;
|
||||
float dist = (mouse - ((Vector3)p)).sqrMagnitude;
|
||||
if(dist < minDist)
|
||||
{
|
||||
mag = p.w;
|
||||
if (mag < 0f)
|
||||
mag = mPointSize;
|
||||
minDist = dist;
|
||||
segment = i;
|
||||
point = j;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
float thresh = mag + Sensitivity;
|
||||
if ((ViewRect.HasValue && !ViewRect.Value.Contains(mouse)) || minDist > thresh * thresh)
|
||||
{
|
||||
segment = -1;
|
||||
point = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void TrimItem(float x1, float y1 ,float x2,float y2,bool xAxis,bool oposite, ref Vector2 from, ref Vector2 to)
|
||||
{
|
||||
Vector2 seg1 = new Vector2(x1, y1);
|
||||
Vector2 seg2 = new Vector2(x2, y2);
|
||||
Vector2 point;
|
||||
if (ChartCommon.SegmentIntersection(seg1, seg2, from, to, out point) == false)
|
||||
return;
|
||||
if(xAxis)
|
||||
{
|
||||
if ((to.y > from.y) ^ oposite)
|
||||
from = point;
|
||||
else
|
||||
to = point;
|
||||
return;
|
||||
}
|
||||
if ((to.x > from.x) ^ oposite)
|
||||
from = point;
|
||||
else
|
||||
to = point;
|
||||
}
|
||||
|
||||
void TrimLine(Rect r,ref Vector2 from, ref Vector2 to)
|
||||
{
|
||||
TrimItem(r.xMin, r.yMin, r.xMax, r.yMin, true, false, ref from, ref to);
|
||||
TrimItem(r.xMin, r.yMax, r.xMax, r.yMax, true, true, ref from, ref to);
|
||||
TrimItem(r.xMin, r.yMin, r.xMin, r.yMax, false, false, ref from, ref to);
|
||||
TrimItem(r.xMax, r.yMin, r.xMax, r.yMax, false, true, ref from, ref to);
|
||||
}
|
||||
|
||||
#pragma warning restore 0672
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2032ee9ddbfbfb74da66a209b05d468d
|
||||
timeCreated: 1478616684
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
#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 CanvasLinesHover : MaskableGraphic
|
||||
{
|
||||
float mHalfThickness;
|
||||
UIVertex[] mTmpVerts = new UIVertex[4];
|
||||
|
||||
public void Init(float thickness)
|
||||
{
|
||||
mHalfThickness = thickness * 0.5f;
|
||||
SetAllDirty();
|
||||
Rebuild(CanvasUpdate.PreRender);
|
||||
}
|
||||
|
||||
IEnumerable<UIVertex> getVerices()
|
||||
{
|
||||
UIVertex v = new UIVertex();
|
||||
v.position = new Vector3(-mHalfThickness, -mHalfThickness);
|
||||
v.uv0 = new Vector2(0f, 0f);
|
||||
yield return v;
|
||||
v.position = new Vector3(-mHalfThickness, mHalfThickness);
|
||||
v.uv0 = new Vector2(0f, 1f);
|
||||
yield return v;
|
||||
v.position = new Vector3(mHalfThickness, mHalfThickness);
|
||||
v.uv0 = new Vector2(1f, 1f);
|
||||
yield return v;
|
||||
v.position = new Vector3(mHalfThickness, -mHalfThickness);
|
||||
v.uv0 = new Vector2(1f, 0f);
|
||||
yield return v;
|
||||
}
|
||||
|
||||
#if (!UNITY_5_2_0) && (!UNITY_5_2_1)
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
base.OnPopulateMesh(vh);
|
||||
vh.Clear();
|
||||
int vPos = 0;
|
||||
foreach (UIVertex v in getVerices())
|
||||
{
|
||||
mTmpVerts[vPos++] = v;
|
||||
if (vPos == 4)
|
||||
{
|
||||
UIVertex tmp = mTmpVerts[2];
|
||||
mTmpVerts[2] = mTmpVerts[3];
|
||||
mTmpVerts[3] = tmp;
|
||||
vPos = 0;
|
||||
vh.AddUIVertexQuad(mTmpVerts);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#pragma warning disable 0672
|
||||
#if !UNITY_2017_1_OR_NEWER
|
||||
protected override void OnPopulateMesh(Mesh m)
|
||||
{
|
||||
WorldSpaceChartMesh mesh = new WorldSpaceChartMesh(1);
|
||||
int vPos = 0;
|
||||
foreach (UIVertex v in getVerices())
|
||||
{
|
||||
mTmpVerts[vPos++] = v;
|
||||
if (vPos == 4)
|
||||
{
|
||||
vPos = 0;
|
||||
|
||||
mesh.AddQuad(mTmpVerts[0], mTmpVerts[1], mTmpVerts[2], mTmpVerts[3]);
|
||||
}
|
||||
}
|
||||
mesh.ApplyToMesh(m);
|
||||
}
|
||||
#endif
|
||||
#pragma warning restore 0672
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ad8c18b253fae84fabcbfd13925da24
|
||||
timeCreated: 1491578596
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,450 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Base class for canvas series graphic object. Contains functionallity that enable creating a hovering prefab where the mouse is located , and event handling
|
||||
/// The main idea behind this implementation is that it allows to create a mesh once. Then in order to create the hover effect , an object is placed on top of that mesh , those leaving the mesh unmodified.
|
||||
/// </summary>
|
||||
public abstract class EventHandlingGraphic : MaskableGraphic
|
||||
{
|
||||
/// <summary>
|
||||
/// The prefab for the hover effect
|
||||
/// </summary>
|
||||
ChartItemEffect mHoverPrefab;
|
||||
/// <summary>
|
||||
/// The currently hovered item
|
||||
/// </summary>
|
||||
ChartItemEffect mCurrentHover = null;
|
||||
/// <summary>
|
||||
/// All the objects that have a hover animation displayed. Only one object can be hovered. But the hover animation has a fade effect so multiple objects can display the animation at the same time
|
||||
/// </summary>
|
||||
List<ChartItemEffect> mHoverObjectes = new List<ChartItemEffect>();
|
||||
/// <summary>
|
||||
/// when hover prefabs end their life time. They are pooled in this list
|
||||
/// </summary>
|
||||
List<ChartItemEffect> mHoverFreeObjects = new List<ChartItemEffect>();
|
||||
|
||||
protected Rect? ViewRect = null;
|
||||
protected Rect? mUvRect;
|
||||
|
||||
/// <summary>
|
||||
/// if true , mouse events will be proccedd even if the mouse hasn't moved
|
||||
/// </summary>
|
||||
bool mForceMouseMove = false;
|
||||
bool mIsMouseIn = false;
|
||||
|
||||
Transform mHoverTransform;
|
||||
|
||||
int mPickedIndex = -1, mPickedType = -1;
|
||||
object mPickedData = null;
|
||||
Vector2 mLastMousePosition = new Vector2();
|
||||
GraphicRaycaster mCaster;
|
||||
|
||||
/// <summary>
|
||||
/// When the graphic data is clliped , this representes the first index being displayed in the graph. Thus the [Data Index] = refrenceIndex + [Graphic Index]
|
||||
/// </summary>
|
||||
protected int refrenceIndex { get; private set; }
|
||||
|
||||
public void SetRefrenceIndex(int index)
|
||||
{
|
||||
refrenceIndex = index;
|
||||
}
|
||||
|
||||
public float Sensitivity
|
||||
{
|
||||
get
|
||||
{
|
||||
float sensitivity = 10f;
|
||||
if(mControl == null)
|
||||
mControl = GetComponent<SensitivityControl>();
|
||||
if (mControl != null)
|
||||
sensitivity = mControl.Sensitivity;
|
||||
return sensitivity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// call this to free all hover objects and reset event input. This is useful mostly when the entire data of the graphic has been replaced and old animations should be discarded
|
||||
/// </summary>
|
||||
public void ClearEvents()
|
||||
{
|
||||
mIsMouseIn = false;
|
||||
for (int i = 0; i < mHoverObjectes.Count; i++)
|
||||
{
|
||||
mHoverObjectes[i].gameObject.SetActive(false);
|
||||
mHoverFreeObjects.Add(mHoverObjectes[i]);
|
||||
}
|
||||
mHoverObjectes.Clear();
|
||||
|
||||
if (mCurrentHover != null)
|
||||
{
|
||||
mCurrentHover.gameObject.SetActive(false);
|
||||
mHoverFreeObjects.Add(mCurrentHover);
|
||||
mCurrentHover = null;
|
||||
}
|
||||
mPickedIndex = mPickedType = -1;
|
||||
mPickedData = null;
|
||||
}
|
||||
/// <summary>
|
||||
/// The minimum for the bounding rect of the graphic data
|
||||
/// </summary>
|
||||
protected abstract Vector2 Min { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum for the bounding rect of the graphic data
|
||||
/// </summary>
|
||||
protected abstract Vector2 Max { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains properties to define mouse sensitivy for event handling
|
||||
/// </summary>
|
||||
SensitivityControl mControl;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="position"></param>
|
||||
public delegate void GraphicEvent(int index, int type, object data, Vector2 position);
|
||||
|
||||
/// <summary>
|
||||
/// The selected index is hovered about the specified point
|
||||
/// </summary>
|
||||
public event GraphicEvent Hover;
|
||||
/// <summary>
|
||||
/// The selected index is clicked about the specified point
|
||||
/// </summary>
|
||||
public event GraphicEvent Click;
|
||||
/// <summary>
|
||||
/// The currently hovered and selected objects are no longer selected or hovered.
|
||||
/// </summary>
|
||||
public event Action Leave;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the viewing data for the graphic.
|
||||
/// </summary>
|
||||
/// <param name="r">the canvas rect bounds</param>
|
||||
/// <param name="uvRect">the uv bounds of the currently cliped data</param>
|
||||
public void SetViewRect(Rect r, Rect uvRect)
|
||||
{
|
||||
ViewRect = r;
|
||||
mUvRect = uvRect;
|
||||
}
|
||||
|
||||
public void HoverTransform(Transform t)
|
||||
{
|
||||
mHoverTransform = t;
|
||||
}
|
||||
|
||||
public void SetHoverPrefab(ChartItemEffect prefab)
|
||||
{
|
||||
mHoverPrefab = prefab;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// call this when the graphic view has changed , this will recheck the mouse position and input for new events.
|
||||
/// This is useful for features such as realtime graph. Where new objects can be picked even if the mouse is in one place only
|
||||
/// </summary>
|
||||
public void RefreshInputs()
|
||||
{
|
||||
mForceMouseMove = true;
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if(HandleMouseMove(mForceMouseMove)) // handle mouse move
|
||||
mForceMouseMove = false; // mouse events are already handled in the above line, so we set this to false
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set up the position of the hover prefab
|
||||
/// </summary>
|
||||
/// <param name="hover">the hovered gameobject passesd using it's ChartItemEffect component</param>
|
||||
/// <param name="index">index of the data item which is hovered</param>
|
||||
protected abstract void SetUpHoverObject(ChartItemEffect hover, int index,int type,object selectionData);
|
||||
/// <summary>
|
||||
/// returns the threshold at which the mouse is considered in the area of the graphic. This threshold is realtive to the graphic rectangle.
|
||||
/// </summary>
|
||||
protected abstract float MouseInThreshold { get; }
|
||||
|
||||
/// <summary>
|
||||
/// override this in a derived class to pick a data item based on the mouse position.
|
||||
/// </summary>
|
||||
/// <param name="mouse">mouse position</param>
|
||||
/// <param name="pickedIndex">first index of the selected item, or -1 for no selection</param>
|
||||
/// <param name="pickedType">type of the selected item, or -1 for no selection</param>
|
||||
protected abstract void Pick(Vector3 mouse, out int pickedIndex, out int pickedType,out object SelectionData);
|
||||
|
||||
/// <summary>
|
||||
/// This method is called during update if RefreshInputs has been called in the preivous frame. When the canvas graph mesh updates , all active hover effects are repositioned to match their new position.
|
||||
/// </summary>
|
||||
protected void SetUpAllHoverObjects()
|
||||
{
|
||||
if (mHoverObjectes == null)
|
||||
return;
|
||||
for (int i = 0; i < mHoverObjectes.Count; i++)
|
||||
SetUpHoverObject(mHoverObjectes[i]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// utillity method that can be used in derived classes in order to
|
||||
/// </summary>
|
||||
/// <param name="hover"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="rect"></param>
|
||||
protected void SetupHoverObjectToRect(ChartItemEffect hover, int index, int type,Rect rect)
|
||||
{
|
||||
if (hover == null)
|
||||
return;
|
||||
RectTransform transform = hover.GetComponent<RectTransform>();
|
||||
transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
transform.sizeDelta = new Vector2(rect.width, rect.height);
|
||||
transform.anchoredPosition3D = new Vector3(rect.center.x, rect.center.y, 0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shuts down a hover prefab effect
|
||||
/// </summary>
|
||||
/// <param name="hover"></param>
|
||||
void TriggerOut(ChartItemEffect hover)
|
||||
{
|
||||
hover.TriggerOut(true);
|
||||
ChartMaterialController control = hover.GetComponent<ChartMaterialController>();
|
||||
if (control)
|
||||
control.TriggerOff();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shuts down a hover prefab effect
|
||||
/// </summary>
|
||||
/// <param name="hover"></param>
|
||||
void TriggerIn(ChartItemEffect hover)
|
||||
{
|
||||
hover.TriggerIn(false);
|
||||
ChartMaterialController control = hover.GetComponent<ChartMaterialController>();
|
||||
if (control)
|
||||
control.TriggerOn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes a hover object out of the pool , or creates a new one if the pool is empty
|
||||
/// </summary>
|
||||
/// <param name="index">the index of the data item , this index will be assigned to the returned object</param>
|
||||
/// <returns></returns>
|
||||
public ChartItemEffect LockHoverObject(int index,int type,object selectionData)
|
||||
{
|
||||
int count = mHoverFreeObjects.Count;
|
||||
ChartItemEffect effect = null;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
effect = mHoverFreeObjects[count - 1];
|
||||
mHoverFreeObjects.RemoveAt(count - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mHoverPrefab == null)
|
||||
return null;
|
||||
GameObject obj = GameObject.Instantiate(mHoverPrefab.gameObject);
|
||||
MaskableGraphic g = obj.GetComponent<MaskableGraphic>();
|
||||
if (g != null)
|
||||
g.maskable = false;
|
||||
ChartCommon.EnsureComponent<ChartItem>(obj);
|
||||
Transform parent = transform;
|
||||
if (mHoverTransform != null)
|
||||
parent = mHoverTransform;
|
||||
obj.transform.SetParent(parent);
|
||||
effect = obj.GetComponent<ChartItemEffect>();
|
||||
effect.Deactivate += Effect_Deactivate;
|
||||
}
|
||||
|
||||
effect.ItemType = type;
|
||||
effect.ItemIndex = index;
|
||||
effect.ItemData = selectionData;
|
||||
mHoverObjectes.Add(effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// called when an effect is done animating. Reclaims the object into the hover object pool
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
private void Effect_Deactivate(ChartItemEffect obj)
|
||||
{
|
||||
obj.gameObject.SetActive(false);
|
||||
mHoverObjectes.Remove(obj);
|
||||
mHoverFreeObjects.Add(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// helped method that extract the index from the hover object and then call SetUpHoverObject overload with index
|
||||
/// </summary>
|
||||
/// <param name="hover"></param>
|
||||
void SetUpHoverObject(ChartItemEffect hover)
|
||||
{
|
||||
if (hover == null)
|
||||
return;
|
||||
int pickedIndex = hover.ItemIndex - refrenceIndex;
|
||||
if (pickedIndex < 0)
|
||||
return;
|
||||
SetUpHoverObject(hover, pickedIndex,hover.ItemType,hover.ItemData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle mouse events
|
||||
/// </summary>
|
||||
/// <param name="mouse"></param>
|
||||
/// <param name="leave"></param>
|
||||
/// <param name="force"></param>
|
||||
void DoMouse(Vector3 mouse, bool leave, bool force)
|
||||
{
|
||||
int prevI = mPickedIndex;
|
||||
int prevJ = mPickedType;
|
||||
if (leave)
|
||||
{
|
||||
mPickedIndex = -1;
|
||||
mPickedType = -1;
|
||||
mPickedData = null;
|
||||
}
|
||||
else
|
||||
Pick(mouse, out mPickedIndex, out mPickedType,out mPickedData);
|
||||
|
||||
if (prevI != mPickedIndex || prevJ != mPickedType)
|
||||
{
|
||||
|
||||
if (mCurrentHover != null)
|
||||
{
|
||||
TriggerOut(mCurrentHover);
|
||||
if (mPickedIndex == -1 && mPickedType == -1)
|
||||
{
|
||||
if (Leave != null)
|
||||
Leave();
|
||||
}
|
||||
mCurrentHover = null;
|
||||
}
|
||||
|
||||
if (mPickedIndex != -1 && mPickedType != -1)
|
||||
{
|
||||
mCurrentHover = LockHoverObject(mPickedIndex,mPickedType, mPickedData);
|
||||
if (mCurrentHover == null)
|
||||
return;
|
||||
if (Hover != null)
|
||||
Hover(mPickedIndex,mPickedType, mPickedData, mouse);
|
||||
mCurrentHover.gameObject.SetActive(true);
|
||||
SetUpHoverObject(mCurrentHover);
|
||||
TriggerIn(mCurrentHover);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles a mouse move event.
|
||||
/// </summary>
|
||||
/// <param name="force"></param>
|
||||
public bool HandleMouseMove(bool force)
|
||||
{
|
||||
mCaster = GetComponentInParent<GraphicRaycaster>();
|
||||
if (mCaster == null)
|
||||
return false;
|
||||
Vector2 mousePos;
|
||||
|
||||
|
||||
// on some machines and settings , it seems that Input.mousePosition returns invalid coordinates, the following checks make sure that the mouse position is valid
|
||||
Vector3 checkMousePos = Input.mousePosition;
|
||||
|
||||
var pointer = GetComponentInParent<CustomChartPointer>();
|
||||
if (pointer != null)
|
||||
checkMousePos = pointer.ScreenPosition;
|
||||
Camera checkCamera = mCaster.eventCamera;
|
||||
if (checkCamera == null)
|
||||
checkCamera = Camera.main;
|
||||
if (checkCamera == null)
|
||||
return false;
|
||||
if (checkCamera.pixelRect.Contains(checkMousePos) == false)
|
||||
return false;
|
||||
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(transform as RectTransform, checkMousePos, mCaster.eventCamera, out mousePos);
|
||||
//DoMouse(mousePos, false);
|
||||
float thresh = MouseInThreshold;
|
||||
if (force)
|
||||
{
|
||||
SetUpAllHoverObjects();
|
||||
}
|
||||
|
||||
Vector2 min = Min;
|
||||
Vector2 max = Max;
|
||||
if (mousePos.x < min.x - thresh || mousePos.y < min.y - thresh || mousePos.x > max.x + thresh || mousePos.y > max.y + thresh)
|
||||
{
|
||||
if (mIsMouseIn)
|
||||
{
|
||||
mIsMouseIn = false;
|
||||
DoMouse(mousePos, true, force);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mIsMouseIn == false)
|
||||
{
|
||||
mIsMouseIn = true;
|
||||
mLastMousePosition = mousePos;
|
||||
DoMouse(mousePos, false, force);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((mLastMousePosition - mousePos).sqrMagnitude > 1) || force)
|
||||
{
|
||||
mLastMousePosition = mousePos;
|
||||
DoMouse(mousePos, false, force);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((pointer== null && Input.GetMouseButtonDown(0)) || (pointer !=null && pointer.Click))
|
||||
{
|
||||
HandleMouseDown();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles mouse down. This method will fire the mouse click event if an item is clicked
|
||||
/// </summary>
|
||||
private void HandleMouseDown()
|
||||
{
|
||||
if (mPickedIndex != -1 && mPickedType != -1)
|
||||
{
|
||||
if (Click != null)
|
||||
{
|
||||
mCaster = GetComponentInParent<GraphicRaycaster>();
|
||||
if (mCaster == null)
|
||||
return;
|
||||
Vector3 checkMousePos = Input.mousePosition;
|
||||
|
||||
var pointer = GetComponentInParent<CustomChartPointer>();
|
||||
if (pointer != null)
|
||||
checkMousePos = pointer.ScreenPosition;
|
||||
Vector2 mousePos;
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(transform as RectTransform, checkMousePos, mCaster.eventCamera, out mousePos);
|
||||
Vector3 pos = transform.InverseTransformPoint(mousePos);
|
||||
Click(mPickedIndex,mPickedType, mPickedData, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e1aa8b268945b540b4b0ef7768aca09
|
||||
timeCreated: 1503250771
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public class SensitivityControl : MonoBehaviour
|
||||
{
|
||||
public float Sensitivity = 10f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c09bf2e39f5ebfa409a492a80a326b3a
|
||||
timeCreated: 1491921896
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// advanced settings for charts (currently includes fraction digits)
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
class ChartAdancedSettings
|
||||
{
|
||||
private static ChartAdancedSettings mInstance;
|
||||
public static ChartAdancedSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mInstance == null)
|
||||
mInstance = new ChartAdancedSettings();
|
||||
return mInstance;
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] FractionDigits = new string[]
|
||||
{
|
||||
"{0:0}",
|
||||
"{0:0.#}",
|
||||
"{0:0.##}",
|
||||
"{0:0.###}",
|
||||
"{0:0.####}",
|
||||
"{0:0.#####}",
|
||||
"{0:0.######}",
|
||||
"{0:0.#######}",
|
||||
};
|
||||
|
||||
[Range(0, 7)]
|
||||
public int ValueFractionDigits = 2;
|
||||
[Range(0, 7)]
|
||||
public int AxisFractionDigits = 2;
|
||||
|
||||
private string InnerFormat(string format,double val)
|
||||
{
|
||||
try
|
||||
{
|
||||
return string.Format(format, val);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
return " ";
|
||||
}
|
||||
|
||||
string getFormat(int value)
|
||||
{
|
||||
value = Mathf.Clamp(value, 0, 7);
|
||||
return FractionDigits[value];
|
||||
}
|
||||
|
||||
public string FormatFractionDigits(int digits,double val,string format = null)
|
||||
{
|
||||
if(String.IsNullOrEmpty(format))
|
||||
return InnerFormat(getFormat(digits), val);
|
||||
return InnerFormat(format, val);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ba628bc11d892c4cabf8f85d6fe888b
|
||||
timeCreated: 1475785789
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,560 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// holds common operations of the charting library
|
||||
/// </summary>
|
||||
public partial class ChartCommon
|
||||
{
|
||||
class IntComparer : IEqualityComparer<int>
|
||||
{
|
||||
public bool Equals(int x, int y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
public int GetHashCode(int obj)
|
||||
{
|
||||
return obj.GetHashCode();
|
||||
}
|
||||
}
|
||||
class DoubleComparer : IEqualityComparer<double>
|
||||
{
|
||||
public bool Equals(double x, double y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
public int GetHashCode(double obj)
|
||||
{
|
||||
return obj.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
class DoubleVector3Comparer : IEqualityComparer<DoubleVector3>
|
||||
{
|
||||
public bool Equals(DoubleVector3 x, DoubleVector3 y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
public int GetHashCode(DoubleVector3 obj)
|
||||
{
|
||||
return obj.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private static Material mDefaultMaterial;
|
||||
|
||||
static ChartCommon()
|
||||
{
|
||||
DefaultIntComparer = new IntComparer();
|
||||
DefaultDoubleComparer = new DoubleComparer();
|
||||
DefaultDoubleVector3Comparer = new DoubleVector3Comparer();
|
||||
}
|
||||
|
||||
internal static float SmoothLerp(float from, float to, float factor)
|
||||
{
|
||||
return (from * (1f - factor)) + (to * factor);
|
||||
}
|
||||
|
||||
internal static GameObject CreateCanvasChartItem()
|
||||
{
|
||||
GameObject obj = new GameObject("item", typeof(RectTransform));
|
||||
obj.AddComponent<ChartItem>();
|
||||
return obj;
|
||||
}
|
||||
|
||||
internal static double Max(double? x, double y)
|
||||
{
|
||||
if (x.HasValue == false)
|
||||
return y;
|
||||
return Math.Max(x.Value, y);
|
||||
}
|
||||
|
||||
internal static double Min(double? x, double y)
|
||||
{
|
||||
if (x.HasValue == false)
|
||||
return y;
|
||||
return Math.Min(x.Value, y);
|
||||
}
|
||||
internal static double Clamp(double val)
|
||||
{
|
||||
if (val > 1.0)
|
||||
return 1.0;
|
||||
if (val < 0.0)
|
||||
return 0.0;
|
||||
return val;
|
||||
}
|
||||
internal static GameObject CreateChartItem()
|
||||
{
|
||||
GameObject obj = new GameObject();
|
||||
obj.AddComponent<ChartItem>();
|
||||
return obj;
|
||||
}
|
||||
internal static double normalizeInRangeX(double value, DoubleVector3 min, DoubleVector3 size)
|
||||
{
|
||||
return normalizeInRange(value, min.x, size.x);
|
||||
}
|
||||
internal static double normalizeInRangeY(double value, DoubleVector3 min, DoubleVector3 size)
|
||||
{
|
||||
return normalizeInRange(value, min.y, size.y);
|
||||
}
|
||||
|
||||
internal static double normalizeInRange(double value, double min, double size)
|
||||
{
|
||||
return (value - min) / size;
|
||||
}
|
||||
internal static double interpolateInRectX(Rect rect, double x)
|
||||
{
|
||||
return rect.x + rect.width * x;
|
||||
}
|
||||
internal static double interpolateInRectY(Rect rect, double y)
|
||||
{
|
||||
return rect.y + rect.height * y;
|
||||
}
|
||||
internal static Rect RectFromCenter(float centerX, float sizeX, float top, float bottom)
|
||||
{
|
||||
float half = sizeX * 0.5f;
|
||||
return new Rect(centerX - half, top, sizeX, bottom - top);
|
||||
}
|
||||
internal static DoubleVector4 interpolateInRect(Rect rect, DoubleVector3 point)
|
||||
{
|
||||
double x = rect.x + rect.width * point.x;
|
||||
double y = rect.y + rect.height * point.y;
|
||||
return new DoubleVector4(x, y, point.z, 0.0);
|
||||
}
|
||||
internal static void HideObjectEditor(GameObject obj, bool hideMode)
|
||||
{
|
||||
obj.hideFlags = HideFlags.DontSaveInEditor | HideFlags.HideInHierarchy | HideFlags.HideInInspector;
|
||||
}
|
||||
internal static void HideObject(GameObject obj, bool hideMode)
|
||||
{
|
||||
// return;
|
||||
if (IsInEditMode == true)
|
||||
{
|
||||
obj.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector | HideFlags.NotEditable | HideFlags.DontSaveInBuild;
|
||||
return;
|
||||
}
|
||||
if (hideMode == false)
|
||||
{
|
||||
obj.hideFlags = HideFlags.DontSaveInEditor;
|
||||
return;
|
||||
}
|
||||
obj.hideFlags = HideFlags.DontSaveInEditor | HideFlags.HideInHierarchy | HideFlags.HideInInspector | HideFlags.NotEditable;
|
||||
}
|
||||
|
||||
internal static float GetAutoLength(AnyChart parent, ChartOrientation orientation)
|
||||
{
|
||||
return (orientation == ChartOrientation.Vertical) ? ((IInternalUse)parent).InternalTotalWidth : ((IInternalUse)parent).InternalTotalHeight;
|
||||
}
|
||||
|
||||
internal static float GetAutoDepth(AnyChart parent, ChartOrientation orientation, ChartDivisionInfo info)
|
||||
{
|
||||
float depth = ((IInternalUse)parent).InternalTotalDepth;
|
||||
if (info.MarkDepth.Automatic == false)
|
||||
depth = info.MarkDepth.Value;
|
||||
return depth;
|
||||
}
|
||||
|
||||
internal static float GetAutoLength(AnyChart parent, ChartOrientation orientation, ChartDivisionInfo info)
|
||||
{
|
||||
float length = (orientation == ChartOrientation.Vertical) ? ((IInternalUse)parent).InternalTotalWidth : ((IInternalUse)parent).InternalTotalHeight;
|
||||
if (info.MarkLength.Automatic == false)
|
||||
length = info.MarkLength.Value;
|
||||
return length;
|
||||
}
|
||||
|
||||
internal static Vector2 Perpendicular(Vector2 v)
|
||||
{
|
||||
return new Vector2(v.y, -v.x);
|
||||
}
|
||||
|
||||
internal static bool SegmentIntersection(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2, out Vector2 intersection)
|
||||
{
|
||||
intersection = new Vector2();
|
||||
|
||||
Vector2 dirA = a2 - a1;
|
||||
Vector2 dirB = b2 - b1;
|
||||
|
||||
float dotA = Vector2.Dot(dirA, Perpendicular(dirB));
|
||||
if (dotA == 0)
|
||||
return false;
|
||||
|
||||
Vector2 dirAB = b1 - a1;
|
||||
float t = Vector2.Dot(dirAB, Perpendicular(dirB)) / dotA;
|
||||
if (t < 0 || t > 1)
|
||||
return false;
|
||||
|
||||
float s = Vector2.Dot(dirAB, Perpendicular(dirA)) / dotA;
|
||||
if (s < 0 || s > 1)
|
||||
return false;
|
||||
|
||||
intersection = a1 + t * dirA;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static Vector2 FromPolarRadians(float angleDeg, float radius)
|
||||
{
|
||||
float x = radius * Mathf.Cos(angleDeg);
|
||||
float y = radius * Mathf.Sin(angleDeg);
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
internal static Vector2 FromPolar(float angleDeg, float radius)
|
||||
{
|
||||
angleDeg *= Mathf.Deg2Rad;
|
||||
float x = radius * Mathf.Cos(angleDeg);
|
||||
float y = radius * Mathf.Sin(angleDeg);
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
internal static Rect FixRect(Rect r)
|
||||
{
|
||||
float x = r.x;
|
||||
float y = r.y;
|
||||
float width = r.width;
|
||||
float height = r.height;
|
||||
if (width < 0)
|
||||
{
|
||||
x = r.x + width;
|
||||
width = -width;
|
||||
}
|
||||
if (height < 0)
|
||||
{
|
||||
y = r.y + height;
|
||||
height = -height;
|
||||
}
|
||||
return new Rect(x, y, width, height);
|
||||
}
|
||||
|
||||
internal static Material DefaultMaterial
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mDefaultMaterial == null)
|
||||
{
|
||||
mDefaultMaterial = new Material(Shader.Find("Standard"));
|
||||
mDefaultMaterial.color = Color.blue;
|
||||
}
|
||||
return mDefaultMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// safely assigns a material to a renderer. if the material is null than the default material is set instead
|
||||
/// </summary>
|
||||
/// <param name="renderer">the renderer</param>
|
||||
/// <param name="material">the material</param>
|
||||
/// <returns>true if material is not null, false otherwise</returns>
|
||||
internal static bool SafeAssignMaterial(Renderer renderer, Material material, Material defualt)
|
||||
{
|
||||
Material toSet = material;
|
||||
if (toSet == null)
|
||||
{
|
||||
toSet = defualt;
|
||||
if (toSet == null)
|
||||
toSet = DefaultMaterial;
|
||||
}
|
||||
renderer.sharedMaterial = toSet;
|
||||
return material != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="newMesh"></param>
|
||||
/// <param name="cleanMesh"></param>
|
||||
internal static void CleanMesh(Mesh newMesh, ref Mesh cleanMesh)
|
||||
{
|
||||
if (cleanMesh == newMesh)
|
||||
return;
|
||||
if (cleanMesh != null)
|
||||
ChartCommon.SafeDestroy(cleanMesh);
|
||||
cleanMesh = newMesh;
|
||||
}
|
||||
|
||||
internal static bool IsInEditMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return Application.isPlaying == false && Application.isEditor;
|
||||
}
|
||||
}
|
||||
|
||||
//#if UNITY_2018_3_OR_NEWER
|
||||
//#if UNITY_EDITOR
|
||||
// public static void SafeDestroy(GameObject obj)
|
||||
// {
|
||||
// if (obj == null)
|
||||
// return;
|
||||
// if (Application.isEditor && Application.isPlaying == false)
|
||||
// {
|
||||
// if (UnityEditor.PrefabUtility.GetPrefabAssetType(obj) != UnityEditor.PrefabAssetType.NotAPrefab)
|
||||
// {
|
||||
// if (UnityEditor.PrefabUtility.IsPartOfPrefabInstance(obj))
|
||||
// {
|
||||
// var parent = UnityEditor.PrefabUtility.GetNearestPrefabInstanceRoot(obj);
|
||||
// UnityEditor.PrefabUtility.UnpackPrefabInstance(parent, UnityEditor.PrefabUnpackMode.Completely, UnityEditor.InteractionMode.AutomatedAction);
|
||||
// }
|
||||
// }
|
||||
// UnityEngine.Object.DestroyImmediate(obj);
|
||||
// }
|
||||
// else
|
||||
// UnityEngine.Object.Destroy(obj);
|
||||
// }
|
||||
//#endif
|
||||
//#endif
|
||||
|
||||
public static void SafeDestroy(UnityEngine.Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return;
|
||||
if (Application.isEditor && Application.isPlaying == false)
|
||||
UnityEngine.Object.DestroyImmediate(obj);
|
||||
else
|
||||
UnityEngine.Object.Destroy(obj);
|
||||
}
|
||||
internal static UIVertex CreateVertex(Vector3 pos, Vector2 uv)
|
||||
{
|
||||
return CreateVertex(pos, uv, pos.z);
|
||||
}
|
||||
|
||||
internal static UIVertex CreateVertex(Vector3 pos, Vector2 uv, float z)
|
||||
{
|
||||
UIVertex vert = new UIVertex();
|
||||
vert.color = Color.white;
|
||||
vert.uv0 = uv;
|
||||
pos.z = z;
|
||||
vert.position = pos;
|
||||
return vert;
|
||||
}
|
||||
|
||||
internal static float GetTiling(MaterialTiling tiling)
|
||||
{
|
||||
if (tiling.EnableTiling == false)
|
||||
return -1f;
|
||||
return tiling.TileFactor;
|
||||
}
|
||||
|
||||
internal static void FixBillboardText(ItemLabelsBase labels, BillboardText text)
|
||||
{
|
||||
float sharpness = Mathf.Clamp(labels.FontSharpness, 1f, 3f);
|
||||
ChartCommon.SetTextParams(text.UIText, null, labels.FontSize, sharpness);
|
||||
text.Scale = 1f / sharpness;
|
||||
text.UIText.transform.localScale = new Vector3(text.Scale, text.Scale);
|
||||
}
|
||||
|
||||
internal static T EnsureComponent<T>(GameObject obj) where T : Component
|
||||
{
|
||||
T comp = obj.GetComponent<T>();
|
||||
if (comp == null)
|
||||
comp = obj.AddComponent<T>();
|
||||
return comp;
|
||||
}
|
||||
|
||||
|
||||
static private float DotProduct(Vector2 a, Vector2 b, Vector2 c)
|
||||
{
|
||||
Vector2 ab = b - a;
|
||||
Vector2 bc = c - b;
|
||||
return Vector2.Dot(ab, bc);
|
||||
}
|
||||
|
||||
static private float CrossProduct(Vector2 a, Vector2 b, Vector2 c)
|
||||
{
|
||||
Vector2 ab = b - a;
|
||||
Vector2 ac = c - a;
|
||||
return ab.x * ac.y - ab.y * ac.x;
|
||||
}
|
||||
|
||||
static internal float SegmentPointSqrDistance(Vector2 a, Vector2 b, Vector2 point)
|
||||
{
|
||||
float dot = DotProduct(a, b, point);
|
||||
|
||||
if (dot > 0)
|
||||
return (b - point).sqrMagnitude;
|
||||
|
||||
dot = DotProduct(b, a, point);
|
||||
if (dot > 0)
|
||||
return (a - point).sqrMagnitude;
|
||||
|
||||
float cross = CrossProduct(a, b, point);
|
||||
return (cross * cross) / (a - b).sqrMagnitude;
|
||||
}
|
||||
|
||||
/* internal static BillboardText CreateBillboardText(Text prefab, Transform parentTransform, string text, float x, float y, float z, float angle, bool hideHirarechy, int fontSize, float sharpness)
|
||||
{
|
||||
return CreateBillboardText(prefab, parentTransform, text, x, y, z, angle, null, hideHirarechy, fontSize, sharpness);
|
||||
}*/
|
||||
|
||||
internal static BillboardText UpdateBillboardText(BillboardText billboardText, Transform parentTransform, string text, float x, float y, float z, float angle, Transform relativeFrom, bool hideHirarechy, bool yMirror)
|
||||
{
|
||||
GameObject UIText = billboardText.UIText.gameObject;
|
||||
GameObject billboard = billboardText.gameObject;
|
||||
ChartCommon.HideObject(billboard, hideHirarechy);
|
||||
TextDirection direction = UIText.GetComponent<TextDirection>();
|
||||
GameObject TextObj = billboardText.UIText;
|
||||
billboardText.YMirror = yMirror;
|
||||
if (direction != null)
|
||||
{
|
||||
TextObj = direction.Text.gameObject;
|
||||
if (relativeFrom != null)
|
||||
direction.SetRelativeTo(relativeFrom, billboard.transform);
|
||||
// else
|
||||
direction.SetDirection(angle);
|
||||
}
|
||||
// if (parentTransform != null && billboard.transform.parent != parentTransform)
|
||||
// {
|
||||
// billboard.transform.SetParent(parentTransform, false);
|
||||
// }
|
||||
UpdateTextParams(TextObj, text);
|
||||
billboard.transform.localPosition = new Vector3(x, y, z);
|
||||
return billboardText;
|
||||
}
|
||||
|
||||
internal static BillboardText CreateBillboardText(BillboardText item, MonoBehaviour prefab, Transform parentTransform, string text, float x, float y, float z, float angle, Transform relativeFrom, bool hideHirarechy, int fontSize, float sharpness)
|
||||
{
|
||||
if (item != null)
|
||||
return UpdateBillboardText(item, parentTransform, text, x, y, z, angle, relativeFrom, hideHirarechy, prefab != null && prefab.transform.localScale.y < 0);
|
||||
if (prefab == null || prefab.gameObject == null)
|
||||
{
|
||||
GameObject g = Resources.Load("Chart And Graph/DefaultText") as GameObject;
|
||||
prefab = g.GetComponent<Text>();
|
||||
}
|
||||
|
||||
GameObject UIText = (GameObject)GameObject.Instantiate(prefab.gameObject);
|
||||
GameObject billboard = new GameObject();
|
||||
ChartCommon.HideObject(billboard, hideHirarechy);
|
||||
if (parentTransform.GetComponent<RectTransform>())
|
||||
billboard.AddComponent<RectTransform>();
|
||||
|
||||
if (parentTransform != null)
|
||||
{
|
||||
billboard.transform.SetParent(parentTransform, false);
|
||||
UIText.transform.SetParent(parentTransform, false);
|
||||
}
|
||||
|
||||
BillboardText billboardText = billboard.AddComponent<BillboardText>();
|
||||
billboard.AddComponent<ChartItem>();
|
||||
TextDirection direction = UIText.GetComponent<TextDirection>();
|
||||
|
||||
GameObject obj = null;
|
||||
|
||||
if (direction != null)
|
||||
{
|
||||
obj = direction.Text.gameObject;
|
||||
if (relativeFrom != null)
|
||||
direction.SetRelativeTo(relativeFrom, billboard.transform);
|
||||
// else
|
||||
direction.SetDirection(angle);
|
||||
}
|
||||
|
||||
if (obj == null)
|
||||
obj = UIText;
|
||||
sharpness = Mathf.Clamp(sharpness, 1f, 3f);
|
||||
bool setParams = SetTextParams(obj, text, fontSize, sharpness);
|
||||
|
||||
if (billboardText == null || setParams == false)
|
||||
{
|
||||
SafeDestroy(UIText);
|
||||
SafeDestroy(billboard);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (prefab != null && prefab.transform.localScale.y < 0)
|
||||
billboardText.YMirror = true;
|
||||
billboardText.Scale = (1f / sharpness);
|
||||
billboardText.UIText = obj;
|
||||
billboardText.Direction = direction;
|
||||
if (direction != null)
|
||||
billboardText.RectTransformOverride = direction.GetComponent<RectTransform>();
|
||||
else
|
||||
billboardText.RectTransformOverride = null;
|
||||
billboard.transform.localPosition = new Vector3(x, y, z);
|
||||
return billboardText;
|
||||
}
|
||||
|
||||
static partial void DoTextSignInternal(MonoBehaviour Text, double sign);
|
||||
static partial void DoTextSignInternal3D(MonoBehaviour Text, double sign);
|
||||
|
||||
internal static void DoTextSign(MonoBehaviour Text, double sign)
|
||||
{
|
||||
DoTextSignInternal(Text, sign);
|
||||
DoTextSignInternal3D(Text, sign);
|
||||
}
|
||||
static partial void GetTextInternal(GameObject obj, ref string text);
|
||||
static partial void GetTextInternal3D(GameObject obj, ref string text);
|
||||
|
||||
|
||||
internal static string GetText(GameObject obj)
|
||||
{
|
||||
var t = obj.GetComponent<Text>();
|
||||
if (t != null)
|
||||
return t.text;
|
||||
string res = null;
|
||||
GetTextInternal(obj, ref res);
|
||||
if (res == null)
|
||||
GetTextInternal3D(obj, ref res);
|
||||
return res;
|
||||
|
||||
}
|
||||
static partial void UpdateTextParamsInternal(GameObject obj, string text);
|
||||
static partial void UpdateTextParamsInternal3D(GameObject obj, string text);
|
||||
|
||||
internal static void UpdateTextParams(GameObject obj, string text)
|
||||
{
|
||||
var t = obj.GetComponent<Text>();
|
||||
if (t != null)
|
||||
t.text = text;
|
||||
UpdateTextParamsInternal(obj, text);
|
||||
UpdateTextParamsInternal3D(obj, text);
|
||||
}
|
||||
|
||||
internal static void MakeMaskable(GameObject obj, bool masksable)
|
||||
{
|
||||
foreach (MaskableGraphic g in obj.GetComponents<MaskableGraphic>())
|
||||
g.maskable = masksable;
|
||||
}
|
||||
static partial void SetTextParamsInternal(GameObject obj, string text, int fontSize, float sharpness, ref bool res);
|
||||
static partial void SetTextParamsInternal3D(GameObject obj, string text, int fontSize, float sharpness, ref bool res);
|
||||
|
||||
internal static bool SetTextParams(GameObject obj, string text, int fontSize, float sharpness)
|
||||
{
|
||||
var t = obj.GetComponent<Text>();
|
||||
if (t != null)
|
||||
{
|
||||
t.fontSize = (int)(fontSize * sharpness);
|
||||
t.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||
t.verticalOverflow = VerticalWrapMode.Overflow;
|
||||
t.resizeTextForBestFit = false;
|
||||
if (text != null)
|
||||
t.text = text;
|
||||
return true;
|
||||
}
|
||||
bool res = false;
|
||||
SetTextParamsInternal(obj, text, fontSize, sharpness, ref res);
|
||||
if (res == false)
|
||||
SetTextParamsInternal3D(obj, text, fontSize, sharpness, ref res);
|
||||
if (res == false)
|
||||
Debug.LogError("Text prefab must be either UI.Text or TextMeshPro object. For text mesh pro , you need to import the support package first. worldSpace text meshpro can only be used with non canvas charts. Check out the following link for more info http://prosourcelabs.com/Tutorials/TextMeshPro/IntegratingTextMeshPro.html");
|
||||
return res;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static IEqualityComparer<int> DefaultIntComparer { get; private set; }
|
||||
public static IEqualityComparer<double> DefaultDoubleComparer { get; private set; }
|
||||
public static IEqualityComparer<DoubleVector3> DefaultDoubleVector3Comparer { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cc5db808d7e6a945966126025c774ab
|
||||
timeCreated: 1471942061
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5040ce9f4c3d8e84a89a86d289264c87
|
||||
folderAsset: yes
|
||||
timeCreated: 1502383500
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public class BaseScrollableCategoryData
|
||||
{
|
||||
public string Name;
|
||||
public bool Enabled = true;
|
||||
[HideInInspector]
|
||||
public int ViewOrder = -1;
|
||||
public double? MaxX, MaxY, MinX, MinY, MaxRadius;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c7006a05a5b1994088b734d33541efc
|
||||
timeCreated: 1502383500
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public abstract class BaseSlider
|
||||
{
|
||||
/// <summary>
|
||||
/// Duration of the sliding action
|
||||
/// </summary>
|
||||
public double Duration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Start time of the sliding action
|
||||
/// </summary>
|
||||
public double StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The bottom right edge of the slider bounding box (use for detemining automatic view size and position)
|
||||
/// </summary>
|
||||
public abstract DoubleVector2 Max { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The top left edge of the slider bounding box (use for detemining automatic view size and position)
|
||||
/// </summary>
|
||||
public abstract DoubleVector2 Min { get; }
|
||||
|
||||
public abstract string Category { get; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract int MinIndex { get; }
|
||||
/// <summary>
|
||||
/// returns true if the slider should be removed after this update. (meaning the slider is done)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool Update()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42de3f57996db6449a8ac05a372a94fa
|
||||
timeCreated: 1502395357
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public interface IChartData
|
||||
{
|
||||
void Update();
|
||||
void OnAfterDeserialize();
|
||||
void OnBeforeSerialize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 172dda9bf9c4051429ad0bb76be443d5
|
||||
timeCreated: 1502625145
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,439 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public abstract class ScrollableChartData : IChartData, IMixedSeriesProxy
|
||||
{
|
||||
protected List<BaseSlider> mSliders = new List<BaseSlider>();
|
||||
protected Dictionary<string, BaseScrollableCategoryData> mData = new Dictionary<string, BaseScrollableCategoryData>();
|
||||
|
||||
protected event EventHandler DataChanged;
|
||||
protected event EventHandler ViewPortionChanged;
|
||||
protected event Action<int,string> RealtimeDataChanged;
|
||||
|
||||
protected bool mSuspendEvents = false;
|
||||
|
||||
[SerializeField]
|
||||
private double automaticVerticalViewGap = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// call this to suspend chart redrawing while updating the data of the chart
|
||||
/// </summary>
|
||||
public void StartBatch()
|
||||
{
|
||||
mSuspendEvents = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// call this after StartBatch , this will apply all the changed made between the StartBatch call to this call
|
||||
/// </summary>
|
||||
public void EndBatch()
|
||||
{
|
||||
mSuspendEvents = false;
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// set this to true to automatically detect the horizontal size of the graph chart
|
||||
/// </summary>
|
||||
public double AutomaticVerticallViewGap
|
||||
{
|
||||
get { return automaticVerticalViewGap; }
|
||||
set
|
||||
{
|
||||
automaticVerticalViewGap = value;
|
||||
RestoreDataValues();
|
||||
RaiseViewPortionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// set this to true to automatically detect the horizontal size of the graph chart
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private bool automaticVerticallView = true;
|
||||
|
||||
/// <summary>
|
||||
/// set this to true to automatically detect the horizontal size of the graph chart
|
||||
/// </summary>
|
||||
public bool AutomaticVerticallView
|
||||
{
|
||||
get { return automaticVerticallView; }
|
||||
set
|
||||
{
|
||||
automaticVerticallView = value;
|
||||
RestoreDataValues();
|
||||
RaiseViewPortionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private double automaticcHorizontaViewGap = 0f;
|
||||
/// set this to true to automatically detect the horizontal size of the graph chart
|
||||
/// </summary>
|
||||
public double AutomaticcHorizontaViewGap
|
||||
{
|
||||
get { return automaticcHorizontaViewGap; }
|
||||
set
|
||||
{
|
||||
automaticcHorizontaViewGap = value;
|
||||
RestoreDataValues();
|
||||
RaiseViewPortionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// set this to true to automatically detect the horizontal size of the graph chart
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private bool automaticHorizontalView = true;
|
||||
|
||||
/// <summary>
|
||||
/// set this to true to automatically detect the horizontal size of the graph chart
|
||||
/// </summary>
|
||||
public bool AutomaticHorizontalView
|
||||
{
|
||||
get { return automaticHorizontalView; }
|
||||
set
|
||||
{
|
||||
automaticHorizontalView = value;
|
||||
RestoreDataValues();
|
||||
RaiseViewPortionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private double horizontalViewSize = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Mannualy set the horizontal view size.
|
||||
/// </summary>
|
||||
public double HorizontalViewSize
|
||||
{
|
||||
get { return horizontalViewSize; }
|
||||
set
|
||||
{
|
||||
horizontalViewSize = value;
|
||||
RaiseViewPortionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[SerializeField]
|
||||
private double horizontalViewOrigin = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Mannualy set the horizontal view origin.
|
||||
/// </summary>
|
||||
public double HorizontalViewOrigin
|
||||
{
|
||||
get { return horizontalViewOrigin; }
|
||||
set
|
||||
{
|
||||
horizontalViewOrigin = value;
|
||||
RaiseViewPortionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private double verticalViewSize = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Mannualy set the horizontal view size.
|
||||
/// </summary>
|
||||
public double VerticalViewSize
|
||||
{
|
||||
get { return verticalViewSize; }
|
||||
set
|
||||
{
|
||||
verticalViewSize = value;
|
||||
RaiseViewPortionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// clears all graph data
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
mSliders.Clear();
|
||||
mData.Clear();
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private double verticalViewOrigin = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Mannualy set the horizontal view origin.
|
||||
/// </summary>
|
||||
public double VerticalViewOrigin
|
||||
{
|
||||
get { return verticalViewOrigin; }
|
||||
set
|
||||
{
|
||||
verticalViewOrigin = value;
|
||||
RaiseViewPortionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// bool updated = mSliders.Count > 0;
|
||||
|
||||
mSliders.RemoveAll(x =>
|
||||
{
|
||||
bool res = x.Update();
|
||||
if(res == false)
|
||||
{
|
||||
RaiseRealtimeDataChanged(x.MinIndex,x.Category);
|
||||
}
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns true if the data contains a category by the given name
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <returns></returns>
|
||||
public bool HasCategory(string category)
|
||||
{
|
||||
return mData.ContainsKey(category);
|
||||
}
|
||||
|
||||
protected void ModifyMinMax(BaseScrollableCategoryData data, DoubleVector3 point)
|
||||
{
|
||||
if (data.MaxRadius.HasValue == false || data.MaxRadius.Value < point.z)
|
||||
data.MaxRadius = point.z;
|
||||
if (data.MaxX.HasValue == false || data.MaxX.Value < point.x)
|
||||
data.MaxX = point.x;
|
||||
if (data.MinX.HasValue == false || data.MinX.Value > point.x)
|
||||
data.MinX = point.x;
|
||||
if (data.MaxY.HasValue == false || data.MaxY.Value < point.y)
|
||||
data.MaxY = point.y;
|
||||
if (data.MinY.HasValue == false || data.MinY.Value > point.y)
|
||||
data.MinY = point.y;
|
||||
}
|
||||
|
||||
public virtual double GetMaxValue(int axis, bool dataValue)
|
||||
{
|
||||
if (dataValue == false)
|
||||
{
|
||||
if (axis == 0 && automaticHorizontalView == false)
|
||||
{
|
||||
double axisAdd = horizontalViewSize;
|
||||
if (Math.Abs(axisAdd) < 0.0001f)
|
||||
{
|
||||
if (axisAdd < 0)
|
||||
axisAdd = -0.0001f;
|
||||
else
|
||||
axisAdd = 0.0001f;
|
||||
}
|
||||
return HorizontalViewOrigin + axisAdd;
|
||||
}
|
||||
if (axis == 1 && AutomaticVerticallView == false)
|
||||
{
|
||||
double axisAdd = verticalViewSize;
|
||||
if (Math.Abs(axisAdd) < 0.0001f)
|
||||
{
|
||||
if (axisAdd < 0)
|
||||
axisAdd = -0.0001f;
|
||||
else
|
||||
axisAdd = 0.0001f;
|
||||
}
|
||||
return VerticalViewOrigin + axisAdd;
|
||||
}
|
||||
}
|
||||
double? res = null;
|
||||
double add = 0;
|
||||
foreach (BaseScrollableCategoryData cat in mData.Values)
|
||||
{
|
||||
if (cat.Enabled == false)
|
||||
continue;
|
||||
if (cat.MaxRadius.HasValue && add < cat.MaxRadius)
|
||||
add = cat.MaxRadius.Value;
|
||||
if (axis == 0)
|
||||
{
|
||||
if (res.HasValue == false || (cat.MaxX.HasValue && res.Value < cat.MaxX))
|
||||
res = cat.MaxX;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.HasValue == false || (cat.MaxY.HasValue && res.Value < cat.MaxY))
|
||||
res = cat.MaxY;
|
||||
}
|
||||
}
|
||||
for(int i=0; i<mSliders.Count; i++)
|
||||
{
|
||||
BaseSlider s = mSliders[i];
|
||||
if (axis == 0)
|
||||
res = ChartCommon.Max(res, s.Max.x);
|
||||
else
|
||||
res = ChartCommon.Max(res, s.Max.y);
|
||||
}
|
||||
if (res.HasValue == false)
|
||||
return 10f;
|
||||
double gap = (axis == 0) ? automaticcHorizontaViewGap : automaticVerticalViewGap;
|
||||
return res.Value + add + gap;
|
||||
}
|
||||
|
||||
public virtual double GetMinValue(int axis, bool dataValue)
|
||||
{
|
||||
if (dataValue == false)
|
||||
{
|
||||
if (axis == 0 && automaticHorizontalView == false)
|
||||
return horizontalViewOrigin;
|
||||
if (axis == 1 && AutomaticVerticallView == false)
|
||||
return verticalViewOrigin;
|
||||
}
|
||||
double? res = null;
|
||||
double add = 0f;
|
||||
|
||||
foreach (BaseScrollableCategoryData cat in mData.Values)
|
||||
{
|
||||
if (cat.Enabled == false)
|
||||
continue;
|
||||
if (cat.MaxRadius.HasValue && add < cat.MaxRadius)
|
||||
add = cat.MaxRadius.Value;
|
||||
|
||||
if (axis == 0)
|
||||
{
|
||||
if (res.HasValue == false || (cat.MinX.HasValue && res.Value > cat.MinX))
|
||||
res = cat.MinX;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.HasValue == false || (cat.MinY.HasValue && res.Value > cat.MinY))
|
||||
res = cat.MinY;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < mSliders.Count; i++)
|
||||
{
|
||||
BaseSlider s = mSliders[i];
|
||||
if (axis == 0)
|
||||
res = ChartCommon.Min(res, s.Max.x);
|
||||
else
|
||||
res = ChartCommon.Min(res, s.Max.y);
|
||||
}
|
||||
if (res.HasValue == false)
|
||||
return 0.0;
|
||||
double max = GetMaxValue(axis, dataValue);
|
||||
if (max == res.Value)
|
||||
{
|
||||
if (res.Value == 0.0)
|
||||
return -10.0f;
|
||||
return 0.0;
|
||||
}
|
||||
double gap = (axis == 0) ? automaticcHorizontaViewGap : automaticVerticalViewGap;
|
||||
return res.Value - add - gap;
|
||||
}
|
||||
|
||||
protected void RaiseRealtimeDataChanged(int index,string category)
|
||||
{
|
||||
if (mSuspendEvents)
|
||||
return;
|
||||
|
||||
if (RealtimeDataChanged != null)
|
||||
RealtimeDataChanged(index, category);
|
||||
}
|
||||
|
||||
protected void RaiseViewPortionChanged()
|
||||
{
|
||||
if (mSuspendEvents)
|
||||
return;
|
||||
if (ViewPortionChanged != null)
|
||||
ViewPortionChanged(this, EventArgs.Empty);
|
||||
}
|
||||
protected void RaiseDataChanged()
|
||||
{
|
||||
if (mSuspendEvents)
|
||||
return;
|
||||
if (DataChanged != null)
|
||||
DataChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void RestoreDataValues()
|
||||
{
|
||||
if (automaticHorizontalView)
|
||||
RestoreDataValues(0);
|
||||
if (AutomaticVerticallView)
|
||||
RestoreDataValues(1);
|
||||
}
|
||||
|
||||
void RestoreDataValues(int axis)
|
||||
{
|
||||
if (axis == 0)
|
||||
{
|
||||
double maxH = GetMaxValue(0, true);
|
||||
double minH = GetMinValue(0, true);
|
||||
horizontalViewOrigin = minH;
|
||||
horizontalViewSize = maxH - minH;
|
||||
}
|
||||
else
|
||||
{
|
||||
double maxV = GetMaxValue(1, true);
|
||||
double minV = GetMinValue(1, true);
|
||||
verticalViewOrigin = minV;
|
||||
verticalViewSize = maxV - minV;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// clears the specified category from any data
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
protected abstract void InnerClearCategory(string category);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new category based on a BaseScrollableCategoryData object
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract bool AddCategory(string category, BaseScrollableCategoryData data);
|
||||
|
||||
protected abstract void AppendDatum(string category, MixedSeriesGenericValue value);
|
||||
protected abstract void AppendDatum(string category, IList<MixedSeriesGenericValue> value);
|
||||
|
||||
/// <summary>
|
||||
/// instanciates a new category object with default settings. returns nulls if not supported
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract BaseScrollableCategoryData GetDefaultCategory();
|
||||
public abstract void OnAfterDeserialize();
|
||||
public abstract void OnBeforeSerialize();
|
||||
|
||||
bool IMixedSeriesProxy.AddCategory(string category, BaseScrollableCategoryData data)
|
||||
{
|
||||
return AddCategory(category, data);
|
||||
}
|
||||
|
||||
bool IMixedSeriesProxy.HasCategory(string catgeory)
|
||||
{
|
||||
return mData.ContainsKey(catgeory);
|
||||
}
|
||||
|
||||
void IMixedSeriesProxy.ClearCategory(string category)
|
||||
{
|
||||
InnerClearCategory(category);
|
||||
}
|
||||
|
||||
void IMixedSeriesProxy.AppendDatum(string category, MixedSeriesGenericValue value)
|
||||
{
|
||||
AppendDatum(category, value);
|
||||
}
|
||||
|
||||
void IMixedSeriesProxy.AppendDatum(string category, IList<MixedSeriesGenericValue> value)
|
||||
{
|
||||
AppendDatum(category, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5927a12575fbc674fbf41f96a09b70cc
|
||||
timeCreated: 1502383500
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,54 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// holds date values
|
||||
/// </summary>
|
||||
class ChartDateUtility
|
||||
{
|
||||
private static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
|
||||
|
||||
public static double TimeSpanToValue(TimeSpan span)
|
||||
{
|
||||
return span.TotalSeconds;
|
||||
}
|
||||
public static double DateToValue(DateTime dateTime)
|
||||
{
|
||||
return (dateTime - Epoch).TotalSeconds;
|
||||
}
|
||||
|
||||
public static string DateToTimeString(DateTime dateTime)
|
||||
{
|
||||
return dateTime.ToString("t");
|
||||
}
|
||||
|
||||
public static string DateToDateString(DateTime dateTime)
|
||||
{
|
||||
return dateTime.ToString("d");
|
||||
}
|
||||
public static string DateToDateTimeString(DateTime dateTime,string customFormat)
|
||||
{
|
||||
if(customFormat != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return dateTime.ToString(customFormat);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
return string.Format("{0}{1}{2}", dateTime.ToString("d"), Environment.NewLine, dateTime.ToString("t"));
|
||||
}
|
||||
public static DateTime ValueToDate(double value)
|
||||
{
|
||||
return Epoch.AddSeconds(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee78c6f50add7864f9d2c2730c975416
|
||||
timeCreated: 1480864086
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
public enum ChartDivisionAligment
|
||||
{
|
||||
/// <summary>
|
||||
/// left for vertical axis and top for horizontal axis
|
||||
/// </summary>
|
||||
Standard = 1,
|
||||
/// <summary>
|
||||
/// right for vertical axis and bottom for horizontal axis
|
||||
/// </summary>
|
||||
Opposite = 2,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e64f0c7a130aa441a75309e27ca5398
|
||||
timeCreated: 1473344127
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains diffrent mateirals for different gui events
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ChartDynamicMaterial
|
||||
{
|
||||
public ChartDynamicMaterial()
|
||||
:this(null,Color.clear,Color.clear)
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// creates a new dynamic material
|
||||
/// </summary>
|
||||
/// <param name="normal">the default material</param>
|
||||
public ChartDynamicMaterial(Material normal)
|
||||
:this(normal, Color.clear, Color.clear)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="normal">the default material</param>
|
||||
/// <param name="hover">the material of the mouse hover event</param>
|
||||
/// <param name="selected">the material of the mouse click event </param>
|
||||
public ChartDynamicMaterial(Material normal,Color hover, Color selected)
|
||||
{
|
||||
Normal = normal;
|
||||
Hover = hover;
|
||||
Selected = selected;
|
||||
}
|
||||
|
||||
public Material Normal;
|
||||
public Color Hover;
|
||||
public Color Selected;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7ba70921175f234f8842dcefb39cb6d
|
||||
timeCreated: 1471948670
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 056217c93a043134d95085112cf37489
|
||||
folderAsset: yes
|
||||
timeCreated: 1478280231
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,91 @@
|
||||
#define Graph_And_Chart_PRO
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ChartAndGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// manages all the chart effect for a chart item. This includes scale translation and rotation effects
|
||||
/// </summary>
|
||||
public class CharItemEffectController : MonoBehaviour
|
||||
{
|
||||
List<ChartItemEffect> mEffects = new List<ChartItemEffect>();
|
||||
Transform mParent;
|
||||
internal bool WorkOnParent { get; set; }
|
||||
internal bool InitialScale { get; set; }
|
||||
Vector3 mInitialScale;
|
||||
protected Transform Parent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mParent == null)
|
||||
mParent = transform.parent;
|
||||
return mParent;
|
||||
}
|
||||
}
|
||||
public CharItemEffectController()
|
||||
{
|
||||
InitialScale = true;
|
||||
}
|
||||
void Start()
|
||||
{
|
||||
mInitialScale = transform.localScale;
|
||||
}
|
||||
void OnTransformParentChanged()
|
||||
{
|
||||
mInitialScale = transform.localScale;
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
Transform trans = transform;
|
||||
if (WorkOnParent)
|
||||
{
|
||||
trans = Parent;
|
||||
if (trans == null)
|
||||
return;
|
||||
}
|
||||
Vector3 scale = new Vector3(1f,1f,1f);
|
||||
if (InitialScale)
|
||||
scale = mInitialScale;
|
||||
Vector3 translation = Vector3.zero;
|
||||
Quaternion rotation = Quaternion.identity;
|
||||
|
||||
for (int i=0; i<mEffects.Count; i++)
|
||||
{
|
||||
ChartItemEffect effect = mEffects[i];
|
||||
if (effect == null || effect.gameObject == null)
|
||||
{
|
||||
mEffects.RemoveAt(i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
scale.x *= effect.ScaleMultiplier.x;
|
||||
scale.y *= effect.ScaleMultiplier.y;
|
||||
scale.z *= effect.ScaleMultiplier.z;
|
||||
|
||||
translation += effect.Translation;
|
||||
rotation *= effect.Rotation;
|
||||
}
|
||||
trans.localScale = scale;
|
||||
}
|
||||
|
||||
public void Unregister(ChartItemEffect effect)
|
||||
{
|
||||
mEffects.Remove(effect);
|
||||
if(mEffects.Count == 0)
|
||||
enabled = false;
|
||||
}
|
||||
public void Register(ChartItemEffect effect)
|
||||
{
|
||||
if (mEffects.Contains(effect))
|
||||
return;
|
||||
if (enabled == false)
|
||||
enabled = true;
|
||||
mEffects.Add(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d991d151f2c9184aa1f2b9cc6106d32
|
||||
timeCreated: 1478280231
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loaded 100 of 2374 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user