mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-16 05:10:12 +00:00
401 lines
14 KiB
C#
401 lines
14 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using UnityEngine.UI;
|
|
using System.Collections.Generic;
|
|
|
|
namespace xcharts
|
|
{
|
|
|
|
[System.Serializable]
|
|
public class Coordinate
|
|
{
|
|
public bool show = true;
|
|
public float left = 40f;
|
|
public float right = 10f;
|
|
public float top = 10;
|
|
public float bottom = 20f;
|
|
public float tickness = 0.8f;
|
|
public float scaleLen = 5.0f;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public enum AxisType
|
|
{
|
|
value,
|
|
category,
|
|
time,
|
|
log
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class Axis
|
|
{
|
|
public AxisType type;
|
|
public int splitNumber = 5;
|
|
public int maxSplitNumber = 5;
|
|
public bool showSplitLine;
|
|
public bool boundaryGap = true;
|
|
public List<string> data;
|
|
|
|
public void AddCategory(string category)
|
|
{
|
|
if (data.Count >= maxSplitNumber)
|
|
{
|
|
data.RemoveAt(0);
|
|
}
|
|
data.Add(category);
|
|
}
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class XAxis : Axis
|
|
{
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class YAxis : Axis
|
|
{
|
|
}
|
|
|
|
public class BaseAxesChart : BaseChart
|
|
{
|
|
private const int DEFAULT_YSACLE_NUM = 5;
|
|
private const string YSCALE_TEXT_PREFIX = "yScale";
|
|
private const string XSCALE_TEXT_PREFIX = "xScale";
|
|
|
|
[SerializeField]
|
|
protected Coordinate coordinate;
|
|
[SerializeField]
|
|
protected XAxis xAxis;
|
|
[SerializeField]
|
|
protected YAxis yAxis;
|
|
|
|
private float lastXMaxValue;
|
|
private float lastYMaxValue;
|
|
private float lastCoordinateWid;
|
|
private float lastCoordinateHig;
|
|
private float lastCoordinateScaleLen;
|
|
|
|
private XAxis checkXAxis = new XAxis();
|
|
private YAxis checkYAxis = new YAxis();
|
|
private Coordinate checkCoordinate = new Coordinate();
|
|
|
|
protected List<Text> yScaleTextList = new List<Text>();
|
|
protected List<Text> xScaleTextList = new List<Text>();
|
|
protected float zeroX { get { return coordinate.left; } }
|
|
protected float zeroY { get { return coordinate.bottom; } }
|
|
protected float coordinateWid { get { return chartWid - coordinate.left - coordinate.right; } }
|
|
protected float coordinateHig { get { return chartHig - coordinate.top - coordinate.bottom; } }
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
lastCoordinateHig = chartHig;
|
|
lastCoordinateWid = chartWid;
|
|
lastCoordinateScaleLen = coordinate.scaleLen;
|
|
InitXScale();
|
|
InitYScale();
|
|
}
|
|
|
|
protected override void Update()
|
|
{
|
|
base.Update();
|
|
CheckYAxisType();
|
|
CheckXAxisType();
|
|
CheckMaxValue();
|
|
CheckCoordinate();
|
|
}
|
|
|
|
protected override void OnPopulateMesh(VertexHelper vh)
|
|
{
|
|
base.OnPopulateMesh(vh);
|
|
DrawCoordinate(vh);
|
|
}
|
|
|
|
public void AddXAxisCategory(string category)
|
|
{
|
|
xAxis.AddCategory(category);
|
|
OnXAxisChanged();
|
|
}
|
|
|
|
public void AddYAxisCategory(string category)
|
|
{
|
|
yAxis.AddCategory(category);
|
|
OnYAxisChanged();
|
|
}
|
|
|
|
private void InitYScale()
|
|
{
|
|
yScaleTextList.Clear();
|
|
if (yAxis.type == AxisType.value)
|
|
{
|
|
float max = GetMaxValue();
|
|
if (max <= 0) max = 400;
|
|
yAxis.splitNumber = DEFAULT_YSACLE_NUM;
|
|
for (int i = 0; i < yAxis.splitNumber; i++)
|
|
{
|
|
Text txt = ChartUtils.AddTextObject(YSCALE_TEXT_PREFIX + i, transform, font,
|
|
TextAnchor.MiddleRight, Vector2.zero, Vector2.zero, new Vector2(1, 0.5f),
|
|
new Vector2(coordinate.left, 20));
|
|
txt.transform.localPosition = GetYScalePosition(i);
|
|
txt.text = ((int)(max * i / yAxis.splitNumber)).ToString();
|
|
txt.gameObject.SetActive(coordinate.show);
|
|
yScaleTextList.Add(txt);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
yAxis.splitNumber = yAxis.boundaryGap ? yAxis.data.Count + 1 : yAxis.data.Count;
|
|
for (int i = 0; i < yAxis.data.Count; i++)
|
|
{
|
|
Text txt = ChartUtils.AddTextObject(YSCALE_TEXT_PREFIX + i, transform, font,
|
|
TextAnchor.MiddleRight, Vector2.zero, Vector2.zero, new Vector2(1, 0.5f),
|
|
new Vector2(coordinate.left, 20));
|
|
txt.transform.localPosition = GetYScalePosition(i);
|
|
txt.text = yAxis.data[i];
|
|
txt.gameObject.SetActive(coordinate.show);
|
|
yScaleTextList.Add(txt);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void InitXScale()
|
|
{
|
|
xScaleTextList.Clear();
|
|
if (xAxis.type == AxisType.value)
|
|
{
|
|
float max = GetMaxValue();
|
|
if (max <= 0) max = 400;
|
|
xAxis.splitNumber = DEFAULT_YSACLE_NUM;
|
|
float scaleWid = coordinateWid / (xAxis.splitNumber - 1);
|
|
for (int i = 0; i < xAxis.splitNumber; i++)
|
|
{
|
|
Text txt = ChartUtils.AddTextObject(XSCALE_TEXT_PREFIX + i, transform, font,
|
|
TextAnchor.MiddleCenter, Vector2.zero, Vector2.zero, new Vector2(1, 0.5f),
|
|
new Vector2(scaleWid, 20));
|
|
txt.transform.localPosition = GetXScalePosition(i);
|
|
txt.text = ((int)(max * i / xAxis.splitNumber)).ToString();
|
|
txt.gameObject.SetActive(coordinate.show);
|
|
xScaleTextList.Add(txt);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xAxis.splitNumber = xAxis.boundaryGap ? xAxis.data.Count + 1 : xAxis.data.Count;
|
|
float scaleWid = coordinateWid / (xAxis.data.Count - 1);
|
|
for (int i = 0; i < xAxis.data.Count; i++)
|
|
{
|
|
Text txt = ChartUtils.AddTextObject(XSCALE_TEXT_PREFIX + i, transform, font,
|
|
TextAnchor.MiddleCenter, Vector2.zero, Vector2.zero, new Vector2(1, 0.5f),
|
|
new Vector2(scaleWid, 20));
|
|
txt.transform.localPosition = GetXScalePosition(i);
|
|
txt.text = xAxis.data[i];
|
|
txt.gameObject.SetActive(coordinate.show);
|
|
xScaleTextList.Add(txt);
|
|
}
|
|
}
|
|
}
|
|
|
|
private Vector3 GetYScalePosition(int i)
|
|
{
|
|
float scaleWid = coordinateHig / (yAxis.splitNumber - 1);
|
|
if (yAxis.type == AxisType.value)
|
|
{
|
|
return new Vector3(zeroX - coordinate.scaleLen - 2f,
|
|
zeroY + i * scaleWid, 0);
|
|
}
|
|
else
|
|
{
|
|
if (yAxis.boundaryGap)
|
|
{
|
|
return new Vector3(zeroX - coordinate.scaleLen - 2f,
|
|
zeroY + (i + 0.5f) * scaleWid, 0);
|
|
}
|
|
else
|
|
{
|
|
return new Vector3(zeroX - coordinate.scaleLen - 2f,
|
|
zeroY + i * scaleWid, 0);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
private Vector3 GetXScalePosition(int i)
|
|
{
|
|
float scaleWid = coordinateWid / (xAxis.splitNumber - 1);
|
|
if (xAxis.type == AxisType.value)
|
|
{
|
|
return new Vector3(zeroX + (i + 1 - 0.5f) * scaleWid, zeroY - coordinate.scaleLen - 10, 0);
|
|
}
|
|
else
|
|
{
|
|
if (xAxis.boundaryGap)
|
|
{
|
|
return new Vector3(zeroX + (i + 1) * scaleWid, zeroY - coordinate.scaleLen - 5, 0);
|
|
}
|
|
else
|
|
{
|
|
return new Vector3(zeroX + (i + 1 - 0.5f) * scaleWid, zeroY - coordinate.scaleLen - 5, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CheckCoordinate()
|
|
{
|
|
if (lastCoordinateHig != coordinateHig
|
|
|| lastCoordinateWid != coordinateWid
|
|
|| lastCoordinateScaleLen != coordinate.scaleLen)
|
|
{
|
|
lastCoordinateWid = coordinateWid;
|
|
lastCoordinateHig = coordinateHig;
|
|
lastCoordinateScaleLen = coordinate.scaleLen;
|
|
OnCoordinateSize();
|
|
}
|
|
if (checkCoordinate.show != coordinate.show)
|
|
{
|
|
checkCoordinate.show = coordinate.show;
|
|
OnXAxisChanged();
|
|
OnYAxisChanged();
|
|
}
|
|
}
|
|
|
|
private void CheckYAxisType()
|
|
{
|
|
if (checkYAxis.type != yAxis.type ||
|
|
checkYAxis.boundaryGap != yAxis.boundaryGap ||
|
|
checkYAxis.showSplitLine != yAxis.showSplitLine ||
|
|
checkYAxis.splitNumber != yAxis.splitNumber)
|
|
{
|
|
checkYAxis.type = yAxis.type;
|
|
checkYAxis.boundaryGap = yAxis.boundaryGap;
|
|
checkYAxis.showSplitLine = yAxis.showSplitLine;
|
|
checkYAxis.splitNumber = yAxis.splitNumber;
|
|
OnYAxisChanged();
|
|
}
|
|
}
|
|
|
|
private void CheckXAxisType()
|
|
{
|
|
if (checkXAxis.type != xAxis.type ||
|
|
checkXAxis.boundaryGap != xAxis.boundaryGap ||
|
|
checkXAxis.showSplitLine != xAxis.showSplitLine ||
|
|
checkXAxis.splitNumber != xAxis.splitNumber)
|
|
{
|
|
checkXAxis.type = xAxis.type;
|
|
checkXAxis.boundaryGap = xAxis.boundaryGap;
|
|
checkXAxis.showSplitLine = xAxis.showSplitLine;
|
|
checkXAxis.splitNumber = xAxis.splitNumber;
|
|
OnXAxisChanged();
|
|
}
|
|
}
|
|
|
|
private void CheckMaxValue()
|
|
{
|
|
if (xAxis.type == AxisType.value)
|
|
{
|
|
float max = GetMaxValue();
|
|
if (lastXMaxValue != max)
|
|
{
|
|
lastXMaxValue = max;
|
|
OnXMaxValueChanged();
|
|
}
|
|
}
|
|
else if (yAxis.type == AxisType.value)
|
|
{
|
|
|
|
float max = GetMaxValue();
|
|
if (lastYMaxValue != max)
|
|
{
|
|
lastYMaxValue = max;
|
|
OnYMaxValueChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void OnCoordinateSize()
|
|
{
|
|
//update yScale pos
|
|
for (int i = 0; i < yAxis.splitNumber; i++)
|
|
{
|
|
if (i < yScaleTextList.Count && yScaleTextList[i])
|
|
{
|
|
yScaleTextList[i].transform.localPosition = GetYScalePosition(i);
|
|
}
|
|
}
|
|
for (int i = 0; i < xAxis.splitNumber; i++)
|
|
{
|
|
if (i < xScaleTextList.Count && xScaleTextList[i])
|
|
{
|
|
xScaleTextList[i].transform.localPosition = GetXScalePosition(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void OnYAxisChanged()
|
|
{
|
|
HideChild(YSCALE_TEXT_PREFIX);
|
|
InitYScale();
|
|
}
|
|
|
|
protected virtual void OnXAxisChanged()
|
|
{
|
|
HideChild(XSCALE_TEXT_PREFIX);
|
|
InitXScale();
|
|
}
|
|
|
|
protected virtual void OnXMaxValueChanged()
|
|
{
|
|
float max = GetMaxValue();
|
|
for (int i = 0; i < xScaleTextList.Count; i++)
|
|
{
|
|
xScaleTextList[i].text = ((int)(max * i / xScaleTextList.Count)).ToString();
|
|
}
|
|
}
|
|
|
|
protected override void OnYMaxValueChanged()
|
|
{
|
|
float max = GetMaxValue();
|
|
for (int i = 0; i < yScaleTextList.Count; i++)
|
|
{
|
|
yScaleTextList[i].text = ((int)(max * i / (yScaleTextList.Count - 1))).ToString();
|
|
}
|
|
}
|
|
|
|
private void DrawCoordinate(VertexHelper vh)
|
|
{
|
|
if (!coordinate.show) return;
|
|
// draw scale
|
|
for (int i = 1; i < yAxis.splitNumber; i++)
|
|
{
|
|
float pX = zeroX - coordinate.scaleLen;
|
|
float pY = zeroY + i * coordinateHig / (yAxis.splitNumber - 1);
|
|
ChartUtils.DrawLine(vh, new Vector3(pX, pY), new Vector3(zeroX, pY), coordinate.tickness,
|
|
Color.white);
|
|
if (yAxis.showSplitLine)
|
|
{
|
|
ChartUtils.DrawLine(vh, new Vector3(zeroX, pY),
|
|
new Vector3(zeroX + coordinateWid, pY), coordinate.tickness, Color.grey);
|
|
}
|
|
}
|
|
for (int i = 1; i < xAxis.splitNumber; i++)
|
|
{
|
|
float pX = zeroX + i * coordinateWid / (xAxis.splitNumber - 1);
|
|
float pY = zeroY - coordinate.scaleLen - 2;
|
|
ChartUtils.DrawLine(vh, new Vector3(pX, zeroY), new Vector3(pX, pY), coordinate.tickness,
|
|
Color.white);
|
|
if (xAxis.showSplitLine)
|
|
{
|
|
ChartUtils.DrawLine(vh, new Vector3(pX, zeroY), new Vector3(pX, zeroY + coordinateHig),
|
|
coordinate.tickness, Color.grey);
|
|
}
|
|
}
|
|
//draw x,y axis
|
|
ChartUtils.DrawLine(vh, new Vector3(zeroX, zeroY - coordinate.scaleLen),
|
|
new Vector3(zeroX, zeroY + coordinateHig + 2), coordinate.tickness, Color.white);
|
|
ChartUtils.DrawLine(vh, new Vector3(zeroX - coordinate.scaleLen, zeroY),
|
|
new Vector3(zeroX + coordinateWid + 2, zeroY), coordinate.tickness, Color.white);
|
|
}
|
|
}
|
|
}
|
|
|