WaterTrendPanel.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using Best.HTTP.JSON;
  7. using Bitsplash.DatePicker;
  8. using Newtonsoft.Json;
  9. using UnityEngine;
  10. using UnityEngine.UI;
  11. using XCharts.Runtime;
  12. public class WaterTrendPanel : MonoBehaviour
  13. {
  14. public LineChart _LineChart;
  15. public Text nameText;
  16. public GameObject listItemOri;
  17. public List<GameObject> listObj = new List<GameObject>();
  18. public Button closeButton;
  19. public string currentStcd;
  20. public string currentName;
  21. public Transform listRoot;
  22. public DatePickerDropDownTextMeshPro DatePicker_Start;
  23. public DatePickerDropDownTextMeshPro DatePicker_End;
  24. public string startDateStr = "";
  25. public string endDateStr = "";
  26. public Button lineChartBtn;
  27. public Button infoBtn;
  28. public RectTransform lineChartPanel;
  29. public RectTransform infoPanel;
  30. public int currentType;
  31. public Text typeTitle;
  32. public Text idText;
  33. public Text stnmText;
  34. public Text stcdText;
  35. public Text stlcText;
  36. public Text sttpText;
  37. public Text addvcdText;
  38. public Text bsnmText;
  39. public Text hnnmText;
  40. public Text rvnmText;
  41. public Text lgtdText;
  42. public Text lttdText;
  43. public Text dtmnmText;
  44. public Text dtmelText;
  45. public Text atcunitText;
  46. public Text localityText;
  47. public Text frgrdText;
  48. public Text usflText;
  49. public Button searchButton;
  50. public GameObject threePanel;
  51. public GameObject bythreePanel;
  52. public GameObject taokouthreePanel;
  53. public void Init()
  54. {
  55. _LineChart = this.transform.Find("linePanel/LineChart").GetComponent<LineChart>();
  56. listRoot = this.transform.Find("linePanel/ScrollView/Viewport/Content").transform;
  57. closeButton = this.transform.Find("CloseButton").GetComponent<Button>();
  58. nameText = this.transform.Find("nameText").GetComponent<Text>();
  59. closeButton.onClick.AddListener(() =>
  60. {
  61. print(111);
  62. Hide();
  63. });
  64. }
  65. private void Awake()
  66. {
  67. // // Get today's date
  68. // DateTime today = DateTime.Today;
  69. //
  70. // // Get the date 3 months ago
  71. // DateTime startDate = today.AddMonths(-3);
  72. //
  73. // // Format the dates to string
  74. // startDateStr = startDate.ToString("yyyy-MM-dd");
  75. // endDateStr = today.ToString("yyyy-MM-dd");
  76. DatePicker_Start = this.transform.Find("linePanel/DatePicker_Start").GetComponent<DatePickerDropDownTextMeshPro>();
  77. DatePicker_End = this.transform.Find("linePanel/DatePicker_End").GetComponent<DatePickerDropDownTextMeshPro>();
  78. // DatePicker_Start.SetLabelText(startDateStr);
  79. // DatePicker_End.SetLabelText(endDateStr);
  80. lineChartBtn.onClick.AddListener(() =>
  81. {
  82. if (lineChartBtn.GetComponent<CanvasGroup>().alpha < 1)
  83. {
  84. ChangePanel(0);
  85. ShowTrend(currentStcd, currentName, currentType);
  86. }
  87. });
  88. infoBtn.onClick.AddListener(() =>
  89. {
  90. if (infoBtn.GetComponent<CanvasGroup>().alpha < 1)
  91. {
  92. ChangePanel(1);
  93. ShowInfo();
  94. }
  95. });
  96. searchButton.onClick.AddListener(() =>
  97. {
  98. ShowTrend(currentStcd, currentName, currentType, false);
  99. });
  100. }
  101. private void Start()
  102. {
  103. DatePicker_Start.GetDateString += (string dateStr) =>
  104. {
  105. startDateStr = dateStr;
  106. CheckDate();
  107. };
  108. DatePicker_End.GetDateString += (string dateStr) =>
  109. {
  110. endDateStr = dateStr;
  111. CheckDate();
  112. };
  113. }
  114. public void CheckDate()
  115. {
  116. if (!startDateStr.Equals("") && !endDateStr.Equals(""))
  117. {
  118. var startD = DateTime.ParseExact(startDateStr, "yyyy-MM-dd", null);
  119. var endD = DateTime.ParseExact(endDateStr, "yyyy-MM-dd", null);
  120. var disD = endD - startD;
  121. Debug.Log(disD.TotalDays);
  122. if (disD.TotalDays > 183)
  123. {
  124. Debug.Log("时间间隔大于6个月");
  125. }
  126. }
  127. }
  128. /// <summary>
  129. /// 获取时间范围内的趋势图
  130. /// </summary>
  131. /// <param name="type"></param>
  132. /// <param name="gid"></param>
  133. /// <param name="sid"></param>
  134. /// <param name="startTime"></param>
  135. /// <param name="endTime"></param>
  136. public async Task GetTrend(int type, string gid, string sid)
  137. {
  138. string getJsonStr = await HttpHelper._Instance.GetDeviceTrend(type, gid, sid, startDateStr, endDateStr);
  139. try
  140. {
  141. Debug.Log("GetTrend requestData:" + getJsonStr);
  142. DeviceTrendRequest requestData = JsonConvert.DeserializeObject<DeviceTrendRequest>(getJsonStr);
  143. XAxis tempXaxis = _LineChart.GetChartComponent<XAxis>();
  144. tempXaxis.data.Clear();
  145. for (int i = 0; i < requestData.data.Length; i++)
  146. {
  147. tempXaxis.AddData(requestData.data[i].timeGroup);
  148. }
  149. var tempSeries = _LineChart.series;
  150. SerieData[] tempDatas = new SerieData[requestData.data.Length];
  151. for (int i = 0; i < tempDatas.Length; i++)
  152. {
  153. tempDatas[i] = new SerieData();
  154. tempDatas[i].data = new List<double>();
  155. tempDatas[i].data.Add(i);
  156. tempDatas[i].data.Add(float.Parse(requestData.data[i].r1));
  157. }
  158. tempSeries[0].data.Clear();
  159. tempSeries[0].data.AddRange(tempDatas);
  160. }
  161. catch (Exception e)
  162. {
  163. Debug.Log(e.ToString());
  164. throw;
  165. }
  166. }
  167. public void ChangePanel(int panelIndex = 0)
  168. {
  169. if (panelIndex == 0)
  170. {
  171. lineChartPanel.gameObject.SetActive(true);
  172. infoPanel.gameObject.SetActive(false);
  173. lineChartBtn.GetComponent<CanvasGroup>().alpha = 1;
  174. infoBtn.GetComponent<CanvasGroup>().alpha = 0.5f;
  175. }
  176. else
  177. {
  178. lineChartPanel.gameObject.SetActive(false);
  179. infoPanel.gameObject.SetActive(true);
  180. lineChartBtn.GetComponent<CanvasGroup>().alpha = 0.5f;
  181. infoBtn.GetComponent<CanvasGroup>().alpha = 1;
  182. }
  183. }
  184. public async Task ShowTrend(string stcd, string name, int type, bool useDefault = true)
  185. {
  186. var tempSeries = _LineChart.series;
  187. tempSeries[0].data.Clear();
  188. if (listObj.Count > 0)
  189. {
  190. GameObject[] deleteObjs = listObj.ToArray();
  191. for (int i = 0; i < deleteObjs.Length; i++)
  192. {
  193. Destroy(deleteObjs[i]);
  194. }
  195. }
  196. listObj.Clear();
  197. string endTime = DateTime.Now.ToString("yyyy-MM-dd");
  198. string startTime = DateTime.Now.AddMonths(-3).ToString("yyyy-MM-dd");
  199. if (useDefault)
  200. {
  201. startDateStr = startTime;
  202. endDateStr = endTime;
  203. DatePicker_Start.SetLabelText(startTime);
  204. DatePicker_End.SetLabelText(endTime);
  205. }
  206. else
  207. {
  208. startDateStr = DatePicker_Start.Label.text;
  209. endDateStr = DatePicker_End.Label.text;
  210. }
  211. Debug.Log(startDateStr);
  212. Debug.Log(endDateStr);
  213. currentType = type;
  214. if (type == 0)
  215. {
  216. threePanel.gameObject.SetActive(true);
  217. typeTitle.text = "站点水位趋势";
  218. }
  219. else
  220. {
  221. threePanel.gameObject.SetActive(false);
  222. typeTitle.text = "站点降雨趋势";
  223. }
  224. currentStcd = stcd;
  225. Debug.Log(stcd);
  226. currentName = name;
  227. ChangePanel(0);
  228. name = name.Replace(" ", "");
  229. nameText.text = $"站点:{name}";
  230. this.gameObject.SetActive(true);
  231. string chartJsonStr = "";
  232. if (type == 0)
  233. {
  234. _LineChart.GetChartComponent<YAxis>().axisName.name = "水位(m)";
  235. chartJsonStr = await HttpHelper._Instance.GetWaterTrend_Chart(stcd, startDateStr, endDateStr);
  236. }
  237. else
  238. {
  239. _LineChart.GetChartComponent<YAxis>().axisName.name = "降雨量(mm)";
  240. chartJsonStr = await HttpHelper._Instance.GetDropTrend_Chart(stcd, startDateStr, endDateStr);
  241. }
  242. if (stcd == "61017810")
  243. {
  244. bythreePanel.gameObject.SetActive(true);
  245. taokouthreePanel.gameObject.SetActive(false);
  246. }
  247. else
  248. {
  249. bythreePanel.gameObject.SetActive(false);
  250. taokouthreePanel.gameObject.SetActive(true);
  251. }
  252. SetChartLine(chartJsonStr);
  253. StartCoroutine(CreatList(chartJsonStr));
  254. }
  255. public async Task ShowInfo()
  256. {
  257. idText.text = "-";
  258. stnmText.text = "-";
  259. stcdText.text = "-";
  260. stlcText.text = "-";
  261. sttpText.text = "-";
  262. addvcdText.text = "-";
  263. bsnmText.text = "-";
  264. hnnmText.text = "-";
  265. rvnmText.text = "-";
  266. lgtdText.text = "-";
  267. lttdText.text = "-";
  268. dtmnmText.text = "-";
  269. dtmelText.text = "-";
  270. atcunitText.text = "-";
  271. localityText.text = "-";
  272. frgrdText.text = "-";
  273. usflText.text = "-";
  274. string infoJsonStr = await HttpHelper._Instance.GetWaterTrend_Info(currentStcd);
  275. Debug.Log(infoJsonStr);
  276. WaterTrendData_Info waterTrendData_Info = JsonConvert.DeserializeObject<WaterTrendData_Info>(infoJsonStr);
  277. Debug.Log(waterTrendData_Info);
  278. idText.text = waterTrendData_Info.data.id;
  279. stnmText.text = waterTrendData_Info.data.stnm;
  280. stcdText.text = waterTrendData_Info.data.stcd;
  281. stlcText.text = waterTrendData_Info.data.stlc;
  282. sttpText.text = waterTrendData_Info.data.sttp;
  283. addvcdText.text = waterTrendData_Info.data.addvcd;
  284. bsnmText.text = waterTrendData_Info.data.bsnm;
  285. hnnmText.text = waterTrendData_Info.data.hnnm;
  286. rvnmText.text = waterTrendData_Info.data.rvnm;
  287. lgtdText.text = waterTrendData_Info.data.lgtd;
  288. lttdText.text = waterTrendData_Info.data.lttd;
  289. dtmnmText.text = waterTrendData_Info.data.dtmnm;
  290. dtmelText.text = waterTrendData_Info.data.dtmel;
  291. atcunitText.text = waterTrendData_Info.data.atcunit;
  292. localityText.text = waterTrendData_Info.data.locality;
  293. frgrdText.text = waterTrendData_Info.data.frgrd;
  294. usflText.text = waterTrendData_Info.data.usfl;
  295. }
  296. public void Hide()
  297. {
  298. this.gameObject.SetActive(false);
  299. }
  300. public void SetChartLine(string jsonData)
  301. {
  302. WaterTrendData_Chart tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<WaterTrendData_Chart>(jsonData);
  303. tempData.data.Reverse();
  304. XAxis tempXaxis = _LineChart.GetChartComponent<XAxis>();
  305. tempXaxis.data.Clear();
  306. for (int i = 0; i < tempData.data.Count; i++)
  307. {
  308. tempXaxis.AddData(tempData.data[i].time);
  309. }
  310. var tempSeries = _LineChart.series;
  311. tempSeries[0].serieName = "水位(m)";
  312. SerieData[] tempDatas = new SerieData[tempData.data.Count];
  313. for (int i = 0; i < tempDatas.Length; i++)
  314. {
  315. tempDatas[i] = new SerieData();
  316. tempDatas[i].data = new List<double>();
  317. tempDatas[i].data.Add(i);
  318. string valueTex = tempData.data[i].value;
  319. if (valueTex == "-")
  320. {
  321. valueTex = "-1";
  322. }
  323. double tempValue = double.Parse(float.Parse(valueTex).ToString("0.00"));
  324. //if (tempValue < 0) {
  325. // tempValue = 24.99f;
  326. //}
  327. tempDatas[i].data.Add(tempValue);
  328. }
  329. tempSeries[0].data.Clear();
  330. tempSeries[0].data.AddRange(tempDatas);
  331. }
  332. private float? TryParseFloat(string s)
  333. {
  334. if (string.IsNullOrWhiteSpace(s))
  335. return null;
  336. s = s.Trim();
  337. // 常见无效值直接忽略
  338. if (s == "-" || s == "--" || s == "—" || s.ToLower() == "nan")
  339. return null;
  340. // 抽取字符串中的数字字符(比如 "26.5米")
  341. string num = "";
  342. foreach (char c in s)
  343. {
  344. if ((c >= '0' && c <= '9') || c == '.' || c == '-')
  345. num += c;
  346. }
  347. if (float.TryParse(num, out float result))
  348. return result;
  349. return null;
  350. }
  351. IEnumerator CreatList(string jsonData)
  352. {
  353. var wait = new WaitForEndOfFrame();
  354. WaterTrendData_Chart tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<WaterTrendData_Chart>(jsonData);
  355. //=========================
  356. // 1. 按天分组
  357. //=========================
  358. var groups = tempData.data
  359. .GroupBy(x => DateTime.Parse(x.time).ToString("yyyy-MM-dd"))
  360. .OrderByDescending(g => g.Key) // 日期降序
  361. .ToList();
  362. //=========================
  363. // 2. 生成每天的数据(平均值)
  364. //=========================
  365. List<(string date, float avgValue, int trend)> dayList =
  366. new List<(string, float, int)>();
  367. foreach (var g in groups)
  368. {
  369. var validValues = g
  370. .Select(v => TryParseFloat(v.value))
  371. .Where(v => v.HasValue) // 只保留有效数字
  372. .Select(v => v.Value)
  373. .ToList();
  374. float avg = validValues.Count > 0 ? validValues.Average() : 0f;
  375. dayList.Add((g.Key, avg, 0)); // trend 后面再算
  376. }
  377. //=========================
  378. // 3. 计算趋势 trend(与下一天比较)
  379. //=========================
  380. for (int i = 0; i < dayList.Count - 1; i++)
  381. {
  382. float today = dayList[i].avgValue;
  383. float yesterday = dayList[i + 1].avgValue;
  384. int t = 0;
  385. if (today > yesterday) t = 1; // 上升
  386. else if (today < yesterday) t = 3; // 下降(你原来下降用 3)
  387. else t = 2; // 持平(你原来持平是 2 → →)
  388. dayList[i] = (dayList[i].date, dayList[i].avgValue, t);
  389. }
  390. // 最后一条没有下一天,趋势设为 -
  391. dayList[dayList.Count - 1] = (dayList.Last().date, dayList.Last().avgValue, 2);
  392. //=========================
  393. // 4. 生成 UI
  394. //=========================
  395. int creatCount = 0;
  396. listObj.Clear();
  397. for (int i = 0; i < dayList.Count; i++)
  398. {
  399. GameObject tempObj = Instantiate(listItemOri, listRoot);
  400. tempObj.transform.Find("id").GetComponent<Text>().text = $"{i + 1}";
  401. tempObj.transform.Find("time").GetComponent<Text>().text = dayList[i].date;
  402. tempObj.transform.Find("value").GetComponent<Text>().text = dayList[i].avgValue.ToString("0.00");
  403. // 设置趋势字符和颜色
  404. string dirStr = "-";
  405. var trendTxt = tempObj.transform.Find("trend").GetComponent<Text>();
  406. if (dayList[i].trend == 1)
  407. {
  408. dirStr = "↑"; trendTxt.color = Color.red;
  409. }
  410. else if (dayList[i].trend == 2)
  411. {
  412. dirStr = "→"; trendTxt.color = Color.blue;
  413. }
  414. else if (dayList[i].trend == 3)
  415. {
  416. dirStr = "↓"; trendTxt.color = Color.green;
  417. }
  418. else
  419. {
  420. trendTxt.color = Color.white;
  421. }
  422. trendTxt.text = dirStr;
  423. listObj.Add(tempObj);
  424. // 分帧生成
  425. creatCount++;
  426. if (creatCount >= 10)
  427. {
  428. creatCount = 0;
  429. yield return wait;
  430. }
  431. }
  432. }
  433. }
  434. [Serializable]
  435. public class WaterTrendData_Chart
  436. {
  437. public int code;
  438. public string msg;
  439. public List<WaterCharData> data;
  440. }
  441. [Serializable]
  442. public class WaterCharData
  443. {
  444. public string time;
  445. public int trend;
  446. public string value;
  447. }
  448. [Serializable]
  449. public class WaterTrendData_Info
  450. {
  451. public int code;
  452. public string msg;
  453. public WaterInfoData data;
  454. }
  455. [Serializable]
  456. public class WaterInfoData
  457. {
  458. public string id { get; set; }
  459. public string addvcd { get; set; }
  460. public string atcunit { get; set; }
  461. public string bsnm { get; set; }
  462. public string dtmel { get; set; }
  463. public string dtmnm { get; set; }
  464. public string frgrd { get; set; }
  465. public string hnnm { get; set; }
  466. public string lgtd { get; set; }
  467. public string locality { get; set; }
  468. public string lttd { get; set; }
  469. public string rvnm { get; set; }
  470. public string stcd { get; set; }
  471. public string stlc { get; set; }
  472. public string stnm { get; set; }
  473. public string sttp { get; set; }
  474. public string usfl { get; set; }
  475. }