handle_data.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package chart
  2. import (
  3. "errors"
  4. "github.com/shopspring/decimal"
  5. edbDataModel "hongze/hongze_yb/models/tables/edb_data"
  6. "hongze/hongze_yb/utils"
  7. "math"
  8. "time"
  9. )
  10. // HandleDataByLinearRegression 插值法补充数据(线性方程式)
  11. func HandleDataByLinearRegression(edbInfoDataList []*edbDataModel.EdbDataList, handleDataMap map[string]float64) (err error) {
  12. if len(edbInfoDataList) < 2 {
  13. return
  14. }
  15. var startEdbInfoData *edbDataModel.EdbDataList
  16. for _, v := range edbInfoDataList {
  17. handleDataMap[v.DataTime] = v.Value
  18. // 第一个数据就给过滤了,给后面的试用
  19. if startEdbInfoData == nil {
  20. startEdbInfoData = v
  21. continue
  22. }
  23. // 获取两条数据之间相差的天数
  24. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  25. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  26. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  27. betweenDay := betweenHour / 24
  28. // 如果相差一天,那么过滤
  29. if betweenDay <= 1 {
  30. startEdbInfoData = v
  31. continue
  32. }
  33. // 生成线性方程式
  34. var a, b float64
  35. {
  36. coordinateData := make([]utils.Coordinate, 0)
  37. tmpCoordinate1 := utils.Coordinate{
  38. X: 1,
  39. Y: startEdbInfoData.Value,
  40. }
  41. coordinateData = append(coordinateData, tmpCoordinate1)
  42. tmpCoordinate2 := utils.Coordinate{
  43. X: float64(betweenDay) + 1,
  44. Y: v.Value,
  45. }
  46. coordinateData = append(coordinateData, tmpCoordinate2)
  47. a, b = utils.GetLinearResult(coordinateData)
  48. if math.IsNaN(a) || math.IsNaN(b) {
  49. err = errors.New("线性方程公式生成失败")
  50. return
  51. }
  52. }
  53. // 生成对应的值
  54. {
  55. for i := 1; i < betweenDay; i++ {
  56. tmpDataTime := startDataTime.AddDate(0, 0, i)
  57. aDecimal := decimal.NewFromFloat(a)
  58. xDecimal := decimal.NewFromInt(int64(i) + 1)
  59. bDecimal := decimal.NewFromFloat(b)
  60. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  61. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
  62. }
  63. }
  64. startEdbInfoData = v
  65. }
  66. return
  67. }
  68. // HandleDataByPreviousData 当前日期无值时,用上一个日期的数据补充当前日期的数据
  69. func HandleDataByPreviousData(edbInfoDataList []*edbDataModel.EdbDataList, handleDataMap map[string]float64) (err error) {
  70. if len(edbInfoDataList) < 2 {
  71. return
  72. }
  73. var startEdbInfoData *edbDataModel.EdbDataList
  74. for _, v := range edbInfoDataList {
  75. handleDataMap[v.DataTime] = v.Value
  76. // 第一个数据就给过滤了,给后面的试用
  77. if startEdbInfoData == nil {
  78. startEdbInfoData = v
  79. continue
  80. }
  81. // 获取两条数据之间相差的天数
  82. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  83. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  84. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  85. betweenDay := betweenHour / 24
  86. // 如果相差一天,那么过滤
  87. if betweenDay <= 1 {
  88. startEdbInfoData = v
  89. continue
  90. }
  91. // 生成对应的值
  92. {
  93. for i := 1; i < betweenDay; i++ {
  94. tmpDataTime := startDataTime.AddDate(0, 0, i)
  95. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = startEdbInfoData.Value
  96. }
  97. }
  98. startEdbInfoData = v
  99. }
  100. return
  101. }