predict_edb_info_rule.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. package data
  2. import (
  3. "github.com/shopspring/decimal"
  4. "hongze/hongze_chart_lib/models"
  5. "hongze/hongze_chart_lib/utils"
  6. "time"
  7. )
  8. // GetChartPredictEdbInfoDataListByRule1 根据规则1获取预测数据
  9. func GetChartPredictEdbInfoDataListByRule1(edbInfoId int, dataValue float64, startDate, endDate time.Time, frequency string, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList) {
  10. newPredictEdbInfoData = predictEdbInfoData
  11. //获取后面的预测数据
  12. dayList := getPredictEdbDayList(startDate, endDate, frequency)
  13. predictEdbInfoData = make([]*models.EdbDataList, 0)
  14. for k, v := range dayList {
  15. newPredictEdbInfoData = append(newPredictEdbInfoData, &models.EdbDataList{
  16. EdbDataId: edbInfoId + 10000000000 + k,
  17. EdbInfoId: edbInfoId,
  18. DataTime: v.Format(utils.FormatDate),
  19. Value: dataValue,
  20. DataTimestamp: (v.UnixNano() / 1e6) + 1000, //前端需要让加1s,说是2022-09-01 00:00:00 这样的整点不合适
  21. })
  22. existMap[v.Format(utils.FormatDate)] = dataValue
  23. }
  24. return
  25. }
  26. // GetChartPredictEdbInfoDataListByRuleTb 根据同比值规则获取预测数据
  27. // 2.1 同比: 在未来某一个时间段内,给定一个固定的同比增速a,用去年同期值X乘以同比增速(1+a),得到预测值Y=X(1+a)
  28. // 例: 今年1-3月值,100,100,120。给定同比增速a=0.1,则明年1-3月预测值为: 100*1.1=110,100*1.1=110,120*1.1=132。
  29. func GetChartPredictEdbInfoDataListByRuleTb(edbInfoId int, tbValue float64, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  30. allDataList := make([]*models.EdbDataList, 0)
  31. allDataList = append(allDataList, realPredictEdbInfoData...)
  32. allDataList = append(allDataList, predictEdbInfoData...)
  33. newPredictEdbInfoData = predictEdbInfoData
  34. index := len(allDataList)
  35. //获取后面的预测数据
  36. dayList := getPredictEdbDayList(startDate, endDate, frequency)
  37. predictEdbInfoData = make([]*models.EdbDataList, 0)
  38. for k, currentDate := range dayList {
  39. tmpData := &models.EdbDataList{
  40. EdbDataId: edbInfoId + 10000000000 + index + k,
  41. EdbInfoId: edbInfoId,
  42. DataTime: currentDate.Format(utils.FormatDate),
  43. //Value: dataValue,
  44. DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000, //前端需要让加1s,说是2022-09-01 00:00:00 这样的整点不合适
  45. }
  46. var val float64
  47. var calculateStatus bool //计算结果
  48. //currentItem := existMap[av]
  49. //上一年的日期
  50. preDate := currentDate.AddDate(-1, 0, 0)
  51. preDateStr := preDate.Format(utils.FormatDate)
  52. if preValue, ok := existMap[preDateStr]; ok { //上一年同期找到
  53. val = TbzDiv(preValue, tbValue)
  54. calculateStatus = true
  55. } else {
  56. switch frequency {
  57. case "月度":
  58. //向上和向下,各找一个月
  59. nextDateDay := preDate
  60. preDateDay := preDate
  61. for i := 0; i <= 35; i++ {
  62. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  63. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  64. val = TbzDiv(preValue, tbValue)
  65. calculateStatus = true
  66. break
  67. } else {
  68. preDateDayStr := preDateDay.Format(utils.FormatDate)
  69. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  70. val = TbzDiv(preValue, tbValue)
  71. calculateStatus = true
  72. break
  73. }
  74. }
  75. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  76. preDateDay = preDateDay.AddDate(0, 0, -1)
  77. }
  78. case "季度", "年度":
  79. if preValue, ok := existMap[preDateStr]; ok { //上一年同期->下一个月找到
  80. val = TbzDiv(preValue, tbValue)
  81. calculateStatus = true
  82. break
  83. }
  84. default:
  85. nextDateDay := preDate
  86. preDateDay := preDate
  87. for i := 0; i < 35; i++ {
  88. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  89. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  90. val = TbzDiv(preValue, tbValue)
  91. calculateStatus = true
  92. break
  93. } else {
  94. preDateDayStr := preDateDay.Format(utils.FormatDate)
  95. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  96. val = TbzDiv(preValue, tbValue)
  97. calculateStatus = true
  98. break
  99. } else {
  100. //fmt.Println("pre not find:", preDateStr, "i:", i)
  101. }
  102. }
  103. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  104. preDateDay = preDateDay.AddDate(0, 0, -1)
  105. }
  106. }
  107. }
  108. if calculateStatus {
  109. tmpData.Value = val
  110. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  111. allDataList = append(allDataList, tmpData)
  112. existMap[tmpData.DataTime] = val
  113. // 最大最小值
  114. if val < minValue {
  115. minValue = val
  116. }
  117. if val > maxValue {
  118. maxValue = val
  119. }
  120. }
  121. }
  122. return
  123. }
  124. // TbzDiv 同比值计算
  125. // @params a float64 去年同期值
  126. // @params b float64 固定同比增速
  127. func TbzDiv(a, b float64) (result float64) {
  128. if b != 0 {
  129. // 去年同期值
  130. af := decimal.NewFromFloat(a)
  131. // 同比增速
  132. bf := decimal.NewFromFloat(b)
  133. // 默认1
  134. cf := decimal.NewFromFloat(1)
  135. // 总增速
  136. val := bf.Add(cf)
  137. // 计算
  138. result, _ = val.Mul(af).RoundCeil(4).Float64()
  139. } else {
  140. result = 0
  141. }
  142. return
  143. }
  144. // GetChartPredictEdbInfoDataListByRuleTc 根据同差值规则获取预测数据
  145. // 2.2 同差: 在未来某一个时间段内,给定一个固定的同比增加值a,用去年同期值X加上同比增加值A,得到预测值Y=X+a
  146. // 例: 今年1-3月值,100,100,120。给定同比增加值a=10,则明年1-3月预测值为: 100+10=110,100+10=110,120+10=130
  147. func GetChartPredictEdbInfoDataListByRuleTc(edbInfoId int, tcValue float64, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  148. allDataList := make([]*models.EdbDataList, 0)
  149. allDataList = append(allDataList, realPredictEdbInfoData...)
  150. allDataList = append(allDataList, predictEdbInfoData...)
  151. newPredictEdbInfoData = predictEdbInfoData
  152. index := len(allDataList)
  153. //获取后面的预测数据
  154. dayList := getPredictEdbDayList(startDate, endDate, frequency)
  155. predictEdbInfoData = make([]*models.EdbDataList, 0)
  156. for k, currentDate := range dayList {
  157. tmpData := &models.EdbDataList{
  158. EdbDataId: edbInfoId + 10000000000 + index + k,
  159. EdbInfoId: edbInfoId,
  160. DataTime: currentDate.Format(utils.FormatDate),
  161. //Value: dataValue,
  162. DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000, //前端需要让加1s,说是2022-09-01 00:00:00 这样的整点不合适
  163. }
  164. var val float64
  165. var calculateStatus bool //计算结果
  166. //currentItem := existMap[av]
  167. //上一年的日期
  168. preDate := currentDate.AddDate(-1, 0, 0)
  169. preDateStr := preDate.Format(utils.FormatDate)
  170. if preValue, ok := existMap[preDateStr]; ok { //上一年同期找到
  171. val = TczDiv(preValue, tcValue)
  172. calculateStatus = true
  173. } else {
  174. switch frequency {
  175. case "月度":
  176. //向上和向下,各找一个月
  177. nextDateDay := preDate
  178. preDateDay := preDate
  179. for i := 0; i <= 35; i++ {
  180. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  181. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  182. val = TczDiv(preValue, tcValue)
  183. calculateStatus = true
  184. break
  185. } else {
  186. preDateDayStr := preDateDay.Format(utils.FormatDate)
  187. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  188. val = TczDiv(preValue, tcValue)
  189. calculateStatus = true
  190. break
  191. }
  192. }
  193. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  194. preDateDay = preDateDay.AddDate(0, 0, -1)
  195. }
  196. case "季度", "年度":
  197. if preValue, ok := existMap[preDateStr]; ok { //上一年同期->下一个月找到
  198. val = TczDiv(preValue, tcValue)
  199. calculateStatus = true
  200. break
  201. }
  202. default:
  203. nextDateDay := preDate
  204. preDateDay := preDate
  205. for i := 0; i < 35; i++ {
  206. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  207. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  208. val = TczDiv(preValue, tcValue)
  209. calculateStatus = true
  210. break
  211. } else {
  212. preDateDayStr := preDateDay.Format(utils.FormatDate)
  213. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  214. val = TczDiv(preValue, tcValue)
  215. calculateStatus = true
  216. break
  217. } else {
  218. //fmt.Println("pre not find:", preDateStr, "i:", i)
  219. }
  220. }
  221. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  222. preDateDay = preDateDay.AddDate(0, 0, -1)
  223. }
  224. }
  225. }
  226. if calculateStatus {
  227. tmpData.Value = val
  228. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  229. allDataList = append(allDataList, tmpData)
  230. existMap[tmpData.DataTime] = val
  231. // 最大最小值
  232. if val < minValue {
  233. minValue = val
  234. }
  235. if val > maxValue {
  236. maxValue = val
  237. }
  238. }
  239. }
  240. return
  241. }
  242. // TczDiv 环差值计算
  243. // @params a float64 上一期值
  244. // @params b float64 固定的环比增加值
  245. func TczDiv(a, b float64) (result float64) {
  246. if b != 0 {
  247. // 上一期值
  248. af := decimal.NewFromFloat(a)
  249. // 固定的环比增加值
  250. bf := decimal.NewFromFloat(b)
  251. // 计算
  252. result, _ = af.Add(bf).RoundCeil(4).Float64()
  253. } else {
  254. result = 0
  255. }
  256. return
  257. }
  258. // GetChartPredictEdbInfoDataListByRuleHb 根据环比值规则获取预测数据
  259. // 环比:在未来某一个时间段内,给定一个固定的环比增速a,用上一期值X乘以环比增速(1+a),得到预测值Y=X(1+a)
  260. // 例: 最近1期值为100,给定环比增速a=0.2,则未来3期预测值为: 100*1.2=120,120*1.2=144,144*1.2=172.8
  261. func GetChartPredictEdbInfoDataListByRuleHb(edbInfoId int, hbValue float64, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  262. allDataList := make([]*models.EdbDataList, 0)
  263. allDataList = append(allDataList, realPredictEdbInfoData...)
  264. allDataList = append(allDataList, predictEdbInfoData...)
  265. newPredictEdbInfoData = predictEdbInfoData
  266. index := len(allDataList)
  267. //获取后面的预测数据
  268. dayList := getPredictEdbDayList(startDate, endDate, frequency)
  269. for k, currentDate := range dayList {
  270. tmpK := index + k - 1 //上1期的值
  271. // 环比值计算
  272. val := HbzDiv(allDataList[tmpK].Value, hbValue)
  273. currentDateStr := currentDate.Format(utils.FormatDate)
  274. tmpData := &models.EdbDataList{
  275. EdbDataId: edbInfoId + 10000000000 + index + k,
  276. EdbInfoId: edbInfoId,
  277. DataTime: currentDateStr,
  278. Value: val,
  279. DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000, //前端需要让加1s,说是2022-09-01 00:00:00 这样的整点不合适
  280. }
  281. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  282. allDataList = append(allDataList, tmpData)
  283. existMap[currentDateStr] = val
  284. // 最大最小值
  285. if val < minValue {
  286. minValue = val
  287. }
  288. if val > maxValue {
  289. maxValue = val
  290. }
  291. }
  292. return
  293. }
  294. // HbzDiv 环比值计算
  295. // @params a float64 上一期值
  296. // @params b float64 固定的环比增速
  297. func HbzDiv(a, b float64) (result float64) {
  298. if b != 0 {
  299. // 上一期值
  300. af := decimal.NewFromFloat(a)
  301. // 固定的环比增速
  302. bf := decimal.NewFromFloat(b)
  303. // 默认1
  304. cf := decimal.NewFromFloat(1)
  305. // 总增速
  306. val := bf.Add(cf)
  307. // 计算
  308. result, _ = val.Mul(af).RoundCeil(4).Float64()
  309. } else {
  310. result = 0
  311. }
  312. return
  313. }
  314. // GetChartPredictEdbInfoDataListByRuleHc 根据环差值规则获取预测数据
  315. // 2.4 环差:在未来某一个时间段内,给定一个固定的环比增加值a,用上一期值X加上环比增加值a,得到预测值Y=X+a
  316. // 例: 最近1期值为100,给定环比增加值a=10,则未来3期预测值为: 100+10=110,110+10=120,120+10=130
  317. func GetChartPredictEdbInfoDataListByRuleHc(edbInfoId int, hcValue float64, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  318. allDataList := make([]*models.EdbDataList, 0)
  319. allDataList = append(allDataList, realPredictEdbInfoData...)
  320. allDataList = append(allDataList, predictEdbInfoData...)
  321. newPredictEdbInfoData = predictEdbInfoData
  322. index := len(allDataList)
  323. //获取后面的预测数据
  324. dayList := getPredictEdbDayList(startDate, endDate, frequency)
  325. for k, currentDate := range dayList {
  326. tmpK := index + k - 1 //上1期的值
  327. // 环差别值计算
  328. val := HczDiv(allDataList[tmpK].Value, hcValue)
  329. currentDateStr := currentDate.Format(utils.FormatDate)
  330. tmpData := &models.EdbDataList{
  331. EdbDataId: edbInfoId + 10000000000 + index + k,
  332. EdbInfoId: edbInfoId,
  333. DataTime: currentDateStr,
  334. Value: val,
  335. DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000, //前端需要让加1s,说是2022-09-01 00:00:00 这样的整点不合适
  336. }
  337. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  338. allDataList = append(allDataList, tmpData)
  339. existMap[currentDateStr] = val
  340. // 最大最小值
  341. if val < minValue {
  342. minValue = val
  343. }
  344. if val > maxValue {
  345. maxValue = val
  346. }
  347. }
  348. return
  349. }
  350. // HczDiv 环差值计算
  351. // @params a float64 上一期值
  352. // @params b float64 固定的环比增加值
  353. func HczDiv(a, b float64) (result float64) {
  354. if b != 0 {
  355. // 上一期值
  356. af := decimal.NewFromFloat(a)
  357. // 固定的环比增加值
  358. bf := decimal.NewFromFloat(b)
  359. // 计算
  360. result, _ = af.Add(bf).RoundCeil(4).Float64()
  361. } else {
  362. result = 0
  363. }
  364. return
  365. }
  366. // GetChartPredictEdbInfoDataListByRuleNMoveMeanValue 根据N期移动均值规则获取预测数据
  367. // 2.5 N期移动均值:在未来某一个时间段内,下一期值等于过去N期值得平均值。
  368. // 例:最近3期值(N=3),为95,98,105则未来第1期值为 1/3*(95+98+105)=99.33, 未来第2期值为 1/3*(98+105+99.33)=100.78依次类推。
  369. func GetChartPredictEdbInfoDataListByRuleNMoveMeanValue(edbInfoId int, nValue int, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  370. allDataList := make([]*models.EdbDataList, 0)
  371. allDataList = append(allDataList, realPredictEdbInfoData...)
  372. allDataList = append(allDataList, predictEdbInfoData...)
  373. newPredictEdbInfoData = predictEdbInfoData
  374. lenAllData := len(allDataList)
  375. if lenAllData < nValue || lenAllData <= 0 {
  376. return
  377. }
  378. if nValue <= 0 {
  379. return
  380. }
  381. // 分母
  382. decimalN := decimal.NewFromInt(int64(nValue))
  383. //获取后面的预测数据
  384. dayList := getPredictEdbDayList(startDate, endDate, frequency)
  385. for k, currentDate := range dayList {
  386. tmpIndex := lenAllData + k - 1 //上1期的值
  387. // 数据集合中的最后一个数据
  388. tmpDecimalVal := decimal.NewFromFloat(allDataList[tmpIndex].Value)
  389. for tmpK := 2; tmpK <= nValue; tmpK++ {
  390. tmpIndex2 := tmpIndex - tmpK //上N期的值
  391. tmpDecimalVal2 := decimal.NewFromFloat(allDataList[tmpIndex2].Value)
  392. tmpDecimalVal = tmpDecimalVal.Add(tmpDecimalVal2)
  393. }
  394. // N期移动均值计算
  395. val, _ := tmpDecimalVal.Div(decimalN).RoundCeil(4).Float64()
  396. currentDateStr := currentDate.Format(utils.FormatDate)
  397. tmpData := &models.EdbDataList{
  398. EdbDataId: edbInfoId + 10000000000 + lenAllData + k,
  399. EdbInfoId: edbInfoId,
  400. DataTime: currentDateStr,
  401. Value: val,
  402. DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000, //前端需要让加1s,说是2022-09-01 00:00:00 这样的整点不合适
  403. }
  404. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  405. allDataList = append(allDataList, tmpData)
  406. existMap[currentDateStr] = val
  407. // 最大最小值
  408. if val < minValue {
  409. minValue = val
  410. }
  411. if val > maxValue {
  412. maxValue = val
  413. }
  414. }
  415. return
  416. }
  417. // GetChartPredictEdbInfoDataListByRuleNLinearRegression 根据N期移动均值规则获取预测数据
  418. // 2.6N期段线性外推值:给出过去N期值所确定的线性回归方程(Y=aX+b)在未来一段时间内的推算值。回归方程虽然比较复杂,但各种编程语言应该都有现成的模块或函数,应该无需自己编写。
  419. // 例1:过去5期值(N=5)分别为:3,5,7,9,11(每两期值之间的时间间隔相等)。那么按照线性回归方程推算,未来三期的预测值是:13,15,17。
  420. //
  421. // 例2:过去6期值(N=6)分别为:3,3,5,7,9,11(每两期值之间的时间间隔相等)。那么按照线性回归方程推算,未来三期的预测值是:12.33,14.05,15.76。例1和例2的区别在于,多加了一期数据,导致回归方程发生改变,从而预测值不同。
  422. func GetChartPredictEdbInfoDataListByRuleNLinearRegression(edbInfoId int, nValue int, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  423. //var errMsg string
  424. //defer func() {
  425. // if errMsg != `` {
  426. // go alarm_msg.SendAlarmMsg("更新上海的token失败;ERR:"+err.Error(), 3)
  427. // }
  428. //}()
  429. allDataList := make([]*models.EdbDataList, 0)
  430. allDataList = append(allDataList, realPredictEdbInfoData...)
  431. allDataList = append(allDataList, predictEdbInfoData...)
  432. newPredictEdbInfoData = predictEdbInfoData
  433. lenAllData := len(allDataList)
  434. if lenAllData < nValue || lenAllData <= 0 {
  435. return
  436. }
  437. if nValue <= 1 {
  438. return
  439. }
  440. //获取后面的预测数据
  441. // 获取线性方程公式的a、b的值
  442. coordinateData := make([]Coordinate, 0)
  443. for tmpK := nValue; tmpK > 0; tmpK-- {
  444. tmpIndex2 := lenAllData - tmpK //上N期的值
  445. tmpCoordinate := Coordinate{
  446. X: float64(nValue - tmpK + 1),
  447. Y: allDataList[tmpIndex2].Value,
  448. }
  449. coordinateData = append(coordinateData, tmpCoordinate)
  450. }
  451. a, b := getLinearResult(coordinateData)
  452. //fmt.Println("a:", a, ";======b:", b)
  453. dayList := getPredictEdbDayList(startDate, endDate, frequency)
  454. for k, currentDate := range dayList {
  455. tmpK := nValue + k + 1
  456. aDecimal := decimal.NewFromFloat(a)
  457. xDecimal := decimal.NewFromInt(int64(tmpK))
  458. bDecimal := decimal.NewFromFloat(b)
  459. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).RoundCeil(4).Float64()
  460. currentDateStr := currentDate.Format(utils.FormatDate)
  461. tmpData := &models.EdbDataList{
  462. EdbDataId: edbInfoId + 10000000000 + lenAllData + k,
  463. EdbInfoId: edbInfoId,
  464. DataTime: currentDateStr,
  465. Value: val,
  466. DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000, //前端需要让加1s,说是2022-09-01 00:00:00 这样的整点不合适
  467. }
  468. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  469. allDataList = append(allDataList, tmpData)
  470. existMap[currentDateStr] = val
  471. // 最大最小值
  472. if val < minValue {
  473. minValue = val
  474. }
  475. if val > maxValue {
  476. maxValue = val
  477. }
  478. }
  479. return
  480. }
  481. // Series is a container for a series of data
  482. type Series []Coordinate
  483. // Coordinate holds the data in a series
  484. type Coordinate struct {
  485. X, Y float64
  486. }
  487. func getLinearResult(s []Coordinate) (gradient, intercept float64) {
  488. if len(s) <= 1 {
  489. return
  490. }
  491. // Placeholder for the math to be done
  492. var sum [5]float64
  493. // Loop over data keeping index in place
  494. i := 0
  495. for ; i < len(s); i++ {
  496. sum[0] += s[i].X
  497. sum[1] += s[i].Y
  498. sum[2] += s[i].X * s[i].X
  499. sum[3] += s[i].X * s[i].Y
  500. sum[4] += s[i].Y * s[i].Y
  501. }
  502. // Find gradient and intercept
  503. f := float64(i)
  504. gradient = (f*sum[3] - sum[0]*sum[1]) / (f*sum[2] - sum[0]*sum[0])
  505. intercept = (sum[1] / f) - (gradient * sum[0] / f)
  506. //fmt.Println("gradient:", gradient, ";intercept:", intercept)
  507. // Create the new regression series
  508. //for j := 0; j < len(s); j++ {
  509. // regressions = append(regressions, Coordinate{
  510. // X: s[j].X,
  511. // Y: s[j].X*gradient + intercept,
  512. // })
  513. //}
  514. return
  515. }