chart_info.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package correlation
  2. import (
  3. "fmt"
  4. "github.com/shopspring/decimal"
  5. "hongze/hongze_ETA_mobile_api/models/data_manage"
  6. "hongze/hongze_ETA_mobile_api/services/data"
  7. "hongze/hongze_ETA_mobile_api/utils"
  8. "math"
  9. "time"
  10. )
  11. // HandleDataByLinearRegression 线性方程插值法补全数据
  12. func HandleDataByLinearRegression(originList []*data_manage.EdbDataList, handleDataMap map[string]float64) (newList []*data_manage.EdbDataList, err error) {
  13. if len(originList) < 2 {
  14. return
  15. }
  16. var startEdbInfoData *data_manage.EdbDataList
  17. for _, v := range originList {
  18. handleDataMap[v.DataTime] = v.Value
  19. // 第一个数据就给过滤了,给后面的试用
  20. if startEdbInfoData == nil {
  21. startEdbInfoData = v
  22. newList = append(newList, &data_manage.EdbDataList{
  23. DataTime: v.DataTime,
  24. Value: v.Value,
  25. })
  26. continue
  27. }
  28. // 获取两条数据之间相差的天数
  29. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  30. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  31. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  32. betweenDay := betweenHour / 24
  33. // 如果相差一天,那么过滤
  34. if betweenDay <= 1 {
  35. startEdbInfoData = v
  36. newList = append(newList, &data_manage.EdbDataList{
  37. DataTime: v.DataTime,
  38. Value: v.Value,
  39. })
  40. continue
  41. }
  42. // 生成线性方程式
  43. var a, b float64
  44. {
  45. coordinateData := make([]utils.Coordinate, 0)
  46. tmpCoordinate1 := utils.Coordinate{
  47. X: 1,
  48. Y: startEdbInfoData.Value,
  49. }
  50. coordinateData = append(coordinateData, tmpCoordinate1)
  51. tmpCoordinate2 := utils.Coordinate{
  52. X: float64(betweenDay) + 1,
  53. Y: v.Value,
  54. }
  55. coordinateData = append(coordinateData, tmpCoordinate2)
  56. a, b = utils.GetLinearResult(coordinateData)
  57. if math.IsNaN(a) || math.IsNaN(b) {
  58. err = fmt.Errorf("线性方程公式生成失败")
  59. return
  60. }
  61. }
  62. // 生成对应的值
  63. {
  64. for i := 1; i < betweenDay; i++ {
  65. tmpDataTime := startDataTime.AddDate(0, 0, i)
  66. aDecimal := decimal.NewFromFloat(a)
  67. xDecimal := decimal.NewFromInt(int64(i) + 1)
  68. bDecimal := decimal.NewFromFloat(b)
  69. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  70. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
  71. newList = append(newList, &data_manage.EdbDataList{
  72. DataTime: tmpDataTime.Format(utils.FormatDate),
  73. Value: val,
  74. })
  75. }
  76. }
  77. startEdbInfoData = v
  78. }
  79. return
  80. }
  81. // MoveDataDaysToNewDataList 平移指标数据生成新的数据序列
  82. func MoveDataDaysToNewDataList(dataList []*data_manage.EdbDataList, moveDay int) (newDataList []data_manage.EdbDataList, dateDataMap map[string]float64) {
  83. dateMap := make(map[time.Time]float64)
  84. var minDate, maxDate time.Time
  85. dateDataMap = make(map[string]float64)
  86. for _, v := range dataList {
  87. currDate, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  88. if minDate.IsZero() || currDate.Before(minDate) {
  89. minDate = currDate
  90. }
  91. if maxDate.IsZero() || currDate.After(maxDate) {
  92. maxDate = currDate
  93. }
  94. dateMap[currDate] = v.Value
  95. }
  96. // 处理领先、滞后数据
  97. newDateMap := make(map[time.Time]float64)
  98. for currDate, value := range dateMap {
  99. newDate := currDate.AddDate(0, 0, moveDay)
  100. newDateMap[newDate] = value
  101. }
  102. minDate = minDate.AddDate(0, 0, moveDay)
  103. maxDate = maxDate.AddDate(0, 0, moveDay)
  104. // 获取日期相差日
  105. dayNum := utils.GetTimeSubDay(minDate, maxDate)
  106. for i := 0; i <= dayNum; i++ {
  107. currDate := minDate.AddDate(0, 0, i)
  108. tmpValue, ok := newDateMap[currDate]
  109. if !ok {
  110. //找不到数据,那么就用前面的数据吧
  111. if len(newDataList)-1 < 0 {
  112. tmpValue = 0
  113. } else {
  114. tmpValue = newDataList[len(newDataList)-1].Value
  115. }
  116. }
  117. tmpData := data_manage.EdbDataList{
  118. DataTime: currDate.Format(utils.FormatDate),
  119. Value: tmpValue,
  120. }
  121. dateDataMap[tmpData.DataTime] = tmpData.Value
  122. newDataList = append(newDataList, tmpData)
  123. }
  124. return
  125. }
  126. // GetChartEdbInfoFormat 相关性图表-获取指标信息
  127. func GetChartEdbInfoFormat(chartInfoId int, edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping) (edbList []*data_manage.ChartEdbInfoMapping, err error) {
  128. edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
  129. if edbInfoMappingA == nil || edbInfoMappingB == nil {
  130. err = fmt.Errorf("指标信息有误")
  131. return
  132. }
  133. edbInfoMappingA.FrequencyEn = data.GetFrequencyEn(edbInfoMappingA.Frequency)
  134. if edbInfoMappingA.Unit == `无` {
  135. edbInfoMappingA.Unit = ``
  136. }
  137. if edbInfoMappingB.Unit == `无` {
  138. edbInfoMappingB.Unit = ``
  139. }
  140. if chartInfoId <= 0 {
  141. edbInfoMappingA.IsAxis = 1
  142. edbInfoMappingA.LeadValue = 0
  143. edbInfoMappingA.LeadUnit = ""
  144. edbInfoMappingA.ChartEdbMappingId = 0
  145. edbInfoMappingA.ChartInfoId = 0
  146. edbInfoMappingA.IsOrder = false
  147. edbInfoMappingA.EdbInfoType = 1
  148. edbInfoMappingA.ChartStyle = ""
  149. edbInfoMappingA.ChartColor = ""
  150. edbInfoMappingA.ChartWidth = 0
  151. edbInfoMappingB.IsAxis = 1
  152. edbInfoMappingB.LeadValue = 0
  153. edbInfoMappingB.LeadUnit = ""
  154. edbInfoMappingB.ChartEdbMappingId = 0
  155. edbInfoMappingB.ChartInfoId = 0
  156. edbInfoMappingB.IsOrder = false
  157. edbInfoMappingB.EdbInfoType = 1
  158. edbInfoMappingB.ChartStyle = ""
  159. edbInfoMappingB.ChartColor = ""
  160. edbInfoMappingB.ChartWidth = 0
  161. } else {
  162. edbInfoMappingA.LeadUnitEn = data.GetLeadUnitEn(edbInfoMappingA.LeadUnit)
  163. edbInfoMappingB.LeadUnitEn = data.GetLeadUnitEn(edbInfoMappingB.LeadUnit)
  164. }
  165. edbList = append(edbList, edbInfoMappingA, edbInfoMappingB)
  166. return
  167. }
  168. // GetChartAndCorrelationInfo 获取图表信息和相关信息信息
  169. func GetChartAndCorrelationInfo(chartInfoId int) (chartInfo *data_manage.ChartInfo, correlationInfo *data_manage.ChartInfoCorrelation, tips string, err error) {
  170. item, e := data_manage.GetChartInfoById(chartInfoId)
  171. if e != nil {
  172. if e.Error() == utils.ErrNoRow() {
  173. tips = "图表已被删除, 请刷新页面"
  174. err = fmt.Errorf("图表已被删除, 请刷新页面")
  175. return
  176. }
  177. err = fmt.Errorf("获取图表信息失败, Err: %s", e.Error())
  178. return
  179. }
  180. if item.Source != utils.CHART_SOURCE_CORRELATION {
  181. tips = "该图不是相关性图表"
  182. err = fmt.Errorf("该图不是相关性图表")
  183. return
  184. }
  185. chartInfo = item
  186. correlationInfo = new(data_manage.ChartInfoCorrelation)
  187. if e = correlationInfo.GetItemById(chartInfo.ChartInfoId); e != nil {
  188. err = fmt.Errorf("获取图表相关性信息失败, Err: %s", e.Error())
  189. return
  190. }
  191. return
  192. }