chart_info.go 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583
  1. package correlation
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_api/models/data_manage"
  6. "eta/eta_api/models/system"
  7. "eta/eta_api/services/alarm_msg"
  8. "eta/eta_api/services/data"
  9. "eta/eta_api/utils"
  10. "fmt"
  11. "github.com/shopspring/decimal"
  12. "math"
  13. "sort"
  14. "strconv"
  15. "strings"
  16. "time"
  17. )
  18. // HandleDataByLinearRegression 线性方程插值法补全数据
  19. func HandleDataByLinearRegression(originList []*data_manage.EdbDataList, handleDataMap map[string]float64) (newList []*data_manage.EdbDataList, err error) {
  20. if len(originList) < 2 {
  21. return
  22. }
  23. var startEdbInfoData *data_manage.EdbDataList
  24. for _, v := range originList {
  25. handleDataMap[v.DataTime] = v.Value
  26. // 第一个数据就给过滤了,给后面的试用
  27. if startEdbInfoData == nil {
  28. startEdbInfoData = v
  29. newList = append(newList, &data_manage.EdbDataList{
  30. DataTime: v.DataTime,
  31. Value: v.Value,
  32. })
  33. continue
  34. }
  35. // 获取两条数据之间相差的天数
  36. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  37. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  38. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  39. betweenDay := betweenHour / 24
  40. // 如果相差一天,那么过滤
  41. if betweenDay <= 1 {
  42. startEdbInfoData = v
  43. newList = append(newList, &data_manage.EdbDataList{
  44. DataTime: v.DataTime,
  45. Value: v.Value,
  46. })
  47. continue
  48. }
  49. // 生成线性方程式
  50. var a, b float64
  51. {
  52. coordinateData := make([]utils.Coordinate, 0)
  53. tmpCoordinate1 := utils.Coordinate{
  54. X: 1,
  55. Y: startEdbInfoData.Value,
  56. }
  57. coordinateData = append(coordinateData, tmpCoordinate1)
  58. tmpCoordinate2 := utils.Coordinate{
  59. X: float64(betweenDay) + 1,
  60. Y: v.Value,
  61. }
  62. coordinateData = append(coordinateData, tmpCoordinate2)
  63. a, b = utils.GetLinearResult(coordinateData)
  64. if math.IsNaN(a) || math.IsNaN(b) {
  65. err = fmt.Errorf("线性方程公式生成失败")
  66. return
  67. }
  68. }
  69. // 生成对应的值
  70. {
  71. for i := 1; i < betweenDay; i++ {
  72. tmpDataTime := startDataTime.AddDate(0, 0, i)
  73. aDecimal := decimal.NewFromFloat(a)
  74. xDecimal := decimal.NewFromInt(int64(i) + 1)
  75. bDecimal := decimal.NewFromFloat(b)
  76. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  77. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
  78. newList = append(newList, &data_manage.EdbDataList{
  79. DataTime: tmpDataTime.Format(utils.FormatDate),
  80. Value: val,
  81. })
  82. }
  83. }
  84. // 最后将自己赋值
  85. newList = append(newList, &data_manage.EdbDataList{
  86. EdbDataId: v.EdbDataId,
  87. DataTime: v.DataTime,
  88. Value: v.Value,
  89. })
  90. startEdbInfoData = v
  91. }
  92. return
  93. }
  94. // MoveDataDaysToNewDataList 平移指标数据生成新的数据序列
  95. func MoveDataDaysToNewDataList(dataList []*data_manage.EdbDataList, moveDay int) (newDataList []data_manage.EdbDataList, dateDataMap map[string]float64) {
  96. dateMap := make(map[time.Time]float64)
  97. var minDate, maxDate time.Time
  98. dateDataMap = make(map[string]float64)
  99. for _, v := range dataList {
  100. currDate, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  101. if minDate.IsZero() || currDate.Before(minDate) {
  102. minDate = currDate
  103. }
  104. if maxDate.IsZero() || currDate.After(maxDate) {
  105. maxDate = currDate
  106. }
  107. dateMap[currDate] = v.Value
  108. }
  109. // 处理领先、滞后数据
  110. newDateMap := make(map[time.Time]float64)
  111. for currDate, value := range dateMap {
  112. newDate := currDate.AddDate(0, 0, moveDay)
  113. newDateMap[newDate] = value
  114. }
  115. minDate = minDate.AddDate(0, 0, moveDay)
  116. maxDate = maxDate.AddDate(0, 0, moveDay)
  117. // 获取日期相差日
  118. dayNum := utils.GetTimeSubDay(minDate, maxDate)
  119. for i := 0; i <= dayNum; i++ {
  120. currDate := minDate.AddDate(0, 0, i)
  121. tmpValue, ok := newDateMap[currDate]
  122. if !ok {
  123. //找不到数据,那么就用前面的数据吧
  124. if len(newDataList)-1 < 0 {
  125. tmpValue = 0
  126. } else {
  127. tmpValue = newDataList[len(newDataList)-1].Value
  128. }
  129. }
  130. tmpData := data_manage.EdbDataList{
  131. DataTime: currDate.Format(utils.FormatDate),
  132. Value: tmpValue,
  133. }
  134. dateDataMap[tmpData.DataTime] = tmpData.Value
  135. newDataList = append(newDataList, tmpData)
  136. }
  137. return
  138. }
  139. // GetChartEdbInfoFormat 相关性图表-获取指标信息
  140. func GetChartEdbInfoFormat(chartInfoId int, edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping) (edbList []*data_manage.ChartEdbInfoMapping, err error) {
  141. edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
  142. if edbInfoMappingA == nil || edbInfoMappingB == nil {
  143. err = fmt.Errorf("指标信息有误")
  144. return
  145. }
  146. edbInfoMappingA.FrequencyEn = data.GetFrequencyEn(edbInfoMappingA.Frequency)
  147. if edbInfoMappingA.Unit == `无` {
  148. edbInfoMappingA.Unit = ``
  149. }
  150. if edbInfoMappingB.Unit == `无` {
  151. edbInfoMappingB.Unit = ``
  152. }
  153. if chartInfoId <= 0 {
  154. edbInfoMappingA.IsAxis = 1
  155. edbInfoMappingA.LeadValue = 0
  156. edbInfoMappingA.LeadUnit = ""
  157. edbInfoMappingA.ChartEdbMappingId = 0
  158. edbInfoMappingA.ChartInfoId = 0
  159. edbInfoMappingA.IsOrder = false
  160. edbInfoMappingA.EdbInfoType = 1
  161. edbInfoMappingA.ChartStyle = ""
  162. edbInfoMappingA.ChartColor = ""
  163. edbInfoMappingA.ChartWidth = 0
  164. edbInfoMappingB.IsAxis = 1
  165. edbInfoMappingB.LeadValue = 0
  166. edbInfoMappingB.LeadUnit = ""
  167. edbInfoMappingB.ChartEdbMappingId = 0
  168. edbInfoMappingB.ChartInfoId = 0
  169. edbInfoMappingB.IsOrder = false
  170. edbInfoMappingB.EdbInfoType = 1
  171. edbInfoMappingB.ChartStyle = ""
  172. edbInfoMappingB.ChartColor = ""
  173. edbInfoMappingB.ChartWidth = 0
  174. } else {
  175. edbInfoMappingA.LeadUnitEn = data.GetLeadUnitEn(edbInfoMappingA.LeadUnit)
  176. edbInfoMappingB.LeadUnitEn = data.GetLeadUnitEn(edbInfoMappingB.LeadUnit)
  177. }
  178. edbList = append(edbList, edbInfoMappingA, edbInfoMappingB)
  179. return
  180. }
  181. // GetChartDataByEdbInfo 相关性图表-根据指标信息获取x轴和y轴
  182. func GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping, leadValue int, leadUnit, startDate, endDate, extraConfig string) (xEdbIdValue []int, yDataList []data_manage.YData, err error) {
  183. xData := make([]int, 0)
  184. yData := make([]float64, 0)
  185. if leadValue == 0 {
  186. xData = append(xData, 0)
  187. }
  188. if leadValue > 0 {
  189. leadMin := 0 - leadValue
  190. xLen := 2*leadValue + 1
  191. for i := 0; i < xLen; i++ {
  192. n := leadMin + i
  193. xData = append(xData, n)
  194. }
  195. }
  196. // 计算窗口,不包含第一天
  197. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  198. startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  199. //// 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
  200. //baseEdbInfo := edbInfoMappingB
  201. //changeEdbInfo := edbInfoMappingA
  202. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  203. baseEdbInfo := edbInfoMappingA
  204. changeEdbInfo := edbInfoMappingB
  205. // 获取时间基准指标在时间区间内的值
  206. aDataList := make([]*data_manage.EdbDataList, 0)
  207. switch baseEdbInfo.EdbInfoCategoryType {
  208. case 0:
  209. aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
  210. case 1:
  211. _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
  212. default:
  213. err = errors.New("指标base类型异常")
  214. return
  215. }
  216. // 获取变频指标所有日期的值, 插值法完善数据
  217. bDataList := make([]*data_manage.EdbDataList, 0)
  218. switch changeEdbInfo.EdbInfoCategoryType {
  219. case 0:
  220. bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
  221. case 1:
  222. _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
  223. default:
  224. err = errors.New("指标change类型异常")
  225. return
  226. }
  227. //changeDataMap := make(map[string]float64)
  228. //newChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  229. //if e != nil {
  230. // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  231. // return
  232. //}
  233. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  234. baseDataList := make([]*data_manage.EdbDataList, 0)
  235. baseDataMap := make(map[string]float64)
  236. changeDataList := make([]*data_manage.EdbDataList, 0)
  237. changeDataMap := make(map[string]float64)
  238. // 先把低频指标升频为高频
  239. {
  240. frequencyIntMap := map[string]int{
  241. "日度": 1,
  242. "周度": 2,
  243. "旬度": 3,
  244. "月度": 4,
  245. "季度": 5,
  246. "年度": 6,
  247. }
  248. // 如果A指标是高频,那么就需要对B指标进行升频
  249. if frequencyIntMap[edbInfoMappingA.Frequency] < frequencyIntMap[edbInfoMappingB.Frequency] {
  250. tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  251. if e != nil {
  252. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  253. return
  254. }
  255. changeDataList = tmpNewChangeDataList
  256. baseDataList = aDataList
  257. for _, v := range baseDataList {
  258. baseDataMap[v.DataTime] = v.Value
  259. }
  260. } else if frequencyIntMap[edbInfoMappingA.Frequency] > frequencyIntMap[edbInfoMappingB.Frequency] {
  261. // 如果B指标是高频,那么就需要对A指标进行升频
  262. tmpNewChangeDataList, e := HandleDataByLinearRegression(aDataList, baseDataMap)
  263. if e != nil {
  264. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  265. return
  266. }
  267. baseDataList = tmpNewChangeDataList
  268. changeDataList = bDataList
  269. for _, v := range changeDataList {
  270. changeDataMap[v.DataTime] = v.Value
  271. }
  272. } else {
  273. baseDataList = aDataList
  274. for _, v := range baseDataList {
  275. baseDataMap[v.DataTime] = v.Value
  276. }
  277. changeDataList = bDataList
  278. for _, v := range changeDataList {
  279. changeDataMap[v.DataTime] = v.Value
  280. }
  281. }
  282. }
  283. // 计算不领先也不滞后时的相关系数
  284. baseCalculateData := make([]float64, 0)
  285. baseDataTimeArr := make([]string, 0)
  286. for i := range baseDataList {
  287. baseDataTimeArr = append(baseDataTimeArr, baseDataList[i].DataTime)
  288. baseCalculateData = append(baseCalculateData, baseDataList[i].Value)
  289. }
  290. //zeroBaseData := make([]float64, 0)
  291. //zeroCalculateData := make([]float64, 0)
  292. //for i := range baseDataTimeArr {
  293. // tmpBaseVal, ok1 := baseDataMap[baseDataTimeArr[i]]
  294. // tmpCalculateVal, ok2 := changeDataMap[baseDataTimeArr[i]]
  295. // if ok1 && ok2 {
  296. // zeroBaseData = append(zeroBaseData, tmpBaseVal)
  297. // zeroCalculateData = append(zeroCalculateData, tmpCalculateVal)
  298. // }
  299. //}
  300. //if len(zeroBaseData) != len(zeroCalculateData) {
  301. // err = fmt.Errorf("相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(zeroCalculateData))
  302. // return
  303. //}
  304. //zeroRatio := utils.CalculateCorrelationByIntArr(zeroBaseData, zeroCalculateData)
  305. //if leadValue == 0 {
  306. // yData = append(yData, zeroRatio)
  307. //}
  308. // 计算领先/滞后N期
  309. if leadValue > 0 {
  310. // 平移变频指标领先/滞后的日期(单位天)
  311. moveUnitDays := utils.FrequencyDaysMap[leadUnit]
  312. for i := range xData {
  313. //if xData[i] == 0 {
  314. // yData = append(yData, zeroRatio)
  315. // continue
  316. //}
  317. xCalculateData := make([]float64, 0)
  318. yCalculateData := make([]float64, 0)
  319. // 平移指定天数
  320. mDays := int(moveUnitDays) * xData[i]
  321. _, dMap := MoveDataDaysToNewDataList(changeDataList, mDays)
  322. // 取出对应的基准日期的值
  323. for i2 := range baseDataTimeArr {
  324. tmpDate := baseDataTimeArr[i2]
  325. if yVal, ok := dMap[tmpDate]; ok {
  326. xCalculateData = append(xCalculateData, baseCalculateData[i2])
  327. yCalculateData = append(yCalculateData, yVal)
  328. }
  329. }
  330. if len(yCalculateData) <= 0 {
  331. //err = fmt.Errorf("领先滞后相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(yCalculateData))
  332. //return
  333. // 领先滞后后,没有可以计算的数据了
  334. continue
  335. }
  336. // 公式计算出领先/滞后频度对应点的相关性系数
  337. ratio := utils.CalculateCorrelationByIntArr(xCalculateData, yCalculateData)
  338. yData = append(yData, ratio)
  339. }
  340. }
  341. // 图例
  342. var extra data_manage.CorrelationChartInfoExtraConfig
  343. legend := new(data_manage.CorrelationChartLegend)
  344. if extraConfig != "" {
  345. if e := json.Unmarshal([]byte(extraConfig), &extra); e != nil {
  346. err = fmt.Errorf("图例解析异常, err: %v", e)
  347. return
  348. }
  349. if len(extra.LegendConfig) > 0 {
  350. legend = extra.LegendConfig[0]
  351. }
  352. }
  353. xEdbIdValue = xData
  354. yDataList = make([]data_manage.YData, 0)
  355. yDate := "0000-00-00"
  356. var y data_manage.YData
  357. y.Date = yDate
  358. y.Value = yData
  359. if legend != nil {
  360. y.Name = legend.LegendName
  361. y.Color = legend.Color
  362. }
  363. yDataList = append(yDataList, y)
  364. return
  365. }
  366. // RollingCorrelationChartDataResp 滚动相关性图表数据
  367. type RollingCorrelationChartDataResp struct {
  368. MaxData float64
  369. MinData float64
  370. LatestDate string `description:"真实数据的最后日期"`
  371. EdbInfoCategoryType int
  372. ChartColor string
  373. ChartStyle string
  374. PredictChartColor string
  375. ChartType int
  376. ChartWidth int
  377. EdbName string
  378. EdbNameEn string
  379. Unit string
  380. UnitEn string
  381. IsAxis int
  382. DataList []data_manage.EdbDataList
  383. }
  384. // GetRollingCorrelationChartDataByEdbInfo 滚动相关性计算
  385. func GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping, leadValue int, leadUnit string, calculateValue int, calculateUnit string, startDate, endDate, chartName, chartNameEn string) (dataResp RollingCorrelationChartDataResp, err error) {
  386. dataResp = RollingCorrelationChartDataResp{
  387. DataList: make([]data_manage.EdbDataList, 0),
  388. MaxData: 0,
  389. MinData: 0,
  390. ChartColor: "#00f",
  391. ChartStyle: `spline`,
  392. PredictChartColor: `#00f`,
  393. ChartType: 0,
  394. ChartWidth: 3,
  395. EdbName: chartName,
  396. EdbNameEn: chartNameEn,
  397. IsAxis: 1,
  398. }
  399. dataList := make([]data_manage.EdbDataList, 0)
  400. // 计算窗口,不包含第一天
  401. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  402. startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  403. baseEdbInfo := edbInfoMappingA
  404. changeEdbInfo := edbInfoMappingB
  405. // 获取时间基准指标在时间区间内的值
  406. aDataList := make([]*data_manage.EdbDataList, 0)
  407. switch baseEdbInfo.EdbInfoCategoryType {
  408. case 0:
  409. aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
  410. case 1:
  411. _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, true)
  412. default:
  413. err = errors.New("指标base类型异常")
  414. return
  415. }
  416. // 获取变频指标所有日期的值, 插值法完善数据
  417. bDataList := make([]*data_manage.EdbDataList, 0)
  418. switch changeEdbInfo.EdbInfoCategoryType {
  419. case 0:
  420. bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
  421. case 1:
  422. _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
  423. default:
  424. err = errors.New("指标change类型异常")
  425. return
  426. }
  427. // 数据平移变频指标领先/滞后的日期(单位天)
  428. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  429. //baseDataList := make([]*data_manage.EdbDataList, 0)
  430. baseDataMap := make(map[string]float64)
  431. changeDataList := make([]*data_manage.EdbDataList, 0)
  432. changeDataMap := make(map[string]float64)
  433. // A指标不管三七二十一,先变个频再说
  434. {
  435. _, e := HandleDataByLinearRegression(aDataList, baseDataMap)
  436. if e != nil {
  437. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  438. return
  439. }
  440. //baseDataList = tmpNewChangeDataList
  441. }
  442. // B指标不管三七二十一,先变个频再说
  443. {
  444. tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  445. if e != nil {
  446. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  447. return
  448. }
  449. changeDataList = tmpNewChangeDataList
  450. // 平移下日期
  451. moveUnitDays := utils.FrequencyDaysMap[leadUnit]
  452. _, changeDataMap = MoveDataDaysToNewDataList(changeDataList, leadValue*moveUnitDays)
  453. }
  454. // 计算计算时,需要多少个日期内数据
  455. calculateDay := utils.FrequencyDaysMap[calculateUnit] * calculateValue
  456. // 计算 每个日期的相关性值
  457. {
  458. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  459. if endDate == `` {
  460. endDate = baseEdbInfo.EndDate
  461. }
  462. endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  463. endDateTime = endDateTime.AddDate(0, 0, -(calculateDay - 1))
  464. // 是否开始第一条数据
  465. var isStart, isNotFirst bool
  466. for currDay := startDateTime; !currDay.After(endDateTime); currDay = currDay.AddDate(0, 0, 1) {
  467. yCalculateData := make([]float64, 0)
  468. baseCalculateData := make([]float64, 0)
  469. // 取出对应的基准日期的值
  470. for i := 0; i < calculateDay; i++ {
  471. iDay := currDay.AddDate(0, 0, i).Format(utils.FormatDate)
  472. tmpBaseValue, ok1 := baseDataMap[iDay]
  473. tmpChangeValue, ok2 := changeDataMap[iDay]
  474. if ok1 && ok2 {
  475. baseCalculateData = append(baseCalculateData, tmpBaseValue)
  476. yCalculateData = append(yCalculateData, tmpChangeValue)
  477. } else {
  478. continue
  479. }
  480. }
  481. // 公式计算出领先/滞后频度对应点的相关性系数
  482. var ratio float64
  483. if len(baseCalculateData) > 0 {
  484. ratio = utils.CalculateCorrelationByIntArr(baseCalculateData, yCalculateData)
  485. } else {
  486. // 没有数据的话,那就不返回
  487. continue
  488. }
  489. // 过滤前面都是0的数据
  490. {
  491. if ratio != 0 {
  492. isStart = true
  493. }
  494. if !isStart {
  495. continue
  496. }
  497. }
  498. dataTime := currDay.AddDate(0, 0, calculateDay-1)
  499. dataList = append(dataList, data_manage.EdbDataList{
  500. //EdbDataId: 0,
  501. EdbInfoId: 0,
  502. DataTime: dataTime.Format(utils.FormatDate),
  503. DataTimestamp: dataTime.UnixNano() / 1e6,
  504. Value: ratio,
  505. })
  506. if !isNotFirst {
  507. dataResp.MinData = ratio
  508. dataResp.MaxData = ratio
  509. isNotFirst = true
  510. }
  511. if dataResp.MinData > ratio {
  512. dataResp.MinData = ratio
  513. }
  514. if dataResp.MaxData < ratio {
  515. dataResp.MaxData = ratio
  516. }
  517. }
  518. dataResp.DataList = dataList
  519. }
  520. return
  521. }
  522. // ChartInfoRefresh 图表刷新
  523. func ChartInfoRefresh(chartInfoId int, uniqueCode string) (isAsync bool, err error) {
  524. var errMsg string
  525. defer func() {
  526. if err != nil {
  527. tips := fmt.Sprintf("CorrelationChartInfoRefresh: %s", errMsg)
  528. utils.FileLog.Info(tips)
  529. go alarm_msg.SendAlarmMsg(tips, 3)
  530. }
  531. }()
  532. correlationChart := new(data_manage.ChartInfoCorrelation)
  533. if err = correlationChart.GetItemById(chartInfoId); err != nil {
  534. errMsg = "获取相关性图表失败, Err: " + err.Error()
  535. return
  536. }
  537. // 多因子刷新-异步
  538. if correlationChart.AnalysisMode == 1 {
  539. isAsync = true
  540. go func() {
  541. // 1.刷新图表关联的指标
  542. mappings, e := data_manage.GetChartEdbMappingList(chartInfoId)
  543. if e != nil {
  544. utils.FileLog.Info(fmt.Sprintf("获取图表关联指标失败, err: %v", e))
  545. return
  546. }
  547. if len(mappings) == 0 {
  548. utils.FileLog.Info("图表无关联指标")
  549. return
  550. }
  551. var edbIds []int
  552. for _, v := range mappings {
  553. edbIds = append(edbIds, v.EdbInfoId)
  554. }
  555. if e, _ = data.EdbInfoRefreshAllFromBaseV3(edbIds, false, true, false); e != nil {
  556. utils.FileLog.Info(fmt.Sprintf("批量刷新指标失败, err: %v", e))
  557. return
  558. }
  559. // 2.刷新指标系列计算数据
  560. for _, v := range mappings {
  561. _, e = data.PostRefreshFactorEdbRecalculate(v.EdbInfoId, v.EdbCode)
  562. if e != nil {
  563. utils.FileLog.Info(fmt.Sprintf("PostRefreshFactorEdbRecalculate err: %v", e))
  564. continue
  565. }
  566. }
  567. // 3.刷新图表矩阵
  568. _, e = data.PostRefreshFactorEdbChartRecalculate(chartInfoId)
  569. if e != nil {
  570. utils.FileLog.Info(fmt.Sprintf("PostRefreshFactorEdbRecalculate err: %v", e))
  571. return
  572. }
  573. // 4.清除图表缓存
  574. key := utils.HZ_CHART_LIB_DETAIL + uniqueCode
  575. _ = utils.Rc.Delete(key)
  576. }()
  577. return
  578. }
  579. // 批量刷新ETA指标
  580. err, _ = data.EdbInfoRefreshAllFromBaseV3([]int{correlationChart.EdbInfoIdFirst, correlationChart.EdbInfoIdSecond}, false, true, false)
  581. if err != nil {
  582. return
  583. }
  584. // 重新生成数据并更新
  585. edbInfoMappingA, err := data_manage.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdFirst)
  586. if err != nil {
  587. errMsg = "获取相关性图表, A指标mapping信息失败, Err:" + err.Error()
  588. return
  589. }
  590. edbInfoMappingB, err := data_manage.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdSecond)
  591. if err != nil {
  592. errMsg = "获取相关性图表, B指标mapping信息失败, Err:" + err.Error()
  593. return
  594. }
  595. periodData, correlationData, err := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationChart.LeadValue, correlationChart.LeadUnit, correlationChart.StartDate.Format(utils.FormatDate), correlationChart.EndDate.Format(utils.FormatDate), "")
  596. if err != nil {
  597. errMsg = "获取相关性图表, 图表计算值失败, Err:" + err.Error()
  598. return
  599. }
  600. periodDataByte, err := json.Marshal(periodData)
  601. if err != nil {
  602. errMsg = "相关性图表, X轴信息有误, Err:" + err.Error()
  603. return
  604. }
  605. correlationDataByte, err := json.Marshal(correlationData[0].Value)
  606. if err != nil {
  607. errMsg = "相关性图表, Y轴信息有误, Err:" + err.Error()
  608. return
  609. }
  610. correlationChart.PeriodData = string(periodDataByte)
  611. correlationChart.CorrelationData = string(correlationDataByte)
  612. correlationChart.ModifyTime = time.Now().Local()
  613. correlationUpdateCols := []string{"PeriodData", "CorrelationData", "ModifyTime"}
  614. if err = correlationChart.Update(correlationUpdateCols); err != nil {
  615. errMsg = "更新相关性图表失败, Err:" + err.Error()
  616. return
  617. }
  618. return
  619. }
  620. // GetChartAndCorrelationInfo 获取图表信息和相关信息信息
  621. func GetChartAndCorrelationInfo(chartInfoId int) (chartInfo *data_manage.ChartInfo, correlationInfo *data_manage.ChartInfoCorrelation, tips string, err error) {
  622. item, e := data_manage.GetChartInfoById(chartInfoId)
  623. if e != nil {
  624. if e.Error() == utils.ErrNoRow() {
  625. tips = "图表已被删除, 请刷新页面"
  626. err = fmt.Errorf("图表已被删除, 请刷新页面")
  627. return
  628. }
  629. err = fmt.Errorf("获取图表信息失败, Err: %s", e.Error())
  630. return
  631. }
  632. if item.Source != utils.CHART_SOURCE_CORRELATION {
  633. tips = "该图不是相关性图表"
  634. err = fmt.Errorf("该图不是相关性图表")
  635. return
  636. }
  637. chartInfo = item
  638. correlationInfo = new(data_manage.ChartInfoCorrelation)
  639. if e = correlationInfo.GetItemById(chartInfo.ChartInfoId); e != nil {
  640. err = fmt.Errorf("获取图表相关性信息失败, Err: %s", e.Error())
  641. return
  642. }
  643. return
  644. }
  645. // AddChartInfo 添加图表
  646. func AddChartInfo(req data_manage.AddChartInfoReq, source int, sysUser *system.Admin, lang string) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
  647. isSendEmail = true
  648. req.ChartName = strings.Trim(req.ChartName, " ")
  649. if req.ChartName == "" {
  650. errMsg = "请填写图表名称!"
  651. err = errors.New(errMsg)
  652. isSendEmail = false
  653. return
  654. }
  655. if req.ChartClassifyId <= 0 {
  656. errMsg = "分类参数错误!"
  657. err = errors.New(errMsg)
  658. isSendEmail = false
  659. return
  660. }
  661. // 相关性图表配置
  662. if req.CorrelationChartInfo.LeadValue == 0 && source == utils.CHART_SOURCE_CORRELATION {
  663. errMsg = "请输入领先期数"
  664. err = errors.New(errMsg)
  665. isSendEmail = false
  666. return
  667. }
  668. if req.CorrelationChartInfo.LeadUnit == "" {
  669. errMsg = "请填写领先单位"
  670. err = errors.New(errMsg)
  671. isSendEmail = false
  672. return
  673. }
  674. //if req.CorrelationChartInfo.StartDate == "" || req.CorrelationChartInfo.EndDate == "" {
  675. // errMsg = "请填写开始结束日期"
  676. // err = errors.New(errMsg)
  677. // isSendEmail = false
  678. // return
  679. //}
  680. //startDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.StartDate)
  681. //if e != nil {
  682. // errMsg = "开始日期格式有误"
  683. // err = errors.New(errMsg)
  684. // isSendEmail = false
  685. // return
  686. //}
  687. //endDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.EndDate)
  688. //if e != nil {
  689. // errMsg = "结束日期格式有误"
  690. // err = errors.New(errMsg)
  691. // isSendEmail = false
  692. // return
  693. //}
  694. if len(req.CorrelationChartInfo.EdbInfoIdList) != 2 {
  695. errMsg = "请选择AB指标"
  696. err = errors.New(errMsg)
  697. isSendEmail = false
  698. return
  699. }
  700. chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
  701. if err != nil {
  702. if err.Error() == utils.ErrNoRow() {
  703. errMsg = "分类不存在"
  704. err = errors.New(errMsg)
  705. isSendEmail = false
  706. return
  707. }
  708. errMsg = "获取分类信息失败"
  709. err = errors.New("获取分类信息失败,Err:" + err.Error())
  710. return
  711. }
  712. if chartClassify == nil {
  713. errMsg = "分类不存在"
  714. err = errors.New(errMsg)
  715. isSendEmail = false
  716. return
  717. }
  718. var edbInfoIdArr []int
  719. for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
  720. edbInfoId := v.EdbInfoId
  721. edbInfo, tmpErr := data_manage.GetEdbInfoById(edbInfoId)
  722. if tmpErr != nil {
  723. if tmpErr.Error() == utils.ErrNoRow() {
  724. errMsg = "指标不存在!"
  725. err = errors.New("指标不存在,edbInfoId:" + strconv.Itoa(edbInfoId))
  726. return
  727. } else {
  728. errMsg = "获取指标信息失败!"
  729. err = errors.New("获取图表的指标信息失败,Err:" + tmpErr.Error())
  730. return
  731. }
  732. }
  733. if edbInfo == nil {
  734. errMsg = "指标已被删除,请重新选择!"
  735. err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  736. return
  737. } else {
  738. if edbInfo.EdbInfoId <= 0 {
  739. errMsg = "指标已被删除,请重新选择!"
  740. err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  741. return
  742. }
  743. }
  744. edbInfoIdArr = append(edbInfoIdArr, edbInfoId)
  745. edbInfo.EdbNameSource = edbInfo.EdbName
  746. }
  747. sort.Ints(edbInfoIdArr)
  748. var edbInfoIdArrStr []string
  749. for _, v := range edbInfoIdArr {
  750. edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
  751. }
  752. edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
  753. var chartInfoId int
  754. // 判断图表是否存在
  755. {
  756. var condition string
  757. var pars []interface{}
  758. switch lang {
  759. case utils.EnLangVersion:
  760. condition += " AND chart_name_en = ? AND source = ? "
  761. default:
  762. condition += " AND chart_name=? AND source = ? "
  763. }
  764. pars = append(pars, req.ChartName, source)
  765. count, tmpErr := data_manage.GetChartInfoCountByCondition(condition, pars)
  766. if tmpErr != nil {
  767. errMsg = "判断图表名称是否存在失败"
  768. err = errors.New("判断图表名称是否存在失败,Err:" + tmpErr.Error())
  769. return
  770. }
  771. if count > 0 {
  772. errMsg = "图表已存在,请重新填写"
  773. err = errors.New(errMsg)
  774. isSendEmail = false
  775. return
  776. }
  777. }
  778. disableVal := data.CheckIsDisableChart(edbInfoIdArr)
  779. chartInfo = new(data_manage.ChartInfo)
  780. chartInfo.ChartName = req.ChartName
  781. chartInfo.ChartNameEn = req.ChartName
  782. chartInfo.EdbInfoIds = edbInfoIdStr
  783. chartInfo.ChartClassifyId = req.ChartClassifyId
  784. chartInfo.SysUserId = sysUser.AdminId
  785. chartInfo.SysUserRealName = sysUser.RealName
  786. chartInfo.CreateTime = time.Now()
  787. chartInfo.ModifyTime = time.Now()
  788. chartInfo.IsSetName = 0
  789. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  790. chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
  791. chartInfo.ChartType = 9 // 相关性图
  792. chartInfo.Calendar = "公历"
  793. chartInfo.DateType = 6
  794. chartInfo.StartDate = req.StartDate
  795. chartInfo.EndDate = req.EndDate
  796. chartInfo.SeasonStartDate = req.StartDate
  797. chartInfo.SeasonEndDate = req.EndDate
  798. chartInfo.LeftMin = req.LeftMin
  799. chartInfo.LeftMax = req.LeftMax
  800. chartInfo.RightMin = req.RightMin
  801. chartInfo.RightMax = req.RightMax
  802. chartInfo.Disabled = disableVal
  803. chartInfo.Source = source
  804. chartInfo.ChartThemeId = req.ChartThemeId
  805. chartInfo.SourcesFrom = req.SourcesFrom
  806. chartInfo.Instructions = req.Instructions
  807. chartInfo.MarkersLines = req.MarkersLines
  808. chartInfo.MarkersAreas = req.MarkersAreas
  809. if req.ExtraConfig != "" {
  810. chartInfo.ExtraConfig = req.ExtraConfig
  811. }
  812. // 指标信息
  813. mapList := make([]*data_manage.ChartEdbMapping, 0)
  814. for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
  815. mapItem := new(data_manage.ChartEdbMapping)
  816. mapItem.EdbInfoId = v.EdbInfoId
  817. mapItem.CreateTime = time.Now()
  818. mapItem.ModifyTime = time.Now()
  819. edbTimestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  820. mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + edbTimestamp + "_" + strconv.Itoa(v.EdbInfoId))
  821. mapItem.IsOrder = true
  822. mapItem.IsAxis = 1
  823. mapItem.EdbInfoType = 1
  824. mapItem.Source = utils.CHART_SOURCE_CORRELATION
  825. mapList = append(mapList, mapItem)
  826. }
  827. // 相关性图表扩展信息
  828. correlationChart := new(data_manage.ChartInfoCorrelation)
  829. correlationChart.LeadValue = req.CorrelationChartInfo.LeadValue
  830. correlationChart.LeadUnit = req.CorrelationChartInfo.LeadUnit
  831. correlationChart.CalculateValue = req.CorrelationChartInfo.CalculateValue
  832. correlationChart.CalculateUnit = req.CorrelationChartInfo.CalculateUnit
  833. correlationChart.BaseCalculateValue = req.CorrelationChartInfo.BaseCalculateValue
  834. correlationChart.BaseCalculateUnit = req.CorrelationChartInfo.BaseCalculateUnit
  835. // 滚动相关性会有日期等信息
  836. if source == utils.CHART_SOURCE_ROLLING_CORRELATION {
  837. correlationChart.DateType = req.CorrelationChartInfo.DateType
  838. if req.CorrelationChartInfo.StartDate != `` {
  839. startDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, req.CorrelationChartInfo.StartDate, time.Local)
  840. if tmpErr != nil {
  841. err = tmpErr
  842. return
  843. }
  844. correlationChart.StartDate = startDateTime
  845. }
  846. if req.CorrelationChartInfo.EndDate != `` {
  847. endDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, req.CorrelationChartInfo.EndDate, time.Local)
  848. if tmpErr != nil {
  849. err = tmpErr
  850. return
  851. }
  852. correlationChart.EndDate = endDateTime
  853. }
  854. }
  855. correlationChart.EdbInfoIdFirst = req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId
  856. correlationChart.EdbInfoIdSecond = req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId
  857. correlationChart.CreateTime = time.Now().Local()
  858. correlationChart.ModifyTime = time.Now().Local()
  859. //// 生成图表x轴y轴数据
  860. //edbInfoMappingA, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId)
  861. //if e != nil {
  862. // errMsg = "获取失败"
  863. // err = errors.New("获取相关性图表, A指标mapping信息失败, Err:" + e.Error())
  864. // return
  865. //}
  866. //edbInfoMappingB, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId)
  867. //if e != nil {
  868. // errMsg = "获取失败"
  869. // err = errors.New("获取相关性图表, B指标mapping信息失败, Err:" + e.Error())
  870. // return
  871. //}
  872. //periodData, correlationData, e := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, req.CorrelationChartInfo.LeadValue, req.CorrelationChartInfo.LeadUnit, req.CorrelationChartInfo.StartDate, req.CorrelationChartInfo.EndDate)
  873. //if e != nil {
  874. // errMsg = "获取失败"
  875. // err = errors.New("获取相关性图表, 图表计算值失败, Err:" + e.Error())
  876. // return
  877. //}
  878. //periodDataByte, e := json.Marshal(periodData)
  879. //if e != nil {
  880. // errMsg = "获取失败"
  881. // err = errors.New("相关性图表, X轴信息有误, Err:" + e.Error())
  882. // return
  883. //}
  884. //correlationDataByte, e := json.Marshal(correlationData[0].Value)
  885. //if e != nil {
  886. // errMsg = "获取失败"
  887. // err = errors.New("相关性图表, Y轴信息有误, Err:" + e.Error())
  888. // return
  889. //}
  890. //correlationChart.PeriodData = string(periodDataByte)
  891. //correlationChart.CorrelationData = string(correlationDataByte)
  892. // 新增图表和指标mapping
  893. chartInfoId, e := data_manage.CreateCorrelationChartAndEdb(chartInfo, mapList, correlationChart)
  894. if e != nil {
  895. errMsg = "操作失败"
  896. err = errors.New("新增相关性图表失败, Err: " + e.Error())
  897. return
  898. }
  899. // 添加指标引用记录
  900. _ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartInfo)
  901. //添加es数据
  902. go data.EsAddOrEditChartInfo(chartInfoId)
  903. return
  904. }
  905. // EditChartInfo 编辑图表
  906. func EditChartInfo(req data_manage.EditChartInfoReq, sysUser *system.Admin, lang string) (chartItem *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
  907. isSendEmail = true
  908. chartItem, err = data_manage.GetChartInfoById(req.ChartInfoId)
  909. if err != nil {
  910. if err.Error() == utils.ErrNoRow() {
  911. errMsg = "图表已被删除,请刷新页面"
  912. err = errors.New(errMsg)
  913. isSendEmail = false
  914. return
  915. }
  916. errMsg = "获取图表信息失败"
  917. err = errors.New("获取图表信息失败,Err:" + err.Error())
  918. return
  919. }
  920. if chartItem.Source != utils.CHART_SOURCE_CORRELATION && chartItem.Source != utils.CHART_SOURCE_ROLLING_CORRELATION {
  921. errMsg = "该图不是相关性图表!"
  922. err = errors.New(errMsg)
  923. isSendEmail = false
  924. return
  925. }
  926. req.ChartName = strings.Trim(req.ChartName, " ")
  927. if req.ChartClassifyId <= 0 {
  928. errMsg = "分类参数错误!"
  929. err = errors.New(errMsg)
  930. isSendEmail = false
  931. return
  932. }
  933. // 相关性图表配置
  934. if req.CorrelationChartInfo.LeadValue == 0 && chartItem.Source == utils.CHART_SOURCE_CORRELATION {
  935. errMsg = "请输入领先期数"
  936. err = errors.New(errMsg)
  937. isSendEmail = false
  938. return
  939. }
  940. if req.CorrelationChartInfo.LeadUnit == "" {
  941. errMsg = "请填写领先单位"
  942. err = errors.New(errMsg)
  943. isSendEmail = false
  944. return
  945. }
  946. //if req.CorrelationChartInfo.StartDate == "" || req.CorrelationChartInfo.EndDate == "" {
  947. // errMsg = "请填写开始结束日期"
  948. // err = errors.New(errMsg)
  949. // isSendEmail = false
  950. // return
  951. //}
  952. startDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.StartDate)
  953. if e != nil {
  954. errMsg = "开始日期格式有误"
  955. err = errors.New(errMsg)
  956. isSendEmail = false
  957. return
  958. }
  959. var endDate time.Time
  960. if req.CorrelationChartInfo.EndDate != `` {
  961. endDate, e = time.Parse(utils.FormatDate, req.CorrelationChartInfo.EndDate)
  962. if e != nil {
  963. errMsg = "结束日期格式有误"
  964. err = errors.New(errMsg)
  965. isSendEmail = false
  966. return
  967. }
  968. }
  969. if len(req.CorrelationChartInfo.EdbInfoIdList) != 2 {
  970. errMsg = "请选择AB指标"
  971. err = errors.New(errMsg)
  972. isSendEmail = false
  973. return
  974. }
  975. chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
  976. if err != nil {
  977. if err.Error() == utils.ErrNoRow() {
  978. errMsg = "分类不存在"
  979. err = errors.New(errMsg)
  980. isSendEmail = false
  981. return
  982. }
  983. errMsg = "获取分类信息失败"
  984. err = errors.New("获取分类信息失败,Err:" + err.Error())
  985. return
  986. }
  987. if chartClassify == nil {
  988. errMsg = "分类不存在"
  989. err = errors.New(errMsg)
  990. isSendEmail = false
  991. return
  992. }
  993. // 图表操作权限
  994. ok := data.CheckOpChartPermission(sysUser, chartItem.SysUserId, true)
  995. if !ok {
  996. errMsg = "没有该图表的操作权限"
  997. err = errors.New(errMsg)
  998. isSendEmail = false
  999. return
  1000. }
  1001. var edbInfoIdArr []int
  1002. for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
  1003. edbInfoId := v.EdbInfoId
  1004. edbInfo, tmpErr := data_manage.GetEdbInfoById(edbInfoId)
  1005. if tmpErr != nil {
  1006. if tmpErr.Error() == utils.ErrNoRow() {
  1007. errMsg = "图表不存在!"
  1008. err = errors.New("图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  1009. return
  1010. } else {
  1011. errMsg = "获取图表信息失败!"
  1012. err = errors.New("获取图表的指标信息失败,Err:" + tmpErr.Error())
  1013. return
  1014. }
  1015. }
  1016. if edbInfo == nil {
  1017. errMsg = "指标不存在!"
  1018. err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  1019. return
  1020. }
  1021. edbInfoIdArr = append(edbInfoIdArr, edbInfoId)
  1022. }
  1023. sort.Ints(edbInfoIdArr)
  1024. var edbInfoIdArrStr []string
  1025. for _, v := range edbInfoIdArr {
  1026. edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
  1027. }
  1028. edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
  1029. //判断图表是否存在
  1030. {
  1031. var condition string
  1032. var pars []interface{}
  1033. condition += " AND chart_info_id <> ? "
  1034. pars = append(pars, req.ChartInfoId)
  1035. switch lang {
  1036. case utils.EnLangVersion:
  1037. condition += " AND chart_name_en = ? AND source = ? "
  1038. default:
  1039. condition += " AND chart_name=? AND source = ? "
  1040. }
  1041. pars = append(pars, req.ChartName, chartItem.Source)
  1042. count, tmpErr := data_manage.GetChartInfoCountByCondition(condition, pars)
  1043. if tmpErr != nil {
  1044. errMsg = "判断图表名称是否存在失败"
  1045. err = errors.New("判断图表名称是否存在失败,Err:" + tmpErr.Error())
  1046. return
  1047. }
  1048. if count > 0 {
  1049. errMsg = "图表已存在,请重新填写"
  1050. err = errors.New(errMsg)
  1051. isSendEmail = false
  1052. return
  1053. }
  1054. }
  1055. correlationChart := new(data_manage.ChartInfoCorrelation)
  1056. if e := correlationChart.GetItemById(chartItem.ChartInfoId); e != nil {
  1057. errMsg = "操作失败"
  1058. err = errors.New("图表相关性信息不存在, Err: " + e.Error())
  1059. return
  1060. }
  1061. // 图表启用与否
  1062. disableVal := data.CheckIsDisableChart(edbInfoIdArr)
  1063. // 重新生成图表值, 并修改相关性图表扩展信息
  1064. //edbInfoMappingA, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId)
  1065. //if e != nil {
  1066. // errMsg = "获取失败"
  1067. // err = errors.New("获取相关性图表, A指标mapping信息失败, Err:" + e.Error())
  1068. // return
  1069. //}
  1070. //edbInfoMappingB, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId)
  1071. //if e != nil {
  1072. // errMsg = "获取失败"
  1073. // err = errors.New("获取相关性图表, B指标mapping信息失败, Err:" + e.Error())
  1074. // return
  1075. //}
  1076. //periodData, correlationData, e := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, req.CorrelationChartInfo.LeadValue, req.CorrelationChartInfo.LeadUnit, req.CorrelationChartInfo.StartDate, req.CorrelationChartInfo.EndDate)
  1077. //if e != nil {
  1078. // errMsg = "获取失败"
  1079. // err = errors.New("获取相关性图表, 图表计算值失败, Err:" + e.Error())
  1080. // return
  1081. //}
  1082. //periodDataByte, e := json.Marshal(periodData)
  1083. //if e != nil {
  1084. // errMsg = "获取失败"
  1085. // err = errors.New("相关性图表, X轴信息有误, Err:" + e.Error())
  1086. // return
  1087. //}
  1088. //correlationDataByte, e := json.Marshal(correlationData[0].Value)
  1089. //if e != nil {
  1090. // errMsg = "获取失败"
  1091. // err = errors.New("相关性图表, Y轴信息有误, Err:" + e.Error())
  1092. // return
  1093. //}
  1094. correlationChart.LeadValue = req.CorrelationChartInfo.LeadValue
  1095. correlationChart.LeadUnit = req.CorrelationChartInfo.LeadUnit
  1096. correlationChart.CalculateValue = req.CorrelationChartInfo.CalculateValue
  1097. correlationChart.CalculateUnit = req.CorrelationChartInfo.CalculateUnit
  1098. correlationChart.StartDate = startDate
  1099. correlationChart.EndDate = endDate
  1100. correlationChart.EdbInfoIdFirst = req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId
  1101. correlationChart.EdbInfoIdSecond = req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId
  1102. // 滚动相关性会有日期等信息
  1103. if chartItem.Source == utils.CHART_SOURCE_ROLLING_CORRELATION {
  1104. correlationChart.DateType = req.CorrelationChartInfo.DateType
  1105. }
  1106. //correlationChart.PeriodData = string(periodDataByte)
  1107. //correlationChart.CorrelationData = string(correlationDataByte)
  1108. correlationChart.ModifyTime = time.Now().Local()
  1109. //correlationUpdateCols := []string{"LeadValue", "LeadUnit", "StartDate", "EndDate", "EdbInfoIdFirst", "EdbInfoIdSecond", "PeriodData","CorrelationData", "ModifyTime"}
  1110. correlationUpdateCols := []string{"LeadValue", "LeadUnit", "CalculateValue", "CalculateUnit", "DateType", "StartDate", "EndDate", "EdbInfoIdFirst", "EdbInfoIdSecond", "ModifyTime"}
  1111. // 修改图表与指标mapping
  1112. req.ChartType = 9
  1113. err = data_manage.EditCorrelationChartInfoAndMapping(&req, edbInfoIdStr, "公历", 6, disableVal, ``,
  1114. correlationChart, correlationUpdateCols)
  1115. if err != nil {
  1116. errMsg = "保存失败"
  1117. err = errors.New("保存失败,Err:" + err.Error())
  1118. return
  1119. }
  1120. resp := new(data_manage.AddChartInfoResp)
  1121. resp.ChartInfoId = chartItem.ChartInfoId
  1122. resp.UniqueCode = chartItem.UniqueCode
  1123. resp.ChartType = req.ChartType
  1124. // 添加指标引用记录
  1125. _ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartItem)
  1126. //添加es数据
  1127. go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
  1128. //修改my eta es数据
  1129. go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
  1130. return
  1131. }
  1132. // CopyChartInfo 复制图表
  1133. func CopyChartInfo(configId, classifyId int, chartName string, correlationChartInfoReq data_manage.CorrelationChartInfoReq, oldChartInfo *data_manage.ChartInfo, sysUser *system.Admin, lang string) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
  1134. configSource := 2
  1135. isSendEmail = true
  1136. // 获取相关性图的配置
  1137. multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(configId, configSource)
  1138. if err != nil {
  1139. return
  1140. }
  1141. multipleGraphConfig, err := data_manage.GetMultipleGraphConfigById(configId)
  1142. if err != nil {
  1143. return
  1144. }
  1145. multipleGraphConfig.MultipleGraphConfigId = 0
  1146. err = data_manage.AddMultipleGraphConfig(multipleGraphConfig)
  1147. if err != nil {
  1148. return
  1149. }
  1150. // 添加图
  1151. addChartReq := data_manage.AddChartInfoReq{
  1152. ChartClassifyId: classifyId,
  1153. ChartName: chartName,
  1154. ChartType: utils.CHART_TYPE_CURVE,
  1155. Calendar: "公历",
  1156. CorrelationChartInfo: correlationChartInfoReq,
  1157. ChartThemeId: oldChartInfo.ChartThemeId,
  1158. SourcesFrom: oldChartInfo.SourcesFrom,
  1159. Instructions: oldChartInfo.Instructions,
  1160. MarkersLines: oldChartInfo.MarkersLines,
  1161. MarkersAreas: oldChartInfo.MarkersAreas,
  1162. }
  1163. chartSource := utils.CHART_SOURCE_CORRELATION // 默认是相关性图
  1164. chartInfo, err, errMsg, isSendEmail = AddChartInfo(addChartReq, chartSource, sysUser, lang)
  1165. if err != nil {
  1166. return
  1167. }
  1168. // 添加关系
  1169. multipleGraphConfigChartMapping = &data_manage.MultipleGraphConfigChartMapping{
  1170. //Id: 0,
  1171. MultipleGraphConfigId: multipleGraphConfig.MultipleGraphConfigId,
  1172. ChartInfoId: chartInfo.ChartInfoId,
  1173. Source: configSource,
  1174. ModifyTime: time.Now(),
  1175. CreateTime: time.Now(),
  1176. }
  1177. err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping)
  1178. if err != nil {
  1179. return
  1180. }
  1181. //添加es数据
  1182. go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
  1183. return
  1184. }
  1185. // CalculateCorrelation 计算相关性-获取x轴和y轴
  1186. func CalculateCorrelation(leadValue int, leadUnit, frequencyA, frequencyB string, dataListA, dataListB []*data_manage.EdbDataList) (xEdbIdValue []int, yDataList []data_manage.YData, err error) {
  1187. xData := make([]int, 0)
  1188. yData := make([]float64, 0)
  1189. if leadValue == 0 {
  1190. xData = append(xData, 0)
  1191. }
  1192. if leadValue > 0 {
  1193. leadMin := 0 - leadValue
  1194. xLen := 2*leadValue + 1
  1195. for i := 0; i < xLen; i++ {
  1196. n := leadMin + i
  1197. xData = append(xData, n)
  1198. }
  1199. }
  1200. // 计算窗口,不包含第一天
  1201. //startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  1202. //startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  1203. //// 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
  1204. //baseEdbInfo := edbInfoMappingB
  1205. //changeEdbInfo := edbInfoMappingA
  1206. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  1207. //baseEdbInfo := edbInfoMappingA
  1208. //changeEdbInfo := edbInfoMappingB
  1209. // 获取时间基准指标在时间区间内的值
  1210. //aDataList := make([]*data_manage.EdbDataList, 0)
  1211. //switch baseEdbInfo.EdbInfoCategoryType {
  1212. //case 0:
  1213. // aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
  1214. //case 1:
  1215. // _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
  1216. //default:
  1217. // err = errors.New("指标base类型异常")
  1218. // return
  1219. //}
  1220. //
  1221. //// 获取变频指标所有日期的值, 插值法完善数据
  1222. //bDataList := make([]*data_manage.EdbDataList, 0)
  1223. //switch changeEdbInfo.EdbInfoCategoryType {
  1224. //case 0:
  1225. // bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
  1226. //case 1:
  1227. // _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
  1228. //default:
  1229. // err = errors.New("指标change类型异常")
  1230. // return
  1231. //}
  1232. //changeDataMap := make(map[string]float64)
  1233. //newChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  1234. //if e != nil {
  1235. // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  1236. // return
  1237. //}
  1238. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  1239. baseDataList := make([]*data_manage.EdbDataList, 0)
  1240. baseDataMap := make(map[string]float64)
  1241. changeDataList := make([]*data_manage.EdbDataList, 0)
  1242. changeDataMap := make(map[string]float64)
  1243. // 先把低频指标升频为高频
  1244. {
  1245. frequencyIntMap := map[string]int{
  1246. "日度": 1,
  1247. "周度": 2,
  1248. "旬度": 3,
  1249. "月度": 4,
  1250. "季度": 5,
  1251. "年度": 6,
  1252. }
  1253. // 如果A指标是高频,那么就需要对B指标进行升频
  1254. if frequencyIntMap[frequencyA] < frequencyIntMap[frequencyB] {
  1255. tmpNewChangeDataList, e := HandleDataByLinearRegression(dataListB, changeDataMap)
  1256. if e != nil {
  1257. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  1258. return
  1259. }
  1260. changeDataList = tmpNewChangeDataList
  1261. baseDataList = dataListA
  1262. for _, v := range baseDataList {
  1263. baseDataMap[v.DataTime] = v.Value
  1264. }
  1265. } else if frequencyIntMap[frequencyA] > frequencyIntMap[frequencyB] {
  1266. // 如果B指标是高频,那么就需要对A指标进行升频
  1267. tmpNewChangeDataList, e := HandleDataByLinearRegression(dataListA, baseDataMap)
  1268. if e != nil {
  1269. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  1270. return
  1271. }
  1272. baseDataList = tmpNewChangeDataList
  1273. changeDataList = dataListB
  1274. for _, v := range changeDataList {
  1275. changeDataMap[v.DataTime] = v.Value
  1276. }
  1277. } else {
  1278. baseDataList = dataListA
  1279. for _, v := range baseDataList {
  1280. baseDataMap[v.DataTime] = v.Value
  1281. }
  1282. changeDataList = dataListB
  1283. for _, v := range changeDataList {
  1284. changeDataMap[v.DataTime] = v.Value
  1285. }
  1286. }
  1287. }
  1288. // 计算不领先也不滞后时的相关系数
  1289. baseCalculateData := make([]float64, 0)
  1290. baseDataTimeArr := make([]string, 0)
  1291. for i := range baseDataList {
  1292. baseDataTimeArr = append(baseDataTimeArr, baseDataList[i].DataTime)
  1293. baseCalculateData = append(baseCalculateData, baseDataList[i].Value)
  1294. }
  1295. //zeroBaseData := make([]float64, 0)
  1296. //zeroCalculateData := make([]float64, 0)
  1297. //for i := range baseDataTimeArr {
  1298. // tmpBaseVal, ok1 := baseDataMap[baseDataTimeArr[i]]
  1299. // tmpCalculateVal, ok2 := changeDataMap[baseDataTimeArr[i]]
  1300. // if ok1 && ok2 {
  1301. // zeroBaseData = append(zeroBaseData, tmpBaseVal)
  1302. // zeroCalculateData = append(zeroCalculateData, tmpCalculateVal)
  1303. // }
  1304. //}
  1305. //if len(zeroBaseData) != len(zeroCalculateData) {
  1306. // err = fmt.Errorf("相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(zeroCalculateData))
  1307. // return
  1308. //}
  1309. //zeroRatio := utils.CalculateCorrelationByIntArr(zeroBaseData, zeroCalculateData)
  1310. //if leadValue == 0 {
  1311. // yData = append(yData, zeroRatio)
  1312. //}
  1313. // 计算领先/滞后N期
  1314. if leadValue > 0 {
  1315. // 平移变频指标领先/滞后的日期(单位天)
  1316. moveUnitDays := utils.FrequencyDaysMap[leadUnit]
  1317. for i := range xData {
  1318. //if xData[i] == 0 {
  1319. // yData = append(yData, zeroRatio)
  1320. // continue
  1321. //}
  1322. xCalculateData := make([]float64, 0)
  1323. yCalculateData := make([]float64, 0)
  1324. // 平移指定天数
  1325. mDays := int(moveUnitDays) * xData[i]
  1326. _, dMap := MoveDataDaysToNewDataList(changeDataList, mDays)
  1327. // 取出对应的基准日期的值
  1328. for i2 := range baseDataTimeArr {
  1329. tmpDate := baseDataTimeArr[i2]
  1330. if yVal, ok := dMap[tmpDate]; ok {
  1331. xCalculateData = append(xCalculateData, baseCalculateData[i2])
  1332. yCalculateData = append(yCalculateData, yVal)
  1333. }
  1334. }
  1335. if len(yCalculateData) <= 0 {
  1336. //err = fmt.Errorf("领先滞后相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(yCalculateData))
  1337. //return
  1338. // 领先滞后后,没有可以计算的数据了
  1339. continue
  1340. }
  1341. // 公式计算出领先/滞后频度对应点的相关性系数
  1342. ratio := utils.CalculateCorrelationByIntArr(xCalculateData, yCalculateData)
  1343. yData = append(yData, ratio)
  1344. }
  1345. }
  1346. xEdbIdValue = xData
  1347. yDataList = make([]data_manage.YData, 0)
  1348. yDate := "0000-00-00"
  1349. yDataList = append(yDataList, data_manage.YData{
  1350. Date: yDate,
  1351. Value: yData,
  1352. })
  1353. return
  1354. }
  1355. // GetFactorChartDataByChartId 获取多因子相关性图表数据
  1356. func GetFactorChartDataByChartId(chartInfoId int, extraConfig string) (xEdbIdValue []int, yDataList []data_manage.YData, err error) {
  1357. if chartInfoId <= 0 {
  1358. return
  1359. }
  1360. // 指标对应的图例
  1361. extra := new(data_manage.CorrelationChartInfoExtraConfig)
  1362. if extraConfig != "" {
  1363. if e := json.Unmarshal([]byte(extraConfig), extra); e != nil {
  1364. err = fmt.Errorf("解析图表额外配置失败, err: %v", e)
  1365. return
  1366. }
  1367. }
  1368. legends := make(map[string]*data_manage.CorrelationChartLegend)
  1369. if extra != nil {
  1370. for _, v := range extra.LegendConfig {
  1371. s := fmt.Sprintf("%d-%d", v.SeriesId, v.EdbInfoId)
  1372. legends[s] = v
  1373. }
  1374. }
  1375. // 获取图表引用到的系列指标
  1376. chartMappingOb := new(data_manage.FactorEdbSeriesChartMapping)
  1377. cond := fmt.Sprintf(" AND %s = ? AND %s = 1", chartMappingOb.Cols().ChartInfoId, chartMappingOb.Cols().EdbUsed)
  1378. pars := make([]interface{}, 0)
  1379. pars = append(pars, chartInfoId)
  1380. chartMappings, e := chartMappingOb.GetItemsByCondition(cond, pars, []string{}, "")
  1381. if e != nil {
  1382. err = fmt.Errorf("获取图表引用系列指标失败")
  1383. return
  1384. }
  1385. // 取出计算结果
  1386. yDataList = make([]data_manage.YData, 0)
  1387. yDate := "0000-00-00"
  1388. for k, m := range chartMappings {
  1389. var values []data_manage.FactorEdbSeriesCorrelationMatrixValues
  1390. if m.CalculateData != "" {
  1391. e = json.Unmarshal([]byte(m.CalculateData), &values)
  1392. if e != nil {
  1393. err = fmt.Errorf("系列指标计算数据有误, err: %v", e)
  1394. return
  1395. }
  1396. }
  1397. var y []float64
  1398. for _, v := range values {
  1399. if k == 0 {
  1400. xEdbIdValue = append(xEdbIdValue, v.XData)
  1401. }
  1402. y = append(y, v.YData)
  1403. }
  1404. var yData data_manage.YData
  1405. yData.Date = yDate
  1406. yData.Value = y
  1407. yData.SeriesEdb.SeriesId = m.FactorEdbSeriesId
  1408. yData.SeriesEdb.EdbInfoId = m.EdbInfoId
  1409. // 图例
  1410. s := fmt.Sprintf("%d-%d", m.FactorEdbSeriesId, m.EdbInfoId)
  1411. legend := legends[s]
  1412. if legend != nil {
  1413. yData.Name = legend.LegendName
  1414. yData.Color = legend.Color
  1415. }
  1416. yDataList = append(yDataList, yData)
  1417. }
  1418. return
  1419. }
  1420. // FormatChartEdbInfoMappings 补充指标信息
  1421. func FormatChartEdbInfoMappings(chartInfoId int, mappings []*data_manage.ChartEdbInfoMapping) (edbList []*data_manage.ChartEdbInfoMapping, err error) {
  1422. edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
  1423. if len(mappings) == 0 {
  1424. return
  1425. }
  1426. for _, v := range mappings {
  1427. if chartInfoId <= 0 {
  1428. v.IsAxis = 1
  1429. v.LeadValue = 0
  1430. v.LeadUnit = ""
  1431. v.ChartEdbMappingId = 0
  1432. v.ChartInfoId = 0
  1433. v.IsOrder = false
  1434. v.EdbInfoType = 1
  1435. v.ChartStyle = ""
  1436. v.ChartColor = ""
  1437. v.ChartWidth = 0
  1438. } else {
  1439. v.LeadUnitEn = data.GetLeadUnitEn(v.LeadUnit)
  1440. v.LeadUnitEn = data.GetLeadUnitEn(v.LeadUnit)
  1441. }
  1442. v.FrequencyEn = data.GetFrequencyEn(v.Frequency)
  1443. if v.Unit == `无` {
  1444. v.Unit = ``
  1445. }
  1446. edbList = append(edbList, v)
  1447. }
  1448. return
  1449. }