using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.UIElements; namespace BITKit.UX { public class LineChart : VisualElement { public new class UxmlTraits : VisualElement.UxmlTraits { private readonly UxmlStringAttributeDescription m_JsonAttribute = new() { name = "Json" }; private readonly UxmlBoolAttributeDescription m_allowWarningsAttribute = new() { name = "allowWarnings", defaultValue = false }; public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc) { base.Init(ve, bag, cc); var x = (LineChart)ve; x.Json = m_JsonAttribute.GetValueFromBag(bag, cc); x.AllowWarning = m_allowWarningsAttribute.GetValueFromBag(bag, cc); } } public new class UxmlFactory : UxmlFactory { } public LineChart() { RegisterCallback(OnCustomStyleResolved); style.flexDirection = FlexDirection.Row; _dataContainer = this.Create(); _chartContainer = this.Create(); _chartContainer.style.flexGrow = 1; _dataContainer.style.justifyContent = Justify.SpaceBetween; _dataContainer.name = "Data"; _chartContainer.name = "Chart"; _chartContainer.generateVisualContent+= GenerateVisualContent; _chartContainer.style.marginBottom = 0; _chartContainer.style.marginLeft = 8; _chartContainer.style.marginRight = 8; _chartContainer.style.marginTop = 0 ; pickingMode = PickingMode.Ignore; _dataContainer.pickingMode = PickingMode.Ignore; _chartContainer.style.flexDirection = FlexDirection.RowReverse; _dataContainer.style.flexDirection = FlexDirection.ColumnReverse; _chartContainer.RegisterCallback(OnPointerMove); } private void OnPointerMove(PointerMoveEvent evt) { //_chartContainer.tooltip = evt.localPosition.ToString(); } private void OnCustomStyleResolved(CustomStyleResolvedEvent evt) { if (evt.customStyle.TryGetValue(new CustomStyleProperty("--chart-secondary-color"), out var helpLineColor)) { _secondaryColor = helpLineColor; } for (int i = 0; i < 8; i++) { if (evt.customStyle.TryGetValue(new CustomStyleProperty($"--chart-line-color--{i}"), out var lineColor)) { _lineColors[i] = lineColor; } } MarkDirtyRepaint(); } public string Json { get => _json; set { _json = value; GenerateLayout(); } } private string _json; public bool AllowWarning { get; set; } public Color SecondaryColor { get => _secondaryColor; set { _secondaryColor = value; GenerateLayout(); } } private Color _secondaryColor; private readonly VisualElement _dataContainer; private readonly VisualElement _chartContainer; private readonly Color[] _lineColors = new[] { Color.red, Color.red, Color.red, Color.red, Color.red, Color.red, Color.red, Color.red, }; private void GenerateLayout() { JArray[] array; float[] data; try { array = JsonConvert.DeserializeObject(Json); data = array.SelectMany(x => x.ToObject()).ToArray(); } catch (Exception e) { if (AllowWarning) Debug.LogException(e); return; } if (data is null or { Length: 0 }) { if (AllowWarning) BIT4Log.Log("Data is null or empty"); return; } //假如min是x,max是y,将中间的差用data.Length划分 var max = data.Max(); var min = data.Min(); var difference = max - min; var maxLength = array.Select(x => x.Count).Max(); max += difference / maxLength; min -= difference / maxLength; //Debug.Log($"min:{min} max:{max} difference:{difference} max:{max}"); _dataContainer.Clear(); _dataContainer.style.justifyContent = Justify.SpaceAround; for (var i = 0; i <= 4; i++) { var label = _dataContainer.Create