chart_info.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. package correlation
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/shopspring/decimal"
  6. "hongze/hongze_ETA_mobile_api/models/data_manage"
  7. "hongze/hongze_ETA_mobile_api/models/system"
  8. "hongze/hongze_ETA_mobile_api/services/data"
  9. "hongze/hongze_ETA_mobile_api/utils"
  10. "math"
  11. "sort"
  12. "strconv"
  13. "strings"
  14. "time"
  15. )
  16. // HandleDataByLinearRegression 线性方程插值法补全数据
  17. func HandleDataByLinearRegression(originList []*data_manage.EdbDataList, handleDataMap map[string]float64) (newList []*data_manage.EdbDataList, err error) {
  18. if len(originList) < 2 {
  19. return
  20. }
  21. var startEdbInfoData *data_manage.EdbDataList
  22. for _, v := range originList {
  23. handleDataMap[v.DataTime] = v.Value
  24. // 第一个数据就给过滤了,给后面的试用
  25. if startEdbInfoData == nil {
  26. startEdbInfoData = v
  27. newList = append(newList, &data_manage.EdbDataList{
  28. DataTime: v.DataTime,
  29. Value: v.Value,
  30. })
  31. continue
  32. }
  33. // 获取两条数据之间相差的天数
  34. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  35. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  36. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  37. betweenDay := betweenHour / 24
  38. // 如果相差一天,那么过滤
  39. if betweenDay <= 1 {
  40. startEdbInfoData = v
  41. newList = append(newList, &data_manage.EdbDataList{
  42. DataTime: v.DataTime,
  43. Value: v.Value,
  44. })
  45. continue
  46. }
  47. // 生成线性方程式
  48. var a, b float64
  49. {
  50. coordinateData := make([]utils.Coordinate, 0)
  51. tmpCoordinate1 := utils.Coordinate{
  52. X: 1,
  53. Y: startEdbInfoData.Value,
  54. }
  55. coordinateData = append(coordinateData, tmpCoordinate1)
  56. tmpCoordinate2 := utils.Coordinate{
  57. X: float64(betweenDay) + 1,
  58. Y: v.Value,
  59. }
  60. coordinateData = append(coordinateData, tmpCoordinate2)
  61. a, b = utils.GetLinearResult(coordinateData)
  62. if math.IsNaN(a) || math.IsNaN(b) {
  63. err = fmt.Errorf("线性方程公式生成失败")
  64. return
  65. }
  66. }
  67. // 生成对应的值
  68. {
  69. for i := 1; i < betweenDay; i++ {
  70. tmpDataTime := startDataTime.AddDate(0, 0, i)
  71. aDecimal := decimal.NewFromFloat(a)
  72. xDecimal := decimal.NewFromInt(int64(i) + 1)
  73. bDecimal := decimal.NewFromFloat(b)
  74. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  75. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
  76. newList = append(newList, &data_manage.EdbDataList{
  77. DataTime: tmpDataTime.Format(utils.FormatDate),
  78. Value: val,
  79. })
  80. }
  81. }
  82. // 最后将自己赋值
  83. newList = append(newList, &data_manage.EdbDataList{
  84. EdbDataId: v.EdbDataId,
  85. DataTime: v.DataTime,
  86. Value: v.Value,
  87. })
  88. startEdbInfoData = v
  89. }
  90. return
  91. }
  92. // MoveDataDaysToNewDataList 平移指标数据生成新的数据序列
  93. func MoveDataDaysToNewDataList(dataList []*data_manage.EdbDataList, moveDay int) (newDataList []data_manage.EdbDataList, dateDataMap map[string]float64) {
  94. dateMap := make(map[time.Time]float64)
  95. var minDate, maxDate time.Time
  96. dateDataMap = make(map[string]float64)
  97. for _, v := range dataList {
  98. currDate, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  99. if minDate.IsZero() || currDate.Before(minDate) {
  100. minDate = currDate
  101. }
  102. if maxDate.IsZero() || currDate.After(maxDate) {
  103. maxDate = currDate
  104. }
  105. dateMap[currDate] = v.Value
  106. }
  107. // 处理领先、滞后数据
  108. newDateMap := make(map[time.Time]float64)
  109. for currDate, value := range dateMap {
  110. newDate := currDate.AddDate(0, 0, moveDay)
  111. newDateMap[newDate] = value
  112. }
  113. minDate = minDate.AddDate(0, 0, moveDay)
  114. maxDate = maxDate.AddDate(0, 0, moveDay)
  115. // 获取日期相差日
  116. dayNum := utils.GetTimeSubDay(minDate, maxDate)
  117. for i := 0; i <= dayNum; i++ {
  118. currDate := minDate.AddDate(0, 0, i)
  119. tmpValue, ok := newDateMap[currDate]
  120. if !ok {
  121. //找不到数据,那么就用前面的数据吧
  122. if len(newDataList)-1 < 0 {
  123. tmpValue = 0
  124. } else {
  125. tmpValue = newDataList[len(newDataList)-1].Value
  126. }
  127. }
  128. tmpData := data_manage.EdbDataList{
  129. DataTime: currDate.Format(utils.FormatDate),
  130. Value: tmpValue,
  131. }
  132. dateDataMap[tmpData.DataTime] = tmpData.Value
  133. newDataList = append(newDataList, tmpData)
  134. }
  135. return
  136. }
  137. // GetChartEdbInfoFormat 相关性图表-获取指标信息
  138. func GetChartEdbInfoFormat(chartInfoId int, edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping) (edbList []*data_manage.ChartEdbInfoMapping, err error) {
  139. edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
  140. if edbInfoMappingA == nil || edbInfoMappingB == nil {
  141. err = fmt.Errorf("指标信息有误")
  142. return
  143. }
  144. edbInfoMappingA.FrequencyEn = data.GetFrequencyEn(edbInfoMappingA.Frequency)
  145. if edbInfoMappingA.Unit == `无` {
  146. edbInfoMappingA.Unit = ``
  147. }
  148. if edbInfoMappingB.Unit == `无` {
  149. edbInfoMappingB.Unit = ``
  150. }
  151. if chartInfoId <= 0 {
  152. edbInfoMappingA.IsAxis = 1
  153. edbInfoMappingA.LeadValue = 0
  154. edbInfoMappingA.LeadUnit = ""
  155. edbInfoMappingA.ChartEdbMappingId = 0
  156. edbInfoMappingA.ChartInfoId = 0
  157. edbInfoMappingA.IsOrder = false
  158. edbInfoMappingA.EdbInfoType = 1
  159. edbInfoMappingA.ChartStyle = ""
  160. edbInfoMappingA.ChartColor = ""
  161. edbInfoMappingA.ChartWidth = 0
  162. edbInfoMappingB.IsAxis = 1
  163. edbInfoMappingB.LeadValue = 0
  164. edbInfoMappingB.LeadUnit = ""
  165. edbInfoMappingB.ChartEdbMappingId = 0
  166. edbInfoMappingB.ChartInfoId = 0
  167. edbInfoMappingB.IsOrder = false
  168. edbInfoMappingB.EdbInfoType = 1
  169. edbInfoMappingB.ChartStyle = ""
  170. edbInfoMappingB.ChartColor = ""
  171. edbInfoMappingB.ChartWidth = 0
  172. } else {
  173. edbInfoMappingA.LeadUnitEn = data.GetLeadUnitEn(edbInfoMappingA.LeadUnit)
  174. edbInfoMappingB.LeadUnitEn = data.GetLeadUnitEn(edbInfoMappingB.LeadUnit)
  175. }
  176. edbList = append(edbList, edbInfoMappingA, edbInfoMappingB)
  177. return
  178. }
  179. // GetChartAndCorrelationInfo 获取图表信息和相关信息信息
  180. func GetChartAndCorrelationInfo(chartInfoId int) (chartInfo *data_manage.ChartInfo, correlationInfo *data_manage.ChartInfoCorrelation, tips string, err error) {
  181. item, e := data_manage.GetChartInfoById(chartInfoId)
  182. if e != nil {
  183. if e.Error() == utils.ErrNoRow() {
  184. tips = "图表已被删除, 请刷新页面"
  185. err = fmt.Errorf("图表已被删除, 请刷新页面")
  186. return
  187. }
  188. err = fmt.Errorf("获取图表信息失败, Err: %s", e.Error())
  189. return
  190. }
  191. if item.Source != utils.CHART_SOURCE_CORRELATION {
  192. tips = "该图不是相关性图表"
  193. err = fmt.Errorf("该图不是相关性图表")
  194. return
  195. }
  196. chartInfo = item
  197. correlationInfo = new(data_manage.ChartInfoCorrelation)
  198. if e = correlationInfo.GetItemById(chartInfo.ChartInfoId); e != nil {
  199. err = fmt.Errorf("获取图表相关性信息失败, Err: %s", e.Error())
  200. return
  201. }
  202. return
  203. }
  204. // GetChartDataByEdbInfo 相关性图表-根据指标信息获取x轴和y轴
  205. func GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping, leadValue int, leadUnit, startDate, endDate string) (xEdbIdValue []int, yDataList []data_manage.YData, err error) {
  206. xData := make([]int, 0)
  207. yData := make([]float64, 0)
  208. if leadValue == 0 {
  209. xData = append(xData, 0)
  210. }
  211. if leadValue > 0 {
  212. leadMin := 0 - leadValue
  213. xLen := 2*leadValue + 1
  214. for i := 0; i < xLen; i++ {
  215. n := leadMin + i
  216. xData = append(xData, n)
  217. }
  218. }
  219. // 计算窗口,不包含第一天
  220. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  221. startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  222. //// 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
  223. //baseEdbInfo := edbInfoMappingB
  224. //changeEdbInfo := edbInfoMappingA
  225. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  226. baseEdbInfo := edbInfoMappingA
  227. changeEdbInfo := edbInfoMappingB
  228. // 获取时间基准指标在时间区间内的值
  229. aDataList := make([]*data_manage.EdbDataList, 0)
  230. switch baseEdbInfo.EdbInfoCategoryType {
  231. case 0:
  232. aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.EdbInfoId, startDate, endDate)
  233. case 1:
  234. _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
  235. default:
  236. err = errors.New("指标base类型异常")
  237. return
  238. }
  239. // 获取变频指标所有日期的值, 插值法完善数据
  240. bDataList := make([]*data_manage.EdbDataList, 0)
  241. switch changeEdbInfo.EdbInfoCategoryType {
  242. case 0:
  243. bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.EdbInfoId, "", "")
  244. case 1:
  245. _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
  246. default:
  247. err = errors.New("指标change类型异常")
  248. return
  249. }
  250. //changeDataMap := make(map[string]float64)
  251. //newChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  252. //if e != nil {
  253. // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  254. // return
  255. //}
  256. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  257. baseDataList := make([]*data_manage.EdbDataList, 0)
  258. baseDataMap := make(map[string]float64)
  259. changeDataList := make([]*data_manage.EdbDataList, 0)
  260. changeDataMap := make(map[string]float64)
  261. // 先把低频指标升频为高频
  262. {
  263. frequencyIntMap := map[string]int{
  264. "日度": 1,
  265. "周度": 2,
  266. "旬度": 3,
  267. "月度": 4,
  268. "季度": 5,
  269. "年度": 6,
  270. }
  271. // 如果A指标是高频,那么就需要对B指标进行升频
  272. if frequencyIntMap[edbInfoMappingA.Frequency] < frequencyIntMap[edbInfoMappingB.Frequency] {
  273. tmpNewChangeDataList, e := HandleDataByLinearRegression(aDataList, baseDataMap)
  274. if e != nil {
  275. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  276. return
  277. }
  278. baseDataList = tmpNewChangeDataList
  279. } else {
  280. baseDataList = aDataList
  281. for _, v := range baseDataList {
  282. baseDataMap[v.DataTime] = v.Value
  283. }
  284. }
  285. // 如果B指标是高频,那么就需要对A指标进行升频
  286. if frequencyIntMap[edbInfoMappingA.Frequency] > frequencyIntMap[edbInfoMappingB.Frequency] {
  287. tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  288. if e != nil {
  289. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  290. return
  291. }
  292. changeDataList = tmpNewChangeDataList
  293. } else {
  294. changeDataList = bDataList
  295. for _, v := range changeDataList {
  296. changeDataMap[v.DataTime] = v.Value
  297. }
  298. }
  299. }
  300. // 计算不领先也不滞后时的相关系数
  301. baseCalculateData := make([]float64, 0)
  302. baseDataTimeArr := make([]string, 0)
  303. for i := range baseDataList {
  304. baseDataTimeArr = append(baseDataTimeArr, baseDataList[i].DataTime)
  305. baseCalculateData = append(baseCalculateData, baseDataList[i].Value)
  306. }
  307. zeroBaseData := make([]float64, 0)
  308. zeroCalculateData := make([]float64, 0)
  309. for i := range baseDataTimeArr {
  310. tmpBaseVal, ok1 := baseDataMap[baseDataTimeArr[i]]
  311. tmpCalculateVal, ok2 := changeDataMap[baseDataTimeArr[i]]
  312. if ok1 && ok2 {
  313. zeroBaseData = append(zeroBaseData, tmpBaseVal)
  314. zeroCalculateData = append(zeroCalculateData, tmpCalculateVal)
  315. }
  316. }
  317. if len(zeroBaseData) != len(zeroCalculateData) {
  318. err = fmt.Errorf("相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(zeroCalculateData))
  319. return
  320. }
  321. zeroRatio := utils.CalculateCorrelationByIntArr(zeroBaseData, zeroCalculateData)
  322. if leadValue == 0 {
  323. yData = append(yData, zeroRatio)
  324. }
  325. // 计算领先/滞后N期
  326. if leadValue > 0 {
  327. // 平移变频指标领先/滞后的日期(单位天)
  328. moveUnitDays := utils.FrequencyDaysMap[leadUnit]
  329. for i := range xData {
  330. if xData[i] == 0 {
  331. yData = append(yData, zeroRatio)
  332. continue
  333. }
  334. xCalculateData := make([]float64, 0)
  335. yCalculateData := make([]float64, 0)
  336. // 平移指定天数
  337. mDays := int(moveUnitDays) * xData[i]
  338. _, dMap := MoveDataDaysToNewDataList(changeDataList, mDays)
  339. // 取出对应的基准日期的值
  340. for i2 := range baseDataTimeArr {
  341. if yVal, ok := dMap[baseDataTimeArr[i2]]; ok {
  342. xCalculateData = append(xCalculateData, baseCalculateData[i2])
  343. yCalculateData = append(yCalculateData, yVal)
  344. }
  345. }
  346. if len(yCalculateData) <= 0 {
  347. //err = fmt.Errorf("领先滞后相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(yCalculateData))
  348. //return
  349. // 领先滞后后,没有可以计算的数据了
  350. continue
  351. }
  352. // 公式计算出领先/滞后频度对应点的相关性系数
  353. ratio := utils.CalculateCorrelationByIntArr(xCalculateData, yCalculateData)
  354. yData = append(yData, ratio)
  355. }
  356. }
  357. xEdbIdValue = xData
  358. yDataList = make([]data_manage.YData, 0)
  359. yDate := "0000-00-00"
  360. yDataList = append(yDataList, data_manage.YData{
  361. Date: yDate,
  362. Value: yData,
  363. })
  364. return
  365. }
  366. // GetRollingCorrelationChartDataByEdbInfo 滚动相关性计算
  367. func GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping, leadValue int, leadUnit string, calculateValue int, calculateUnit string, startDate, endDate string) (xDateTimeValue []string, yDataList []data_manage.YData, err error) {
  368. xDateTimeValue = make([]string, 0)
  369. yData := make([]float64, 0)
  370. // 计算窗口,不包含第一天
  371. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  372. startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  373. baseEdbInfo := edbInfoMappingA
  374. changeEdbInfo := edbInfoMappingB
  375. // 获取时间基准指标在时间区间内的值
  376. aDataList := make([]*data_manage.EdbDataList, 0)
  377. switch baseEdbInfo.EdbInfoCategoryType {
  378. case 0:
  379. aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.EdbInfoId, startDate, endDate)
  380. case 1:
  381. _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
  382. default:
  383. err = errors.New("指标base类型异常")
  384. return
  385. }
  386. // 获取变频指标所有日期的值, 插值法完善数据
  387. bDataList := make([]*data_manage.EdbDataList, 0)
  388. switch changeEdbInfo.EdbInfoCategoryType {
  389. case 0:
  390. bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.EdbInfoId, "", "")
  391. case 1:
  392. _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
  393. default:
  394. err = errors.New("指标change类型异常")
  395. return
  396. }
  397. // 数据平移变频指标领先/滞后的日期(单位天)
  398. // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
  399. //baseDataList := make([]*data_manage.EdbDataList, 0)
  400. baseDataMap := make(map[string]float64)
  401. changeDataList := make([]*data_manage.EdbDataList, 0)
  402. changeDataMap := make(map[string]float64)
  403. // A指标不管三七二十一,先变个频再说
  404. {
  405. _, e := HandleDataByLinearRegression(aDataList, baseDataMap)
  406. if e != nil {
  407. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  408. return
  409. }
  410. //baseDataList = tmpNewChangeDataList
  411. }
  412. // B指标不管三七二十一,先变个频再说
  413. {
  414. tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
  415. if e != nil {
  416. err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
  417. return
  418. }
  419. changeDataList = tmpNewChangeDataList
  420. // 平移下日期
  421. moveUnitDays := utils.FrequencyDaysMap[leadUnit]
  422. _, changeDataMap = MoveDataDaysToNewDataList(changeDataList, leadValue*moveUnitDays)
  423. }
  424. // 计算计算时,需要多少个日期内数据
  425. calculateDay := utils.FrequencyDaysMap[calculateUnit] * calculateValue
  426. // 计算 每个日期的相关性值
  427. {
  428. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  429. endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  430. for currDay := startDateTime; !currDay.After(endDateTime); currDay = currDay.AddDate(0, 0, 1) {
  431. yCalculateData := make([]float64, 0)
  432. baseCalculateData := make([]float64, 0)
  433. // 取出对应的基准日期的值
  434. for i := 0; i < calculateDay; i++ {
  435. iDay := currDay.AddDate(0, 0, i).Format(utils.FormatDate)
  436. tmpBaseValue, ok1 := baseDataMap[iDay]
  437. tmpChangeValue, ok2 := changeDataMap[iDay]
  438. if ok1 && ok2 {
  439. baseCalculateData = append(baseCalculateData, tmpBaseValue)
  440. yCalculateData = append(yCalculateData, tmpChangeValue)
  441. } else {
  442. continue
  443. }
  444. }
  445. // 公式计算出领先/滞后频度对应点的相关性系数
  446. var ratio float64
  447. if len(baseCalculateData) > 0 {
  448. ratio = utils.CalculateCorrelationByIntArr(baseCalculateData, yCalculateData)
  449. }
  450. yData = append(yData, ratio)
  451. xDateTimeValue = append(xDateTimeValue, currDay.AddDate(0, 0, calculateDay-1).Format(utils.FormatDate))
  452. }
  453. }
  454. yDataList = make([]data_manage.YData, 0)
  455. yDate := "0000-00-00"
  456. yDataList = append(yDataList, data_manage.YData{
  457. Date: yDate,
  458. Value: yData,
  459. })
  460. return
  461. }
  462. // AddChartInfo 添加图表
  463. func AddChartInfo(req data_manage.AddChartInfoReq, source int, sysUser *system.Admin) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
  464. isSendEmail = true
  465. req.ChartName = strings.Trim(req.ChartName, " ")
  466. if req.ChartName == "" {
  467. errMsg = "请填写图表名称!"
  468. err = errors.New(errMsg)
  469. isSendEmail = false
  470. return
  471. }
  472. if req.ChartClassifyId <= 0 {
  473. errMsg = "分类参数错误!"
  474. err = errors.New(errMsg)
  475. isSendEmail = false
  476. return
  477. }
  478. // 相关性图表配置
  479. if req.CorrelationChartInfo.LeadValue == 0 {
  480. errMsg = "请输入领先期数"
  481. err = errors.New(errMsg)
  482. isSendEmail = false
  483. return
  484. }
  485. if req.CorrelationChartInfo.LeadUnit == "" {
  486. errMsg = "请填写领先单位"
  487. err = errors.New(errMsg)
  488. isSendEmail = false
  489. return
  490. }
  491. //if req.CorrelationChartInfo.StartDate == "" || req.CorrelationChartInfo.EndDate == "" {
  492. // errMsg = "请填写开始结束日期"
  493. // err = errors.New(errMsg)
  494. // isSendEmail = false
  495. // return
  496. //}
  497. //startDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.StartDate)
  498. //if e != nil {
  499. // errMsg = "开始日期格式有误"
  500. // err = errors.New(errMsg)
  501. // isSendEmail = false
  502. // return
  503. //}
  504. //endDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.EndDate)
  505. //if e != nil {
  506. // errMsg = "结束日期格式有误"
  507. // err = errors.New(errMsg)
  508. // isSendEmail = false
  509. // return
  510. //}
  511. if len(req.CorrelationChartInfo.EdbInfoIdList) != 2 {
  512. errMsg = "请选择AB指标"
  513. err = errors.New(errMsg)
  514. isSendEmail = false
  515. return
  516. }
  517. chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
  518. if err != nil {
  519. if err.Error() == utils.ErrNoRow() {
  520. errMsg = "分类不存在"
  521. err = errors.New(errMsg)
  522. isSendEmail = false
  523. return
  524. }
  525. errMsg = "获取分类信息失败"
  526. err = errors.New("获取分类信息失败,Err:" + err.Error())
  527. return
  528. }
  529. if chartClassify == nil {
  530. errMsg = "分类不存在"
  531. err = errors.New(errMsg)
  532. isSendEmail = false
  533. return
  534. }
  535. var edbInfoIdArr []int
  536. for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
  537. edbInfoId := v.EdbInfoId
  538. edbInfo, tmpErr := data_manage.GetEdbInfoById(edbInfoId)
  539. if tmpErr != nil {
  540. if tmpErr.Error() == utils.ErrNoRow() {
  541. errMsg = "指标不存在!"
  542. err = errors.New("指标不存在,edbInfoId:" + strconv.Itoa(edbInfoId))
  543. return
  544. } else {
  545. errMsg = "获取指标信息失败!"
  546. err = errors.New("获取图表的指标信息失败,Err:" + tmpErr.Error())
  547. return
  548. }
  549. }
  550. if edbInfo == nil {
  551. errMsg = "指标已被删除,请重新选择!"
  552. err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  553. return
  554. } else {
  555. if edbInfo.EdbInfoId <= 0 {
  556. errMsg = "指标已被删除,请重新选择!"
  557. err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
  558. return
  559. }
  560. }
  561. edbInfoIdArr = append(edbInfoIdArr, edbInfoId)
  562. edbInfo.EdbNameSource = edbInfo.EdbName
  563. }
  564. sort.Ints(edbInfoIdArr)
  565. var edbInfoIdArrStr []string
  566. for _, v := range edbInfoIdArr {
  567. edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
  568. }
  569. edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
  570. var chartInfoId int
  571. // 判断图表是否存在
  572. var condition string
  573. var pars []interface{}
  574. condition += " AND chart_name=? AND source = ? "
  575. pars = append(pars, req.ChartName, source)
  576. count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
  577. if err != nil {
  578. errMsg = "判断图表名称是否存在失败"
  579. err = errors.New("判断图表名称是否存在失败,Err:" + err.Error())
  580. return
  581. }
  582. if count > 0 {
  583. errMsg = "图表已存在,请重新填写"
  584. err = errors.New(errMsg)
  585. isSendEmail = false
  586. return
  587. }
  588. disableVal := data.CheckIsDisableChart(edbInfoIdArr)
  589. chartInfo = new(data_manage.ChartInfo)
  590. chartInfo.ChartName = req.ChartName
  591. chartInfo.EdbInfoIds = edbInfoIdStr
  592. chartInfo.ChartClassifyId = req.ChartClassifyId
  593. chartInfo.SysUserId = sysUser.AdminId
  594. chartInfo.SysUserRealName = sysUser.RealName
  595. chartInfo.CreateTime = time.Now()
  596. chartInfo.ModifyTime = time.Now()
  597. chartInfo.IsSetName = 0
  598. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  599. chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
  600. chartInfo.ChartType = 9 // 相关性图
  601. chartInfo.Calendar = "公历"
  602. chartInfo.DateType = 6
  603. chartInfo.StartDate = req.StartDate
  604. chartInfo.EndDate = req.EndDate
  605. chartInfo.SeasonStartDate = req.SeasonStartDate
  606. chartInfo.SeasonEndDate = req.SeasonEndDate
  607. chartInfo.LeftMin = req.LeftMin
  608. chartInfo.LeftMax = req.LeftMax
  609. chartInfo.RightMin = req.RightMin
  610. chartInfo.RightMax = req.RightMax
  611. chartInfo.Disabled = disableVal
  612. chartInfo.Source = source
  613. // 指标信息
  614. mapList := make([]*data_manage.ChartEdbMapping, 0)
  615. for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
  616. mapItem := new(data_manage.ChartEdbMapping)
  617. mapItem.EdbInfoId = v.EdbInfoId
  618. mapItem.CreateTime = time.Now()
  619. mapItem.ModifyTime = time.Now()
  620. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  621. mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp + "_" + strconv.Itoa(v.EdbInfoId))
  622. mapItem.IsOrder = true
  623. mapItem.IsAxis = 1
  624. mapItem.EdbInfoType = 1
  625. mapItem.Source = utils.CHART_SOURCE_CORRELATION
  626. mapList = append(mapList, mapItem)
  627. }
  628. // 相关性图表扩展信息
  629. correlationChart := new(data_manage.ChartInfoCorrelation)
  630. correlationChart.LeadValue = req.CorrelationChartInfo.LeadValue
  631. correlationChart.LeadUnit = req.CorrelationChartInfo.LeadUnit
  632. correlationChart.CalculateValue = req.CorrelationChartInfo.CalculateValue
  633. correlationChart.CalculateUnit = req.CorrelationChartInfo.CalculateUnit
  634. correlationChart.BaseCalculateValue = req.CorrelationChartInfo.BaseCalculateValue
  635. correlationChart.BaseCalculateUnit = req.CorrelationChartInfo.BaseCalculateUnit
  636. correlationChart.EdbInfoIdFirst = req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId
  637. correlationChart.EdbInfoIdSecond = req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId
  638. correlationChart.CreateTime = time.Now().Local()
  639. correlationChart.ModifyTime = time.Now().Local()
  640. //// 生成图表x轴y轴数据
  641. //edbInfoMappingA, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId)
  642. //if e != nil {
  643. // errMsg = "获取失败"
  644. // err = errors.New("获取相关性图表, A指标mapping信息失败, Err:" + e.Error())
  645. // return
  646. //}
  647. //edbInfoMappingB, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId)
  648. //if e != nil {
  649. // errMsg = "获取失败"
  650. // err = errors.New("获取相关性图表, B指标mapping信息失败, Err:" + e.Error())
  651. // return
  652. //}
  653. //periodData, correlationData, e := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, req.CorrelationChartInfo.LeadValue, req.CorrelationChartInfo.LeadUnit, req.CorrelationChartInfo.StartDate, req.CorrelationChartInfo.EndDate)
  654. //if e != nil {
  655. // errMsg = "获取失败"
  656. // err = errors.New("获取相关性图表, 图表计算值失败, Err:" + e.Error())
  657. // return
  658. //}
  659. //periodDataByte, e := json.Marshal(periodData)
  660. //if e != nil {
  661. // errMsg = "获取失败"
  662. // err = errors.New("相关性图表, X轴信息有误, Err:" + e.Error())
  663. // return
  664. //}
  665. //correlationDataByte, e := json.Marshal(correlationData[0].Value)
  666. //if e != nil {
  667. // errMsg = "获取失败"
  668. // err = errors.New("相关性图表, Y轴信息有误, Err:" + e.Error())
  669. // return
  670. //}
  671. //correlationChart.PeriodData = string(periodDataByte)
  672. //correlationChart.CorrelationData = string(correlationDataByte)
  673. // 新增图表和指标mapping
  674. chartInfoId, e := data_manage.CreateCorrelationChartAndEdb(chartInfo, mapList, correlationChart)
  675. if e != nil {
  676. errMsg = "操作失败"
  677. err = errors.New("新增相关性图表失败, Err: " + e.Error())
  678. return
  679. }
  680. //添加es数据
  681. go data.EsAddOrEditChartInfo(chartInfoId)
  682. return
  683. }
  684. // CopyChartInfo 复制图表
  685. func CopyChartInfo(configId, classifyId int, chartName string, correlationChartInfoReq data_manage.CorrelationChartInfoReq, sysUser *system.Admin) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
  686. configSource := 2
  687. isSendEmail = true
  688. // 获取相关性图的配置
  689. multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(configId, configSource)
  690. if err != nil {
  691. return
  692. }
  693. multipleGraphConfig, err := data_manage.GetMultipleGraphConfigById(configId)
  694. if err != nil {
  695. return
  696. }
  697. multipleGraphConfig.MultipleGraphConfigId = 0
  698. err = data_manage.AddMultipleGraphConfig(multipleGraphConfig)
  699. if err != nil {
  700. return
  701. }
  702. // 添加图
  703. addChartReq := data_manage.AddChartInfoReq{
  704. ChartClassifyId: classifyId,
  705. ChartName: chartName,
  706. ChartType: utils.CHART_TYPE_CURVE,
  707. Calendar: "公历",
  708. CorrelationChartInfo: correlationChartInfoReq,
  709. }
  710. chartSource := utils.CHART_SOURCE_CORRELATION // 默认是相关性图
  711. chartInfo, err, errMsg, isSendEmail = AddChartInfo(addChartReq, chartSource, sysUser)
  712. if err != nil {
  713. return
  714. }
  715. // 添加关系
  716. multipleGraphConfigChartMapping = &data_manage.MultipleGraphConfigChartMapping{
  717. //Id: 0,
  718. MultipleGraphConfigId: multipleGraphConfig.MultipleGraphConfigId,
  719. ChartInfoId: chartInfo.ChartInfoId,
  720. Source: configSource,
  721. ModifyTime: time.Now(),
  722. CreateTime: time.Now(),
  723. }
  724. err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping)
  725. if err != nil {
  726. return
  727. }
  728. //添加es数据
  729. go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
  730. return
  731. }