|
@@ -1 +1,1574 @@
|
|
|
package range_analysis
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "eta/eta_api/models/data_manage"
|
|
|
+ "eta/eta_api/models/system"
|
|
|
+ "eta/eta_api/services/alarm_msg"
|
|
|
+ "eta/eta_api/services/data"
|
|
|
+ "eta/eta_api/utils"
|
|
|
+ "fmt"
|
|
|
+ "github.com/shopspring/decimal"
|
|
|
+ "math"
|
|
|
+ "sort"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+// HandleDataByLinearRegression 线性方程插值法补全数据
|
|
|
+func HandleDataByLinearRegression(originList []*data_manage.EdbDataList, handleDataMap map[string]float64) (newList []*data_manage.EdbDataList, err error) {
|
|
|
+ if len(originList) < 2 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var startEdbInfoData *data_manage.EdbDataList
|
|
|
+ for _, v := range originList {
|
|
|
+ handleDataMap[v.DataTime] = v.Value
|
|
|
+
|
|
|
+ // 第一个数据就给过滤了,给后面的试用
|
|
|
+ if startEdbInfoData == nil {
|
|
|
+ startEdbInfoData = v
|
|
|
+ newList = append(newList, &data_manage.EdbDataList{
|
|
|
+ DataTime: v.DataTime,
|
|
|
+ Value: v.Value,
|
|
|
+ })
|
|
|
+ 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
|
|
|
+ newList = append(newList, &data_manage.EdbDataList{
|
|
|
+ DataTime: v.DataTime,
|
|
|
+ Value: v.Value,
|
|
|
+ })
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成线性方程式
|
|
|
+ var a, b float64
|
|
|
+ {
|
|
|
+ coordinateData := make([]utils.Coordinate, 0)
|
|
|
+ tmpCoordinate1 := utils.Coordinate{
|
|
|
+ X: 1,
|
|
|
+ Y: startEdbInfoData.Value,
|
|
|
+ }
|
|
|
+ coordinateData = append(coordinateData, tmpCoordinate1)
|
|
|
+ tmpCoordinate2 := utils.Coordinate{
|
|
|
+ X: float64(betweenDay) + 1,
|
|
|
+ Y: v.Value,
|
|
|
+ }
|
|
|
+ coordinateData = append(coordinateData, tmpCoordinate2)
|
|
|
+
|
|
|
+ a, b = utils.GetLinearResult(coordinateData)
|
|
|
+ if math.IsNaN(a) || math.IsNaN(b) {
|
|
|
+ err = fmt.Errorf("线性方程公式生成失败")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成对应的值
|
|
|
+ {
|
|
|
+ for i := 1; i < betweenDay; i++ {
|
|
|
+ tmpDataTime := startDataTime.AddDate(0, 0, i)
|
|
|
+ aDecimal := decimal.NewFromFloat(a)
|
|
|
+ xDecimal := decimal.NewFromInt(int64(i) + 1)
|
|
|
+ bDecimal := decimal.NewFromFloat(b)
|
|
|
+
|
|
|
+ val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
|
|
|
+ handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
|
|
|
+ newList = append(newList, &data_manage.EdbDataList{
|
|
|
+ DataTime: tmpDataTime.Format(utils.FormatDate),
|
|
|
+ Value: val,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 最后将自己赋值
|
|
|
+ newList = append(newList, &data_manage.EdbDataList{
|
|
|
+ EdbDataId: v.EdbDataId,
|
|
|
+ DataTime: v.DataTime,
|
|
|
+ Value: v.Value,
|
|
|
+ })
|
|
|
+
|
|
|
+ startEdbInfoData = v
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// MoveDataDaysToNewDataList 平移指标数据生成新的数据序列
|
|
|
+func MoveDataDaysToNewDataList(dataList []*data_manage.EdbDataList, moveDay int) (newDataList []data_manage.EdbDataList, dateDataMap map[string]float64) {
|
|
|
+ dateMap := make(map[time.Time]float64)
|
|
|
+ var minDate, maxDate time.Time
|
|
|
+ dateDataMap = make(map[string]float64)
|
|
|
+
|
|
|
+ for _, v := range dataList {
|
|
|
+ currDate, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
|
|
|
+ if minDate.IsZero() || currDate.Before(minDate) {
|
|
|
+ minDate = currDate
|
|
|
+ }
|
|
|
+ if maxDate.IsZero() || currDate.After(maxDate) {
|
|
|
+ maxDate = currDate
|
|
|
+ }
|
|
|
+ dateMap[currDate] = v.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理领先、滞后数据
|
|
|
+ newDateMap := make(map[time.Time]float64)
|
|
|
+ for currDate, value := range dateMap {
|
|
|
+ newDate := currDate.AddDate(0, 0, moveDay)
|
|
|
+ newDateMap[newDate] = value
|
|
|
+ }
|
|
|
+ minDate = minDate.AddDate(0, 0, moveDay)
|
|
|
+ maxDate = maxDate.AddDate(0, 0, moveDay)
|
|
|
+
|
|
|
+ // 获取日期相差日
|
|
|
+ dayNum := utils.GetTimeSubDay(minDate, maxDate)
|
|
|
+
|
|
|
+ for i := 0; i <= dayNum; i++ {
|
|
|
+ currDate := minDate.AddDate(0, 0, i)
|
|
|
+ tmpValue, ok := newDateMap[currDate]
|
|
|
+ if !ok {
|
|
|
+ //找不到数据,那么就用前面的数据吧
|
|
|
+ if len(newDataList)-1 < 0 {
|
|
|
+ tmpValue = 0
|
|
|
+ } else {
|
|
|
+ tmpValue = newDataList[len(newDataList)-1].Value
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tmpData := data_manage.EdbDataList{
|
|
|
+ DataTime: currDate.Format(utils.FormatDate),
|
|
|
+ Value: tmpValue,
|
|
|
+ }
|
|
|
+ dateDataMap[tmpData.DataTime] = tmpData.Value
|
|
|
+ newDataList = append(newDataList, tmpData)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetChartEdbInfoFormat 相关性图表-获取指标信息
|
|
|
+func GetChartEdbInfoFormat(chartInfoId int, edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping) (edbList []*data_manage.ChartEdbInfoMapping, err error) {
|
|
|
+ edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
|
|
|
+ if edbInfoMappingA == nil || edbInfoMappingB == nil {
|
|
|
+ err = fmt.Errorf("指标信息有误")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ edbInfoMappingA.FrequencyEn = data.GetFrequencyEn(edbInfoMappingA.Frequency)
|
|
|
+ if edbInfoMappingA.Unit == `无` {
|
|
|
+ edbInfoMappingA.Unit = ``
|
|
|
+ }
|
|
|
+ if edbInfoMappingB.Unit == `无` {
|
|
|
+ edbInfoMappingB.Unit = ``
|
|
|
+ }
|
|
|
+ if chartInfoId <= 0 {
|
|
|
+ edbInfoMappingA.IsAxis = 1
|
|
|
+ edbInfoMappingA.LeadValue = 0
|
|
|
+ edbInfoMappingA.LeadUnit = ""
|
|
|
+ edbInfoMappingA.ChartEdbMappingId = 0
|
|
|
+ edbInfoMappingA.ChartInfoId = 0
|
|
|
+ edbInfoMappingA.IsOrder = false
|
|
|
+ edbInfoMappingA.EdbInfoType = 1
|
|
|
+ edbInfoMappingA.ChartStyle = ""
|
|
|
+ edbInfoMappingA.ChartColor = ""
|
|
|
+ edbInfoMappingA.ChartWidth = 0
|
|
|
+
|
|
|
+ edbInfoMappingB.IsAxis = 1
|
|
|
+ edbInfoMappingB.LeadValue = 0
|
|
|
+ edbInfoMappingB.LeadUnit = ""
|
|
|
+ edbInfoMappingB.ChartEdbMappingId = 0
|
|
|
+ edbInfoMappingB.ChartInfoId = 0
|
|
|
+ edbInfoMappingB.IsOrder = false
|
|
|
+ edbInfoMappingB.EdbInfoType = 1
|
|
|
+ edbInfoMappingB.ChartStyle = ""
|
|
|
+ edbInfoMappingB.ChartColor = ""
|
|
|
+ edbInfoMappingB.ChartWidth = 0
|
|
|
+ } else {
|
|
|
+ edbInfoMappingA.LeadUnitEn = data.GetLeadUnitEn(edbInfoMappingA.LeadUnit)
|
|
|
+ edbInfoMappingB.LeadUnitEn = data.GetLeadUnitEn(edbInfoMappingB.LeadUnit)
|
|
|
+ }
|
|
|
+ edbList = append(edbList, edbInfoMappingA, edbInfoMappingB)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetChartDataByEdbInfo 相关性图表-根据指标信息获取x轴和y轴
|
|
|
+func GetChartDataByEdbInfo(edbInfoMapping *data_manage.ChartEdbInfoMapping, req data_manage.ChartRangeAnalysisExtraConf) (xEdbIdValue []int, dataResp data_manage.ChartRangeAnalysisDataResp, err error) {
|
|
|
+ // 指标的开始日期和结束日期
|
|
|
+ startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
+ startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
|
|
|
+
|
|
|
+ // 根据时间区间类型来获取数据的计算窗口,然后再拼接成整段数据
|
|
|
+ // 智能划分得到一个开始日期,和结束日期
|
|
|
+ // 手工划分得到多个开始日期和结束日期(已排序)
|
|
|
+ // 跨年划分得到多个开始日期和结束日期
|
|
|
+
|
|
|
+ //// 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
|
|
|
+ //baseEdbInfo := edbInfoMappingB
|
|
|
+ //changeEdbInfo := edbInfoMappingA
|
|
|
+ // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
|
|
|
+ baseEdbInfo := edbInfoMapping
|
|
|
+ changeEdbInfo := edbInfoMappingB
|
|
|
+
|
|
|
+ // 获取时间基准指标在时间区间内的值
|
|
|
+ aDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ switch baseEdbInfo.EdbInfoCategoryType {
|
|
|
+ case 0:
|
|
|
+ aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
|
|
|
+ case 1:
|
|
|
+ _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
|
|
|
+ default:
|
|
|
+ err = errors.New("指标base类型异常")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取变频指标所有日期的值, 插值法完善数据
|
|
|
+ bDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ switch changeEdbInfo.EdbInfoCategoryType {
|
|
|
+ case 0:
|
|
|
+ bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
|
|
|
+ case 1:
|
|
|
+ _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
|
|
|
+ default:
|
|
|
+ err = errors.New("指标change类型异常")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //changeDataMap := make(map[string]float64)
|
|
|
+ //newChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
|
|
|
+ //if e != nil {
|
|
|
+ // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+
|
|
|
+ // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
|
|
|
+ baseDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ baseDataMap := make(map[string]float64)
|
|
|
+ changeDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ changeDataMap := make(map[string]float64)
|
|
|
+
|
|
|
+ // 先把低频指标升频为高频
|
|
|
+ {
|
|
|
+ frequencyIntMap := map[string]int{
|
|
|
+ "日度": 1,
|
|
|
+ "周度": 2,
|
|
|
+ "旬度": 3,
|
|
|
+ "月度": 4,
|
|
|
+ "季度": 5,
|
|
|
+ "年度": 6,
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果A指标是高频,那么就需要对B指标进行升频
|
|
|
+ if frequencyIntMap[edbInfoMappingA.Frequency] < frequencyIntMap[edbInfoMappingB.Frequency] {
|
|
|
+ tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ changeDataList = tmpNewChangeDataList
|
|
|
+ baseDataList = aDataList
|
|
|
+ for _, v := range baseDataList {
|
|
|
+ baseDataMap[v.DataTime] = v.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if frequencyIntMap[edbInfoMappingA.Frequency] > frequencyIntMap[edbInfoMappingB.Frequency] {
|
|
|
+ // 如果B指标是高频,那么就需要对A指标进行升频
|
|
|
+ tmpNewChangeDataList, e := HandleDataByLinearRegression(aDataList, baseDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ baseDataList = tmpNewChangeDataList
|
|
|
+
|
|
|
+ changeDataList = bDataList
|
|
|
+ for _, v := range changeDataList {
|
|
|
+ changeDataMap[v.DataTime] = v.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ baseDataList = aDataList
|
|
|
+ for _, v := range baseDataList {
|
|
|
+ baseDataMap[v.DataTime] = v.Value
|
|
|
+ }
|
|
|
+ changeDataList = bDataList
|
|
|
+ for _, v := range changeDataList {
|
|
|
+ changeDataMap[v.DataTime] = v.Value
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算不领先也不滞后时的相关系数
|
|
|
+ baseCalculateData := make([]float64, 0)
|
|
|
+ baseDataTimeArr := make([]string, 0)
|
|
|
+ for i := range baseDataList {
|
|
|
+ baseDataTimeArr = append(baseDataTimeArr, baseDataList[i].DataTime)
|
|
|
+ baseCalculateData = append(baseCalculateData, baseDataList[i].Value)
|
|
|
+ }
|
|
|
+
|
|
|
+ //zeroBaseData := make([]float64, 0)
|
|
|
+ //zeroCalculateData := make([]float64, 0)
|
|
|
+ //for i := range baseDataTimeArr {
|
|
|
+ // tmpBaseVal, ok1 := baseDataMap[baseDataTimeArr[i]]
|
|
|
+ // tmpCalculateVal, ok2 := changeDataMap[baseDataTimeArr[i]]
|
|
|
+ // if ok1 && ok2 {
|
|
|
+ // zeroBaseData = append(zeroBaseData, tmpBaseVal)
|
|
|
+ // zeroCalculateData = append(zeroCalculateData, tmpCalculateVal)
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+ //if len(zeroBaseData) != len(zeroCalculateData) {
|
|
|
+ // err = fmt.Errorf("相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(zeroCalculateData))
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //zeroRatio := utils.CalculateCorrelationByIntArr(zeroBaseData, zeroCalculateData)
|
|
|
+ //if leadValue == 0 {
|
|
|
+ // yData = append(yData, zeroRatio)
|
|
|
+ //}
|
|
|
+
|
|
|
+ // 计算领先/滞后N期
|
|
|
+ if leadValue > 0 {
|
|
|
+ // 平移变频指标领先/滞后的日期(单位天)
|
|
|
+ moveUnitDays := utils.FrequencyDaysMap[leadUnit]
|
|
|
+
|
|
|
+ for i := range xData {
|
|
|
+ //if xData[i] == 0 {
|
|
|
+ // yData = append(yData, zeroRatio)
|
|
|
+ // continue
|
|
|
+ //}
|
|
|
+ xCalculateData := make([]float64, 0)
|
|
|
+ yCalculateData := make([]float64, 0)
|
|
|
+
|
|
|
+ // 平移指定天数
|
|
|
+ mDays := int(moveUnitDays) * xData[i]
|
|
|
+ _, dMap := MoveDataDaysToNewDataList(changeDataList, mDays)
|
|
|
+
|
|
|
+ // 取出对应的基准日期的值
|
|
|
+ for i2 := range baseDataTimeArr {
|
|
|
+ tmpDate := baseDataTimeArr[i2]
|
|
|
+ if yVal, ok := dMap[tmpDate]; ok {
|
|
|
+ xCalculateData = append(xCalculateData, baseCalculateData[i2])
|
|
|
+ yCalculateData = append(yCalculateData, yVal)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(yCalculateData) <= 0 {
|
|
|
+ //err = fmt.Errorf("领先滞后相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(yCalculateData))
|
|
|
+ //return
|
|
|
+ // 领先滞后后,没有可以计算的数据了
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // 公式计算出领先/滞后频度对应点的相关性系数
|
|
|
+ ratio := utils.CalculateCorrelationByIntArr(xCalculateData, yCalculateData)
|
|
|
+ yData = append(yData, ratio)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图例
|
|
|
+ var extra data_manage.CorrelationChartInfoExtraConfig
|
|
|
+ legend := new(data_manage.CorrelationChartLegend)
|
|
|
+ if extraConfig != "" {
|
|
|
+ if e := json.Unmarshal([]byte(extraConfig), &extra); e != nil {
|
|
|
+ err = fmt.Errorf("图例解析异常, err: %v", e)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if len(extra.LegendConfig) > 0 {
|
|
|
+ legend = extra.LegendConfig[0]
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ xEdbIdValue = xData
|
|
|
+ yDataList = make([]data_manage.YData, 0)
|
|
|
+ yDate := "0000-00-00"
|
|
|
+ var y data_manage.YData
|
|
|
+ y.Date = yDate
|
|
|
+ y.Value = yData
|
|
|
+ if legend != nil {
|
|
|
+ y.Name = legend.LegendName
|
|
|
+ y.Color = legend.Color
|
|
|
+ }
|
|
|
+ yDataList = append(yDataList, y)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// RollingCorrelationChartDataResp 滚动相关性图表数据
|
|
|
+type RollingCorrelationChartDataResp struct {
|
|
|
+ MaxData float64
|
|
|
+ MinData float64
|
|
|
+ LatestDate string `description:"真实数据的最后日期"`
|
|
|
+ EdbInfoCategoryType int
|
|
|
+ ChartColor string
|
|
|
+ ChartStyle string
|
|
|
+ PredictChartColor string
|
|
|
+ ChartType int
|
|
|
+ ChartWidth int
|
|
|
+ EdbName string
|
|
|
+ EdbNameEn string
|
|
|
+ Unit string
|
|
|
+ UnitEn string
|
|
|
+ IsAxis int
|
|
|
+ DataList []data_manage.EdbDataList
|
|
|
+}
|
|
|
+
|
|
|
+// GetRollingCorrelationChartDataByEdbInfo 滚动相关性计算
|
|
|
+func GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping, leadValue int, leadUnit string, calculateValue int, calculateUnit string, startDate, endDate, chartName, chartNameEn string) (dataResp RollingCorrelationChartDataResp, err error) {
|
|
|
+ dataResp = RollingCorrelationChartDataResp{
|
|
|
+ DataList: make([]data_manage.EdbDataList, 0),
|
|
|
+ MaxData: 0,
|
|
|
+ MinData: 0,
|
|
|
+ ChartColor: "#00f",
|
|
|
+ ChartStyle: `spline`,
|
|
|
+ PredictChartColor: `#00f`,
|
|
|
+ ChartType: 0,
|
|
|
+ ChartWidth: 3,
|
|
|
+ EdbName: chartName,
|
|
|
+ EdbNameEn: chartNameEn,
|
|
|
+ IsAxis: 1,
|
|
|
+ }
|
|
|
+ dataList := make([]data_manage.EdbDataList, 0)
|
|
|
+
|
|
|
+ // 计算窗口,不包含第一天
|
|
|
+ startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
+ startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
|
|
|
+
|
|
|
+ baseEdbInfo := edbInfoMappingA
|
|
|
+ changeEdbInfo := edbInfoMappingB
|
|
|
+
|
|
|
+ // 获取时间基准指标在时间区间内的值
|
|
|
+ aDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ switch baseEdbInfo.EdbInfoCategoryType {
|
|
|
+ case 0:
|
|
|
+ aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
|
|
|
+ case 1:
|
|
|
+ _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, true)
|
|
|
+ default:
|
|
|
+ err = errors.New("指标base类型异常")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取变频指标所有日期的值, 插值法完善数据
|
|
|
+ bDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ switch changeEdbInfo.EdbInfoCategoryType {
|
|
|
+ case 0:
|
|
|
+ bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
|
|
|
+ case 1:
|
|
|
+ _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
|
|
|
+ default:
|
|
|
+ err = errors.New("指标change类型异常")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 数据平移变频指标领先/滞后的日期(单位天)
|
|
|
+ // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
|
|
|
+ //baseDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ baseDataMap := make(map[string]float64)
|
|
|
+ changeDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ changeDataMap := make(map[string]float64)
|
|
|
+
|
|
|
+ // A指标不管三七二十一,先变个频再说
|
|
|
+ {
|
|
|
+ _, e := HandleDataByLinearRegression(aDataList, baseDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //baseDataList = tmpNewChangeDataList
|
|
|
+ }
|
|
|
+ // B指标不管三七二十一,先变个频再说
|
|
|
+ {
|
|
|
+ tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ changeDataList = tmpNewChangeDataList
|
|
|
+
|
|
|
+ // 平移下日期
|
|
|
+ moveUnitDays := utils.FrequencyDaysMap[leadUnit]
|
|
|
+ _, changeDataMap = MoveDataDaysToNewDataList(changeDataList, leadValue*moveUnitDays)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算计算时,需要多少个日期内数据
|
|
|
+ calculateDay := utils.FrequencyDaysMap[calculateUnit] * calculateValue
|
|
|
+
|
|
|
+ // 计算 每个日期的相关性值
|
|
|
+ {
|
|
|
+ startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
+ if endDate == `` {
|
|
|
+ endDate = baseEdbInfo.EndDate
|
|
|
+ }
|
|
|
+ endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
|
|
|
+ endDateTime = endDateTime.AddDate(0, 0, -(calculateDay - 1))
|
|
|
+
|
|
|
+ // 是否开始第一条数据
|
|
|
+ var isStart, isNotFirst bool
|
|
|
+ for currDay := startDateTime; !currDay.After(endDateTime); currDay = currDay.AddDate(0, 0, 1) {
|
|
|
+ yCalculateData := make([]float64, 0)
|
|
|
+ baseCalculateData := make([]float64, 0)
|
|
|
+
|
|
|
+ // 取出对应的基准日期的值
|
|
|
+ for i := 0; i < calculateDay; i++ {
|
|
|
+ iDay := currDay.AddDate(0, 0, i).Format(utils.FormatDate)
|
|
|
+
|
|
|
+ tmpBaseValue, ok1 := baseDataMap[iDay]
|
|
|
+ tmpChangeValue, ok2 := changeDataMap[iDay]
|
|
|
+ if ok1 && ok2 {
|
|
|
+ baseCalculateData = append(baseCalculateData, tmpBaseValue)
|
|
|
+ yCalculateData = append(yCalculateData, tmpChangeValue)
|
|
|
+ } else {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 公式计算出领先/滞后频度对应点的相关性系数
|
|
|
+ var ratio float64
|
|
|
+ if len(baseCalculateData) > 0 {
|
|
|
+ ratio = utils.CalculateCorrelationByIntArr(baseCalculateData, yCalculateData)
|
|
|
+ } else {
|
|
|
+ // 没有数据的话,那就不返回
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // 过滤前面都是0的数据
|
|
|
+ {
|
|
|
+ if ratio != 0 {
|
|
|
+ isStart = true
|
|
|
+ }
|
|
|
+
|
|
|
+ if !isStart {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTime := currDay.AddDate(0, 0, calculateDay-1)
|
|
|
+ dataList = append(dataList, data_manage.EdbDataList{
|
|
|
+ //EdbDataId: 0,
|
|
|
+ EdbInfoId: 0,
|
|
|
+ DataTime: dataTime.Format(utils.FormatDate),
|
|
|
+ DataTimestamp: dataTime.UnixNano() / 1e6,
|
|
|
+ Value: ratio,
|
|
|
+ })
|
|
|
+
|
|
|
+ if !isNotFirst {
|
|
|
+ dataResp.MinData = ratio
|
|
|
+ dataResp.MaxData = ratio
|
|
|
+ isNotFirst = true
|
|
|
+ }
|
|
|
+ if dataResp.MinData > ratio {
|
|
|
+ dataResp.MinData = ratio
|
|
|
+ }
|
|
|
+ if dataResp.MaxData < ratio {
|
|
|
+ dataResp.MaxData = ratio
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dataResp.DataList = dataList
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// ChartInfoRefresh 图表刷新
|
|
|
+func ChartInfoRefresh(chartInfoId int, uniqueCode string) (isAsync bool, err error) {
|
|
|
+ var errMsg string
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ tips := fmt.Sprintf("CorrelationChartInfoRefresh: %s", errMsg)
|
|
|
+ utils.FileLog.Info(tips)
|
|
|
+ go alarm_msg.SendAlarmMsg(tips, 3)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ correlationChart := new(data_manage.ChartInfoCorrelation)
|
|
|
+ if err = correlationChart.GetItemById(chartInfoId); err != nil {
|
|
|
+ errMsg = "获取相关性图表失败, Err: " + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 多因子刷新-异步
|
|
|
+ if correlationChart.AnalysisMode == 1 {
|
|
|
+ isAsync = true
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ // 1.刷新图表关联的指标
|
|
|
+ mappings, e := data_manage.GetChartEdbMappingList(chartInfoId)
|
|
|
+ if e != nil {
|
|
|
+ utils.FileLog.Info(fmt.Sprintf("获取图表关联指标失败, err: %v", e))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if len(mappings) == 0 {
|
|
|
+ utils.FileLog.Info("图表无关联指标")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var edbIds []int
|
|
|
+ for _, v := range mappings {
|
|
|
+ edbIds = append(edbIds, v.EdbInfoId)
|
|
|
+ }
|
|
|
+ if e, _ = data.EdbInfoRefreshAllFromBaseV3(edbIds, false, true, false); e != nil {
|
|
|
+ utils.FileLog.Info(fmt.Sprintf("批量刷新指标失败, err: %v", e))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2.刷新指标系列计算数据
|
|
|
+ for _, v := range mappings {
|
|
|
+ _, e = data.PostRefreshFactorEdbRecalculate(v.EdbInfoId, v.EdbCode)
|
|
|
+ if e != nil {
|
|
|
+ utils.FileLog.Info(fmt.Sprintf("PostRefreshFactorEdbRecalculate err: %v", e))
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3.刷新图表矩阵
|
|
|
+ _, e = data.PostRefreshFactorEdbChartRecalculate(chartInfoId)
|
|
|
+ if e != nil {
|
|
|
+ utils.FileLog.Info(fmt.Sprintf("PostRefreshFactorEdbRecalculate err: %v", e))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4.清除图表缓存
|
|
|
+ key := utils.HZ_CHART_LIB_DETAIL + uniqueCode
|
|
|
+ _ = utils.Rc.Delete(key)
|
|
|
+ }()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量刷新ETA指标
|
|
|
+ err, _ = data.EdbInfoRefreshAllFromBaseV3([]int{correlationChart.EdbInfoIdFirst, correlationChart.EdbInfoIdSecond}, false, true, false)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重新生成数据并更新
|
|
|
+ edbInfoMappingA, err := data_manage.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdFirst)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "获取相关性图表, A指标mapping信息失败, Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ edbInfoMappingB, err := data_manage.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdSecond)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "获取相关性图表, B指标mapping信息失败, Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ periodData, correlationData, err := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationChart.LeadValue, correlationChart.LeadUnit, correlationChart.StartDate.Format(utils.FormatDate), correlationChart.EndDate.Format(utils.FormatDate), "")
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "获取相关性图表, 图表计算值失败, Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ periodDataByte, err := json.Marshal(periodData)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "相关性图表, X轴信息有误, Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ correlationDataByte, err := json.Marshal(correlationData[0].Value)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "相关性图表, Y轴信息有误, Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ correlationChart.PeriodData = string(periodDataByte)
|
|
|
+ correlationChart.CorrelationData = string(correlationDataByte)
|
|
|
+ correlationChart.ModifyTime = time.Now().Local()
|
|
|
+ correlationUpdateCols := []string{"PeriodData", "CorrelationData", "ModifyTime"}
|
|
|
+ if err = correlationChart.Update(correlationUpdateCols); err != nil {
|
|
|
+ errMsg = "更新相关性图表失败, Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetChartAndCorrelationInfo 获取图表信息和相关信息信息
|
|
|
+func GetChartAndCorrelationInfo(chartInfoId int) (chartInfo *data_manage.ChartInfo, correlationInfo *data_manage.ChartInfoCorrelation, tips string, err error) {
|
|
|
+ item, e := data_manage.GetChartInfoById(chartInfoId)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ tips = "图表已被删除, 请刷新页面"
|
|
|
+ err = fmt.Errorf("图表已被删除, 请刷新页面")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = fmt.Errorf("获取图表信息失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if item.Source != utils.CHART_SOURCE_CORRELATION {
|
|
|
+ tips = "该图不是相关性图表"
|
|
|
+ err = fmt.Errorf("该图不是相关性图表")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ chartInfo = item
|
|
|
+ correlationInfo = new(data_manage.ChartInfoCorrelation)
|
|
|
+ if e = correlationInfo.GetItemById(chartInfo.ChartInfoId); e != nil {
|
|
|
+ err = fmt.Errorf("获取图表相关性信息失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// AddChartInfo 添加图表
|
|
|
+func AddChartInfo(req data_manage.AddChartInfoReq, source int, sysUser *system.Admin, lang string) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
|
|
|
+ isSendEmail = true
|
|
|
+
|
|
|
+ req.ChartName = strings.Trim(req.ChartName, " ")
|
|
|
+ if req.ChartName == "" {
|
|
|
+ errMsg = "请填写图表名称!"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.ChartClassifyId <= 0 {
|
|
|
+ errMsg = "分类参数错误!"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 相关性图表配置
|
|
|
+ if req.CorrelationChartInfo.LeadValue == 0 && source == utils.CHART_SOURCE_CORRELATION {
|
|
|
+ errMsg = "请输入领先期数"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.CorrelationChartInfo.LeadUnit == "" {
|
|
|
+ errMsg = "请填写领先单位"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //if req.CorrelationChartInfo.StartDate == "" || req.CorrelationChartInfo.EndDate == "" {
|
|
|
+ // errMsg = "请填写开始结束日期"
|
|
|
+ // err = errors.New(errMsg)
|
|
|
+ // isSendEmail = false
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //startDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.StartDate)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "开始日期格式有误"
|
|
|
+ // err = errors.New(errMsg)
|
|
|
+ // isSendEmail = false
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //endDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.EndDate)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "结束日期格式有误"
|
|
|
+ // err = errors.New(errMsg)
|
|
|
+ // isSendEmail = false
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ if len(req.CorrelationChartInfo.EdbInfoIdList) != 2 {
|
|
|
+ errMsg = "请选择AB指标"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
|
|
|
+ if err != nil {
|
|
|
+ if err.Error() == utils.ErrNoRow() {
|
|
|
+ errMsg = "分类不存在"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ errMsg = "获取分类信息失败"
|
|
|
+ err = errors.New("获取分类信息失败,Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if chartClassify == nil {
|
|
|
+ errMsg = "分类不存在"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var edbInfoIdArr []int
|
|
|
+ for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
|
|
|
+ edbInfoId := v.EdbInfoId
|
|
|
+ edbInfo, tmpErr := data_manage.GetEdbInfoById(edbInfoId)
|
|
|
+ if tmpErr != nil {
|
|
|
+ if tmpErr.Error() == utils.ErrNoRow() {
|
|
|
+ errMsg = "指标不存在!"
|
|
|
+ err = errors.New("指标不存在,edbInfoId:" + strconv.Itoa(edbInfoId))
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ errMsg = "获取指标信息失败!"
|
|
|
+ err = errors.New("获取图表的指标信息失败,Err:" + tmpErr.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if edbInfo == nil {
|
|
|
+ errMsg = "指标已被删除,请重新选择!"
|
|
|
+ err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ if edbInfo.EdbInfoId <= 0 {
|
|
|
+ errMsg = "指标已被删除,请重新选择!"
|
|
|
+ err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ edbInfoIdArr = append(edbInfoIdArr, edbInfoId)
|
|
|
+ edbInfo.EdbNameSource = edbInfo.EdbName
|
|
|
+ }
|
|
|
+
|
|
|
+ sort.Ints(edbInfoIdArr)
|
|
|
+ var edbInfoIdArrStr []string
|
|
|
+ for _, v := range edbInfoIdArr {
|
|
|
+ edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
|
|
|
+ }
|
|
|
+ edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
|
|
|
+ var chartInfoId int
|
|
|
+
|
|
|
+ // 判断图表是否存在
|
|
|
+ {
|
|
|
+ var condition string
|
|
|
+ var pars []interface{}
|
|
|
+
|
|
|
+ switch lang {
|
|
|
+ case utils.EnLangVersion:
|
|
|
+ condition += " AND chart_name_en = ? AND source = ? "
|
|
|
+ default:
|
|
|
+ condition += " AND chart_name=? AND source = ? "
|
|
|
+ }
|
|
|
+ pars = append(pars, req.ChartName, source)
|
|
|
+ count, tmpErr := data_manage.GetChartInfoCountByCondition(condition, pars)
|
|
|
+ if tmpErr != nil {
|
|
|
+ errMsg = "判断图表名称是否存在失败"
|
|
|
+ err = errors.New("判断图表名称是否存在失败,Err:" + tmpErr.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if count > 0 {
|
|
|
+ errMsg = "图表已存在,请重新填写"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ disableVal := data.CheckIsDisableChart(edbInfoIdArr)
|
|
|
+
|
|
|
+ chartInfo = new(data_manage.ChartInfo)
|
|
|
+ chartInfo.ChartName = req.ChartName
|
|
|
+ chartInfo.ChartNameEn = req.ChartName
|
|
|
+ chartInfo.EdbInfoIds = edbInfoIdStr
|
|
|
+ chartInfo.ChartClassifyId = req.ChartClassifyId
|
|
|
+ chartInfo.SysUserId = sysUser.AdminId
|
|
|
+ chartInfo.SysUserRealName = sysUser.RealName
|
|
|
+ chartInfo.CreateTime = time.Now()
|
|
|
+ chartInfo.ModifyTime = time.Now()
|
|
|
+ chartInfo.IsSetName = 0
|
|
|
+ timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
|
|
|
+ chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
|
|
|
+ chartInfo.ChartType = 9 // 相关性图
|
|
|
+ chartInfo.Calendar = "公历"
|
|
|
+ chartInfo.DateType = 6
|
|
|
+ chartInfo.StartDate = req.StartDate
|
|
|
+ chartInfo.EndDate = req.EndDate
|
|
|
+ chartInfo.SeasonStartDate = req.StartDate
|
|
|
+ chartInfo.SeasonEndDate = req.EndDate
|
|
|
+ chartInfo.LeftMin = req.LeftMin
|
|
|
+ chartInfo.LeftMax = req.LeftMax
|
|
|
+ chartInfo.RightMin = req.RightMin
|
|
|
+ chartInfo.RightMax = req.RightMax
|
|
|
+ chartInfo.Disabled = disableVal
|
|
|
+ chartInfo.Source = source
|
|
|
+ chartInfo.ChartThemeId = req.ChartThemeId
|
|
|
+ chartInfo.SourcesFrom = req.SourcesFrom
|
|
|
+ chartInfo.Instructions = req.Instructions
|
|
|
+ chartInfo.MarkersLines = req.MarkersLines
|
|
|
+ chartInfo.MarkersAreas = req.MarkersAreas
|
|
|
+ if req.ExtraConfig != "" {
|
|
|
+ chartInfo.ExtraConfig = req.ExtraConfig
|
|
|
+ }
|
|
|
+
|
|
|
+ // 指标信息
|
|
|
+ mapList := make([]*data_manage.ChartEdbMapping, 0)
|
|
|
+ for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
|
|
|
+ mapItem := new(data_manage.ChartEdbMapping)
|
|
|
+ mapItem.EdbInfoId = v.EdbInfoId
|
|
|
+ mapItem.CreateTime = time.Now()
|
|
|
+ mapItem.ModifyTime = time.Now()
|
|
|
+ edbTimestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
|
|
|
+ mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + edbTimestamp + "_" + strconv.Itoa(v.EdbInfoId))
|
|
|
+ mapItem.IsOrder = true
|
|
|
+ mapItem.IsAxis = 1
|
|
|
+ mapItem.EdbInfoType = 1
|
|
|
+ mapItem.Source = utils.CHART_SOURCE_CORRELATION
|
|
|
+ mapList = append(mapList, mapItem)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 相关性图表扩展信息
|
|
|
+ correlationChart := new(data_manage.ChartInfoCorrelation)
|
|
|
+ correlationChart.LeadValue = req.CorrelationChartInfo.LeadValue
|
|
|
+ correlationChart.LeadUnit = req.CorrelationChartInfo.LeadUnit
|
|
|
+ correlationChart.CalculateValue = req.CorrelationChartInfo.CalculateValue
|
|
|
+ correlationChart.CalculateUnit = req.CorrelationChartInfo.CalculateUnit
|
|
|
+ correlationChart.BaseCalculateValue = req.CorrelationChartInfo.BaseCalculateValue
|
|
|
+ correlationChart.BaseCalculateUnit = req.CorrelationChartInfo.BaseCalculateUnit
|
|
|
+
|
|
|
+ // 滚动相关性会有日期等信息
|
|
|
+ if source == utils.CHART_SOURCE_ROLLING_CORRELATION {
|
|
|
+ correlationChart.DateType = req.CorrelationChartInfo.DateType
|
|
|
+ if req.CorrelationChartInfo.StartDate != `` {
|
|
|
+ startDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, req.CorrelationChartInfo.StartDate, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ correlationChart.StartDate = startDateTime
|
|
|
+ }
|
|
|
+ if req.CorrelationChartInfo.EndDate != `` {
|
|
|
+ endDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, req.CorrelationChartInfo.EndDate, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ correlationChart.EndDate = endDateTime
|
|
|
+ }
|
|
|
+ }
|
|
|
+ correlationChart.EdbInfoIdFirst = req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId
|
|
|
+ correlationChart.EdbInfoIdSecond = req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId
|
|
|
+ correlationChart.CreateTime = time.Now().Local()
|
|
|
+ correlationChart.ModifyTime = time.Now().Local()
|
|
|
+ //// 生成图表x轴y轴数据
|
|
|
+ //edbInfoMappingA, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("获取相关性图表, A指标mapping信息失败, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //edbInfoMappingB, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("获取相关性图表, B指标mapping信息失败, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //periodData, correlationData, e := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, req.CorrelationChartInfo.LeadValue, req.CorrelationChartInfo.LeadUnit, req.CorrelationChartInfo.StartDate, req.CorrelationChartInfo.EndDate)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("获取相关性图表, 图表计算值失败, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //periodDataByte, e := json.Marshal(periodData)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("相关性图表, X轴信息有误, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //correlationDataByte, e := json.Marshal(correlationData[0].Value)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("相关性图表, Y轴信息有误, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //correlationChart.PeriodData = string(periodDataByte)
|
|
|
+ //correlationChart.CorrelationData = string(correlationDataByte)
|
|
|
+
|
|
|
+ // 新增图表和指标mapping
|
|
|
+ chartInfoId, e := data_manage.CreateCorrelationChartAndEdb(chartInfo, mapList, correlationChart)
|
|
|
+ if e != nil {
|
|
|
+ errMsg = "操作失败"
|
|
|
+ err = errors.New("新增相关性图表失败, Err: " + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加指标引用记录
|
|
|
+ _ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartInfo)
|
|
|
+ //添加es数据
|
|
|
+ go data.EsAddOrEditChartInfo(chartInfoId)
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// EditChartInfo 编辑图表
|
|
|
+func EditChartInfo(req data_manage.EditChartInfoReq, sysUser *system.Admin, lang string) (chartItem *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
|
|
|
+ isSendEmail = true
|
|
|
+
|
|
|
+ chartItem, err = data_manage.GetChartInfoById(req.ChartInfoId)
|
|
|
+ if err != nil {
|
|
|
+ if err.Error() == utils.ErrNoRow() {
|
|
|
+ errMsg = "图表已被删除,请刷新页面"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ errMsg = "获取图表信息失败"
|
|
|
+ err = errors.New("获取图表信息失败,Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if chartItem.Source != utils.CHART_SOURCE_CORRELATION && chartItem.Source != utils.CHART_SOURCE_ROLLING_CORRELATION {
|
|
|
+ errMsg = "该图不是相关性图表!"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ req.ChartName = strings.Trim(req.ChartName, " ")
|
|
|
+ if req.ChartClassifyId <= 0 {
|
|
|
+ errMsg = "分类参数错误!"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 相关性图表配置
|
|
|
+ if req.CorrelationChartInfo.LeadValue == 0 && chartItem.Source == utils.CHART_SOURCE_CORRELATION {
|
|
|
+ errMsg = "请输入领先期数"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.CorrelationChartInfo.LeadUnit == "" {
|
|
|
+ errMsg = "请填写领先单位"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //if req.CorrelationChartInfo.StartDate == "" || req.CorrelationChartInfo.EndDate == "" {
|
|
|
+ // errMsg = "请填写开始结束日期"
|
|
|
+ // err = errors.New(errMsg)
|
|
|
+ // isSendEmail = false
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ startDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.StartDate)
|
|
|
+ if e != nil {
|
|
|
+ errMsg = "开始日期格式有误"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var endDate time.Time
|
|
|
+ if req.CorrelationChartInfo.EndDate != `` {
|
|
|
+ endDate, e = time.Parse(utils.FormatDate, req.CorrelationChartInfo.EndDate)
|
|
|
+ if e != nil {
|
|
|
+ errMsg = "结束日期格式有误"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(req.CorrelationChartInfo.EdbInfoIdList) != 2 {
|
|
|
+ errMsg = "请选择AB指标"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
|
|
|
+ if err != nil {
|
|
|
+ if err.Error() == utils.ErrNoRow() {
|
|
|
+ errMsg = "分类不存在"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ errMsg = "获取分类信息失败"
|
|
|
+ err = errors.New("获取分类信息失败,Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if chartClassify == nil {
|
|
|
+ errMsg = "分类不存在"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图表操作权限
|
|
|
+ ok := data.CheckOpChartPermission(sysUser, chartItem.SysUserId, true)
|
|
|
+ if !ok {
|
|
|
+ errMsg = "没有该图表的操作权限"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var edbInfoIdArr []int
|
|
|
+ for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
|
|
|
+ edbInfoId := v.EdbInfoId
|
|
|
+ edbInfo, tmpErr := data_manage.GetEdbInfoById(edbInfoId)
|
|
|
+ if tmpErr != nil {
|
|
|
+ if tmpErr.Error() == utils.ErrNoRow() {
|
|
|
+ errMsg = "图表不存在!"
|
|
|
+ err = errors.New("图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ errMsg = "获取图表信息失败!"
|
|
|
+ err = errors.New("获取图表的指标信息失败,Err:" + tmpErr.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if edbInfo == nil {
|
|
|
+ errMsg = "指标不存在!"
|
|
|
+ err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ edbInfoIdArr = append(edbInfoIdArr, edbInfoId)
|
|
|
+ }
|
|
|
+
|
|
|
+ sort.Ints(edbInfoIdArr)
|
|
|
+ var edbInfoIdArrStr []string
|
|
|
+ for _, v := range edbInfoIdArr {
|
|
|
+ edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
|
|
|
+ }
|
|
|
+ edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
|
|
|
+
|
|
|
+ //判断图表是否存在
|
|
|
+ {
|
|
|
+ var condition string
|
|
|
+ var pars []interface{}
|
|
|
+ condition += " AND chart_info_id <> ? "
|
|
|
+ pars = append(pars, req.ChartInfoId)
|
|
|
+ switch lang {
|
|
|
+ case utils.EnLangVersion:
|
|
|
+ condition += " AND chart_name_en = ? AND source = ? "
|
|
|
+ default:
|
|
|
+ condition += " AND chart_name=? AND source = ? "
|
|
|
+ }
|
|
|
+ pars = append(pars, req.ChartName, chartItem.Source)
|
|
|
+ count, tmpErr := data_manage.GetChartInfoCountByCondition(condition, pars)
|
|
|
+ if tmpErr != nil {
|
|
|
+ errMsg = "判断图表名称是否存在失败"
|
|
|
+ err = errors.New("判断图表名称是否存在失败,Err:" + tmpErr.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if count > 0 {
|
|
|
+ errMsg = "图表已存在,请重新填写"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ correlationChart := new(data_manage.ChartInfoCorrelation)
|
|
|
+ if e := correlationChart.GetItemById(chartItem.ChartInfoId); e != nil {
|
|
|
+ errMsg = "操作失败"
|
|
|
+ err = errors.New("图表相关性信息不存在, Err: " + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图表启用与否
|
|
|
+ disableVal := data.CheckIsDisableChart(edbInfoIdArr)
|
|
|
+
|
|
|
+ // 重新生成图表值, 并修改相关性图表扩展信息
|
|
|
+ //edbInfoMappingA, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("获取相关性图表, A指标mapping信息失败, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //edbInfoMappingB, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("获取相关性图表, B指标mapping信息失败, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //periodData, correlationData, e := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, req.CorrelationChartInfo.LeadValue, req.CorrelationChartInfo.LeadUnit, req.CorrelationChartInfo.StartDate, req.CorrelationChartInfo.EndDate)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("获取相关性图表, 图表计算值失败, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //periodDataByte, e := json.Marshal(periodData)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("相关性图表, X轴信息有误, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //correlationDataByte, e := json.Marshal(correlationData[0].Value)
|
|
|
+ //if e != nil {
|
|
|
+ // errMsg = "获取失败"
|
|
|
+ // err = errors.New("相关性图表, Y轴信息有误, Err:" + e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ correlationChart.LeadValue = req.CorrelationChartInfo.LeadValue
|
|
|
+ correlationChart.LeadUnit = req.CorrelationChartInfo.LeadUnit
|
|
|
+ correlationChart.CalculateValue = req.CorrelationChartInfo.CalculateValue
|
|
|
+ correlationChart.CalculateUnit = req.CorrelationChartInfo.CalculateUnit
|
|
|
+ correlationChart.StartDate = startDate
|
|
|
+ correlationChart.EndDate = endDate
|
|
|
+ correlationChart.EdbInfoIdFirst = req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId
|
|
|
+ correlationChart.EdbInfoIdSecond = req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId
|
|
|
+
|
|
|
+ // 滚动相关性会有日期等信息
|
|
|
+ if chartItem.Source == utils.CHART_SOURCE_ROLLING_CORRELATION {
|
|
|
+ correlationChart.DateType = req.CorrelationChartInfo.DateType
|
|
|
+ }
|
|
|
+ //correlationChart.PeriodData = string(periodDataByte)
|
|
|
+ //correlationChart.CorrelationData = string(correlationDataByte)
|
|
|
+ correlationChart.ModifyTime = time.Now().Local()
|
|
|
+ //correlationUpdateCols := []string{"LeadValue", "LeadUnit", "StartDate", "EndDate", "EdbInfoIdFirst", "EdbInfoIdSecond", "PeriodData","CorrelationData", "ModifyTime"}
|
|
|
+ correlationUpdateCols := []string{"LeadValue", "LeadUnit", "CalculateValue", "CalculateUnit", "DateType", "StartDate", "EndDate", "EdbInfoIdFirst", "EdbInfoIdSecond", "ModifyTime"}
|
|
|
+
|
|
|
+ // 修改图表与指标mapping
|
|
|
+ req.ChartType = 9
|
|
|
+ err = data_manage.EditCorrelationChartInfoAndMapping(&req, edbInfoIdStr, "公历", 6, disableVal, ``,
|
|
|
+ correlationChart, correlationUpdateCols)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "保存失败"
|
|
|
+ err = errors.New("保存失败,Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ resp := new(data_manage.AddChartInfoResp)
|
|
|
+ resp.ChartInfoId = chartItem.ChartInfoId
|
|
|
+ resp.UniqueCode = chartItem.UniqueCode
|
|
|
+ resp.ChartType = req.ChartType
|
|
|
+
|
|
|
+ // 添加指标引用记录
|
|
|
+ _ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartItem)
|
|
|
+ //添加es数据
|
|
|
+ go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
|
|
|
+ //修改my eta es数据
|
|
|
+ go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// CopyChartInfo 复制图表
|
|
|
+func CopyChartInfo(configId, classifyId int, chartName string, correlationChartInfoReq data_manage.CorrelationChartInfoReq, oldChartInfo *data_manage.ChartInfo, sysUser *system.Admin, lang string) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
|
|
|
+ configSource := 2
|
|
|
+ isSendEmail = true
|
|
|
+ // 获取相关性图的配置
|
|
|
+ multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(configId, configSource)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ multipleGraphConfig, err := data_manage.GetMultipleGraphConfigById(configId)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ multipleGraphConfig.MultipleGraphConfigId = 0
|
|
|
+ err = data_manage.AddMultipleGraphConfig(multipleGraphConfig)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加图
|
|
|
+ addChartReq := data_manage.AddChartInfoReq{
|
|
|
+ ChartClassifyId: classifyId,
|
|
|
+ ChartName: chartName,
|
|
|
+ ChartType: utils.CHART_TYPE_CURVE,
|
|
|
+ Calendar: "公历",
|
|
|
+ CorrelationChartInfo: correlationChartInfoReq,
|
|
|
+ ChartThemeId: oldChartInfo.ChartThemeId,
|
|
|
+ SourcesFrom: oldChartInfo.SourcesFrom,
|
|
|
+ Instructions: oldChartInfo.Instructions,
|
|
|
+ MarkersLines: oldChartInfo.MarkersLines,
|
|
|
+ MarkersAreas: oldChartInfo.MarkersAreas,
|
|
|
+ }
|
|
|
+ chartSource := utils.CHART_SOURCE_CORRELATION // 默认是相关性图
|
|
|
+ chartInfo, err, errMsg, isSendEmail = AddChartInfo(addChartReq, chartSource, sysUser, lang)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加关系
|
|
|
+ multipleGraphConfigChartMapping = &data_manage.MultipleGraphConfigChartMapping{
|
|
|
+ //Id: 0,
|
|
|
+ MultipleGraphConfigId: multipleGraphConfig.MultipleGraphConfigId,
|
|
|
+ ChartInfoId: chartInfo.ChartInfoId,
|
|
|
+ Source: configSource,
|
|
|
+ ModifyTime: time.Now(),
|
|
|
+ CreateTime: time.Now(),
|
|
|
+ }
|
|
|
+ err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //添加es数据
|
|
|
+ go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// CalculateCorrelation 计算相关性-获取x轴和y轴
|
|
|
+func CalculateCorrelation(leadValue int, leadUnit, frequencyA, frequencyB string, dataListA, dataListB []*data_manage.EdbDataList) (xEdbIdValue []int, yDataList []data_manage.YData, err error) {
|
|
|
+ xData := make([]int, 0)
|
|
|
+ yData := make([]float64, 0)
|
|
|
+ if leadValue == 0 {
|
|
|
+ xData = append(xData, 0)
|
|
|
+ }
|
|
|
+ if leadValue > 0 {
|
|
|
+ leadMin := 0 - leadValue
|
|
|
+ xLen := 2*leadValue + 1
|
|
|
+ for i := 0; i < xLen; i++ {
|
|
|
+ n := leadMin + i
|
|
|
+ xData = append(xData, n)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算窗口,不包含第一天
|
|
|
+ //startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
+ //startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
|
|
|
+
|
|
|
+ //// 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
|
|
|
+ //baseEdbInfo := edbInfoMappingB
|
|
|
+ //changeEdbInfo := edbInfoMappingA
|
|
|
+ // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
|
|
|
+ //baseEdbInfo := edbInfoMappingA
|
|
|
+ //changeEdbInfo := edbInfoMappingB
|
|
|
+
|
|
|
+ // 获取时间基准指标在时间区间内的值
|
|
|
+ //aDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ //switch baseEdbInfo.EdbInfoCategoryType {
|
|
|
+ //case 0:
|
|
|
+ // aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
|
|
|
+ //case 1:
|
|
|
+ // _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
|
|
|
+ //default:
|
|
|
+ // err = errors.New("指标base类型异常")
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ //// 获取变频指标所有日期的值, 插值法完善数据
|
|
|
+ //bDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ //switch changeEdbInfo.EdbInfoCategoryType {
|
|
|
+ //case 0:
|
|
|
+ // bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
|
|
|
+ //case 1:
|
|
|
+ // _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
|
|
|
+ //default:
|
|
|
+ // err = errors.New("指标change类型异常")
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //changeDataMap := make(map[string]float64)
|
|
|
+ //newChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
|
|
|
+ //if e != nil {
|
|
|
+ // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+
|
|
|
+ // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
|
|
|
+ baseDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ baseDataMap := make(map[string]float64)
|
|
|
+ changeDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
+ changeDataMap := make(map[string]float64)
|
|
|
+
|
|
|
+ // 先把低频指标升频为高频
|
|
|
+ {
|
|
|
+ frequencyIntMap := map[string]int{
|
|
|
+ "日度": 1,
|
|
|
+ "周度": 2,
|
|
|
+ "旬度": 3,
|
|
|
+ "月度": 4,
|
|
|
+ "季度": 5,
|
|
|
+ "年度": 6,
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果A指标是高频,那么就需要对B指标进行升频
|
|
|
+ if frequencyIntMap[frequencyA] < frequencyIntMap[frequencyB] {
|
|
|
+ tmpNewChangeDataList, e := HandleDataByLinearRegression(dataListB, changeDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ changeDataList = tmpNewChangeDataList
|
|
|
+ baseDataList = dataListA
|
|
|
+ for _, v := range baseDataList {
|
|
|
+ baseDataMap[v.DataTime] = v.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if frequencyIntMap[frequencyA] > frequencyIntMap[frequencyB] {
|
|
|
+ // 如果B指标是高频,那么就需要对A指标进行升频
|
|
|
+ tmpNewChangeDataList, e := HandleDataByLinearRegression(dataListA, baseDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ baseDataList = tmpNewChangeDataList
|
|
|
+
|
|
|
+ changeDataList = dataListB
|
|
|
+ for _, v := range changeDataList {
|
|
|
+ changeDataMap[v.DataTime] = v.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ baseDataList = dataListA
|
|
|
+ for _, v := range baseDataList {
|
|
|
+ baseDataMap[v.DataTime] = v.Value
|
|
|
+ }
|
|
|
+ changeDataList = dataListB
|
|
|
+ for _, v := range changeDataList {
|
|
|
+ changeDataMap[v.DataTime] = v.Value
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算不领先也不滞后时的相关系数
|
|
|
+ baseCalculateData := make([]float64, 0)
|
|
|
+ baseDataTimeArr := make([]string, 0)
|
|
|
+ for i := range baseDataList {
|
|
|
+ baseDataTimeArr = append(baseDataTimeArr, baseDataList[i].DataTime)
|
|
|
+ baseCalculateData = append(baseCalculateData, baseDataList[i].Value)
|
|
|
+ }
|
|
|
+
|
|
|
+ //zeroBaseData := make([]float64, 0)
|
|
|
+ //zeroCalculateData := make([]float64, 0)
|
|
|
+ //for i := range baseDataTimeArr {
|
|
|
+ // tmpBaseVal, ok1 := baseDataMap[baseDataTimeArr[i]]
|
|
|
+ // tmpCalculateVal, ok2 := changeDataMap[baseDataTimeArr[i]]
|
|
|
+ // if ok1 && ok2 {
|
|
|
+ // zeroBaseData = append(zeroBaseData, tmpBaseVal)
|
|
|
+ // zeroCalculateData = append(zeroCalculateData, tmpCalculateVal)
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+ //if len(zeroBaseData) != len(zeroCalculateData) {
|
|
|
+ // err = fmt.Errorf("相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(zeroCalculateData))
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+ //zeroRatio := utils.CalculateCorrelationByIntArr(zeroBaseData, zeroCalculateData)
|
|
|
+ //if leadValue == 0 {
|
|
|
+ // yData = append(yData, zeroRatio)
|
|
|
+ //}
|
|
|
+
|
|
|
+ // 计算领先/滞后N期
|
|
|
+ if leadValue > 0 {
|
|
|
+ // 平移变频指标领先/滞后的日期(单位天)
|
|
|
+ moveUnitDays := utils.FrequencyDaysMap[leadUnit]
|
|
|
+
|
|
|
+ for i := range xData {
|
|
|
+ //if xData[i] == 0 {
|
|
|
+ // yData = append(yData, zeroRatio)
|
|
|
+ // continue
|
|
|
+ //}
|
|
|
+ xCalculateData := make([]float64, 0)
|
|
|
+ yCalculateData := make([]float64, 0)
|
|
|
+
|
|
|
+ // 平移指定天数
|
|
|
+ mDays := int(moveUnitDays) * xData[i]
|
|
|
+ _, dMap := MoveDataDaysToNewDataList(changeDataList, mDays)
|
|
|
+
|
|
|
+ // 取出对应的基准日期的值
|
|
|
+ for i2 := range baseDataTimeArr {
|
|
|
+ tmpDate := baseDataTimeArr[i2]
|
|
|
+ if yVal, ok := dMap[tmpDate]; ok {
|
|
|
+ xCalculateData = append(xCalculateData, baseCalculateData[i2])
|
|
|
+ yCalculateData = append(yCalculateData, yVal)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(yCalculateData) <= 0 {
|
|
|
+ //err = fmt.Errorf("领先滞后相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(yCalculateData))
|
|
|
+ //return
|
|
|
+ // 领先滞后后,没有可以计算的数据了
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // 公式计算出领先/滞后频度对应点的相关性系数
|
|
|
+ ratio := utils.CalculateCorrelationByIntArr(xCalculateData, yCalculateData)
|
|
|
+ yData = append(yData, ratio)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ xEdbIdValue = xData
|
|
|
+ yDataList = make([]data_manage.YData, 0)
|
|
|
+ yDate := "0000-00-00"
|
|
|
+ yDataList = append(yDataList, data_manage.YData{
|
|
|
+ Date: yDate,
|
|
|
+ Value: yData,
|
|
|
+ })
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetFactorChartDataByChartId 获取多因子相关性图表数据
|
|
|
+func GetFactorChartDataByChartId(chartInfoId int, extraConfig string) (xEdbIdValue []int, yDataList []data_manage.YData, err error) {
|
|
|
+ if chartInfoId <= 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 指标对应的图例
|
|
|
+ extra := new(data_manage.CorrelationChartInfoExtraConfig)
|
|
|
+ if extraConfig != "" {
|
|
|
+ if e := json.Unmarshal([]byte(extraConfig), extra); e != nil {
|
|
|
+ err = fmt.Errorf("解析图表额外配置失败, err: %v", e)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ legends := make(map[string]*data_manage.CorrelationChartLegend)
|
|
|
+ if extra != nil {
|
|
|
+ for _, v := range extra.LegendConfig {
|
|
|
+ s := fmt.Sprintf("%d-%d", v.SeriesId, v.EdbInfoId)
|
|
|
+ legends[s] = v
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取图表引用到的系列指标
|
|
|
+ chartMappingOb := new(data_manage.FactorEdbSeriesChartMapping)
|
|
|
+ cond := fmt.Sprintf(" AND %s = ? AND %s = 1", chartMappingOb.Cols().ChartInfoId, chartMappingOb.Cols().EdbUsed)
|
|
|
+ pars := make([]interface{}, 0)
|
|
|
+ pars = append(pars, chartInfoId)
|
|
|
+ chartMappings, e := chartMappingOb.GetItemsByCondition(cond, pars, []string{}, "")
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取图表引用系列指标失败")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 取出计算结果
|
|
|
+ yDataList = make([]data_manage.YData, 0)
|
|
|
+ yDate := "0000-00-00"
|
|
|
+ for k, m := range chartMappings {
|
|
|
+ var values []data_manage.FactorEdbSeriesCorrelationMatrixValues
|
|
|
+ if m.CalculateData != "" {
|
|
|
+ e = json.Unmarshal([]byte(m.CalculateData), &values)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("系列指标计算数据有误, err: %v", e)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var y []float64
|
|
|
+ for _, v := range values {
|
|
|
+ if k == 0 {
|
|
|
+ xEdbIdValue = append(xEdbIdValue, v.XData)
|
|
|
+ }
|
|
|
+ y = append(y, v.YData)
|
|
|
+ }
|
|
|
+ var yData data_manage.YData
|
|
|
+ yData.Date = yDate
|
|
|
+ yData.Value = y
|
|
|
+ yData.SeriesEdb.SeriesId = m.FactorEdbSeriesId
|
|
|
+ yData.SeriesEdb.EdbInfoId = m.EdbInfoId
|
|
|
+
|
|
|
+ // 图例
|
|
|
+ s := fmt.Sprintf("%d-%d", m.FactorEdbSeriesId, m.EdbInfoId)
|
|
|
+ legend := legends[s]
|
|
|
+ if legend != nil {
|
|
|
+ yData.Name = legend.LegendName
|
|
|
+ yData.Color = legend.Color
|
|
|
+ }
|
|
|
+ yDataList = append(yDataList, yData)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// FormatChartEdbInfoMappings 补充指标信息
|
|
|
+func FormatChartEdbInfoMappings(chartInfoId int, mappings []*data_manage.ChartEdbInfoMapping) (edbList []*data_manage.ChartEdbInfoMapping, err error) {
|
|
|
+ edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
|
|
|
+ if len(mappings) == 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range mappings {
|
|
|
+ if chartInfoId <= 0 {
|
|
|
+ v.IsAxis = 1
|
|
|
+ v.LeadValue = 0
|
|
|
+ v.LeadUnit = ""
|
|
|
+ v.ChartEdbMappingId = 0
|
|
|
+ v.ChartInfoId = 0
|
|
|
+ v.IsOrder = false
|
|
|
+ v.EdbInfoType = 1
|
|
|
+ v.ChartStyle = ""
|
|
|
+ v.ChartColor = ""
|
|
|
+ v.ChartWidth = 0
|
|
|
+ } else {
|
|
|
+ v.LeadUnitEn = data.GetLeadUnitEn(v.LeadUnit)
|
|
|
+ v.LeadUnitEn = data.GetLeadUnitEn(v.LeadUnit)
|
|
|
+ }
|
|
|
+ v.FrequencyEn = data.GetFrequencyEn(v.Frequency)
|
|
|
+ if v.Unit == `无` {
|
|
|
+ v.Unit = ``
|
|
|
+ }
|
|
|
+ edbList = append(edbList, v)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|