chart_info.go 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863
  1. package data
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_chart_lib/models"
  6. "eta/eta_chart_lib/models/data_manage"
  7. "eta/eta_chart_lib/services/alarm_msg"
  8. "eta/eta_chart_lib/utils"
  9. "fmt"
  10. "github.com/shopspring/decimal"
  11. "math"
  12. "sort"
  13. "strconv"
  14. "time"
  15. )
  16. // GetFrequencyEn 获取频度的英文版
  17. func GetFrequencyEn(frequency string) (frequencyEn string) {
  18. switch frequency {
  19. case "日度":
  20. frequencyEn = "day"
  21. return
  22. case "周度":
  23. frequencyEn = "week"
  24. return
  25. case "旬度":
  26. frequencyEn = "ten days"
  27. return
  28. case "月度":
  29. frequencyEn = "month"
  30. return
  31. case "季度":
  32. frequencyEn = "quarter"
  33. return
  34. case "年度":
  35. frequencyEn = "year"
  36. return
  37. }
  38. return
  39. }
  40. func GetLeadUnitEn(unit string) (unitEn string) {
  41. switch unit {
  42. case "天":
  43. unitEn = "day"
  44. return
  45. case "周":
  46. unitEn = "week"
  47. return
  48. case "月":
  49. unitEn = "month"
  50. return
  51. case "季":
  52. unitEn = "quarter"
  53. return
  54. case "年":
  55. unitEn = "year"
  56. return
  57. }
  58. return
  59. }
  60. // GetChartEdbData 获取图表的指标数据
  61. func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, extraConfigStr, seasonExtraConfig string) (edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, yDataList []models.YData, dataResp interface{}, err error, errMsg string) {
  62. edbList = make([]*models.ChartEdbInfoMapping, 0)
  63. // 指标对应的所有数据
  64. xEdbIdValue = make([]int, 0)
  65. yDataList = make([]models.YData, 0)
  66. var extraConfig interface{}
  67. switch chartType {
  68. case 7: // 柱形图
  69. var barConfig data_manage.BarChartInfoReq
  70. if extraConfigStr == `` {
  71. errMsg = "柱方图未配置"
  72. err = errors.New(errMsg)
  73. return
  74. }
  75. err = json.Unmarshal([]byte(extraConfigStr), &barConfig)
  76. if err != nil {
  77. errMsg = "柱方图配置异常"
  78. err = errors.New(errMsg)
  79. return
  80. }
  81. extraConfig = barConfig
  82. case 10: // 截面散点图
  83. var tmpExtraConfig data_manage.SectionScatterReq
  84. if extraConfigStr == `` {
  85. errMsg = "截面散点图未配置"
  86. err = errors.New(errMsg)
  87. return
  88. }
  89. err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
  90. if err != nil {
  91. errMsg = "截面散点配置异常"
  92. err = errors.New(errMsg)
  93. return
  94. }
  95. extraConfig = tmpExtraConfig
  96. case utils.CHART_TYPE_RADAR:
  97. var barConfig data_manage.RadarChartInfoReq
  98. if extraConfigStr == `` {
  99. errMsg = "雷达图未配置"
  100. err = errors.New(errMsg)
  101. return
  102. }
  103. err = json.Unmarshal([]byte(extraConfigStr), &barConfig)
  104. if err != nil {
  105. errMsg = "雷达图配置异常"
  106. err = errors.New(errMsg)
  107. return
  108. }
  109. extraConfig = barConfig
  110. default:
  111. xEdbIdValue = make([]int, 0)
  112. yDataList = make([]models.YData, 0)
  113. }
  114. // 指标对应的所有数据
  115. edbDataListMap, edbList, err := getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, seasonExtraConfig)
  116. if err != nil {
  117. return
  118. }
  119. // 特殊图形数据处理
  120. switch chartType {
  121. case 2: // 季节性图
  122. if seasonExtraConfig != "" {
  123. dataResp, err = SeasonChartData(edbList, seasonExtraConfig)
  124. }
  125. case 7: // 柱形图
  126. barChartConf := extraConfig.(data_manage.BarChartInfoReq)
  127. xEdbIdValue, yDataList, err = BarChartData(mappingList, edbDataListMap, barChartConf.DateList, barChartConf.Sort)
  128. for _, v := range edbList {
  129. // 指标别名
  130. if barChartConf.EdbInfoIdList != nil && len(barChartConf.EdbInfoIdList) > 0 {
  131. for _, reqEdb := range barChartConf.EdbInfoIdList {
  132. if v.EdbInfoId == reqEdb.EdbInfoId {
  133. v.EdbAliasName = reqEdb.Name
  134. }
  135. }
  136. }
  137. }
  138. case 10: // 截面散点图
  139. sectionScatterConf := extraConfig.(data_manage.SectionScatterReq)
  140. xEdbIdValue, dataResp, err = GetSectionScatterChartData(mappingList, edbDataListMap, sectionScatterConf)
  141. // 这个数据没有必要返回给前端
  142. for _, v := range edbList {
  143. v.DataList = nil
  144. }
  145. case utils.CHART_TYPE_RADAR: //雷达图
  146. radarConf := extraConfig.(data_manage.RadarChartInfoReq)
  147. xEdbIdValue, dataResp, err = RadarChartData(mappingList, edbDataListMap, radarConf)
  148. }
  149. return
  150. }
  151. // GetEdbDataMapList 获取指标最后的基础数据
  152. func GetEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, seasonExtraConfig string) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
  153. edbDataListMap, edbList, err = getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, seasonExtraConfig)
  154. return
  155. }
  156. // getEdbDataMapList 获取指标最后的基础数据
  157. func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, seasonExtraConfig string) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
  158. // 指标对应的所有数据
  159. edbDataListMap = make(map[int][]*models.EdbDataList)
  160. for _, v := range mappingList {
  161. //fmt.Println("v:", v.EdbInfoId)
  162. item := new(models.ChartEdbInfoMapping)
  163. item.EdbInfoId = v.EdbInfoId
  164. item.SourceName = v.SourceName
  165. item.Source = v.Source
  166. item.EdbCode = v.EdbCode
  167. item.EdbName = v.EdbName
  168. item.EdbType = v.EdbType
  169. item.EdbNameEn = v.EdbNameEn
  170. item.Frequency = v.Frequency
  171. item.FrequencyEn = GetFrequencyEn(v.Frequency)
  172. if v.Unit != `无` {
  173. item.Unit = v.Unit
  174. }
  175. item.UnitEn = v.UnitEn
  176. item.StartDate = v.StartDate
  177. item.EndDate = v.EndDate
  178. item.ModifyTime = v.ModifyTime
  179. item.EdbInfoCategoryType = v.EdbInfoCategoryType
  180. item.PredictChartColor = v.PredictChartColor
  181. item.EdbAliasName = v.EdbAliasName
  182. if chartInfoId <= 0 {
  183. item.IsAxis = 1
  184. item.LeadValue = 0
  185. item.LeadUnit = ""
  186. //item.ChartEdbMappingId = 0
  187. item.ChartInfoId = 0
  188. item.IsOrder = false
  189. item.EdbInfoType = 1
  190. item.ChartStyle = ""
  191. item.ChartColor = ""
  192. item.ChartWidth = 0
  193. item.MaxData = v.MaxValue
  194. item.MinData = v.MinValue
  195. } else {
  196. item.IsAxis = v.IsAxis
  197. item.EdbInfoType = v.EdbInfoType
  198. item.LeadValue = v.LeadValue
  199. item.LeadUnit = v.LeadUnit
  200. item.LeadUnitEn = GetLeadUnitEn(v.LeadUnit)
  201. //item.ChartEdbMappingId = v.ChartEdbMappingId
  202. item.ChartInfoId = v.ChartInfoId
  203. item.ChartStyle = v.ChartStyle
  204. item.ChartColor = v.ChartColor
  205. item.ChartWidth = v.ChartWidth
  206. item.IsOrder = v.IsOrder
  207. item.MaxData = v.MaxData
  208. item.MinData = v.MinData
  209. }
  210. item.LatestValue = v.LatestValue
  211. item.LatestDate = v.LatestDate
  212. item.UniqueCode = v.UniqueCode
  213. item.MoveLatestDate = v.LatestDate
  214. item.IsConvert = v.IsConvert
  215. item.ConvertType = v.ConvertType
  216. item.ConvertValue = v.ConvertValue
  217. item.ConvertUnit = v.ConvertUnit
  218. item.ConvertEnUnit = v.ConvertEnUnit
  219. var startDateReal string
  220. var diffSeconds int64
  221. if chartType == 2 { //季节性图
  222. startDateReal = startDate
  223. if len(mappingList) > 1 {
  224. item.IsAxis = v.IsAxis
  225. }
  226. } else {
  227. if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 { //领先指标
  228. var startTimeRealTemp time.Time
  229. startDateParse, _ := time.Parse(utils.FormatDate, startDate)
  230. switch v.LeadUnit {
  231. case "天":
  232. startTimeRealTemp = startDateParse.AddDate(0, 0, -v.LeadValue)
  233. case "月":
  234. startTimeRealTemp = startDateParse.AddDate(0, -v.LeadValue, 0)
  235. case "季":
  236. startTimeRealTemp = startDateParse.AddDate(0, -3*v.LeadValue, 0)
  237. case "周":
  238. startTimeRealTemp = startDateParse.AddDate(0, 0, -7*v.LeadValue)
  239. case "年":
  240. startTimeRealTemp = startDateParse.AddDate(-v.LeadValue, 0, 0)
  241. }
  242. if startTimeRealTemp.Before(startDateParse) {
  243. startDateReal = startTimeRealTemp.Format(utils.FormatDate)
  244. diffSeconds = (int64(startTimeRealTemp.UnixNano()) - int64(startDateParse.UnixNano())) / 1e6
  245. } else {
  246. startDateReal = startDate
  247. diffSeconds = 0
  248. }
  249. // 预测指标的开始日期也要偏移
  250. {
  251. day, tmpErr := utils.GetDaysBetween2Date(utils.FormatDate, startDate, startDateReal)
  252. if tmpErr != nil {
  253. err = tmpErr
  254. return
  255. }
  256. moveLatestDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, item.MoveLatestDate, time.Local)
  257. if tmpErr != nil {
  258. err = tmpErr
  259. return
  260. }
  261. item.MoveLatestDate = moveLatestDateTime.AddDate(0, 0, day).Format(utils.FormatDate)
  262. }
  263. } else {
  264. startDateReal = startDate
  265. }
  266. }
  267. //fmt.Println("line 1011 chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
  268. calendarPreYear := 0
  269. if calendar == "农历" {
  270. newStartDateReal, err := time.Parse(utils.FormatDate, startDateReal)
  271. if err != nil {
  272. fmt.Println("time.Parse:" + err.Error())
  273. }
  274. calendarPreYear = newStartDateReal.Year() - 1
  275. newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
  276. startDateReal = newStartDateReal.Format(utils.FormatDate)
  277. }
  278. dataList := make([]*models.EdbDataList, 0)
  279. //fmt.Println("chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
  280. switch v.EdbInfoCategoryType {
  281. case 0:
  282. dataList, err = models.GetEdbDataList(v.Source, v.SubSource, v.EdbInfoId, startDateReal, endDate)
  283. case 1:
  284. _, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(v.EdbInfoId, startDateReal, endDate, false)
  285. default:
  286. err = errors.New(fmt.Sprint("获取失败,指标类型异常", v.EdbInfoCategoryType))
  287. }
  288. if err != nil {
  289. return
  290. }
  291. if v.IsConvert == 1 {
  292. switch v.ConvertType {
  293. case 1:
  294. for i, data := range dataList {
  295. dataList[i].Value = data.Value * v.ConvertValue
  296. }
  297. //item.MaxData = item.MaxData * v.ConvertValue
  298. //item.MinData = item.MinData * v.ConvertValue
  299. case 2:
  300. for i, data := range dataList {
  301. dataList[i].Value = data.Value / v.ConvertValue
  302. }
  303. //item.MaxData = item.MaxData / v.ConvertValue
  304. //item.MinData = item.MinData / v.ConvertValue
  305. case 3:
  306. for i, data := range dataList {
  307. dataList[i].Value = math.Log(data.Value) / math.Log(v.ConvertValue)
  308. }
  309. //item.MaxData = math.Log(item.MaxData) / math.Log(v.ConvertValue)
  310. //item.MinData = math.Log(item.MinData) / math.Log(v.ConvertValue)
  311. }
  312. }
  313. edbDataListMap[v.EdbInfoId] = dataList
  314. if diffSeconds != 0 && v.EdbInfoType == 0 {
  315. dataListLen := len(dataList)
  316. for i := 0; i < dataListLen; i++ {
  317. dataList[i].DataTimestamp = dataList[i].DataTimestamp - diffSeconds
  318. }
  319. }
  320. if chartType == 2 && item.IsAxis == 1 {
  321. latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
  322. if tmpErr != nil {
  323. err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
  324. return
  325. }
  326. if calendar == "农历" {
  327. if len(dataList) <= 0 {
  328. result := new(models.EdbDataResult)
  329. item.DataList = result
  330. } else {
  331. result, tmpErr := models.AddCalculateQuarterV6(dataList)
  332. if tmpErr != nil {
  333. err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
  334. return
  335. }
  336. quarterDataList, tErr := GetSeasonEdbInfoDataListByXDateNong(result, latestDate, seasonExtraConfig, calendarPreYear)
  337. if tErr != nil {
  338. err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
  339. return
  340. }
  341. item.DataList = quarterDataList
  342. }
  343. } else {
  344. quarterDataList, tErr := GetSeasonEdbInfoDataListByXDate(dataList, latestDate, seasonExtraConfig)
  345. if tErr != nil {
  346. err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
  347. return
  348. }
  349. item.DataList = quarterDataList
  350. }
  351. } else if chartType == 2 && item.IsAxis == 0 {
  352. // 右轴数据处理,只要最新一年
  353. latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
  354. if tmpErr != nil {
  355. //item.DataList = dataList
  356. item.IsNullData = true
  357. edbList = append(edbList, item)
  358. continue
  359. err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
  360. return
  361. }
  362. newDataList := make([]*models.EdbDataList, 0)
  363. for _, v := range dataList {
  364. dataTime, e := time.Parse(utils.FormatDate, v.DataTime)
  365. if e != nil {
  366. err = errors.New("季节性图处理右轴指标数据转换日期失败,Err:" + e.Error())
  367. return
  368. }
  369. if dataTime.Year() == latestDate.Year() {
  370. newDataList = append(newDataList, v)
  371. }
  372. }
  373. item.DataList = newDataList
  374. } else if chartType == 7 || chartType == utils.CHART_TYPE_RADAR { //柱方图
  375. //item.DataList = dataList
  376. } else {
  377. item.DataList = dataList
  378. }
  379. edbList = append(edbList, item)
  380. }
  381. return
  382. }
  383. // GetSeasonEdbInfoDataListByXDate 季节性图的指标数据根据横轴展示
  384. func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate time.Time, seasonExtraConfig string) (quarterDataListSort models.QuarterDataList, err error) {
  385. xStartDate := "01-01"
  386. xEndDate := "12-31"
  387. jumpYear := 0
  388. legends := make([]models.SeasonChartLegend, 0)
  389. var seasonExtra models.SeasonExtraItem
  390. if seasonExtraConfig != "" {
  391. err = json.Unmarshal([]byte(seasonExtraConfig), &seasonExtra)
  392. if err != nil {
  393. return
  394. }
  395. }
  396. if seasonExtra.XStartDate != "" {
  397. xStartDate = seasonExtra.XStartDate
  398. xEndDate = seasonExtra.XEndDate
  399. jumpYear = seasonExtra.JumpYear
  400. legends = seasonExtra.ChartLegend
  401. }
  402. length := len(dataList)
  403. if length == 0 {
  404. return
  405. }
  406. legendMap := make(map[string]string, 0)
  407. if len(legends) > 0 {
  408. for _, v := range legends {
  409. legendMap[v.Name] = v.Value
  410. }
  411. }
  412. latestDateStr := latestDate.Format(utils.FormatDate)
  413. //判断横轴的两个时间之间是不是跨年了,如果跨年了,则横轴截止年份比起始年份+1,如果不跨年,截止年份等于起始年份
  414. //根据数据确定最早的年份,和最近年份
  415. //根据横轴的日期,汇总所有的年份
  416. startDate := dataList[0].DataTime
  417. startDateT, tmpErr := time.Parse(utils.FormatDate, startDate)
  418. if tmpErr != nil {
  419. err = tmpErr
  420. return
  421. }
  422. startYear := startDateT.Year()
  423. //获取数据的最新日期
  424. lastDate := dataList[length-1].DataTime
  425. lastDateT, tmpErr := time.Parse(utils.FormatDate, lastDate)
  426. if tmpErr != nil {
  427. err = tmpErr
  428. return
  429. }
  430. endYear := lastDateT.Year()
  431. nowYear := time.Now().Year()
  432. chartLegendMaxYear := 0
  433. dataMap := make(map[string]models.QuarterXDateItem, 0)
  434. quarterDataList := make([]*models.QuarterData, 0)
  435. quarterMap := make(map[string][]*models.EdbDataList, 0)
  436. //整理出日期
  437. idx := 1
  438. chartLegendMap := make(map[string]int, 0)
  439. for currentStartYear := startYear; currentStartYear <= endYear; currentStartYear++ {
  440. startStr := fmt.Sprintf("%d-%s", currentStartYear, xStartDate)
  441. currentEndYear := currentStartYear
  442. if jumpYear == 1 {
  443. currentEndYear = currentStartYear + 1
  444. }
  445. endStr := fmt.Sprintf("%d-%s", currentEndYear, xEndDate)
  446. name := fmt.Sprintf("%s_%s", startStr, endStr)
  447. showName := fmt.Sprintf("%d_%d", currentStartYear, currentEndYear)
  448. startT, tEr := time.Parse(utils.FormatDate, startStr)
  449. if tEr != nil {
  450. err = tEr
  451. return
  452. }
  453. endT, tEr := time.Parse(utils.FormatDate, endStr)
  454. if tEr != nil {
  455. err = tEr
  456. return
  457. }
  458. if lastDateT.Before(startT) {
  459. //如果最新的日期在起始日之前,则跳出循环
  460. break
  461. }
  462. if endT.Year() > nowYear {
  463. //如果最新的日期比真实年份要大,则数据全部按照最大的年份补齐
  464. nowYear = endT.Year()
  465. }
  466. item := models.QuarterXDateItem{
  467. StartDate: startT,
  468. EndDate: endT,
  469. ShowName: showName,
  470. }
  471. chartLegendMaxYear = endT.Year()
  472. dataMap[name] = item
  473. chartLegendMap[name] = idx
  474. idx++
  475. fmt.Println("年份" + showName + "日期" + startStr + " " + endStr)
  476. if lastDateT.Before(endT) {
  477. //如果最新的日期在起始日之前,则跳出循环
  478. break
  479. }
  480. }
  481. lenYear := len(dataMap)
  482. if chartLegendMaxYear > endYear {
  483. chartLegendMaxYear = endYear
  484. }
  485. for k, v := range dataMap {
  486. if i, ok := chartLegendMap[k]; ok {
  487. //v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
  488. v.ChartLegend = strconv.Itoa(chartLegendMaxYear - lenYear + i)
  489. }
  490. dataMap[k] = v
  491. }
  492. for _, v := range dataList {
  493. dataTimeT, _ := time.Parse(utils.FormatDate, v.DataTime)
  494. year := dataTimeT.Year()
  495. newItemDate := dataTimeT.AddDate(nowYear-year, 0, 0)
  496. for k, dateItem := range dataMap {
  497. tmpVal := models.EdbDataList{
  498. EdbDataId: v.EdbDataId,
  499. EdbInfoId: v.EdbInfoId,
  500. DataTime: v.DataTime,
  501. DataTimestamp: v.DataTimestamp,
  502. Value: v.Value,
  503. }
  504. if (dateItem.StartDate.Before(dataTimeT) && dateItem.EndDate.After(dataTimeT)) || dateItem.StartDate == dataTimeT || dateItem.EndDate == dataTimeT {
  505. if jumpYear == 1 {
  506. //计算前一年最大的日期, 只补齐数据到去年
  507. beforeYearMaxDate := fmt.Sprintf("%d-12-31", dateItem.StartDate.Year())
  508. beforeYearMaxDateT, _ := time.Parse(utils.FormatDate, beforeYearMaxDate)
  509. if dataTimeT.Before(beforeYearMaxDateT) || dataTimeT == beforeYearMaxDateT {
  510. newItemDate = dataTimeT.AddDate(nowYear-year-1, 0, 0)
  511. } else {
  512. newItemDate = dataTimeT.AddDate(nowYear-year, 0, 0)
  513. }
  514. } else {
  515. newItemDate = dataTimeT.AddDate(nowYear-year, 0, 0)
  516. }
  517. timestamp := newItemDate.UnixNano() / 1e6
  518. tmpVal.DataTimestamp = timestamp
  519. tmpV := &tmpVal
  520. if findVal, ok := quarterMap[k]; !ok {
  521. findVal = append(findVal, tmpV)
  522. quarterMap[k] = findVal
  523. } else {
  524. findVal = append(findVal, tmpV)
  525. quarterMap[k] = findVal
  526. }
  527. if v.DataTime == latestDateStr {
  528. dateItem.CuttingDataTimestamp = timestamp
  529. dataMap[k] = dateItem
  530. }
  531. //break
  532. }
  533. }
  534. }
  535. for k, v := range dataMap {
  536. itemList := quarterMap[k]
  537. quarterItem := new(models.QuarterData)
  538. quarterItem.Years = v.ShowName
  539. quarterItem.Year = v.ChartLegend
  540. quarterItem.ChartLegend = v.ChartLegend
  541. if le, ok := legendMap[v.ShowName]; ok {
  542. if le != strconv.Itoa(v.StartDate.Year()) && le != strconv.Itoa(v.EndDate.Year()) {
  543. quarterItem.ChartLegend = le
  544. }
  545. }
  546. quarterItem.DataList = itemList
  547. quarterItem.CuttingDataTimestamp = v.CuttingDataTimestamp
  548. //如果等于最后的实际日期,那么将切割时间戳记录
  549. if quarterItem.CuttingDataTimestamp == 0 {
  550. //如果大于最后的实际日期,那么第一个点就是切割的时间戳
  551. if latestDate.Before(v.StartDate) && len(itemList) > 0 {
  552. quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
  553. }
  554. }
  555. quarterDataList = append(quarterDataList, quarterItem)
  556. }
  557. if len(quarterDataList) > 0 {
  558. quarterDataListSort = quarterDataList
  559. sort.Sort(quarterDataListSort)
  560. }
  561. return
  562. }
  563. // GetSeasonEdbInfoDataListByXDateNong 季节性图的指标数据根据横轴选择农历时展示
  564. func GetSeasonEdbInfoDataListByXDateNong(result *models.EdbDataResult, latestDate time.Time, seasonExtraConfig string, calendarPreYear int) (quarterDataListSort models.QuarterDataList, err error) {
  565. xStartDate := "01-01"
  566. xEndDate := "12-31"
  567. jumpYear := 0
  568. legends := make([]models.SeasonChartLegend, 0)
  569. var seasonExtra models.SeasonExtraItem
  570. if seasonExtraConfig != "" {
  571. err = json.Unmarshal([]byte(seasonExtraConfig), &seasonExtra)
  572. if err != nil {
  573. return
  574. }
  575. }
  576. if seasonExtra.XStartDate != "" {
  577. xStartDate = seasonExtra.XStartDate
  578. xEndDate = seasonExtra.XEndDate
  579. jumpYear = seasonExtra.JumpYear
  580. legends = seasonExtra.ChartLegend
  581. }
  582. length := len(result.List)
  583. if length == 0 {
  584. return
  585. }
  586. legendMap := make(map[string]string, 0)
  587. if len(legends) > 0 {
  588. for _, v := range legends {
  589. legendMap[v.Name] = v.Value
  590. }
  591. }
  592. latestDateYear := latestDate.Year()
  593. //判断横轴的两个时间之间是不是跨年了,如果跨年了,则横轴截止年份比起始年份+1,如果不跨年,截止年份等于起始年份
  594. //根据数据确定最早的年份,和最近年份
  595. //根据横轴的日期,汇总所有的年份
  596. startYear := result.List[0].Year
  597. /*if jumpYear == 1 {
  598. if startYear != calendarPreYear {
  599. startYear = startYear - 1
  600. }
  601. }*/
  602. itemLength := len(result.List[length-1].Items)
  603. //获取数据的最新日期
  604. lastDate := result.List[length-1].Items[itemLength-1].DataTime
  605. maxY := result.List[length-1].Year
  606. lastDateT, tmpErr := time.Parse(utils.FormatDate, lastDate)
  607. if tmpErr != nil {
  608. err = tmpErr
  609. return
  610. }
  611. endYear := lastDateT.Year()
  612. nowYear := time.Now().Year()
  613. chartLegendMaxYear := 0
  614. dataMap := make(map[string]models.QuarterXDateItem, 0)
  615. quarterDataList := make([]*models.QuarterData, 0)
  616. resultData := make([]*models.QuarterData, 0)
  617. quarterMap := make(map[string][]*models.EdbDataList, 0)
  618. //整理出日期
  619. var startTmpT, endTmpT time.Time
  620. idx := 1
  621. chartLegendMap := make(map[string]int, 0)
  622. for currentStartYear := startYear; currentStartYear <= endYear; currentStartYear++ {
  623. startStr := fmt.Sprintf("%d-%s", currentStartYear, xStartDate)
  624. currentEndYear := currentStartYear
  625. if jumpYear == 1 {
  626. currentEndYear = currentStartYear + 1
  627. }
  628. endStr := fmt.Sprintf("%d-%s", currentEndYear, xEndDate)
  629. showName := fmt.Sprintf("%d_%d", currentStartYear, currentEndYear)
  630. startT, tEr := time.Parse(utils.FormatDate, startStr)
  631. if tEr != nil {
  632. err = tEr
  633. return
  634. }
  635. endT, tEr := time.Parse(utils.FormatDate, endStr)
  636. if tEr != nil {
  637. err = tEr
  638. return
  639. }
  640. if lastDateT.Before(startT) {
  641. //如果最新的日期在起始日之前,则跳出循环
  642. break
  643. }
  644. if endT.Year() > nowYear {
  645. //如果最新的日期比真实年份要大,则数据全部按照最大的年份补齐
  646. nowYear = endT.Year()
  647. }
  648. item := models.QuarterXDateItem{
  649. StartDate: startT,
  650. EndDate: endT,
  651. ShowName: showName,
  652. }
  653. chartLegendMaxYear = endT.Year()
  654. dataMap[showName] = item
  655. fmt.Println("年份" + showName + "日期" + startStr + " " + endStr)
  656. startTmpT = startT
  657. endTmpT = endT
  658. chartLegendMap[showName] = idx
  659. idx++
  660. if lastDateT.Before(endT) {
  661. //如果最新的日期在起始日之前,则跳出循环
  662. break
  663. }
  664. }
  665. lenYear := len(dataMap)
  666. if chartLegendMaxYear > endYear {
  667. chartLegendMaxYear = endYear
  668. }
  669. for k, v := range dataMap {
  670. if i, ok := chartLegendMap[k]; ok {
  671. //v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
  672. v.ChartLegend = strconv.Itoa(chartLegendMaxYear - lenYear + i)
  673. }
  674. dataMap[k] = v
  675. }
  676. yearDataListMap := make(map[int]*models.EdbDataItems, 0)
  677. for _, lv := range result.List {
  678. yearDataListMap[lv.Year] = lv
  679. }
  680. //判断哪些点应该落在同一条时间线上
  681. /*maxY := lastDateT.Year()
  682. changeFlag := false
  683. if lastDateT.Month() >= 11 {
  684. maxY = maxY + 1
  685. }
  686. if maxY < nowYear {
  687. changeFlag = true
  688. maxY = nowYear
  689. }*/
  690. /*endTmp := fmt.Sprintf("%d-%s", maxY, xEndDate)
  691. endTmpT, _ := time.Parse(utils.FormatDate, endTmp)
  692. minY := maxY
  693. if jumpYear == 1 {
  694. minY = maxY - 1
  695. }
  696. startTmp := fmt.Sprintf("%d-%s", minY, xStartDate)
  697. startTmpT, _ := time.Parse(utils.FormatDate, startTmp)*/
  698. fmt.Println("横轴截取日" + startTmpT.Format(utils.FormatDate) + " " + endTmpT.Format(utils.FormatDate))
  699. fmt.Printf("lastDateT.Year() 为%d \n", lastDateT.Year())
  700. fmt.Printf("maxY 为%d \n", maxY)
  701. for name, dateItem := range dataMap {
  702. tY := dateItem.EndDate.Year()
  703. if lastDateT.Month() >= 11 {
  704. if maxY > endTmpT.Year() {
  705. tY = tY + 1
  706. }
  707. }
  708. lv, ok1 := yearDataListMap[tY]
  709. fmt.Printf("name %s yearDataListMap[%d]\n", name, tY)
  710. if !ok1 {
  711. continue
  712. }
  713. for _, item := range lv.Items {
  714. tmpVal := models.EdbDataList{
  715. EdbDataId: item.EdbDataId,
  716. EdbInfoId: item.EdbInfoId,
  717. DataTime: item.DataTime,
  718. DataTimestamp: item.DataTimestamp,
  719. Value: item.Value,
  720. }
  721. dataTimeT, _ := time.Parse(utils.FormatDate, item.DataTime)
  722. if (startTmpT.Before(dataTimeT) && endTmpT.After(dataTimeT)) || startTmpT == dataTimeT || endTmpT == dataTimeT {
  723. tmpV := &tmpVal
  724. if findVal, ok := quarterMap[name]; !ok {
  725. findVal = append(findVal, tmpV)
  726. quarterMap[name] = findVal
  727. } else {
  728. findVal = append(findVal, tmpV)
  729. quarterMap[name] = findVal
  730. }
  731. if lv.Year >= latestDateYear {
  732. // 切割的日期时间字符串
  733. cuttingDataTimeStr := latestDate.AddDate(0, 0, lv.BetweenDay).Format(utils.FormatDate)
  734. if item.DataTime == cuttingDataTimeStr {
  735. dateItem.CuttingDataTimestamp = tmpVal.DataTimestamp
  736. dataMap[name] = dateItem
  737. }
  738. }
  739. }
  740. }
  741. }
  742. for k, v := range dataMap {
  743. itemList := quarterMap[k]
  744. quarterItem := new(models.QuarterData)
  745. quarterItem.Years = v.ShowName
  746. quarterItem.Year = v.ChartLegend
  747. quarterItem.ChartLegend = v.ChartLegend
  748. if le, ok := legendMap[v.ShowName]; ok {
  749. if le != strconv.Itoa(v.StartDate.Year()) && le != strconv.Itoa(v.EndDate.Year()) {
  750. quarterItem.ChartLegend = le
  751. }
  752. }
  753. quarterItem.DataList = itemList
  754. quarterItem.CuttingDataTimestamp = v.CuttingDataTimestamp
  755. //如果等于最后的实际日期,那么将切割时间戳记录
  756. if quarterItem.CuttingDataTimestamp == 0 {
  757. //如果大于最后的实际日期,那么第一个点就是切割的时间戳
  758. if latestDate.Before(v.StartDate) && len(itemList) > 0 {
  759. quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
  760. }
  761. }
  762. quarterDataList = append(quarterDataList, quarterItem)
  763. }
  764. if result.List[0].Year != calendarPreYear {
  765. itemList := make([]*models.EdbDataList, 0)
  766. items := new(models.QuarterData)
  767. //items.Year = calendarPreYear
  768. items.DataList = itemList
  769. newResult := make([]*models.QuarterData, 0)
  770. newResult = append(newResult, items)
  771. newResult = append(newResult, quarterDataList...)
  772. resultData = newResult
  773. } else {
  774. resultData = quarterDataList
  775. }
  776. if len(quarterDataList) > 0 {
  777. quarterDataListSort = resultData
  778. sort.Sort(quarterDataListSort)
  779. }
  780. return
  781. }
  782. // BarChartData 柱方图的数据处理
  783. func BarChartData(mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (edbIdList []int, yDataList []models.YData, err error) {
  784. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  785. edbDataMap := make(map[int]map[string]float64)
  786. for edbInfoId, edbDataList := range edbDataListMap {
  787. edbDateData := make(map[string]float64)
  788. for _, edbData := range edbDataList {
  789. edbDateData[edbData.DataTime] = edbData.Value
  790. }
  791. edbDataMap[edbInfoId] = edbDateData
  792. }
  793. // edbIdList 指标展示顺序;x轴的指标顺序
  794. edbIdList = make([]int, 0)
  795. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  796. dateData := make(map[int]float64)
  797. if barChartInfoSort.Sort == 0 {
  798. for _, v := range mappingList {
  799. edbIdList = append(edbIdList, v.EdbInfoId)
  800. }
  801. } else {
  802. lenBarChartInfoDateList := len(barChartInfoDateList)
  803. if barChartInfoSort.DateIndex >= lenBarChartInfoDateList {
  804. err = errors.New("排序日期异常")
  805. return
  806. }
  807. notDataEdbIdList := make([]int, 0) //没有数据的指标id
  808. // 日期配置
  809. barChartInfoDate := barChartInfoDateList[barChartInfoSort.DateIndex]
  810. for edbInfoId, dataList := range edbDataListMap {
  811. if len(dataList) <= 0 {
  812. // 没有数据的指标id
  813. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  814. continue
  815. }
  816. findDate := barChartInfoDate.Date
  817. switch barChartInfoDate.Type {
  818. case 1: //最新值
  819. findDate = dataList[len(dataList)-1].DataTime
  820. case 2: //近期几天
  821. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  822. if tmpErr != nil {
  823. err = tmpErr
  824. return
  825. }
  826. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  827. lenData := len(dataList) - 1
  828. for i := lenData; i >= 0; i-- {
  829. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  830. if tmpErr != nil {
  831. err = tmpErr
  832. return
  833. }
  834. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  835. findDate = dataList[i].DataTime
  836. break
  837. }
  838. }
  839. case 3: // 固定日期
  840. //最早的日期
  841. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  842. if tmpErr != nil {
  843. err = tmpErr
  844. return
  845. }
  846. //寻找固定日期的数据
  847. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  848. if tmpErr != nil {
  849. err = tmpErr
  850. return
  851. }
  852. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  853. tmpDate := tmpDateTime.Format(utils.FormatDate)
  854. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  855. findDate = tmpDate
  856. break
  857. }
  858. }
  859. default:
  860. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  861. return
  862. }
  863. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  864. dateData[edbInfoId] = tmpValue
  865. } else {
  866. // 没有数据的指标id
  867. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  868. }
  869. }
  870. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  871. // 排序
  872. dateDataSort := utils.NewMapSorter(dateData)
  873. sort.Sort(dateDataSort)
  874. if barChartInfoSort.Sort == 1 {
  875. // 先将没有数据的指标id放在最前面
  876. if len(notDataEdbIdList) > 0 {
  877. edbIdList = append(edbIdList, notDataEdbIdList...)
  878. }
  879. for _, v := range dateDataSort {
  880. edbIdList = append(edbIdList, v.Key)
  881. }
  882. } else {
  883. for i := len(dateDataSort) - 1; i >= 0; i-- {
  884. edbIdList = append(edbIdList, dateDataSort[i].Key)
  885. }
  886. // 再将没有数据的指标id放在最后面
  887. if len(notDataEdbIdList) > 0 {
  888. edbIdList = append(edbIdList, notDataEdbIdList...)
  889. }
  890. }
  891. }
  892. yDataList = make([]models.YData, 0) //y轴的数据列表
  893. for _, barChartInfoDate := range barChartInfoDateList {
  894. var maxDate time.Time
  895. findDataList := make([]float64, 0) // 当前日期的数据值
  896. for _, edbInfoId := range edbIdList {
  897. findDate := barChartInfoDate.Date //需要的日期值
  898. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  899. if len(dataList) <= 0 {
  900. // 没有数据的指标id
  901. findDataList = append(findDataList, 0)
  902. continue
  903. }
  904. switch barChartInfoDate.Type {
  905. case 1: //最新值
  906. dataList := edbDataListMap[edbInfoId]
  907. findDate = dataList[len(dataList)-1].DataTime
  908. case 2: //近期几天
  909. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  910. if tmpErr != nil {
  911. err = tmpErr
  912. return
  913. }
  914. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  915. lenData := len(dataList) - 1
  916. for i := lenData; i >= 0; i-- {
  917. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  918. if tmpErr != nil {
  919. err = tmpErr
  920. return
  921. }
  922. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  923. findDate = dataList[i].DataTime
  924. break
  925. }
  926. }
  927. case 3: // 固定日期
  928. //最早的日期
  929. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  930. if tmpErr != nil {
  931. err = tmpErr
  932. return
  933. }
  934. //寻找固定日期的数据
  935. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  936. if tmpErr != nil {
  937. err = tmpErr
  938. return
  939. }
  940. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  941. tmpDate := tmpDateTime.Format(utils.FormatDate)
  942. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  943. findDate = tmpDate
  944. break
  945. }
  946. }
  947. default:
  948. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  949. return
  950. }
  951. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  952. if maxDate.IsZero() {
  953. maxDate = findDateTime
  954. } else {
  955. if findDateTime.After(maxDate) {
  956. maxDate = findDateTime
  957. }
  958. }
  959. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  960. findDataList = append(findDataList, tmpValue)
  961. } else {
  962. findDataList = append(findDataList, 0)
  963. }
  964. }
  965. yDate := "0000-00-00"
  966. if !maxDate.IsZero() {
  967. yDate = maxDate.Format(utils.FormatDate)
  968. }
  969. yDataList = append(yDataList, models.YData{
  970. Date: yDate,
  971. Value: findDataList,
  972. Color: barChartInfoDate.Color,
  973. Name: barChartInfoDate.Name,
  974. })
  975. }
  976. return
  977. }
  978. // ChartInfoRefreshV2 图表刷新
  979. // @author Roc
  980. // @datetime 2022-09-16 10:15:38
  981. // @description 将原来自己写的一套获取所有关联指标,然后刷新指标逻辑 改成 只获取使用的指标id,然后遍历去调用“指标刷新服务”
  982. func ChartInfoRefreshV2(chartInfoId int) (err error) {
  983. var errmsg string
  984. defer func() {
  985. if err != nil {
  986. go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errmsg, 3)
  987. //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "ChartInfoRefresh:"+errmsg, utils.EmailSendToUsers)
  988. fmt.Println("ChartInfoRefresh Err:" + errmsg)
  989. }
  990. }()
  991. edbMappingList, err := data_manage.GetChartEdbMappingList(chartInfoId)
  992. if err != nil {
  993. errmsg = "获取需要刷新的指标失败:Err:" + err.Error()
  994. return
  995. }
  996. edbIdList := make([]int, 0)
  997. for _, v := range edbMappingList {
  998. edbIdList = append(edbIdList, v.EdbInfoId)
  999. }
  1000. // 批量刷新
  1001. err, errmsg = EdbInfoRefreshAllFromBase(edbIdList, false)
  1002. if err != nil {
  1003. return
  1004. }
  1005. return
  1006. }
  1007. // GetSectionScatterChartData 柱方图的数据处理
  1008. func GetSectionScatterChartData(mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, extraConfig data_manage.SectionScatterReq) (edbIdList []int, chartDataResp data_manage.SectionScatterInfoResp, err error) {
  1009. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  1010. edbDataMap := make(map[int]map[string]float64)
  1011. for edbInfoId, edbDataList := range edbDataListMap {
  1012. edbDateData := make(map[string]float64)
  1013. for _, edbData := range edbDataList {
  1014. edbDateData[edbData.DataTime] = edbData.Value
  1015. }
  1016. edbDataMap[edbInfoId] = edbDateData
  1017. }
  1018. // edbIdList 指标展示顺序;x轴的指标顺序
  1019. edbIdList = make([]int, 0)
  1020. edbMappingMap := make(map[int]*models.ChartEdbInfoMapping)
  1021. for _, v := range mappingList {
  1022. edbIdList = append(edbIdList, v.EdbInfoId)
  1023. edbMappingMap[v.EdbInfoId] = v
  1024. }
  1025. //SectionScatterSeriesInfoResp
  1026. dataListResp := make([]data_manage.SectionScatterSeriesItemResp, 0) //y轴的数据列表
  1027. for _, seriesItem := range extraConfig.SeriesList {
  1028. var maxDate time.Time
  1029. // 系列中的指标数据
  1030. tmpSeriesEdbInfoList := make([]data_manage.SectionScatterEdbItemResp, 0)
  1031. var minXVal, maxXVal, minYVal, maxYVal float64
  1032. for _, edbConf := range seriesItem.EdbInfoList {
  1033. tmpItem := data_manage.SectionScatterEdbItemResp{
  1034. IsShow: edbConf.IsShow,
  1035. Name: edbConf.Name,
  1036. NameEn: edbConf.NameEn,
  1037. } //单个坐标点的数据
  1038. //X轴的数据
  1039. {
  1040. edbInfoId := edbConf.XEdbInfoId //X轴的指标
  1041. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  1042. if !ok {
  1043. continue
  1044. }
  1045. findDate := edbConf.XDate //需要的日期值
  1046. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  1047. if len(dataList) <= 0 {
  1048. // 没有数据的指标id
  1049. //findDataList = append(findDataList, 0)
  1050. continue
  1051. }
  1052. tmpItem.XEdbInfoId = edbInfoId
  1053. tmpItem.XName = edbMappingInfo.EdbName
  1054. tmpItem.XNameEn = edbMappingInfo.EdbNameEn
  1055. switch edbConf.XDateType {
  1056. case 1: //最新值
  1057. dataList := edbDataListMap[edbInfoId]
  1058. findDate = dataList[len(dataList)-1].DataTime
  1059. case 2: //近期几天
  1060. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  1061. if tmpErr != nil {
  1062. err = tmpErr
  1063. return
  1064. }
  1065. findDateTime = findDateTime.AddDate(0, 0, -edbConf.XDateValue)
  1066. lenData := len(dataList) - 1
  1067. for i := lenData; i >= 0; i-- {
  1068. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  1069. if tmpErr != nil {
  1070. err = tmpErr
  1071. return
  1072. }
  1073. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  1074. findDate = dataList[i].DataTime
  1075. break
  1076. }
  1077. }
  1078. case 3: // 固定日期
  1079. //最早的日期
  1080. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  1081. if tmpErr != nil {
  1082. err = tmpErr
  1083. return
  1084. }
  1085. //寻找固定日期的数据
  1086. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.XDate, time.Local)
  1087. if tmpErr != nil {
  1088. err = tmpErr
  1089. return
  1090. }
  1091. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  1092. tmpDate := tmpDateTime.Format(utils.FormatDate)
  1093. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  1094. findDate = tmpDate
  1095. break
  1096. }
  1097. }
  1098. default:
  1099. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.XDate))
  1100. return
  1101. }
  1102. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  1103. if maxDate.IsZero() {
  1104. maxDate = findDateTime
  1105. } else {
  1106. if findDateTime.After(maxDate) {
  1107. maxDate = findDateTime
  1108. }
  1109. }
  1110. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  1111. tmpItem.XDate = findDate
  1112. tmpItem.XValue = tmpValue
  1113. } else {
  1114. continue
  1115. }
  1116. }
  1117. //Y轴的数据
  1118. {
  1119. edbInfoId := edbConf.YEdbInfoId //Y轴的指标
  1120. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  1121. if !ok {
  1122. continue
  1123. }
  1124. findDate := edbConf.YDate //需要的日期值
  1125. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  1126. if len(dataList) <= 0 {
  1127. // 没有数据的指标id
  1128. //findDataList = append(findDataList, 0)
  1129. continue
  1130. }
  1131. tmpItem.YEdbInfoId = edbInfoId
  1132. tmpItem.YName = edbMappingInfo.EdbName
  1133. tmpItem.YNameEn = edbMappingInfo.EdbNameEn
  1134. switch edbConf.YDateType {
  1135. case 1: //最新值
  1136. dataList := edbDataListMap[edbInfoId]
  1137. findDate = dataList[len(dataList)-1].DataTime
  1138. case 2: //近期几天
  1139. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  1140. if tmpErr != nil {
  1141. err = tmpErr
  1142. return
  1143. }
  1144. findDateTime = findDateTime.AddDate(0, 0, -edbConf.YDateValue)
  1145. lenData := len(dataList) - 1
  1146. for i := lenData; i >= 0; i-- {
  1147. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  1148. if tmpErr != nil {
  1149. err = tmpErr
  1150. return
  1151. }
  1152. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  1153. findDate = dataList[i].DataTime
  1154. break
  1155. }
  1156. }
  1157. case 3: // 固定日期
  1158. //最早的日期
  1159. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  1160. if tmpErr != nil {
  1161. err = tmpErr
  1162. return
  1163. }
  1164. //寻找固定日期的数据
  1165. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.YDate, time.Local)
  1166. if tmpErr != nil {
  1167. err = tmpErr
  1168. return
  1169. }
  1170. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  1171. tmpDate := tmpDateTime.Format(utils.FormatDate)
  1172. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  1173. findDate = tmpDate
  1174. break
  1175. }
  1176. }
  1177. default:
  1178. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.YDate))
  1179. return
  1180. }
  1181. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  1182. if maxDate.IsZero() {
  1183. maxDate = findDateTime
  1184. } else {
  1185. if findDateTime.After(maxDate) {
  1186. maxDate = findDateTime
  1187. }
  1188. }
  1189. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  1190. tmpItem.YDate = findDate
  1191. tmpItem.YValue = tmpValue
  1192. } else {
  1193. continue
  1194. }
  1195. }
  1196. // 获取当前系列的X轴的最大最小值
  1197. {
  1198. if tmpItem.XValue < minXVal {
  1199. minXVal = tmpItem.XValue
  1200. }
  1201. if tmpItem.XValue > maxXVal {
  1202. maxXVal = tmpItem.XValue
  1203. }
  1204. if tmpItem.YValue < minYVal {
  1205. minYVal = tmpItem.YValue
  1206. }
  1207. if tmpItem.YValue > maxYVal {
  1208. maxYVal = tmpItem.YValue
  1209. }
  1210. }
  1211. tmpSeriesEdbInfoList = append(tmpSeriesEdbInfoList, tmpItem)
  1212. }
  1213. trendLimitData := make([]data_manage.CoordinatePoint, 0) //趋势线的前后坐标点
  1214. var trendLine, rSquare string
  1215. // 生成线性方程式
  1216. var a, b float64
  1217. {
  1218. coordinateData := make([]utils.Coordinate, 0)
  1219. for _, tmpSeriesEdbInfo := range tmpSeriesEdbInfoList {
  1220. tmpCoordinate1 := utils.Coordinate{
  1221. X: tmpSeriesEdbInfo.XValue,
  1222. Y: tmpSeriesEdbInfo.YValue,
  1223. }
  1224. coordinateData = append(coordinateData, tmpCoordinate1)
  1225. }
  1226. // 只有存在两个坐标点的时候,才能去计算线性方程和R平方
  1227. if len(coordinateData) >= 2 {
  1228. a, b = utils.GetLinearResult(coordinateData)
  1229. if !math.IsNaN(a) || !math.IsNaN(b) {
  1230. if b > 0 {
  1231. trendLine = fmt.Sprintf("y=%sx+%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  1232. } else {
  1233. trendLine = fmt.Sprintf("y=%sx%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  1234. }
  1235. minYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(minXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  1236. maxYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(maxXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  1237. }
  1238. // 计算R平方
  1239. rSquare = fmt.Sprint(utils.CalculationDecisive(coordinateData))
  1240. }
  1241. trendLimitData = append(trendLimitData, data_manage.CoordinatePoint{
  1242. X: minXVal,
  1243. Y: minYVal,
  1244. }, data_manage.CoordinatePoint{
  1245. X: maxXVal,
  1246. Y: maxYVal,
  1247. })
  1248. }
  1249. dataListResp = append(dataListResp, data_manage.SectionScatterSeriesItemResp{
  1250. Name: seriesItem.Name,
  1251. NameEn: seriesItem.NameEn,
  1252. Color: seriesItem.Color,
  1253. EdbInfoList: tmpSeriesEdbInfoList,
  1254. ShowTrendLine: seriesItem.ShowTrendLine,
  1255. ShowFitEquation: seriesItem.ShowFitEquation,
  1256. ShowRSquare: seriesItem.ShowRSquare,
  1257. TrendLine: trendLine,
  1258. RSquare: rSquare,
  1259. TrendLimitData: trendLimitData,
  1260. })
  1261. }
  1262. chartDataResp = data_manage.SectionScatterInfoResp{
  1263. XName: extraConfig.XName,
  1264. XNameEn: extraConfig.XNameEn,
  1265. XUnitName: extraConfig.XUnitName,
  1266. XUnitNameEn: extraConfig.XUnitNameEn,
  1267. YName: extraConfig.YName,
  1268. YNameEn: extraConfig.YNameEn,
  1269. YUnitName: extraConfig.YUnitName,
  1270. YUnitNameEn: extraConfig.YUnitNameEn,
  1271. XMinValue: extraConfig.XMinValue,
  1272. XMaxValue: extraConfig.XMaxValue,
  1273. YMinValue: extraConfig.YMinValue,
  1274. YMaxValue: extraConfig.YMaxValue,
  1275. DataList: dataListResp,
  1276. }
  1277. return
  1278. }
  1279. // RadarChartData 雷达图的数据处理
  1280. func RadarChartData(mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, extraConfig data_manage.RadarChartInfoReq) (edbIdList []int, chartDataResp data_manage.RadarChartInfoResp, err error) {
  1281. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  1282. edbDataMap := make(map[int]map[string]float64)
  1283. for edbInfoId, edbDataList := range edbDataListMap {
  1284. edbDateData := make(map[string]float64)
  1285. for _, edbData := range edbDataList {
  1286. edbDateData[edbData.DataTime] = edbData.Value
  1287. }
  1288. edbDataMap[edbInfoId] = edbDateData
  1289. }
  1290. // edbIdList 指标展示顺序;x轴的指标顺序
  1291. edbIdList = make([]int, 0)
  1292. for _, v := range mappingList {
  1293. edbIdList = append(edbIdList, v.EdbInfoId)
  1294. }
  1295. chartDateList := extraConfig.DateList
  1296. yDataList := make([]data_manage.RadarYData, 0) //y轴的数据列表
  1297. for _, chartDate := range chartDateList {
  1298. var maxDate time.Time
  1299. findDataList := make([]float64, 0) // 当前日期的数据值
  1300. for _, edbInfoId := range edbIdList {
  1301. findDate := chartDate.Date //需要的日期值
  1302. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  1303. if len(dataList) <= 0 {
  1304. // 没有数据的指标id
  1305. findDataList = append(findDataList, 0)
  1306. continue
  1307. }
  1308. switch chartDate.Type {
  1309. case 1: //最新值
  1310. findDate = dataList[len(dataList)-1].DataTime
  1311. case 2: //近期几天
  1312. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  1313. if tmpErr != nil {
  1314. err = tmpErr
  1315. return
  1316. }
  1317. findDateTime = findDateTime.AddDate(0, 0, -chartDate.Value)
  1318. lenData := len(dataList) - 1
  1319. for i := lenData; i >= 0; i-- {
  1320. currDateTime, e := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  1321. if e != nil {
  1322. err = e
  1323. return
  1324. }
  1325. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  1326. findDate = dataList[i].DataTime
  1327. break
  1328. }
  1329. }
  1330. case 3: // 固定日期
  1331. //最早的日期
  1332. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  1333. if tmpErr != nil {
  1334. err = tmpErr
  1335. return
  1336. }
  1337. //寻找固定日期的数据
  1338. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, chartDate.Date, time.Local)
  1339. if tmpErr != nil {
  1340. err = tmpErr
  1341. return
  1342. }
  1343. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  1344. tmpDate := tmpDateTime.Format(utils.FormatDate)
  1345. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  1346. findDate = tmpDate
  1347. break
  1348. }
  1349. }
  1350. default:
  1351. err = errors.New(fmt.Sprint("日期类型异常,Type:", chartDate.Type))
  1352. return
  1353. }
  1354. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  1355. if maxDate.IsZero() {
  1356. maxDate = findDateTime
  1357. } else {
  1358. if findDateTime.After(maxDate) {
  1359. maxDate = findDateTime
  1360. }
  1361. }
  1362. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  1363. tmpValue, _ = decimal.NewFromFloat(tmpValue).Round(4).Float64()
  1364. findDataList = append(findDataList, tmpValue)
  1365. } else {
  1366. findDataList = append(findDataList, 0)
  1367. }
  1368. }
  1369. yDate := "0000-00-00"
  1370. if !maxDate.IsZero() {
  1371. yDate = maxDate.Format(utils.FormatDate)
  1372. }
  1373. yDataList = append(yDataList, data_manage.RadarYData{
  1374. Date: yDate,
  1375. Value: findDataList,
  1376. Color: chartDate.Color,
  1377. Name: chartDate.Name,
  1378. })
  1379. }
  1380. chartDataResp = data_manage.RadarChartInfoResp{
  1381. YDataList: yDataList,
  1382. XEdbIdValue: edbIdList,
  1383. }
  1384. return
  1385. }
  1386. // GetChartEdbDataV2 获取图表的指标数据
  1387. func GetChartEdbDataV2(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, extraConfigStr, seasonExtraConfig string, chartInfoData ChartInfoDataShow) (edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, yDataList []models.YData, dataResp interface{}, err error, errMsg string) {
  1388. edbList = make([]*models.ChartEdbInfoMapping, 0)
  1389. // 指标对应的所有数据
  1390. xEdbIdValue = make([]int, 0)
  1391. yDataList = make([]models.YData, 0)
  1392. var extraConfig interface{}
  1393. switch chartType {
  1394. case 7: // 柱形图
  1395. var barConfig data_manage.BarChartInfoReq
  1396. if extraConfigStr == `` {
  1397. errMsg = "柱方图未配置"
  1398. err = errors.New(errMsg)
  1399. return
  1400. }
  1401. err = json.Unmarshal([]byte(extraConfigStr), &barConfig)
  1402. if err != nil {
  1403. errMsg = "柱方图配置异常"
  1404. err = errors.New(errMsg)
  1405. return
  1406. }
  1407. extraConfig = barConfig
  1408. case 10: // 截面散点图
  1409. var tmpExtraConfig data_manage.SectionScatterReq
  1410. if extraConfigStr == `` {
  1411. errMsg = "截面散点图未配置"
  1412. err = errors.New(errMsg)
  1413. return
  1414. }
  1415. err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
  1416. if err != nil {
  1417. errMsg = "截面散点配置异常"
  1418. err = errors.New(errMsg)
  1419. return
  1420. }
  1421. extraConfig = tmpExtraConfig
  1422. case utils.CHART_TYPE_RADAR:
  1423. var barConfig data_manage.RadarChartInfoReq
  1424. if extraConfigStr == `` {
  1425. errMsg = "雷达图未配置"
  1426. err = errors.New(errMsg)
  1427. return
  1428. }
  1429. err = json.Unmarshal([]byte(extraConfigStr), &barConfig)
  1430. if err != nil {
  1431. errMsg = "雷达图配置异常"
  1432. err = errors.New(errMsg)
  1433. return
  1434. }
  1435. extraConfig = barConfig
  1436. default:
  1437. xEdbIdValue = make([]int, 0)
  1438. yDataList = make([]models.YData, 0)
  1439. }
  1440. // 指标对应的所有数据
  1441. edbDataListMap, edbList, err := chartInfoData.GetEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, seasonExtraConfig)
  1442. if err != nil {
  1443. return
  1444. }
  1445. // 特殊图形数据处理
  1446. switch chartType {
  1447. case 7: // 柱形图
  1448. barChartConf := extraConfig.(data_manage.BarChartInfoReq)
  1449. xEdbIdValue, yDataList, err = BarChartData(mappingList, edbDataListMap, barChartConf.DateList, barChartConf.Sort)
  1450. for _, v := range edbList {
  1451. // 指标别名
  1452. if barChartConf.EdbInfoIdList != nil && len(barChartConf.EdbInfoIdList) > 0 {
  1453. for _, reqEdb := range barChartConf.EdbInfoIdList {
  1454. if v.EdbInfoId == reqEdb.EdbInfoId {
  1455. v.EdbAliasName = reqEdb.Name
  1456. }
  1457. }
  1458. }
  1459. }
  1460. case 10: // 截面散点图
  1461. sectionScatterConf := extraConfig.(data_manage.SectionScatterReq)
  1462. xEdbIdValue, dataResp, err = GetSectionScatterChartData(mappingList, edbDataListMap, sectionScatterConf)
  1463. // 这个数据没有必要返回给前端
  1464. for _, v := range edbList {
  1465. v.DataList = nil
  1466. }
  1467. case utils.CHART_TYPE_RADAR: //雷达图
  1468. radarConf := extraConfig.(data_manage.RadarChartInfoReq)
  1469. xEdbIdValue, dataResp, err = RadarChartData(mappingList, edbDataListMap, radarConf)
  1470. }
  1471. return
  1472. }
  1473. // SeasonChartData 季节性图的数据处理
  1474. func SeasonChartData(dataList []*models.ChartEdbInfoMapping, seasonExtraConfig string) (dataResp models.SeasonChartResp, err error) {
  1475. var seasonConfig models.SeasonExtraItem
  1476. err = json.Unmarshal([]byte(seasonExtraConfig), &seasonConfig)
  1477. if err != nil {
  1478. err = errors.New("季节性图配置异常, Err:" + err.Error())
  1479. return
  1480. }
  1481. for _, mappingItem := range dataList {
  1482. if mappingItem.IsAxis == 0 {
  1483. continue
  1484. }
  1485. quarterDataList := mappingItem.DataList.(models.QuarterDataList)
  1486. // 上下限区间
  1487. if seasonConfig.MaxMinLimits.Year > 0 {
  1488. dataResp.MaxMinLimits.List = make([]*models.MaxMinLimitsData, 0)
  1489. dataTimeMap := make(map[time.Time]time.Time)
  1490. dataTimeList := make([]string, 0)
  1491. maxValueMap := make(map[time.Time]float64)
  1492. minValueMap := make(map[time.Time]float64)
  1493. maxMinDataList := make([]*models.MaxMinLimitsData, 0)
  1494. // 日度 周度插值
  1495. for _, v := range quarterDataList {
  1496. if mappingItem.Frequency == "日度" || mappingItem.Frequency == "周度" {
  1497. handleDataMap := make(map[string]float64)
  1498. dataTimeList, _, err = HandleDataByLinearRegressionToList(v.DataList, handleDataMap)
  1499. if err != nil {
  1500. err = errors.New("插值处理数据异常, Err:" + err.Error())
  1501. return
  1502. }
  1503. for _, date := range dataTimeList {
  1504. dateTime, e := time.Parse(utils.FormatDate, date)
  1505. if e != nil {
  1506. err = errors.New("时间格式化异常, Err:" + e.Error())
  1507. return
  1508. }
  1509. newDate := dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
  1510. // 处理上下限列表
  1511. if value, ok := maxValueMap[newDate]; ok {
  1512. if value < handleDataMap[date] {
  1513. maxValueMap[newDate] = handleDataMap[date]
  1514. }
  1515. } else {
  1516. maxValueMap[newDate] = handleDataMap[date]
  1517. }
  1518. if value, ok := minValueMap[newDate]; ok {
  1519. if value > handleDataMap[date] {
  1520. minValueMap[newDate] = handleDataMap[date]
  1521. }
  1522. } else {
  1523. minValueMap[newDate] = handleDataMap[date]
  1524. }
  1525. dataTimeMap[newDate] = newDate
  1526. }
  1527. } else {
  1528. // 旬度、月度、季度、半年度 不插值,需要先把日期列表和数据map取出来
  1529. for _, vv := range v.DataList {
  1530. dateTime, e := time.Parse(utils.FormatDate, vv.DataTime)
  1531. if e != nil {
  1532. err = errors.New("时间格式化异常, Err:" + e.Error())
  1533. return
  1534. }
  1535. newDate := dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
  1536. if value, ok := maxValueMap[newDate]; ok {
  1537. if value < vv.Value {
  1538. maxValueMap[newDate] = vv.Value
  1539. }
  1540. } else {
  1541. maxValueMap[newDate] = vv.Value
  1542. }
  1543. if value, ok := minValueMap[newDate]; ok {
  1544. if value > vv.Value {
  1545. minValueMap[newDate] = vv.Value
  1546. }
  1547. } else {
  1548. minValueMap[newDate] = vv.Value
  1549. }
  1550. dataTimeMap[newDate] = newDate
  1551. }
  1552. }
  1553. }
  1554. for _, v := range dataTimeMap {
  1555. maxMinItem := &models.MaxMinLimitsData{}
  1556. if maxValue, ok := maxValueMap[v]; ok {
  1557. maxMinItem.MaxValue = maxValue
  1558. } else {
  1559. maxMinItem.MaxValue = minValueMap[v]
  1560. }
  1561. if minValue, ok := minValueMap[v]; ok {
  1562. maxMinItem.MinValue = minValue
  1563. } else {
  1564. maxMinItem.MinValue = maxValueMap[v]
  1565. }
  1566. maxMinItem.DataTime = v.Format(utils.FormatDate)
  1567. maxMinItem.DataTimestamp = v.UnixNano() / 1e6
  1568. maxMinDataList = append(maxMinDataList, maxMinItem)
  1569. }
  1570. // 排序
  1571. sort.Slice(maxMinDataList, func(i, j int) bool {
  1572. return maxMinDataList[i].DataTime < maxMinDataList[j].DataTime
  1573. })
  1574. dataResp.MaxMinLimits.List = maxMinDataList
  1575. dataResp.MaxMinLimits.Color = seasonConfig.MaxMinLimits.Color
  1576. dataResp.MaxMinLimits.Legend = seasonConfig.MaxMinLimits.Legend
  1577. dataResp.MaxMinLimits.IsShow = seasonConfig.MaxMinLimits.IsShow
  1578. dataResp.MaxMinLimits.IsAdd = seasonConfig.MaxMinLimits.IsAdd
  1579. dataResp.MaxMinLimits.Year = seasonConfig.MaxMinLimits.Year
  1580. }
  1581. // 自定义同期均线
  1582. if seasonConfig.SamePeriodAverage.Year > 0 {
  1583. handleDataMap := make(map[string]float64)
  1584. dataTimeMap := make(map[time.Time]time.Time)
  1585. dataTimeList := make([]string, 0)
  1586. valueMap := make(map[time.Time]float64)
  1587. averageDataList := make([]*models.SamePeriodAverageData, 0)
  1588. for i := len(quarterDataList) - 1; i > len(quarterDataList)-seasonConfig.SamePeriodAverage.Year && i > 0; i-- {
  1589. // 插值成日度
  1590. dataTimeList, _, err = HandleDataByLinearRegressionToList(quarterDataList[i].DataList, handleDataMap)
  1591. if err != nil {
  1592. err = errors.New("插值处理数据异常, Err:" + err.Error())
  1593. return
  1594. }
  1595. for _, date := range dataTimeList {
  1596. dateTime, e := time.Parse(utils.FormatDate, date)
  1597. if e != nil {
  1598. err = errors.New("时间格式化异常, Err:" + e.Error())
  1599. return
  1600. }
  1601. // 不包含今年
  1602. if dateTime.Year() == time.Now().Year() {
  1603. continue
  1604. }
  1605. newDate := dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
  1606. // 处理均值
  1607. if value, ok := valueMap[newDate]; ok {
  1608. valueMap[newDate] = (handleDataMap[date] + value) / 2
  1609. } else {
  1610. valueMap[newDate] = handleDataMap[date]
  1611. }
  1612. dataTimeMap[newDate] = newDate
  1613. }
  1614. }
  1615. for _, v := range dataTimeMap {
  1616. averageItem := &models.SamePeriodAverageData{}
  1617. if value, ok := valueMap[v]; ok {
  1618. averageItem.Value = value
  1619. }
  1620. averageItem.DataTime = v.Format(utils.FormatDate)
  1621. averageItem.DataTimestamp = v.UnixNano() / 1e6
  1622. averageDataList = append(averageDataList, averageItem)
  1623. }
  1624. // 排序
  1625. sort.Slice(averageDataList, func(i, j int) bool {
  1626. return averageDataList[i].DataTime < averageDataList[j].DataTime
  1627. })
  1628. dataResp.SamePeriodAverage.List = averageDataList
  1629. dataResp.SamePeriodAverage.Year = seasonConfig.SamePeriodAverage.Year
  1630. dataResp.SamePeriodAverage.Color = seasonConfig.SamePeriodAverage.Color
  1631. dataResp.SamePeriodAverage.Legend = seasonConfig.SamePeriodAverage.Legend
  1632. dataResp.SamePeriodAverage.IsShow = seasonConfig.SamePeriodAverage.IsShow
  1633. dataResp.SamePeriodAverage.LineType = seasonConfig.SamePeriodAverage.LineType
  1634. dataResp.SamePeriodAverage.LineWidth = seasonConfig.SamePeriodAverage.LineWidth
  1635. dataResp.SamePeriodAverage.IsAdd = seasonConfig.SamePeriodAverage.IsAdd
  1636. }
  1637. // 自定义同期标准差
  1638. if seasonConfig.SamePeriodStandardDeviation.Year > 1 && seasonConfig.SamePeriodStandardDeviation.Multiple > 0 {
  1639. // 先算均值,再算标准差
  1640. handleDataMap := make(map[string]float64)
  1641. dataTimeMap := make(map[time.Time]time.Time)
  1642. dataTimeValueMap := make(map[time.Time][]float64)
  1643. dataTimeList := make([]string, 0)
  1644. valueMap := make(map[time.Time]float64)
  1645. samePeriodStandardDeviationList := make([]*models.MaxMinLimitsData, 0)
  1646. for i := len(quarterDataList) - 1; i > len(quarterDataList)-seasonConfig.SamePeriodAverage.Year-1 && i > 0; i-- {
  1647. // 插值成日度
  1648. dataTimeList, _, err = HandleDataByLinearRegressionToListV2(quarterDataList[i].DataList, handleDataMap)
  1649. if err != nil {
  1650. err = errors.New("插值处理数据异常, Err:" + err.Error())
  1651. return
  1652. }
  1653. for _, date := range dataTimeList {
  1654. dateTime, e := time.Parse(utils.FormatDate, date)
  1655. if e != nil {
  1656. err = errors.New("时间格式化异常, Err:" + e.Error())
  1657. return
  1658. }
  1659. // 不包含今年
  1660. if dateTime.Year() == time.Now().Year() {
  1661. continue
  1662. }
  1663. newDate := dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
  1664. // 处理均值
  1665. if value, ok := valueMap[newDate]; ok {
  1666. valueMap[newDate] = (handleDataMap[date] + value) / 2
  1667. } else {
  1668. valueMap[newDate] = handleDataMap[date]
  1669. }
  1670. dataTimeMap[newDate] = newDate
  1671. valueList := dataTimeValueMap[newDate]
  1672. valueList = append(valueList, handleDataMap[date])
  1673. dataTimeValueMap[newDate] = valueList
  1674. }
  1675. }
  1676. for _, v := range dataTimeMap {
  1677. valueList := dataTimeValueMap[v]
  1678. stdev := utils.CalculateStandardDeviation(valueList)
  1679. stdev, _ = decimal.NewFromFloat(stdev).Round(4).Float64()
  1680. maxMinItem := &models.MaxMinLimitsData{}
  1681. if value, ok := valueMap[v]; ok {
  1682. maxMinItem.MaxValue = value + stdev*seasonConfig.SamePeriodStandardDeviation.Multiple
  1683. maxMinItem.MinValue = value - stdev*seasonConfig.SamePeriodStandardDeviation.Multiple
  1684. }
  1685. maxMinItem.DataTime = v.Format(utils.FormatDate)
  1686. maxMinItem.DataTimestamp = v.UnixNano() / 1e6
  1687. samePeriodStandardDeviationList = append(samePeriodStandardDeviationList, maxMinItem)
  1688. }
  1689. // 排序
  1690. sort.Slice(samePeriodStandardDeviationList, func(i, j int) bool {
  1691. return samePeriodStandardDeviationList[i].DataTime < samePeriodStandardDeviationList[j].DataTime
  1692. })
  1693. dataResp.SamePeriodStandardDeviation.List = samePeriodStandardDeviationList
  1694. dataResp.SamePeriodStandardDeviation.Color = seasonConfig.SamePeriodStandardDeviation.Color
  1695. dataResp.SamePeriodStandardDeviation.Legend = seasonConfig.SamePeriodStandardDeviation.Legend
  1696. dataResp.SamePeriodStandardDeviation.IsShow = seasonConfig.SamePeriodStandardDeviation.IsShow
  1697. dataResp.SamePeriodStandardDeviation.Multiple = seasonConfig.SamePeriodStandardDeviation.Multiple
  1698. dataResp.SamePeriodStandardDeviation.Year = seasonConfig.SamePeriodStandardDeviation.Year
  1699. dataResp.SamePeriodStandardDeviation.IsAdd = seasonConfig.SamePeriodStandardDeviation.IsAdd
  1700. }
  1701. // 自定义右轴
  1702. if seasonConfig.RightAxis.IndicatorType != 0 {
  1703. if seasonConfig.RightAxis.IndicatorType == 1 {
  1704. startTime, _ := time.Parse(utils.FormatDate, mappingItem.StartDate)
  1705. for i := len(quarterDataList) - 1; i > len(quarterDataList)-2 && i > 0; i-- {
  1706. var rightMappingItem models.ChartEdbInfoMapping
  1707. rightMappingItem = *mappingItem
  1708. // 计算同比值
  1709. tbzDataList, minValue, maxValue, e := GetEdbDataTbzForSeason(mappingItem.Frequency, quarterDataList[i].DataList, startTime)
  1710. if e != nil {
  1711. err = errors.New("计算同比值失败, Err:" + e.Error())
  1712. return
  1713. }
  1714. rightMappingItem.DataList = tbzDataList
  1715. rightMappingItem.MaxData = maxValue
  1716. rightMappingItem.MinData = minValue
  1717. dataResp.RightAxis.EdbInfoList = append(dataResp.RightAxis.EdbInfoList, &rightMappingItem)
  1718. }
  1719. }
  1720. dataResp.RightAxis.SeasonRightAxis = seasonConfig.RightAxis
  1721. }
  1722. }
  1723. return
  1724. }