808 lines
38 KiB
C#
808 lines
38 KiB
C#
#define Graph_And_Chart_PRO
|
|
using System;
|
|
using System.Collections;
|
|
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();
|
|
}
|
|
}
|
|
[SerializeField]
|
|
[Tooltip("")]
|
|
private bool withEdges2 = true;
|
|
public bool WithEdges
|
|
{
|
|
get { return withEdges2; }
|
|
set
|
|
{
|
|
withEdges2 = 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 double 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;
|
|
}
|
|
class DivisionEnumerable : IEnumerable
|
|
{
|
|
double mStartValue, mFraction, mDirection, mGap, mEndValue;
|
|
bool mWithSides;
|
|
public DivisionEnumerable(double startValue, double fraction, double direction,double gap,double endValue,bool withSides)
|
|
{
|
|
mStartValue = startValue;
|
|
mFraction = fraction;
|
|
mDirection = direction;
|
|
mGap = gap;
|
|
mEndValue = endValue;
|
|
mWithSides = withSides;
|
|
}
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
double startRange = mStartValue + mFraction;
|
|
if(Math.Abs(mFraction) <0.001f && mWithSides)
|
|
yield return mStartValue;
|
|
for (double current = startRange; mDirection * current < mDirection * mEndValue; current += mGap * mDirection)
|
|
yield return current;
|
|
if(mWithSides)
|
|
yield return mDirection * mEndValue;
|
|
}
|
|
}
|
|
private void DrawCustomDivisions(double scrollOffset, AnyChart parent, Transform parentTransform, ChartDivisionInfo info, IChartMesh mesh, int group, ChartOrientation orientation, bool oppositeSide,bool subDivision = false)
|
|
{
|
|
//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;
|
|
}
|
|
|
|
mTmpToRemove.Clear();
|
|
foreach (double key in mFormats.Keys)
|
|
{
|
|
if (key * direction > endValue * direction || key * direction < startValue * direction)
|
|
mTmpToRemove.Add(key);
|
|
}
|
|
for (int k = 0; k < mTmpToRemove.Count; k++)
|
|
mFormats.Remove(mTmpToRemove[k]);
|
|
HashSet<double> customValues = (orientation == ChartOrientation.Vertical) ? ((IInternalUse)parent).VerticalCustomAxis : ((IInternalUse)parent).HorizontalCustomAxis;
|
|
if(subDivision)
|
|
customValues = (orientation == ChartOrientation.Vertical) ? ((IInternalUse)parent).VerticalCustomAxisSubDivision : ((IInternalUse)parent).HorizontalCustomAxisSubDivision;
|
|
foreach (double current in customValues)
|
|
{
|
|
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 = (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));
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
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]);
|
|
|
|
foreach (double current in new DivisionEnumerable(startValue,fraction,direction,gap,endValue, WithEdges))
|
|
{
|
|
++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*0.5f;
|
|
//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*10000000.0)/ 10000000.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.0000001 && 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;
|
|
textPos += halfThickness * 0.5f;
|
|
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);
|
|
}
|
|
internal void AddCustomDivisionsToChartMesh(double scrollOffset, AnyChart parent, Transform parentTransform, IChartMesh mesh, ChartOrientation orientation,bool isSub)
|
|
{
|
|
double maxValue = ((IInternalUse)parent).InternalMaxValue(this);
|
|
double minValue = ((IInternalUse)parent).InternalMinValue(this);
|
|
double range = maxValue - minValue;
|
|
if (isSub)
|
|
{
|
|
mesh.Tile = ChartCommon.GetTiling(SubDivisions.MaterialTiling);
|
|
if ((SubDivisions.Alignment & ChartDivisionAligment.Opposite) == ChartDivisionAligment.Opposite)
|
|
DrawCustomDivisions(scrollOffset, parent, parentTransform, SubDivisions, mesh, 0, orientation, false, true);
|
|
if ((SubDivisions.Alignment & ChartDivisionAligment.Standard) == ChartDivisionAligment.Standard)
|
|
DrawCustomDivisions(scrollOffset, parent, parentTransform, SubDivisions, mesh, 0, orientation, true, true);
|
|
}
|
|
else
|
|
{
|
|
mesh.Tile = ChartCommon.GetTiling(MainDivisions.MaterialTiling);
|
|
if ((MainDivisions.Alignment & ChartDivisionAligment.Opposite) == ChartDivisionAligment.Opposite)
|
|
DrawCustomDivisions(scrollOffset, parent, parentTransform, MainDivisions, mesh, 0, orientation, false, false);
|
|
if ((MainDivisions.Alignment & ChartDivisionAligment.Standard) == ChartDivisionAligment.Standard)
|
|
DrawCustomDivisions(scrollOffset, parent, parentTransform, MainDivisions, mesh, 0, orientation, true, false);
|
|
}
|
|
|
|
}
|
|
/// <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();
|
|
}
|
|
}
|
|
}
|