using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace xchart { [System.Serializable] public class LineData { [SerializeField] public string name; [SerializeField] public string key; [SerializeField] public Color lineColor; [SerializeField] public Color pointColor; [SerializeField] public Button button; private List _dataList = new List(); public List dataList { get { return _dataList; } } private bool _visible = true; public bool visible { get { return _visible; } set { _visible = value; if (button) { button.GetComponent().color = visible ? lineColor : Color.grey; } } } private int _min = 0; public int min { get { return _min; } } private int _max = 10; public int max { get { return _max; } } private int _step = 10; public int step { get { return _step; } set { _step = value; } } public void AddData(float data, int maxCount) { dataList.Add(data); if (dataList.Count > maxCount) { dataList.RemoveAt(0); UpdateMinMax(); } else { if (data < _min) { _min = (int)data; } if (data > _max) { _max = (int)data; } CheckMax(); } } public void ClearData() { _dataList.Clear(); } public void UpdateMinMax() { _min = 0; _max = 4; foreach (var data in dataList) { if (data < _min) { _min = (int)data; } if (data > _max) { _max = (int)data; } } CheckMax(); } private void CheckMax() { if (_max <= 10) { if (_max < 4) _max = 4; } else { int diff = _max % _step; if (diff > 1) { _max = (_max - diff) + _step; } } } } public class LineChart : MaskableGraphic { private const int MAX_GRADUATION = 10; [SerializeField] private int pointWidth = 15; [SerializeField] private float lineSize = 1f; [SerializeField] private float pointSize = 1.5f; [SerializeField] private int graduationCount = 4; [SerializeField] private int graduationStep = 10; [SerializeField] private int graduationWidth = 50; private float arrowLen = 10; private float arrowSize = 6; [SerializeField] private Color backgroundColor; [SerializeField] private Font font; [SerializeField] private List lineList = new List(); private Button btnAll; private bool isShowAll; private List graduationList = new List(); private Dictionary lineMap = new Dictionary(); private float lastMaxData = 0; private float lastChartHig = 0; private float lastGraduationWid = 0; protected override void Awake() { base.Awake(); InitGraduation(); InitLineButton(); InitHideAndShowButton(); for (int i = 0; i < lineList.Count; i++) { LineData line = lineList[i]; line.dataList.Clear(); if (line.button) { Color bcolor = line.visible ? line.lineColor : Color.grey; line.button.GetComponent().color = bcolor; line.button.GetComponentInChildren().text = line.name; line.button.onClick.AddListener(delegate () { OnClickButton(line.key); }); } AddLineToLineMap(line); } } private void InitGraduation() { float chartHigh = rectTransform.sizeDelta.y; float graduationHig = chartHigh / graduationCount; for (int i = 0; i < MAX_GRADUATION; i++) { if (i >= graduationCount + 1) { if (transform.Find("graduation" + i)) { transform.Find("graduation" + i).gameObject.SetActive(false); } } else { GameObject g1; if (transform.Find("graduation" + i)) { g1 = transform.Find("graduation" + i).gameObject; g1.SetActive(true); } else { g1 = new GameObject(); g1.name = "graduation" + i; g1.transform.parent = transform; g1.transform.localPosition = Vector3.zero; g1.transform.localScale = Vector3.one; Text txtg1 = g1.AddComponent(); txtg1.font = font; txtg1.text = (i * 100).ToString(); txtg1.alignment = TextAnchor.MiddleRight; } RectTransform rect = g1.GetComponent(); rect.anchorMax = Vector2.zero; rect.anchorMin = Vector2.zero; rect.sizeDelta = new Vector2(50, 20); rect.localPosition = new Vector3(-33, i * graduationHig, 0); graduationList.Add(g1.GetComponent()); } } } private void InitLineButton() { float chartHigh = rectTransform.sizeDelta.y; for (int i = 0; i < lineList.Count; i++) { if (lineList[i].button) continue; GameObject goBtn; if (transform.Find("button" + i)) { goBtn = transform.Find("button" + i).gameObject; } else { goBtn = new GameObject(); goBtn.name = "button" + i; goBtn.transform.parent = transform; goBtn.transform.localPosition = Vector3.zero; goBtn.transform.localScale = Vector3.one; goBtn.AddComponent(); goBtn.AddComponent