|
@@ -0,0 +1,329 @@
|
|
|
+package line_equation
|
|
|
+
|
|
|
+import (
|
|
|
+ "errors"
|
|
|
+ "hongze/hongze_chart_lib/models"
|
|
|
+ "hongze/hongze_chart_lib/models/data_manage/line_equation/request"
|
|
|
+ "hongze/hongze_chart_lib/services/data"
|
|
|
+ "hongze/hongze_chart_lib/utils"
|
|
|
+ "math"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+type LineEquationResp struct {
|
|
|
+ AData LineEquationDataResp
|
|
|
+ BData LineEquationDataResp
|
|
|
+ R2Data LineEquationDataResp
|
|
|
+}
|
|
|
+
|
|
|
+type LineEquationDataResp struct {
|
|
|
+ MaxData float64
|
|
|
+ MinData float64
|
|
|
+ LatestDate string `description:"真实数据的最后日期"`
|
|
|
+ EdbInfoCategoryType int
|
|
|
+ ChartColor string
|
|
|
+ ChartStyle string
|
|
|
+ PredictChartColor string
|
|
|
+ ChartType int
|
|
|
+ ChartWidth int
|
|
|
+ EdbName string
|
|
|
+ EdbNameEn string
|
|
|
+ IsAxis int
|
|
|
+ DataList []models.EdbDataList
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func GetChartEdbData(chartInfoId int, lineChartInfoConfig request.LineChartInfoReq, getAData, getBData, getR2Data bool) (edbList []*models.ChartEdbInfoMapping, dataResp LineEquationResp, err error, errMsg string) {
|
|
|
+
|
|
|
+ mappingList, startDate, endDate, err, errMsg := getConfigData(lineChartInfoConfig)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ xEdbInfoIdList := lineChartInfoConfig.XEdbInfoIdList
|
|
|
+ yEdbInfoIdList := lineChartInfoConfig.YEdbInfoIdList
|
|
|
+
|
|
|
+ aLineEquationDataResp := LineEquationDataResp{
|
|
|
+ DataList: make([]models.EdbDataList, 0),
|
|
|
+ MaxData: 0,
|
|
|
+ MinData: 0,
|
|
|
+ ChartColor: "#00f",
|
|
|
+ ChartStyle: `spline`,
|
|
|
+ PredictChartColor: `#00f`,
|
|
|
+ ChartType: 0,
|
|
|
+ ChartWidth: 3,
|
|
|
+ EdbName: `弹性系数`,
|
|
|
+ EdbNameEn: `elastic coefficient`,
|
|
|
+ IsAxis: 1,
|
|
|
+ }
|
|
|
+ bLineEquationDataResp := LineEquationDataResp{
|
|
|
+ DataList: make([]models.EdbDataList, 0),
|
|
|
+ MaxData: 0,
|
|
|
+ MinData: 0,
|
|
|
+ ChartColor: "#00f",
|
|
|
+ ChartStyle: `spline`,
|
|
|
+ PredictChartColor: `#00f`,
|
|
|
+ ChartType: 0,
|
|
|
+ ChartWidth: 3,
|
|
|
+ EdbName: `截距`,
|
|
|
+ EdbNameEn: `intercept`,
|
|
|
+ IsAxis: 1,
|
|
|
+ }
|
|
|
+ r2LineEquationDataResp := LineEquationDataResp{
|
|
|
+ DataList: make([]models.EdbDataList, 0),
|
|
|
+ MaxData: 0,
|
|
|
+ MinData: 0,
|
|
|
+ ChartColor: "#00f",
|
|
|
+ ChartStyle: `spline`,
|
|
|
+ PredictChartColor: `#00f`,
|
|
|
+ ChartType: 0,
|
|
|
+ ChartWidth: 3,
|
|
|
+ EdbName: `相关系数`,
|
|
|
+ EdbNameEn: `coefficient of association`,
|
|
|
+ IsAxis: 1,
|
|
|
+ }
|
|
|
+ edbList = make([]*models.ChartEdbInfoMapping, 0)
|
|
|
+ dataResp = LineEquationResp{
|
|
|
+ AData: aLineEquationDataResp,
|
|
|
+ BData: bLineEquationDataResp,
|
|
|
+ R2Data: r2LineEquationDataResp,
|
|
|
+ }
|
|
|
+
|
|
|
+ var baseEdbInfo *models.ChartEdbInfoMapping
|
|
|
+
|
|
|
+ {
|
|
|
+ var xEdbInfo, yEdbInfo *models.ChartEdbInfoMapping
|
|
|
+ for _, v := range mappingList {
|
|
|
+ if v.EdbInfoId == xEdbInfoIdList[0] {
|
|
|
+ xEdbInfo = v
|
|
|
+ } else if v.EdbInfoId == yEdbInfoIdList[0] {
|
|
|
+ yEdbInfo = v
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if xEdbInfo == nil {
|
|
|
+ errMsg = `X轴第一个指标异常`
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if yEdbInfo == nil {
|
|
|
+ errMsg = `Y轴第一个指标异常`
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ frequencyIntMap := map[string]int{
|
|
|
+ "日度": 1,
|
|
|
+ "周度": 2,
|
|
|
+ "旬度": 3,
|
|
|
+ "月度": 4,
|
|
|
+ "季度": 5,
|
|
|
+ "年度": 6,
|
|
|
+ }
|
|
|
+
|
|
|
+ if frequencyIntMap[xEdbInfo.Frequency] <= frequencyIntMap[yEdbInfo.Frequency] {
|
|
|
+ baseEdbInfo = yEdbInfo
|
|
|
+ } else {
|
|
|
+
|
|
|
+ baseEdbInfo = xEdbInfo
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ chartType := 1
|
|
|
+ calendar := "农历"
|
|
|
+ edbDataListMap, edbList, err := data.GetEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ dateList := make([]string, 0)
|
|
|
+ for _, v := range edbDataListMap[baseEdbInfo.EdbInfoId] {
|
|
|
+ dateList = append(dateList, v.DataTime)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ dateEdbMap, err := handleData(baseEdbInfo.EdbInfoId, edbDataListMap)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ lenX := len(xEdbInfoIdList)
|
|
|
+
|
|
|
+ for i, date := range dateList {
|
|
|
+ coordinateData := make([]utils.Coordinate, 0)
|
|
|
+ for k := 0; k < lenX; k++ {
|
|
|
+ xVal, ok1 := dateEdbMap[date][xEdbInfoIdList[k]]
|
|
|
+ yVal, ok2 := dateEdbMap[date][yEdbInfoIdList[k]]
|
|
|
+ if !ok1 || !ok2 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ tmpCoordinate1 := utils.Coordinate{
|
|
|
+ X: xVal,
|
|
|
+ Y: yVal,
|
|
|
+ }
|
|
|
+ coordinateData = append(coordinateData, tmpCoordinate1)
|
|
|
+ }
|
|
|
+ dataTime, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
|
|
|
+ timestamp := dataTime.UnixNano() / 1e6
|
|
|
+
|
|
|
+ if len(coordinateData) >= 2 {
|
|
|
+ a, b := utils.GetLinearResult(coordinateData)
|
|
|
+ if !math.IsNaN(a) && !math.IsNaN(b) && !math.IsInf(a, 0) && !math.IsInf(b, 0) {
|
|
|
+ if getAData {
|
|
|
+ dataResp.AData.DataList = append(dataResp.AData.DataList, models.EdbDataList{
|
|
|
+ EdbDataId: i,
|
|
|
+ EdbInfoId: 0,
|
|
|
+ DataTime: date,
|
|
|
+ DataTimestamp: timestamp,
|
|
|
+ Value: a,
|
|
|
+ })
|
|
|
+ if dataResp.AData.MinData > a {
|
|
|
+ dataResp.AData.MinData = a
|
|
|
+ }
|
|
|
+ if dataResp.AData.MaxData < a {
|
|
|
+ dataResp.AData.MaxData = a
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if getBData {
|
|
|
+ dataResp.BData.DataList = append(dataResp.BData.DataList, models.EdbDataList{
|
|
|
+ EdbDataId: i,
|
|
|
+ EdbInfoId: 0,
|
|
|
+ DataTime: date,
|
|
|
+ DataTimestamp: timestamp,
|
|
|
+ Value: b,
|
|
|
+ })
|
|
|
+ if dataResp.BData.MinData > a {
|
|
|
+ dataResp.BData.MinData = a
|
|
|
+ }
|
|
|
+ if dataResp.BData.MaxData < a {
|
|
|
+ dataResp.BData.MaxData = a
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if getR2Data {
|
|
|
+ tmpVal := utils.CalculationDecisive(coordinateData)
|
|
|
+ if math.IsNaN(tmpVal) || math.IsInf(tmpVal, 0) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ dataResp.R2Data.DataList = append(dataResp.R2Data.DataList, models.EdbDataList{
|
|
|
+ EdbDataId: i,
|
|
|
+ EdbInfoId: 0,
|
|
|
+ DataTime: date,
|
|
|
+ DataTimestamp: timestamp,
|
|
|
+ Value: tmpVal,
|
|
|
+ })
|
|
|
+ if dataResp.R2Data.MinData > tmpVal {
|
|
|
+ dataResp.R2Data.MinData = tmpVal
|
|
|
+ }
|
|
|
+ if dataResp.R2Data.MaxData < tmpVal {
|
|
|
+ dataResp.R2Data.MaxData = tmpVal
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dataResp.AData.LatestDate = baseEdbInfo.LatestDate
|
|
|
+ dataResp.AData.EdbInfoCategoryType = baseEdbInfo.EdbInfoCategoryType
|
|
|
+ dataResp.BData.LatestDate = baseEdbInfo.LatestDate
|
|
|
+ dataResp.BData.EdbInfoCategoryType = baseEdbInfo.EdbInfoCategoryType
|
|
|
+ dataResp.R2Data.LatestDate = baseEdbInfo.LatestDate
|
|
|
+ dataResp.R2Data.EdbInfoCategoryType = baseEdbInfo.EdbInfoCategoryType
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func getConfigData(lineChartInfoConfig request.LineChartInfoReq) (mappingList []*models.ChartEdbInfoMapping, startDate, endDate string, err error, errMsg string) {
|
|
|
+ dateType := lineChartInfoConfig.DateType
|
|
|
+ switch dateType {
|
|
|
+ case 1:
|
|
|
+ startDate = "2000-01-01"
|
|
|
+ case 2:
|
|
|
+ startDate = "2010-01-01"
|
|
|
+ case 3:
|
|
|
+ startDate = "2015-01-01"
|
|
|
+ case 4:
|
|
|
+
|
|
|
+ startDate = "2021-01-01"
|
|
|
+ case 5:
|
|
|
+ startDate = lineChartInfoConfig.StartDate + "-01"
|
|
|
+ endDate = lineChartInfoConfig.EndDate + "-01"
|
|
|
+ case 6:
|
|
|
+ startDate = lineChartInfoConfig.StartDate + "-01"
|
|
|
+ case 7:
|
|
|
+ startDate = "2018-01-01"
|
|
|
+ case 8:
|
|
|
+ startDate = "2019-01-01"
|
|
|
+ case 9:
|
|
|
+ startDate = "2020-01-01"
|
|
|
+ case 11:
|
|
|
+ startDate = "2022-01-01"
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ edbInfoIdList := make([]int, 0)
|
|
|
+ {
|
|
|
+ edbInfoIdMap := make(map[int]int, 0)
|
|
|
+ for _, edbInfoId := range lineChartInfoConfig.XEdbInfoIdList {
|
|
|
+ edbInfoIdMap[edbInfoId] = edbInfoId
|
|
|
+ }
|
|
|
+ for _, edbInfoId := range lineChartInfoConfig.YEdbInfoIdList {
|
|
|
+ edbInfoIdMap[edbInfoId] = edbInfoId
|
|
|
+ }
|
|
|
+ for _, edbInfoId := range edbInfoIdMap {
|
|
|
+ edbInfoIdList = append(edbInfoIdList, edbInfoId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mappingList, err = models.GetChartEdbMappingListByEdbInfoIdList(edbInfoIdList)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = `获取失败`
|
|
|
+ err = errors.New("获取图表,指标信息失败,Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func handleData(baseEdbInfoId int, edbDataListMap map[int][]*models.EdbDataList) (dateEdbMap map[string]map[int]float64, err error) {
|
|
|
+ dateEdbMap = make(map[string]map[int]float64)
|
|
|
+ for edbInfoId, edbDataList := range edbDataListMap {
|
|
|
+ if edbInfoId != baseEdbInfoId {
|
|
|
+
|
|
|
+ handleDataMap := make(map[string]float64)
|
|
|
+ err = models.HandleDataByPreviousData(edbDataList, handleDataMap)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ for date, val := range handleDataMap {
|
|
|
+ item, ok := dateEdbMap[date]
|
|
|
+ if ok {
|
|
|
+ item[edbInfoId] = val
|
|
|
+ } else {
|
|
|
+ item = map[int]float64{
|
|
|
+ edbInfoId: val,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dateEdbMap[date] = item
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ for _, edbData := range edbDataList {
|
|
|
+ item, ok := dateEdbMap[edbData.DataTime]
|
|
|
+ if ok {
|
|
|
+ item[edbInfoId] = edbData.Value
|
|
|
+ } else {
|
|
|
+ item = map[int]float64{
|
|
|
+ edbInfoId: edbData.Value,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dateEdbMap[edbData.DataTime] = item
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|