|
@@ -58,7 +58,7 @@ func ResidualAnalysisPreview(req residual_analysis_model.ResidualAnalysisReq) (r
|
|
// 原始图表信息
|
|
// 原始图表信息
|
|
originalEdbList := make([]residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, 0)
|
|
originalEdbList := make([]residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, 0)
|
|
|
|
|
|
- originalEdbList, err = fillOriginalChart(req, mappingList, startDate, endDate, edbInfoMappingA, edbInfoMappingB, originalEdbList)
|
|
|
|
|
|
+ originalEdbList, fullADataList, fullBDataList, err := fillOriginalChart(req, mappingList, startDate, endDate, edbInfoMappingA, edbInfoMappingB, originalEdbList)
|
|
if err != nil {
|
|
if err != nil {
|
|
return residual_analysis_model.ResidualAnalysisResp{}, err
|
|
return residual_analysis_model.ResidualAnalysisResp{}, err
|
|
}
|
|
}
|
|
@@ -84,7 +84,7 @@ func ResidualAnalysisPreview(req residual_analysis_model.ResidualAnalysisReq) (r
|
|
}
|
|
}
|
|
|
|
|
|
// 映射图表信息
|
|
// 映射图表信息
|
|
- mappingEdbList, a, b, r, err := fillMappingChartInfo(req, edbInfoMappingA, edbInfoMappingB, originalEdbList, indexADataMap)
|
|
|
|
|
|
+ mappingEdbList, a, b, r, err := fillMappingChartInfo(req, edbInfoMappingA, edbInfoMappingB, originalEdbList, indexADataMap, startDate, endDate, fullADataList, fullBDataList)
|
|
if err != nil {
|
|
if err != nil {
|
|
return residual_analysis_model.ResidualAnalysisResp{}, err
|
|
return residual_analysis_model.ResidualAnalysisResp{}, err
|
|
}
|
|
}
|
|
@@ -246,7 +246,7 @@ func fillResidualChartInfo(req residual_analysis_model.ResidualAnalysisReq, edbI
|
|
return mappingEdb, R2, nil
|
|
return mappingEdb, R2, nil
|
|
}
|
|
}
|
|
|
|
|
|
-func fillMappingChartInfo(req residual_analysis_model.ResidualAnalysisReq, edbInfoMappingA *data_manage.ChartEdbInfoMapping, edbInfoMappingB *data_manage.ChartEdbInfoMapping, originalEdbList []residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, indexADataMap map[string]*data_manage.EdbDataList) ([]residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, float64, float64, float64, error) {
|
|
|
|
|
|
+func fillMappingChartInfo(req residual_analysis_model.ResidualAnalysisReq, edbInfoMappingA *data_manage.ChartEdbInfoMapping, edbInfoMappingB *data_manage.ChartEdbInfoMapping, originalEdbList []residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, indexADataMap map[string]*data_manage.EdbDataList, startDate string, endDate string, fullADataList []*data_manage.EdbDataList, fullBDataList []*data_manage.EdbDataList) ([]residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, float64, float64, float64, error) {
|
|
// 计算公式:Y=aX+b,Y为映射后的指标,X为自变量指标
|
|
// 计算公式:Y=aX+b,Y为映射后的指标,X为自变量指标
|
|
// 正序:a=(L2-L1)/(R2-R1) b=L2-R2*a
|
|
// 正序:a=(L2-L1)/(R2-R1) b=L2-R2*a
|
|
// 逆序:a=(L2-L1)/(R1-R2) b=L2-R1*a
|
|
// 逆序:a=(L2-L1)/(R1-R2) b=L2-R1*a
|
|
@@ -264,28 +264,12 @@ func fillMappingChartInfo(req residual_analysis_model.ResidualAnalysisReq, edbIn
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ //dataAList := edbInfoMappingA.DataList.([]*data_manage.EdbDataList)
|
|
dataList, ok := edbInfoMappingB.DataList.([]*data_manage.EdbDataList)
|
|
dataList, ok := edbInfoMappingB.DataList.([]*data_manage.EdbDataList)
|
|
if !ok {
|
|
if !ok {
|
|
return nil, a, b, r, fmt.Errorf("数据类型转换失败")
|
|
return nil, a, b, r, fmt.Errorf("数据类型转换失败")
|
|
}
|
|
}
|
|
|
|
|
|
- // 拟合残差 计算a,b
|
|
|
|
- var coordinateList []utils.Coordinate
|
|
|
|
- if req.ResidualType == 2 {
|
|
|
|
- for _, indexData := range dataList {
|
|
|
|
- if _, ok := indexADataMap[indexData.DataTime]; ok {
|
|
|
|
-
|
|
|
|
- coordinate := utils.Coordinate{
|
|
|
|
- X: indexData.Value,
|
|
|
|
- Y: indexADataMap[indexData.DataTime].Value,
|
|
|
|
- }
|
|
|
|
- coordinateList = append(coordinateList, coordinate)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- a, b = utils.GetLinearResult(coordinateList)
|
|
|
|
- r = utils.CalculationDecisive(coordinateList)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
// 指标B数据补充
|
|
// 指标B数据补充
|
|
// 新建一个切片来保存补充的数据
|
|
// 新建一个切片来保存补充的数据
|
|
var replenishDataList []*data_manage.EdbDataList
|
|
var replenishDataList []*data_manage.EdbDataList
|
|
@@ -317,12 +301,109 @@ func fillMappingChartInfo(req residual_analysis_model.ResidualAnalysisReq, edbIn
|
|
// 将补充数据插入原始数据列表
|
|
// 将补充数据插入原始数据列表
|
|
dataList = append(dataList, replenishDataList...)
|
|
dataList = append(dataList, replenishDataList...)
|
|
|
|
|
|
- // 填充映射指标值 使得时间长度一致
|
|
|
|
- dataList = FillDataBList(dataList, edbInfoMappingA)
|
|
|
|
-
|
|
|
|
// 排序
|
|
// 排序
|
|
sort.Sort(ByDataTime(dataList))
|
|
sort.Sort(ByDataTime(dataList))
|
|
|
|
|
|
|
|
+ // 拟合残差 计算a,b
|
|
|
|
+ var coordinateList []utils.Coordinate
|
|
|
|
+ var replenishADataList []*data_manage.EdbDataList
|
|
|
|
+ var replenishBDataList []*data_manage.EdbDataList
|
|
|
|
+ if req.ResidualType == 2 {
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ // 因变量指标也转换为日度
|
|
|
|
+ for index := 0; index < len(fullADataList)-1; index++ {
|
|
|
|
+ // 获取当前数据和下一个数据
|
|
|
|
+ beforeIndexData := fullADataList[index]
|
|
|
|
+ afterIndexData := fullADataList[index+1]
|
|
|
|
+
|
|
|
|
+ replenishADataList = append(replenishADataList, beforeIndexData)
|
|
|
|
+ // 从最早时间开始,补充时间为自然日
|
|
|
|
+ if utils.IsMoreThanOneDay(beforeIndexData.DataTime, afterIndexData.DataTime) {
|
|
|
|
+ for {
|
|
|
|
+ // 创建补充数据
|
|
|
|
+ nextDay := utils.GetNextDay(beforeIndexData.DataTime)
|
|
|
|
+ toTime := utils.StringToTime(nextDay)
|
|
|
|
+ replenishIndexData := data_manage.EdbDataList{
|
|
|
|
+ DataTime: nextDay, // 计算下一个自然日
|
|
|
|
+ DataTimestamp: toTime.UnixMilli(),
|
|
|
|
+ Value: beforeIndexData.Value, // 可以选择使用前一天的值,或者其他逻辑来计算值
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 将补充数据加入补充数据列表
|
|
|
|
+ replenishADataList = append(replenishADataList, &replenishIndexData)
|
|
|
|
+
|
|
|
|
+ // 更新 beforeIndexData 为新创建的补充数据
|
|
|
|
+ beforeIndexData = &replenishIndexData
|
|
|
|
+
|
|
|
|
+ // 检查是否还需要继续补充数据
|
|
|
|
+ if !utils.IsMoreThanOneDay(beforeIndexData.DataTime, afterIndexData.DataTime) {
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ replenishADataList = append(replenishADataList, fullADataList[len(fullADataList)-1])
|
|
|
|
+
|
|
|
|
+ // 自变量指标也转换为日度
|
|
|
|
+ for index := 0; index < len(fullBDataList)-1; index++ {
|
|
|
|
+ // 获取当前数据和下一个数据
|
|
|
|
+ beforeIndexData := fullBDataList[index]
|
|
|
|
+ afterIndexData := fullBDataList[index+1]
|
|
|
|
+
|
|
|
|
+ replenishBDataList = append(replenishBDataList, beforeIndexData)
|
|
|
|
+ // 从最早时间开始,补充时间为自然日
|
|
|
|
+ if utils.IsMoreThanOneDay(beforeIndexData.DataTime, afterIndexData.DataTime) {
|
|
|
|
+ for {
|
|
|
|
+ // 创建补充数据
|
|
|
|
+ nextDay := utils.GetNextDay(beforeIndexData.DataTime)
|
|
|
|
+ toTime := utils.StringToTime(nextDay)
|
|
|
|
+ replenishIndexData := data_manage.EdbDataList{
|
|
|
|
+ DataTime: nextDay, // 计算下一个自然日
|
|
|
|
+ DataTimestamp: toTime.UnixMilli(),
|
|
|
|
+ Value: beforeIndexData.Value, // 可以选择使用前一天的值,或者其他逻辑来计算值
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 将补充数据加入补充数据列表
|
|
|
|
+ replenishBDataList = append(replenishBDataList, &replenishIndexData)
|
|
|
|
+
|
|
|
|
+ // 更新 beforeIndexData 为新创建的补充数据
|
|
|
|
+ beforeIndexData = &replenishIndexData
|
|
|
|
+
|
|
|
|
+ // 检查是否还需要继续补充数据
|
|
|
|
+ if !utils.IsMoreThanOneDay(beforeIndexData.DataTime, afterIndexData.DataTime) {
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ replenishBDataList = append(replenishBDataList, fullBDataList[len(fullBDataList)-1])
|
|
|
|
+
|
|
|
|
+ // replenishADataList --> map
|
|
|
|
+ replenishADataMap := make(map[string]*data_manage.EdbDataList)
|
|
|
|
+ for _, indexData := range replenishADataList {
|
|
|
|
+ if (utils.StringToTime(indexData.DataTime).After(utils.StringToTime(startDate)) || utils.StringToTime(indexData.DataTime).Equal(utils.StringToTime(startDate))) && (endDate == "" || utils.StringToTime(indexData.DataTime).Before(utils.StringToTime(endDate))) {
|
|
|
|
+ replenishADataMap[indexData.DataTime] = indexData
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, indexData := range replenishBDataList {
|
|
|
|
+ if _, ok = replenishADataMap[indexData.DataTime]; ok {
|
|
|
|
+
|
|
|
|
+ coordinate := utils.Coordinate{
|
|
|
|
+ X: indexData.Value,
|
|
|
|
+ Y: replenishADataMap[indexData.DataTime].Value,
|
|
|
|
+ }
|
|
|
|
+ coordinateList = append(coordinateList, coordinate)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ a, b = utils.GetLinearResult(coordinateList)
|
|
|
|
+ r = utils.ComputeCorrelation(coordinateList)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 填充映射指标值 使得时间长度一致
|
|
|
|
+ dataList = FillDataBList(dataList, edbInfoMappingA)
|
|
|
|
+
|
|
// 根据指标A的时间key,在B的映射指标中筛选出对应的值
|
|
// 根据指标A的时间key,在B的映射指标中筛选出对应的值
|
|
var dataBList []*data_manage.EdbDataList
|
|
var dataBList []*data_manage.EdbDataList
|
|
|
|
|
|
@@ -417,7 +498,9 @@ func (a ByDataTime) Less(i, j int) bool {
|
|
return t1.Before(t2)
|
|
return t1.Before(t2)
|
|
}
|
|
}
|
|
|
|
|
|
-func fillOriginalChart(req residual_analysis_model.ResidualAnalysisReq, mappingList []*data_manage.ChartEdbInfoMapping, startDate string, endDate string, edbInfoMappingA *data_manage.ChartEdbInfoMapping, edbInfoMappingB *data_manage.ChartEdbInfoMapping, originalEdbList []residual_analysis_model.ResidualAnalysisChartEdbInfoMapping) ([]residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, error) {
|
|
|
|
|
|
+func fillOriginalChart(req residual_analysis_model.ResidualAnalysisReq, mappingList []*data_manage.ChartEdbInfoMapping, startDate string, endDate string, edbInfoMappingA *data_manage.ChartEdbInfoMapping, edbInfoMappingB *data_manage.ChartEdbInfoMapping, originalEdbList []residual_analysis_model.ResidualAnalysisChartEdbInfoMapping) ([]residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, []*data_manage.EdbDataList, []*data_manage.EdbDataList, error) {
|
|
|
|
+
|
|
|
|
+ var fullADataList, fullBDataList []*data_manage.EdbDataList
|
|
for _, v := range mappingList {
|
|
for _, v := range mappingList {
|
|
var edbInfoMapping residual_analysis_model.ResidualAnalysisChartEdbInfoMapping
|
|
var edbInfoMapping residual_analysis_model.ResidualAnalysisChartEdbInfoMapping
|
|
edbInfoMapping.EdbInfoType = 1
|
|
edbInfoMapping.EdbInfoType = 1
|
|
@@ -430,7 +513,12 @@ func fillOriginalChart(req residual_analysis_model.ResidualAnalysisReq, mappingL
|
|
// 获取图表中的指标数据
|
|
// 获取图表中的指标数据
|
|
dataList, err := data_manage.GetEdbDataList(v.Source, v.SubSource, v.EdbInfoId, startDate, endDate)
|
|
dataList, err := data_manage.GetEdbDataList(v.Source, v.SubSource, v.EdbInfoId, startDate, endDate)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return nil, fmt.Errorf("获取指标数据失败,Err:%s", err.Error())
|
|
|
|
|
|
+ return nil, nil, nil, fmt.Errorf("获取指标数据失败,Err:%s", err.Error())
|
|
|
|
+ }
|
|
|
|
+ // 重新获取指标数据 产品要求需要和计算指标-拟合残差逻辑保持一致
|
|
|
|
+ fullDataList, err := data_manage.GetEdbDataList(v.Source, v.SubSource, v.EdbInfoId, "", "")
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, nil, nil, fmt.Errorf("获取指标数据失败,Err:%s", err.Error())
|
|
}
|
|
}
|
|
|
|
|
|
if v.EdbInfoId == req.EdbInfoIdB {
|
|
if v.EdbInfoId == req.EdbInfoIdB {
|
|
@@ -445,7 +533,7 @@ func fillOriginalChart(req residual_analysis_model.ResidualAnalysisReq, mappingL
|
|
// 领先指标 dataList进行数据处理
|
|
// 领先指标 dataList进行数据处理
|
|
if req.IndexType == 2 {
|
|
if req.IndexType == 2 {
|
|
if req.LeadValue < 0 {
|
|
if req.LeadValue < 0 {
|
|
- return nil, fmt.Errorf("领先值不能小于0")
|
|
|
|
|
|
+ return nil, nil, nil, fmt.Errorf("领先值不能小于0")
|
|
} else if req.LeadValue > 0 {
|
|
} else if req.LeadValue > 0 {
|
|
edbInfoMapping.EdbName = v.EdbName + "(领先" + strconv.Itoa(req.LeadValue) + req.LeadFrequency + ")"
|
|
edbInfoMapping.EdbName = v.EdbName + "(领先" + strconv.Itoa(req.LeadValue) + req.LeadFrequency + ")"
|
|
for _, indexData := range dataList {
|
|
for _, indexData := range dataList {
|
|
@@ -467,8 +555,10 @@ func fillOriginalChart(req residual_analysis_model.ResidualAnalysisReq, mappingL
|
|
}
|
|
}
|
|
|
|
|
|
edbInfoMappingB.DataList = dataList
|
|
edbInfoMappingB.DataList = dataList
|
|
|
|
+ fullBDataList = fullDataList
|
|
} else {
|
|
} else {
|
|
edbInfoMappingA.DataList = dataList
|
|
edbInfoMappingA.DataList = dataList
|
|
|
|
+ fullADataList = fullDataList
|
|
}
|
|
}
|
|
edbInfoMapping.EdbInfoId = v.EdbInfoId
|
|
edbInfoMapping.EdbInfoId = v.EdbInfoId
|
|
edbInfoMapping.EdbCode = v.EdbCode
|
|
edbInfoMapping.EdbCode = v.EdbCode
|
|
@@ -484,7 +574,7 @@ func fillOriginalChart(req residual_analysis_model.ResidualAnalysisReq, mappingL
|
|
edbInfoMapping.DataList = dataList
|
|
edbInfoMapping.DataList = dataList
|
|
originalEdbList = append(originalEdbList, edbInfoMapping)
|
|
originalEdbList = append(originalEdbList, edbInfoMapping)
|
|
}
|
|
}
|
|
- return originalEdbList, nil
|
|
|
|
|
|
+ return originalEdbList, fullADataList, fullBDataList, nil
|
|
}
|
|
}
|
|
|
|
|
|
func ContrastPreview(indexCode string) (residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, error) {
|
|
func ContrastPreview(indexCode string) (residual_analysis_model.ResidualAnalysisChartEdbInfoMapping, error) {
|