|
@@ -244,6 +244,7 @@ func (obj Percentile) GetEdbType() int {
|
|
|
type PercentileConfig struct {
|
|
|
CalculateValue int `description:"时间长度期数"`
|
|
|
CalculateUnit string `description:"时间长度频度"`
|
|
|
+ PercentType int `description:"百分位:0-数据区间(兼容历史数据); 1-数据个数;"`
|
|
|
}
|
|
|
|
|
|
// refresh 刷新
|
|
@@ -259,7 +260,7 @@ func (obj Percentile) refresh(to orm.TxOrmer, edbInfo, fromEdbInfo *EdbInfo, edb
|
|
|
}
|
|
|
|
|
|
// 获取百分位的指标数据
|
|
|
- fromDataList, err, errMsg := obj.getPercentileData(fromEdbInfo, percentileConfig.CalculateValue, percentileConfig.CalculateUnit)
|
|
|
+ fromDataList, err, errMsg := obj.getPercentileData(fromEdbInfo, percentileConfig.CalculateValue, percentileConfig.CalculateUnit, percentileConfig.PercentType)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
@@ -374,7 +375,7 @@ func (obj Percentile) calculate(edbInfoId int, date, edbInfoIdStr, edbCode, data
|
|
|
}
|
|
|
|
|
|
// GetPercentileData 获取百分位图表的指标数据
|
|
|
-func (obj Percentile) getPercentileData(fromEdbInfo *EdbInfo, calculateValue int, calculateUnit string) (newDataList []EdbInfoSearchData, err error, errMsg string) {
|
|
|
+func (obj Percentile) getPercentileData(fromEdbInfo *EdbInfo, calculateValue int, calculateUnit string, percentType int) (newDataList []EdbInfoSearchData, err error, errMsg string) {
|
|
|
// 获取时间基准指标在时间区间内的值
|
|
|
dataList := make([]*EdbInfoSearchData, 0)
|
|
|
switch fromEdbInfo.EdbInfoType {
|
|
@@ -408,33 +409,79 @@ func (obj Percentile) getPercentileData(fromEdbInfo *EdbInfo, calculateValue int
|
|
|
}
|
|
|
|
|
|
//百分位:对所选指标滚动地取对应时间长度的数据值,取最大值Max,最小值Min,计算Max-Min,百分位=(现值-Min)/(Max-Min),Max=Min时不予计算。
|
|
|
- for i, tmpData := range dataList {
|
|
|
- currDateTime, _ := time.ParseInLocation(utils.FormatDate, tmpData.DataTime, time.Local)
|
|
|
- maxVal := tmpData.Value
|
|
|
- minVal := tmpData.Value
|
|
|
- for k := 0; k < calculateDay; k++ {
|
|
|
- preVal, ok2 := dataMap[currDateTime.AddDate(0, 0, -k)]
|
|
|
- if ok2 {
|
|
|
- if preVal > maxVal {
|
|
|
- maxVal = preVal
|
|
|
- }
|
|
|
- if preVal < minVal {
|
|
|
- minVal = preVal
|
|
|
+ if percentType == utils.PercentCalculateTypeRange {
|
|
|
+ for i, tmpData := range dataList {
|
|
|
+ currDateTime, _ := time.ParseInLocation(utils.FormatDate, tmpData.DataTime, time.Local)
|
|
|
+ maxVal := tmpData.Value
|
|
|
+ minVal := tmpData.Value
|
|
|
+ for k := 0; k < calculateDay; k++ {
|
|
|
+ preVal, ok2 := dataMap[currDateTime.AddDate(0, 0, -k)]
|
|
|
+ if ok2 {
|
|
|
+ if preVal > maxVal {
|
|
|
+ maxVal = preVal
|
|
|
+ }
|
|
|
+ if preVal < minVal {
|
|
|
+ minVal = preVal
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if maxVal == minVal {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ tmpV := (tmpData.Value - minVal) / (maxVal - minVal) * 100
|
|
|
+ tmpV, _ = decimal.NewFromFloat(tmpV).Round(4).Float64()
|
|
|
+ //百分位=(现值-Min)/(Max-Min)
|
|
|
+ newDataList = append(newDataList, EdbInfoSearchData{
|
|
|
+ EdbDataId: i,
|
|
|
+ DataTime: dataList[i].DataTime,
|
|
|
+ Value: tmpV,
|
|
|
+ })
|
|
|
}
|
|
|
+ }
|
|
|
+ // 百分位数据个数算法
|
|
|
+ // 数据区间第一个和最后一个数据点的时间和数据分别为(T1,S1)(T2,S2); N=T1到T2指标数据个数, n=小于等于S2的数据个数
|
|
|
+ // 个数百分位=(n-1)/(N-1)
|
|
|
+ maxDay := len(dataList) // 往前找数据的边界
|
|
|
+ if percentType == utils.PercentCalculateTypeNum {
|
|
|
+ for i, d := range dataList {
|
|
|
+ // T2为当前日期
|
|
|
+ s2 := decimal.NewFromFloat(d.Value)
|
|
|
+ t2, _ := time.ParseInLocation(utils.FormatDate, d.DataTime, time.Local)
|
|
|
+
|
|
|
+ // 计算N和n
|
|
|
+ var bigN, tinyN int
|
|
|
+ for k := 0; k < maxDay; k++ {
|
|
|
+ // 往前找(时间长度)个有数据的, N理论上只有最前面几个日期<calculateDay, 后面的N=calculateDay
|
|
|
+ if bigN >= calculateDay {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ preVal, preOk := dataMap[t2.AddDate(0, 0, -k)]
|
|
|
+ if !preOk {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ bigN += 1
|
|
|
+ if decimal.NewFromFloat(preVal).LessThanOrEqual(s2) {
|
|
|
+ tinyN += 1
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if maxVal == minVal {
|
|
|
- continue
|
|
|
+ // N<=1时说明计算无效
|
|
|
+ if bigN <= 1 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ numerator := decimal.NewFromInt(int64(tinyN - 1))
|
|
|
+ denominator := decimal.NewFromInt(int64(bigN - 1))
|
|
|
+ // 因为是百分位所以这里是要*100, 跟之前的算法保持同步
|
|
|
+ percentVal, _ := numerator.Div(denominator).Mul(decimal.NewFromFloat(100)).Round(4).Float64()
|
|
|
+
|
|
|
+ // 写进数组并判断指标最大最小值
|
|
|
+ newDataList = append(newDataList, EdbInfoSearchData{
|
|
|
+ EdbDataId: i,
|
|
|
+ DataTime: dataList[i].DataTime,
|
|
|
+ Value: percentVal,
|
|
|
+ })
|
|
|
}
|
|
|
- tmpV := (tmpData.Value - minVal) / (maxVal - minVal) * 100
|
|
|
- tmpV, _ = decimal.NewFromFloat(tmpV).Round(4).Float64()
|
|
|
- //百分位=(现值-Min)/(Max-Min)
|
|
|
- newDataList = append(newDataList, EdbInfoSearchData{
|
|
|
- EdbDataId: i,
|
|
|
- DataTime: dataList[i].DataTime,
|
|
|
- Value: tmpV,
|
|
|
- })
|
|
|
}
|
|
|
|
|
|
return
|