|
@@ -0,0 +1,2478 @@
|
|
|
+package services
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "eta/eta_forum_hub/models"
|
|
|
+ "eta/eta_forum_hub/models/data"
|
|
|
+ "eta/eta_forum_hub/utils"
|
|
|
+ "fmt"
|
|
|
+ "github.com/shopspring/decimal"
|
|
|
+ "math"
|
|
|
+ "sort"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+type ChartInfoReq struct {
|
|
|
+ ChartInfoId int `description:"图表id,新增时传0"`
|
|
|
+}
|
|
|
+
|
|
|
+// DeleteChartInfoDataRedis 清除图表缓存
|
|
|
+func DeleteChartInfoDataRedis(bodyByte []byte) (err error) {
|
|
|
+ var req ChartInfoReq
|
|
|
+ err = json.Unmarshal(bodyByte, &req)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.ChartInfoId > 0 {
|
|
|
+ err = utils.Rc.Delete(GetChartInfoDataKey(req.ChartInfoId))
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetChartInfoDataKey 获取图表缓存的key
|
|
|
+func GetChartInfoDataKey(chartInfoId int) string {
|
|
|
+ key := fmt.Sprint(utils.CACHE_CHART_INFO_DATA, chartInfoId)
|
|
|
+ return key
|
|
|
+}
|
|
|
+
|
|
|
+// GetChartEdbData 获取图表的指标数据
|
|
|
+// GetChartEdbData 获取图表的指标数据
|
|
|
+func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, extraConfigStr string, seasonExtraConfig string) (edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, yDataList []models.YData, dataResp interface{}, err error, errMsg string) {
|
|
|
+ edbList = make([]*models.ChartEdbInfoMapping, 0)
|
|
|
+ xEdbIdValue = make([]int, 0)
|
|
|
+ yDataList = make([]models.YData, 0)
|
|
|
+
|
|
|
+ var extraConfig interface{}
|
|
|
+ switch chartType {
|
|
|
+ case 6:
|
|
|
+ var tmpConfig models.ChartTimeCombineExtraConf
|
|
|
+ if extraConfigStr != `` {
|
|
|
+ err = json.Unmarshal([]byte(extraConfigStr), &tmpConfig)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "雷达图配置异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ extraConfig = tmpConfig
|
|
|
+ case 7: // 柱形图
|
|
|
+ var barConfig models.BarChartInfoReq
|
|
|
+ if extraConfigStr == `` {
|
|
|
+ errMsg = "柱方图未配置"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = json.Unmarshal([]byte(extraConfigStr), &barConfig)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "柱方图配置异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ extraConfig = barConfig
|
|
|
+ case 10: // 截面散点图
|
|
|
+ var tmpExtraConfig models.SectionScatterReq
|
|
|
+ if extraConfigStr == `` {
|
|
|
+ errMsg = "截面散点图未配置"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "截面散点配置异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ extraConfig = tmpExtraConfig
|
|
|
+ case utils.CHART_TYPE_RADAR:
|
|
|
+ var barConfig models.RadarChartInfoReq
|
|
|
+ if extraConfigStr == `` {
|
|
|
+ errMsg = "雷达图未配置"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = json.Unmarshal([]byte(extraConfigStr), &barConfig)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "雷达图配置异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ extraConfig = barConfig
|
|
|
+ case utils.CHART_TYPE_SECTION_COMBINE:
|
|
|
+ // 预览和详情都走这个接口
|
|
|
+ var sectionExtraConfig models.ChartSectionAllExtraConf
|
|
|
+ if extraConfigStr == `` {
|
|
|
+ errMsg = "截面组合图未配置"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if chartInfoId > 0 {
|
|
|
+ var sectionExtraConfigTmp models.ChartSectionExtraConf
|
|
|
+ err = json.Unmarshal([]byte(extraConfigStr), §ionExtraConfigTmp)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "截面组合图配置异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sectionExtraConfig.XDataList = sectionExtraConfigTmp.XDataList
|
|
|
+ sectionExtraConfig.BaseChartSeriesName = sectionExtraConfigTmp.BaseChartSeriesName
|
|
|
+ sectionExtraConfig.UnitList = sectionExtraConfigTmp.UnitList
|
|
|
+ sectionExtraConfig.DateConfList = sectionExtraConfigTmp.DateConfList
|
|
|
+ sectionExtraConfig.IsHeap = sectionExtraConfigTmp.IsHeap
|
|
|
+ sectionExtraConfig.SortType = sectionExtraConfigTmp.SortType
|
|
|
+ // 查询所有的seriesEdb
|
|
|
+ seriesEdbList, e := models.GetChartSeriesEdbByChartInfoId(chartInfoId)
|
|
|
+ if e != nil {
|
|
|
+ errMsg = "查询seriesEdb失败"
|
|
|
+ err = errors.New(errMsg + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // todo 是否有必要返回单位信息
|
|
|
+ // 组装成map
|
|
|
+ seriesEdbMap := make(map[int][]*models.ChartSectionSeriesEdbConf)
|
|
|
+ for _, v := range seriesEdbList {
|
|
|
+ var dateConf *models.ChartSectionSeriesDateConfItem
|
|
|
+ if v.DateConf != "" {
|
|
|
+ err = json.Unmarshal([]byte(v.DateConf), &dateConf)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "截面组合图配置异常"
|
|
|
+ err = errors.New(errMsg + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tmp := &models.ChartSectionSeriesEdbConf{
|
|
|
+ ChartSeriesEdbMappingId: v.ChartSeriesEdbMappingId,
|
|
|
+ ChartSeriesId: v.ChartSeriesId,
|
|
|
+ //ChartInfoId: v.ChartInfoId,
|
|
|
+ EdbInfoId: v.EdbInfoId,
|
|
|
+ DateConf: dateConf,
|
|
|
+ EdbName: "",
|
|
|
+ EdbNameEn: "",
|
|
|
+ Unit: "",
|
|
|
+ UnitEn: "",
|
|
|
+ DateConfName: v.DateConfName,
|
|
|
+ DateConfType: v.DateConfType,
|
|
|
+ }
|
|
|
+ seriesEdbMap[v.ChartSeriesId] = append(seriesEdbMap[v.ChartSeriesId], tmp)
|
|
|
+ }
|
|
|
+ //查询series
|
|
|
+ seriesListTmp, e := models.GetChartSeriesByChartInfoId(chartInfoId)
|
|
|
+ if e != nil {
|
|
|
+ errMsg = "查询series失败"
|
|
|
+ err = errors.New(errMsg + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ seriesList := make([]*models.ChartSectionSeriesItem, 0)
|
|
|
+ for _, v := range seriesListTmp {
|
|
|
+
|
|
|
+ tmpSeries := &models.ChartSectionSeriesItem{
|
|
|
+ ChartSeriesId: v.ChartSeriesId,
|
|
|
+ SeriesName: v.SeriesName,
|
|
|
+ SeriesNameEn: v.SeriesNameEn,
|
|
|
+ ChartStyle: v.ChartStyle,
|
|
|
+ ChartColor: v.ChartColor,
|
|
|
+ ChartWidth: v.ChartWidth,
|
|
|
+ IsPoint: v.IsPoint,
|
|
|
+ IsNumber: v.IsNumber,
|
|
|
+ IsAxis: v.IsAxis,
|
|
|
+ MaxData: v.MaxData,
|
|
|
+ MinData: v.MinData,
|
|
|
+ //IsOrder: false,
|
|
|
+ EdbInfoList: nil,
|
|
|
+ DataList: nil,
|
|
|
+ }
|
|
|
+ edbInfoList, ok := seriesEdbMap[v.ChartSeriesId]
|
|
|
+ if ok {
|
|
|
+ tmpSeries.EdbInfoList = edbInfoList
|
|
|
+ }
|
|
|
+ seriesList = append(seriesList, tmpSeries)
|
|
|
+ }
|
|
|
+ sectionExtraConfig.SeriesList = seriesList
|
|
|
+
|
|
|
+ } else {
|
|
|
+ err = json.Unmarshal([]byte(extraConfigStr), §ionExtraConfig)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "截面组合图配置异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //校验引用日期名称是否重复
|
|
|
+ dateNameMap := make(map[string]int)
|
|
|
+ dateNameEnMap := make(map[string]int)
|
|
|
+ for _, v := range sectionExtraConfig.DateConfList {
|
|
|
+ if _, ok := dateNameMap[v.DateConfName]; ok {
|
|
|
+ errMsg = "截面组合图引用日期名称设置重复"
|
|
|
+ err = errors.New(errMsg + v.DateConfName)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if _, ok := dateNameEnMap[v.DateConfNameEn]; ok {
|
|
|
+ errMsg = "截面组合图引用日期名称设置重复"
|
|
|
+ err = errors.New(errMsg + v.DateConfNameEn)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if v.DateConfName != "" {
|
|
|
+ dateNameMap[v.DateConfName] = 1
|
|
|
+ }
|
|
|
+ if v.DateConfNameEn != "" {
|
|
|
+ dateNameEnMap[v.DateConfNameEn] = 1
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //检查系列名称是否重复
|
|
|
+ seriesNameMap := make(map[string]int)
|
|
|
+ seriesNameEnMap := make(map[string]int)
|
|
|
+ for _, v := range sectionExtraConfig.SeriesList {
|
|
|
+ if _, ok := seriesNameMap[v.SeriesName]; ok {
|
|
|
+ errMsg = "截面组合图系列名称设置重复"
|
|
|
+ err = errors.New(errMsg + v.SeriesName)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if _, ok := seriesNameEnMap[v.SeriesNameEn]; ok {
|
|
|
+ errMsg = "截面组合图系列名称设置重复"
|
|
|
+ err = errors.New(errMsg + v.SeriesNameEn)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if v.SeriesName != "" {
|
|
|
+ seriesNameMap[v.SeriesName] = 1
|
|
|
+ }
|
|
|
+ if v.SeriesNameEn != "" {
|
|
|
+ seriesNameEnMap[v.SeriesNameEn] = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查基准系列是否设置
|
|
|
+ if sectionExtraConfig.BaseChartSeriesName == "" {
|
|
|
+ errMsg = "截面组合图基准系列名称未设置"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //todo 如果是详情接口,应该要从其他表里查询配置
|
|
|
+ extraConfig = sectionExtraConfig
|
|
|
+ default:
|
|
|
+ xEdbIdValue = make([]int, 0)
|
|
|
+ yDataList = make([]models.YData, 0)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 指标对应的所有数据
|
|
|
+ edbDataListMap, edbList, err := getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, seasonExtraConfig)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 特殊图形数据处理
|
|
|
+ switch chartType {
|
|
|
+ case 2: // 季节性图
|
|
|
+ if seasonExtraConfig != "" {
|
|
|
+ // 季节性图计算不管图上数据时间,拿所有数据
|
|
|
+ _, tempEdbList, e := getEdbDataMapList(chartInfoId, chartType, calendar, "1990-01-01", "", mappingList, seasonExtraConfig)
|
|
|
+ if e != nil {
|
|
|
+ err = e
|
|
|
+ return
|
|
|
+ }
|
|
|
+ dataResp, err = SeasonChartData(tempEdbList, seasonExtraConfig)
|
|
|
+ } else {
|
|
|
+ // 兼容无配置的老图
|
|
|
+ dataResp = new(models.SeasonChartResp)
|
|
|
+ }
|
|
|
+ case 6: //时序组合图
|
|
|
+ //判断是否堆积
|
|
|
+ timeConf := extraConfig.(models.ChartTimeCombineExtraConf)
|
|
|
+ if extraConfigStr == "" { //历史数据,默认开启堆积
|
|
|
+ timeConf = models.ChartTimeCombineExtraConf{
|
|
|
+ IsHeap: 1,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dataResp = models.ChartTimeCombineDataResp{IsHeap: timeConf.IsHeap}
|
|
|
+ case 7: // 柱形图
|
|
|
+ barChartConf := extraConfig.(models.BarChartInfoReq)
|
|
|
+ xEdbIdValue, yDataList, err = BarChartData(mappingList, edbDataListMap, barChartConf.DateList, barChartConf.Sort)
|
|
|
+
|
|
|
+ for k := range yDataList {
|
|
|
+ yDataList[k].Unit = barChartConf.Unit
|
|
|
+ yDataList[k].UnitEn = barChartConf.UnitEn
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range edbList {
|
|
|
+ // 指标别名
|
|
|
+ if barChartConf.EdbInfoIdList != nil && len(barChartConf.EdbInfoIdList) > 0 {
|
|
|
+ for _, reqEdb := range barChartConf.EdbInfoIdList {
|
|
|
+ if v.EdbInfoId == reqEdb.EdbInfoId {
|
|
|
+ v.EdbAliasName = reqEdb.Name
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case 10: // 截面散点图
|
|
|
+ sectionScatterConf := extraConfig.(models.SectionScatterReq)
|
|
|
+ xEdbIdValue, dataResp, err = GetSectionScatterChartData(chartInfoId, mappingList, edbDataListMap, sectionScatterConf)
|
|
|
+
|
|
|
+ var tmpExtraConfig models.SectionScatterReq
|
|
|
+ if extraConfigStr == `` {
|
|
|
+ errMsg = "截面散点图未配置"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "截面散点配置异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 这个数据没有必要返回给前端
|
|
|
+ for _, v := range edbList {
|
|
|
+ v.DataList = nil
|
|
|
+ }
|
|
|
+ case utils.CHART_TYPE_SECTION_COMBINE: // 截面组合图
|
|
|
+ sectionConf := extraConfig.(models.ChartSectionAllExtraConf)
|
|
|
+ var chartInfo *models.ChartInfo
|
|
|
+ if chartInfoId > 0 {
|
|
|
+ chartInfo, err = models.GetChartInfoById(chartInfoId)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "获取图表信息失败"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ xEdbIdValue, dataResp, err = GetChartSectionCombineData(chartInfo, mappingList, edbDataListMap, sectionConf)
|
|
|
+
|
|
|
+ // 这个数据没有必要返回给前端
|
|
|
+ for _, v := range edbList {
|
|
|
+ v.DataList = nil
|
|
|
+ }
|
|
|
+ case utils.CHART_TYPE_RADAR: //雷达图
|
|
|
+ radarConf := extraConfig.(models.RadarChartInfoReq)
|
|
|
+ xEdbIdValue, dataResp, err = RadarChartData(mappingList, edbDataListMap, radarConf)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetEdbDataMapList 获取指标最后的基础数据
|
|
|
+func GetEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, seasonExtra string) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
|
|
|
+ edbDataListMap, edbList, err = getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, seasonExtra)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// getEdbDataMapList 获取指标最后的基础数据
|
|
|
+func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, seasonExtraConfig string) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
|
|
|
+ // 指标对应的所有数据
|
|
|
+ edbDataListMap = make(map[int][]*models.EdbDataList)
|
|
|
+
|
|
|
+ for _, v := range mappingList {
|
|
|
+ //fmt.Println("v:", v.EdbInfoId)
|
|
|
+ item := new(models.ChartEdbInfoMapping)
|
|
|
+ item.EdbInfoId = v.EdbInfoId
|
|
|
+ item.SourceName = v.SourceName
|
|
|
+ item.Source = v.Source
|
|
|
+ item.EdbCode = v.EdbCode
|
|
|
+ item.EdbName = v.EdbName
|
|
|
+ item.EdbNameEn = v.EdbNameEn
|
|
|
+ item.Frequency = v.Frequency
|
|
|
+ item.EdbType = v.EdbType
|
|
|
+ item.FrequencyEn = GetFrequencyEn(v.Frequency)
|
|
|
+ if v.Unit != `无` {
|
|
|
+ item.Unit = v.Unit
|
|
|
+ }
|
|
|
+ item.UnitEn = v.UnitEn
|
|
|
+ item.StartDate = v.StartDate
|
|
|
+ item.EndDate = v.EndDate
|
|
|
+ item.ModifyTime = v.ModifyTime
|
|
|
+ item.EdbInfoCategoryType = v.EdbInfoCategoryType
|
|
|
+ item.PredictChartColor = v.PredictChartColor
|
|
|
+ item.ClassifyId = v.ClassifyId
|
|
|
+ if chartInfoId <= 0 {
|
|
|
+ item.IsAxis = 1
|
|
|
+ item.LeadValue = 0
|
|
|
+ item.LeadUnit = ""
|
|
|
+ item.ChartEdbMappingId = 0
|
|
|
+ item.ChartInfoId = 0
|
|
|
+ item.IsOrder = false
|
|
|
+ item.EdbInfoType = 1
|
|
|
+ item.ChartStyle = ""
|
|
|
+ item.ChartColor = ""
|
|
|
+ item.ChartWidth = 0
|
|
|
+ item.MaxData = v.MaxValue
|
|
|
+ item.MinData = v.MinValue
|
|
|
+ } else {
|
|
|
+ item.IsAxis = v.IsAxis
|
|
|
+ item.EdbInfoType = v.EdbInfoType
|
|
|
+ item.LeadValue = v.LeadValue
|
|
|
+ item.LeadUnit = v.LeadUnit
|
|
|
+ item.LeadUnitEn = GetLeadUnitEn(v.LeadUnit)
|
|
|
+ item.ChartEdbMappingId = v.ChartEdbMappingId
|
|
|
+ item.ChartInfoId = v.ChartInfoId
|
|
|
+ item.ChartStyle = v.ChartStyle
|
|
|
+ item.ChartColor = v.ChartColor
|
|
|
+ item.ChartWidth = v.ChartWidth
|
|
|
+ item.IsOrder = v.IsOrder
|
|
|
+ item.MaxData = v.MaxData
|
|
|
+ item.MinData = v.MinData
|
|
|
+ }
|
|
|
+ item.LatestValue = v.LatestValue
|
|
|
+ item.LatestDate = v.LatestDate
|
|
|
+ item.UniqueCode = v.UniqueCode
|
|
|
+ item.MoveLatestDate = v.LatestDate
|
|
|
+ item.EdbAliasName = v.EdbAliasName
|
|
|
+ item.IsConvert = v.IsConvert
|
|
|
+ item.ConvertType = v.ConvertType
|
|
|
+ item.ConvertValue = v.ConvertValue
|
|
|
+ item.ConvertUnit = v.ConvertUnit
|
|
|
+ item.ConvertEnUnit = v.ConvertEnUnit
|
|
|
+ item.IsJoinPermission = v.IsJoinPermission
|
|
|
+
|
|
|
+ var startDateReal string
|
|
|
+ var diffSeconds int64
|
|
|
+ if chartType == 2 { //季节性图
|
|
|
+ startDateReal = startDate
|
|
|
+ if len(mappingList) > 1 {
|
|
|
+ item.IsAxis = v.IsAxis
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 { //领先指标
|
|
|
+ var startTimeRealTemp time.Time
|
|
|
+ startDateParse, _ := time.Parse(utils.FormatDate, startDate)
|
|
|
+ switch v.LeadUnit {
|
|
|
+ case "天":
|
|
|
+ startTimeRealTemp = startDateParse.AddDate(0, 0, -v.LeadValue)
|
|
|
+ case "月":
|
|
|
+ startTimeRealTemp = startDateParse.AddDate(0, -v.LeadValue, 0)
|
|
|
+ case "季":
|
|
|
+ startTimeRealTemp = startDateParse.AddDate(0, -3*v.LeadValue, 0)
|
|
|
+ case "周":
|
|
|
+ startTimeRealTemp = startDateParse.AddDate(0, 0, -7*v.LeadValue)
|
|
|
+ case "年":
|
|
|
+ startTimeRealTemp = startDateParse.AddDate(-v.LeadValue, 0, 0)
|
|
|
+ }
|
|
|
+ if startTimeRealTemp.Before(startDateParse) {
|
|
|
+ startDateReal = startTimeRealTemp.Format(utils.FormatDate)
|
|
|
+ diffSeconds = (int64(startTimeRealTemp.UnixNano()) - int64(startDateParse.UnixNano())) / 1e6
|
|
|
+ } else {
|
|
|
+ startDateReal = startDate
|
|
|
+ diffSeconds = 0
|
|
|
+ }
|
|
|
+
|
|
|
+ // todo 预测指标的开始日期也要偏移
|
|
|
+ /*{
|
|
|
+ day, tmpErr := utils.GetDaysBetween2Date(utils.FormatDate, startDate, startDateReal)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ moveLatestDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, item.MoveLatestDate, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ item.MoveLatestDate = moveLatestDateTime.AddDate(0, 0, day).Format(utils.FormatDate)
|
|
|
+ }*/
|
|
|
+ } else {
|
|
|
+ startDateReal = startDate
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //fmt.Println("line 1011 chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
|
|
|
+ calendarPreYear := 0
|
|
|
+ if calendar == "农历" {
|
|
|
+ newStartDateReal, err := time.Parse(utils.FormatDate, startDateReal)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("time.Parse:" + err.Error())
|
|
|
+ }
|
|
|
+ calendarPreYear = newStartDateReal.Year() - 1
|
|
|
+ newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
|
|
|
+ startDateReal = newStartDateReal.Format(utils.FormatDate)
|
|
|
+ }
|
|
|
+ dataList := make([]*models.EdbDataList, 0)
|
|
|
+ dataList, err = GetEdbDataList(v.EdbInfoId, v.EdbType, startDateReal, endDate)
|
|
|
+ if err != nil {
|
|
|
+ // 获取指标数据失败
|
|
|
+ err = fmt.Errorf("获取指标数据失败 GetEdbDataList error, %v", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if v.IsConvert == 1 {
|
|
|
+ switch v.ConvertType {
|
|
|
+ case 1:
|
|
|
+ for i, data := range dataList {
|
|
|
+ dataList[i].Value = data.Value * v.ConvertValue
|
|
|
+ }
|
|
|
+ //item.MaxData = item.MaxData * v.ConvertValue
|
|
|
+ //item.MinData = item.MinData * v.ConvertValue
|
|
|
+ case 2:
|
|
|
+ for i, data := range dataList {
|
|
|
+ dataList[i].Value = data.Value / v.ConvertValue
|
|
|
+ }
|
|
|
+ //item.MaxData = item.MaxData / v.ConvertValue
|
|
|
+ //item.MinData = item.MinData / v.ConvertValue
|
|
|
+ case 3:
|
|
|
+ for i, data := range dataList {
|
|
|
+ if data.Value <= 0 {
|
|
|
+ err = errors.New("数据中含有负数或0,无法对数运算")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ dataList[i].Value = math.Log(data.Value) / math.Log(v.ConvertValue)
|
|
|
+ }
|
|
|
+ //item.MaxData = math.Log(item.MaxData) / math.Log(v.ConvertValue)
|
|
|
+ //item.MinData = math.Log(item.MinData) / math.Log(v.ConvertValue)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ edbDataListMap[v.EdbInfoId] = dataList
|
|
|
+
|
|
|
+ if diffSeconds != 0 && v.EdbInfoType == 0 {
|
|
|
+ dataListLen := len(dataList)
|
|
|
+ for i := 0; i < dataListLen; i++ {
|
|
|
+ dataList[i].DataTimestamp = dataList[i].DataTimestamp - diffSeconds
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if chartType == 2 && item.IsAxis == 1 {
|
|
|
+ latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
|
|
|
+ if tmpErr != nil {
|
|
|
+ //item.DataList = dataList
|
|
|
+ item.IsNullData = true
|
|
|
+ edbList = append(edbList, item)
|
|
|
+ continue
|
|
|
+ err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if calendar == "农历" {
|
|
|
+ if len(dataList) <= 0 {
|
|
|
+ result := new(data.EdbDataResult)
|
|
|
+ item.DataList = result
|
|
|
+ } else {
|
|
|
+ result, tmpErr := data.AddCalculateQuarterV6(dataList)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ quarterDataList, tErr := GetSeasonEdbInfoDataListByXDateNong(result, latestDate, seasonExtraConfig, calendarPreYear)
|
|
|
+ if tErr != nil {
|
|
|
+ err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ item.DataList = quarterDataList
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ quarterDataList, tErr := GetSeasonEdbInfoDataListByXDate(dataList, latestDate, seasonExtraConfig)
|
|
|
+ if tErr != nil {
|
|
|
+ err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ item.DataList = quarterDataList
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if chartType == 2 && item.IsAxis == 0 {
|
|
|
+ // 右轴数据处理,只要最新一年
|
|
|
+ latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
|
|
|
+ if tmpErr != nil {
|
|
|
+ //item.DataList = dataList
|
|
|
+ item.IsNullData = true
|
|
|
+ edbList = append(edbList, item)
|
|
|
+ continue
|
|
|
+ err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ newDataList := make([]*models.EdbDataList, 0)
|
|
|
+ for _, v := range dataList {
|
|
|
+ dataTime, e := time.Parse(utils.FormatDate, v.DataTime)
|
|
|
+ if e != nil {
|
|
|
+ err = errors.New("季节性图处理右轴指标数据转换日期失败,Err:" + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if dataTime.Year() == latestDate.Year() {
|
|
|
+ newDataList = append(newDataList, v)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ item.DataList = newDataList
|
|
|
+ } else if chartType == 7 || chartType == utils.CHART_TYPE_RADAR { //柱方图
|
|
|
+ //item.DataList = dataList
|
|
|
+ } else {
|
|
|
+ item.DataList = dataList
|
|
|
+ }
|
|
|
+ edbList = append(edbList, item)
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetSeasonEdbInfoDataListByXDate 季节性图的指标数据根据横轴展示
|
|
|
+func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate time.Time, seasonExtraConfig string) (quarterDataListSort models.QuarterDataList, err error) {
|
|
|
+ xStartDate := "01-01"
|
|
|
+ xEndDate := "12-31"
|
|
|
+ jumpYear := 0
|
|
|
+ legends := make([]models.SeasonChartLegend, 0)
|
|
|
+ var seasonExtra models.SeasonExtraItem
|
|
|
+ if seasonExtraConfig != "" {
|
|
|
+ err = json.Unmarshal([]byte(seasonExtraConfig), &seasonExtra)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if seasonExtra.XStartDate != "" {
|
|
|
+ xStartDate = seasonExtra.XStartDate
|
|
|
+ xEndDate = seasonExtra.XEndDate
|
|
|
+ jumpYear = seasonExtra.JumpYear
|
|
|
+ legends = seasonExtra.ChartLegend
|
|
|
+ }
|
|
|
+
|
|
|
+ length := len(dataList)
|
|
|
+ if length == 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ legendMap := make(map[string]string, 0)
|
|
|
+ if len(legends) > 0 {
|
|
|
+ for _, v := range legends {
|
|
|
+ legendMap[v.Name] = v.Value
|
|
|
+ }
|
|
|
+ }
|
|
|
+ latestDateStr := latestDate.Format(utils.FormatDate)
|
|
|
+
|
|
|
+ //判断横轴的两个时间之间是不是跨年了,如果跨年了,则横轴截止年份比起始年份+1,如果不跨年,截止年份等于起始年份
|
|
|
+ //根据数据确定最早的年份,和最近年份
|
|
|
+ //根据横轴的日期,汇总所有的年份
|
|
|
+ startDate := dataList[0].DataTime
|
|
|
+ startDateT, tmpErr := time.Parse(utils.FormatDate, startDate)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ startYear := startDateT.Year()
|
|
|
+ //获取数据的最新日期
|
|
|
+ lastDate := dataList[length-1].DataTime
|
|
|
+ lastDateT, tmpErr := time.Parse(utils.FormatDate, lastDate)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ endYear := lastDateT.Year()
|
|
|
+ nowYear := time.Now().Year()
|
|
|
+ dataMap := make(map[string]models.QuarterXDateItem, 0)
|
|
|
+
|
|
|
+ quarterDataList := make([]*models.QuarterData, 0)
|
|
|
+ quarterMap := make(map[string][]*models.EdbDataList, 0)
|
|
|
+
|
|
|
+ //整理出日期
|
|
|
+ idx := 1
|
|
|
+ chartLegendMap := make(map[string]int, 0)
|
|
|
+ for currentStartYear := startYear; currentStartYear <= endYear; currentStartYear++ {
|
|
|
+ startStr := fmt.Sprintf("%d-%s", currentStartYear, xStartDate)
|
|
|
+ currentEndYear := currentStartYear
|
|
|
+ if jumpYear == 1 {
|
|
|
+ currentEndYear = currentStartYear + 1
|
|
|
+ }
|
|
|
+ endStr := fmt.Sprintf("%d-%s", currentEndYear, xEndDate)
|
|
|
+ name := fmt.Sprintf("%s_%s", startStr, endStr)
|
|
|
+ showName := fmt.Sprintf("%d_%d", currentStartYear, currentEndYear)
|
|
|
+
|
|
|
+ startT, tEr := time.Parse(utils.FormatDate, startStr)
|
|
|
+ if tEr != nil {
|
|
|
+ err = tEr
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ endT, tEr := time.Parse(utils.FormatDate, endStr)
|
|
|
+ if tEr != nil {
|
|
|
+ err = tEr
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if lastDateT.Before(startT) {
|
|
|
+ //如果最新的日期在起始日之前,则跳出循环
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ if endT.Year() > nowYear {
|
|
|
+ //如果最新的日期比真实年份要大,则数据全部按照最大的年份补齐
|
|
|
+ nowYear = endT.Year()
|
|
|
+ }
|
|
|
+
|
|
|
+ item := models.QuarterXDateItem{
|
|
|
+ StartDate: startT,
|
|
|
+ EndDate: endT,
|
|
|
+ ShowName: showName,
|
|
|
+ }
|
|
|
+ dataMap[name] = item
|
|
|
+ chartLegendMap[name] = idx
|
|
|
+ idx++
|
|
|
+ fmt.Println("年份" + showName + "日期" + startStr + " " + endStr)
|
|
|
+ if lastDateT.Before(endT) {
|
|
|
+ //如果最新的日期在起始日之前,则跳出循环
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lenYear := len(dataMap)
|
|
|
+ for k, v := range dataMap {
|
|
|
+ if i, ok := chartLegendMap[k]; ok {
|
|
|
+ v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
|
|
|
+ }
|
|
|
+ dataMap[k] = v
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range dataList {
|
|
|
+ dataTimeT, _ := time.Parse(utils.FormatDate, v.DataTime)
|
|
|
+ year := dataTimeT.Year()
|
|
|
+ newItemDate := dataTimeT.AddDate(nowYear-year, 0, 0)
|
|
|
+ for k, dateItem := range dataMap {
|
|
|
+ tmpVal := models.EdbDataList{
|
|
|
+ EdbDataId: v.EdbDataId,
|
|
|
+ EdbInfoId: v.EdbInfoId,
|
|
|
+ DataTime: v.DataTime,
|
|
|
+ DataTimestamp: v.DataTimestamp,
|
|
|
+ Value: v.Value,
|
|
|
+ }
|
|
|
+ if (dateItem.StartDate.Before(dataTimeT) && dateItem.EndDate.After(dataTimeT)) || dateItem.StartDate == dataTimeT || dateItem.EndDate == dataTimeT {
|
|
|
+ if jumpYear == 1 {
|
|
|
+ //计算前一年最大的日期, 只补齐数据到去年
|
|
|
+ beforeYearMaxDate := fmt.Sprintf("%d-12-31", dateItem.StartDate.Year())
|
|
|
+ beforeYearMaxDateT, _ := time.Parse(utils.FormatDate, beforeYearMaxDate)
|
|
|
+ if dataTimeT.Before(beforeYearMaxDateT) || dataTimeT == beforeYearMaxDateT {
|
|
|
+ newItemDate = dataTimeT.AddDate(nowYear-year-1, 0, 0)
|
|
|
+ } else {
|
|
|
+ newItemDate = dataTimeT.AddDate(nowYear-year, 0, 0)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ newItemDate = dataTimeT.AddDate(nowYear-year, 0, 0)
|
|
|
+ }
|
|
|
+ timestamp := newItemDate.UnixNano() / 1e6
|
|
|
+ tmpVal.DataTimestamp = timestamp
|
|
|
+ tmpV := &tmpVal
|
|
|
+ if findVal, ok := quarterMap[k]; !ok {
|
|
|
+ findVal = append(findVal, tmpV)
|
|
|
+ quarterMap[k] = findVal
|
|
|
+ } else {
|
|
|
+ findVal = append(findVal, tmpV)
|
|
|
+ quarterMap[k] = findVal
|
|
|
+ }
|
|
|
+
|
|
|
+ if v.DataTime == latestDateStr {
|
|
|
+ dateItem.CuttingDataTimestamp = timestamp
|
|
|
+ dataMap[k] = dateItem
|
|
|
+ }
|
|
|
+ //break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for k, v := range dataMap {
|
|
|
+ itemList := quarterMap[k]
|
|
|
+ quarterItem := new(models.QuarterData)
|
|
|
+ quarterItem.Years = v.ShowName
|
|
|
+ quarterItem.ChartLegend = v.ChartLegend
|
|
|
+ if le, ok := legendMap[v.ShowName]; ok {
|
|
|
+ if le != strconv.Itoa(v.StartDate.Year()) && le != strconv.Itoa(v.EndDate.Year()) {
|
|
|
+ quarterItem.ChartLegend = le
|
|
|
+ }
|
|
|
+ }
|
|
|
+ quarterItem.DataList = itemList
|
|
|
+ quarterItem.CuttingDataTimestamp = v.CuttingDataTimestamp
|
|
|
+
|
|
|
+ //如果等于最后的实际日期,那么将切割时间戳记录
|
|
|
+ if quarterItem.CuttingDataTimestamp == 0 {
|
|
|
+ //如果大于最后的实际日期,那么第一个点就是切割的时间戳
|
|
|
+ if latestDate.Before(v.StartDate) && len(itemList) > 0 {
|
|
|
+ quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
|
|
|
+ }
|
|
|
+ }
|
|
|
+ quarterDataList = append(quarterDataList, quarterItem)
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(quarterDataList) > 0 {
|
|
|
+ quarterDataListSort = quarterDataList
|
|
|
+ sort.Sort(quarterDataListSort)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetSeasonEdbInfoDataListByXDateNong 季节性图的指标数据根据横轴选择农历时展示
|
|
|
+func GetSeasonEdbInfoDataListByXDateNong(result *data.EdbDataResult, latestDate time.Time, seasonExtraConfig string, calendarPreYear int) (quarterDataListSort models.QuarterDataList, err error) {
|
|
|
+ xStartDate := "01-01"
|
|
|
+ xEndDate := "12-31"
|
|
|
+ jumpYear := 0
|
|
|
+ legends := make([]models.SeasonChartLegend, 0)
|
|
|
+ var seasonExtra models.SeasonExtraItem
|
|
|
+ if seasonExtraConfig != "" {
|
|
|
+ err = json.Unmarshal([]byte(seasonExtraConfig), &seasonExtra)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if seasonExtra.XStartDate != "" {
|
|
|
+ xStartDate = seasonExtra.XStartDate
|
|
|
+ xEndDate = seasonExtra.XEndDate
|
|
|
+ jumpYear = seasonExtra.JumpYear
|
|
|
+ legends = seasonExtra.ChartLegend
|
|
|
+ }
|
|
|
+
|
|
|
+ length := len(result.List)
|
|
|
+ if length == 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ legendMap := make(map[string]string, 0)
|
|
|
+ if len(legends) > 0 {
|
|
|
+ for _, v := range legends {
|
|
|
+ legendMap[v.Name] = v.Value
|
|
|
+ }
|
|
|
+ }
|
|
|
+ latestDateYear := latestDate.Year()
|
|
|
+ //判断横轴的两个时间之间是不是跨年了,如果跨年了,则横轴截止年份比起始年份+1,如果不跨年,截止年份等于起始年份
|
|
|
+ //根据数据确定最早的年份,和最近年份
|
|
|
+ //根据横轴的日期,汇总所有的年份
|
|
|
+
|
|
|
+ startYear := result.List[0].Year
|
|
|
+ /*if jumpYear == 1 {
|
|
|
+ if startYear != calendarPreYear {
|
|
|
+ startYear = startYear - 1
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+
|
|
|
+ itemLength := len(result.List[length-1].Items)
|
|
|
+ //获取数据的最新日期
|
|
|
+ lastDate := result.List[length-1].Items[itemLength-1].DataTime
|
|
|
+ maxY := result.List[length-1].Year
|
|
|
+ lastDateT, tmpErr := time.Parse(utils.FormatDate, lastDate)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ endYear := lastDateT.Year()
|
|
|
+ nowYear := time.Now().Year()
|
|
|
+ dataMap := make(map[string]models.QuarterXDateItem, 0)
|
|
|
+
|
|
|
+ quarterDataList := make([]*models.QuarterData, 0)
|
|
|
+ resultData := make([]*models.QuarterData, 0)
|
|
|
+ quarterMap := make(map[string][]*models.EdbDataList, 0)
|
|
|
+
|
|
|
+ //整理出日期
|
|
|
+ var startTmpT, endTmpT time.Time
|
|
|
+ idx := 1
|
|
|
+ chartLegendMap := make(map[string]int, 0)
|
|
|
+ for currentStartYear := startYear; currentStartYear <= endYear; currentStartYear++ {
|
|
|
+ startStr := fmt.Sprintf("%d-%s", currentStartYear, xStartDate)
|
|
|
+ currentEndYear := currentStartYear
|
|
|
+ if jumpYear == 1 {
|
|
|
+ currentEndYear = currentStartYear + 1
|
|
|
+ }
|
|
|
+ endStr := fmt.Sprintf("%d-%s", currentEndYear, xEndDate)
|
|
|
+ showName := fmt.Sprintf("%d_%d", currentStartYear, currentEndYear)
|
|
|
+
|
|
|
+ startT, tEr := time.Parse(utils.FormatDate, startStr)
|
|
|
+ if tEr != nil {
|
|
|
+ err = tEr
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ endT, tEr := time.Parse(utils.FormatDate, endStr)
|
|
|
+ if tEr != nil {
|
|
|
+ err = tEr
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if lastDateT.Before(startT) {
|
|
|
+ //如果最新的日期在起始日之前,则跳出循环
|
|
|
+ break
|
|
|
+ }
|
|
|
+ if endT.Year() > nowYear {
|
|
|
+ //如果最新的日期比真实年份要大,则数据全部按照最大的年份补齐
|
|
|
+ nowYear = endT.Year()
|
|
|
+ }
|
|
|
+ item := models.QuarterXDateItem{
|
|
|
+ StartDate: startT,
|
|
|
+ EndDate: endT,
|
|
|
+ ShowName: showName,
|
|
|
+ }
|
|
|
+ dataMap[showName] = item
|
|
|
+ fmt.Println("年份" + showName + "日期" + startStr + " " + endStr)
|
|
|
+ startTmpT = startT
|
|
|
+ endTmpT = endT
|
|
|
+ chartLegendMap[showName] = idx
|
|
|
+ idx++
|
|
|
+ if lastDateT.Before(endT) {
|
|
|
+ //如果最新的日期在起始日之前,则跳出循环
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lenYear := len(dataMap)
|
|
|
+ for k, v := range dataMap {
|
|
|
+ if i, ok := chartLegendMap[k]; ok {
|
|
|
+ v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
|
|
|
+ }
|
|
|
+ dataMap[k] = v
|
|
|
+ }
|
|
|
+
|
|
|
+ yearDataListMap := make(map[int]*data.EdbDataItems, 0)
|
|
|
+
|
|
|
+ for _, lv := range result.List {
|
|
|
+ yearDataListMap[lv.Year] = lv
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断哪些点应该落在同一条时间线上
|
|
|
+ /*maxY := lastDateT.Year()
|
|
|
+ changeFlag := false
|
|
|
+ if lastDateT.Month() >= 11 {
|
|
|
+ maxY = maxY + 1
|
|
|
+ }
|
|
|
+ if maxY < nowYear {
|
|
|
+ changeFlag = true
|
|
|
+ maxY = nowYear
|
|
|
+ }*/
|
|
|
+ /*endTmp := fmt.Sprintf("%d-%s", maxY, xEndDate)
|
|
|
+ endTmpT, _ := time.Parse(utils.FormatDate, endTmp)
|
|
|
+ minY := maxY
|
|
|
+ if jumpYear == 1 {
|
|
|
+ minY = maxY - 1
|
|
|
+ }
|
|
|
+ startTmp := fmt.Sprintf("%d-%s", minY, xStartDate)
|
|
|
+ startTmpT, _ := time.Parse(utils.FormatDate, startTmp)*/
|
|
|
+
|
|
|
+ fmt.Println("横轴截取日" + startTmpT.Format(utils.FormatDate) + " " + endTmpT.Format(utils.FormatDate))
|
|
|
+ fmt.Printf("lastDateT.Year() 为%d \n", lastDateT.Year())
|
|
|
+ fmt.Printf("maxY 为%d \n", maxY)
|
|
|
+ for name, dateItem := range dataMap {
|
|
|
+ tY := dateItem.EndDate.Year()
|
|
|
+ if lastDateT.Month() >= 11 {
|
|
|
+ if maxY > endTmpT.Year() {
|
|
|
+ tY = tY + 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lv, ok1 := yearDataListMap[tY]
|
|
|
+ fmt.Printf("name %s yearDataListMap[%d]\n", name, tY)
|
|
|
+ if !ok1 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for _, item := range lv.Items {
|
|
|
+ tmpVal := models.EdbDataList{
|
|
|
+ EdbDataId: item.EdbDataId,
|
|
|
+ EdbInfoId: item.EdbInfoId,
|
|
|
+ DataTime: item.DataTime,
|
|
|
+ DataTimestamp: item.DataTimestamp,
|
|
|
+ Value: item.Value,
|
|
|
+ }
|
|
|
+ dataTimeT, _ := time.Parse(utils.FormatDate, item.DataTime)
|
|
|
+ if (startTmpT.Before(dataTimeT) && endTmpT.After(dataTimeT)) || startTmpT == dataTimeT || endTmpT == dataTimeT {
|
|
|
+ tmpV := &tmpVal
|
|
|
+ if findVal, ok := quarterMap[name]; !ok {
|
|
|
+ findVal = append(findVal, tmpV)
|
|
|
+ quarterMap[name] = findVal
|
|
|
+ } else {
|
|
|
+ findVal = append(findVal, tmpV)
|
|
|
+ quarterMap[name] = findVal
|
|
|
+ }
|
|
|
+ if lv.Year >= latestDateYear {
|
|
|
+ // 切割的日期时间字符串
|
|
|
+ cuttingDataTimeStr := latestDate.AddDate(0, 0, lv.BetweenDay).Format(utils.FormatDate)
|
|
|
+ if item.DataTime == cuttingDataTimeStr {
|
|
|
+ dateItem.CuttingDataTimestamp = tmpVal.DataTimestamp
|
|
|
+ dataMap[name] = dateItem
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for k, v := range dataMap {
|
|
|
+ itemList := quarterMap[k]
|
|
|
+ quarterItem := new(models.QuarterData)
|
|
|
+ quarterItem.Years = v.ShowName
|
|
|
+ quarterItem.ChartLegend = v.ChartLegend
|
|
|
+ if le, ok := legendMap[v.ShowName]; ok {
|
|
|
+ if le != strconv.Itoa(v.StartDate.Year()) && le != strconv.Itoa(v.EndDate.Year()) {
|
|
|
+ quarterItem.ChartLegend = le
|
|
|
+ }
|
|
|
+ }
|
|
|
+ quarterItem.DataList = itemList
|
|
|
+ quarterItem.CuttingDataTimestamp = v.CuttingDataTimestamp
|
|
|
+ //如果等于最后的实际日期,那么将切割时间戳记录
|
|
|
+ if quarterItem.CuttingDataTimestamp == 0 {
|
|
|
+ //如果大于最后的实际日期,那么第一个点就是切割的时间戳
|
|
|
+ if latestDate.Before(v.StartDate) && len(itemList) > 0 {
|
|
|
+ quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
|
|
|
+ }
|
|
|
+ }
|
|
|
+ quarterDataList = append(quarterDataList, quarterItem)
|
|
|
+ }
|
|
|
+
|
|
|
+ if result.List[0].Year != calendarPreYear {
|
|
|
+ itemList := make([]*models.EdbDataList, 0)
|
|
|
+ items := new(models.QuarterData)
|
|
|
+ //items.Year = calendarPreYear
|
|
|
+ items.DataList = itemList
|
|
|
+
|
|
|
+ newResult := make([]*models.QuarterData, 0)
|
|
|
+ newResult = append(newResult, items)
|
|
|
+ newResult = append(newResult, quarterDataList...)
|
|
|
+ resultData = newResult
|
|
|
+ } else {
|
|
|
+ resultData = quarterDataList
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(quarterDataList) > 0 {
|
|
|
+ quarterDataListSort = resultData
|
|
|
+ sort.Sort(quarterDataListSort)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// BarChartData 柱方图的数据处理
|
|
|
+func BarChartData(mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, barChartInfoDateList []models.BarChartInfoDateReq, barChartInfoSort models.BarChartInfoSortReq) (edbIdList []int, yDataList []models.YData, err error) {
|
|
|
+ // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
|
|
|
+ edbDataMap := make(map[int]map[string]float64)
|
|
|
+ for edbInfoId, edbDataList := range edbDataListMap {
|
|
|
+ edbDateData := make(map[string]float64)
|
|
|
+ for _, edbData := range edbDataList {
|
|
|
+ edbDateData[edbData.DataTime] = edbData.Value
|
|
|
+ }
|
|
|
+ edbDataMap[edbInfoId] = edbDateData
|
|
|
+ }
|
|
|
+
|
|
|
+ // edbIdList 指标展示顺序;x轴的指标顺序
|
|
|
+ edbIdList = make([]int, 0)
|
|
|
+ //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
|
|
|
+ dateData := make(map[int]float64)
|
|
|
+ if barChartInfoSort.Sort == 0 {
|
|
|
+ for _, v := range mappingList {
|
|
|
+ edbIdList = append(edbIdList, v.EdbInfoId)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ lenBarChartInfoDateList := len(barChartInfoDateList)
|
|
|
+ if barChartInfoSort.DateIndex >= lenBarChartInfoDateList {
|
|
|
+ err = errors.New("排序日期异常")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ notDataEdbIdList := make([]int, 0) //没有数据的指标id
|
|
|
+ // 日期配置
|
|
|
+ barChartInfoDate := barChartInfoDateList[barChartInfoSort.DateIndex]
|
|
|
+ for edbInfoId, dataList := range edbDataListMap {
|
|
|
+ if len(dataList) <= 0 {
|
|
|
+ // 没有数据的指标id
|
|
|
+ notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ findDate := barChartInfoDate.Date
|
|
|
+ switch barChartInfoDate.Type {
|
|
|
+ case 1: //最新值
|
|
|
+ findDate = dataList[len(dataList)-1].DataTime
|
|
|
+ case 2: //近期几天
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
|
|
|
+
|
|
|
+ lenData := len(dataList) - 1
|
|
|
+
|
|
|
+ for i := lenData; i >= 0; i-- {
|
|
|
+ currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
|
|
|
+ findDate = dataList[i].DataTime
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case 3: // 固定日期
|
|
|
+ //最早的日期
|
|
|
+ minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //寻找固定日期的数据
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
|
|
|
+ tmpDate := tmpDateTime.Format(utils.FormatDate)
|
|
|
+ if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
|
|
|
+ findDate = tmpDate
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
|
|
|
+ dateData[edbInfoId] = tmpValue
|
|
|
+ } else {
|
|
|
+ // 没有数据的指标id
|
|
|
+ notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
|
|
|
+ // 排序
|
|
|
+ dateDataSort := utils.NewMapSorter(dateData)
|
|
|
+ sort.Sort(dateDataSort)
|
|
|
+ if barChartInfoSort.Sort == 1 {
|
|
|
+ // 先将没有数据的指标id放在最前面
|
|
|
+ if len(notDataEdbIdList) > 0 {
|
|
|
+ edbIdList = append(edbIdList, notDataEdbIdList...)
|
|
|
+ }
|
|
|
+ for _, v := range dateDataSort {
|
|
|
+ edbIdList = append(edbIdList, v.Key)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ for i := len(dateDataSort) - 1; i >= 0; i-- {
|
|
|
+ edbIdList = append(edbIdList, dateDataSort[i].Key)
|
|
|
+ }
|
|
|
+ // 再将没有数据的指标id放在最后面
|
|
|
+ if len(notDataEdbIdList) > 0 {
|
|
|
+ edbIdList = append(edbIdList, notDataEdbIdList...)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ yDataList = make([]models.YData, 0) //y轴的数据列表
|
|
|
+
|
|
|
+ for _, barChartInfoDate := range barChartInfoDateList {
|
|
|
+ var maxDate time.Time
|
|
|
+
|
|
|
+ findDataList := make([]float64, 0) // 当前日期的数据值
|
|
|
+ for _, edbInfoId := range edbIdList {
|
|
|
+ findDate := barChartInfoDate.Date //需要的日期值
|
|
|
+ dataList := edbDataListMap[edbInfoId] //指标的所有数据值
|
|
|
+ if len(dataList) <= 0 {
|
|
|
+ // 没有数据的指标id
|
|
|
+ findDataList = append(findDataList, 0)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ switch barChartInfoDate.Type {
|
|
|
+ case 1: //最新值
|
|
|
+ dataList := edbDataListMap[edbInfoId]
|
|
|
+ findDate = dataList[len(dataList)-1].DataTime
|
|
|
+ case 2: //近期几天
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
|
|
|
+
|
|
|
+ lenData := len(dataList) - 1
|
|
|
+ for i := lenData; i >= 0; i-- {
|
|
|
+ currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
|
|
|
+ findDate = dataList[i].DataTime
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case 3: // 固定日期
|
|
|
+ //最早的日期
|
|
|
+ minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //寻找固定日期的数据
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
|
|
|
+ tmpDate := tmpDateTime.Format(utils.FormatDate)
|
|
|
+ if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
|
|
|
+ findDate = tmpDate
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
|
|
|
+ if maxDate.IsZero() {
|
|
|
+ maxDate = findDateTime
|
|
|
+ } else {
|
|
|
+ if findDateTime.After(maxDate) {
|
|
|
+ maxDate = findDateTime
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
|
|
|
+ tmpValue, _ = decimal.NewFromFloat(tmpValue).Round(4).Float64()
|
|
|
+ findDataList = append(findDataList, tmpValue)
|
|
|
+ } else {
|
|
|
+ findDataList = append(findDataList, 0)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ yDate := "0000-00-00"
|
|
|
+ if !maxDate.IsZero() {
|
|
|
+ yDate = maxDate.Format(utils.FormatDate)
|
|
|
+ }
|
|
|
+ yDataList = append(yDataList, models.YData{
|
|
|
+ Date: yDate,
|
|
|
+ Value: findDataList,
|
|
|
+ Color: barChartInfoDate.Color,
|
|
|
+ Name: barChartInfoDate.Name,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func CheckIsEnChart(chartNameEn string, edbList []*models.ChartEdbInfoMapping, source, chartType int) bool {
|
|
|
+ // 相关性图表不判断指标
|
|
|
+ if utils.InArrayByInt([]int{utils.CHART_SOURCE_CORRELATION, utils.CHART_SOURCE_ROLLING_CORRELATION, utils.CHART_SOURCE_LINE_EQUATION}, source) && chartNameEn != "" {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if chartNameEn != "" && len(edbList) <= 0 {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if chartNameEn == "" {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ // 截面散点图的话,肯定是有英文配置的
|
|
|
+ if chartType == utils.CHART_TYPE_SECTION_SCATTER {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range edbList {
|
|
|
+ if v.EdbNameEn == "" {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if v.Unit != "无" && v.Unit != "" && v.UnitEn == "" {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+func CheckIsEnEdb(edbNameEn, unit, unitEn string) bool {
|
|
|
+ if edbNameEn == "" {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if unit != "无" && unit != "" && unitEn == "" {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+// CheckChartExtraConfig 校验图表额外配置的信息,并且获取相关联的指标id
|
|
|
+func CheckChartExtraConfig(chartType int, extraConfigStr string) (edbIdList []int, err error, errMsg string) {
|
|
|
+ switch chartType {
|
|
|
+ case 10: //截面散点
|
|
|
+ var extraConfig models.SectionScatterReq
|
|
|
+ err = json.Unmarshal([]byte(extraConfigStr), &extraConfig)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断是否有配置日期序列
|
|
|
+ if len(extraConfig.SeriesList) <= 0 {
|
|
|
+ errMsg = `请配置序列`
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断是否有填写指标
|
|
|
+ if len(extraConfig.SeriesList[0].EdbInfoList) <= 0 {
|
|
|
+ errMsg = `请选择指标`
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 遍历指标列表获取指标id
|
|
|
+ edbIdMap := make(map[int]int)
|
|
|
+ for _, v := range extraConfig.SeriesList[0].EdbInfoList {
|
|
|
+ // X 轴的指标id
|
|
|
+ if _, ok := edbIdMap[v.XEdbInfoId]; !ok {
|
|
|
+ edbIdMap[v.XEdbInfoId] = v.XEdbInfoId
|
|
|
+ edbIdList = append(edbIdList, v.XEdbInfoId)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Y 轴的指标id
|
|
|
+ if _, ok := edbIdMap[v.YEdbInfoId]; !ok {
|
|
|
+ edbIdMap[v.YEdbInfoId] = v.YEdbInfoId
|
|
|
+ edbIdList = append(edbIdList, v.YEdbInfoId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case utils.CHART_TYPE_RADAR:
|
|
|
+ var extraConfig models.RadarChartInfoReq
|
|
|
+ if extraConfigStr == `` {
|
|
|
+ errMsg = "雷达图未配置"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = json.Unmarshal([]byte(extraConfigStr), &extraConfig)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "雷达图配置异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetSectionScatterChartData 截面散点图的数据处理
|
|
|
+func GetSectionScatterChartData(chartInfoId int, mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, extraConfig models.SectionScatterReq) (edbIdList []int, chartDataResp models.SectionScatterInfoResp, err error) {
|
|
|
+ // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
|
|
|
+ edbDataMap := make(map[int]map[string]float64)
|
|
|
+ for edbInfoId, edbDataList := range edbDataListMap {
|
|
|
+ edbDateData := make(map[string]float64)
|
|
|
+ for _, edbData := range edbDataList {
|
|
|
+ edbDateData[edbData.DataTime] = edbData.Value
|
|
|
+ }
|
|
|
+ edbDataMap[edbInfoId] = edbDateData
|
|
|
+ }
|
|
|
+
|
|
|
+ // edbIdList 指标展示顺序;x轴的指标顺序
|
|
|
+ edbIdList = make([]int, 0)
|
|
|
+ edbMappingMap := make(map[int]*models.ChartEdbInfoMapping)
|
|
|
+ for _, v := range mappingList {
|
|
|
+ edbIdList = append(edbIdList, v.EdbInfoId)
|
|
|
+ edbMappingMap[v.EdbInfoId] = v
|
|
|
+ }
|
|
|
+ //SectionScatterSeriesInfoResp
|
|
|
+
|
|
|
+ dataListResp := make([]models.SectionScatterSeriesItemResp, 0) //y轴的数据列表
|
|
|
+
|
|
|
+ for _, seriesItem := range extraConfig.SeriesList {
|
|
|
+ var maxDate time.Time
|
|
|
+ // 系列中的指标数据
|
|
|
+ tmpSeriesEdbInfoList := make([]models.SectionScatterEdbItemResp, 0)
|
|
|
+
|
|
|
+ var minXVal, maxXVal, minYVal, maxYVal float64
|
|
|
+ for _, edbConf := range seriesItem.EdbInfoList {
|
|
|
+ tmpItem := models.SectionScatterEdbItemResp{
|
|
|
+ IsShow: edbConf.IsShow,
|
|
|
+ Name: edbConf.Name,
|
|
|
+ NameEn: edbConf.NameEn,
|
|
|
+ } //单个坐标点的数据
|
|
|
+
|
|
|
+ //X轴的数据
|
|
|
+ {
|
|
|
+ edbInfoId := edbConf.XEdbInfoId //X轴的指标
|
|
|
+ edbMappingInfo, ok := edbMappingMap[edbInfoId]
|
|
|
+ if !ok {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ findDate := edbConf.XDate //需要的日期值
|
|
|
+ dataList := edbDataListMap[edbInfoId] //指标的所有数据值
|
|
|
+ if len(dataList) <= 0 {
|
|
|
+ // 没有数据的指标id
|
|
|
+ //findDataList = append(findDataList, 0)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpItem.XEdbInfoId = edbInfoId
|
|
|
+ tmpItem.XName = edbMappingInfo.EdbName
|
|
|
+ tmpItem.XNameEn = edbMappingInfo.EdbNameEn
|
|
|
+
|
|
|
+ switch edbConf.XDateType {
|
|
|
+ case 1: //最新值
|
|
|
+ findDate = dataList[len(dataList)-1].DataTime
|
|
|
+ case 2: //近期几天
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ findDateTime = findDateTime.AddDate(0, 0, -edbConf.XDateValue)
|
|
|
+
|
|
|
+ lenData := len(dataList) - 1
|
|
|
+ for i := lenData; i >= 0; i-- {
|
|
|
+ currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
|
|
|
+ findDate = dataList[i].DataTime
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case 3: // 固定日期
|
|
|
+ //最早的日期
|
|
|
+ minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //寻找固定日期的数据
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.XDate, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
|
|
|
+ tmpDate := tmpDateTime.Format(utils.FormatDate)
|
|
|
+ if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
|
|
|
+ findDate = tmpDate
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.XDate))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
|
|
|
+ if maxDate.IsZero() {
|
|
|
+ maxDate = findDateTime
|
|
|
+ } else {
|
|
|
+ if findDateTime.After(maxDate) {
|
|
|
+ maxDate = findDateTime
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
|
|
|
+ tmpItem.XDate = findDate
|
|
|
+ tmpItem.XValue = tmpValue
|
|
|
+ } else {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //Y轴的数据
|
|
|
+ {
|
|
|
+ edbInfoId := edbConf.YEdbInfoId //Y轴的指标
|
|
|
+ edbMappingInfo, ok := edbMappingMap[edbInfoId]
|
|
|
+ if !ok {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ findDate := edbConf.YDate //需要的日期值
|
|
|
+ dataList := edbDataListMap[edbInfoId] //指标的所有数据值
|
|
|
+ if len(dataList) <= 0 {
|
|
|
+ // 没有数据的指标id
|
|
|
+ //findDataList = append(findDataList, 0)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpItem.YEdbInfoId = edbInfoId
|
|
|
+ tmpItem.YName = edbMappingInfo.EdbName
|
|
|
+ tmpItem.YNameEn = edbMappingInfo.EdbNameEn
|
|
|
+
|
|
|
+ switch edbConf.YDateType {
|
|
|
+ case 1: //最新值
|
|
|
+ findDate = dataList[len(dataList)-1].DataTime
|
|
|
+ case 2: //近期几天
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ findDateTime = findDateTime.AddDate(0, 0, -edbConf.YDateValue)
|
|
|
+
|
|
|
+ lenData := len(dataList) - 1
|
|
|
+ for i := lenData; i >= 0; i-- {
|
|
|
+ currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
|
|
|
+ findDate = dataList[i].DataTime
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case 3: // 固定日期
|
|
|
+ //最早的日期
|
|
|
+ minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //寻找固定日期的数据
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.YDate, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
|
|
|
+ tmpDate := tmpDateTime.Format(utils.FormatDate)
|
|
|
+ if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
|
|
|
+ findDate = tmpDate
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.YDate))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
|
|
|
+ if maxDate.IsZero() {
|
|
|
+ maxDate = findDateTime
|
|
|
+ } else {
|
|
|
+ if findDateTime.After(maxDate) {
|
|
|
+ maxDate = findDateTime
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
|
|
|
+ tmpItem.YDate = findDate
|
|
|
+ tmpItem.YValue = tmpValue
|
|
|
+ } else {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取当前系列的X轴的最大最小值
|
|
|
+ {
|
|
|
+ if tmpItem.XValue < minXVal {
|
|
|
+ minXVal = tmpItem.XValue
|
|
|
+ }
|
|
|
+ if tmpItem.XValue > maxXVal {
|
|
|
+ maxXVal = tmpItem.XValue
|
|
|
+ }
|
|
|
+ if tmpItem.YValue < minYVal {
|
|
|
+ minYVal = tmpItem.YValue
|
|
|
+ }
|
|
|
+ if tmpItem.YValue > maxYVal {
|
|
|
+ maxYVal = tmpItem.YValue
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tmpSeriesEdbInfoList = append(tmpSeriesEdbInfoList, tmpItem)
|
|
|
+ }
|
|
|
+
|
|
|
+ trendLimitData := make([]models.CoordinatePoint, 0) //趋势线的前后坐标点
|
|
|
+ var trendLine, rSquare string
|
|
|
+ // 生成线性方程式
|
|
|
+ var a, b float64
|
|
|
+ {
|
|
|
+ coordinateData := make([]utils.Coordinate, 0)
|
|
|
+ for _, tmpSeriesEdbInfo := range tmpSeriesEdbInfoList {
|
|
|
+ tmpCoordinate1 := utils.Coordinate{
|
|
|
+ X: tmpSeriesEdbInfo.XValue,
|
|
|
+ Y: tmpSeriesEdbInfo.YValue,
|
|
|
+ }
|
|
|
+ coordinateData = append(coordinateData, tmpCoordinate1)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 只有存在两个坐标点的时候,才能去计算线性方程和R平方
|
|
|
+ if len(coordinateData) >= 2 {
|
|
|
+ a, b = utils.GetLinearResult(coordinateData)
|
|
|
+ if !math.IsNaN(a) && !math.IsNaN(b) {
|
|
|
+ if b > 0 {
|
|
|
+ trendLine = fmt.Sprintf("y=%sx+%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
|
|
|
+ } else {
|
|
|
+ trendLine = fmt.Sprintf("y=%sx%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
|
|
|
+ }
|
|
|
+
|
|
|
+ minYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(minXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
|
|
|
+ maxYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(maxXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算R平方
|
|
|
+ rSquare = fmt.Sprint(utils.CalculationDecisive(coordinateData))
|
|
|
+ }
|
|
|
+
|
|
|
+ trendLimitData = append(trendLimitData, models.CoordinatePoint{
|
|
|
+ X: minXVal,
|
|
|
+ Y: minYVal,
|
|
|
+ }, models.CoordinatePoint{
|
|
|
+ X: maxXVal,
|
|
|
+ Y: maxYVal,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ dataListResp = append(dataListResp, models.SectionScatterSeriesItemResp{
|
|
|
+ Name: seriesItem.Name,
|
|
|
+ NameEn: seriesItem.NameEn,
|
|
|
+ IsNameDefault: seriesItem.IsNameDefault,
|
|
|
+ Color: seriesItem.Color,
|
|
|
+ EdbInfoList: tmpSeriesEdbInfoList,
|
|
|
+ ShowTrendLine: seriesItem.ShowTrendLine,
|
|
|
+ ShowFitEquation: seriesItem.ShowFitEquation,
|
|
|
+ ShowRSquare: seriesItem.ShowRSquare,
|
|
|
+ TrendLine: trendLine,
|
|
|
+ RSquare: rSquare,
|
|
|
+ TrendLimitData: trendLimitData,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 截面散点图点击详情时自动更新系列名
|
|
|
+ if len(extraConfig.SeriesList) > 0 {
|
|
|
+ // 默认名字的时候才自动更新
|
|
|
+ if extraConfig.SeriesList[0].IsNameDefault {
|
|
|
+ firstXEdbInfoId := extraConfig.SeriesList[0].EdbInfoList[0].XEdbInfoId
|
|
|
+ needUpdate := false
|
|
|
+ if v, ok := edbMappingMap[firstXEdbInfoId]; ok {
|
|
|
+ extraConfig.SeriesList[0].Name = v.LatestDate
|
|
|
+ extraConfig.SeriesList[0].NameEn = v.LatestDate
|
|
|
+ dataListResp[0].Name = v.LatestDate
|
|
|
+ dataListResp[0].NameEn = v.LatestDate
|
|
|
+ needUpdate = true
|
|
|
+ }
|
|
|
+
|
|
|
+ extraConfigByte, e := json.Marshal(extraConfig)
|
|
|
+ if e != nil {
|
|
|
+ errMsg := "截面散点系列更新异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ extraConfigStr := string(extraConfigByte)
|
|
|
+
|
|
|
+ if needUpdate {
|
|
|
+ err = models.EditChartInfoExtraConfig(chartInfoId, extraConfigStr)
|
|
|
+ if err != nil {
|
|
|
+ errMsg := "截面散点系列更新异常"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ chartDataResp = models.SectionScatterInfoResp{
|
|
|
+ XName: extraConfig.XName,
|
|
|
+ XNameEn: extraConfig.XNameEn,
|
|
|
+ XUnitName: extraConfig.XUnitName,
|
|
|
+ XUnitNameEn: extraConfig.XUnitNameEn,
|
|
|
+ YName: extraConfig.YName,
|
|
|
+ YNameEn: extraConfig.YNameEn,
|
|
|
+ YUnitName: extraConfig.YUnitName,
|
|
|
+ YUnitNameEn: extraConfig.YUnitNameEn,
|
|
|
+ XMinValue: extraConfig.XMinValue,
|
|
|
+ XMaxValue: extraConfig.XMaxValue,
|
|
|
+ YMinValue: extraConfig.YMinValue,
|
|
|
+ YMaxValue: extraConfig.YMaxValue,
|
|
|
+ DataList: dataListResp,
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetEdbSourceByEdbInfoIdList 获取关联指标的来源
|
|
|
+func GetEdbSourceByEdbInfoIdList(chartEdbInfoMappingList []*models.ChartEdbInfoMapping) (sourceNameList, sourceNameEnList []string) {
|
|
|
+ sourceNameList = make([]string, 0)
|
|
|
+ sourceNameEnList = make([]string, 0)
|
|
|
+ sourceMap := make(map[int]string)
|
|
|
+ for _, v := range chartEdbInfoMappingList {
|
|
|
+ // 指标类型:1:基础指标,2:计算指标
|
|
|
+ if v.EdbType == 2 || v.EdbInfoCategoryType == 1 {
|
|
|
+ //sourceMap[0] = "弘则研究"
|
|
|
+ baseEdbInfoArr, _, _ := GetRefreshEdbInfoFromBase(v.EdbInfoId, v.Source)
|
|
|
+ for _, baseEdbInfo := range baseEdbInfoArr {
|
|
|
+ if baseEdbInfo.EdbInfoType == 0 { //普通指标才参与,预测指标不参与
|
|
|
+ sourceMap[baseEdbInfo.Source] = baseEdbInfo.SourceName
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ sourceMap[v.Source] = v.SourceName
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for source, sourceName := range sourceMap {
|
|
|
+ if utils.InArrayByInt([]int{utils.DATA_SOURCE_MANUAL, utils.DATA_SOURCE_MYSTEEL_CHEMICAL}, source) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ sourceNameList = append(sourceNameList, sourceName)
|
|
|
+
|
|
|
+ sourceNameEn, ok := utils.DataSourceEnMap[source]
|
|
|
+ if !ok {
|
|
|
+ sourceNameEn = sourceName
|
|
|
+ }
|
|
|
+ sourceNameEnList = append(sourceNameEnList, sourceNameEn)
|
|
|
+ }
|
|
|
+ //sourceNameList = append(sourceNameList, utils.ChartDefaultNameCn)
|
|
|
+ //sourceNameEnList = append(sourceNameEnList, utils.ChartDefaultNameEn)
|
|
|
+
|
|
|
+ // 图表来源
|
|
|
+ /*conf, e := models.GetBusinessConf()
|
|
|
+ if e != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if conf[models.BusinessConfCompanyName] != "" {
|
|
|
+ sourceNameList = append(sourceNameList, conf[models.BusinessConfCompanyName])
|
|
|
+ sourceNameEnList = append(sourceNameEnList, conf[models.BusinessConfCompanyName])
|
|
|
+ }*/
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// RadarChartData 雷达图的数据处理
|
|
|
+func RadarChartData(mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, extraConfig models.RadarChartInfoReq) (edbIdList []int, chartDataResp models.RadarChartInfoResp, err error) {
|
|
|
+ // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
|
|
|
+ edbDataMap := make(map[int]map[string]float64)
|
|
|
+ for edbInfoId, edbDataList := range edbDataListMap {
|
|
|
+ edbDateData := make(map[string]float64)
|
|
|
+ for _, edbData := range edbDataList {
|
|
|
+ edbDateData[edbData.DataTime] = edbData.Value
|
|
|
+ }
|
|
|
+ edbDataMap[edbInfoId] = edbDateData
|
|
|
+ }
|
|
|
+ // edbIdList 指标展示顺序;x轴的指标顺序
|
|
|
+ edbIdList = make([]int, 0)
|
|
|
+ for _, v := range mappingList {
|
|
|
+ edbIdList = append(edbIdList, v.EdbInfoId)
|
|
|
+ }
|
|
|
+ chartDateList := extraConfig.DateList
|
|
|
+
|
|
|
+ yDataList := make([]models.RadarYData, 0) //y轴的数据列表
|
|
|
+
|
|
|
+ for _, chartDate := range chartDateList {
|
|
|
+ var maxDate time.Time
|
|
|
+
|
|
|
+ findDataList := make([]float64, 0) // 当前日期的数据值
|
|
|
+ for _, edbInfoId := range edbIdList {
|
|
|
+ findDate := chartDate.Date //需要的日期值
|
|
|
+ dataList := edbDataListMap[edbInfoId] //指标的所有数据值
|
|
|
+ if len(dataList) <= 0 {
|
|
|
+ // 没有数据的指标id
|
|
|
+ findDataList = append(findDataList, 0)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ switch chartDate.Type {
|
|
|
+ case 1: //最新值
|
|
|
+ findDate = dataList[len(dataList)-1].DataTime
|
|
|
+ case 2: //近期几天
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ findDateTime = findDateTime.AddDate(0, 0, -chartDate.Value)
|
|
|
+
|
|
|
+ lenData := len(dataList) - 1
|
|
|
+ for i := lenData; i >= 0; i-- {
|
|
|
+ currDateTime, e := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
|
|
|
+ if e != nil {
|
|
|
+ err = e
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
|
|
|
+ findDate = dataList[i].DataTime
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case 3: // 固定日期
|
|
|
+ //最早的日期
|
|
|
+ minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //寻找固定日期的数据
|
|
|
+ findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, chartDate.Date, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
|
|
|
+ tmpDate := tmpDateTime.Format(utils.FormatDate)
|
|
|
+ if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
|
|
|
+ findDate = tmpDate
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ err = errors.New(fmt.Sprint("日期类型异常,Type:", chartDate.Type))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
|
|
|
+ if maxDate.IsZero() {
|
|
|
+ maxDate = findDateTime
|
|
|
+ } else {
|
|
|
+ if findDateTime.After(maxDate) {
|
|
|
+ maxDate = findDateTime
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
|
|
|
+ tmpValue, _ = decimal.NewFromFloat(tmpValue).Round(4).Float64()
|
|
|
+ findDataList = append(findDataList, tmpValue)
|
|
|
+ } else {
|
|
|
+ findDataList = append(findDataList, 0)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ yDate := "0000-00-00"
|
|
|
+ if !maxDate.IsZero() {
|
|
|
+ yDate = maxDate.Format(utils.FormatDate)
|
|
|
+ }
|
|
|
+ yDataList = append(yDataList, models.RadarYData{
|
|
|
+ Date: yDate,
|
|
|
+ Value: findDataList,
|
|
|
+ Color: chartDate.Color,
|
|
|
+ Name: chartDate.Name,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ chartDataResp = models.RadarChartInfoResp{
|
|
|
+ YDataList: yDataList,
|
|
|
+ XEdbIdValue: edbIdList,
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// SeasonChartData 季节性图的数据处理
|
|
|
+func SeasonChartData(dataList []*models.ChartEdbInfoMapping, seasonExtraConfig string) (dataResp models.SeasonChartResp, err error) {
|
|
|
+ var seasonConfig models.SeasonExtraItem
|
|
|
+ err = json.Unmarshal([]byte(seasonExtraConfig), &seasonConfig)
|
|
|
+ if err != nil {
|
|
|
+ err = errors.New("季节性图配置异常, Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, mappingItem := range dataList {
|
|
|
+ if mappingItem.IsAxis == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ quarterDataList, ok := mappingItem.DataList.(models.QuarterDataList)
|
|
|
+ if !ok {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ // 上下限区间
|
|
|
+ if seasonConfig.MaxMinLimits.Year > 0 {
|
|
|
+ startYear := time.Now().AddDate(-seasonConfig.MaxMinLimits.Year, 0, 0).Year()
|
|
|
+ dataResp.MaxMinLimits.List = make([]*models.MaxMinLimitsData, 0)
|
|
|
+ dataTimeMap := make(map[time.Time]time.Time)
|
|
|
+ dataTimeList := make([]string, 0)
|
|
|
+ maxValueMap := make(map[time.Time]float64)
|
|
|
+ minValueMap := make(map[time.Time]float64)
|
|
|
+
|
|
|
+ maxMinDataList := make([]*models.MaxMinLimitsData, 0)
|
|
|
+ var startDateStr string
|
|
|
+ var endDateStr string
|
|
|
+ var newDate time.Time
|
|
|
+
|
|
|
+ startDateStr = fmt.Sprintf("%d-%s", time.Now().Year(), seasonConfig.XStartDate)
|
|
|
+ endDateStr = fmt.Sprintf("%d-%s", time.Now().Year(), seasonConfig.XEndDate)
|
|
|
+ startDate, e := time.Parse(utils.FormatDate, startDateStr)
|
|
|
+ if e != nil {
|
|
|
+ err = e
|
|
|
+ return
|
|
|
+ }
|
|
|
+ endDate, e := time.Parse(utils.FormatDate, endDateStr)
|
|
|
+ if e != nil {
|
|
|
+ err = e
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 日度 周度插值
|
|
|
+ for _, v := range quarterDataList {
|
|
|
+ if mappingItem.Frequency == "日度" || mappingItem.Frequency == "周度" {
|
|
|
+ handleDataMap := make(map[string]float64)
|
|
|
+ dataTimeList, _, err = HandleDataByLinearRegressionToList(v.DataList, handleDataMap)
|
|
|
+ if err != nil {
|
|
|
+ err = errors.New("插值处理数据异常, Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 不包含当年
|
|
|
+ if v.ChartLegend == strconv.Itoa(time.Now().Year()) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for _, date := range dataTimeList {
|
|
|
+ dateTime, e := time.Parse(utils.FormatDate, date)
|
|
|
+ if e != nil {
|
|
|
+ err = errors.New("时间格式化异常, Err:" + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if dateTime.Year() < startYear {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ // 不包含2月29号
|
|
|
+ if dateTime.Month() == 2 && dateTime.Day() == 29 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ newDate = dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
|
|
|
+ if seasonConfig.JumpYear == 1 {
|
|
|
+ if startDate.After(endDate) {
|
|
|
+ // 如果跨年且不到一年
|
|
|
+ // 全年截取一部分
|
|
|
+ if newDate.Before(startDate.AddDate(0, 0, 1)) && newDate.After(endDate) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if newDate.After(startDate.AddDate(0, 0, -1)) {
|
|
|
+ // 减一年
|
|
|
+ newDate = dateTime.AddDate(time.Now().Year()-dateTime.Year()-1, 0, 0)
|
|
|
+ }
|
|
|
+ // 处理上下限列表
|
|
|
+ if value, ok := maxValueMap[newDate]; ok {
|
|
|
+ if value < handleDataMap[date] {
|
|
|
+ maxValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ maxValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ if value, ok := minValueMap[newDate]; ok {
|
|
|
+ if value > handleDataMap[date] {
|
|
|
+ minValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ minValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ } else {
|
|
|
+ // 如果跨年且大于等于一年
|
|
|
+ // double后截取
|
|
|
+ if newDate.After(startDate) {
|
|
|
+ // 处理上下限列表
|
|
|
+ if value, ok := maxValueMap[newDate]; ok {
|
|
|
+ if value < handleDataMap[date] {
|
|
|
+ maxValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ maxValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ if value, ok := minValueMap[newDate]; ok {
|
|
|
+ if value > handleDataMap[date] {
|
|
|
+ minValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ minValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ }
|
|
|
+
|
|
|
+ newDate = dateTime.AddDate(time.Now().Year()-dateTime.Year()+1, 0, 0)
|
|
|
+ newEndDate := endDate.AddDate(1, 0, 0)
|
|
|
+ if newDate.Before(newEndDate) {
|
|
|
+ // 处理上下限列表
|
|
|
+ if value, ok := maxValueMap[newDate]; ok {
|
|
|
+ if value < handleDataMap[date] {
|
|
|
+ maxValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ maxValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ if value, ok := minValueMap[newDate]; ok {
|
|
|
+ if value > handleDataMap[date] {
|
|
|
+ minValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ minValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果不跨年 正常获取
|
|
|
+ // 获取当前日期所在区间
|
|
|
+ // 处理上下限列表
|
|
|
+ if value, ok := maxValueMap[newDate]; ok {
|
|
|
+ if value < handleDataMap[date] {
|
|
|
+ maxValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ maxValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ if value, ok := minValueMap[newDate]; ok {
|
|
|
+ if value > handleDataMap[date] {
|
|
|
+ minValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ minValueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 旬度、月度、季度、半年度 不插值,需要先把日期列表和数据map取出来
|
|
|
+ for _, vv := range v.DataList {
|
|
|
+ dateTime, e := time.Parse(utils.FormatDate, vv.DataTime)
|
|
|
+ if e != nil {
|
|
|
+ err = errors.New("时间格式化异常, Err:" + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 不包含当年
|
|
|
+ if v.ChartLegend == strconv.Itoa(time.Now().Year()) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ if dateTime.Year() < startYear {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ // 月度的2月29号日期改为2月28日
|
|
|
+ if dateTime.Month() == 2 && dateTime.Day() == 29 {
|
|
|
+ dateTime = dateTime.AddDate(0, 0, -1)
|
|
|
+ }
|
|
|
+ newDate = dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
|
|
|
+ if seasonConfig.JumpYear == 1 {
|
|
|
+ if startDate.After(endDate) {
|
|
|
+ // 如果跨年且不到一年
|
|
|
+ // 全年截取一部分
|
|
|
+ if newDate.Before(startDate.AddDate(0, 0, 1)) && newDate.After(endDate) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if newDate.After(startDate.AddDate(0, 0, -1)) {
|
|
|
+ // 减一年
|
|
|
+ newDate = dateTime.AddDate(time.Now().Year()-dateTime.Year()-1, 0, 0)
|
|
|
+ }
|
|
|
+ // 处理上下限列表
|
|
|
+ if value, ok := maxValueMap[newDate]; ok {
|
|
|
+ if value < vv.Value {
|
|
|
+ maxValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ maxValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ if value, ok := minValueMap[newDate]; ok {
|
|
|
+ if value > vv.Value {
|
|
|
+ minValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ minValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ } else {
|
|
|
+ // 如果跨年且大于等于一年
|
|
|
+ // double后截取
|
|
|
+ if newDate.After(startDate) {
|
|
|
+ // 处理上下限列表
|
|
|
+ if value, ok := maxValueMap[newDate]; ok {
|
|
|
+ if value < vv.Value {
|
|
|
+ maxValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ maxValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ if value, ok := minValueMap[newDate]; ok {
|
|
|
+ if value > vv.Value {
|
|
|
+ minValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ minValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ }
|
|
|
+
|
|
|
+ newDate = dateTime.AddDate(time.Now().Year()-dateTime.Year()+1, 0, 0)
|
|
|
+ newEndDate := endDate.AddDate(1, 0, 0)
|
|
|
+ if newDate.Before(newEndDate) {
|
|
|
+ // 处理上下限列表
|
|
|
+ if value, ok := maxValueMap[newDate]; ok {
|
|
|
+ if value < vv.Value {
|
|
|
+ maxValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ maxValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ if value, ok := minValueMap[newDate]; ok {
|
|
|
+ if value > vv.Value {
|
|
|
+ minValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ minValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果不跨年 正常获取
|
|
|
+ // 获取当前日期所在区间
|
|
|
+ // 处理上下限列表
|
|
|
+ if value, ok := maxValueMap[newDate]; ok {
|
|
|
+ if value < vv.Value {
|
|
|
+ maxValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ maxValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ if value, ok := minValueMap[newDate]; ok {
|
|
|
+ if value > vv.Value {
|
|
|
+ minValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ minValueMap[newDate] = vv.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range dataTimeMap {
|
|
|
+ maxMinItem := &models.MaxMinLimitsData{}
|
|
|
+ if maxValue, ok := maxValueMap[v]; ok {
|
|
|
+ maxMinItem.MaxValue = maxValue
|
|
|
+ } else {
|
|
|
+ maxMinItem.MaxValue = minValueMap[v]
|
|
|
+ }
|
|
|
+
|
|
|
+ if minValue, ok := minValueMap[v]; ok {
|
|
|
+ maxMinItem.MinValue = minValue
|
|
|
+ } else {
|
|
|
+ maxMinItem.MinValue = maxValueMap[v]
|
|
|
+ }
|
|
|
+
|
|
|
+ maxMinItem.DataTime = v.Format(utils.FormatDate)
|
|
|
+ maxMinItem.DataTimestamp = v.UnixNano() / 1e6
|
|
|
+
|
|
|
+ maxMinDataList = append(maxMinDataList, maxMinItem)
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 排序
|
|
|
+ sort.Slice(maxMinDataList, func(i, j int) bool {
|
|
|
+ return maxMinDataList[i].DataTime < maxMinDataList[j].DataTime
|
|
|
+ })
|
|
|
+
|
|
|
+ dataResp.MaxMinLimits.List = maxMinDataList
|
|
|
+ dataResp.MaxMinLimits.Color = seasonConfig.MaxMinLimits.Color
|
|
|
+ dataResp.MaxMinLimits.Legend = seasonConfig.MaxMinLimits.Legend
|
|
|
+ dataResp.MaxMinLimits.IsShow = seasonConfig.MaxMinLimits.IsShow
|
|
|
+ dataResp.MaxMinLimits.IsAdd = seasonConfig.MaxMinLimits.IsAdd
|
|
|
+ dataResp.MaxMinLimits.Year = seasonConfig.MaxMinLimits.Year
|
|
|
+ }
|
|
|
+
|
|
|
+ // 自定义同期均线
|
|
|
+ if seasonConfig.SamePeriodAverage.Year > 0 {
|
|
|
+ handleDataMap := make(map[string]float64)
|
|
|
+ dataTimeMap := make(map[time.Time]time.Time)
|
|
|
+ dataTimeList := make([]string, 0)
|
|
|
+ valueMap := make(map[time.Time]float64)
|
|
|
+ averageDataList := make([]*models.SamePeriodAverageData, 0)
|
|
|
+ for i := len(quarterDataList) - 1; i >= 0; i-- {
|
|
|
+ // 插值成日度
|
|
|
+ dataTimeList, _, err = HandleDataByLinearRegressionToList(quarterDataList[i].DataList, handleDataMap)
|
|
|
+ if err != nil {
|
|
|
+ err = errors.New("插值处理数据异常, Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for _, date := range dataTimeList {
|
|
|
+ dateTime, e := time.Parse(utils.FormatDate, date)
|
|
|
+ if e != nil {
|
|
|
+ err = errors.New("时间格式化异常, Err:" + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ startYear := time.Now().AddDate(-seasonConfig.SamePeriodAverage.Year, 0, 0).Year()
|
|
|
+ if dateTime.Year() < startYear {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ // 不包含2月29号
|
|
|
+ if dateTime.Month() == 2 && dateTime.Day() == 29 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ // 不包含当年
|
|
|
+ if quarterDataList[i].ChartLegend == strconv.Itoa(time.Now().Year()) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ newDate := dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
|
|
|
+ // 处理均值
|
|
|
+ if value, ok := valueMap[newDate]; ok {
|
|
|
+ valueMap[newDate] = (handleDataMap[date] + value) / 2
|
|
|
+ } else {
|
|
|
+ valueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range dataTimeMap {
|
|
|
+ averageItem := &models.SamePeriodAverageData{}
|
|
|
+ if value, ok := valueMap[v]; ok {
|
|
|
+ averageItem.Value = value
|
|
|
+ }
|
|
|
+ averageItem.DataTime = v.Format(utils.FormatDate)
|
|
|
+ averageItem.DataTimestamp = v.UnixNano() / 1e6
|
|
|
+
|
|
|
+ averageDataList = append(averageDataList, averageItem)
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 排序
|
|
|
+ sort.Slice(averageDataList, func(i, j int) bool {
|
|
|
+ return averageDataList[i].DataTime < averageDataList[j].DataTime
|
|
|
+ })
|
|
|
+
|
|
|
+ dataResp.SamePeriodAverage.List = averageDataList
|
|
|
+ dataResp.SamePeriodAverage.Year = seasonConfig.SamePeriodAverage.Year
|
|
|
+ dataResp.SamePeriodAverage.Color = seasonConfig.SamePeriodAverage.Color
|
|
|
+ dataResp.SamePeriodAverage.Legend = seasonConfig.SamePeriodAverage.Legend
|
|
|
+ dataResp.SamePeriodAverage.IsShow = seasonConfig.SamePeriodAverage.IsShow
|
|
|
+ dataResp.SamePeriodAverage.LineType = seasonConfig.SamePeriodAverage.LineType
|
|
|
+ dataResp.SamePeriodAverage.LineWidth = seasonConfig.SamePeriodAverage.LineWidth
|
|
|
+ dataResp.SamePeriodAverage.IsAdd = seasonConfig.SamePeriodAverage.IsAdd
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 自定义同期标准差
|
|
|
+ if seasonConfig.SamePeriodStandardDeviation.Year > 1 && seasonConfig.SamePeriodStandardDeviation.Multiple > 0 {
|
|
|
+ startYear := time.Now().AddDate(-seasonConfig.SamePeriodStandardDeviation.Year, 0, 0).Year()
|
|
|
+
|
|
|
+ // 先算均值,再算标准差
|
|
|
+ handleDataMap := make(map[string]float64)
|
|
|
+ dataTimeMap := make(map[time.Time]time.Time)
|
|
|
+ dataTimeValueMap := make(map[time.Time][]float64)
|
|
|
+ dataTimeList := make([]string, 0)
|
|
|
+ valueMap := make(map[time.Time]float64)
|
|
|
+
|
|
|
+ samePeriodStandardDeviationList := make([]*models.MaxMinLimitsData, 0)
|
|
|
+ for i := len(quarterDataList) - 1; i > len(quarterDataList)-seasonConfig.SamePeriodAverage.Year-1 && i > 0; i-- {
|
|
|
+ // 插值成日度
|
|
|
+ dataTimeList, _, err = HandleDataByLinearRegressionToListV2(quarterDataList[i].DataList, handleDataMap)
|
|
|
+ if err != nil {
|
|
|
+ err = errors.New("插值处理数据异常, Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for _, date := range dataTimeList {
|
|
|
+ dateTime, e := time.Parse(utils.FormatDate, date)
|
|
|
+ if e != nil {
|
|
|
+ err = errors.New("时间格式化异常, Err:" + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if dateTime.Year() < startYear {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ // 不包含2月29号
|
|
|
+ if dateTime.Month() == 2 && dateTime.Day() == 29 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ newDate := dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
|
|
|
+ // 处理均值
|
|
|
+ if value, ok := valueMap[newDate]; ok {
|
|
|
+ valueMap[newDate] = (handleDataMap[date] + value) / 2
|
|
|
+ } else {
|
|
|
+ valueMap[newDate] = handleDataMap[date]
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTimeMap[newDate] = newDate
|
|
|
+ valueList := dataTimeValueMap[newDate]
|
|
|
+ valueList = append(valueList, handleDataMap[date])
|
|
|
+ dataTimeValueMap[newDate] = valueList
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range dataTimeMap {
|
|
|
+ valueList := dataTimeValueMap[v]
|
|
|
+ stdev := utils.CalculateStandardDeviation(valueList)
|
|
|
+ stdev, _ = decimal.NewFromFloat(stdev).Round(4).Float64()
|
|
|
+
|
|
|
+ maxMinItem := &models.MaxMinLimitsData{}
|
|
|
+
|
|
|
+ if value, ok := valueMap[v]; ok {
|
|
|
+ maxMinItem.MaxValue = value + stdev*seasonConfig.SamePeriodStandardDeviation.Multiple
|
|
|
+ maxMinItem.MinValue = value - stdev*seasonConfig.SamePeriodStandardDeviation.Multiple
|
|
|
+ }
|
|
|
+
|
|
|
+ maxMinItem.DataTime = v.Format(utils.FormatDate)
|
|
|
+ maxMinItem.DataTimestamp = v.UnixNano() / 1e6
|
|
|
+
|
|
|
+ samePeriodStandardDeviationList = append(samePeriodStandardDeviationList, maxMinItem)
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 排序
|
|
|
+ sort.Slice(samePeriodStandardDeviationList, func(i, j int) bool {
|
|
|
+ return samePeriodStandardDeviationList[i].DataTime < samePeriodStandardDeviationList[j].DataTime
|
|
|
+ })
|
|
|
+
|
|
|
+ dataResp.SamePeriodStandardDeviation.List = samePeriodStandardDeviationList
|
|
|
+ dataResp.SamePeriodStandardDeviation.Color = seasonConfig.SamePeriodStandardDeviation.Color
|
|
|
+ dataResp.SamePeriodStandardDeviation.Legend = seasonConfig.SamePeriodStandardDeviation.Legend
|
|
|
+ dataResp.SamePeriodStandardDeviation.IsShow = seasonConfig.SamePeriodStandardDeviation.IsShow
|
|
|
+ dataResp.SamePeriodStandardDeviation.Multiple = seasonConfig.SamePeriodStandardDeviation.Multiple
|
|
|
+ dataResp.SamePeriodStandardDeviation.Year = seasonConfig.SamePeriodStandardDeviation.Year
|
|
|
+ dataResp.SamePeriodStandardDeviation.IsAdd = seasonConfig.SamePeriodStandardDeviation.IsAdd
|
|
|
+ }
|
|
|
+
|
|
|
+ // 自定义右轴
|
|
|
+ if seasonConfig.RightAxis.IndicatorType != 0 {
|
|
|
+ if seasonConfig.RightAxis.IndicatorType == 1 {
|
|
|
+ startTime, _ := time.Parse(utils.FormatDate, mappingItem.StartDate)
|
|
|
+ for i := len(quarterDataList) - 1; i > len(quarterDataList)-2 && i > 0; i-- {
|
|
|
+ var rightMappingItem models.ChartEdbInfoMapping
|
|
|
+ rightMappingItem = *mappingItem
|
|
|
+ // 计算同比值
|
|
|
+ tbzDataList, minValue, maxValue, e := GetEdbDataTbzForSeason(mappingItem.Frequency, quarterDataList[i].DataList, startTime)
|
|
|
+ if e != nil {
|
|
|
+ err = errors.New("计算同比值失败, Err:" + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ rightMappingItem.DataList = tbzDataList
|
|
|
+ rightMappingItem.MaxData = maxValue
|
|
|
+ rightMappingItem.MinData = minValue
|
|
|
+ dataResp.RightAxis.EdbInfoList = append(dataResp.RightAxis.EdbInfoList, &rightMappingItem)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dataResp.RightAxis.SeasonRightAxis = seasonConfig.RightAxis
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetChartDetailDataByChartInfoId 根据图表信息id获取图表详情数据
|
|
|
+func GetChartDetailDataByChartInfoId(chartInfo *models.ChartInfoView, isCache bool) (resp *models.ChartInfoDetailResp, err error, errMsg string) {
|
|
|
+ // 添加至缓存中
|
|
|
+ //是否走缓存
|
|
|
+ chartInfoId := chartInfo.ChartInfoId
|
|
|
+ resp = new(models.ChartInfoDetailResp)
|
|
|
+
|
|
|
+ //判断是否存在缓存,如果存在缓存,那么直接从缓存中获取
|
|
|
+ key := fmt.Sprint(utils.CACHE_CHART_INFO_DATA, chartInfo.ChartInfoId)
|
|
|
+ if utils.Re == nil && isCache {
|
|
|
+ if utils.Re == nil && utils.Rc.IsExist(key) {
|
|
|
+ if chartData, err1 := utils.Rc.RedisBytes(key); err1 == nil {
|
|
|
+ err = json.Unmarshal(chartData, &resp)
|
|
|
+ if err != nil || resp == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ chartType := chartInfo.ChartType
|
|
|
+
|
|
|
+ startDate := chartInfo.StartDate
|
|
|
+ endDate := chartInfo.EndDate
|
|
|
+ seasonStartDate := chartInfo.SeasonStartDate
|
|
|
+ seasonEndDate := chartInfo.SeasonEndDate
|
|
|
+ startYear := chartInfo.StartYear
|
|
|
+
|
|
|
+ calendar := chartInfo.Calendar
|
|
|
+
|
|
|
+ dateType := chartInfo.DateType
|
|
|
+
|
|
|
+ // 获取主题样式
|
|
|
+ chartTheme, err := GetChartThemeConfig(chartInfo.ChartThemeId, chartInfo.Source, chartInfo.ChartType)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "获取失败"
|
|
|
+ err = fmt.Errorf("获取主题信息失败,Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ chartInfo.ChartThemeStyle = chartTheme.Config
|
|
|
+ chartInfo.ChartThemeId = chartTheme.ChartThemeId
|
|
|
+
|
|
|
+ mappingList := make([]*models.ChartEdbInfoMapping, 0)
|
|
|
+
|
|
|
+ mappingList, err = models.GetChartEdbMappingList(chartInfoId)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "获取失败"
|
|
|
+ err = fmt.Errorf("获取图表,指标信息失败,Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图表额外数据参数
|
|
|
+ extraConfigStr := chartInfo.ExtraConfig
|
|
|
+ // 柱方图的一些配置
|
|
|
+ var barConfig models.BarChartInfoReq
|
|
|
+ if chartInfo != nil && chartInfo.ChartType == 7 {
|
|
|
+ if chartInfo.BarConfig == `` {
|
|
|
+ errMsg = "柱方图未配置"
|
|
|
+ err = fmt.Errorf("柱方图未配置")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = json.Unmarshal([]byte(chartInfo.BarConfig), &barConfig)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "柱方图配置异常"
|
|
|
+ err = fmt.Errorf("柱方图配置异常")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ extraConfigStr = chartInfo.BarConfig
|
|
|
+ }
|
|
|
+ if chartType == 2 {
|
|
|
+ startDate = seasonStartDate
|
|
|
+ endDate = seasonEndDate
|
|
|
+ if dateType <= 0 {
|
|
|
+ if startDate != "" {
|
|
|
+ dateType = 5
|
|
|
+ } else {
|
|
|
+ dateType = utils.DateTypeNYears
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if dateType <= 0 {
|
|
|
+ dateType = 3
|
|
|
+ }
|
|
|
+ }
|
|
|
+ yearMax := 0
|
|
|
+ if dateType == utils.DateTypeNYears {
|
|
|
+ for _, v := range mappingList {
|
|
|
+ if v.LatestDate != "" {
|
|
|
+ lastDateT, tErr := time.Parse(utils.FormatDate, v.LatestDate)
|
|
|
+ if tErr != nil {
|
|
|
+ errMsg = "获取失败"
|
|
|
+ err = fmt.Errorf("获取图表日期信息失败,Err:" + tErr.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if lastDateT.Year() > yearMax {
|
|
|
+ yearMax = lastDateT.Year()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax)
|
|
|
+
|
|
|
+ if chartInfo.ChartType == 2 {
|
|
|
+ chartInfo.StartDate = startDate
|
|
|
+ chartInfo.EndDate = endDate
|
|
|
+ chartInfo.Calendar = calendar
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取图表中的指标数据
|
|
|
+ edbList, xEdbIdValue, yDataList, dataResp, err, errMsg := GetChartEdbData(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr, chartInfo.SeasonExtraConfig)
|
|
|
+ if err != nil {
|
|
|
+ if errMsg == `` {
|
|
|
+ errMsg = "获取失败"
|
|
|
+ }
|
|
|
+ err = fmt.Errorf("获取图表,指标信息失败,Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 单位
|
|
|
+ if chartType == utils.CHART_TYPE_BAR && len(yDataList) > 0 {
|
|
|
+ chartInfo.Unit = yDataList[0].Unit
|
|
|
+ chartInfo.UnitEn = yDataList[0].UnitEn
|
|
|
+ }
|
|
|
+ warnEdbList := make([]string, 0)
|
|
|
+ for _, v := range edbList {
|
|
|
+ if v.IsNullData {
|
|
|
+ warnEdbList = append(warnEdbList, v.EdbName+"("+v.EdbCode+")")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(warnEdbList) > 0 {
|
|
|
+ chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
|
|
|
+ }
|
|
|
+ // 图表的指标来源
|
|
|
+ sourceNameList, sourceNameEnList := GetEdbSourceByEdbInfoIdList(edbList)
|
|
|
+ chartInfo.ChartSource = strings.Join(sourceNameList, ",")
|
|
|
+ chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
|
|
|
+ //判断是否需要展示英文标识
|
|
|
+ chartInfo.IsEnChart = CheckIsEnChart(chartInfo.ChartNameEn, edbList, chartInfo.Source, chartInfo.ChartType)
|
|
|
+
|
|
|
+ resp.EdbInfoList = edbList
|
|
|
+ resp.XEdbIdValue = xEdbIdValue
|
|
|
+ resp.YDataList = yDataList
|
|
|
+ resp.DataResp = dataResp
|
|
|
+
|
|
|
+ chartInfo.Button = models.ChartViewButton{
|
|
|
+ IsEdit: chartInfo.IsEdit,
|
|
|
+ IsEnChart: chartInfo.IsEnChart,
|
|
|
+ IsAdd: chartInfo.IsAdd,
|
|
|
+ IsCopy: true,
|
|
|
+ IsSetName: chartInfo.IsSetName,
|
|
|
+ }
|
|
|
+ resp.ChartInfo = chartInfo
|
|
|
+ // 将数据加入缓存
|
|
|
+ if utils.Re == nil {
|
|
|
+ d, _ := json.Marshal(resp)
|
|
|
+ _ = utils.Rc.Put(key, d, 2*time.Hour)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|