chart_info.go 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506
  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 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. xEdbIdValue = xData
  342. yDataList = make([]data_manage.YData, 0)
  343. yDate := "0000-00-00"
  344. yDataList = append(yDataList, data_manage.YData{
  345. Date: yDate,
  346. Value: yData,
  347. })
  348. return
  349. }
  350. // RollingCorrelationChartDataResp 滚动相关性图表数据
  351. type RollingCorrelationChartDataResp struct {
  352. MaxData float64
  353. MinData float64
  354. LatestDate string `description:"真实数据的最后日期"`
  355. EdbInfoCategoryType int
  356. ChartColor string
  357. ChartStyle string
  358. PredictChartColor string
  359. ChartType int
  360. ChartWidth int
  361. EdbName string
  362. EdbNameEn string
  363. Unit string
  364. UnitEn string
  365. IsAxis int
  366. DataList []data_manage.EdbDataList
  367. }
  368. // GetRollingCorrelationChartDataByEdbInfo 滚动相关性计算
  369. func GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping, leadValue int, leadUnit string, calculateValue int, calculateUnit string, startDate, endDate, chartName, chartNameEn string) (dataResp RollingCorrelationChartDataResp, err error) {
  370. dataResp = RollingCorrelationChartDataResp{
  371. DataList: make([]data_manage.EdbDataList, 0),
  372. MaxData: 0,
  373. MinData: 0,
  374. ChartColor: "#00f",
  375. ChartStyle: `spline`,
  376. PredictChartColor: `#00f`,
  377. ChartType: 0,
  378. ChartWidth: 3,
  379. EdbName: chartName,
  380. EdbNameEn: chartNameEn,
  381. IsAxis: 1,
  382. }
  383. dataList := make([]data_manage.EdbDataList, 0)
  384. // 计算窗口,不包含第一天
  385. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  386. startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  387. baseEdbInfo := edbInfoMappingA
  388. changeEdbInfo := edbInfoMappingB
  389. // 获取时间基准指标在时间区间内的值
  390. aDataList := make([]*data_manage.EdbDataList, 0)
  391. switch baseEdbInfo.EdbInfoCategoryType {
  392. case 0:
  393. aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
  394. case 1:
  395. _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, true)
  396. default:
  397. err = errors.New("指标base类型异常")
  398. return
  399. }
  400. // 获取变频指标所有日期的值, 插值法完善数据
  401. bDataList := make([]*data_manage.EdbDataList, 0)
  402. switch changeEdbInfo.EdbInfoCategoryType {
  403. case 0:
  404. bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
  405. case 1:
  406. _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
  407. default:
  408. err = errors.New("指标change类型异常")
  409. return
  410. }
  411. // 数据平移变频指标领先/滞后的日期(单位天)
  412. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  413. //baseDataList := make([]*data_manage.EdbDataList, 0)
  414. baseDataMap := make(map[string]float64)
  415. changeDataList := make([]*data_manage.EdbDataList, 0)
  416. changeDataMap := make(map[string]float64)
  417. // A指标不管三七二十一,先变个频再说
  418. {
  419. _, e := HandleDataByLinearRegression(aDataList, baseDataMap)
  420. if e != nil {
  421. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  422. return
  423. }
  424. //baseDataList = tmpNewChangeDataList
  425. }
  426. // B指标不管三七二十一,先变个频再说
  427. {
  428. tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  429. if e != nil {
  430. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  431. return
  432. }
  433. changeDataList = tmpNewChangeDataList
  434. // 平移下日期
  435. moveUnitDays := utils.FrequencyDaysMap[leadUnit]
  436. _, changeDataMap = MoveDataDaysToNewDataList(changeDataList, leadValue*moveUnitDays)
  437. }
  438. // 计算计算时,需要多少个日期内数据
  439. calculateDay := utils.FrequencyDaysMap[calculateUnit] * calculateValue
  440. // 计算 每个日期的相关性值
  441. {
  442. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  443. if endDate == `` {
  444. endDate = baseEdbInfo.EndDate
  445. }
  446. endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  447. endDateTime = endDateTime.AddDate(0, 0, -(calculateDay - 1))
  448. // 是否开始第一条数据
  449. var isStart, isNotFirst bool
  450. for currDay := startDateTime; !currDay.After(endDateTime); currDay = currDay.AddDate(0, 0, 1) {
  451. yCalculateData := make([]float64, 0)
  452. baseCalculateData := make([]float64, 0)
  453. // 取出对应的基准日期的值
  454. for i := 0; i < calculateDay; i++ {
  455. iDay := currDay.AddDate(0, 0, i).Format(utils.FormatDate)
  456. tmpBaseValue, ok1 := baseDataMap[iDay]
  457. tmpChangeValue, ok2 := changeDataMap[iDay]
  458. if ok1 && ok2 {
  459. baseCalculateData = append(baseCalculateData, tmpBaseValue)
  460. yCalculateData = append(yCalculateData, tmpChangeValue)
  461. } else {
  462. continue
  463. }
  464. }
  465. // 公式计算出领先/滞后频度对应点的相关性系数
  466. var ratio float64
  467. if len(baseCalculateData) > 0 {
  468. ratio = utils.CalculateCorrelationByIntArr(baseCalculateData, yCalculateData)
  469. } else {
  470. // 没有数据的话,那就不返回
  471. continue
  472. }
  473. // 过滤前面都是0的数据
  474. {
  475. if ratio != 0 {
  476. isStart = true
  477. }
  478. if !isStart {
  479. continue
  480. }
  481. }
  482. dataTime := currDay.AddDate(0, 0, calculateDay-1)
  483. dataList = append(dataList, data_manage.EdbDataList{
  484. //EdbDataId: 0,
  485. EdbInfoId: 0,
  486. DataTime: dataTime.Format(utils.FormatDate),
  487. DataTimestamp: dataTime.UnixNano() / 1e6,
  488. Value: ratio,
  489. })
  490. if !isNotFirst {
  491. dataResp.MinData = ratio
  492. dataResp.MaxData = ratio
  493. isNotFirst = true
  494. }
  495. if dataResp.MinData > ratio {
  496. dataResp.MinData = ratio
  497. }
  498. if dataResp.MaxData < ratio {
  499. dataResp.MaxData = ratio
  500. }
  501. }
  502. dataResp.DataList = dataList
  503. }
  504. return
  505. }
  506. // ChartInfoRefresh 图表刷新
  507. func ChartInfoRefresh(chartInfoId int) (err error) {
  508. var errMsg string
  509. defer func() {
  510. if err != nil {
  511. go alarm_msg.SendAlarmMsg("CorrelationChartInfoRefresh: "+errMsg, 3)
  512. }
  513. }()
  514. correlationChart := new(data_manage.ChartInfoCorrelation)
  515. if err = correlationChart.GetItemById(chartInfoId); err != nil {
  516. errMsg = "获取相关性图表失败, Err: " + err.Error()
  517. return
  518. }
  519. // 批量刷新ETA指标
  520. err, _ = data.EdbInfoRefreshAllFromBaseV3([]int{correlationChart.EdbInfoIdFirst, correlationChart.EdbInfoIdSecond}, false, true, false)
  521. if err != nil {
  522. return
  523. }
  524. // 重新生成数据并更新
  525. edbInfoMappingA, err := data_manage.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdFirst)
  526. if err != nil {
  527. errMsg = "获取相关性图表, A指标mapping信息失败, Err:" + err.Error()
  528. return
  529. }
  530. edbInfoMappingB, err := data_manage.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdSecond)
  531. if err != nil {
  532. errMsg = "获取相关性图表, B指标mapping信息失败, Err:" + err.Error()
  533. return
  534. }
  535. periodData, correlationData, err := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationChart.LeadValue, correlationChart.LeadUnit, correlationChart.StartDate.Format(utils.FormatDate), correlationChart.EndDate.Format(utils.FormatDate))
  536. if err != nil {
  537. errMsg = "获取相关性图表, 图表计算值失败, Err:" + err.Error()
  538. return
  539. }
  540. periodDataByte, err := json.Marshal(periodData)
  541. if err != nil {
  542. errMsg = "相关性图表, X轴信息有误, Err:" + err.Error()
  543. return
  544. }
  545. correlationDataByte, err := json.Marshal(correlationData[0].Value)
  546. if err != nil {
  547. errMsg = "相关性图表, Y轴信息有误, Err:" + err.Error()
  548. return
  549. }
  550. correlationChart.PeriodData = string(periodDataByte)
  551. correlationChart.CorrelationData = string(correlationDataByte)
  552. correlationChart.ModifyTime = time.Now().Local()
  553. correlationUpdateCols := []string{"PeriodData", "CorrelationData", "ModifyTime"}
  554. if err = correlationChart.Update(correlationUpdateCols); err != nil {
  555. errMsg = "更新相关性图表失败, Err:" + err.Error()
  556. return
  557. }
  558. return
  559. }
  560. // GetChartAndCorrelationInfo 获取图表信息和相关信息信息
  561. func GetChartAndCorrelationInfo(chartInfoId int) (chartInfo *data_manage.ChartInfo, correlationInfo *data_manage.ChartInfoCorrelation, tips string, err error) {
  562. item, e := data_manage.GetChartInfoById(chartInfoId)
  563. if e != nil {
  564. if e.Error() == utils.ErrNoRow() {
  565. tips = "图表已被删除, 请刷新页面"
  566. err = fmt.Errorf("图表已被删除, 请刷新页面")
  567. return
  568. }
  569. err = fmt.Errorf("获取图表信息失败, Err: %s", e.Error())
  570. return
  571. }
  572. if item.Source != utils.CHART_SOURCE_CORRELATION {
  573. tips = "该图不是相关性图表"
  574. err = fmt.Errorf("该图不是相关性图表")
  575. return
  576. }
  577. chartInfo = item
  578. correlationInfo = new(data_manage.ChartInfoCorrelation)
  579. if e = correlationInfo.GetItemById(chartInfo.ChartInfoId); e != nil {
  580. err = fmt.Errorf("获取图表相关性信息失败, Err: %s", e.Error())
  581. return
  582. }
  583. return
  584. }
  585. // AddChartInfo 添加图表
  586. func AddChartInfo(req data_manage.AddChartInfoReq, source int, sysUser *system.Admin, lang string) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
  587. isSendEmail = true
  588. req.ChartName = strings.Trim(req.ChartName, " ")
  589. if req.ChartName == "" {
  590. errMsg = "请填写图表名称!"
  591. err = errors.New(errMsg)
  592. isSendEmail = false
  593. return
  594. }
  595. if req.ChartClassifyId <= 0 {
  596. errMsg = "分类参数错误!"
  597. err = errors.New(errMsg)
  598. isSendEmail = false
  599. return
  600. }
  601. // 相关性图表配置
  602. if req.CorrelationChartInfo.LeadValue == 0 && source == utils.CHART_SOURCE_CORRELATION {
  603. errMsg = "请输入领先期数"
  604. err = errors.New(errMsg)
  605. isSendEmail = false
  606. return
  607. }
  608. if req.CorrelationChartInfo.LeadUnit == "" {
  609. errMsg = "请填写领先单位"
  610. err = errors.New(errMsg)
  611. isSendEmail = false
  612. return
  613. }
  614. //if req.CorrelationChartInfo.StartDate == "" || req.CorrelationChartInfo.EndDate == "" {
  615. // errMsg = "请填写开始结束日期"
  616. // err = errors.New(errMsg)
  617. // isSendEmail = false
  618. // return
  619. //}
  620. //startDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.StartDate)
  621. //if e != nil {
  622. // errMsg = "开始日期格式有误"
  623. // err = errors.New(errMsg)
  624. // isSendEmail = false
  625. // return
  626. //}
  627. //endDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.EndDate)
  628. //if e != nil {
  629. // errMsg = "结束日期格式有误"
  630. // err = errors.New(errMsg)
  631. // isSendEmail = false
  632. // return
  633. //}
  634. if len(req.CorrelationChartInfo.EdbInfoIdList) != 2 {
  635. errMsg = "请选择AB指标"
  636. err = errors.New(errMsg)
  637. isSendEmail = false
  638. return
  639. }
  640. chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
  641. if err != nil {
  642. if err.Error() == utils.ErrNoRow() {
  643. errMsg = "分类不存在"
  644. err = errors.New(errMsg)
  645. isSendEmail = false
  646. return
  647. }
  648. errMsg = "获取分类信息失败"
  649. err = errors.New("获取分类信息失败,Err:" + err.Error())
  650. return
  651. }
  652. if chartClassify == nil {
  653. errMsg = "分类不存在"
  654. err = errors.New(errMsg)
  655. isSendEmail = false
  656. return
  657. }
  658. var edbInfoIdArr []int
  659. for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
  660. edbInfoId := v.EdbInfoId
  661. edbInfo, tmpErr := data_manage.GetEdbInfoById(edbInfoId)
  662. if tmpErr != nil {
  663. if tmpErr.Error() == utils.ErrNoRow() {
  664. errMsg = "指标不存在!"
  665. err = errors.New("指标不存在,edbInfoId:" + strconv.Itoa(edbInfoId))
  666. return
  667. } else {
  668. errMsg = "获取指标信息失败!"
  669. err = errors.New("获取图表的指标信息失败,Err:" + tmpErr.Error())
  670. return
  671. }
  672. }
  673. if edbInfo == nil {
  674. errMsg = "指标已被删除,请重新选择!"
  675. err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  676. return
  677. } else {
  678. if edbInfo.EdbInfoId <= 0 {
  679. errMsg = "指标已被删除,请重新选择!"
  680. err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  681. return
  682. }
  683. }
  684. edbInfoIdArr = append(edbInfoIdArr, edbInfoId)
  685. edbInfo.EdbNameSource = edbInfo.EdbName
  686. }
  687. sort.Ints(edbInfoIdArr)
  688. var edbInfoIdArrStr []string
  689. for _, v := range edbInfoIdArr {
  690. edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
  691. }
  692. edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
  693. var chartInfoId int
  694. // 判断图表是否存在
  695. {
  696. var condition string
  697. var pars []interface{}
  698. switch lang {
  699. case utils.EnLangVersion:
  700. condition += " AND chart_name_en = ? AND source = ? "
  701. default:
  702. condition += " AND chart_name=? AND source = ? "
  703. }
  704. pars = append(pars, req.ChartName, source)
  705. count, tmpErr := data_manage.GetChartInfoCountByCondition(condition, pars)
  706. if tmpErr != nil {
  707. errMsg = "判断图表名称是否存在失败"
  708. err = errors.New("判断图表名称是否存在失败,Err:" + tmpErr.Error())
  709. return
  710. }
  711. if count > 0 {
  712. errMsg = "图表已存在,请重新填写"
  713. err = errors.New(errMsg)
  714. isSendEmail = false
  715. return
  716. }
  717. }
  718. disableVal := data.CheckIsDisableChart(edbInfoIdArr)
  719. chartInfo = new(data_manage.ChartInfo)
  720. chartInfo.ChartName = req.ChartName
  721. chartInfo.ChartNameEn = req.ChartName
  722. chartInfo.EdbInfoIds = edbInfoIdStr
  723. chartInfo.ChartClassifyId = req.ChartClassifyId
  724. chartInfo.SysUserId = sysUser.AdminId
  725. chartInfo.SysUserRealName = sysUser.RealName
  726. chartInfo.CreateTime = time.Now()
  727. chartInfo.ModifyTime = time.Now()
  728. chartInfo.IsSetName = 0
  729. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  730. chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
  731. chartInfo.ChartType = 9 // 相关性图
  732. chartInfo.Calendar = "公历"
  733. chartInfo.DateType = 6
  734. chartInfo.StartDate = req.StartDate
  735. chartInfo.EndDate = req.EndDate
  736. chartInfo.SeasonStartDate = req.StartDate
  737. chartInfo.SeasonEndDate = req.EndDate
  738. chartInfo.LeftMin = req.LeftMin
  739. chartInfo.LeftMax = req.LeftMax
  740. chartInfo.RightMin = req.RightMin
  741. chartInfo.RightMax = req.RightMax
  742. chartInfo.Disabled = disableVal
  743. chartInfo.Source = source
  744. chartInfo.ChartThemeId = req.ChartThemeId
  745. chartInfo.SourcesFrom = req.SourcesFrom
  746. chartInfo.Instructions = req.Instructions
  747. chartInfo.MarkersLines = req.MarkersLines
  748. chartInfo.MarkersAreas = req.MarkersAreas
  749. // 指标信息
  750. mapList := make([]*data_manage.ChartEdbMapping, 0)
  751. for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
  752. mapItem := new(data_manage.ChartEdbMapping)
  753. mapItem.EdbInfoId = v.EdbInfoId
  754. mapItem.CreateTime = time.Now()
  755. mapItem.ModifyTime = time.Now()
  756. edbTimestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  757. mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + edbTimestamp + "_" + strconv.Itoa(v.EdbInfoId))
  758. mapItem.IsOrder = true
  759. mapItem.IsAxis = 1
  760. mapItem.EdbInfoType = 1
  761. mapItem.Source = utils.CHART_SOURCE_CORRELATION
  762. mapList = append(mapList, mapItem)
  763. }
  764. // 相关性图表扩展信息
  765. correlationChart := new(data_manage.ChartInfoCorrelation)
  766. correlationChart.LeadValue = req.CorrelationChartInfo.LeadValue
  767. correlationChart.LeadUnit = req.CorrelationChartInfo.LeadUnit
  768. correlationChart.CalculateValue = req.CorrelationChartInfo.CalculateValue
  769. correlationChart.CalculateUnit = req.CorrelationChartInfo.CalculateUnit
  770. correlationChart.BaseCalculateValue = req.CorrelationChartInfo.BaseCalculateValue
  771. correlationChart.BaseCalculateUnit = req.CorrelationChartInfo.BaseCalculateUnit
  772. // 滚动相关性会有日期等信息
  773. if source == utils.CHART_SOURCE_ROLLING_CORRELATION {
  774. correlationChart.DateType = req.CorrelationChartInfo.DateType
  775. if req.CorrelationChartInfo.StartDate != `` {
  776. startDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, req.CorrelationChartInfo.StartDate, time.Local)
  777. if tmpErr != nil {
  778. err = tmpErr
  779. return
  780. }
  781. correlationChart.StartDate = startDateTime
  782. }
  783. if req.CorrelationChartInfo.EndDate != `` {
  784. endDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, req.CorrelationChartInfo.EndDate, time.Local)
  785. if tmpErr != nil {
  786. err = tmpErr
  787. return
  788. }
  789. correlationChart.EndDate = endDateTime
  790. }
  791. }
  792. correlationChart.EdbInfoIdFirst = req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId
  793. correlationChart.EdbInfoIdSecond = req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId
  794. correlationChart.CreateTime = time.Now().Local()
  795. correlationChart.ModifyTime = time.Now().Local()
  796. //// 生成图表x轴y轴数据
  797. //edbInfoMappingA, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId)
  798. //if e != nil {
  799. // errMsg = "获取失败"
  800. // err = errors.New("获取相关性图表, A指标mapping信息失败, Err:" + e.Error())
  801. // return
  802. //}
  803. //edbInfoMappingB, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId)
  804. //if e != nil {
  805. // errMsg = "获取失败"
  806. // err = errors.New("获取相关性图表, B指标mapping信息失败, Err:" + e.Error())
  807. // return
  808. //}
  809. //periodData, correlationData, e := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, req.CorrelationChartInfo.LeadValue, req.CorrelationChartInfo.LeadUnit, req.CorrelationChartInfo.StartDate, req.CorrelationChartInfo.EndDate)
  810. //if e != nil {
  811. // errMsg = "获取失败"
  812. // err = errors.New("获取相关性图表, 图表计算值失败, Err:" + e.Error())
  813. // return
  814. //}
  815. //periodDataByte, e := json.Marshal(periodData)
  816. //if e != nil {
  817. // errMsg = "获取失败"
  818. // err = errors.New("相关性图表, X轴信息有误, Err:" + e.Error())
  819. // return
  820. //}
  821. //correlationDataByte, e := json.Marshal(correlationData[0].Value)
  822. //if e != nil {
  823. // errMsg = "获取失败"
  824. // err = errors.New("相关性图表, Y轴信息有误, Err:" + e.Error())
  825. // return
  826. //}
  827. //correlationChart.PeriodData = string(periodDataByte)
  828. //correlationChart.CorrelationData = string(correlationDataByte)
  829. // 新增图表和指标mapping
  830. chartInfoId, e := data_manage.CreateCorrelationChartAndEdb(chartInfo, mapList, correlationChart)
  831. if e != nil {
  832. errMsg = "操作失败"
  833. err = errors.New("新增相关性图表失败, Err: " + e.Error())
  834. return
  835. }
  836. //添加es数据
  837. go data.EsAddOrEditChartInfo(chartInfoId)
  838. return
  839. }
  840. // EditChartInfo 编辑图表
  841. func EditChartInfo(req data_manage.EditChartInfoReq, sysUser *system.Admin, lang string) (chartItem *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
  842. isSendEmail = true
  843. chartItem, err = data_manage.GetChartInfoById(req.ChartInfoId)
  844. if err != nil {
  845. if err.Error() == utils.ErrNoRow() {
  846. errMsg = "图表已被删除,请刷新页面"
  847. err = errors.New(errMsg)
  848. isSendEmail = false
  849. return
  850. }
  851. errMsg = "获取图表信息失败"
  852. err = errors.New("获取图表信息失败,Err:" + err.Error())
  853. return
  854. }
  855. if chartItem.Source != utils.CHART_SOURCE_CORRELATION && chartItem.Source != utils.CHART_SOURCE_ROLLING_CORRELATION {
  856. errMsg = "该图不是相关性图表!"
  857. err = errors.New(errMsg)
  858. isSendEmail = false
  859. return
  860. }
  861. req.ChartName = strings.Trim(req.ChartName, " ")
  862. if req.ChartClassifyId <= 0 {
  863. errMsg = "分类参数错误!"
  864. err = errors.New(errMsg)
  865. isSendEmail = false
  866. return
  867. }
  868. // 相关性图表配置
  869. if req.CorrelationChartInfo.LeadValue == 0 && chartItem.Source == utils.CHART_SOURCE_CORRELATION {
  870. errMsg = "请输入领先期数"
  871. err = errors.New(errMsg)
  872. isSendEmail = false
  873. return
  874. }
  875. if req.CorrelationChartInfo.LeadUnit == "" {
  876. errMsg = "请填写领先单位"
  877. err = errors.New(errMsg)
  878. isSendEmail = false
  879. return
  880. }
  881. //if req.CorrelationChartInfo.StartDate == "" || req.CorrelationChartInfo.EndDate == "" {
  882. // errMsg = "请填写开始结束日期"
  883. // err = errors.New(errMsg)
  884. // isSendEmail = false
  885. // return
  886. //}
  887. startDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.StartDate)
  888. if e != nil {
  889. errMsg = "开始日期格式有误"
  890. err = errors.New(errMsg)
  891. isSendEmail = false
  892. return
  893. }
  894. var endDate time.Time
  895. if req.CorrelationChartInfo.EndDate != `` {
  896. endDate, e = time.Parse(utils.FormatDate, req.CorrelationChartInfo.EndDate)
  897. if e != nil {
  898. errMsg = "结束日期格式有误"
  899. err = errors.New(errMsg)
  900. isSendEmail = false
  901. return
  902. }
  903. }
  904. if len(req.CorrelationChartInfo.EdbInfoIdList) != 2 {
  905. errMsg = "请选择AB指标"
  906. err = errors.New(errMsg)
  907. isSendEmail = false
  908. return
  909. }
  910. chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
  911. if err != nil {
  912. if err.Error() == utils.ErrNoRow() {
  913. errMsg = "分类不存在"
  914. err = errors.New(errMsg)
  915. isSendEmail = false
  916. return
  917. }
  918. errMsg = "获取分类信息失败"
  919. err = errors.New("获取分类信息失败,Err:" + err.Error())
  920. return
  921. }
  922. if chartClassify == nil {
  923. errMsg = "分类不存在"
  924. err = errors.New(errMsg)
  925. isSendEmail = false
  926. return
  927. }
  928. // 图表操作权限
  929. ok := data.CheckOpChartPermission(sysUser, chartItem.SysUserId, true)
  930. if !ok {
  931. errMsg = "没有该图表的操作权限"
  932. err = errors.New(errMsg)
  933. isSendEmail = false
  934. return
  935. }
  936. var edbInfoIdArr []int
  937. for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
  938. edbInfoId := v.EdbInfoId
  939. edbInfo, tmpErr := data_manage.GetEdbInfoById(edbInfoId)
  940. if tmpErr != nil {
  941. if tmpErr.Error() == utils.ErrNoRow() {
  942. errMsg = "图表不存在!"
  943. err = errors.New("图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  944. return
  945. } else {
  946. errMsg = "获取图表信息失败!"
  947. err = errors.New("获取图表的指标信息失败,Err:" + tmpErr.Error())
  948. return
  949. }
  950. }
  951. if edbInfo == nil {
  952. errMsg = "指标不存在!"
  953. err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  954. return
  955. }
  956. edbInfoIdArr = append(edbInfoIdArr, edbInfoId)
  957. }
  958. sort.Ints(edbInfoIdArr)
  959. var edbInfoIdArrStr []string
  960. for _, v := range edbInfoIdArr {
  961. edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
  962. }
  963. edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
  964. //判断图表是否存在
  965. {
  966. var condition string
  967. var pars []interface{}
  968. condition += " AND chart_info_id <> ? "
  969. pars = append(pars, req.ChartInfoId)
  970. switch lang {
  971. case utils.EnLangVersion:
  972. condition += " AND chart_name_en = ? AND source = ? "
  973. default:
  974. condition += " AND chart_name=? AND source = ? "
  975. }
  976. pars = append(pars, req.ChartName, chartItem.Source)
  977. count, tmpErr := data_manage.GetChartInfoCountByCondition(condition, pars)
  978. if tmpErr != nil {
  979. errMsg = "判断图表名称是否存在失败"
  980. err = errors.New("判断图表名称是否存在失败,Err:" + tmpErr.Error())
  981. return
  982. }
  983. if count > 0 {
  984. errMsg = "图表已存在,请重新填写"
  985. err = errors.New(errMsg)
  986. isSendEmail = false
  987. return
  988. }
  989. }
  990. correlationChart := new(data_manage.ChartInfoCorrelation)
  991. if e := correlationChart.GetItemById(chartItem.ChartInfoId); e != nil {
  992. errMsg = "操作失败"
  993. err = errors.New("图表相关性信息不存在, Err: " + e.Error())
  994. return
  995. }
  996. // 图表启用与否
  997. disableVal := data.CheckIsDisableChart(edbInfoIdArr)
  998. // 重新生成图表值, 并修改相关性图表扩展信息
  999. //edbInfoMappingA, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId)
  1000. //if e != nil {
  1001. // errMsg = "获取失败"
  1002. // err = errors.New("获取相关性图表, A指标mapping信息失败, Err:" + e.Error())
  1003. // return
  1004. //}
  1005. //edbInfoMappingB, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId)
  1006. //if e != nil {
  1007. // errMsg = "获取失败"
  1008. // err = errors.New("获取相关性图表, B指标mapping信息失败, Err:" + e.Error())
  1009. // return
  1010. //}
  1011. //periodData, correlationData, e := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, req.CorrelationChartInfo.LeadValue, req.CorrelationChartInfo.LeadUnit, req.CorrelationChartInfo.StartDate, req.CorrelationChartInfo.EndDate)
  1012. //if e != nil {
  1013. // errMsg = "获取失败"
  1014. // err = errors.New("获取相关性图表, 图表计算值失败, Err:" + e.Error())
  1015. // return
  1016. //}
  1017. //periodDataByte, e := json.Marshal(periodData)
  1018. //if e != nil {
  1019. // errMsg = "获取失败"
  1020. // err = errors.New("相关性图表, X轴信息有误, Err:" + e.Error())
  1021. // return
  1022. //}
  1023. //correlationDataByte, e := json.Marshal(correlationData[0].Value)
  1024. //if e != nil {
  1025. // errMsg = "获取失败"
  1026. // err = errors.New("相关性图表, Y轴信息有误, Err:" + e.Error())
  1027. // return
  1028. //}
  1029. correlationChart.LeadValue = req.CorrelationChartInfo.LeadValue
  1030. correlationChart.LeadUnit = req.CorrelationChartInfo.LeadUnit
  1031. correlationChart.CalculateValue = req.CorrelationChartInfo.CalculateValue
  1032. correlationChart.CalculateUnit = req.CorrelationChartInfo.CalculateUnit
  1033. correlationChart.StartDate = startDate
  1034. correlationChart.EndDate = endDate
  1035. correlationChart.EdbInfoIdFirst = req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId
  1036. correlationChart.EdbInfoIdSecond = req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId
  1037. // 滚动相关性会有日期等信息
  1038. if chartItem.Source == utils.CHART_SOURCE_ROLLING_CORRELATION {
  1039. correlationChart.DateType = req.CorrelationChartInfo.DateType
  1040. }
  1041. //correlationChart.PeriodData = string(periodDataByte)
  1042. //correlationChart.CorrelationData = string(correlationDataByte)
  1043. correlationChart.ModifyTime = time.Now().Local()
  1044. //correlationUpdateCols := []string{"LeadValue", "LeadUnit", "StartDate", "EndDate", "EdbInfoIdFirst", "EdbInfoIdSecond", "PeriodData","CorrelationData", "ModifyTime"}
  1045. correlationUpdateCols := []string{"LeadValue", "LeadUnit", "CalculateValue", "CalculateUnit", "DateType", "StartDate", "EndDate", "EdbInfoIdFirst", "EdbInfoIdSecond", "ModifyTime"}
  1046. // 修改图表与指标mapping
  1047. req.ChartType = 9
  1048. err = data_manage.EditCorrelationChartInfoAndMapping(&req, edbInfoIdStr, "公历", 6, disableVal, ``,
  1049. correlationChart, correlationUpdateCols)
  1050. if err != nil {
  1051. errMsg = "保存失败"
  1052. err = errors.New("保存失败,Err:" + err.Error())
  1053. return
  1054. }
  1055. resp := new(data_manage.AddChartInfoResp)
  1056. resp.ChartInfoId = chartItem.ChartInfoId
  1057. resp.UniqueCode = chartItem.UniqueCode
  1058. resp.ChartType = req.ChartType
  1059. //添加es数据
  1060. go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
  1061. //修改my eta es数据
  1062. go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
  1063. return
  1064. }
  1065. // CopyChartInfo 复制图表
  1066. 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) {
  1067. configSource := 2
  1068. isSendEmail = true
  1069. // 获取相关性图的配置
  1070. multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(configId, configSource)
  1071. if err != nil {
  1072. return
  1073. }
  1074. multipleGraphConfig, err := data_manage.GetMultipleGraphConfigById(configId)
  1075. if err != nil {
  1076. return
  1077. }
  1078. multipleGraphConfig.MultipleGraphConfigId = 0
  1079. err = data_manage.AddMultipleGraphConfig(multipleGraphConfig)
  1080. if err != nil {
  1081. return
  1082. }
  1083. // 添加图
  1084. addChartReq := data_manage.AddChartInfoReq{
  1085. ChartClassifyId: classifyId,
  1086. ChartName: chartName,
  1087. ChartType: utils.CHART_TYPE_CURVE,
  1088. Calendar: "公历",
  1089. CorrelationChartInfo: correlationChartInfoReq,
  1090. ChartThemeId: oldChartInfo.ChartThemeId,
  1091. SourcesFrom: oldChartInfo.SourcesFrom,
  1092. Instructions: oldChartInfo.Instructions,
  1093. MarkersLines: oldChartInfo.MarkersLines,
  1094. MarkersAreas: oldChartInfo.MarkersAreas,
  1095. }
  1096. chartSource := utils.CHART_SOURCE_CORRELATION // 默认是相关性图
  1097. chartInfo, err, errMsg, isSendEmail = AddChartInfo(addChartReq, chartSource, sysUser, lang)
  1098. if err != nil {
  1099. return
  1100. }
  1101. // 添加关系
  1102. multipleGraphConfigChartMapping = &data_manage.MultipleGraphConfigChartMapping{
  1103. //Id: 0,
  1104. MultipleGraphConfigId: multipleGraphConfig.MultipleGraphConfigId,
  1105. ChartInfoId: chartInfo.ChartInfoId,
  1106. Source: configSource,
  1107. ModifyTime: time.Now(),
  1108. CreateTime: time.Now(),
  1109. }
  1110. err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping)
  1111. if err != nil {
  1112. return
  1113. }
  1114. //添加es数据
  1115. go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
  1116. return
  1117. }
  1118. // CalculateCorrelation 计算相关性-获取x轴和y轴
  1119. func CalculateCorrelation(leadValue int, leadUnit, frequencyA, frequencyB string, dataListA, dataListB []*data_manage.EdbDataList) (xEdbIdValue []int, yDataList []data_manage.YData, err error) {
  1120. xData := make([]int, 0)
  1121. yData := make([]float64, 0)
  1122. if leadValue == 0 {
  1123. xData = append(xData, 0)
  1124. }
  1125. if leadValue > 0 {
  1126. leadMin := 0 - leadValue
  1127. xLen := 2*leadValue + 1
  1128. for i := 0; i < xLen; i++ {
  1129. n := leadMin + i
  1130. xData = append(xData, n)
  1131. }
  1132. }
  1133. // 计算窗口,不包含第一天
  1134. //startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  1135. //startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  1136. //// 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
  1137. //baseEdbInfo := edbInfoMappingB
  1138. //changeEdbInfo := edbInfoMappingA
  1139. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  1140. //baseEdbInfo := edbInfoMappingA
  1141. //changeEdbInfo := edbInfoMappingB
  1142. // 获取时间基准指标在时间区间内的值
  1143. //aDataList := make([]*data_manage.EdbDataList, 0)
  1144. //switch baseEdbInfo.EdbInfoCategoryType {
  1145. //case 0:
  1146. // aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
  1147. //case 1:
  1148. // _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
  1149. //default:
  1150. // err = errors.New("指标base类型异常")
  1151. // return
  1152. //}
  1153. //
  1154. //// 获取变频指标所有日期的值, 插值法完善数据
  1155. //bDataList := make([]*data_manage.EdbDataList, 0)
  1156. //switch changeEdbInfo.EdbInfoCategoryType {
  1157. //case 0:
  1158. // bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
  1159. //case 1:
  1160. // _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
  1161. //default:
  1162. // err = errors.New("指标change类型异常")
  1163. // return
  1164. //}
  1165. //changeDataMap := make(map[string]float64)
  1166. //newChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  1167. //if e != nil {
  1168. // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  1169. // return
  1170. //}
  1171. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  1172. baseDataList := make([]*data_manage.EdbDataList, 0)
  1173. baseDataMap := make(map[string]float64)
  1174. changeDataList := make([]*data_manage.EdbDataList, 0)
  1175. changeDataMap := make(map[string]float64)
  1176. // 先把低频指标升频为高频
  1177. {
  1178. frequencyIntMap := map[string]int{
  1179. "日度": 1,
  1180. "周度": 2,
  1181. "旬度": 3,
  1182. "月度": 4,
  1183. "季度": 5,
  1184. "年度": 6,
  1185. }
  1186. // 如果A指标是高频,那么就需要对B指标进行升频
  1187. if frequencyIntMap[frequencyA] < frequencyIntMap[frequencyB] {
  1188. tmpNewChangeDataList, e := HandleDataByLinearRegression(dataListB, changeDataMap)
  1189. if e != nil {
  1190. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  1191. return
  1192. }
  1193. changeDataList = tmpNewChangeDataList
  1194. baseDataList = dataListA
  1195. for _, v := range baseDataList {
  1196. baseDataMap[v.DataTime] = v.Value
  1197. }
  1198. } else if frequencyIntMap[frequencyA] > frequencyIntMap[frequencyB] {
  1199. // 如果B指标是高频,那么就需要对A指标进行升频
  1200. tmpNewChangeDataList, e := HandleDataByLinearRegression(dataListA, baseDataMap)
  1201. if e != nil {
  1202. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  1203. return
  1204. }
  1205. baseDataList = tmpNewChangeDataList
  1206. changeDataList = dataListB
  1207. for _, v := range changeDataList {
  1208. changeDataMap[v.DataTime] = v.Value
  1209. }
  1210. } else {
  1211. baseDataList = dataListA
  1212. for _, v := range baseDataList {
  1213. baseDataMap[v.DataTime] = v.Value
  1214. }
  1215. changeDataList = dataListB
  1216. for _, v := range changeDataList {
  1217. changeDataMap[v.DataTime] = v.Value
  1218. }
  1219. }
  1220. }
  1221. // 计算不领先也不滞后时的相关系数
  1222. baseCalculateData := make([]float64, 0)
  1223. baseDataTimeArr := make([]string, 0)
  1224. for i := range baseDataList {
  1225. baseDataTimeArr = append(baseDataTimeArr, baseDataList[i].DataTime)
  1226. baseCalculateData = append(baseCalculateData, baseDataList[i].Value)
  1227. }
  1228. //zeroBaseData := make([]float64, 0)
  1229. //zeroCalculateData := make([]float64, 0)
  1230. //for i := range baseDataTimeArr {
  1231. // tmpBaseVal, ok1 := baseDataMap[baseDataTimeArr[i]]
  1232. // tmpCalculateVal, ok2 := changeDataMap[baseDataTimeArr[i]]
  1233. // if ok1 && ok2 {
  1234. // zeroBaseData = append(zeroBaseData, tmpBaseVal)
  1235. // zeroCalculateData = append(zeroCalculateData, tmpCalculateVal)
  1236. // }
  1237. //}
  1238. //if len(zeroBaseData) != len(zeroCalculateData) {
  1239. // err = fmt.Errorf("相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(zeroCalculateData))
  1240. // return
  1241. //}
  1242. //zeroRatio := utils.CalculateCorrelationByIntArr(zeroBaseData, zeroCalculateData)
  1243. //if leadValue == 0 {
  1244. // yData = append(yData, zeroRatio)
  1245. //}
  1246. // 计算领先/滞后N期
  1247. if leadValue > 0 {
  1248. // 平移变频指标领先/滞后的日期(单位天)
  1249. moveUnitDays := utils.FrequencyDaysMap[leadUnit]
  1250. for i := range xData {
  1251. //if xData[i] == 0 {
  1252. // yData = append(yData, zeroRatio)
  1253. // continue
  1254. //}
  1255. xCalculateData := make([]float64, 0)
  1256. yCalculateData := make([]float64, 0)
  1257. // 平移指定天数
  1258. mDays := int(moveUnitDays) * xData[i]
  1259. _, dMap := MoveDataDaysToNewDataList(changeDataList, mDays)
  1260. // 取出对应的基准日期的值
  1261. for i2 := range baseDataTimeArr {
  1262. tmpDate := baseDataTimeArr[i2]
  1263. if yVal, ok := dMap[tmpDate]; ok {
  1264. xCalculateData = append(xCalculateData, baseCalculateData[i2])
  1265. yCalculateData = append(yCalculateData, yVal)
  1266. }
  1267. }
  1268. if len(yCalculateData) <= 0 {
  1269. //err = fmt.Errorf("领先滞后相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(yCalculateData))
  1270. //return
  1271. // 领先滞后后,没有可以计算的数据了
  1272. continue
  1273. }
  1274. // 公式计算出领先/滞后频度对应点的相关性系数
  1275. ratio := utils.CalculateCorrelationByIntArr(xCalculateData, yCalculateData)
  1276. yData = append(yData, ratio)
  1277. }
  1278. }
  1279. xEdbIdValue = xData
  1280. yDataList = make([]data_manage.YData, 0)
  1281. yDate := "0000-00-00"
  1282. yDataList = append(yDataList, data_manage.YData{
  1283. Date: yDate,
  1284. Value: yData,
  1285. })
  1286. return
  1287. }
  1288. // GetFactorChartDataByChartId 获取多因子相关性图表数据
  1289. func GetFactorChartDataByChartId(chartInfoId int, extraConfig string) (xEdbIdValue []int, yDataList []data_manage.YData, err error) {
  1290. if chartInfoId <= 0 {
  1291. return
  1292. }
  1293. // 指标对应的图例
  1294. extra := new(data_manage.CorrelationChartInfoExtraConfig)
  1295. if extraConfig != "" {
  1296. if e := json.Unmarshal([]byte(extraConfig), extra); e != nil {
  1297. err = fmt.Errorf("解析图表额外配置失败, err: %v", e)
  1298. return
  1299. }
  1300. }
  1301. legends := make(map[string]*data_manage.CorrelationChartLegend)
  1302. if extra != nil {
  1303. for _, v := range extra.LegendConfig {
  1304. s := fmt.Sprintf("%d-%d", v.SeriesId, v.EdbInfoId)
  1305. legends[s] = v
  1306. }
  1307. }
  1308. // 获取图表引用到的系列指标
  1309. edbMappings, e := data_manage.GetChartUsedFactorSeriesEdb(chartInfoId)
  1310. if e != nil {
  1311. err = fmt.Errorf("获取图表引用系列指标失败, err: %v", e)
  1312. return
  1313. }
  1314. // 取出计算结果
  1315. yDataList = make([]data_manage.YData, 0)
  1316. yDate := "0000-00-00"
  1317. for k, m := range edbMappings {
  1318. var values []data_manage.FactorEdbSeriesCorrelationMatrixValues
  1319. if m.CalculateData != "" {
  1320. e = json.Unmarshal([]byte(m.CalculateData), &values)
  1321. if e != nil {
  1322. err = fmt.Errorf("系列指标计算数据有误, err: %v", e)
  1323. return
  1324. }
  1325. }
  1326. var y []float64
  1327. for _, v := range values {
  1328. if k == 0 {
  1329. xEdbIdValue = append(xEdbIdValue, v.XData)
  1330. }
  1331. y = append(y, v.YData)
  1332. }
  1333. var yData data_manage.YData
  1334. yData.Date = yDate
  1335. yData.Value = y
  1336. yData.SeriesEdb.SeriesId = m.FactorEdbSeriesId
  1337. yData.SeriesEdb.EdbInfoId = m.EdbInfoId
  1338. // 图例
  1339. s := fmt.Sprintf("%d-%d", m.FactorEdbSeriesId, m.EdbInfoId)
  1340. legend := legends[s]
  1341. if legend != nil {
  1342. yData.Name = legend.LegendName
  1343. yData.Color = legend.Color
  1344. }
  1345. yDataList = append(yDataList, yData)
  1346. }
  1347. return
  1348. }
  1349. // FormatChartEdbInfoMappings 补充指标信息
  1350. func FormatChartEdbInfoMappings(chartInfoId int, mappings []*data_manage.ChartEdbInfoMapping) (edbList []*data_manage.ChartEdbInfoMapping, err error) {
  1351. edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
  1352. if len(mappings) == 0 {
  1353. return
  1354. }
  1355. for _, v := range mappings {
  1356. if chartInfoId <= 0 {
  1357. v.IsAxis = 1
  1358. v.LeadValue = 0
  1359. v.LeadUnit = ""
  1360. v.ChartEdbMappingId = 0
  1361. v.ChartInfoId = 0
  1362. v.IsOrder = false
  1363. v.EdbInfoType = 1
  1364. v.ChartStyle = ""
  1365. v.ChartColor = ""
  1366. v.ChartWidth = 0
  1367. } else {
  1368. v.LeadUnitEn = data.GetLeadUnitEn(v.LeadUnit)
  1369. v.LeadUnitEn = data.GetLeadUnitEn(v.LeadUnit)
  1370. }
  1371. v.FrequencyEn = data.GetFrequencyEn(v.Frequency)
  1372. if v.Unit == `无` {
  1373. v.Unit = ``
  1374. }
  1375. edbList = append(edbList, v)
  1376. }
  1377. return
  1378. }