chart_info.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. package correlation
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/shopspring/decimal"
  7. "hongze/hongze_yb/models/response/chart_info"
  8. "hongze/hongze_yb/models/tables/chart_edb_mapping"
  9. "hongze/hongze_yb/models/tables/chart_info_correlation"
  10. "hongze/hongze_yb/models/tables/edb_data"
  11. edbDataModel "hongze/hongze_yb/models/tables/edb_data"
  12. "hongze/hongze_yb/services/alarm_msg"
  13. "hongze/hongze_yb/services/chart"
  14. "hongze/hongze_yb/utils"
  15. "math"
  16. "strings"
  17. "time"
  18. )
  19. // HandleDataByLinearRegression 线性方程插值法补全数据
  20. func HandleDataByLinearRegression(originList []*edb_data.EdbDataList, handleDataMap map[string]float64) (newList []*edb_data.EdbDataList, err error) {
  21. if len(originList) < 2 {
  22. return
  23. }
  24. var startEdbInfoData *edb_data.EdbDataList
  25. for _, v := range originList {
  26. handleDataMap[v.DataTime] = v.Value
  27. // 第一个数据就给过滤了,给后面的试用
  28. if startEdbInfoData == nil {
  29. startEdbInfoData = v
  30. newList = append(newList, &edb_data.EdbDataList{
  31. DataTime: v.DataTime,
  32. Value: v.Value,
  33. })
  34. continue
  35. }
  36. // 获取两条数据之间相差的天数
  37. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  38. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  39. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  40. betweenDay := betweenHour / 24
  41. // 如果相差一天,那么过滤
  42. if betweenDay <= 1 {
  43. startEdbInfoData = v
  44. newList = append(newList, &edb_data.EdbDataList{
  45. DataTime: v.DataTime,
  46. Value: v.Value,
  47. })
  48. continue
  49. }
  50. // 生成线性方程式
  51. var a, b float64
  52. {
  53. coordinateData := make([]utils.Coordinate, 0)
  54. tmpCoordinate1 := utils.Coordinate{
  55. X: 1,
  56. Y: startEdbInfoData.Value,
  57. }
  58. coordinateData = append(coordinateData, tmpCoordinate1)
  59. tmpCoordinate2 := utils.Coordinate{
  60. X: float64(betweenDay) + 1,
  61. Y: v.Value,
  62. }
  63. coordinateData = append(coordinateData, tmpCoordinate2)
  64. a, b = utils.GetLinearResult(coordinateData)
  65. if math.IsNaN(a) || math.IsNaN(b) {
  66. err = fmt.Errorf("线性方程公式生成失败")
  67. return
  68. }
  69. }
  70. // 生成对应的值
  71. {
  72. for i := 1; i < betweenDay; i++ {
  73. tmpDataTime := startDataTime.AddDate(0, 0, i)
  74. aDecimal := decimal.NewFromFloat(a)
  75. xDecimal := decimal.NewFromInt(int64(i) + 1)
  76. bDecimal := decimal.NewFromFloat(b)
  77. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  78. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
  79. newList = append(newList, &edb_data.EdbDataList{
  80. DataTime: tmpDataTime.Format(utils.FormatDate),
  81. Value: val,
  82. })
  83. }
  84. }
  85. // 最后将自己赋值
  86. newList = append(newList, &edb_data.EdbDataList{
  87. EdbDataId: v.EdbDataId,
  88. DataTime: v.DataTime,
  89. Value: v.Value,
  90. })
  91. startEdbInfoData = v
  92. }
  93. return
  94. }
  95. // MoveDataDaysToNewDataList 平移指标数据生成新的数据序列
  96. func MoveDataDaysToNewDataList(dataList []*edb_data.EdbDataList, moveDay int) (newDataList []edb_data.EdbDataList, dateDataMap map[string]float64) {
  97. dateMap := make(map[time.Time]float64)
  98. var minDate, maxDate time.Time
  99. dateDataMap = make(map[string]float64)
  100. for _, v := range dataList {
  101. currDate, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  102. if minDate.IsZero() || currDate.Before(minDate) {
  103. minDate = currDate
  104. }
  105. if maxDate.IsZero() || currDate.After(maxDate) {
  106. maxDate = currDate
  107. }
  108. dateMap[currDate] = v.Value
  109. }
  110. // 处理领先、滞后数据
  111. newDateMap := make(map[time.Time]float64)
  112. for currDate, value := range dateMap {
  113. newDate := currDate.AddDate(0, 0, moveDay)
  114. newDateMap[newDate] = value
  115. }
  116. minDate = minDate.AddDate(0, 0, moveDay)
  117. maxDate = maxDate.AddDate(0, 0, moveDay)
  118. // 获取日期相差日
  119. dayNum := utils.GetTimeSubDay(minDate, maxDate)
  120. for i := 0; i <= dayNum; i++ {
  121. currDate := minDate.AddDate(0, 0, i)
  122. tmpValue, ok := newDateMap[currDate]
  123. if !ok {
  124. //找不到数据,那么就用前面的数据吧
  125. if len(newDataList)-1 < 0 {
  126. tmpValue = 0
  127. } else {
  128. tmpValue = newDataList[len(newDataList)-1].Value
  129. }
  130. }
  131. tmpData := edb_data.EdbDataList{
  132. DataTime: currDate.Format(utils.FormatDate),
  133. Value: tmpValue,
  134. }
  135. dateDataMap[tmpData.DataTime] = tmpData.Value
  136. newDataList = append(newDataList, tmpData)
  137. }
  138. return
  139. }
  140. // GetChartEdbInfoFormat 相关性图表-获取指标信息
  141. func GetChartEdbInfoFormat(chartInfoId int, edbInfoMappingA, edbInfoMappingB *chart_edb_mapping.ChartEdbInfoMapping) (edbList []*chart_edb_mapping.ChartEdbInfoMappingList, err error) {
  142. edbList = make([]*chart_edb_mapping.ChartEdbInfoMappingList, 0)
  143. if edbInfoMappingA == nil || edbInfoMappingB == nil {
  144. err = fmt.Errorf("指标信息有误")
  145. return
  146. }
  147. edbInfoMappingA.FrequencyEn = chart.GetFrequencyEn(edbInfoMappingA.Frequency)
  148. if edbInfoMappingA.Unit == `无` {
  149. edbInfoMappingA.Unit = ``
  150. }
  151. if edbInfoMappingB.Unit == `无` {
  152. edbInfoMappingB.Unit = ``
  153. }
  154. if chartInfoId <= 0 {
  155. edbInfoMappingA.IsAxis = 1
  156. edbInfoMappingA.LeadValue = 0
  157. edbInfoMappingA.LeadUnit = ""
  158. edbInfoMappingA.ChartEdbMappingId = 0
  159. edbInfoMappingA.ChartInfoId = 0
  160. edbInfoMappingA.IsOrder = false
  161. edbInfoMappingA.EdbInfoType = 1
  162. edbInfoMappingA.ChartStyle = ""
  163. edbInfoMappingA.ChartColor = ""
  164. edbInfoMappingA.ChartWidth = 0
  165. edbInfoMappingB.IsAxis = 1
  166. edbInfoMappingB.LeadValue = 0
  167. edbInfoMappingB.LeadUnit = ""
  168. edbInfoMappingB.ChartEdbMappingId = 0
  169. edbInfoMappingB.ChartInfoId = 0
  170. edbInfoMappingB.IsOrder = false
  171. edbInfoMappingB.EdbInfoType = 1
  172. edbInfoMappingB.ChartStyle = ""
  173. edbInfoMappingB.ChartColor = ""
  174. edbInfoMappingB.ChartWidth = 0
  175. } else {
  176. edbInfoMappingA.LeadUnitEn = chart.GetLeadUnitEn(edbInfoMappingA.LeadUnit)
  177. edbInfoMappingB.LeadUnitEn = chart.GetLeadUnitEn(edbInfoMappingB.LeadUnit)
  178. }
  179. aList := new(chart_edb_mapping.ChartEdbInfoMappingList)
  180. aList.ChartEdbInfoMapping = *edbInfoMappingA
  181. bList := new(chart_edb_mapping.ChartEdbInfoMappingList)
  182. bList.ChartEdbInfoMapping = *edbInfoMappingB
  183. edbList = append(edbList, aList, bList)
  184. return
  185. }
  186. // GetChartDataByEdbInfo 相关性图表-根据指标信息获取x轴和y轴
  187. func GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *chart_edb_mapping.ChartEdbInfoMapping, leadValue int, leadUnit, startDate, endDate string) (xEdbIdValue []int, yDataList []chart_info.YData, err error) {
  188. xData := make([]int, 0)
  189. yData := make([]float64, 0)
  190. if leadValue == 0 {
  191. xData = append(xData, 0)
  192. }
  193. if leadValue > 0 {
  194. leadMin := 0 - leadValue
  195. xLen := 2*leadValue + 1
  196. for i := 0; i < xLen; i++ {
  197. n := leadMin + i
  198. xData = append(xData, n)
  199. }
  200. }
  201. // 计算窗口,不包含第一天
  202. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  203. startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  204. //// 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
  205. //baseEdbInfo := edbInfoMappingB
  206. //changeEdbInfo := edbInfoMappingA
  207. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  208. baseEdbInfo := edbInfoMappingA
  209. changeEdbInfo := edbInfoMappingB
  210. // 获取时间基准指标在时间区间内的值
  211. aDataList := make([]*edb_data.EdbDataList, 0)
  212. switch baseEdbInfo.EdbInfoCategoryType {
  213. case 0:
  214. aDataList, err = edb_data.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
  215. case 1:
  216. _, aDataList, _, _, err, _ = chart.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
  217. default:
  218. err = errors.New("指标base类型异常")
  219. return
  220. }
  221. // 获取变频指标所有日期的值, 插值法完善数据
  222. bDataList := make([]*edb_data.EdbDataList, 0)
  223. switch changeEdbInfo.EdbInfoCategoryType {
  224. case 0:
  225. bDataList, err = edb_data.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
  226. case 1:
  227. _, bDataList, _, _, err, _ = chart.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
  228. default:
  229. err = errors.New("指标change类型异常")
  230. return
  231. }
  232. //changeDataMap := make(map[string]float64)
  233. //newChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  234. //if e != nil {
  235. // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  236. // return
  237. //}
  238. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  239. baseDataList := make([]*edb_data.EdbDataList, 0)
  240. baseDataMap := make(map[string]float64)
  241. changeDataList := make([]*edb_data.EdbDataList, 0)
  242. changeDataMap := make(map[string]float64)
  243. // 先把低频指标升频为高频
  244. {
  245. frequencyIntMap := map[string]int{
  246. "日度": 1,
  247. "周度": 2,
  248. "旬度": 3,
  249. "月度": 4,
  250. "季度": 5,
  251. "年度": 6,
  252. }
  253. // 如果A指标是高频,那么就需要对B指标进行升频
  254. if frequencyIntMap[edbInfoMappingA.Frequency] < frequencyIntMap[edbInfoMappingB.Frequency] {
  255. tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  256. if e != nil {
  257. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  258. return
  259. }
  260. changeDataList = tmpNewChangeDataList
  261. baseDataList = aDataList
  262. for _, v := range baseDataList {
  263. baseDataMap[v.DataTime] = v.Value
  264. }
  265. } else if frequencyIntMap[edbInfoMappingA.Frequency] > frequencyIntMap[edbInfoMappingB.Frequency] {
  266. // 如果B指标是高频,那么就需要对A指标进行升频
  267. tmpNewChangeDataList, e := HandleDataByLinearRegression(aDataList, baseDataMap)
  268. if e != nil {
  269. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  270. return
  271. }
  272. baseDataList = tmpNewChangeDataList
  273. changeDataList = bDataList
  274. for _, v := range changeDataList {
  275. changeDataMap[v.DataTime] = v.Value
  276. }
  277. } else {
  278. baseDataList = aDataList
  279. for _, v := range baseDataList {
  280. baseDataMap[v.DataTime] = v.Value
  281. }
  282. changeDataList = bDataList
  283. for _, v := range changeDataList {
  284. changeDataMap[v.DataTime] = v.Value
  285. }
  286. }
  287. }
  288. // 计算不领先也不滞后时的相关系数
  289. baseCalculateData := make([]float64, 0)
  290. baseDataTimeArr := make([]string, 0)
  291. for i := range baseDataList {
  292. baseDataTimeArr = append(baseDataTimeArr, baseDataList[i].DataTime)
  293. baseCalculateData = append(baseCalculateData, baseDataList[i].Value)
  294. }
  295. //zeroBaseData := make([]float64, 0)
  296. //zeroCalculateData := make([]float64, 0)
  297. //for i := range baseDataTimeArr {
  298. // tmpBaseVal, ok1 := baseDataMap[baseDataTimeArr[i]]
  299. // tmpCalculateVal, ok2 := changeDataMap[baseDataTimeArr[i]]
  300. // if ok1 && ok2 {
  301. // zeroBaseData = append(zeroBaseData, tmpBaseVal)
  302. // zeroCalculateData = append(zeroCalculateData, tmpCalculateVal)
  303. // }
  304. //}
  305. //if len(zeroBaseData) != len(zeroCalculateData) {
  306. // err = fmt.Errorf("相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(zeroCalculateData))
  307. // return
  308. //}
  309. //zeroRatio := utils.CalculateCorrelationByIntArr(zeroBaseData, zeroCalculateData)
  310. //if leadValue == 0 {
  311. // yData = append(yData, zeroRatio)
  312. //}
  313. // 计算领先/滞后N期
  314. if leadValue > 0 {
  315. // 平移变频指标领先/滞后的日期(单位天)
  316. moveUnitDays := utils.FrequencyDaysMap[leadUnit]
  317. for i := range xData {
  318. //if xData[i] == 0 {
  319. // yData = append(yData, zeroRatio)
  320. // continue
  321. //}
  322. xCalculateData := make([]float64, 0)
  323. yCalculateData := make([]float64, 0)
  324. // 平移指定天数
  325. mDays := int(moveUnitDays) * xData[i]
  326. _, dMap := MoveDataDaysToNewDataList(changeDataList, mDays)
  327. // 取出对应的基准日期的值
  328. for i2 := range baseDataTimeArr {
  329. if yVal, ok := dMap[baseDataTimeArr[i2]]; ok {
  330. xCalculateData = append(xCalculateData, baseCalculateData[i2])
  331. yCalculateData = append(yCalculateData, yVal)
  332. }
  333. }
  334. if len(yCalculateData) <= 0 {
  335. //err = fmt.Errorf("领先滞后相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(yCalculateData))
  336. //return
  337. // 领先滞后后,没有可以计算的数据了
  338. continue
  339. }
  340. // 公式计算出领先/滞后频度对应点的相关性系数
  341. ratio := utils.CalculateCorrelationByIntArr(xCalculateData, yCalculateData)
  342. yData = append(yData, ratio)
  343. }
  344. }
  345. xEdbIdValue = xData
  346. yDataList = make([]chart_info.YData, 0)
  347. yDate := "0000-00-00"
  348. yDataList = append(yDataList, chart_info.YData{
  349. Date: yDate,
  350. Value: yData,
  351. })
  352. return
  353. }
  354. // RollingCorrelationChartDataResp 滚动相关性图的数据
  355. type RollingCorrelationChartDataResp struct {
  356. MaxData float64
  357. MinData float64
  358. LatestDate string `description:"真实数据的最后日期"`
  359. EdbInfoCategoryType int
  360. ChartColor string
  361. ChartStyle string
  362. PredictChartColor string
  363. ChartType int
  364. ChartWidth int
  365. EdbName string
  366. EdbNameEn string
  367. Unit string
  368. UnitEn string
  369. IsAxis int
  370. DataList []edbDataModel.EdbDataList
  371. }
  372. // GetRollingCorrelationChartDataByEdbInfo 滚动相关性计算
  373. func GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *chart_edb_mapping.ChartEdbInfoMapping, leadValue int, leadUnit string, calculateValue int, calculateUnit string, startDate, endDate, chartName, chartNameEn string) (dataResp RollingCorrelationChartDataResp, err error) {
  374. dataResp = RollingCorrelationChartDataResp{
  375. DataList: make([]edbDataModel.EdbDataList, 0),
  376. MaxData: 0,
  377. MinData: 0,
  378. ChartColor: "#00f",
  379. ChartStyle: `spline`,
  380. PredictChartColor: `#00f`,
  381. ChartType: 0,
  382. ChartWidth: 3,
  383. EdbName: chartName,
  384. EdbNameEn: chartNameEn,
  385. IsAxis: 1,
  386. }
  387. dataList := make([]edbDataModel.EdbDataList, 0)
  388. // 计算窗口,不包含第一天
  389. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  390. startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  391. baseEdbInfo := edbInfoMappingA
  392. changeEdbInfo := edbInfoMappingB
  393. // 获取时间基准指标在时间区间内的值
  394. aDataList := make([]*edb_data.EdbDataList, 0)
  395. switch baseEdbInfo.EdbInfoCategoryType {
  396. case 0:
  397. aDataList, err = edb_data.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
  398. case 1:
  399. _, aDataList, _, _, err, _ = chart.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
  400. default:
  401. err = errors.New("指标base类型异常")
  402. return
  403. }
  404. // 获取变频指标所有日期的值, 插值法完善数据
  405. bDataList := make([]*edb_data.EdbDataList, 0)
  406. switch changeEdbInfo.EdbInfoCategoryType {
  407. case 0:
  408. bDataList, err = edb_data.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
  409. case 1:
  410. _, bDataList, _, _, err, _ = chart.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
  411. default:
  412. err = errors.New("指标change类型异常")
  413. return
  414. }
  415. // 数据平移变频指标领先/滞后的日期(单位天)
  416. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  417. //baseDataList := make([]*edb_data.EdbDataList, 0)
  418. baseDataMap := make(map[string]float64)
  419. changeDataList := make([]*edb_data.EdbDataList, 0)
  420. changeDataMap := make(map[string]float64)
  421. // A指标不管三七二十一,先变个频再说
  422. {
  423. _, e := HandleDataByLinearRegression(aDataList, baseDataMap)
  424. if e != nil {
  425. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  426. return
  427. }
  428. //baseDataList = tmpNewChangeDataList
  429. }
  430. // B指标不管三七二十一,先变个频再说
  431. {
  432. tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  433. if e != nil {
  434. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  435. return
  436. }
  437. changeDataList = tmpNewChangeDataList
  438. // 平移下日期
  439. moveUnitDays := utils.FrequencyDaysMap[leadUnit]
  440. _, changeDataMap = MoveDataDaysToNewDataList(changeDataList, leadValue*moveUnitDays)
  441. }
  442. // 计算计算时,需要多少个日期内数据
  443. calculateDay := utils.FrequencyDaysMap[calculateUnit] * calculateValue
  444. // 计算 每个日期的相关性值
  445. {
  446. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  447. if endDate == `` {
  448. // 因为时间格式是:2023-07-19T00:00:00+08:00;所以需要分开
  449. endDateList := strings.Split(baseEdbInfo.EndDate, "T")
  450. endDate = endDateList[0]
  451. }
  452. endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  453. endDateTime = endDateTime.AddDate(0, 0, -(calculateDay - 1))
  454. // 是否开始第一条数据
  455. var isStart, isNotFirst bool
  456. for currDay := startDateTime; !currDay.After(endDateTime); currDay = currDay.AddDate(0, 0, 1) {
  457. yCalculateData := make([]float64, 0)
  458. baseCalculateData := make([]float64, 0)
  459. // 取出对应的基准日期的值
  460. for i := 0; i < calculateDay; i++ {
  461. iDay := currDay.AddDate(0, 0, i).Format(utils.FormatDate)
  462. tmpBaseValue, ok1 := baseDataMap[iDay]
  463. tmpChangeValue, ok2 := changeDataMap[iDay]
  464. if ok1 && ok2 {
  465. baseCalculateData = append(baseCalculateData, tmpBaseValue)
  466. yCalculateData = append(yCalculateData, tmpChangeValue)
  467. } else {
  468. continue
  469. }
  470. }
  471. // 公式计算出领先/滞后频度对应点的相关性系数
  472. var ratio float64
  473. if len(baseCalculateData) > 0 {
  474. ratio = utils.CalculateCorrelationByIntArr(baseCalculateData, yCalculateData)
  475. } else {
  476. // 没有数据的话,那就不返回
  477. continue
  478. }
  479. // 过滤前面都是0的数据
  480. {
  481. if ratio != 0 {
  482. isStart = true
  483. }
  484. if !isStart {
  485. continue
  486. }
  487. }
  488. dataTime := currDay.AddDate(0, 0, calculateDay-1)
  489. dataList = append(dataList, edbDataModel.EdbDataList{
  490. //EdbDataId: 0,
  491. EdbInfoId: 0,
  492. DataTime: dataTime.Format(utils.FormatDate),
  493. DataTimestamp: dataTime.UnixNano() / 1e6,
  494. Value: ratio,
  495. })
  496. if !isNotFirst {
  497. dataResp.MinData = ratio
  498. dataResp.MaxData = ratio
  499. isNotFirst = true
  500. }
  501. if dataResp.MinData > ratio {
  502. dataResp.MinData = ratio
  503. }
  504. if dataResp.MaxData < ratio {
  505. dataResp.MaxData = ratio
  506. }
  507. }
  508. dataResp.DataList = dataList
  509. }
  510. return
  511. }
  512. // ChartInfoRefresh 图表刷新
  513. func ChartInfoRefresh(chartInfoId int) (err error) {
  514. var errMsg string
  515. defer func() {
  516. if err != nil {
  517. //fmt.Println(err.Error())
  518. go alarm_msg.SendAlarmMsg("CorrelationChartInfoRefresh: "+errMsg, 3)
  519. }
  520. }()
  521. correlationChart := new(chart_info_correlation.ChartInfoCorrelation)
  522. if err = correlationChart.GetItemById(chartInfoId); err != nil {
  523. errMsg = "获取相关性图表失败, Err: " + err.Error()
  524. return
  525. }
  526. // 批量刷新ETA指标
  527. err, errMsg = chart.EdbInfoRefreshAllFromBase([]int{correlationChart.EdbInfoIdFirst, correlationChart.EdbInfoIdSecond}, false)
  528. if err != nil {
  529. return
  530. }
  531. // 重新生成数据并更新
  532. edbInfoMappingA, err := chart_edb_mapping.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdFirst)
  533. if err != nil {
  534. errMsg = "获取相关性图表, A指标mapping信息失败, Err:" + err.Error()
  535. return
  536. }
  537. edbInfoMappingB, err := chart_edb_mapping.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdSecond)
  538. if err != nil {
  539. errMsg = "获取相关性图表, B指标mapping信息失败, Err:" + err.Error()
  540. return
  541. }
  542. periodData, correlationData, err := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationChart.LeadValue, correlationChart.LeadUnit, correlationChart.StartDate.Format(utils.FormatDate), correlationChart.EndDate.Format(utils.FormatDate))
  543. if err != nil {
  544. errMsg = "获取相关性图表, 图表计算值失败, Err:" + err.Error()
  545. return
  546. }
  547. periodDataByte, err := json.Marshal(periodData)
  548. if err != nil {
  549. errMsg = "相关性图表, X轴信息有误, Err:" + err.Error()
  550. return
  551. }
  552. correlationDataByte, err := json.Marshal(correlationData[0].Value)
  553. if err != nil {
  554. errMsg = "相关性图表, Y轴信息有误, Err:" + err.Error()
  555. return
  556. }
  557. correlationChart.PeriodData = string(periodDataByte)
  558. correlationChart.CorrelationData = string(correlationDataByte)
  559. correlationChart.ModifyTime = time.Now().Local()
  560. correlationUpdateCols := []string{"PeriodData", "CorrelationData", "ModifyTime"}
  561. if err = correlationChart.Update(correlationUpdateCols); err != nil {
  562. errMsg = "更新相关性图表失败, Err:" + err.Error()
  563. return
  564. }
  565. return
  566. }