Files
ChunilENG/Assets/WorkSpace/Personal/JYM/UI_GraphChart.cs
2025-04-17 14:11:53 +09:00

188 lines
5.5 KiB
C#

using ChartAndGraph;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using WI;
using TMPro;
using static ChartAndGraph.GraphChartBase;
public class UI_GraphChart : UIBase, IPointerClickHandler
{
public GraphChart Graph;
private UI_DateTime prf_dateTime;
private RectTransform Content_DateTime;
public UI_GraphChartData chartDetailData;
private TextMeshProUGUI GraphName;
public string graphName;
public int targetCount;
public int startIndex;
public float offsetY;
public bool isMainChart;
public Action<string> onClickChart;
private List<float> graphChartData = new List<float>();
private List<string> graphDateTimeData = new List<string>();
private Dictionary<int, Vector3> labelPos = new();
private TextMeshProUGUI MinValue;
private TextMeshProUGUI MaxValue;
private TextMeshProUGUI AveValue;
private float min;
private float max;
private float ave;
public override void AfterAwake()
{
Graph = GetComponentInChildren<GraphChart>();
prf_dateTime = Resources.Load<UI_DateTime>("Prefabs/UI/PRF_UI_DateTime");
chartDetailData = GetComponentInChildren<UI_GraphChartData>(true);
}
public void Update()
{
if (!isMainChart)
return;
if (Input.GetMouseButtonDown(0))
{
if (RectTransformUtility.RectangleContainsScreenPoint(chartDetailData.rectTransform, Input.mousePosition))
{
return;
}
chartDetailData.SetActive(false);
}
}
public void OnPointerClick(PointerEventData eventData)
{
if (!isMainChart)
{
onClickChart?.Invoke(graphName);
}
}
public void OnClickItem(GraphEventArgs args)
{
chartDetailData.SetData(graphName, graphChartData[args.Index], graphDateTimeData[args.Index], args.Position);
}
public void SetChartData(string graphName, GraphChartData graphData)
{
this.graphName = graphName;
SetDataValue(graphData);
graphChartData.Clear();
graphDateTimeData.Clear();
Graph.DataSource.VerticalViewSize = max * 2f;
Graph.DataSource.ClearCategory("WorkConditionsData");
Graph.DataSource.StartBatch();
for (int i = 0; i < graphData.chartData.Count; i++)
{
Graph.DataSource.AddPointToCategory("WorkConditionsData", i, graphData.chartData[i]);
graphChartData.Add(graphData.chartData[i]);
graphDateTimeData.Add(graphData.timeData[i]);
}
Graph.DataSource.EndBatch();
if (isMainChart)
{
Graph.OnRedraw.AddListener(SetChartLabels);
}
}
private void SetDataValue(GraphChartData graphData)
{
min = graphData.chartData.Min();
max = graphData.chartData.Max();
ave = graphData.chartData.Average();
AveValue.SetText(DecimalPointCalculate(ave));
if (isMainChart)
{
MinValue.SetText(DecimalPointCalculate(min));
MaxValue.SetText(DecimalPointCalculate(max));
}
else
{
GraphName.SetText(this.graphName);
}
}
private void SetChartLabels()
{
ClearLabels();
this.labelPos.Clear();
for (int i = 0; i < graphChartData.Count; i++)
{
Graph.PointToWorldSpace(out var worldSpace, i, graphChartData[i], "WorkConditionsData");
this.labelPos.Add(i, worldSpace);
}
var labelPos = DownSampleToFixedCount(this.labelPos, targetCount, startIndex);
foreach(var index in labelPos.Keys)
{
var date = Instantiate(prf_dateTime, Content_DateTime);
date.transform.position = new Vector3(labelPos[index].x, offsetY, 0);
date.SetDateTime(graphDateTimeData[index]);
}
}
private void ClearLabels()
{
if (Content_DateTime.childCount <= 0)
return;
for (int i = 0; i < Content_DateTime.childCount; i++)
{
Destroy(Content_DateTime.transform.GetChild(i).gameObject);
}
}
private Dictionary<int, Vector3> DownSampleToFixedCount(Dictionary<int, Vector3> labelPos, int targetCount, int startIndex)
{
Dictionary<int, Vector3> sampledData = new Dictionary<int, Vector3>();
if (labelPos.Count <= targetCount || targetCount <= 0)
return new Dictionary<int, Vector3>(labelPos);
if (startIndex < 0)
startIndex = 0;
List<int> keys = labelPos.Keys.OrderBy(k => k).ToList();
int totalCount = keys.Count;
if (startIndex >= totalCount)
startIndex = totalCount - 1;
int availableCount = totalCount - startIndex;
double interval = (double)(availableCount - 1) / (targetCount - 1);
for (int i = 0; i < targetCount; i++)
{
int indexInKeys = (int)Math.Round(startIndex + i * interval);
if (i == targetCount - 1)
indexInKeys = totalCount - 1;
if (indexInKeys >= totalCount)
indexInKeys = totalCount - 1;
int key = keys[indexInKeys];
if (!sampledData.ContainsKey(key))
sampledData.Add(key, labelPos[key]);
}
return sampledData;
}
private string DecimalPointCalculate(float value)
{
var floatValue = Mathf.Round(value * 10f) / 10f;
return floatValue.ToString();
}
}