制作曲线图数据

This commit is contained in:
lujiajian 2026-03-24 16:37:29 +08:00
parent df1ba524d1
commit 94fcb4feac
3 changed files with 123 additions and 43 deletions

View File

@ -11042,7 +11042,7 @@ MonoBehaviour:
objectValue: {fileID: 5627652597274816387}
dataValue:
variableType: 10
- name: "\u65F6\u957F\u8F93\u5165\u6846"
- name: "\u8FD0\u884C\u65F6\u957F\u8F93\u5165\u6846"
objectValue: {fileID: 5627652595602229817}
dataValue:
variableType: 10
@ -15539,8 +15539,8 @@ MonoBehaviour:
allowNegative: 0
allowEmpty: 0
maxDecimalPlaces: 1
minValue: -15
maxValue: 55
minValue: 16
maxValue: 32
--- !u!1 &5627652596662180239
GameObject:
m_ObjectHideFlags: 0
@ -17828,7 +17828,7 @@ MonoBehaviour:
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: "\u6E29\u5EA6\u8303\u56F4(-15\u2103~55\u2103)"
m_Text: "\u6E29\u5EA6\u8303\u56F4(16\u2103~32\u2103)"
--- !u!1 &5627652596936877788
GameObject:
m_ObjectHideFlags: 0
@ -23919,7 +23919,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
m_IsActive: 1
--- !u!224 &2218283927450267575
RectTransform:
m_ObjectHideFlags: 0
@ -23957,7 +23957,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 448, y: -11}
m_AnchoredPosition: {x: -650, y: -359.76}
m_SizeDelta: {x: 580, y: 300}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3579183680715366806

View File

@ -18,13 +18,13 @@ public class NumberInputField : MonoBehaviour
[Header("输入规则")]
[Tooltip("是否允许输入小数(小数点)")]
public bool allowDecimal = true;
[Tooltip("是否允许输入负数")]
public bool allowNegative = false;
[Tooltip("是否允许为空")]
public bool allowEmpty = true;
[Tooltip("小数点后最多几位0表示不限制")]
[Range(0, 10)]
public int maxDecimalPlaces = 2;
@ -38,11 +38,12 @@ public class NumberInputField : MonoBehaviour
private string previousValidText = "";
private InputField legacyInputField;
#if TMP_PRESENT
#if TMP_PRESENT
private TMP_InputField tmpInputField;
#endif
#endif
private bool isInitialized = false;
void Start()
{
InitializeInputField();
@ -68,7 +69,7 @@ public class NumberInputField : MonoBehaviour
{
targetInputField = legacyInputField;
}
#if TMP_PRESENT
#if TMP_PRESENT
else
{
tmpInputField = GetComponent<TMP_InputField>();
@ -77,17 +78,17 @@ public class NumberInputField : MonoBehaviour
targetInputField = tmpInputField;
}
}
#endif
#endif
}
else
{
legacyInputField = targetInputField as InputField;
#if TMP_PRESENT
legacyInputField = targetInputField.GetComponent<InputField>();
#if TMP_PRESENT
if (legacyInputField == null)
{
tmpInputField = targetInputField as TMP_InputField;
tmpInputField = targetInputField.GetComponent<TMP_InputField>();
}
#endif
#endif
}
if (targetInputField == null)
@ -100,15 +101,15 @@ public class NumberInputField : MonoBehaviour
if (legacyInputField != null)
{
previousValidText = legacyInputField.text;
legacyInputField.onValueChanged.AddListener(OnInputValueChanged);
legacyInputField.onEndEdit.AddListener(OnInputValueChanged);
}
#if TMP_PRESENT
#if TMP_PRESENT
else if (tmpInputField != null)
{
previousValidText = tmpInputField.text;
tmpInputField.onValueChanged.AddListener(OnInputValueChanged);
tmpInputField.onEndEdit.AddListener(OnInputValueChanged);
}
#endif
#endif
isInitialized = true;
}
@ -200,7 +201,7 @@ public class NumberInputField : MonoBehaviour
// 3. 检查小数点和数字
bool hasDecimalPoint = false;
int decimalPlaces = 0;
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
@ -213,7 +214,7 @@ public class NumberInputField : MonoBehaviour
if (!allowDecimal) return false; // 不允许小数
if (hasDecimalPoint) return false; // 已经有一个小数点了
hasDecimalPoint = true;
// 小数点不能是唯一字符(除非前面有符号)
if (i == 0 || (i == 1 && (str[0] == '-' || str[0] == '+')))
{
@ -248,10 +249,10 @@ public class NumberInputField : MonoBehaviour
private bool HasTooManyDecimalPlaces(string str)
{
if (maxDecimalPlaces <= 0 || !allowDecimal) return false;
int decimalIndex = str.IndexOf('.');
if (decimalIndex == -1) return false;
int decimalPlaces = str.Length - decimalIndex - 1;
return decimalPlaces > maxDecimalPlaces;
}
@ -262,15 +263,15 @@ public class NumberInputField : MonoBehaviour
private string TruncateDecimalPlaces(string str)
{
if (maxDecimalPlaces <= 0) return str;
int decimalIndex = str.IndexOf('.');
if (decimalIndex == -1) return str;
if (decimalIndex + 1 + maxDecimalPlaces < str.Length)
{
return str.Substring(0, decimalIndex + 1 + maxDecimalPlaces);
}
return str;
}
@ -292,12 +293,12 @@ public class NumberInputField : MonoBehaviour
{
legacyInputField.text = text;
}
#if TMP_PRESENT
#if TMP_PRESENT
else if (tmpInputField != null)
{
tmpInputField.text = text;
}
#endif
#endif
}
/// <summary>
@ -318,12 +319,12 @@ public class NumberInputField : MonoBehaviour
{
text = legacyInputField.text;
}
#if TMP_PRESENT
#if TMP_PRESENT
else if (tmpInputField != null)
{
text = tmpInputField.text;
}
#endif
#endif
if (string.IsNullOrEmpty(text) || text == "-" || text == "+" || text == ".")
{
@ -363,7 +364,7 @@ public class NumberInputField : MonoBehaviour
{
text = clampedValue.ToString("F" + maxDecimalPlaces);
}
SetInputFieldText(text);
previousValidText = text;
}
@ -399,11 +400,11 @@ public class NumberInputField : MonoBehaviour
{
legacyInputField.onValueChanged.RemoveListener(OnInputValueChanged);
}
#if TMP_PRESENT
#if TMP_PRESENT
if (tmpInputField != null)
{
tmpInputField.onValueChanged.RemoveListener(OnInputValueChanged);
}
#endif
#endif
}
}

View File

@ -215,7 +215,7 @@ public class EquipmentSimulationView : UIView
#region
void InitLeftBtns()
void InitLeftBtns()
{
// 初始化字典
@ -235,7 +235,7 @@ public class EquipmentSimulationView : UIView
{
SetSelectedButton(deviceBtns[0]);
}
}
}
private void OnButtonSelected(Button selectedButton, int index)
{
@ -352,7 +352,7 @@ public class EquipmentSimulationView : UIView
/**/
variables.Get<Button>("运行工况模拟").onClick.AddListener(delegate
{
SetHightlight(variables.Get<Button>("运行工况模拟"),modeData[0]);
SetHightlight(variables.Get<Button>("运行工况模拟"), modeData[0]);
SetNormal(variables.Get<Button>("高耗能场景模拟"), modeData[1]);
SetNormal(variables.Get<Button>("节能改造实操"), modeData[2]);
@ -424,6 +424,11 @@ public class EquipmentSimulationView : UIView
ShowWarming("请输入温度值!");
return;
}
else if (!(string.IsNullOrEmpty(variables.Get<InputField>("运行时长输入框").text.Trim())))
{
InitializeChart("运行工况", "时间", 5, "温度");
GenerateTemperatureChart(float.Parse(variables.Get<InputField>("运行时长输入框").text), float.Parse(variables.Get<InputField>("温度输入框").text));
}
}
if (variables.Get<InputField>("风速输入框").gameObject.activeSelf)
{
@ -433,6 +438,11 @@ public class EquipmentSimulationView : UIView
ShowWarming("请输入风速值!");
return;
}
else if (!(string.IsNullOrEmpty(variables.Get<InputField>("运行时长输入框").text.Trim())))
{
InitializeChart("运行工况", "时间", 5, "风速");
GenerateTemperatureChart(float.Parse(variables.Get<InputField>("运行时长输入框").text), float.Parse(variables.Get<InputField>("风速输入框").text));
}
}
if (string.IsNullOrEmpty(variables.Get<InputField>("运行时长输入框").text.Trim()))
{
@ -459,6 +469,8 @@ public class EquipmentSimulationView : UIView
{
Debug.Log($"{field.text}");
isEnterValue = true;
InitializeChart("能耗变化", "异常参数", 10, "能耗");
HighenErgyConsumptionChart(float.Parse(field.text));
}
}
}
@ -511,9 +523,9 @@ public class EquipmentSimulationView : UIView
/// <summary>
/// 折线设置
/// </summary>
private void InitializeChart(string title,string xAxisName,double yAxisMaxValue, string yAxisName)
private void InitializeChart(string title, string xAxisName, double yAxisMaxValue, string yAxisName)
{
lineChart.RemoveData();
lineChart.EnsureChartComponent<Title>().text = title;
@ -563,13 +575,13 @@ public class EquipmentSimulationView : UIView
}
// 生成图表主方法
public void GenerateTemperatureChart(float durationHours,float initialTemp)
public void GenerateTemperatureChart(float durationHours, float initialTemp)
{
// 生成温度数据
List<Vector2> temperatureData = GenerateTemperatureData(durationHours, initialTemp);
// 更新图表
UpdateChartWithData(temperatureData, durationHours);
UpdateChartWithData(temperatureData, 5);
}
// 生成温度数据
@ -582,13 +594,45 @@ public class EquipmentSimulationView : UIView
{
// 可以根据需要调整时间间隔
float time = hour;
float temperature = CalculateTemperatureAtHour(hour, initialTemp, durationHours);
float temperature = CalculateTemperatureAtHour_(hour, initialTemp, durationHours);
dataPoints.Add(new Vector2(time, temperature));
}
return dataPoints;
}
// 生成高耗能场景图表
public void HighenErgyConsumptionChart(float parameter)
{
// 生成温度数据
List<Vector2> temperatureData = GetDynamicChartPoints(parameter);
// 更新图表
UpdateChartWithData(temperatureData, 5);
}
/// <summary>
/// 根据当前故障程度,动态生成 X 轴和 Y 轴坐标点
/// </summary>
/// <param name="currentFault">当前的故障百分比数字 (如:输入 10 代表 10%)</param>
/// <returns>返回 3 个动态坐标点</returns>
public List<Vector2> GetDynamicChartPoints(float currentFault)
{
List<Vector2> points = new List<Vector2>();
// 1. 起点:永远是 (0, 基础能耗)
points.Add(new Vector2(0f, 100));
// 2. 中点X 轴是当前故障的一半Y 轴能耗也相应增加一半
float xMid = currentFault / 2f;
float yMid = 100 + (100 * (xMid / 100f)); // 按比例增加能耗
points.Add(new Vector2(xMid, yMid));
// 3. 终点X 轴达到当前故障值Y 轴达到目标能耗
float xEnd = currentFault;
float yEnd = 100 + (100 * (xEnd / 100f));
points.Add(new Vector2(xEnd, yEnd));
return points;
}
// 计算每小时温度 - 可自定义算法
private float CalculateTemperatureAtHour(int hour, float initialTemp, float totalDuration)
{
@ -607,7 +651,42 @@ public class EquipmentSimulationView : UIView
return maxTemp;
}
}
/// <summary>
/// 平滑显示温度曲线从0-initialTemp
/// </summary>
/// <param name="hour"></param>
/// <param name="initialTemp"></param>
/// <param name="totalDuration"></param>
/// <returns></returns>
private float CalculateTemperatureAtHour_(int hour, float initialTemp, float totalDuration)
{
// 固定从 0 度开始
float startTemp = 0f;
// 计算总体时间进度 (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<Vector2> dataPoints, float maxDuration)
{