chart_info.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package line_feature
  2. import (
  3. "errors"
  4. "github.com/shopspring/decimal"
  5. "hongze/hongze_ETA_mobile_api/models/data_manage"
  6. "hongze/hongze_ETA_mobile_api/models/data_manage/line_feature/response"
  7. "hongze/hongze_ETA_mobile_api/services/data"
  8. "hongze/hongze_ETA_mobile_api/utils"
  9. "time"
  10. )
  11. // GetStandardDeviationData 获取标准差图表的指标数据
  12. func GetStandardDeviationData(chartInfoId int, mappingInfo *data_manage.ChartEdbInfoMapping, calculateValue int) (edbList []*data_manage.ChartEdbInfoMapping, dataResp response.LineFeatureDataResp, err error, errMsg string) {
  13. edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
  14. // 指标对应的所有数据
  15. _, edbList, err = data.GetEdbDataMapList(chartInfoId, 1, `公历`, ``, ``, []*data_manage.ChartEdbInfoMapping{mappingInfo})
  16. if err != nil {
  17. return
  18. }
  19. if len(edbList) != 1 {
  20. errMsg = `指标异常`
  21. err = errors.New(errMsg)
  22. return
  23. }
  24. edb := edbList[0]
  25. dataList := edb.DataList.([]*data_manage.EdbDataList)
  26. newDataList := make([]data_manage.EdbDataList, 0)
  27. lenData := len(dataList)
  28. var minVal, maxVal float64
  29. if lenData >= calculateValue {
  30. tmpDataList := make([]float64, 0)
  31. for _, tmpData := range dataList {
  32. tmpDataList = append(tmpDataList, tmpData.Value)
  33. }
  34. for i := calculateValue; i <= lenData; i++ {
  35. tmpV := utils.CalculateStandardDeviation(tmpDataList[i-calculateValue : i])
  36. tmpV, _ = decimal.NewFromFloat(tmpV).Round(4).Float64()
  37. newDataList = append(newDataList, data_manage.EdbDataList{
  38. EdbDataId: i,
  39. EdbInfoId: edb.EdbInfoId,
  40. DataTime: dataList[i-1].DataTime,
  41. DataTimestamp: dataList[i-1].DataTimestamp,
  42. Value: tmpV,
  43. })
  44. if tmpV > maxVal {
  45. maxVal = tmpV
  46. }
  47. if tmpV < minVal {
  48. minVal = tmpV
  49. }
  50. }
  51. }
  52. dataResp = response.LineFeatureDataResp{
  53. MaxData: maxVal,
  54. MinData: minVal,
  55. LatestDate: edb.LatestDate,
  56. EdbInfoCategoryType: edb.EdbInfoCategoryType,
  57. ChartColor: `#00F`,
  58. ChartStyle: `spline`,
  59. PredictChartColor: `#00F`,
  60. ChartType: 0,
  61. ChartWidth: 3,
  62. EdbName: "标准差",
  63. EdbNameEn: "standard deviation",
  64. Unit: edb.Unit,
  65. UnitEn: edb.UnitEn,
  66. IsAxis: 1,
  67. DataList: newDataList,
  68. }
  69. return
  70. }
  71. // GetPercentileData 获取百分位图表的指标数据
  72. func GetPercentileData(chartInfoId int, mappingInfo *data_manage.ChartEdbInfoMapping, calculateValue int, calculateUnit string) (edbList []*data_manage.ChartEdbInfoMapping, dataResp response.LineFeatureDataResp, err error, errMsg string) {
  73. edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
  74. moveUnitDays, ok := utils.FrequencyDaysMap[calculateUnit]
  75. if !ok {
  76. errMsg = `错误的周期`
  77. err = errors.New(errMsg)
  78. return
  79. }
  80. calculateDay := calculateValue * moveUnitDays
  81. // 指标对应的所有数据
  82. _, edbList, err = data.GetEdbDataMapList(chartInfoId, 1, `公历`, ``, ``, []*data_manage.ChartEdbInfoMapping{mappingInfo})
  83. if err != nil {
  84. return
  85. }
  86. if len(edbList) != 1 {
  87. errMsg = `指标异常`
  88. err = errors.New(errMsg)
  89. return
  90. }
  91. edb := edbList[0]
  92. dataList := edb.DataList.([]*data_manage.EdbDataList)
  93. newDataList := make([]data_manage.EdbDataList, 0)
  94. var edbMinVal, edbMaxVal float64
  95. dataMap := make(map[time.Time]float64, 0)
  96. for _, tmpData := range dataList {
  97. currDateTime, _ := time.ParseInLocation(utils.FormatDate, tmpData.DataTime, time.Local)
  98. dataMap[currDateTime] = tmpData.Value
  99. }
  100. //百分位:对所选指标滚动地取对应时间长度的数据值,取最大值Max,最小值Min,计算Max-Min,百分位=(现值-Min)/(Max-Min),Max=Min时不予计算。
  101. for i, tmpData := range dataList {
  102. currDateTime, _ := time.ParseInLocation(utils.FormatDate, tmpData.DataTime, time.Local)
  103. maxVal := tmpData.Value
  104. minVal := tmpData.Value
  105. for i := 0; i < calculateDay; i++ {
  106. preVal, ok := dataMap[currDateTime.AddDate(0, 0, -i)]
  107. if ok {
  108. if preVal > maxVal {
  109. maxVal = preVal
  110. }
  111. if preVal < minVal {
  112. minVal = preVal
  113. }
  114. }
  115. }
  116. if maxVal == minVal {
  117. continue
  118. }
  119. tmpV := (tmpData.Value) / (maxVal - minVal) * 100
  120. tmpV, _ = decimal.NewFromFloat(tmpV).Round(4).Float64()
  121. //百分位=(现值-Min)/(Max-Min)
  122. newDataList = append(newDataList, data_manage.EdbDataList{
  123. EdbDataId: i,
  124. EdbInfoId: edb.EdbInfoId,
  125. DataTime: dataList[i-1].DataTime,
  126. DataTimestamp: dataList[i-1].DataTimestamp,
  127. Value: tmpV,
  128. })
  129. if tmpV < edbMinVal {
  130. edbMinVal = tmpV
  131. }
  132. if tmpV > edbMaxVal {
  133. edbMaxVal = tmpV
  134. }
  135. }
  136. dataResp = response.LineFeatureDataResp{
  137. MaxData: edbMaxVal,
  138. MinData: edbMinVal,
  139. LatestDate: edb.LatestDate,
  140. EdbInfoCategoryType: edb.EdbInfoCategoryType,
  141. ChartColor: `#00F`,
  142. ChartStyle: `spline`,
  143. PredictChartColor: `#00F`,
  144. ChartType: 0,
  145. ChartWidth: 3,
  146. EdbName: "百分位",
  147. EdbNameEn: "percentile",
  148. Unit: "%",
  149. UnitEn: "%",
  150. IsAxis: 1,
  151. DataList: newDataList,
  152. }
  153. return
  154. }
  155. // GetFrequencyDistributionData 获取频率分布的图表数据
  156. func GetFrequencyDistributionData(chartInfoId int, mappingInfo *data_manage.ChartEdbInfoMapping, dateType, stepVal int, startDate, endDate string) (edbList []*data_manage.ChartEdbInfoMapping, dataResp response.FrequencyDistributionResp, err error, errMsg string) {
  157. //日期类型:1:最近3月;2:最近6月;3:最近1年;4:最近2年;5:最近3年;6:最近5年;7:最近10年,8:自定义时间
  158. startDate, endDate = utils.GetDateByDateType2(dateType, startDate, endDate)
  159. if startDate == `` {
  160. errMsg = "错误的日期"
  161. err = errors.New(errMsg)
  162. return
  163. }
  164. XDataList := make([]float64, 0)
  165. // 频度
  166. Y1DataList := make([]response.FrequencyDistributionYData, 0)
  167. // 累计频率
  168. Y2DataList := make([]response.FrequencyDistributionYData, 0)
  169. edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
  170. // 指标对应的所有数据
  171. _, edbList, err = data.GetEdbDataMapList(chartInfoId, 1, `公历`, startDate, endDate, []*data_manage.ChartEdbInfoMapping{mappingInfo})
  172. if err != nil {
  173. return
  174. }
  175. if len(edbList) != 1 {
  176. err = errors.New("指标异常")
  177. return
  178. }
  179. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  180. var endDateTime time.Time
  181. if endDate != `` {
  182. endDateTime, _ = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  183. }
  184. edb := edbList[0]
  185. dataList := edb.DataList.([]*data_manage.EdbDataList)
  186. if len(dataList) <= 0 {
  187. return
  188. }
  189. maxVal := dataList[0].Value
  190. minVal := dataList[0].Value
  191. dataValMap := make(map[float64]int)
  192. total := 0 // 数据总量
  193. for _, tmpData := range dataList {
  194. currDateTime, _ := time.ParseInLocation(utils.FormatDate, tmpData.DataTime, time.Local)
  195. if (currDateTime.Equal(startDateTime) || currDateTime.After(startDateTime)) && (endDateTime.IsZero() || currDateTime.Before(endDateTime)) {
  196. if maxVal < tmpData.Value {
  197. maxVal = tmpData.Value
  198. }
  199. if minVal > tmpData.Value {
  200. minVal = tmpData.Value
  201. }
  202. num, ok := dataValMap[tmpData.Value]
  203. if ok {
  204. dataValMap[tmpData.Value] = num + 1
  205. } else {
  206. dataValMap[tmpData.Value] = 1
  207. }
  208. total++
  209. }
  210. }
  211. if total <= 0 {
  212. errMsg = `没有数据`
  213. err = errors.New(errMsg)
  214. return
  215. }
  216. // 最大最小值 向上/下取整
  217. minVal = utils.GetFloorNewNum(minVal, 2)
  218. maxVal = utils.GetCeilNewNum(maxVal, 2)
  219. //间距
  220. spacing, _ := (decimal.NewFromFloat(maxVal).Sub(decimal.NewFromFloat(minVal))).Div(decimal.NewFromInt(int64(stepVal))).Float64()
  221. distributionDataNumMap := make(map[float64]int)
  222. for i := 1; i <= stepVal; i++ {
  223. tmpMinVal, _ := decimal.NewFromFloat(minVal).Add((decimal.NewFromFloat(spacing)).Mul(decimal.NewFromInt(int64(i - 1)))).Float64()
  224. tmpMaxVal, _ := decimal.NewFromFloat(minVal).Add((decimal.NewFromFloat(spacing)).Mul(decimal.NewFromInt(int64(i)))).Float64()
  225. XDataList = append(XDataList, tmpMinVal)
  226. distributionDataNumMap[tmpMinVal] = 0
  227. for tmpVal, num := range dataValMap {
  228. if tmpMinVal <= tmpVal && tmpVal < tmpMaxVal {
  229. distributionDataNumMap[tmpMinVal] += num
  230. }
  231. }
  232. }
  233. tmpNum := 0
  234. for _, tmpMinVal := range XDataList {
  235. // 频率
  236. frequencyYNum := distributionDataNumMap[tmpMinVal]
  237. Y1DataList = append(Y1DataList, response.FrequencyDistributionYData{
  238. X: tmpMinVal,
  239. Y: float64(frequencyYNum),
  240. })
  241. // 累计数
  242. tmpNum += frequencyYNum
  243. // 累计频率
  244. tmpTotalFrequency, _ := decimal.NewFromInt(int64(tmpNum)).Div(decimal.NewFromInt(int64(total))).Mul(decimal.NewFromInt(100)).Round(4).Float64()
  245. Y2DataList = append(Y2DataList, response.FrequencyDistributionYData{
  246. X: tmpMinVal,
  247. Y: tmpTotalFrequency,
  248. })
  249. }
  250. newDataList := []response.FrequencyDistributionData{
  251. {
  252. Name: "频率",
  253. NameEn: "Frequency",
  254. Unit: "",
  255. UnitEn: "",
  256. Value: Y1DataList,
  257. Color: "#00F",
  258. IsAxis: 1,
  259. }, {
  260. Name: "累计频率",
  261. NameEn: "Total Frequency",
  262. Unit: "%",
  263. UnitEn: "%",
  264. Value: Y2DataList,
  265. Color: "#F00",
  266. IsAxis: 0,
  267. },
  268. }
  269. edbList[0].DataList = nil
  270. dataResp = response.FrequencyDistributionResp{
  271. LeftMinValue: minVal,
  272. LeftMaxValue: maxVal,
  273. RightMinValue: 0,
  274. RightMaxValue: 100,
  275. DataList: newDataList,
  276. }
  277. return
  278. }