拼ui 一些业务逻辑x实现

This commit is contained in:
FloatGaming
2026-03-19 06:15:09 +08:00
parent f5c6f143c0
commit 49e45ac464
1118 changed files with 246518 additions and 5368 deletions
@@ -0,0 +1,352 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace EasyChart.Demo
{
/// <summary>
/// Controller for the EasyChart Demo Showcase.
/// Manages multiple groups of 16 demos each (4x4 grid).
/// </summary>
public class DemoShowcaseController : MonoBehaviour
{
public const int DemosPerGroup = 16;
[Header("UI Document")]
[SerializeField] private UIDocument _uiDocument;
[Header("Demo Profiles")]
[Tooltip("Drag ChartProfile assets here in the order you want them displayed")]
[SerializeField] private List<ChartProfile> _demoProfiles = new List<ChartProfile>();
[Header("Group Control")]
[Tooltip("Current active group index (0-based)")]
[SerializeField] private int _activeGroup = 0;
[Header("Navigation")]
[SerializeField] private KeyCode _nextGroupKey = KeyCode.RightArrow;
[SerializeField] private KeyCode _prevGroupKey = KeyCode.LeftArrow;
[Header("UGUI Navigation Buttons")]
[SerializeField] private UnityEngine.UI.Button _nextbutton;
[SerializeField] private UnityEngine.UI.Button _lastbutton;
[Header("Appearance")]
[SerializeField] private Color _slotBackgroundColor = new Color(0.12f, 0.12f, 0.12f, 0.9f);
[SerializeField] private Color _slotBorderColor = new Color(0.3f, 0.3f, 0.3f, 0.5f);
private VisualElement _root;
private VisualElement _groupContainer;
private List<VisualElement> _slots = new List<VisualElement>();
private List<ChartElement> _chartElements = new List<ChartElement>();
/// <summary>
/// Total number of groups based on demo count.
/// </summary>
public int GroupCount => Mathf.CeilToInt(_demoProfiles.Count / (float)DemosPerGroup);
/// <summary>
/// Current active group index.
/// </summary>
public int ActiveGroup => _activeGroup;
/// <summary>
/// Total demo count.
/// </summary>
public int DemoCount => _demoProfiles.Count;
private void OnEnable()
{
if (_uiDocument == null)
{
_uiDocument = GetComponent<UIDocument>();
}
if (_uiDocument != null)
{
_root = _uiDocument.rootVisualElement;
BuildUI();
ShowGroup(_activeGroup);
}
if (_nextbutton != null) _nextbutton.onClick.AddListener(OnNextButtonClicked);
if (_lastbutton != null) _lastbutton.onClick.AddListener(OnLastButtonClicked);
}
private void OnDisable()
{
if (_nextbutton != null) _nextbutton.onClick.RemoveListener(OnNextButtonClicked);
if (_lastbutton != null) _lastbutton.onClick.RemoveListener(OnLastButtonClicked);
}
private void OnNextButtonClicked()
{
int groupCount = GroupCount;
if (groupCount <= 1) return;
int next = (_activeGroup + 1) % groupCount;
ShowGroup(next);
}
private void OnLastButtonClicked()
{
int groupCount = GroupCount;
if (groupCount <= 1) return;
int prev = (_activeGroup - 1 + groupCount) % groupCount;
ShowGroup(prev);
}
private void Update()
{
int groupCount = GroupCount;
if (groupCount <= 1) return;
if (Input.GetKeyDown(_nextGroupKey))
{
int next = (_activeGroup + 1) % groupCount;
ShowGroup(next);
}
else if (Input.GetKeyDown(_prevGroupKey))
{
int prev = (_activeGroup - 1 + groupCount) % groupCount;
ShowGroup(prev);
}
// Number keys 1-9 for quick group access
for (int i = 0; i < Mathf.Min(9, groupCount); i++)
{
if (Input.GetKeyDown(KeyCode.Alpha1 + i))
{
ShowGroup(i);
break;
}
}
}
private void BuildUI()
{
if (_root == null) return;
_root.Clear();
_chartElements.Clear();
_slots.Clear();
// Create main container
_groupContainer = new VisualElement();
_groupContainer.name = "GroupContainer";
_groupContainer.style.width = Length.Percent(100);
_groupContainer.style.height = Length.Percent(100);
_groupContainer.style.flexDirection = FlexDirection.Column;
_groupContainer.style.justifyContent = Justify.SpaceAround;
_groupContainer.style.alignItems = Align.Center;
_groupContainer.style.paddingLeft = 25;
_groupContainer.style.paddingRight = 25;
_groupContainer.style.paddingTop = 25;
_groupContainer.style.paddingBottom = 25;
_root.Add(_groupContainer);
// Build 4x4 grid (16 slots)
for (int row = 0; row < 4; row++)
{
var rowElement = new VisualElement();
rowElement.name = $"Row{row}";
rowElement.style.flexDirection = FlexDirection.Row;
rowElement.style.justifyContent = Justify.SpaceAround;
rowElement.style.alignItems = Align.Center;
rowElement.style.width = Length.Percent(100);
rowElement.style.flexGrow = 1;
_groupContainer.Add(rowElement);
for (int col = 0; col < 4; col++)
{
var slot = new VisualElement();
slot.name = $"Slot{row * 4 + col}";
slot.style.width = 450;
slot.style.height = 300;
slot.style.backgroundColor = _slotBackgroundColor;
slot.style.borderTopWidth = 1;
slot.style.borderBottomWidth = 1;
slot.style.borderLeftWidth = 1;
slot.style.borderRightWidth = 1;
slot.style.borderTopColor = _slotBorderColor;
slot.style.borderBottomColor = _slotBorderColor;
slot.style.borderLeftColor = _slotBorderColor;
slot.style.borderRightColor = _slotBorderColor;
slot.style.borderTopLeftRadius = 4;
slot.style.borderTopRightRadius = 4;
slot.style.borderBottomLeftRadius = 4;
slot.style.borderBottomRightRadius = 4;
rowElement.Add(slot);
_slots.Add(slot);
var chartElement = new ChartElement();
chartElement.style.width = Length.Percent(100);
chartElement.style.height = Length.Percent(100);
slot.Add(chartElement);
_chartElements.Add(chartElement);
}
}
// Add group indicator label
var groupLabel = new Label();
groupLabel.name = "GroupLabel";
groupLabel.style.position = Position.Absolute;
groupLabel.style.bottom = 10;
groupLabel.style.right = 20;
groupLabel.style.fontSize = 14;
groupLabel.style.color = new Color(0.7f, 0.7f, 0.7f);
_root.Add(groupLabel);
}
/// <summary>
/// Show the specified group.
/// </summary>
public void ShowGroup(int groupIndex)
{
int groupCount = GroupCount;
if (groupCount == 0)
{
_activeGroup = 0;
ClearAllSlots();
UpdateGroupLabel();
return;
}
int clampedGroup = Mathf.Clamp(groupIndex, 0, groupCount - 1);
_activeGroup = clampedGroup;
int startIndex = _activeGroup * DemosPerGroup;
for (int i = 0; i < DemosPerGroup; i++)
{
var slot = i < _slots.Count ? _slots[i] : null;
if (slot == null) continue;
int profileIndex = startIndex + i;
ChartProfile profile = profileIndex < _demoProfiles.Count ? _demoProfiles[profileIndex] : null;
var chart = new ChartElement();
chart.style.width = Length.Percent(100);
chart.style.height = Length.Percent(100);
chart.Profile = profile;
slot.Clear();
slot.Add(chart);
if (i < _chartElements.Count) _chartElements[i] = chart;
}
UpdateGroupLabel();
}
private void ClearAllSlots()
{
for (int i = 0; i < _slots.Count; i++)
{
var slot = _slots[i];
if (slot == null) continue;
var chart = new ChartElement();
chart.style.width = Length.Percent(100);
chart.style.height = Length.Percent(100);
slot.Clear();
slot.Add(chart);
if (i < _chartElements.Count) _chartElements[i] = chart;
}
}
private void UpdateGroupLabel()
{
var label = _root?.Q<Label>("GroupLabel");
if (label != null)
{
int groupCount = GroupCount;
if (groupCount > 1)
{
label.text = $"Group {_activeGroup + 1} / {groupCount} (← → to navigate)";
label.style.display = DisplayStyle.Flex;
}
else
{
label.style.display = DisplayStyle.None;
}
}
}
/// <summary>
/// Swap two demo positions.
/// </summary>
public void SwapDemos(int indexA, int indexB)
{
if (indexA < 0 || indexA >= _demoProfiles.Count) return;
if (indexB < 0 || indexB >= _demoProfiles.Count) return;
var temp = _demoProfiles[indexA];
_demoProfiles[indexA] = _demoProfiles[indexB];
_demoProfiles[indexB] = temp;
ShowGroup(_activeGroup);
}
/// <summary>
/// Set a specific demo at a position.
/// </summary>
public void SetDemo(int index, ChartProfile profile)
{
if (index < 0) return;
while (_demoProfiles.Count <= index)
{
_demoProfiles.Add(null);
}
_demoProfiles[index] = profile;
ShowGroup(_activeGroup);
}
/// <summary>
/// Add profiles to the list.
/// </summary>
public void AddProfiles(IEnumerable<ChartProfile> profiles)
{
foreach (var p in profiles)
{
if (p != null && !_demoProfiles.Contains(p))
{
_demoProfiles.Add(p);
}
}
ShowGroup(_activeGroup);
}
/// <summary>
/// Clear all profiles.
/// </summary>
public void ClearProfiles()
{
_demoProfiles.Clear();
_activeGroup = 0;
ShowGroup(0);
}
/// <summary>
/// Refresh current group display.
/// </summary>
public void RefreshCurrentGroup()
{
ShowGroup(_activeGroup);
}
#if UNITY_EDITOR
/// <summary>
/// Editor access to demo profiles list.
/// </summary>
public List<ChartProfile> DemoProfiles => _demoProfiles;
#endif
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: d6a4de88929cc02498d651df046337bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Demo/Scripts/DemoShowcaseController.cs
uploadId: 857482
@@ -0,0 +1,100 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace EasyChart.Demo
{
public class ExamplesChildSwitcher : MonoBehaviour
{
[SerializeField] private Transform _examples;
[SerializeField] private Button _nextButton;
[SerializeField] private Button _lastButton;
private readonly List<GameObject> _children = new List<GameObject>();
private int _index;
private void OnEnable()
{
RefreshChildren();
if (_nextButton != null) _nextButton.onClick.AddListener(Next);
if (_lastButton != null) _lastButton.onClick.AddListener(Last);
ApplyActive();
}
private void OnDisable()
{
if (_nextButton != null) _nextButton.onClick.RemoveListener(Next);
if (_lastButton != null) _lastButton.onClick.RemoveListener(Last);
}
public void RefreshChildren()
{
_children.Clear();
if (_examples == null) return;
for (int i = 0; i < _examples.childCount; i++)
{
var child = _examples.GetChild(i);
if (child == null) continue;
_children.Add(child.gameObject);
}
if (_children.Count == 0)
{
_index = 0;
return;
}
int activeIndex = -1;
for (int i = 0; i < _children.Count; i++)
{
if (_children[i] != null && _children[i].activeSelf)
{
activeIndex = i;
break;
}
}
_index = activeIndex >= 0 ? activeIndex : 0;
}
public void Show(int index)
{
if (_children.Count == 0) return;
_index = ((index % _children.Count) + _children.Count) % _children.Count;
ApplyActive();
}
private void Next()
{
if (_children.Count == 0) return;
_index = (_index + 1) % _children.Count;
ApplyActive();
}
private void Last()
{
if (_children.Count == 0) return;
_index = (_index - 1 + _children.Count) % _children.Count;
ApplyActive();
}
private void ApplyActive()
{
if (_children.Count == 0) return;
for (int i = 0; i < _children.Count; i++)
{
var go = _children[i];
if (go == null) continue;
go.SetActive(i == _index);
}
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 355f5a1487e0ad648a481ce49950d1b7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Demo/Scripts/ExamplesChildSwitcher.cs
uploadId: 857482
@@ -0,0 +1,146 @@
using UnityEngine;
using UnityEngine.UI;
using EasyChart.UGUI;
using EasyChart.UIToolKit;
namespace EasyChart.Samples
{
/// <summary>
/// Simple example demonstrating how to use UGUIRuntimeJsonInjection or UIToolKitRuntimeJsonInjection
/// to update chart data via code. Attach this script to a GameObject with a Button.
/// </summary>
public class JsonInjectionExample : MonoBehaviour
{
[Header("References (assign one)")]
[Tooltip("Reference to the UGUIRuntimeJsonInjection component on the chart (for UGUI)")]
[SerializeField] private UGUIRuntimeJsonInjection _uguiJsonInjection;
[Tooltip("Reference to the UIToolKitRuntimeJsonInjection component on the chart (for UI Toolkit)")]
[SerializeField] private UIToolKitRuntimeJsonInjection _uiToolkitJsonInjection;
[Tooltip("Optional: Button to trigger the update. If not set, will try to get from this GameObject.")]
[SerializeField] private Button _updateButton;
[Header("Sample JSON Data")]
[Tooltip("The JSON data to inject into the chart when button is clicked")]
[TextArea(10, 20)]
public string JsonData = @"{
""series"": [
{
""name"": ""Sales"",
""data"": [
{ ""x"": 0, ""value"": 120 },
{ ""x"": 1, ""value"": 200 },
{ ""x"": 2, ""value"": 150 },
{ ""x"": 3, ""value"": 80 },
{ ""x"": 4, ""value"": 170 }
]
}
]
}";
private void Start()
{
// Auto-get button if not assigned
if (_updateButton == null)
{
_updateButton = GetComponent<Button>();
}
// Register button click listener
if (_updateButton != null)
{
_updateButton.onClick.AddListener(OnUpdateButtonClicked);
}
else
{
Debug.LogWarning("[JsonInjectionExample] No Button found. Call UpdateChart() manually.");
}
}
private void OnDestroy()
{
if (_updateButton != null)
{
_updateButton.onClick.RemoveListener(OnUpdateButtonClicked);
}
}
/// <summary>
/// Called when the update button is clicked.
/// </summary>
private void OnUpdateButtonClicked()
{
UpdateChart();
}
/// <summary>
/// Update the chart with the current JsonData.
/// Can be called from code or UnityEvent.
/// </summary>
public void UpdateChart()
{
if (string.IsNullOrWhiteSpace(JsonData))
{
Debug.LogWarning("[JsonInjectionExample] JsonData is empty.");
return;
}
// Try UGUI injection first
if (_uguiJsonInjection != null)
{
_uguiJsonInjection.JsonContent = JsonData;
_uguiJsonInjection.ApplyJsonToChart();
Debug.Log("[JsonInjectionExample] Chart updated via UGUIRuntimeJsonInjection.");
return;
}
// Try UI Toolkit injection
if (_uiToolkitJsonInjection != null)
{
_uiToolkitJsonInjection.JsonContent = JsonData;
_uiToolkitJsonInjection.ApplyJsonToChart();
Debug.Log("[JsonInjectionExample] Chart updated via UIToolKitRuntimeJsonInjection.");
return;
}
Debug.LogError("[JsonInjectionExample] No injection component reference is set. Assign either UGUIRuntimeJsonInjection or UIToolKitRuntimeJsonInjection.");
}
/// <summary>
/// Example: Update chart with random data (can be called from button or code).
/// </summary>
public void UpdateChartWithRandomData()
{
// Generate random data
string randomJson = GenerateRandomJson();
JsonData = randomJson;
UpdateChart();
}
private string GenerateRandomJson()
{
var sb = new System.Text.StringBuilder();
sb.AppendLine("{");
sb.AppendLine(" \"series\": [");
sb.AppendLine(" {");
sb.AppendLine(" \"name\": \"Random Data\",");
sb.AppendLine(" \"data\": [");
int pointCount = Random.Range(4, 8);
for (int i = 0; i < pointCount; i++)
{
int value = Random.Range(50, 200);
string comma = i < pointCount - 1 ? "," : "";
sb.AppendLine($" {{ \"x\": {i}, \"value\": {value} }}{comma}");
}
sb.AppendLine(" ]");
sb.AppendLine(" }");
sb.AppendLine(" ]");
sb.AppendLine("}");
return sb.ToString();
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 142f8686940936a45ad253d44c7cbcd0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Demo/Scripts/JsonInjectionExample.cs
uploadId: 857482
@@ -0,0 +1,40 @@
using UnityEngine;
namespace EasyChart.Samples
{
/// <summary>
/// Example script that opens the EasyChart manual in the default browser when clicked.
/// Attach this to a UI Button or call OpenManual() from your own code.
/// </summary>
public class OpenManualExample : MonoBehaviour
{
[Tooltip("The manual page to open (e.g., '00_01-QuickStart')")]
public string manualPage = "00_01-QuickStart";
/// <summary>
/// Opens the EasyChart manual in the default browser.
/// Call this from a UI Button's OnClick event.
/// </summary>
public void OpenManual()
{
string manualPath = System.IO.Path.GetFullPath(
System.IO.Path.Combine(Application.dataPath, "EasyChart/Docs/ManualWeb/manual.html")
);
string url = $"file:///{manualPath.Replace("\\", "/")}#/{manualPage}";
Debug.Log($"[OpenManualExample] Opening manual: {url}");
Application.OpenURL(url);
}
/// <summary>
/// Opens the manual to a specific page.
/// </summary>
/// <param name="page">The page name without extension (e.g., "00_01-QuickStart")</param>
public void OpenManualPage(string page)
{
manualPage = page;
OpenManual();
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 6027d78feb02ca34897f4fd263102ea1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 359794
packageName: Easy Chart Lite
packageVersion: 1.0
assetPath: Assets/EasyChart/Demo/Scripts/OpenManualExample.cs
uploadId: 857482