Procházet zdrojové kódy

feat:新增返回拟合方程图表

Roc před 1 rokem
rodič
revize
2f36e7c305

+ 83 - 40
controllers/chart_common.go

@@ -8,9 +8,11 @@ import (
 	"hongze/hongze_chart_lib/models/data_manage/future_good"
 	"hongze/hongze_chart_lib/models/data_manage/future_good/request"
 	"hongze/hongze_chart_lib/models/data_manage/future_good/response"
+	line_equationReq "hongze/hongze_chart_lib/models/data_manage/line_equation/request"
 	"hongze/hongze_chart_lib/services/data"
 	correlationServ "hongze/hongze_chart_lib/services/data/correlation"
 	future_goodServ "hongze/hongze_chart_lib/services/data/future_good"
+	"hongze/hongze_chart_lib/services/data/line_equation"
 	"hongze/hongze_chart_lib/utils"
 	"strings"
 	"time"
@@ -67,56 +69,34 @@ func (this *ChartController) CommonChartInfoDetailFromUniqueCode() {
 		return
 	}
 
+	//var resp interface{}
+	var isOk bool
+	var msg, errMsg string
 	switch chartInfo.Source {
 	case utils.CHART_SOURCE_DEFAULT:
-		resp, isOk, msg, errMsg := GetChartInfoDetailFromUniqueCode(chartInfo, key)
-		if !isOk {
-			br.Msg = msg
-			br.ErrMsg = errMsg
-			return
-		}
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
+		resp, isOk, msg, errMsg = GetChartInfoDetailFromUniqueCode(chartInfo, key)
 	case utils.CHART_SOURCE_FUTURE_GOOD:
-		resp, isOk, msg, errMsg := GetFutureGoodChartInfoDetailFromUniqueCode(chartInfo, key)
-		if !isOk {
-			br.Msg = msg
-			br.ErrMsg = errMsg
-			return
-		}
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
+		resp, isOk, msg, errMsg = GetFutureGoodChartInfoDetailFromUniqueCode(chartInfo, key)
 	case utils.CHART_SOURCE_FUTURE_GOOD_PROFIT:
-		resp, isOk, msg, errMsg := GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo, key)
-		if !isOk {
-			br.Msg = msg
-			br.ErrMsg = errMsg
-			return
-		}
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
+		resp, isOk, msg, errMsg = GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo, key)
 	case utils.CHART_SOURCE_CORRELATION, utils.CHART_SOURCE_ROLLING_CORRELATION:
-		resp, isOk, msg, errMsg := GetCorrelationChartInfoDetailFromUniqueCode(chartInfo, key)
-		if !isOk {
-			br.Msg = msg
-			br.ErrMsg = errMsg
-			return
-		}
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
+		resp, isOk, msg, errMsg = GetCorrelationChartInfoDetailFromUniqueCode(chartInfo, key)
+	case utils.CHART_SOURCE_LINE_EQUATION:
+		resp, isOk, msg, errMsg = GetLineEquationChartInfoDetailFromUniqueCode(chartInfo, key)
 	default:
 		br.Msg = "错误的图表"
 		br.ErrMsg = "错误的图表"
 		return
 	}
+	if !isOk {
+		br.Msg = msg
+		br.ErrMsg = errMsg
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
 }
 
 // GetFutureGoodChartInfoDetailFromUniqueCode 根据编码获取图表详情
@@ -311,6 +291,69 @@ func GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo *models.ChartInf
 	return
 }
 
+// GetLineEquationChartInfoDetailFromUniqueCode 根据编码获取拟合方程图表详情
+func GetLineEquationChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfo, key string) (resp *models.ChartInfoDetailResp, isOk bool, msg, errMsg string) {
+	resp = new(models.ChartInfoDetailResp)
+
+	//chartInfoId := chartInfo.ChartInfoId
+	if chartInfo.ExtraConfig == `` {
+		msg = "获取失败"
+		errMsg = "获取配置信息失败"
+		return
+	}
+
+	var lineChartInfoConfig line_equationReq.LineChartInfoReq
+	err := json.Unmarshal([]byte(chartInfo.ExtraConfig), &lineChartInfoConfig)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取图表配置信息失败, Err:" + err.Error()
+		return
+	}
+
+	var getAData, getBData, getR2Data bool
+	switch lineChartInfoConfig.Source {
+	case utils.CHART_SOURCE_LINE_EQUATION_ONE:
+		getAData = true
+	case utils.CHART_SOURCE_LINE_EQUATION_TWO:
+		getBData = true
+	case utils.CHART_SOURCE_LINE_EQUATION_THREE:
+		getR2Data = true
+	}
+
+	edbList, dataResp, err, errMsg := line_equation.GetChartEdbData(chartInfo.ChartInfoId, lineChartInfoConfig, getAData, getBData, getR2Data)
+	if err != nil {
+		if errMsg == `` {
+			errMsg = "获取失败"
+		}
+		return
+	}
+
+	var resultResp interface{}
+	switch lineChartInfoConfig.Source {
+	case utils.CHART_SOURCE_LINE_EQUATION_ONE:
+		resultResp = dataResp.AData
+	case utils.CHART_SOURCE_LINE_EQUATION_TWO:
+		resultResp = dataResp.BData
+	case utils.CHART_SOURCE_LINE_EQUATION_THREE:
+		resultResp = dataResp.R2Data
+	}
+
+	//chartInfo.UnitEn = baseEdbInfo.UnitEn
+
+	resp.ChartInfo = chartInfo
+	resp.DataResp = resultResp
+	resp.EdbInfoList = edbList
+
+	// 将数据加入缓存
+	if utils.Re == nil {
+		data, _ := json.Marshal(resp)
+		utils.Rc.Put(key, data, 2*time.Hour)
+	}
+	isOk = true
+
+	return
+}
+
 // FutureGoodChartInfoRefresh
 // @Title 商品价格图表刷新接口
 // @Description 商品价格图表刷新接口

+ 16 - 0
models/chart_edb_mapping.go

@@ -54,3 +54,19 @@ func GetChartEdbMappingByEdbInfoId(edbInfoId int) (item *ChartEdbInfoMapping, er
 	err = o.Raw(sql, edbInfoId).QueryRow(&item)
 	return
 }
+
+// GetChartEdbMappingListByEdbInfoIdList 根据指标id列表获取关联关系
+func GetChartEdbMappingListByEdbInfoIdList(edbIdList []int) (list []*ChartEdbInfoMapping, err error) {
+	num := len(edbIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT edb_info_id,source_name,source,edb_code,edb_name,edb_name_en,frequency,unit,unit_en,start_date,end_date,modify_time,latest_date,latest_value,unique_code,edb_info_type AS edb_info_category_type,max_value,min_value
+             FROM edb_info
+			 WHERE edb_info_id IN(` + utils.GetOrmInReplace(num) + `)
+			ORDER BY FIELD(edb_info_id,` + utils.GetOrmInReplace(num) + `)
+              `
+	_, err = o.Raw(sql, edbIdList, edbIdList).QueryRows(&list)
+	return
+}

+ 31 - 0
models/data_manage/line_equation/request/line_equation.go

@@ -0,0 +1,31 @@
+package request
+
+// LineChartInfoReq 线性拟合图表预览请求数据
+type LineChartInfoReq struct {
+	DateType       int    `description:"日期类型"`
+	StartDate      string `description:"开始日期"`
+	EndDate        string `description:"结束日期"`
+	XEdbInfoIdList []int  `description:"X轴的指标id列表"`
+	YEdbInfoIdList []int  `description:"Y轴的指标id列表"`
+	Source         int    `description:"来源,5:斜率图;6:截距图;7:相关性图"`
+}
+
+type AddChartInfoReq struct {
+	MultipleGraphConfigId int              `description:"统一配置id,有的话就是编辑,没有则是新增"`
+	BatchAddChart         []AddChart       `description:"批量创建图的信息"`
+	ExtraConfig           LineChartInfoReq `description:"图表额外配置信息"`
+}
+
+type AddChart struct {
+	Source          int    `description:"来源,5:斜率图;6:截距图;7:相关性图"`
+	ChartClassifyId int    `description:"分类id"`
+	ChartName       string `description:"图表名称"`
+	LeftMin         string `description:"图表左侧最小值"`
+	LeftMax         string `description:"图表左侧最大值"`
+}
+
+// EditChartEnInfoReq 编辑图表英文信息
+type EditChartEnInfoReq struct {
+	ChartInfoId int    `description:"图表ID"`
+	ChartNameEn string `description:"英文图表名称"`
+}

+ 37 - 0
models/data_manage/line_equation/response/line_equation.go

@@ -0,0 +1,37 @@
+package response
+
+import (
+	"hongze/hongze_admin/models/data_manage"
+	"hongze/hongze_admin/models/data_manage/line_equation/request"
+)
+
+type ChartInfoResp struct {
+	List []ChartDataResp `description:"数据列表"`
+}
+
+// ChartDataResp 图表数据
+type ChartDataResp struct {
+	LatestDate          string  `description:"真实数据的日期"`
+	Name                string  `description:"名称"`
+	NameEn              string  `description:"英文名称"`
+	EdbInfoCategoryType int     `description:"普通数据还是预测数据,0:普通,1:预测"`
+	MaxData             float64 `description:"最大值"`
+	MinData             float64 `description:"最小值"`
+	DataList            []data_manage.EdbDataList
+}
+
+// MultipleGraphConfigDetailResp 配置详情接口返回
+type MultipleGraphConfigDetailResp struct {
+	MultipleGraphConfigId int
+	LineChartInfoConfig   request.LineChartInfoReq
+	EdbInfoList           []*data_manage.ChartEdbInfoMapping
+	ChartMappingList      []MultipleGraphConfigChartMapping `description:"关联图表"`
+}
+type MultipleGraphConfigChartMapping struct {
+	ChartInfoId int `description:"图表id"`
+	Source      int `description:"来源,5:斜率图,6:截距图;7:相关性图;"`
+}
+type MultipleGraphConfigEdbMapping struct {
+	EdbInfoId int `description:"图表id"`
+	Source    int `description:"来源,5:斜率图,6:截距图;7:相关性图;"`
+}

+ 48 - 0
models/handle_data.go

@@ -0,0 +1,48 @@
+package models
+
+import (
+	"hongze/hongze_chart_lib/utils"
+	"time"
+)
+
+// HandleDataByPreviousData 当前日期无值时,用上一个日期的数据补充当前日期的数据
+func HandleDataByPreviousData(edbInfoDataList []*EdbDataList, handleDataMap map[string]float64) (err error) {
+	if len(edbInfoDataList) < 2 {
+		return
+	}
+
+	var startEdbInfoData *EdbDataList
+	for _, v := range edbInfoDataList {
+		handleDataMap[v.DataTime] = v.Value
+
+		// 第一个数据就给过滤了,给后面的试用
+		if startEdbInfoData == nil {
+			startEdbInfoData = v
+			continue
+		}
+
+		// 获取两条数据之间相差的天数
+		startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
+		currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
+		betweenHour := int(currDataTime.Sub(startDataTime).Hours())
+		betweenDay := betweenHour / 24
+
+		// 如果相差一天,那么过滤
+		if betweenDay <= 1 {
+			startEdbInfoData = v
+			continue
+		}
+
+		// 生成对应的值
+		{
+			for i := 1; i < betweenDay; i++ {
+				tmpDataTime := startDataTime.AddDate(0, 0, i)
+				handleDataMap[tmpDataTime.Format(utils.FormatDate)] = startEdbInfoData.Value
+			}
+		}
+
+		startEdbInfoData = v
+	}
+
+	return
+}

+ 6 - 0
services/data/chart_info.go

@@ -268,6 +268,12 @@ func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate st
 	return
 }
 
+// GetEdbDataMapList 获取指标最后的基础数据
+func GetEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
+	edbDataListMap, edbList, err = getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList)
+	return
+}
+
 // getEdbDataMapList 获取指标最后的基础数据
 func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
 	// 指标对应的所有数据

+ 329 - 0
services/data/line_equation/chart_info.go

@@ -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
+}
+
+// GetChartEdbData 获取图表数据
+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
+		}
+
+		// 时间截面规则:按照什么频率来取不同的截面的问题。原则是:按照X轴和Y轴所选择的第一个指标(X和Y分别有一个第一个指标),两个指标中,以低频的那个作为基准。如果X轴和Y轴是同频的,那以Y轴第一个指标的为准。
+		frequencyIntMap := map[string]int{
+			"日度": 1,
+			"周度": 2,
+			"旬度": 3,
+			"月度": 4,
+			"季度": 5,
+			"年度": 6,
+		}
+		// 如果x是高频 或者 x与y是同频的,那么就是Y轴的第一个指标为主
+		if frequencyIntMap[xEdbInfo.Frequency] <= frequencyIntMap[yEdbInfo.Frequency] {
+			baseEdbInfo = yEdbInfo
+		} else {
+			// 否则是X轴的第一个指标是低频
+			baseEdbInfo = xEdbInfo
+		}
+	}
+
+	// 指标对应的所有数据
+	chartType := 1 //1:普通图,2:季节性图
+	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)
+	}
+
+	// 数据整理
+	// [日期][A指标id:值,B指标id:值]
+	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
+		// 只有存在两个坐标点的时候,才能去计算线性方程和R平方
+		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
+					}
+				}
+			}
+
+			// 计算R平方
+			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
+}
+
+// getConfigData 获取配置数据
+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 = strconv.Itoa(time.Now().Year()) + "-01-01"
+		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
+}
+
+// handleData 数据处理
+func handleData(baseEdbInfoId int, edbDataListMap map[int][]*models.EdbDataList) (dateEdbMap map[string]map[int]float64, err error) {
+	dateEdbMap = make(map[string]map[int]float64) // [日期][A指标id:值,B指标id:值]
+	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
+}

+ 12 - 0
utils/constants.go

@@ -140,6 +140,7 @@ const (
 	CHART_SOURCE_CORRELATION         = 3 // 相关性图表
 	CHART_SOURCE_ROLLING_CORRELATION = 4 // 滚动相关性图表
 	CHART_SOURCE_FUTURE_GOOD_PROFIT  = 5 // 商品利润曲线
+	CHART_SOURCE_LINE_EQUATION       = 6 // 拟合方程图表
 )
 
 // 图表样式类型
@@ -149,6 +150,17 @@ const (
 	CHART_TYPE_SECTION_SCATTER = 10 //截面散点图样式
 )
 
+// 图表类型
+const (
+	CHART_MULTIPLE_GRAPH_CURVE                   = 1 // 曲线图
+	CHART_MULTIPLE_GRAPH_CORRELATION             = 2 // 相关性图
+	CHART_MULTIPLE_GRAPH_ROLLING_CORRELATION_ONE = 3 // 滚动相关性图1
+	CHART_MULTIPLE_GRAPH_ROLLING_CORRELATION_TWO = 4 // 滚动相关性图2
+	CHART_SOURCE_LINE_EQUATION_ONE               = 5 // 拟合方程-斜率图
+	CHART_SOURCE_LINE_EQUATION_TWO               = 6 // 拟合方程-截距图
+	CHART_SOURCE_LINE_EQUATION_THREE             = 7 // 拟合方程-相关性图
+)
+
 // FrequencyDaysMap 频度日期的map关系
 var FrequencyDaysMap = map[string]int{
 	"天": 1, "周": 7, "月": 30, "季": 90, "年": 365,