|
@@ -66,6 +66,9 @@ type CoordinatePoint struct {
|
|
|
YEdbInfoId int
|
|
|
XDate string
|
|
|
YDate string
|
|
|
+ DateType int `description:"日期类型:1-最新日期;2-N天前;3-固定日期"`
|
|
|
+ DaysAgo int `description:"N天前的N值"`
|
|
|
+ ShowTips int `description:"是否显示标注:0-否;1-是"`
|
|
|
}
|
|
|
|
|
|
// GetChartData
|
|
@@ -161,7 +164,14 @@ func GetChartData(chartInfoId int, config request.ChartConfigReq) (edbList []*da
|
|
|
|
|
|
dataMap := make(map[string]float64)
|
|
|
dateMap := make(map[string]string)
|
|
|
+ dateTypeMap := make(map[int]int) // 日期配置key对应的日期类型
|
|
|
+ daysAgoMap := make(map[int]int) // 日期配置key对应的N天前的N值
|
|
|
+ showTipsMap := make(map[int]int) // 日期配置key对应点是否显示标注
|
|
|
+
|
|
|
for dateIndex, dateConfig := range config.DateConfigList {
|
|
|
+ dateTypeMap[dateIndex] = dateConfig.DateType
|
|
|
+ daysAgoMap[dateIndex] = dateConfig.Num
|
|
|
+ showTipsMap[dateIndex] = dateConfig.ShowTips
|
|
|
for _, edbInfoMapping := range mappingList {
|
|
|
// 数据会是正序的
|
|
|
dataList, ok := edbDataListMap[edbInfoMapping.EdbInfoId]
|
|
@@ -193,8 +203,8 @@ func GetChartData(chartInfoId int, config request.ChartConfigReq) (edbList []*da
|
|
|
endDateStr = dataEndDateStr
|
|
|
endDate = dataEndDate
|
|
|
currVal = dataList[k].Value
|
|
|
- case 2: // 2:N天前
|
|
|
- tmpEndDate := dataEndDate.AddDate(0, 0, -dateConfig.Num)
|
|
|
+ case 2: // 2:N天前(原为指标最新日期的N天前, 现为系统日期的N天)
|
|
|
+ tmpEndDate := time.Now().AddDate(0, 0, -dateConfig.Num)
|
|
|
tmpEndDateStr := tmpEndDate.Format(utils.FormatDate)
|
|
|
|
|
|
for i := k; i >= 0; i-- {
|
|
@@ -222,6 +232,45 @@ func GetChartData(chartInfoId int, config request.ChartConfigReq) (edbList []*da
|
|
|
currVal = dataList[i].Value
|
|
|
break
|
|
|
}
|
|
|
+ case 3: // 固定日期
|
|
|
+ if dateConfig.FixDate == "" {
|
|
|
+ errMsg = "固定日期不可为空"
|
|
|
+ err = fmt.Errorf("固定日期为空")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ strFixDate := dateConfig.FixDate
|
|
|
+ fixDate, e := time.ParseInLocation(utils.FormatDate, strFixDate, time.Local)
|
|
|
+ if e != nil {
|
|
|
+ errMsg = "固定日期格式有误"
|
|
|
+ err = fmt.Errorf("固定日期有误, FixDate: %s", dateConfig.FixDate)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ for i := k; i >= 0; i-- {
|
|
|
+ strThisDate := dataList[i].DataTime
|
|
|
+ // 如果正好是这一天,那么就直接break了
|
|
|
+ if strFixDate == strThisDate {
|
|
|
+ k = i
|
|
|
+ endDateStr = strThisDate
|
|
|
+ endDate = fixDate
|
|
|
+ currVal = dataList[i].Value
|
|
|
+ break
|
|
|
+ }
|
|
|
+ // 若固定日期无值, 则取固定日期之前, 能找到的第一个值(同上N天前的逻辑)
|
|
|
+ thisDate, e := time.ParseInLocation(utils.FormatDate, strThisDate, time.Local)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("数据日期格式有误: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if thisDate.After(fixDate) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ k = i
|
|
|
+ endDateStr = strThisDate
|
|
|
+ endDate = thisDate
|
|
|
+ currVal = dataList[i].Value
|
|
|
+ break
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 没有找到日期,那么就不处理
|
|
@@ -233,51 +282,85 @@ func GetChartData(chartInfoId int, config request.ChartConfigReq) (edbList []*da
|
|
|
earliestDate := endDate.AddDate(0, 0, -config.CalculateValue*moveUnitDays)
|
|
|
earliestDateStr := earliestDate.Format(utils.FormatDate)
|
|
|
|
|
|
- var minVal, maxVal float64
|
|
|
- var isNotFirst bool // 是否是第一条数据
|
|
|
- for i := k; i >= 0; i-- {
|
|
|
- tmpData := dataList[i]
|
|
|
- if !isNotFirst {
|
|
|
- maxVal = tmpData.Value
|
|
|
- minVal = tmpData.Value
|
|
|
- isNotFirst = true
|
|
|
- continue
|
|
|
- }
|
|
|
+ var percentVal float64 // 百分位计算值
|
|
|
+ // 百分位数据区间算法
|
|
|
+ if config.PercentType == utils.PercentCalculateTypeRange {
|
|
|
+ var minVal, maxVal float64
|
|
|
+ var isNotFirst bool // 是否是第一条数据
|
|
|
+ for i := k; i >= 0; i-- {
|
|
|
+ tmpData := dataList[i]
|
|
|
+ if !isNotFirst {
|
|
|
+ maxVal = tmpData.Value
|
|
|
+ minVal = tmpData.Value
|
|
|
+ isNotFirst = true
|
|
|
+ continue
|
|
|
+ }
|
|
|
|
|
|
- tmpDateStr := dataList[i].DataTime
|
|
|
- // 如果正好是这一天,那么就直接break了
|
|
|
- if earliestDateStr == tmpDateStr {
|
|
|
- break
|
|
|
- }
|
|
|
- tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
|
|
|
- if tmpErr != nil {
|
|
|
- err = tmpErr
|
|
|
- return
|
|
|
+ tmpDateStr := dataList[i].DataTime
|
|
|
+ // 如果正好是这一天,那么就直接break了
|
|
|
+ if earliestDateStr == tmpDateStr {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 如果这期的日期早于选择的日期,那么继续停止遍历
|
|
|
+ if tmpDate.Before(earliestDate) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ if tmpData.Value > maxVal {
|
|
|
+ maxVal = tmpData.Value
|
|
|
+ }
|
|
|
+ if tmpData.Value < minVal {
|
|
|
+ minVal = tmpData.Value
|
|
|
+ }
|
|
|
}
|
|
|
- // 如果这期的日期早于选择的日期,那么继续停止遍历
|
|
|
- if tmpDate.Before(earliestDate) {
|
|
|
+
|
|
|
+ // 最大值等于最小值,说明计算结果无效
|
|
|
+ if maxVal == minVal {
|
|
|
continue
|
|
|
}
|
|
|
+ // 数据区间百分位=(现值-Min)/(Max-Min)
|
|
|
+ tmpV := (currVal - minVal) / (maxVal - minVal) * 100
|
|
|
+ percentVal, _ = decimal.NewFromFloat(tmpV).Round(4).Float64()
|
|
|
+ }
|
|
|
|
|
|
- if tmpData.Value > maxVal {
|
|
|
- maxVal = tmpData.Value
|
|
|
+ // 百分位数据个数算法
|
|
|
+ // 数据区间第一个和最后一个数据点的时间和数据分别为(T1,S1)(T2,S2); N=T1到T2指标数据个数, n=小于等于S2的数据个数
|
|
|
+ // 个数百分位=(n-1)/(N-1)
|
|
|
+ if config.PercentType == utils.PercentCalculateTypeNum {
|
|
|
+ // T1为earliestDate, T2为endDate, S2为currVal
|
|
|
+ var tinyN, bigN int
|
|
|
+ lastVal := decimal.NewFromFloat(currVal)
|
|
|
+ for i := k; i >= 0; i-- {
|
|
|
+ date, e := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("数据日期格式有误: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if !date.Before(earliestDate) && !date.After(endDate) {
|
|
|
+ bigN += 1
|
|
|
+ dateVal := decimal.NewFromFloat(dataList[i].Value)
|
|
|
+ if dateVal.LessThanOrEqual(lastVal) {
|
|
|
+ tinyN += 1
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- if tmpData.Value < minVal {
|
|
|
- minVal = tmpData.Value
|
|
|
+ // N=1时说明计算无效
|
|
|
+ if bigN == 1 {
|
|
|
+ continue
|
|
|
}
|
|
|
+ numerator := decimal.NewFromInt(int64(tinyN - 1))
|
|
|
+ denominator := decimal.NewFromInt(int64(bigN - 1))
|
|
|
+ percentVal, _ = numerator.Div(denominator).Mul(decimal.NewFromFloat(100)).Round(4).Float64()
|
|
|
}
|
|
|
|
|
|
- // 最大值等于最小值,说明计算结果无效
|
|
|
- if maxVal == minVal {
|
|
|
- continue
|
|
|
- }
|
|
|
- //百分位=(现值-Min)/(Max-Min)
|
|
|
- tmpV := (currVal - minVal) / (maxVal - minVal) * 100
|
|
|
- tmpV, _ = decimal.NewFromFloat(tmpV).Round(4).Float64()
|
|
|
-
|
|
|
// key的生成(日期配置下标+指标id)
|
|
|
key := fmt.Sprint(dateIndex, "_", edbInfoMapping.EdbInfoId)
|
|
|
- dataMap[key] = tmpV
|
|
|
+ dataMap[key] = percentVal
|
|
|
dateMap[key] = endDateStr
|
|
|
}
|
|
|
}
|
|
@@ -341,6 +424,9 @@ func GetChartData(chartInfoId int, config request.ChartConfigReq) (edbList []*da
|
|
|
YEdbInfoId: yEdbInfoId,
|
|
|
XDate: dateMap[key1],
|
|
|
YDate: dateMap[key2],
|
|
|
+ DateType: dateTypeMap[dateIndex], // 日期类型
|
|
|
+ DaysAgo: daysAgoMap[dateIndex], // N天前的N值
|
|
|
+ ShowTips: showTipsMap[dateIndex], // 是否显示标注
|
|
|
})
|
|
|
}
|
|
|
|
|
@@ -512,6 +598,12 @@ func AddChartInfo(req request.AddChartReq, sysUser *system.Admin) (chartInfo *da
|
|
|
isSendEmail = false
|
|
|
return
|
|
|
}
|
|
|
+ if req.PercentType != utils.PercentCalculateTypeRange && req.PercentType != utils.PercentCalculateTypeNum {
|
|
|
+ errMsg = "请选择百分位"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
// 品种配置
|
|
|
if len(req.VarietyList) < 0 {
|
|
|
errMsg = "请选择品种!"
|
|
@@ -610,6 +702,8 @@ func AddChartInfo(req request.AddChartReq, sysUser *system.Admin) (chartInfo *da
|
|
|
//chartInfo.SeasonEndDate = req.EndDate
|
|
|
chartInfo.LeftMin = req.LeftMin
|
|
|
chartInfo.LeftMax = req.LeftMax
|
|
|
+ chartInfo.XMin = req.XMin
|
|
|
+ chartInfo.XMax = req.XMax
|
|
|
//chartInfo.RightMin = req.RightMin
|
|
|
//chartInfo.RightMax = req.RightMax
|
|
|
//chartInfo.Disabled = disableVal
|
|
@@ -724,6 +818,12 @@ func EditChartInfo(req request.EditChartReq, sysUser *system.Admin) (chartItem *
|
|
|
isSendEmail = false
|
|
|
return
|
|
|
}
|
|
|
+ if req.PercentType != utils.PercentCalculateTypeRange && req.PercentType != utils.PercentCalculateTypeNum {
|
|
|
+ errMsg = "请选择百分位"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ isSendEmail = false
|
|
|
+ return
|
|
|
+ }
|
|
|
// 品种配置
|
|
|
if len(req.VarietyList) < 0 {
|
|
|
errMsg = "请选择品种!"
|
|
@@ -783,7 +883,11 @@ func EditChartInfo(req request.EditChartReq, sysUser *system.Admin) (chartItem *
|
|
|
chartItem.ChartName = req.ChartName
|
|
|
chartItem.ExtraConfig = string(extraConfigByte)
|
|
|
chartItem.ModifyTime = time.Now()
|
|
|
- chartUpdateCols := []string{"ChartName", "ExtraConfig", "ModifyTime"}
|
|
|
+ chartItem.LeftMin = req.LeftMin
|
|
|
+ chartItem.LeftMax = req.LeftMax
|
|
|
+ chartItem.XMin = req.XMin
|
|
|
+ chartItem.XMax = req.XMax
|
|
|
+ chartUpdateCols := []string{"ChartName", "ExtraConfig", "ModifyTime", "LeftMin", "LeftMax", "XMin", "XMax"}
|
|
|
|
|
|
// 跨品种分析配置
|
|
|
chartInfoCrossVariety, err := cross_varietyModel.GetChartInfoCrossVarietyByChartInfoId(chartItem.ChartInfoId)
|