graph chart引入&骑行结果弹窗

This commit is contained in:
lishuo committed 2021-04-22 19:29:59 +08:00
1 parent 40d118cea3
commit 96f3644b5b
2374 files changed
+485161 -2410

No files matched your search

@@ -0,0 +1,14 @@
#define Graph_And_Chart_PRO
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChartAndGraph
{
interface IInternalPyramidData
{
ChartSparseDataSource InternalDataSource { get; }
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 369d1c0e7b4b9fc498252bc1ed05b04c
timeCreated: 1579445919
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
{
public interface IPyramidGenerator
{
GameObject ContainerObject { get; }
void SetParams(float baseX1, float baseX2, float baseSize, float slopLeft, float slopeRight, float height,float inset,float startV,float endV);
Vector3 GetTextPosition(PyramidChart.JustificationType justification,bool isBase);
void GetUpperBase(out float baseX1, out float baseX2);
void Generate();
void ApplyInfo(string title, string text, Sprite image, float scale);
void SetAlpha(float alpha);
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2a1189b51e201054181a7018cd594f6c
timeCreated: 1579168376
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,42 @@
#define Graph_And_Chart_PRO
using UnityEngine;
using System.Collections;
using ChartAndGraph;
public class PyramidAnimation : MonoBehaviour {
public AnimationCurve Curve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
public bool AnimateOnStart = true;
public float AnimationTime = 3f;
float animationStart = -1f;
PyramidChart chart;
// Use this for initialization
void Start () {
chart = GetComponent<PyramidChart>();
if (AnimateOnStart)
Animate();
}
public void Animate()
{
animationStart = Time.time;
}
// Update is called once per frame
void Update ()
{
if (chart == null)
return;
if (animationStart < 0f)
return;
float elasped = (Time.time - animationStart) / AnimationTime;
elasped = Mathf.Clamp(elasped, 0f, 1f);
float blend = Curve.Evaluate(elasped);
for(int i=0; i<chart.DataSource.TotalCategories; i++)
{
string name = chart.DataSource.GetCategoryName(i);
chart.DataSource.SetCategoryAlpha(name, blend);
chart.DataSource.SetCategoryOrientation(name, blend, 0f, 0f);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3f8e5b63d2caba14993994657aeb9d90
timeCreated: 1579516412
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,202 @@
#define Graph_And_Chart_PRO
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
namespace ChartAndGraph
{
[Serializable]
public class PyramidCanvasGenerator : MaskableGraphic, IPyramidGenerator
{
public RectTransform Container;
public Text Title;
public Text Info;
public Image Sprite;
bool mPopulated = false;
float mBaseX1;
float mBaseX2;
float mBaseSize;
float mSlopLeft;
float mSlopeRight;
float mHeight;
float mInset;
float mStartV;
float mEndV;
CanvasGroup mGroup;
UIVertex[] vertices = new UIVertex[4];
Vector2[] normals = new Vector2[4];
protected override void Start()
{
base.Start();
mGroup = ChartCommon.EnsureComponent<CanvasGroup>(gameObject);
}
public GameObject ContainerObject {
get {
if (Container == null)
return null;
return Container.gameObject;
}
}
public void SetAlpha(float alpha)
{
if(mGroup != null)
mGroup.alpha = alpha;
}
public override Texture mainTexture
{
get { return material.mainTexture; }
}
public void ApplyInfo(string title, string text, Sprite image,float scale)
{
if(Container != null)
{
Vector3 centtroid = vertices[0].position + vertices[1].position + vertices[2].position + vertices[3].position;
centtroid *= 0.25f;
float upperSize = Math.Abs(vertices[2].position.x - vertices[3].position.x);
float downSize = Math.Abs(vertices[0].position.x - vertices[1].position.x);
float total = upperSize + downSize;
float weight = (downSize - upperSize) / total;
weight = -weight * 0.5f + 0.5f;
weight = Mathf.Lerp(0.3f, 0.7f, weight);
centtroid.y = Mathf.Lerp(vertices[0].position.y, vertices[2].position.y, weight);
centtroid = new Vector3(centtroid.x / rectTransform.rect.width, centtroid.y / rectTransform.rect.height);
centtroid += new Vector3(0.5f, 0.5f, 0f);
Container.anchorMax = centtroid;
Container.anchorMin = centtroid;
Container.anchoredPosition = new Vector2();
Container.sizeDelta = new Vector2(Mathf.Abs(mBaseX1 - mBaseX2) - mInset*4, mHeight - mInset*2);
Container.localScale = new Vector3(scale, scale, scale);
}
if (Title != null)
Title.text = title;
if (Info != null)
Info.text = text;
if (Sprite != null)
Sprite.sprite = image;
}
public void Generate()
{
SetAllDirty();
Rebuild(CanvasUpdate.PreRender);
}
public Vector3 GetTextPosition(PyramidChart.JustificationType justification, bool isBase)
{
Vector3 res = new Vector3();
switch(justification)
{
case PyramidChart.JustificationType.LeftAligned:
if (isBase)
res = vertices[0].position;
else
res = (vertices[0].position + vertices[2].position) * 0.5f;
break;
case PyramidChart.JustificationType.RightAligned:
if (isBase)
res = vertices[1].position;
else
res = (vertices[1].position + vertices[3].position) * 0.5f;
break;
case PyramidChart.JustificationType.CenterAligned:
if (isBase)
res = (vertices[0].position + vertices[1].position) * 0.5f;
else
res = (vertices[0].position + vertices[1].position +vertices[2].position + vertices[3].position) * 0.25f;
break;
}
return res;
}
public void GetUpperBase(out float baseX1, out float baseX2)
{
baseX1 = vertices[2].position.x + mBaseSize * 0.5f;
baseX2 = vertices[3].position.x + mBaseSize * 0.5f;
}
public void SetParams(float baseX1, float baseX2, float baseSize, float slopLeft, float slopeRight, float height, float inset, float startV, float endV)
{
mPopulated = true;
mBaseX1 = baseX1;
mBaseX2 = baseX2;
mBaseSize = baseSize;
mSlopLeft = slopLeft;
mSlopeRight = slopeRight;
mHeight = height;
mInset = inset;
mStartV = startV;
mEndV = endV;
PyramidMesh.Generate2dMesh(vertices, normals, mBaseX1, mBaseX2, mBaseSize, mSlopLeft, mSlopeRight, mHeight,mStartV,mEndV);
}
#pragma warning disable 0672
protected override void OnFillVBO(List<UIVertex> vbo)
{
vbo.Clear();
if (mPopulated == false)
return;
CanvasChartMesh mesh = new CanvasChartMesh(vbo);
FillChartMesh(mesh);
}
#pragma warning restore 0672
#if (!UNITY_5_2_0) && (!UNITY_5_2_1)
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
if (mPopulated == false)
return;
CanvasChartMesh mesh = new CanvasChartMesh(vh);
FillChartMesh(mesh);
}
#endif
#pragma warning disable 0672
#if !UNITY_2017_1_OR_NEWER
protected override void OnPopulateMesh(Mesh m)
{
m.Clear();
if (mPopulated == false)
return;
WorldSpaceChartMesh chartmesh = new WorldSpaceChartMesh(true);
FillChartMesh(chartmesh);
chartmesh.ApplyToMesh(m);
}
#endif
#pragma warning restore 0672
void FillChartMesh(IChartMesh mesh)
{
UIVertex v1 = vertices[0];
UIVertex v2 = vertices[1];
UIVertex v3 = vertices[2];
UIVertex v4 = vertices[3];
v1.position += (Vector3)(normals[0] * mInset);
v2.position += (Vector3)(normals[1] * mInset);
v3.position += (Vector3)(normals[2] * mInset);
v4.position += (Vector3)(normals[3] * mInset);
Vector2 inter;
if(ChartCommon.SegmentIntersection(v1.position,v3.position,v2.position,v4.position,out inter))
{
v3.position = inter;
v4.position = inter;
}
mesh.AddQuad(v1, v2, v3, v4);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7b2cb334c0c0a6448971702fcddbfecd
timeCreated: 1579182822
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,639 @@
#define Graph_And_Chart_PRO
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace ChartAndGraph
{
/// <summary>
/// Pie chart class
/// </summary>
[ExecuteInEditMode]
[Serializable]
public class PyramidChart : AnyChart
{
public class PyramidEventArgs
{
public PyramidEventArgs(string category, string title,string text)
{
Title = title;
Text = text;
Category = category;
}
public string Category { get; private set; }
public string Title { get; private set; }
public string Text { get; private set; }
}
public enum JustificationType
{
LeftAligned,
RightAligned,
CenterAligned
}
public enum SlopeType
{
Center,
Left,
Right,
Custom
}
bool mQuick = false;
[Serializable]
public class PyramidEvent : UnityEvent<PyramidEventArgs>
{
}
/// <summary>
/// occures when a pie item is clicked
/// </summary>
public PyramidEvent ItemClicked = new PyramidEvent();
/// <summary>
/// occures when a pie item is hovered
/// </summary>
public PyramidEvent ItemHovered = new PyramidEvent();
/// <summary>
/// occurs when no pie is hovered any longer
/// </summary>
public UnityEvent NonHovered = new UnityEvent();
[SerializeField]
[Tooltip("The material of the back of the pyramid")]
public Material backMaterial;
/// <summary>
/// The inset of each pyramid component
/// </summary>
public Material BackMaterial
{
get { return backMaterial; }
set
{
backMaterial = value;
OnPropertyUpdated();
}
}
[SerializeField]
[Tooltip("The inset of each pyramid component")]
public float inset;
/// <summary>
/// The inset of each pyramid component
/// </summary>
public float Inset
{
get { return inset; }
set
{
inset = value;
OnPropertyUpdated();
}
}
[SerializeField]
[Tooltip("the text justification of the pyramid chart")]
private JustificationType justification;
/// <summary>
/// the text justification of the pyramid chart
/// </summary>
public JustificationType Justification
{
get { return justification; }
set
{
justification = value;
OnPropertyUpdated();
}
}
[SerializeField]
[Tooltip("the slope type of the pyramid")]
public SlopeType slope;
/// <summary>
/// prefab for the pie item. must contain a PieCanvasGenerator component
/// </summary>
public SlopeType Slope
{
get { return slope; }
set
{
slope = value;
OnPropertyUpdated();
}
}
[SerializeField]
[Tooltip("prefab for the pyramid item. must contain a PyramidCanvasGenerator component")]
private PyramidCanvasGenerator prefab;
/// <summary>
/// prefab for the pie item. must contain a PieCanvasGenerator component
/// </summary>
public PyramidCanvasGenerator Prefab
{
get { return prefab; }
set
{
prefab = value;
OnPropertyUpdated();
}
}
[HideInInspector]
[SerializeField]
private PyramidData Data = new PyramidData();
float totalWidth, totalHeight;
protected override IChartData DataLink
{
get
{
return Data;
}
}
public PyramidData DataSource
{
get { return Data; }
}
public override bool SupportRealtimeGeneration
{
get
{
return false;
}
}
protected override LegenedData LegendInfo
{
get
{
LegenedData legend = new LegenedData();
if (Data == null)
return legend;
foreach (var column in ((IInternalPyramidData)Data).InternalDataSource.Columns)
{
var item = new LegenedData.LegenedItem();
item.Name = column.Name;
if (column.Material != null)
item.Material = column.Material.Normal;
else
item.Material = null;
legend.AddLegenedItem(item);
}
return legend;
}
}
public PyramidChart()
{
}
public class PyramidObject
{
public string category;
public GameObject pyramidObject;
public GameObject backObject;
public IPyramidGenerator Generator;
public IPyramidGenerator BackGenerator;
public string Title, Text;
public BillboardText ItemLabel;
}
Dictionary<string, PyramidObject> mPyramids = new Dictionary<string, PyramidObject>();
void HookEvents()
{
Data.ProperyUpdated -= Data_ProperyUpdated;
Data.ProperyUpdated += Data_ProperyUpdated;
Data.RealtimeProperyUpdated -= Data_RealtimeProperyUpdated;
Data.RealtimeProperyUpdated += Data_RealtimeProperyUpdated;
((IInternalPyramidData)Data).InternalDataSource.DataStructureChanged -= MDataSource_DataStructureChanged;
((IInternalPyramidData)Data).InternalDataSource.DataStructureChanged += MDataSource_DataStructureChanged;
((IInternalPyramidData)Data).InternalDataSource.DataValueChanged -= MDataSource_DataValueChanged;
((IInternalPyramidData)Data).InternalDataSource.DataValueChanged += MDataSource_DataValueChanged;
}
private void Data_RealtimeProperyUpdated()
{
QuickInvalidate();
}
private void Data_ProperyUpdated()
{
Invalidate();
}
protected void QuickInvalidate()
{
if (Invalidating)
return;
Invalidate();
mQuick = true;
}
public override void Invalidate()
{
base.Invalidate();
mQuick = false;
}
private void MDataSource_DataValueChanged(object sender, DataSource.ChartDataSourceBase.DataValueChangedEventArgs e)
{
QuickInvalidate();
}
private void MDataSource_DataStructureChanged(object sender, EventArgs e)
{
Invalidate();
}
protected override void Start()
{
base.Start();
if (ChartCommon.IsInEditMode == false)
{
HookEvents();
}
Invalidate();
}
protected override void OnValidate()
{
base.OnValidate();
if (Application.isPlaying)
{
HookEvents();
}
Invalidate();
}
protected override void ClearChart()
{
base.ClearChart();
mPyramids.Clear();
}
Vector3 AlignTextPosition(AlignedItemLabels labels, PyramidObject obj, IPyramidGenerator generator,float height)
{
Vector3 position = new Vector3(labels.Location.Breadth, labels.Seperation, labels.Location.Depth);
position.y += height;
position = generator.GetTextPosition(justification, labels.Alignment == ChartLabelAlignment.Base);
return position;
}
protected IPyramidGenerator PreparePyramidObject(out GameObject pyramidObject)
{
if (Prefab == null)
pyramidObject = new GameObject();
else
pyramidObject = GameObject.Instantiate(Prefab.gameObject);
ChartCommon.EnsureComponent<RectTransform>(pyramidObject);
ChartCommon.EnsureComponent<CanvasRenderer>(pyramidObject);
return ChartCommon.EnsureComponent<PyramidCanvasGenerator>(pyramidObject);
}
private void GeneratePyramid(bool update)
{
if (update == false)
ClearChart();
else
EnsureTextController();
if (((IInternalPyramidData)Data).InternalDataSource == null)
return;
double[,] data = ((IInternalPyramidData)Data).InternalDataSource.getRawData();
int rowCount = data.GetLength(0);
int columnCount = data.GetLength(1);
if (rowCount != 1) // row count for pie must be 1
return;
double total = 0.0;
for (int i = 0; i < columnCount; ++i)
{
double val = Math.Max(data[0, i], 0);
total += val;
}
var rectTrans = GetComponent<RectTransform>();
totalHeight = rectTrans.rect.height;
totalWidth = rectTrans.rect.width;
float baseX1 = 0;
float baseX2 = totalWidth;
float accumilatedHeight = 0;
float? firstCenterHeight = null;
float acummilatedWeight = 0;
for (int i = 0; i < columnCount; ++i)
{
object userData = ((IInternalPyramidData)Data).InternalDataSource.Columns[i].UserData;
var categoryData = ((PyramidData.CategoryData)userData);
string name = ((IInternalPyramidData)Data).InternalDataSource.Columns[i].Name;
double amount = Math.Max(data[0, i], 0);
if (amount == 0f)
continue;
float weight = (float)(amount / total);
float actualHeight = totalHeight * weight;
float slopeRight = categoryData.RightSlope;
float slopeLeft = categoryData.LeftSlope;
float atan;
switch(slope)
{
case SlopeType.Center:
atan = -Mathf.Atan2(totalHeight, totalWidth * 0.5f) * Mathf.Rad2Deg +90;
slopeRight = atan;
slopeLeft = atan;
break;
case SlopeType.Left:
atan = -Mathf.Atan2(totalHeight, totalWidth) * Mathf.Rad2Deg + 90;
slopeLeft = 0;
slopeRight = atan;
break;
case SlopeType.Right:
atan = -Mathf.Atan2(totalHeight, totalWidth) * Mathf.Rad2Deg + 90;
slopeLeft = atan;
slopeRight = 0;
break;
default:
break;
}
GameObject pyramidObject = null;
GameObject pyramidBackObject = null;
IPyramidGenerator generator = null;
IPyramidGenerator backgenerator = null;
PyramidObject dataObject;
float centerHeight = actualHeight * 0.5f + accumilatedHeight;
float unblendedHeight = centerHeight;
if (firstCenterHeight.HasValue == false)
firstCenterHeight = centerHeight;
centerHeight = Mathf.Lerp(firstCenterHeight.Value, centerHeight, categoryData.PositionBlend);
if (mPyramids.TryGetValue(name, out dataObject))
{
pyramidBackObject = dataObject.backObject;
pyramidObject = dataObject.pyramidObject;
backgenerator = dataObject.BackGenerator;
generator = dataObject.Generator;
generator.SetParams(baseX1, baseX2, totalWidth, slopeLeft, slopeRight, actualHeight,inset,0f,1f);
if (backgenerator !=null)
backgenerator.SetParams(baseX1, baseX2, totalWidth, slopeLeft, slopeRight, actualHeight, 0f, acummilatedWeight, acummilatedWeight + weight);
if (dataObject.ItemLabel)
{
Vector3 labelPos = AlignTextPosition(mItemLabels, dataObject,generator, centerHeight);
dataObject.ItemLabel.transform.localPosition = labelPos;
ChartCommon.UpdateTextParams(dataObject.ItemLabel.UIText, categoryData.Title);
}
}
else
{
dataObject = new PyramidObject();
if (backMaterial != null)
{
var backGenerator = PreparePyramidObject(out pyramidBackObject);
backGenerator.SetParams(baseX1, baseX2, totalWidth, slopeLeft, slopeRight, actualHeight, 0f, acummilatedWeight, acummilatedWeight +weight);
dataObject.backObject = pyramidBackObject;
dataObject.BackGenerator = backGenerator;
ChartCommon.HideObject(pyramidBackObject, hideHierarchy);
pyramidBackObject.transform.SetParent(transform,false);
ChartCommon.EnsureComponent<ChartItem>(pyramidBackObject);
ChartMaterialController backcontrol = ChartCommon.EnsureComponent<ChartMaterialController>(pyramidBackObject);
backcontrol.Materials = new ChartDynamicMaterial(backMaterial);
foreach(var itemEffect in pyramidBackObject.GetComponents<ChartItemEffect>())
ChartCommon.SafeDestroy(itemEffect);
ChartCommon.SafeDestroy(backGenerator.ContainerObject);
}
generator = PreparePyramidObject(out pyramidObject);
generator.SetParams(baseX1, baseX2, totalWidth, slopeLeft, slopeRight, actualHeight, inset,0f,1f);
ChartCommon.HideObject(pyramidObject, hideHierarchy);
pyramidObject.transform.SetParent(transform,false);
ChartCommon.EnsureComponent<ChartItem>(pyramidObject);
ChartMaterialController control = ChartCommon.EnsureComponent<ChartMaterialController>(pyramidObject);
control.Materials = Data.GetMaterial(name);
control.Refresh();
dataObject.Generator = generator;
dataObject.category = name;
dataObject.pyramidObject = pyramidObject;
mPyramids.Add(name, dataObject);
CharItemEffectController effect = ChartCommon.EnsureComponent<CharItemEffectController>(pyramidObject);
effect.WorkOnParent = false;
effect.InitialScale = false;
ChartItemEvents[] events = pyramidObject.GetComponentsInChildren<ChartItemEvents>();
for (int j = 0; j < events.Length; ++j)
{
if (events[j] == null)
continue;
InternalItemEvents comp = (InternalItemEvents)events[j];
comp.Parent = this;
comp.UserData = dataObject;
}
if (mItemLabels != null)
{
Vector3 labelPos = AlignTextPosition(mItemLabels, dataObject, generator, 0f);
float angle = justification == JustificationType.LeftAligned ? -180f : 180f;
BillboardText billboard = ChartCommon.CreateBillboardText(null, mItemLabels.TextPrefab, dataObject.pyramidObject.transform, categoryData.Title, labelPos.x, labelPos.y, labelPos.z, angle, null, hideHierarchy, mItemLabels.FontSize, mItemLabels.FontSharpness);
dataObject.ItemLabel = billboard;
dataObject.ItemLabel.transform.localPosition = labelPos;
TextController.AddText(billboard);
}
}
dataObject.Text = categoryData.Text;
dataObject.Title = categoryData.Title;
if (IsCanvas)
{
if (pyramidObject != null)
{
Vector2 actualPosition = new Vector2(0.5f, centerHeight) + categoryData.Shift;
actualPosition = new Vector2(actualPosition.x , actualPosition.y / TotalHeight);
var objectRect = pyramidObject.GetComponent<RectTransform>();
objectRect.pivot = new Vector2(0.5f, 0.5f);
objectRect.anchorMin = actualPosition;
objectRect.anchorMax = actualPosition;
objectRect.anchoredPosition = new Vector2();
objectRect.sizeDelta = new Vector2(totalWidth, actualHeight);
}
if(pyramidBackObject != null)
{
Vector2 actualPosition = new Vector2(0.5f, unblendedHeight);
actualPosition = new Vector2(actualPosition.x, actualPosition.y / TotalHeight);
var objectRect = pyramidBackObject.GetComponent<RectTransform>();
objectRect.pivot = new Vector2(0f, 0f);
objectRect.anchorMin = actualPosition;
objectRect.anchorMax = actualPosition;
objectRect.anchoredPosition = new Vector2();
}
}
accumilatedHeight += actualHeight;
acummilatedWeight += weight;
if(backgenerator!= null)
backgenerator.Generate();
generator.Generate();
generator.GetUpperBase(out baseX1, out baseX2);
generator.ApplyInfo(categoryData.Title, categoryData.Text, categoryData.Image,categoryData.Scale);
generator.SetAlpha(categoryData.Alpha);
}
}
protected override void OnLabelSettingChanged()
{
base.OnLabelSettingChanged();
Invalidate();
}
protected override void OnLabelSettingsSet()
{
base.OnLabelSettingsSet();
Invalidate();
}
public override void InternalGenerateChart()
{
if (gameObject.activeInHierarchy == false)
return;
base.InternalGenerateChart();
GeneratePyramid(mQuick);
mQuick = false;
}
protected override bool HasValues(AxisBase axis)
{
return false;
}
protected override double MaxValue(AxisBase axis)
{
return 0.0;
}
protected override double MinValue(AxisBase axis)
{
return 0.0;
}
protected virtual void OnPropertyChanged()
{
QuickInvalidate();
}
protected override void OnPropertyUpdated()
{
base.OnPropertyUpdated();
Invalidate();
}
protected override void ValidateProperties()
{
base.ValidateProperties();
if (inset < 0)
inset = 0;
}
PyramidEventArgs userDataToEventArgs(object userData)
{
PyramidObject pyramid = (PyramidObject)userData;
return new PyramidEventArgs(pyramid.category, pyramid.Title,pyramid.Text);
}
protected override void OnNonHoverted()
{
base.OnNonHoverted();
if (NonHovered != null)
NonHovered.Invoke();
}
protected override void OnItemHoverted(object userData)
{
base.OnItemHoverted(userData);
if (ItemHovered != null)
ItemHovered.Invoke(userDataToEventArgs(userData));
}
protected override void OnItemSelected(object userData)
{
base.OnItemSelected(userData);
var args = userDataToEventArgs(userData);
if (ItemClicked != null)
ItemClicked.Invoke(args);
}
protected override void Update()
{
base.Update();
}
protected override bool SupportsCategoryLabels
{
get
{
return true;
}
}
protected override bool SupportsGroupLables
{
get
{
return false;
}
}
protected override bool SupportsItemLabels
{
get
{
return false;
}
}
protected override bool ShouldFitCanvas { get { return false; } }
protected override float TotalDepthLink { get { return 0f; } }
protected override float TotalHeightLink { get { return totalHeight; } }
protected override float TotalWidthLink { get { return totalWidth; } }
public override bool IsCanvas { get { return true; } }
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5d0cd7c0544e4cc439d4a030e8a7a470
timeCreated: 1578949498
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,450 @@
#define Graph_And_Chart_PRO
using ChartAndGraph.DataSource;
using ChartAndGraph.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace ChartAndGraph
{
[Serializable]
public class PyramidData : AbstractChartData, IInternalPyramidData, IChartData
{
[Serializable]
internal class CategoryData
{
public string Name;
public ChartDynamicMaterial Materials;
public String Title;
public String Text;
public Sprite Image;
public float RightSlope;
public float LeftSlope;
public float HeightRatio;
public float Alpha;
public float Scale;
public float ShiftX, ShiftY;
public float PositionBlend;
public Vector2 Shift { get { return new Vector2(ShiftX, ShiftY); } }
}
[Serializable]
class DataEntry
{
public string GroupName;
public string ColumnName;
public double Amount;
}
public PyramidData()
{
mDataSource = new ChartSparseDataSource();
if (mDataSource.Rows.Count == 0)
mDataSource.Rows.Add(new DataSource.ChartDataRow("Pyramid"));
}
private ChartSparseDataSource mDataSource;
ChartSparseDataSource IInternalPyramidData.InternalDataSource { get { return mDataSource; } }
[SerializeField]
private CategoryData[] mCategories = new CategoryData[0];
[SerializeField]
private string[] mGroups = new string[1] { "Pyramid" };
[SerializeField]
private DataEntry[] mData = new DataEntry[0];
public int TotalCategories { get { return mDataSource.Columns.Count; } }
public void Update()
{
UpdateSliders();
}
public string GetCategoryName(int index)
{
return mDataSource.Columns[index].Name;
}
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;
object userData = mDataSource.Columns[i].UserData;
if (userData != null && userData is CategoryData)
{
data.Alpha = ((CategoryData)userData).Alpha;
data.HeightRatio = ((CategoryData)userData).HeightRatio;
data.Image = ((CategoryData)userData).Image;
data.Title = ((CategoryData)userData).Title;
data.LeftSlope = ((CategoryData)userData).LeftSlope;
data.RightSlope = ((CategoryData)userData).RightSlope;
data.Scale = ((CategoryData)userData).Scale;
data.ShiftX = ((CategoryData)userData).ShiftX;
data.ShiftY = ((CategoryData)userData).ShiftY;
data.Text = ((CategoryData)userData).Text;
data.PositionBlend = ((CategoryData)userData).PositionBlend;
}
else
{
data.Alpha = 1f;
data.HeightRatio = 1f;
data.Image = null;
data.Title = "";
data.LeftSlope = -0.5f;
data.RightSlope = -0.5f;
data.Scale = 1f;
data.ShiftX = 0f;
data.ShiftY = 0f;
data.Text = ((CategoryData)userData).Text;
data.PositionBlend = 1f;
}
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 event Action ProperyUpdated;
public event Action RealtimeProperyUpdated;
protected void RaiseRealtimePropertyUpdated()
{
if (RealtimeProperyUpdated != null)
RealtimeProperyUpdated();
}
protected void RaisePropertyUpdated()
{
if (ProperyUpdated != null)
ProperyUpdated();
}
public bool HasCategory(string category)
{
try
{
var col = mDataSource.Columns[category];
if (col != null)
return true;
}
catch
{
}
return false;
}
/// <summary>
/// rename a category. throws 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();
}
public object StoreCategory(string category)
{
CategoryData data = (CategoryData)(mDataSource.Columns[category].UserData);
data.Materials = mDataSource.Columns[category].Material;
return data;
}
public void RestoreCategory(string category, object data)
{
var toSet = (CategoryData)data;
CategoryData current = (CategoryData)(mDataSource.Columns[category].UserData);
current.Alpha = ((CategoryData)toSet).Alpha;
current.HeightRatio = ((CategoryData)toSet).HeightRatio;
current.Image = ((CategoryData)toSet).Image;
current.Title = ((CategoryData)toSet).Title;
current.LeftSlope = ((CategoryData)toSet).LeftSlope;
current.RightSlope = ((CategoryData)toSet).RightSlope;
current.Scale = ((CategoryData)toSet).Scale;
current.ShiftX = ((CategoryData)toSet).ShiftX;
current.ShiftY = ((CategoryData)toSet).ShiftY;
current.Text = ((CategoryData)toSet).Text;
current.PositionBlend = ((CategoryData)toSet).PositionBlend;
current.Materials = toSet.Materials;
mDataSource.Columns[category].Material = toSet.Materials;
RaisePropertyUpdated();
}
/// <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 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, mCategories[i].Title, mCategories[i].Text, mCategories[i].Image, mCategories[i].Alpha, mCategories[i].HeightRatio, mCategories[i].LeftSlope, mCategories[i].RightSlope, mCategories[i].PositionBlend, mCategories[i].Scale, mCategories[i].ShiftX, mCategories[i].ShiftY);
// for (int i = 0; i < mGroups.Length; i++)
// AddGroup(mGroups[i]);
if (mDataSource.Rows.Count == 0)
mDataSource.Rows.Add(new DataSource.ChartDataRow("Pyramid"));
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;
}
private void AddGroup(string name)
{
mDataSource.Rows.Add(new ChartDataRow(name));
}
/// <summary>
/// Adds a new category to the pyramid chart. Each category has it's own material and name. each category corresponds to one pyr slice
/// </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, String title, String text, Sprite image)
{
AddCategory(name, new ChartDynamicMaterial(material),title,text,image);
}
/// <summary>
/// Adds a new category to the pyramid chart. Each category has it's own material and name. each category corresponds to one pie slice
/// </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, String title, String text, Sprite image,float alpha = 1f,float heightRatio = 1f,float leftSlope = 45f,float rightSlope = 45f,float positionBlend = 1f,float scale = 1f, float shiftX = 0f,float shiftY =0f)
{
if (title == null)
title = "";
if (text == null)
text = "";
ChartDataColumn column = new ChartDataColumn(name);
column.Material = material;
CategoryData d = new CategoryData();
d.Title = title;
d.Text = text;
d.Image = image;
d.Alpha = alpha;
d.HeightRatio = heightRatio;
d.LeftSlope = leftSlope;
d.RightSlope = rightSlope;
d.PositionBlend = positionBlend;
d.Scale = scale;
d.ShiftX = shiftX;
d.ShiftY = shiftY;
column.UserData = d;
mDataSource.mColumns.Add(column);
SetValueInternal(name, "Pyramid", heightRatio);
}
public void SetCategoryInfo(string category,string title,string text,Sprite image)
{
if (title == null)
title = "";
if (text == null)
text = "";
var col = mDataSource.Columns[category];
CategoryData data = col.UserData as CategoryData;
data.Text = text;
data.Title = title;
data.Image = image;
RaisePropertyUpdated();
}
public void SetCategoryAlpha(string category, float alpha)
{
var col = mDataSource.Columns[category];
CategoryData data = col.UserData as CategoryData;
data.Alpha = alpha;
RaiseRealtimePropertyUpdated();
}
public void SetCategoryContentScale(string category,float scale)
{
var col = mDataSource.Columns[category];
CategoryData data = col.UserData as CategoryData;
data.Scale = scale;
RaiseRealtimePropertyUpdated();
}
public void SetCategoryOrientation(string category,float positionBlend,float shiftX ,float shiftY)
{
var col = mDataSource.Columns[category];
CategoryData data = col.UserData as CategoryData;
data.PositionBlend = positionBlend;
data.ShiftX = shiftX;
data.ShiftY = shiftY;
RaiseRealtimePropertyUpdated();
}
public void SetCategorySlope(string category,float leftSlop,float rightSlope)
{
var col = mDataSource.Columns[category];
CategoryData data = col.UserData as CategoryData;
data.LeftSlope = leftSlop;
data.RightSlope = rightSlope;
RaiseRealtimePropertyUpdated();
}
public void SetCategoryHeightRatio(string category, float heightRatio)
{
var col = mDataSource.Columns[category];
CategoryData data = col.UserData as CategoryData;
data.HeightRatio = heightRatio;
SetValueInternal(category, "Pyramid", heightRatio);
RaiseRealtimePropertyUpdated();
}
/// <summary>
/// clears the pyramid chart data
/// </summary>
public void Clear()
{
string[] groups = mDataSource.Columns.Select(x => x.Name).ToArray();
foreach (string s in groups)
{
RemoveCategory(s);
}
}
/// <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 allow 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 pyramid chart
/// </summary>
/// <param name="name">the name of the category to remove</param>
public void RemoveCategory(string name)
{
ChartDataColumn column = mDataSource.Columns[name];
RemoveSlider(name, "Pyramid");
mDataSource.Columns.Remove(column);
}
/// <summary>
/// gets the value for the specified category
/// </summary>
/// <param name="category">the category name</param>
/// <param name="group">the group name</param>
/// <returns></returns>
public double GetValue(string category)
{
return mDataSource.GetValue(category, "Pyramid");
}
public bool CheckAnimationEnded(float time, AnimationCurve curve)
{
if (curve.length == 0)
return true;
return time > curve.keys[curve.length - 1].time;
}
/// <summary>
/// used intenally , do not call
/// </summary>
/// <param name="cats"></param>
public object[] StoreAllCategoriesinOrder()
{
return mCategories.ToArray();
}
private void FixEaseFunction(AnimationCurve curve)
{
curve.postWrapMode = WrapMode.Once;
curve.preWrapMode = WrapMode.Once;
}
protected override void SetValueInternal(string column, string row, double value)
{
try
{
if(mDataSource.Rows.Count ==0 )
mDataSource.Rows.Add(new DataSource.ChartDataRow("Pyramid"));
mDataSource.SetValue(column, "Pyramid", value);
}
catch (ChartException e)
{
Debug.LogWarning(e.Message);
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 46cd052151826fb41a072a83f913f790
timeCreated: 1578948915
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,47 @@
#define Graph_And_Chart_PRO
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace ChartAndGraph
{
class PyramidMesh
{
public static void Generate2dMesh(UIVertex[] mesh, Vector2[] normals,float baseX1, float baseX2,float baseSize, float slopLeft, float slopeRight, float height,float startV,float endV)
{
float halfHeight = height * 0.5f;
float halfWidth = baseSize * 0.5f;
slopLeft = -Mathf.Clamp(slopLeft, -90, 90) +90;
slopeRight = Mathf.Clamp(slopeRight ,- 90, 90) +90;
float tanLeft = (1f/Mathf.Tan(slopLeft * Mathf.Deg2Rad)) * height;
float tanRight =(1f/Mathf.Tan(slopeRight * Mathf.Deg2Rad)) * height;
float leftPos = baseX1 + tanLeft;
float rightPos = baseX2 + tanRight;
leftPos = Mathf.Clamp(leftPos, 0,baseSize);
rightPos = Mathf.Clamp(rightPos, 0, baseSize);
if (leftPos > rightPos)
leftPos = rightPos = Mathf.Clamp(Mathf.Lerp(leftPos, rightPos, 0.5f), 0, baseSize);
UIVertex v1 = ChartCommon.CreateVertex(new Vector3(baseX1 - halfWidth, -halfHeight), new Vector2(0f, startV));
UIVertex v2 = ChartCommon.CreateVertex(new Vector3(baseX2 - halfWidth, -halfHeight), new Vector2(1f, startV));
UIVertex v3 = ChartCommon.CreateVertex(new Vector3(leftPos - halfWidth, halfHeight), new Vector2(0f, endV));
UIVertex v4 = ChartCommon.CreateVertex(new Vector3(rightPos - halfWidth, halfHeight), new Vector2(1f, endV));
normals[0] = ((Vector2.up + ChartCommon.Perpendicular(v3.position - v1.position).normalized) * 0.5f).normalized;
normals[1] = ((Vector2.up + ChartCommon.Perpendicular(v2.position - v4.position).normalized) * 0.5f).normalized;
normals[2] = ((Vector2.down + ChartCommon.Perpendicular(v3.position - v1.position).normalized) * 0.5f).normalized;
normals[3] = ((Vector2.down + ChartCommon.Perpendicular(v2.position - v4.position).normalized) * 0.5f).normalized;
mesh[0] = v1;
mesh[1] = v2;
mesh[2] = v3;
mesh[3] = v4;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1cc5bd615b17ae34292624585cda8e6a
timeCreated: 1579182822
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: