using DG.Tweening;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
using SK.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using XCharts.Runtime;
///
/// 设备模拟界面,用于展示设备运行工况参数、高能耗场景参数和改造方案参数,并提供参数输入功能。
///
public class EquipmentSimulationView : UIView
{
public Variables variables;
//设备模型
private List devices = new List();
//设备运行工况参数面板
private List equipmentRuningInfo = new List();
//设备高能耗场景参数面板
private List equipmentUsingInfo = new List();
//设备改造方案参数面板
private List equipmentRepareInfo = new List();
//参数面板
private List parameterInfo = new List();
//空调参数输入框
private List inputFields_ac = new List();
//水泵参数输入框
private List inputFields_pump = new List();
//空压机参数输入框
private List inputFields_acp = new List();
private string repare_ac_name = "";
private string repare_pump_name = "";
private string repare_acp_name = "";
public List deviceBtns = new List();
[System.Serializable]
public class ButtonData
{
public Sprite normalSprite;
public Sprite selectedSprite;
}
public List buttonData = new List();
// 运行时使用的字典
private Dictionary buttonDictionary = new Dictionary();
private Button _currentSelectedButton;
private EnhancedModelViewerOrbitCamera enhancedModelViewerOrbitCamera;
public List modeData = new List();
#region 打字动画
//打字动画协程句柄,防止重复打字导致打字动画卡顿问题
private Coroutine typingCoroutine;
//打字动画速度,单位:秒/字符
private float typingSpeed = 0.05f;
#endregion
///
/// 设备开启面板
///
public List AllPanel;
///
/// 判断当前状态是打开还是关闭
///
public List Stepbools;
protected override void OnInit(IViewData data)
{
base.OnInit(data);
variables.Set("my_EquipmentSimulation", this);
enhancedModelViewerOrbitCamera = Camera.main.GetComponent();
devices.Clear();
GameObject trans = GameObject.Find("AllModels");
if (trans != null)
{
for (int i = 0; i < trans.transform.childCount; i++)
{
devices.Add(trans.transform.GetChild(i).gameObject);
devices[i].SetActive(false);
}
}
devices.RemoveAt(0);
devices[0].Activate();
InitLeftBtns();
SetSelectedButton(deviceBtns[0]);
ListInit();
DropdownInit();
//SimulationSelectInit();
BtnClickInit();
ToggleInit();
lineChart = variables.Get("LineChart").GetComponent();
}
///
/// 列表初始化,暂时没用到,留着以防万一
///
private void ListInit()
{
equipmentRuningInfo.Clear();
equipmentUsingInfo.Clear();
equipmentRepareInfo.Clear();
parameterInfo.Clear();
equipmentRuningInfo.Add(variables.Get("参数面板-空调"));
equipmentRuningInfo.Add(variables.Get("参数面板-水泵"));
equipmentRuningInfo.Add(variables.Get("参数面板-空压机"));
equipmentUsingInfo.Add(variables.Get("空调-高能耗"));
equipmentUsingInfo.Add(variables.Get("水泵-高能耗"));
equipmentUsingInfo.Add(variables.Get("空压机-高能耗"));
equipmentRepareInfo.Add(variables.Get("改造方案-空调"));
equipmentRepareInfo.Add(variables.Get("改造方案-水泵"));
equipmentRepareInfo.Add(variables.Get("改造方案-空压机"));
parameterInfo.Add(variables.Get("运行工况参数面板"));
parameterInfo.Add(variables.Get("高耗能场景参数面板"));
parameterInfo.Add(variables.Get("改造方案"));
inputFields_ac.Clear();
inputFields_pump.Clear();
inputFields_acp.Clear();
inputFields_ac.Add(variables.Get("堵塞输入框"));
inputFields_ac.Add(variables.Get("泄露输入框"));
inputFields_ac.Add(variables.Get("故障输入框"));
inputFields_pump.Add(variables.Get("预设阀门异常输入框"));
inputFields_pump.Add(variables.Get("叶轮磨损输入框"));
inputFields_pump.Add(variables.Get("管路堵塞输入框"));
inputFields_acp.Add(variables.Get("压力输入框"));
inputFields_acp.Add(variables.Get("泄漏量输入框"));
inputFields_acp.Add(variables.Get("电机过载输入框"));
}
///
/// 设备选择初始化
///
private void DropdownInit()
{
//variables.Get("设备列表").onValueChanged.AddListener((index) => OnEquipmentSelectChanged(index));
variables.Get("下拉框-空调-运行工况").onValueChanged.AddListener((index) => AcRuningDpValueChanged(index));
variables.Get("下拉框-空调-高能耗").onValueChanged.AddListener((index) => AcUsingDpValueChanged(index, inputFields_ac));
variables.Get("下拉框-水泵-高能耗").onValueChanged.AddListener((index) => AcUsingDpValueChanged(index, inputFields_pump));
variables.Get("下拉框-空压机-高能耗").onValueChanged.AddListener((index) => AcUsingDpValueChanged(index, inputFields_acp));
variables.Get("下拉框-空调-改造方案").onValueChanged.AddListener((index) => OnRepareCheck(index, 0));
variables.Get("下拉框-水泵-改造方案").onValueChanged.AddListener((index) => OnRepareCheck(index, 1));
variables.Get("下拉框-空压机-改造方案").onValueChanged.AddListener((index) => OnRepareCheck(index, 2));
}
///
/// 模拟场景选择初始化
///
private void SimulationSelectInit()
{
/*
Toggle[] toggles = variables.Get("模式选择").GetComponentsInChildren();
for (int i = 0; i < toggles.Length; i++)
{
int index = i;
toggles[i].onValueChanged.AddListener((isOn) => OnSimulationSelectChanged(isOn, index));
}*/
}
///
/// 模拟场景选择改变事件回调函数
///
///
private void OnSimulationSelectChanged(int index)
{
//if (isOn)
{
//Debug.Log($"{index},{parameterInfo.Count}");
for (int i = 0; i < parameterInfo.Count; i++)
{
if (i == index)
{
parameterInfo[i].Activate();
}
else
{
parameterInfo[i].Deactivate();
}
}
}
}
///
/// 设备选择改变事件回调函数,根据选择的设备显示对应的参数面板和改造方案信息面板。
///
///
private void OnEquipmentSelectChanged(int index)
{
if (index < 0 || index > equipmentRuningInfo.Count)
{
ShowWarming($"数组越界异常!请检查设备列表索引是否正确!{index}_{equipmentRuningInfo.Count}");
return;
}
for (int i = 0; i < equipmentRuningInfo.Count; i++)
{
if (i == index)
{
equipmentRuningInfo[i].Activate();
equipmentUsingInfo[i].Activate();
equipmentRepareInfo[i].Activate();
}
else
{
equipmentRuningInfo[i].Deactivate();
equipmentUsingInfo[i].Deactivate();
equipmentRepareInfo[i].Deactivate();
}
}
}
#region 切换设备
void InitLeftBtns()
{
// 初始化字典
for (int i = 0; i < deviceBtns.Count; i++)
{
buttonDictionary[deviceBtns[i]] = buttonData[i];
SetNormal(deviceBtns[i], buttonData[i]);
// 添加点击事件
int index = i; // 闭包需要
deviceBtns[i].onClick.AddListener(() => OnButtonSelected(deviceBtns[index], index));
}
// 设置默认选中
if (deviceBtns.Count > 0)
{
SetSelectedButton(deviceBtns[0]);
}
}
private void OnButtonSelected(Button selectedButton, int index)
{
if (_currentSelectedButton == selectedButton) return;
// 取消上一个按钮的选中
if (_currentSelectedButton != null && buttonDictionary.ContainsKey(_currentSelectedButton))
{
SetNormal(_currentSelectedButton, buttonDictionary[_currentSelectedButton]);
}
OnEquipmentSelectChanged(index);
for (int i = 0; i < devices.Count; i++)
{
if (i == index)
{
devices[i].Activate();
Debug.Log("_____________+_____________");
ShowPanel(selectedButton.name);
enhancedModelViewerOrbitCamera.SetTarget(devices[i].transform);
}
else
{
devices[i].Deactivate();
Debug.Log("+++++++++++++++");
// 设置新按钮的选中
SetSelectedButton(selectedButton);
}
}
}
public void ShowPanel(string BtnName)
{
switch (BtnName)
{
case "空调":
UIView.Get().variables.Get("楼层").Activate();
UIView.Get().variables.Get("参数面板空调").Activate();
UIView.Get().variables.Get("参数面板水泵").Deactivate();
UIView.Get().variables.Get("空调操作步骤").Activate();
UIView.Get().variables.Get("togglegroup").Deactivate();
UIView.Get().variables.Get("参数面板空调").Activate();
UIView.Get().variables.Get("一键启停-空压机").Deactivate();
UIView.Get().variables.Get("一键启停-泵").Deactivate();
break;
case "泵":
UIView.Get().variables.Get("楼层").Deactivate();
UIView.Get().variables.Get("参数面板空调").Deactivate();
UIView.Get().variables.Get("参数面板水泵").Deactivate();
UIView.Get().variables.Get("空调操作步骤").Deactivate();
UIView.Get().variables.Get("togglegroup").Activate();
UIView.Get().variables.Get("参数面板空调").Deactivate();
UIView.Get().variables.Get("一键启停-空压机").Deactivate();
UIView.Get().variables.Get("一键启停-泵").Activate();
BengPanel();
break;
case "空压机":
UIView.Get().variables.Get("楼层").Deactivate();
UIView.Get().variables.Get("参数面板空调").Deactivate();
UIView.Get().variables.Get("参数面板水泵").Deactivate();
UIView.Get().variables.Get("空调操作步骤").Deactivate();
UIView.Get().variables.Get("togglegroup").Activate();
UIView.Get().variables.Get("参数面板空调").Deactivate();
UIView.Get().variables.Get("一键启停-空压机").Activate();
UIView.Get().variables.Get("一键启停-泵").Deactivate();
FengJiPanel();
break;
default:
break;
}
}
public void SetSelectedButton(Button button)
{
if (!buttonDictionary.ContainsKey(button))
{
Debug.LogWarning($"按钮 {button.name} 不在管理列表中");
return;
}
_currentSelectedButton = button;
SetHightlight(button, buttonDictionary[button]);
}
#endregion
///
/// 空调运行工况下拉框改变事件回调函数,根据选择的运行模式显示对应的输入框。
///
///
private void AcRuningDpValueChanged(int index)
{
if (index == 2)
{
variables.Get("风速输入框").Activate();
variables.Get("温度输入框").Deactivate();
}
else
{
variables.Get("风速输入框").Deactivate();
variables.Get("温度输入框").Activate();
}
}
///
/// 空调高能耗下拉框改变事件回调函数
///
///
private void AcUsingDpValueChanged(int index, List target)
{
if (index < 0 || index > target.Count)
{
ShowWarming("索引越界");
//Debug.LogError($"索引越界_{index}_{target.Count}");
return;
}
for (int i = 0; i < target.Count; i++)
{
if (target[i] != null)
{
if (i == index)
target[i].Activate();
else
target[i].Deactivate();
}
}
}
///
/// 改造方案下拉框改变事件回调函数,获取选择的改造方案名称
///
///
private void OnRepareCheck(int index, int type)
{
switch (type)
{
case 0:
repare_ac_name = variables.Get("下拉框-空调-改造方案").options[index].text;
break;
case 1:
repare_pump_name = variables.Get("下拉框-水泵-改造方案").options[index].text;
break;
case 2:
repare_acp_name = variables.Get("下拉框-空压机-改造方案").options[index].text;
break;
}
}
///
/// 按钮点击事件初始化
///
private void BtnClickInit()
{
/**/
variables.Get("运行工况模拟").onClick.AddListener(delegate
{
SetHightlight(variables.Get("运行工况模拟"), modeData[0]);
SetNormal(variables.Get("高耗能场景模拟"), modeData[1]);
SetNormal(variables.Get("节能改造实操"), modeData[2]);
OnSimulationSelectChanged(0);
//OnEquipmentSelectChanged(0);
});
variables.Get("高耗能场景模拟").onClick.AddListener(delegate
{
SetNormal(variables.Get("运行工况模拟"), modeData[0]);
SetHightlight(variables.Get("高耗能场景模拟"), modeData[1]);
SetNormal(variables.Get("节能改造实操"), modeData[2]);
OnSimulationSelectChanged(1);
//OnEquipmentSelectChanged(1);
});
variables.Get("节能改造实操").onClick.AddListener(delegate
{
SetNormal(variables.Get("运行工况模拟"), modeData[0]);
SetNormal(variables.Get("高耗能场景模拟"), modeData[1]);
SetHightlight(variables.Get("节能改造实操"), modeData[2]);
OnSimulationSelectChanged(2);
//OnEquipmentSelectChanged(2);
});
SetHightlight(variables.Get("运行工况模拟"), modeData[0]);
variables.Get("启动运行-空调-运行工况").onClick.AddListener(delegate
{
AcRuning();
});
variables.Get("启动运行-空调-高能耗").onClick.AddListener(delegate
{
RuningCheck(inputFields_ac);
});
variables.Get("启动运行-水泵-高能耗").onClick.AddListener(delegate
{
RuningCheck(inputFields_pump);
});
variables.Get("启动运行-空压机-高能耗").onClick.AddListener(delegate
{
RuningCheck(inputFields_acp);
});
variables.Get("启动改造-空调-改造方案").onClick.AddListener(delegate
{
RepareCheck(0);
});
variables.Get("启动改造-水泵-改造方案").onClick.AddListener(delegate
{
RepareCheck(1);
});
variables.Get("启动改造-空压机-改造方案").onClick.AddListener(delegate
{
RepareCheck(2);
});
variables.Get("关闭界面").onClick.AddListener(delegate
{
Unload();
Load();
});
//开启
variables.Get("启动运行-冷却塔风机1").onClick.AddListener(delegate
{
Stepbools[0] = true;
SBStartOperation("开启冷却塔风机1成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-冷却塔风机1"));
});
variables.Get("启动运行-冷却塔风机2").onClick.AddListener(delegate
{
Stepbools[1] = true;
SBStartOperation("开启冷却塔风机2成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-冷却塔风机2"));
});
variables.Get("启动运行-冷却泵1").onClick.AddListener(delegate
{
if (variables.Get("水流开关1").isOn == true)
{
Stepbools[2] = true;
SBStartOperation("启动运行-冷却泵成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-冷却泵1"));
}
else
{
ShowWarming("启动水泵前请打开水流开关");
}
});
variables.Get("启动运行-冷却泵2").onClick.AddListener(delegate
{
if (variables.Get("水流开关2").isOn == true)
{
Stepbools[3] = true;
SBStartOperation("启动运行-冷却泵成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-冷却泵2"));
}
else
{
ShowWarming("启动水泵前请打开水流开关");
}
});
variables.Get("启动运行-风机盘管1").onClick.AddListener(delegate
{
if (variables.Get("水流开关1").isOn == true && variables.Get("水流开关2").isOn == true)
{
Stepbools[4] = true;
SBStartOperation("启动风机盘管成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-风机盘管1"));
}
else
{
ShowWarming("启动风机盘管前请打开冷冻泵");
}
});
variables.Get("启动运行-风机盘管2").onClick.AddListener(delegate
{
if (variables.Get("水流开关1").isOn == true && variables.Get("水流开关2").isOn == true)
{
Stepbools[5] = true;
SBStartOperation("启动风机盘管成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-风机盘管2"));
}
else
{
ShowWarming("启动风机盘管前请打开冷冻泵");
}
});
variables.Get("启动运行-中央空调主机").onClick.AddListener(delegate
{
Stepbools[6] = true;
SBStartOperation("开启中央空调主机成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-中央空调主机"));
});
//关闭
variables.Get("停止运行-冷却塔风机1").onClick.AddListener(delegate
{
Stepbools[0] = false;
SBStartOperation("关闭冷却塔风机1成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-冷却塔风机1"));
});
variables.Get("停止运行-冷却塔风机2").onClick.AddListener(delegate
{
Stepbools[1] = false;
SBStartOperation("关闭冷却塔风机2成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-冷却塔风机2"));
});
variables.Get("停止运行-冷却泵1").onClick.AddListener(delegate
{
if (variables.Get("水流开关1").isOn == false)
{
Stepbools[2] = false;
SBStartOperation("停止运行冷却泵1成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-冷却泵1"));
}
else
{
ShowWarming("停止水泵1前请关闭水流开关");
}
});
variables.Get("停止运行-冷却泵2").onClick.AddListener(delegate
{
if (variables.Get("水流开关2").isOn == false)
{
Stepbools[3] = false;
SBStartOperation("停止运行冷却泵2成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-冷却泵2"));
}
else
{
ShowWarming("停止水泵2前请关闭水流开关");
}
});
variables.Get("停止运行-风机盘管1").onClick.AddListener(delegate
{
if (variables.Get("水流开关1").isOn == false && variables.Get("水流开关2").isOn == false)
{
Stepbools[4] = false;
SBStartOperation("停止风机盘管成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-风机盘管1"));
}
else
{
ShowWarming("关闭风机盘管前请关闭冷冻泵");
}
});
variables.Get("停止运行-风机盘管2").onClick.AddListener(delegate
{
if (variables.Get("水流开关1").isOn == false && variables.Get("水流开关2").isOn == false)
{
Stepbools[5] = false;
SBStartOperation("停止风机盘管成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-风机盘管2"));
}
else
{
ShowWarming("关闭风机盘管前请关闭冷冻泵");
}
});
variables.Get("停止运行-中央空调主机").onClick.AddListener(delegate
{
Stepbools[6] = false;
SBStartOperation("关闭中央空调主机成功");
StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-中央空调主机"));
});
variables.Get("启动运行-泵").onClick.AddListener(delegate
{
Stepbools[7] = true;
GameMangner_TSQ.instance.bengStartOrStop(true);
SBStartOperation("开启泵成功");
UIView.Get().variables.Get("泵机Text").text = "关闭泵";
UIView.Get().variables.Get("启动运行-泵").Deactivate();
UIView.Get().variables.Get("停止运行-泵").Activate();
//StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-中央空调主机"));
});
variables.Get("停止运行-泵").onClick.AddListener(delegate
{
Stepbools[7] = false;
SBStartOperation("关闭泵成功");
GameMangner_TSQ.instance.bengStartOrStop(false);
UIView.Get().variables.Get("泵机Text").text = "开启泵";
UIView.Get().variables.Get("启动运行-泵").Activate();
UIView.Get().variables.Get("停止运行-泵").Deactivate();
//StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-中央空调主机"));
});
variables.Get("启动运行-空压机").onClick.AddListener(delegate
{
Stepbools[8] = true;
SBStartOperation("开启空压机成功");
GameMangner_TSQ.instance.FengJiStartOrStop(true);
UIView.Get().variables.Get("空压机主机Text").text = "关闭空压机";
UIView.Get().variables.Get("启动运行-空压机").Deactivate();
UIView.Get().variables.Get("停止运行-空压机").Activate();
//StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-中央空调主机"));
});
variables.Get("停止运行-空压机").onClick.AddListener(delegate
{
Stepbools[8] = false;
SBStartOperation("关闭空压机成功");
GameMangner_TSQ.instance.FengJiStartOrStop(false);
UIView.Get().variables.Get("空压机主机Text").text = "开启空压机";
UIView.Get().variables.Get("启动运行-空压机").Activate();
UIView.Get().variables.Get("停止运行-空压机").Deactivate();
//StartCoroutine(EquipmentIIntroduction_TSQ.instance.AutoHide(4, "参数面板-中央空调主机"));
});
variables.Get("启动改造-空压机-改造方案").onClick.AddListener(delegate
{
RepareCheck(2);
});
variables.Get("启动改造-空压机-改造方案").onClick.AddListener(delegate
{
RepareCheck(2);
});
}
///
/// 空调运行工况模拟按钮点击事件回调函数
///
private void AcRuning()
{
//TODO:根据不同温度,风速,运行时长,显示不同的timeline动画
if (variables.Get("温度输入框").gameObject.activeSelf)
{
if (string.IsNullOrEmpty(variables.Get("温度输入框").text.Trim()))
{ //TODO:提醒用户输入温度
ShowWarming("请输入温度值!");
return;
}
else if (!(string.IsNullOrEmpty(variables.Get("运行时长输入框").text.Trim())))
{
InitializeChart("运行工况", "时间", 5, "温度");
GenerateTemperatureChart(float.Parse(variables.Get("运行时长输入框").text), float.Parse(variables.Get("温度输入框").text));
}
}
if (variables.Get("风速输入框").gameObject.activeSelf)
{
if (string.IsNullOrEmpty(variables.Get("风速输入框").text.Trim()))
{
//TODO:提醒用户输入风速
ShowWarming("请输入风速值!");
return;
}
else if (!(string.IsNullOrEmpty(variables.Get("运行时长输入框").text.Trim())))
{
InitializeChart("运行工况", "时间", 5, "风速");
GenerateTemperatureChart(float.Parse(variables.Get("运行时长输入框").text), float.Parse(variables.Get("风速输入框").text));
}
}
if (string.IsNullOrEmpty(variables.Get("运行时长输入框").text.Trim()))
{
//TODO:提醒用户输入运行时长
ShowWarming("请输入运行时长!");
return;
}
//TODO:根据输入的参数,播放对应的timeline动画
}
///
/// 启动检查
///
///
private void RuningCheck(List target)
{
bool isEnterValue = false;
foreach (InputField field in target)
{
if (field.gameObject.activeSelf)
{
if (!string.IsNullOrEmpty(field.text) && !string.IsNullOrWhiteSpace(field.text))
{
Debug.Log($"{field.text}");
isEnterValue = true;
InitializeChart("能耗变化", "异常参数", 10, "能耗");
HighenErgyConsumptionChart(float.Parse(field.text));
}
}
}
if (!isEnterValue)
{
//Debug.LogError($"没有键入有效参数!");
ShowWarming("没有键入有效参数!");
return;
}
//TODO: 显示不同的曲线信息
}
///
/// 改造检查-空调
/// x
private void RepareCheck(int type)
{
switch (type)
{
case 0:
if (string.IsNullOrEmpty(repare_ac_name))
{
ShowWarming("请选择改造方案!");
return;
}
lineChart.RemoveData();
series = new List();
series.Add(InitializeChart_Serie("能耗变化", "异常参数", 10, "改造前"));
series.Add(InitializeChart_Serie("能耗变化", "异常参数", 10, "改造后"));
EnergySavingChart(0);
EnergySavingChart(1);
break;
case 1:
if (string.IsNullOrEmpty(repare_pump_name))
{
ShowWarming("请选择改造方案!");
return;
}
series.Add(InitializeChart_Serie("能耗变化", "异常参数", 10, "改造前"));
series.Add(InitializeChart_Serie("能耗变化", "异常参数", 10, "改造后"));
EnergySavingChart(0);
EnergySavingChart(1);
break;
case 2:
if (string.IsNullOrEmpty(repare_acp_name))
{
ShowWarming("请选择改造方案!");
return;
}
series.Add(InitializeChart_Serie("能耗变化", "异常参数", 10, "改造前"));
series.Add(InitializeChart_Serie("能耗变化", "异常参数", 10, "改造后"));
EnergySavingChart(0);
EnergySavingChart(1);
break;
}
}
#region 图表
private Serie serie;
private LineChart lineChart;
private List series = new List();//存储多个series图表
///
/// 折线设置
///
private void InitializeChart(string title, string xAxisName, double yAxisMaxValue, string yAxisName)
{
lineChart.RemoveData();
lineChart.EnsureChartComponent().text = title;
// 设置X轴(时间轴)
var xAxis = lineChart.EnsureChartComponent();
xAxis.show = true;
xAxis.type = Axis.AxisType.Value;
xAxis.min = 0;
xAxis.axisName.name = xAxisName;
// 设置Y轴(温度轴)
var yAxis = lineChart.EnsureChartComponent();
yAxis.show = true;
yAxis.type = Axis.AxisType.Value;
yAxis.min = 0;
yAxis.max = yAxisMaxValue;
yAxis.axisName.name = yAxisName;
// 添加折线序列
serie = lineChart.AddSerie();
if (serie != null)
{
//serie.serieName = "温度变化";
serie.serieName = yAxisName;
serie.symbol.show = true;
serie.symbol.size = 5f;
serie.lineType = LineType.Normal;
serie.lineStyle.width = 3f;
serie.animation.enable = true;
// 设置颜色
serie.lineStyle.color = Color.red;
serie.symbol.color = Color.blue;
}
// 设置提示框
var tooltip = lineChart.GetChartComponent();
if (tooltip == null) tooltip = lineChart.AddChartComponent();
tooltip.show = true;
tooltip.type = Tooltip.Type.Line;
// 设置图例
var legend = lineChart.GetChartComponent();
if (legend == null) legend = lineChart.AddChartComponent();
legend.show = true;
//legend.data = new List { "温度变化" };
legend.data = new List { yAxisName };
}
///
/// 多个折线设置,返回Serie
///
private Serie InitializeChart_Serie(string title, string xAxisName, double yAxisMaxValue, string yAxisName)
{
// 标题
lineChart.EnsureChartComponent().text = title;
// X轴
var xAxis = lineChart.EnsureChartComponent();
xAxis.show = true;
xAxis.type = Axis.AxisType.Value;
xAxis.min = 0;
xAxis.axisName.name = xAxisName;
// Y轴
var yAxis = lineChart.EnsureChartComponent();
yAxis.show = true;
yAxis.type = Axis.AxisType.Value;
yAxis.min = 0;
yAxis.max = yAxisMaxValue;
yAxis.axisName.name = yAxisName;
// 折线系列
var serie = lineChart.AddSerie();
if (serie != null)
{
serie.serieName = yAxisName;
serie.symbol.show = true;
serie.symbol.size = 5f;
serie.lineType = LineType.Normal;
serie.lineStyle.width = 3f;
serie.animation.enable = true;
serie.lineStyle.color = Color.red;
serie.symbol.color = Color.blue;
}
// 提示框
var tooltip = lineChart.GetChartComponent();
if (tooltip == null) tooltip = lineChart.AddChartComponent();
tooltip.show = true;
tooltip.type = Tooltip.Type.Line;
// 图例
var legend = lineChart.GetChartComponent();
if (legend == null) legend = lineChart.AddChartComponent();
legend.show = true;
legend.data = new List { yAxisName };
return serie;
}
// 生成图表主方法
private void GenerateTemperatureChart(float durationHours, float initialTemp)
{
// 生成温度数据
List temperatureData = GenerateTemperatureData(durationHours, initialTemp);
// 更新图表
UpdateChartWithData(temperatureData, 5);
}
// 生成温度数据
private List GenerateTemperatureData(float durationHours, float initialTemp)
{
List dataPoints = new List();
// 生成时间点(每小时一个点)
for (int hour = 0; hour <= durationHours; hour++)
{
// 可以根据需要调整时间间隔
float time = hour;
float temperature = CalculateTemperatureAtHour_(hour, initialTemp, durationHours);
dataPoints.Add(new Vector2(time, temperature));
}
return dataPoints;
}
// 生成高耗能场景图表
private void HighenErgyConsumptionChart(float parameter)
{
// 生成温度数据
List temperatureData = GetDynamicChartPoints(parameter);
// 更新图表
UpdateChartWithData(temperatureData, 5);
}
///
/// 生成节能改造图表
///
///
/// 数据表下标
private void EnergySavingChart(int indext)
{
// 生成温度数据
List temperatureData = Energysavingdata(indext);
// 更新图表
UpdateEnergySavingChartWithData(temperatureData, 5, indext);
}
//------"改造前参数"
float beforeStartEnergy = 20f; // 起始能耗
float beforePeakEnergy = 50; // 峰值(平稳段的值)
[Range(0, 1)] public float beforePlateauStart = 0.7f; // 平稳开始点(0~1),默认70%处开始平稳
//------"改造前参数"
//------"改造后参数"
float afterStartEnergy = 15f; // 起始能耗(必须低于改造前起始,保证始终低于)
float afterPeakEnergy = 40; // 平稳段峰值(必须小于改造前峰值)
float afterPlateauStart = 0.5f; // 平稳开始点(0~1),默认50%处开始平稳
float afterFluctuation = 0.5f; // 改造后波动幅度(微小波动)
//------"改造后参数"
public List Energysavingdata(int indext)
{
RandomValue();
List data = new List();
if (indext == 0)
{
// 生成数据点
for (int i = 0; i <= 10; i++) // 包含端点,共 pointCount+1 个点
{
float t = (float)i / 10; // 归一化进度 [0,1]
float x = t * 24; // X坐标(时间)
// --- 改造前数据 ---
float beforeEnergy;
if (t <= beforePlateauStart)
{
// 上升阶段:线性插值
float progress = t / beforePlateauStart; // 0~1
beforeEnergy = Mathf.Lerp(beforeStartEnergy, beforePeakEnergy, progress);
}
else
{
// 平稳阶段:保持峰值
beforeEnergy = beforePeakEnergy;
}
// 添加数据点 (x, y)
data.Add(new Vector2(x, beforeEnergy));
}
return data;
}
else
{
for (int i = 0; i <= 10; i++) // 包含端点,共 pointCount+1 个点
{
float t = (float)i / 10; // 归一化进度 [0,1]
float x = t * 24; // X坐标(时间)
float afterEnergy;
if (t <= afterPlateauStart)
{
// 上升阶段:线性插值(更缓)
float progress = t / afterPlateauStart;
afterEnergy = Mathf.Lerp(afterStartEnergy, afterPeakEnergy, progress);
}
else
{
// 平稳阶段:保持峰值 + 微小正弦波动
afterEnergy = afterPeakEnergy + afterFluctuation * Mathf.Sin(x * 0.8f);
}
data.Add(new Vector2(x, afterEnergy));
}
return data;
}
}
///
/// 随机生成改造前改造后数值
///
private void RandomValue()
{
beforeStartEnergy = UnityEngine.Random.Range(20, 50);// 起始能耗
beforePeakEnergy = UnityEngine.Random.Range(50, 80);// 峰值(平稳段的值)
beforePlateauStart = UnityEngine.Random.Range(0.5f, 0.8f);// 平稳开始点(0~1),0.5为50%处开始平稳
afterStartEnergy = UnityEngine.Random.Range(10, 20); // 起始能耗(必须低于改造前起始,保证始终低于)
afterPeakEnergy = UnityEngine.Random.Range(40, 49); // 平稳段峰值(必须小于改造前峰值)
afterPlateauStart = UnityEngine.Random.Range(0.4f, 0.7f); // 平稳开始点(0~1),默认50%处开始平稳
afterFluctuation = UnityEngine.Random.Range(0.3f, 0.7f); // 改造后波动幅度(微小波动)
}
///
/// 根据当前故障程度,动态生成 X 轴和 Y 轴坐标点
///
/// 当前的故障百分比数字 (如:输入 10 代表 10%)
/// 返回 3 个动态坐标点
public List GetDynamicChartPoints(float currentFault)
{
List points = new List();
float starpower = UnityEngine.Random.Range(0, 100);
// 1. 起点:永远是 (0, 基础能耗)
points.Add(new Vector2(0f, starpower));
// 2. 中点:X 轴是当前故障的一半,Y 轴能耗也相应增加一半
float xMid = currentFault / 2f;
float yMid = starpower + (starpower * (xMid / starpower)); // 按比例增加能耗
points.Add(new Vector2(xMid, yMid));
// 3. 终点:X 轴达到当前故障值,Y 轴达到目标能耗
float xEnd = currentFault;
float yEnd = starpower + (starpower * (xEnd / starpower));
points.Add(new Vector2(xEnd, yEnd));
return points;
}
// 计算每小时温度 - 可自定义算法
private float CalculateTemperatureAtHour(int hour, float initialTemp, float totalDuration)
{
// 示例1: 指数升温然后稳定
float maxTemp = initialTemp + 30f;
float timeFactor = hour / totalDuration;
if (timeFactor < 0.7f)
{
// 前70%时间指数升温
return initialTemp + (maxTemp - initialTemp) * (1 - Mathf.Exp(-timeFactor * 3));
}
else
{
// 后30%时间保持稳定
return maxTemp;
}
}
///
/// 平滑显示温度曲线,从0-initialTemp
///
///
///
///
///
private float CalculateTemperatureAtHour_(int hour, float initialTemp, float totalDuration)
{
// 固定从 0 度开始
float startTemp = UnityEngine.Random.Range(0, 25);
// 计算总体时间进度 (0.0 到 1.0)
float timeFactor = Mathf.Clamp01((float)hour / totalDuration);
float currentTemp;
if (timeFactor < 0.7f)
{
// 前 70% 时间:从 0 指数升温
// 为了让升温在 70% 的节点刚好平滑到达终点,我们将 0~0.7 的进度重新映射为 0~1
float normalizedTime = timeFactor / 0.7f;
// 使用指数公式:当 normalizedTime 接近 1 时,1 - Exp(-5) 非常接近 1 (约0.993)
// 这样温度就会从 0 平滑地上升到 initialTemp
currentTemp = startTemp + (initialTemp - startTemp) * (1 - Mathf.Exp(-5f * normalizedTime));
}
else
{
// 后 30% 时间:保持稳定在最高温
currentTemp = initialTemp;
}
// 最终安全限制:确保返回值被严格卡在 0 到 initialTemp 之间
return Mathf.Clamp(currentTemp, 0f, initialTemp);
}
// 更新图表数据
private void UpdateChartWithData(List dataPoints, float maxDuration)
{
if (serie == null) return;
// 清空序列数据
serie.ClearData();
// 添加新数据点
foreach (var point in dataPoints)
{
serie.AddXYData(point.x, point.y);
//serie.AddData(new List { point.x, point.y }, dataPoints.IndexOf(point));
}
// 更新X轴范围
var xAxis = lineChart.GetChartComponent();
if (xAxis != null)
{
xAxis.max = maxDuration;
xAxis.splitNumber = Mathf.Max(1, Mathf.FloorToInt(maxDuration));
}
// 自动调整Y轴范围
var yAxis = lineChart.GetChartComponent();
if (yAxis != null)
{
// 找到最小最大值
float minTemp = float.MaxValue;
float maxTemp = float.MinValue;
foreach (var point in dataPoints)
{
if (point.y < minTemp) minTemp = point.y;
if (point.y > maxTemp) maxTemp = point.y;
}
// 设置Y轴范围,留出10%边距
float margin = (maxTemp - minTemp) * 0.1f;
yAxis.min = Mathf.Floor(minTemp - margin);
yAxis.max = Mathf.Ceil(maxTemp + margin);
}
// 重绘图表
lineChart.RefreshChart();
}
// 更新节能改造图表数据
private void UpdateEnergySavingChartWithData(List dataPoints, float maxDuration, int serieindex)
{
if (series[serieindex] == null) return;
// 清空序列数据
series[serieindex].ClearData();
// 添加新数据点
foreach (var point in dataPoints)
{
series[serieindex].AddXYData(point.x, point.y);
//serie.AddData(new List { point.x, point.y }, dataPoints.IndexOf(point));
}
// 更新X轴范围
var xAxis = lineChart.GetChartComponent();
if (xAxis != null)
{
xAxis.max = maxDuration;
xAxis.splitNumber = Mathf.Max(1, Mathf.FloorToInt(maxDuration));
}
// 自动调整Y轴范围
var yAxis = lineChart.GetChartComponent();
if (yAxis != null)
{
// 找到最小最大值
float minTemp = float.MaxValue;
float maxTemp = float.MinValue;
foreach (var point in dataPoints)
{
if (point.y < minTemp) minTemp = point.y;
if (point.y > maxTemp) maxTemp = point.y;
}
// 设置Y轴范围,留出10%边距
float margin = (maxTemp - minTemp) * 0.1f;
yAxis.min = Mathf.Floor(minTemp - margin);
yAxis.max = Mathf.Ceil(maxTemp + margin);
}
// 重绘图表
lineChart.RefreshChart();
}
// 添加多种温度变化模式
public void SetTemperatureMode(int mode, float durationHours, float initialTemp)
{
//if (!float.TryParse(durationInput.text, out float durationHours) ||
// !float.TryParse(initialTempInput.text, out float initialTemp))
//{
// return;
//}
List dataPoints = new List();
for (int hour = 0; hour <= durationHours; hour++)
{
float temperature = 0f;
switch (mode)
{
case 0: // 线性升温
temperature = initialTemp + 2f * hour;
break;
case 1: // 指数升温
temperature = initialTemp + 20f * (1 - Mathf.Exp(-hour * 0.5f));
break;
case 2: // 正弦波动
temperature = initialTemp + 10f + 5f * Mathf.Sin(hour * Mathf.PI / durationHours);
break;
case 3: // 阶梯式上升
temperature = initialTemp + 5f * Mathf.Floor(hour / 2);
break;
}
dataPoints.Add(new Vector2(hour, temperature));
}
UpdateChartWithData(dataPoints, durationHours);
}
// 添加实时数据功能
public void StartRealTimeUpdate(float initialTemp)
{
//if (!float.TryParse(initialTempInput.text, out float initialTemp))
// return;
StartCoroutine(RealTimeTemperatureUpdate(initialTemp));
}
private System.Collections.IEnumerator RealTimeTemperatureUpdate(float initialTemp)
{
float elapsedTime = 0f;
List dataPoints = new List();
while (elapsedTime < 10f) // 模拟10秒实时数据
{
// 添加新数据点
float temperature = initialTemp + UnityEngine.Random.Range(-2f, 2f) + elapsedTime * 2f;
dataPoints.Add(new Vector2(elapsedTime, temperature));
// 更新图表
UpdateChartWithData(dataPoints, elapsedTime);
elapsedTime += 0.5f; // 每0.5秒更新一次
yield return new WaitForSeconds(0.5f);
}
}
// 清空图表
public void ClearChart()
{
if (serie != null)
{
serie.ClearData();
}
if (lineChart != null)
{
lineChart.RefreshChart();
}
}
#endregion
#region 警告提示
///
/// 显示警告信息
///
///
private void ShowWarming(string warmingText)
{
if (string.IsNullOrEmpty(warmingText.Trim())) return;
if (!variables.Get("警告").gameObject.activeSelf)
variables.Get