Переглянути джерело

Merge branch 'master' of http://8.136.199.33:3000/hongze/raiwechat_link_h5

ldong 3 місяців тому
батько
коміт
04e70275c4

Різницю між файлами не показано, бо вона завелика
+ 27 - 1240
src/views/hzyb/chart/Detail.vue


+ 1 - 1
src/views/hzyb/chart/component/chartBox.vue

@@ -200,7 +200,7 @@ watch(
             >
 
 							<template v-if="!item.linkedTo">
-                <span class="color" :style="{background:item.visible?item.color:'#ccc'}"></span>
+                <span class="color" :style="{background:item.visible?(item.color||props.options.colors[index]):'#ccc'}"></span>
                 <span :style="{color:item.visible?'':'#ccc'}">{{item.name.length>20?item.name.replace(/<br>/g,''):item.name}}</span>
 							</template>	
             </div>

+ 2409 - 0
src/views/hzyb/hooks/chartRender.js

@@ -0,0 +1,2409 @@
+import { reactive, toRefs, onMounted, ref,watch } from "vue";
+import _ from "lodash";
+import Highcharts from "highcharts";
+import moment from "moment";
+// import router from '@/router'
+
+
+// 散点x轴
+const scatterXAxis = {
+  tickPosition: 'inside',
+  lineColor: '#bfbfbf',
+  tickColor: '#bfbfbf',
+  tickLength:5,
+  ordinal: false,
+  type: 'linear',
+}
+
+// 基础y轴配置
+const basicYAxis = {
+  tickWidth: 1,
+  tickLength: 5,
+  lineWidth: 1,
+  lineColor: '#bfbfbf',
+  tickColor: '#bfbfbf',
+  // offset: 0,
+  visible: true,
+  gridLineWidth: 0,
+  tickPosition: 'inside',
+  endOnTick: false,
+  startOnTick: false,
+  showLastLabel: true,
+  tickPixelInterval: 50,
+}
+
+//基础x轴配置
+const basicXAxis={
+  tickPosition: 'inside',
+  lineColor: '#bfbfbf',
+  tickColor: '#bfbfbf',
+  tickLength:5,
+  type: 'datetime',
+  ordinal: false,
+  dateTimeLabelFormats: {
+      day: '%y/%m',
+      week: '%y/%m',
+      month: '%y/%m',
+      year: '%y/%m',
+  },
+  xDateFormat:'%Y-%m-%d'
+}
+//季节性图设置
+const seasonOptions = {
+  //默认颜色配置
+  colors:['#4B0082','#7FFFAA','#FF4500','#808000','#EEE8AA','#849EC1','#8A4294','#578B5A','#FDA8C7','#53B3FF','#999999','#000000','#FFDF0C','#FF0000','#0033FF'],
+  yAxis: {
+      lineWidth: 1,
+      lineColor: '#bfbfbf',
+      tickColor: '#bfbfbf',
+      offset: 0,
+      opposite: false,
+      reversed: false,
+      visible: true,
+      gridLineWidth: 0,
+      tickWidth: 1,
+      tickLength:5,
+      tickPosition: 'inside',
+      endOnTick: false,
+      startOnTick: false,
+      showLastLabel: true, //显示最后刻度值
+      tickPixelInterval: 50
+  }
+}
+
+
+
+/**
+ * useChartRender 处理图表渲染 返回options
+ * @param Data 详情数据
+ * @param {
+*  Source 1 //ETA图  ChartType: 1曲线图 2季节图 3面积图 4柱状图 5散点图 6组合图 7柱形 10截面散点 11雷达图
+* 2 商品价格
+* 3 相关性
+* 4 滚动相关性
+* 5 商品利润
+* 6 拟合方程
+* 7 统计特征/标准差
+* 8 统计特征/百分位
+* 9 统计特征/频率
+* 10 跨品种分析
+* 11 平衡表图
+* 12 区间分析图
+* }
+*
+*/
+//依赖数据
+const chartData = ref(null)
+let hasLeftAxis=ref(false)//是否有左轴
+let hasRightAxis=ref(false)//是否有右轴
+let hasRightTwoAxis=ref(false)//是否有右2轴
+let axisLimitData=reactive({//左右轴极值
+    leftMin:0,
+    leftMax:0,
+    rightMin:0,
+    rightMax:0,
+    rightTwoMin:0,
+    rightTwoMax:0,
+    xMin:0,
+    xMax:0,
+})
+
+export function userChartRenderState() {
+  return {
+    useChartRender,
+    hasLeftAxis,
+    hasRightAxis,
+    hasRightTwoAxis,
+    axisLimitData
+  }
+}
+
+export const useChartRender = (Data) => {
+
+  chartData.value = Data;
+
+  let chartOptions;
+
+  //eta图
+  if ([1,11,12].includes(Data.ChartInfo.Source)) {
+    setLimitData(Data)
+    const typeMap = {
+      1: setSplineOpt,
+      2: setSeasonOpt,
+      3: setStackOrCombinChart,
+      4: setStackOrCombinChart,
+      5: setScatterOptions,
+      6: setStackOrCombinChart,
+      7: initBarData,
+      10: initSectionScatterData,
+      11: initRadarData,
+      14: initSectionalCombinationChart,
+    };
+
+    chartOptions = typeMap[Data.ChartInfo.ChartType] && typeMap[Data.ChartInfo.ChartType](Data);
+  }else {
+    //其他source图
+    const sourceTypeMap = {
+      2: initCommodityData,
+      3: initRelevanceChart,
+      4: setSplineOpt,
+      5: initCommodityData,
+      6: setSplineOpt,
+      7: setSplineOpt,
+      8: setSplineOpt,
+      9: setStatisticFrequency,
+      10: initCrossVarietyChartData,
+      12: setSplineOpt
+    };
+  
+    chartOptions = sourceTypeMap[Data.ChartInfo.Source] &&
+      sourceTypeMap[Data.ChartInfo.Source](Data);
+  }
+
+
+  return chartOptions
+};
+
+
+// 设置常规图配置 曲线
+function setSplineOpt(e){
+  const isETASource = [1,11,12].includes(e.ChartInfo.Source)  
+  const data=[4,6,7,8].includes(e.ChartInfo.Source)?[e.DataResp]:e.EdbInfoList
+  let series=[]
+  let yAxis=[]
+  let xAxis = {}
+
+  let temYLeftArr=[]
+  let temYRightArr=[]
+  let temYLeftIndex=data.findIndex((item) => item.IsAxis===1)
+  let temYRightIndex=data.findIndex((item) => !item.IsAxis)
+  let temYRightTwoIndex = data.findIndex((item) => item.IsAxis===2)
+  hasLeftAxis.value=temYLeftIndex!==-1
+  hasRightAxis.value=temYRightIndex!==-1
+  hasRightTwoAxis.value=temYRightTwoIndex!==-1
+
+   /* 主题样式*/
+  const chartTheme =  e.ChartInfo.ChartThemeStyle ? JSON.parse(e.ChartInfo.ChartThemeStyle) : null;
+
+  let minAndMaxTimeTemArr=[]//存放所有指标的最大最小时间
+
+  //有右二轴时排个序 按照左 右 右2的顺序
+  let newData = data.some(_ =>_.IsAxis===2) ? changeEdbOrder(data) : data;
+  
+
+  newData.forEach((item,index)=>{
+
+       //轴位置值相同的下标
+      let sameSideIndex = newData.findIndex(i => i.IsAxis === item.IsAxis);
+
+      let dynamic_title = item.EdbName;
+      let dynamic_arr = newData.filter(
+        (item) => dynamic_title === item.EdbName
+      );
+      //处理数据列name
+      let temName= setDyncmicSerieName(item,dynamic_arr)  
+
+      //预测指标配置
+      let predict_params = item.EdbInfoCategoryType === 1 ? getPredictParams(item) : {};
+      // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+      const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
+      let seriesItemObj={
+          data:[],
+          dataGrouping:{
+              enabled:false
+          },
+          type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
+          yAxis:index,
+          name:temName,
+          color: item.ChartColor,
+          lineWidth: Number(item.ChartWidth)|| (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth)||1,
+          visible:true,
+          LatestDate:item.LatestDate,
+          LatestValue:item.LatestValue,
+          marker: chartTheme && chartTheme.lineOptionList[lineIndex].dataMark && chartTheme.lineOptionList[lineIndex].dataMark!='none'?{
+              enabled:true,
+              symbol: chartTheme.lineOptionList[lineIndex].markType || 'circle',
+              fillColor:chartTheme.lineOptionList[lineIndex].markColor,
+              radius: chartTheme.lineOptionList[lineIndex].markSize
+          }:{},
+          ...predict_params
+      }
+      item.DataList = item.DataList || [];
+      for (let i of item.DataList) {
+        seriesItemObj.data.push([i.DataTimestamp, i.Value]);
+      }
+      series.push(seriesItemObj)
+      
+
+      // 设置y轴
+      if(item.IsAxis){
+          temYLeftArr.push(item)
+      }else{
+          temYRightArr.push(item)
+      }
+
+      //获取上下限
+      let minLimit = 0,maxLimit = 0;
+      if(isETASource){
+          const limitMap = {
+              0:['rightMin','rightMax'],
+              1:['leftMin','leftMax'],
+              2:['rightTwoMin','rightTwoMax']
+          }
+          if(limitMap[item.IsAxis]){
+              minLimit = axisLimitData[`${limitMap[item.IsAxis][0]}`]||0
+              maxLimit = axisLimitData[`${limitMap[item.IsAxis][1]}`]||0
+          }
+      }else {
+        minLimit =  item.MinData
+        maxLimit = item.MaxData
+      }
+      const textZh =e.ChartInfo.Source===12?item.ConvertUnit : item.ConvertUnit||item.Unit
+
+      let yItem={
+          ...basicYAxis,
+          IsAxis:item.IsAxis,
+          labels: {
+              formatter: function (ctx) {
+                  return sameSideIndex !== index ? '' : ctx.value;
+              },
+              align: 'center',
+              x: [0,2].includes(item.IsAxis) ? 5 : -5,
+              style:{
+                  ...chartTheme&&chartTheme.yAxisOptions.style
+              },
+          },
+          tickWidth: sameSideIndex !== index ? 0 : 1,
+          title: {
+              text:  sameSideIndex !== index ? '' : textZh,
+              align: 'high',
+              rotation: 0,
+              y: -15,
+              x: (item.IsAxis===0 && temYRightTwoIndex>-1) ? -newData[temYRightTwoIndex].Unit.length*12 : 0,
+              textAlign: item.IsAxis===1 ? 'left' : 'right',
+              reserveSpace: false,
+              style:{
+                  ...chartTheme&&chartTheme.yAxisOptions.style
+              },
+          },
+          opposite: [0,2].includes(item.IsAxis),
+          reversed: item.IsOrder,
+          min: Number(minLimit),
+          max: Number(maxLimit),
+          visible: sameSideIndex === index,
+          plotBands: setAxisPlotAreas(item.IsAxis),
+          plotLines: setAxisPlotLines(item.IsAxis),
+          chartEdbInfo:item//指标数据用于在保存时读取指标数据
+      }
+      yAxis.push(yItem)
+      
+      if(item.DataList.length>0){
+          minAndMaxTimeTemArr.push(item.DataList[0].DataTimestamp)
+          minAndMaxTimeTemArr.push(item.DataList[item.DataList.length-1].DataTimestamp)
+      }
+      
+  })
+  
+  
+  // 设置x轴
+  // 找出所有指标的最大和最小时间 分成6段
+  let minTime=Math.min.apply(null,minAndMaxTimeTemArr)
+  let maxTime=Math.max.apply(null,minAndMaxTimeTemArr)
+
+
+  const isLessThanOneYear = xTimeDiffer(minTime,maxTime)
+  xAxis={
+      ...basicXAxis,
+      tickInterval:((maxTime-minTime)/6)/(24*3600*1000)>30?(maxTime-minTime)/6:24*3600*1000*30,
+      labels: {
+          formatter:  (ctx)=> {
+              return isLessThanOneYear
+              ? Highcharts.dateFormat('%m/%d', ctx.value)
+              : Highcharts.dateFormat('%y/%m', ctx.value);
+          },
+          style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+          }
+      },
+      plotBands: setAxisPlotAreas(3,'datetime'),
+      plotLines: setAxisPlotLines(3,'datetime')
+  }
+  
+
+  yAxis.forEach(item=>{
+      if(item.IsAxis===1){//左轴
+          hasLeftAxis.value=true
+          if(!isETASource){
+            item.min=data[temYLeftIndex].MinData
+            item.max=data[temYLeftIndex].MaxData
+            axisLimitData.leftMin=data[temYLeftIndex].MinData
+            axisLimitData.leftMax=data[temYLeftIndex].MaxData
+          }
+      }else if (item.IsAxis===2){ // 右2轴
+          hasRightTwoAxis.value=true
+          if(!isETASource){
+            item.min=data[temYRightTwoIndex].MinData
+            item.max=data[temYRightTwoIndex].MaxData
+            axisLimitData.rightTwoMin=data[temYRightTwoIndex].MinData
+            axisLimitData.rightTwoMax=data[temYRightTwoIndex].MaxData
+          }
+      }else{
+          hasRightAxis.value=true
+          if(!isETASource){
+            item.min=data[temYRightIndex].MinData
+            item.max=data[temYRightIndex].MaxData
+            axisLimitData.rightMin=data[temYRightIndex].MinData
+            axisLimitData.rightMax=data[temYRightIndex].MaxData
+          }
+      }
+  })
+
+   //滚动相关性独立tooltip
+  if(chartData.value.ChartInfo.Source === 4) {
+      const { LeadValue,LeadUnit } = chartData.value.CorrelationChartInfo;
+      chartData.value.tooltip = {
+        formatter: function() {
+          let str = `${Highcharts.dateFormat('%Y/%m/%d',this.x)}<br><p>相关性系数:${this.y.toFixed(4)}</p><br><p>领先${LeadValue+LeadUnit}</p>`
+         
+          return str
+        }
+      }
+  }
+
+  return {
+    xAxis: [xAxis],
+    yAxis,
+    series,
+    rangeSelector:{ enabled: false}
+  }
+}
+
+
+//设置季节图配置
+function setSeasonOpt(e){
+  hasLeftAxis.value=true
+  hasRightTwoAxis = false
+
+  const {RightAxis:SeasonRightConfig={}} = e.DataResp||{}
+  hasRightAxis.value=SeasonRightConfig.IsShow?true:false
+
+  /* 主题样式*/
+  const chartTheme =  e.ChartInfo.ChartThemeStyle ? JSON.parse(e.ChartInfo.ChartThemeStyle) : null;
+
+  let chartData={}
+  const data=e.EdbInfoList[0]
+  const calendarType=e.ChartInfo.Calendar||'公历'
+
+  const colorsArr=chartTheme&&chartTheme.colorsOptions.reverse();
+  let series=[],yAxis=[]
+
+  // 公历
+  // ETA1.0.5 农历数据需要去除第一项 除此之外 农历和公历处理逻辑一样
+  const chartDataHandle = calendarType === '农历'?
+                          data.DataList.slice(1,data.DataList.length)||[]:
+                          data.DataList
+
+  // 跟颜色对应
+  chartTheme && (chartTheme.lineOptionList=chartTheme.lineOptionList.reverse().slice(-chartDataHandle.length))
+
+  let maxDateRange=0;
+  //常规左轴
+  chartDataHandle.forEach((item,index)=>{
+          //预测指标配置
+      let predict_params =  data.EdbInfoCategoryType === 1 ? getSeasonPredictParams(item.CuttingDataTimestamp) : {};
+      // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+      const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
+      let seriesItem={
+          data:[],
+          dataGrouping:{
+              enabled:false
+          },
+          type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || data.ChartStyle,
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
+          yAxis:0,
+          name:item.ChartLegend,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 1,
+          // color:colorsArr.slice(-chartDataHandle.length)[lineIndex],       
+          visible:true,
+          marker: chartTheme && chartTheme.lineOptionList[lineIndex].dataMark && chartTheme.lineOptionList[lineIndex].dataMark!='none'?{
+              enabled:true,
+              symbol: chartTheme.lineOptionList[lineIndex].markType || 'circle',
+              fillColor:chartTheme.lineOptionList[lineIndex].markColor,
+              radius: chartTheme.lineOptionList[lineIndex].markSize
+          }:{},
+          ...predict_params
+      }
+      item.DataList=item.DataList||[]
+
+      const data_array=item.DataList||[]
+      if(data_array.length>0){
+          let dateRange = item.DataList[item.DataList.length-1].DataTimestamp - item.DataList[0].DataTimestamp
+          // 时间范围
+          maxDateRange=Math.max(maxDateRange,dateRange)
+      }
+
+      for(let i of item.DataList){
+          seriesItem.data.push([i.DataTimestamp, i.Value])
+      }
+      series.push(seriesItem)
+
+  })
+  //同期上下限/均线/标准差
+  const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = e.DataResp||{}
+  if(MaxMinLimits.IsShow&&MaxMinLimits.List&&MaxMinLimits.List.length){
+      let serieItem = {
+          type:'arearange',//上下限是一个范围
+          data:[],
+          name:MaxMinLimits.Legend||'同期上下限',
+          color:MaxMinLimits.Color||'#075EEE' ,
+          fillOpacity:parseRgbaColor(MaxMinLimits.Color||'')>0.75?0.75:parseRgbaColor(MaxMinLimits.Color||''), //透明度最高0.75 
+          visible:true,
+      }
+      MaxMinLimits.List.forEach(item=>{
+          serieItem.data.push([item.DataTimestamp,item.MinValue,item.MaxValue])
+      })
+      series.push(serieItem)
+  }
+  if(SamePeriodAverage.IsShow&&SamePeriodAverage.List){
+      let serieItem = {
+          type:'line',
+          data:[],
+          lineWidth:SamePeriodAverage.LineWidth,
+          dashStyle:SamePeriodAverage.LineType,
+          name:SamePeriodAverage.Legend||'同期均值',
+          color:SamePeriodAverage.Color||'#075EEE',
+          visible:true,
+      }
+      SamePeriodAverage.List.forEach(item=>{
+          serieItem.data.push([item.DataTimestamp,item.Value])
+      })
+      series.push(serieItem)
+  }
+  if(SamePeriodStandardDeviation.IsShow&&SamePeriodStandardDeviation.List){
+      let serieItem = {
+          type:'arearange',//标准差也是一个范围
+          data:[],
+          name:SamePeriodStandardDeviation.Legend||'同期标准差',
+          color:SamePeriodStandardDeviation.Color||'#075EEE',
+          fillOpacity:parseRgbaColor(SamePeriodStandardDeviation.Color||'')>0.75?0.75:parseRgbaColor(SamePeriodStandardDeviation.Color||''),
+          visible:true,
+      }
+      SamePeriodStandardDeviation.List.forEach(item=>{
+          serieItem.data.push([item.DataTimestamp,item.MinValue,item.MaxValue])
+      })
+      series.push(serieItem)
+  }
+  //右轴
+  if(SeasonRightConfig.IsShow){
+      //右轴的设置
+      let serieConfig = SeasonRightConfig.Style==='column'?{
+          //柱形
+          type:'column',
+          color:SeasonRightConfig.ChartColor,
+          visible:true,
+      }:{
+          //标记点
+          type:'spline',
+          lineWidth:SeasonRightConfig.LineWidth,
+          dashStyle:SeasonRightConfig.LineStyle,
+          color:SeasonRightConfig.IsConnected?SeasonRightConfig.LineColor:'rgba(255, 255, 255, 0)',//没有连线颜色设置为透明
+          marker:{
+              enabled:true,
+              symbol:SeasonRightConfig.Shape,
+              fillColor:SeasonRightConfig.ChartColor,
+              radius:SeasonRightConfig.Size
+          },
+          visible:true,
+      }
+      let serieItem = {
+          ...serieConfig,
+          name:SeasonRightConfig.Legend||'',
+          data:[],
+          yAxis:1,
+      }
+      const DataList = (SeasonRightConfig.IndicatorType===1?SeasonRightConfig.EdbInfoList[0].DataList:e.EdbInfoList[1]?.DataList)||[]
+      DataList.forEach(item=>{
+          serieItem.data.push([item.DataTimestamp,item.Value])
+      })
+      series.push(serieItem)
+  }
+
+  //获取上下限
+  let minLimit = 0,maxLimit = 0,rightMin = 0,rightMax = 0
+  //非ETA图库不使用自定义上下限 非ETA图库的季节性图也不能设置右轴
+  minLimit = axisLimitData.leftMin||0
+  maxLimit = axisLimitData.leftMax||0
+  //右轴上下限设置
+  if(SeasonRightConfig.IsShow){
+      rightMin = axisLimitData.rightMin||0
+      rightMax = axisLimitData.rightMax||0
+  }
+  const textZh = data.ConvertUnit||data.Unit
+
+  yAxis=[{
+      IsAxis:data.IsAxis,
+      labels: {
+          align: 'center',
+          y:5,
+          style: {
+              ...chartTheme&&chartTheme.yAxisOptions.style
+          }
+      },
+      title: {
+          text:  textZh,
+          align: 'high',
+          rotation: 0,
+          y: -15,
+          x: 0,
+          textAlign: 'left',
+          reserveSpace: false,
+          style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+          },
+      },
+      max: Number(maxLimit),
+      min: Number(minLimit),
+      plotBands: setAxisPlotAreas(1),
+      plotLines: setAxisPlotLines(1),
+      lineWidth: 1,
+      lineColor: '#bfbfbf',
+      tickColor: '#bfbfbf',
+      offset: 0,
+      opposite: false,
+      reversed: false,
+      visible: true,
+      gridLineWidth: 0,
+      tickWidth: 1,
+      tickLength:5,
+      tickPosition: 'inside',
+      endOnTick: false,
+      startOnTick: false,
+      showLastLabel: true, //显示最后刻度值
+      tickPixelInterval: 50,
+      // chartEdbInfo:item//指标数据
+  }]
+
+  //如果有右轴,yAxis加上右轴
+  if(SeasonRightConfig.IsShow){
+      const rightEdb = (SeasonRightConfig.IndicatorType===1?SeasonRightConfig.EdbInfoList[0]:e.EdbInfoList[1])||{Unit:''}
+      //左轴同比:text为空或% 右轴指标:取指标单位
+      if(SeasonRightConfig.IndicatorType===1){
+          rightEdb.Unit = SeasonRightConfig.NumFormat===1?'%':''
+      }else{
+          rightEdb.Unit = e.EdbInfoList[1]&&(e.EdbInfoList[1].ConvertUnit||e.EdbInfoList[1].Unit)||''
+      }
+      yAxis.push({
+          ...seasonOptions.yAxis,
+          opposite: true,//右轴
+          labels: {
+              align: 'center',
+              y:5,
+              style: {
+                ...chartTheme&&chartTheme.yAxisOptions.style
+              }
+            },
+            title: {
+              text: rightEdb.Unit||'',
+              style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+              },
+              align: 'high',
+              rotation: 0,
+              y: -5,
+              x: 0,
+              textAlign: 'right',
+              reserveSpace: false,
+            },
+            max: Number(rightEdb.MaxData||''),
+            min: Number(rightEdb.MinData||''),
+      })
+  }
+
+  // 季节图x轴显示月/日
+  let xAxis={
+    tickPosition: 'inside',
+    lineColor: '#bfbfbf',
+    tickColor: '#bfbfbf',
+    tickLength:5,
+    type: 'datetime',
+    ordinal: false,
+    dateTimeLabelFormats: {
+      day: '%y/%m',
+      week: '%y/%m',
+      month: '%y/%m',
+      year: '%y/%m',
+    },
+    labels: {
+        formatter: (ctx)=> {
+            return Highcharts.dateFormat('%m/%d', ctx.value)
+        },
+        style: {
+            ...chartTheme&&chartTheme.xAxisOptions.style
+        }
+    },
+    tickInterval:24*3600*1000*60,//季节图
+    plotBands: setAxisPlotAreas(3,'datetime'),
+    plotLines: setAxisPlotLines(3,'datetime')
+  }
+
+  // 季节图提示框显示 月/日
+  let tooltip={
+      split: false,
+      shared: true,
+      dateTimeLabelFormats: {
+        // 时间格式化字符
+        day: '%m/%d',
+        week: '%m/%d',
+        month: '%m/%d',
+        year: '%m/%d',
+      },
+      xDateFormat: '%m/%d',
+  }
+
+  return {
+    colors:colorsArr.slice(-chartDataHandle.length),
+    xAxis:[xAxis],
+    series,
+    yAxis,
+    tooltip
+  }
+
+}
+
+
+/* 堆叠图/组合图设置  
+    本来和曲线图逻辑基本一致兼容下即可 为了以后便于维护和阅读还是拆开写吧
+*/
+function setStackOrCombinChart(e) {
+  const data = e.EdbInfoList;
+  //图表类型
+  const chartTypeMap = {
+      3: 'areaspline',
+      4: 'column',
+      6: ''
+  };
+  let chartStyle = chartTypeMap[e.ChartInfo.ChartType];
+
+  /* 主题样式*/
+  const chartTheme =  e.ChartInfo.ChartThemeStyle ? JSON.parse(e.ChartInfo.ChartThemeStyle) : null;
+
+  let series=[]
+  let yAxis=[]
+  let xAxis = {}
+
+  let temYLeftArr=[]
+  let temYRightArr=[]
+  let temYLeftIndex,temYRightIndex,temYRightTwoIndex;
+
+  let minAndMaxTimeTemArr=[]//存放所有指标的最大最小时间
+
+  //有右二轴时排个序 按照左 右 右2的顺序
+  let newData = data.some(_ =>_.IsAxis===2) ? changeEdbOrder(data) : data;
+
+  newData.forEach((item,index)=>{
+
+      //轴位置值相同的下标
+      let sameSideIndex = newData.findIndex(i => i.IsAxis === item.IsAxis);
+
+      //堆叠图的yAxis必须一致 数据列所对应的y轴
+      let serie_yIndex = index;
+      if([3,4].includes(e.ChartInfo.ChartType)) {
+          // 类型为堆叠图时公用第一个指标y轴 
+          serie_yIndex =  0;
+      } else if(e.ChartInfo.ChartType ===6 && ['areaspline','column'].includes(item.ChartStyle)) {
+          // 组合图找第一个堆叠柱状或面积的作为公用
+          serie_yIndex = newData.findIndex(i => i.ChartStyle === item.ChartStyle);
+      }
+      //数据对应的y轴是公用轴则配置也共享
+      item.IsAxis = serie_yIndex === index ? item.IsAxis : newData[serie_yIndex].IsAxis;
+      item.IsOrder = serie_yIndex === index ? item.IsOrder : newData[serie_yIndex].IsOrder;
+
+      temYLeftIndex = [3,4].includes(e.ChartInfo.ChartType) 
+          ? (newData[serie_yIndex].IsAxis ? serie_yIndex : -1)
+          : data.findIndex((item) => item.IsAxis===1);
+      temYRightIndex = [3,4].includes(e.ChartInfo.ChartType) 
+          ? (newData[serie_yIndex].IsAxis ? -1 : serie_yIndex)
+          : data.findIndex((item) => !item.IsAxis);
+      temYRightTwoIndex = [3,4].includes(e.ChartInfo.ChartType) 
+          ? -1
+          : data.findIndex((item) => item.IsAxis===2);
+
+      let dynamic_title = item.EdbName;
+      let dynamic_arr = newData.filter(
+        (item) => dynamic_title === item.EdbName
+      );
+      //处理数据列name
+      let temName= setDyncmicSerieName(item,dynamic_arr)  
+
+      //预测指标配置
+      let predict_params = item.EdbInfoCategoryType === 1 ? getPredictParams(item,chartStyle) : {};
+      //图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+      const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
+
+      let seriesItemObj={
+          data:[],
+          dataGrouping:{
+              enabled:false
+          },
+          type: chartStyle || item.ChartStyle,
+          yAxis:serie_yIndex,
+          name:temName,
+          color: item.ChartColor,
+          lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 1,
+          fillColor: (e.ChartInfo.ChartType === 3 || (e.ChartInfo.ChartType === 6 && item.ChartStyle === 'areaspline')) ? item.ChartColor : undefined,
+          visible:true,
+          LatestDate:item.LatestDate,
+          LatestValue:item.LatestValue,
+          ...predict_params,
+          stacking:e.ChartInfo.ChartType==6&&!e.DataResp.IsHeap?undefined:'normal',
+      }
+      item.DataList = item.DataList || [];
+      for (let i of item.DataList) {
+        seriesItemObj.data.push([i.DataTimestamp, i.Value]);
+      }
+      series.push(seriesItemObj)
+      
+       //获取上下限
+      let minLimit = 0,maxLimit = 0
+      const limitMap = {
+          0:['rightMin','rightMax'],
+          1:['leftMin','leftMax'],
+          2:['rightTwoMin','rightTwoMax']
+      }
+      if(limitMap[item.IsAxis]){
+          minLimit = axisLimitData[`${limitMap[item.IsAxis][0]}`]||0
+          maxLimit = axisLimitData[`${limitMap[item.IsAxis][1]}`]||0
+      }
+
+      // 设置y轴
+      if(item.IsAxis){
+          temYLeftArr.push(item)
+      }else{
+          temYRightArr.push(item)
+      }
+      const textZh = item.ConvertUnit||item.Unit
+      let yItem={
+          ...basicYAxis,
+          IsAxis:item.IsAxis,
+          labels: {
+              formatter: function (ctx) {
+                  return sameSideIndex !== index ? '' : ctx.value;
+              },
+              align: 'center',
+              x: [0,2].includes(item.IsAxis) ? 5 : -5,
+              style:{
+                  ...chartTheme&&chartTheme.yAxisOptions.style
+              },
+          },
+          title: {
+              text:  textZh,
+              align: 'high',
+              rotation: 0,
+              y: -15,
+              x: (item.IsAxis===0 && temYRightTwoIndex>-1) ? -newData[temYRightTwoIndex].Unit.length*12 : 0,
+              textAlign: item.IsAxis===1 ? 'left' : 'right',
+              reserveSpace: false,
+              style:{
+                  ...chartTheme&&chartTheme.yAxisOptions.style
+              },
+          },
+          opposite: [0,2].includes(item.IsAxis),
+          reversed: item.IsOrder,
+          min: Number(minLimit),
+          max: Number(maxLimit),
+          tickWidth: sameSideIndex !== index ? 0 : 1,
+          visible: serie_yIndex === index && sameSideIndex ===index,
+          chartEdbInfo:item,//指标数据用于在保存时读取指标数据
+          plotBands: setAxisPlotAreas(item.IsAxis),
+          plotLines: setAxisPlotLines(item.IsAxis)
+      }
+      yAxis.push(yItem)
+      
+      if(item.DataList.length>0){
+          minAndMaxTimeTemArr.push(item.DataList[0].DataTimestamp)
+          minAndMaxTimeTemArr.push(item.DataList[item.DataList.length-1].DataTimestamp)
+      }
+      
+  })
+  
+  
+  // 设置x轴
+  // 找出所有指标的最大和最小时间 分成6段
+  let minTime=Math.min.apply(null,minAndMaxTimeTemArr)
+  let maxTime=Math.max.apply(null,minAndMaxTimeTemArr)
+
+
+  const isLessThanOneYear = xTimeDiffer(minTime,maxTime)
+  xAxis={
+      ...basicXAxis,
+      tickInterval:((maxTime-minTime)/6)/(24*3600*1000)>30?(maxTime-minTime)/6:24*3600*1000*30,
+      labels: {
+          formatter: (ctx)=> {
+              return isLessThanOneYear
+              ? Highcharts.dateFormat('%m/%d', ctx.value)
+              : Highcharts.dateFormat('%y/%m', ctx.value);
+          },
+          style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+          }
+      },
+      plotBands: setAxisPlotAreas(3,'datetime'),
+      plotLines: setAxisPlotLines(3,'datetime')
+  }
+  
+
+  yAxis.forEach(item=>{
+      if(item.IsAxis === 1){//左轴
+          hasLeftAxis.value=true
+      }else if (item.IsAxis===2){ // 右2轴
+          hasRightTwoAxis.value=true
+      }else{
+          hasRightAxis.value=true
+      }
+  })
+
+  return {
+    xAxis: [xAxis],
+    yAxis,
+    series,
+    rangeSelector:{ enabled: false}
+  }
+}
+
+
+/* 散点图 第一个指标值为x轴 第二个指标为y轴*/
+function setScatterOptions(e) {
+  hasLeftAxis.value=true
+
+  const { ChartInfo,EdbInfoList } = e;
+  const dataList = EdbInfoList;
+
+   /* 主题样式*/
+  const chartTheme = ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+
+  // 取2个指标中日期相同的数据
+  const real_data = [];
+  let tmpData_date = {};//用来取点对应的日期
+  let data1 =  _.cloneDeep(dataList)[0].DataList || [];
+  let data2 =  _.cloneDeep(dataList)[1].DataList || [];
+  data1.forEach((_item) => {
+      data2.forEach((_item2) => {
+          if(_item.DataTimestamp === _item2.DataTimestamp) {
+              //日期
+              let itemIndex =_item.Value + "_" +_item2.Value
+              if(tmpData_date[itemIndex]) {
+                  tmpData_date[itemIndex].push( moment(_item.DataTimestamp).format('YYYY/MM/DD'))
+              } else {
+                  tmpData_date[itemIndex] = [moment(_item.DataTimestamp).format('YYYY/MM/DD')]
+              }
+          
+              //值
+              real_data.push({
+                  x: _item.Value,
+                  y: _item2.Value
+              })
+          }
+      })
+  })
+  real_data.sort((x,y) => x-y);
+
+  //悬浮窗 拼接日期 原始指标名称
+  let tooltip = {
+      formatter: function() {
+          return `<strong>${ tmpData_date[this.x+'_'+this.y].length > 4 ? tmpData_date[this.x+'_'+this.y].slice(0,4).join()+'...' : tmpData_date[this.x+'_'+this.y].join() }</strong><br>
+          ${dataList[0].EdbName}: <span style="font-weight: 600">	${this.x}</span><br>
+          ${dataList[1].EdbName}: <span style="font-weight: 600">	${this.y}</span>
+          `
+      }
+  }
+
+  const { IsOrder,ChartColor } = dataList[0];
+   //获取上下限
+  let minLimit = 0,maxLimit = 0
+    minLimit = axisLimitData.leftMin||0
+    maxLimit = axisLimitData.leftMax||0
+
+  //y轴
+  let yAxis = {
+      title: {
+          text:  `${dataList[1].ConvertUnit||dataList[1].Unit}`,
+          align: 'high',
+          rotation: 0,
+          y: -15,
+          x:0,
+          textAlign: 'left',
+          reserveSpace: false,
+          style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+          },
+      },
+      labels: {
+          formatter: function (ctx) {
+          return ctx.value;
+          },
+          align: 'center',
+          style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+          },
+      },
+      IsAxis:1,
+      opposite: false,
+      reversed: IsOrder,
+      min: Number(minLimit),
+      max: Number(maxLimit),
+      plotBands: setAxisPlotAreas(1),
+      plotLines: setAxisPlotLines(1),
+      tickWidth: 1,
+      tickLength: 5,
+      lineWidth: 1,
+      lineColor: '#bfbfbf',
+      tickColor: '#bfbfbf',
+      offset: 0,
+      visible: true,
+      gridLineWidth: 0,
+      tickPosition: 'inside',
+      endOnTick: false,
+      startOnTick: false,
+      showLastLabel: true,
+      tickPixelInterval: 50
+  }
+
+  //数据列
+  let series = {
+      data: [],
+      type: 'scatter',
+      name: `${ChartInfo.ChartName}${IsOrder ? '(逆序)' : ''}`,
+      color: ChartColor,
+      visible:true,
+      chartType: 'linear',
+      marker: {
+        radius: (chartTheme&&chartTheme.lineOptionList[0].radius)||5,
+      },
+  }
+  real_data.forEach(_ => {
+      series.data.push([_.x,_.y])
+  })
+  
+  return {
+      title: {
+          text:''
+      },
+      series: [ series ],
+      yAxis: [yAxis],
+      xAxis: {
+          ...scatterXAxis,
+          title: {
+              text:  `${dataList[0].ConvertUnit||dataList[0].Unit}`,
+              align: 'high',
+              rotation: 0,
+              x: 0,
+              offset: 20,
+              style: {
+                  ...chartTheme&&chartTheme.xAxisOptions.style
+              },
+          },
+          labels: {
+              style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+              }
+          },
+          plotBands: setAxisPlotAreas(3),
+          plotLines: setAxisPlotLines(3)
+      },
+      tooltip
+  }
+}
+
+
+/* 奇怪柱形图 */
+const barDateList = ref([]);//柱形图的绘图数据
+const barXData = ref([]);//柱形图的x轴
+const barEdbData = ref([]);//柱形图的表格数据 只用于取值
+ /* 获取图表详情后赋值柱状图数据 */
+function initBarData (data) {
+    const { XEdbIdValue,YDataList,EdbInfoList,ChartInfo } = data;
+
+    let xData = XEdbIdValue.map(_ => EdbInfoList.find(edb => edb.EdbInfoId===_).EdbAliasName)
+
+    barDateList.value = YDataList;
+    barXData.value = xData;
+    barEdbData.value = EdbInfoList;
+
+    hasLeftAxis.value=true;
+    axisLimitData.leftMin=Number(ChartInfo.LeftMin)
+    axisLimitData.leftMax=Number(ChartInfo.LeftMax)
+
+    return setBarChart(data);
+}
+/* 奇怪柱状图 和其他逻辑无公用点 依赖数据为单独的数据
+    x轴为指标名称的柱形图 以日期作为series
+*/
+function setBarChart(e) {
+    let seriesData = [];
+    const data = _.cloneDeep(barDateList.value);
+    const { ChartInfo } = e;
+
+     /* 主题样式*/
+    const chartTheme =  ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+
+    //x轴
+    let xAxis = {
+        ...scatterXAxis,
+        categories: barXData.value,
+        tickWidth: 1,
+        labels: {
+            style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        }
+    }
+
+    const { leftMin,leftMax } = axisLimitData;
+    //y轴
+    let yAxis = {
+        ...basicYAxis,
+        title: {
+            text: ChartInfo.Unit,
+            align: 'high',
+            rotation: 0,
+            y: -15,
+            textAlign: 'left',
+            reserveSpace: false,
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        labels: {
+            formatter: function (ctx) {
+            let val = ctx.value;
+            return val;
+            },
+            align: 'center',
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        min: Number(leftMin),
+        max: Number(leftMax),
+        opposite: false,
+        tickWidth: 1,
+        plotBands: setAxisPlotAreas(1),
+        plotLines: setAxisPlotLines(1)
+    }
+
+    //数据列
+    data.forEach(item => {
+        let serie_item = {
+            data: item.Value,
+            type: 'column',
+            yAxis: 0,
+            name: item.Name || item.Date,
+            color: item.Color,
+            chartType: 'linear',              
+            visible:true,
+        };
+        seriesData.push(serie_item)
+    })
+    
+    return {
+        title: {
+            text:''
+        },
+        plotOptions: {
+            column:{
+            stacking: null,
+            },
+        },
+        series: seriesData,
+        yAxis: [ yAxis ],
+        xAxis
+    }
+}
+
+
+
+/* 散点截面图 */
+const sectionScatterData = ref({});
+/* 截面散点图获取详情赋值 */
+const initSectionScatterData = (e) => {
+    const { DataResp } = e;
+    sectionScatterData.value = DataResp;
+
+    hasLeftAxis.value=true;
+    axisLimitData.leftMin=Number(DataResp.YMinValue)
+    axisLimitData.leftMax=Number(DataResp.YMaxValue)
+    axisLimitData.xMin=Number(DataResp.XMinValue)
+    axisLimitData.xMax=Number(DataResp.XMaxValue)
+    return setSectionScatterChart(e)
+}
+/* 截面散点图设置 sectionScatterData */
+const setSectionScatterChart = (e) => {
+    const { DataList,XName,XNameEn,XUnitName,XUnitNameEn,YName,YNameEn,YUnitName,YUnitNameEn } = sectionScatterData.value;
+    const { leftMin,leftMax,xMin,xMax }  = axisLimitData;
+    const { ChartInfo } = e;
+    
+     /* 主题样式*/
+    const chartTheme =  ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+
+    //y轴
+    let yAxis = {
+        ...basicYAxis,
+        title: {
+            text: YName,
+            align: 'middle',
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        labels: {
+            style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        opposite: false,
+        reversed: false,
+        min: Number(leftMin),
+        max: Number(leftMax),
+        tickWidth: 1,
+        plotBands: setAxisPlotAreas(1),
+        plotLines: setAxisPlotLines(1)
+    }
+
+    //x轴
+    let xAxis = {
+        ...scatterXAxis,
+        title: {
+            text: XName,
+            align: 'middle',
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            },
+        },
+        labels: {
+            style:{
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            },
+        },
+        min: Number(xMin),
+        max: Number(xMax),
+        plotBands: setAxisPlotAreas(3),
+        plotLines: setAxisPlotLines(3)
+    }
+
+    //数据列
+    let series = [];
+    DataList.forEach((item,index) => {
+        // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+        const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
+        //数据列
+        let series_item = {
+            data: [],
+            type: 'scatter',
+            name: item.Name,
+            color: item.Color,
+            lineWidth: 0,
+            chartType: 'linear',
+            zIndex:1,
+            marker: {
+                radius: (chartTheme&&chartTheme.lineOptionList[lineIndex].radius)||5,
+            },
+            visible: true
+        }
+        item.EdbInfoList.forEach(_ => {
+            series_item.data.push({
+            x: _.XValue,
+            y: _.YValue,
+            dataLabels: {
+                enabled: _.IsShow,
+                allowOverlap: true,
+                align: 'left',
+                format: _.Name,
+                formatCh: _.Name,
+                formatEn: _.NameEn
+            }
+            })
+        })
+        series.push(series_item);
+
+    //趋势线
+    if(item.ShowTrendLine)  {
+        
+        let trend_data = item.TrendLimitData.map((_,_index) => (
+            _index === item.TrendLimitData.length-1 ? {
+                x: _.X,
+                y: _.Y,
+                dataLabels: {
+                enabled: item.ShowRSquare || item.ShowFitEquation,
+                align: 'left',
+                color: '#666',
+                x: 20,
+                y: 30,
+                zIndex: 9,
+                allowOverlap: true,
+                formatter: function(){
+                    let tag = '';
+                    item.ShowRSquare && item.ShowFitEquation
+                    ? tag =`<span>${item.TrendLine}</span><br><span>R²=${item.RSquare}</span>`
+                    : item.ShowRSquare && !item.ShowFitEquation
+                    ? tag =`<span>R²=${item.RSquare}</span>`
+                    : item.ShowFitEquation && !item.ShowRSquare
+                    ? tag =`<span>${item.TrendLine}</span>`
+                    : ''
+                    return tag
+                }
+                }
+            } : {
+                x: _.X,
+                y: _.Y,
+            }
+        ))
+
+        let trend_item = {
+            data: trend_data,
+            type: 'spline',
+            linkedTo: ':previous',
+            color: item.Color,
+            lineWidth: 1,
+            chartType: 'linear',
+            enableMouseTracking: false,
+            dashStyle:'Dash',
+            zIndex: 2,
+            visible: true,
+            marker: {
+                enabled: false
+            }
+        }
+        series.push(trend_item)
+    }
+    })
+
+    let tooltip = {
+        formatter: function() {
+            let series_obj = DataList.find(_ => _.Name === this.series.name);
+            let ponit_obj = series_obj.EdbInfoList.find(_ => _.XValue ===this.x && _.YValue===this.y);
+
+            let str=`<b>${ ponit_obj.Name }</b>`;
+            str += `<br><span style="color:${this.color}">\u25CF</span>${ponit_obj.XName}: ${this.x} ${ponit_obj.XDate}<br>`;
+            str += `<span style="color:${this.color}">\u25CF</span>${ponit_obj.YName}: ${this.y} (${ponit_obj.YDate})`;
+
+            return str
+        }
+    }
+    
+    return {
+        title: {
+            text:''
+        },
+        series,
+        yAxis: [yAxis],
+        xAxis,
+        tooltip
+    }
+}
+
+
+/* 雷达图 */
+const radarChartRenderData =  ref({})
+const initRadarData = (data) => {
+    const { DataResp,EdbInfoList,ChartInfo } = data;
+    
+    radarChartRenderData.value = {
+        YDataList: DataResp.YDataList,
+        XDataList: EdbInfoList.filter(_ => DataResp.XEdbIdValue.includes(_.EdbInfoId))
+    }
+
+    hasLeftAxis.value=true;
+    axisLimitData.leftMin=Number(ChartInfo.LeftMin)
+    axisLimitData.leftMax=Number(ChartInfo.LeftMax)
+
+    return setRadarChart(data);
+}
+const setRadarChart = (data) => {
+  const { YDataList,XDataList } = radarChartRenderData.value;
+
+  const { ChartInfo } = data;
+
+    /* 主题样式*/
+    const chartTheme =  ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+
+    let categories = XDataList.map(_ => _.EdbAliasName||_.EdbName);
+
+    //x轴
+    let xAxis = {
+      lineWidth: 0,
+      tickLength: 0,
+      tickmarkPlacement: 'on',
+      categories,
+      labels: {
+        allowOverlap: true,
+        autoRotationLimit: 40,
+        style: {
+          ...chartTheme&&chartTheme.xAxisOptions.style
+        }
+      }
+    }
+
+    //y轴
+    const { leftMin,leftMax } = axisLimitData;
+    let yAxis = [{
+      gridLineInterpolation: 'polygon',
+      gridLineWidth: 1,
+      lineWidth: 0,
+      endOnTick: false,
+      startOnTick: false,
+      showLastLabel: true,
+      // tickAmount:4,
+      title: {
+        text:  ChartInfo.Unit ,
+        align: 'high',
+        rotation: 0,
+        y: 5,
+        x:10,
+        textAlign: 'left',
+        reserveSpace: false,
+        style:{
+          ...chartTheme&&chartTheme.yAxisOptions.style
+        },
+      },
+      labels: {
+        allowOverlap: true,
+        style:{
+          ...chartTheme&&chartTheme.yAxisOptions.style
+        }
+      },
+      min: Number(leftMin),
+      max: Number(leftMax)
+    }]
+
+    //系列
+    let series = [];
+    YDataList.forEach((item,index) => {
+        // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+        const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
+        let serie_item = {
+            data: item.Value,
+            pointPlacement: 'on',
+            type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'line',
+            dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
+            yAxis: 0,
+            name: item.Name || item.Date,
+            color: item.Color,
+            lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 1,
+            chartType: 'linear',
+            visible: true
+        };
+        series.push(serie_item)
+    })
+
+    return {
+        chart: {
+            ...chartTheme.drawOption,
+            spacing: [2,10,2,10],
+            polar:true,
+        },
+        title: {
+            text:''
+        },
+        pane: {
+            size: '85%'
+        },
+        series,
+        yAxis,
+        xAxis
+    }
+}
+
+
+// 截面组合图初始化
+function initSectionalCombinationChart(e){
+  const {XDataList,UnitList,SeriesList,IsHeap}=e.DataResp
+  /* 主题样式*/
+  const chartTheme =  e.ChartInfo.ChartThemeStyle ? JSON.parse(e.ChartInfo.ChartThemeStyle) : null;
+    
+  let leftIndex = SeriesList.findIndex((item) => item.IsAxis===1);
+  let rightIndex = SeriesList.findIndex((item) => !item.IsAxis);
+  let rightTwoIndex = SeriesList.findIndex((item) => item.IsAxis ===2);
+  // axisLimitData.leftMin=data.ChartInfo.LeftMin
+  // axisLimitData.leftMax=data.ChartInfo.LeftMax
+  // axisLimitData.rightTwoMin=data.ChartInfo.Right2Min
+  // axisLimitData.rightTwoMax=data.ChartInfo.Right2Max
+  // axisLimitData.rightMin=data.ChartInfo.RightMin
+  // axisLimitData.rightMax=data.ChartInfo.RightMax
+  if(leftIndex!=-1) {
+      hasLeftAxis.value=true
+  }
+  if(rightIndex!=-1){
+      hasRightAxis.value=true
+  }
+  if(rightTwoIndex!=-1){
+      hasRightTwoAxis.value=true
+  }
+
+  //x轴
+  const xAxis={
+      categories:XDataList.map(_=>_.Name),
+      tickWidth: 1,
+      labels: {
+        style:{
+          ...chartTheme&&chartTheme.xAxisOptions.style
+        },
+      },
+      plotBands: setAxisPlotAreas(3),
+      plotLines: setAxisPlotLines(3)
+  }
+
+  let yAxis=[]
+  let seriesData=[]
+
+  //有右二轴时排个序 按照左 右 右2的顺序
+  const chartDataList = SeriesList.some(_ =>_.IsAxis===2) ? changeEdbOrder(SeriesList) : _.cloneDeep(SeriesList);
+  chartDataList.forEach((item,index)=>{
+      //轴位置值相同的下标
+      const sameSideIndex = chartDataList.findIndex(
+        (i) => i.IsAxis === item.IsAxis
+      );
+
+      const yTitleMap={
+        1:['LeftName','LeftNameEn'],
+        0:['RightName','RightNameEn'],
+        2:['RightTwoName','RightTwoNameEn'],
+      }
+
+      let minLimit = 0,maxLimit = 0
+      const limitMap = {
+          0:['rightMin','rightMax'],
+          1:['leftMin','leftMax'],
+          2:['rightTwoMin','rightTwoMax']
+      }
+      if(limitMap[item.IsAxis]){
+          minLimit = axisLimitData[`${limitMap[item.IsAxis][0]}`]||0
+          maxLimit = axisLimitData[`${limitMap[item.IsAxis][1]}`]||0
+      }
+
+      let yItem = {
+        ...basicYAxis,
+        title: {
+          text: UnitList[yTitleMap[item.IsAxis][0]],
+          style:{
+            ...chartTheme&&chartTheme.yAxisOptions.style
+          },
+          align: 'high',
+          rotation: 0,
+          y: -12,
+          // x: (item.IsAxis===0 && this.rightTwoIndex>-1) ? -chartData[this.rightTwoIndex].Unit.length*12 : 0,
+          textAlign: item.IsAxis===1 ? 'left' : 'right',
+          reserveSpace: false
+        },
+        labels: {
+          formatter: function (ctx) {
+            return ctx.value;
+          },
+          align: 'center',
+          x: [0,2].includes(item.IsAxis) ? 5 : -5,
+          style: {
+            ...chartTheme&&chartTheme.yAxisOptions.style,
+          }
+        },
+        IsAxis:item.IsAxis,
+        opposite: [0,2].includes(item.IsAxis),
+        min: Number(minLimit),
+        max: Number(maxLimit),
+        tickWidth: 1,
+        visible: sameSideIndex === index,
+        plotBands: setAxisPlotAreas(item.IsAxis),
+        plotLines: setAxisPlotLines(item.IsAxis)
+      };
+
+      //堆叠图的yAxis必须一致 数据列所对应的y轴
+      let serie_yIndex = index;
+      if(IsHeap==1) {
+        // 类型为堆叠图时公用第一个指标y轴 
+        serie_yIndex =  0;
+      }
+
+      //数据列
+      let dataArr=item.DataList||[]
+      // 根据NoDataEdbIndex 将对应位置的值置为null
+      dataArr.forEach((i,index)=>{
+        if(item.NoDataEdbIndex.includes(index)){
+          dataArr[index]=null
+        }
+      })
+      //图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+      const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
+      let obj={
+        data:dataArr,
+        type: item.ChartStyle||'',
+        dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
+        chartType:'linear',
+        yAxis: serie_yIndex,
+        name:item.SeriesName,
+        nameCh:item.SeriesName,
+        nameEn:item.SeriesNameEn,
+        color: item.ChartColor,
+        lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth),
+        borderWidth: 1,
+        borderColor: item.ChartColor,
+        marker: {//展示数据点
+          enabled:item.ChartStyle!='column'&&item.IsPoint?true:false,
+          radius: (chartTheme&&chartTheme.lineOptionList[lineIndex].radius)||5,
+        },
+        dataLabels: {//展示数值
+          enabled: item.IsNumber?true:false,
+          align:item.ChartStyle=='column'?'center':undefined,
+          y:item.ChartStyle=='column'?-20:0,
+          inside: item.ChartStyle=='column'?false:undefined,
+          crop: item.ChartStyle=='column'?false:true,
+        },
+        visible:true,
+        stacking:IsHeap==1?'normal':undefined,
+        zIndex: ['line','spline'].includes(item.ChartStyle) ? 1 : 0, //防止组合图曲线被遮住
+      }
+
+      yAxis.push(yItem)
+      seriesData.push(obj)
+  })
+  
+  console.log(seriesData);
+
+  const tooltip={
+      formatter:function () { 
+        let str=`<b>${this.points[0].x}</b>`
+        this.points.forEach(item=>{
+          const sObj=seriesData.find(_=>_.name===item.series.name)
+          str=str+`<br><span style="color:${item.color}">\u25CF</span>${sObj.name}:${item.y} ${sObj.unitNameCh}`
+        })
+        return str
+      },
+      shared:true
+  }
+  
+
+  return {
+      title: {
+          text:''
+      },
+      tooltip,
+      series: seriesData,
+      yAxis,
+      xAxis,
+  };
+
+    
+}
+
+
+/* 商品价格图 */
+const commodityChartData = ref([]);//商品价格图的绘图数据
+const commodityXData = ref([]);//商品价格图的x轴
+const commodityEdbList = ref([]);//商品价格图的表格数据 只用于取值
+ /* 商品价格曲线获取详情赋值 */
+const initCommodityData = (data) => {
+    const { XDataList,YDataList,EdbInfoList,ChartInfo,DataResp } = data;
+
+    commodityEdbList.value = EdbInfoList;
+    commodityChartData.value = ChartInfo.Source===5?DataResp.YDataList:YDataList;
+    commodityXData.value = ChartInfo.Source===5?DataResp.XDataList:XDataList;
+
+    hasLeftAxis.value=true;
+    axisLimitData.leftMin=Number(ChartInfo.LeftMin)
+    axisLimitData.leftMax=Number(ChartInfo.LeftMax)
+
+    return setCommodityChart(data);
+}
+/* 商品价格曲线设置 绘图逻辑同奇怪柱形图*/
+const setCommodityChart = (e) => {
+
+    const { ChartInfo } = e;
+    /* 主题样式*/
+    const chartTheme =  ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+    
+    let seriesData = [];
+    const data = _.cloneDeep(commodityChartData.value);
+
+    //x轴
+    let xAxis = {
+        ...scatterXAxis,
+        categories: commodityXData.value.filter(_=>_.IsHide===0).map(_ => _.Name),
+        tickWidth: 1,
+        labels: {
+            style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        }
+    }
+
+    const { leftMin,leftMax } = axisLimitData;
+    //y轴
+    let yAxis = {
+        ...basicYAxis,
+        title: {
+            text: commodityEdbList.value[0].Unit,
+            align: 'high',
+            rotation: 0,
+            y: -15,
+            textAlign: 'left',
+            reserveSpace: false,
+            style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        labels: {
+            formatter: function (ctx) {
+            let val = ctx.value;
+            return val;
+            },
+            align: 'center',
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        min: Number(leftMin),
+        max: Number(leftMax),
+        opposite: false,
+        tickWidth: 1,
+    }
+
+    //数据列
+    data.forEach((item,index) => {
+        //处理首或/尾全是无效数据的以null填充
+        let filterData = filterInvalidData(item)
+        // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+        const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
+        let serie_item = {
+            data: filterData,
+            type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'spline',
+            dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
+            yAxis: 0,
+            name: item.Name,
+            color: item.Color,
+            chartType: 'linear',
+            lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 3,
+            visible: true,
+            marker: {
+                enabled: false
+            }
+        };
+        seriesData.push(serie_item)
+    })
+
+    //tooltip
+    let tooltip = {
+        formatter: function() {
+            const ctx = this;
+            let str = '';
+            ctx.points.forEach(item => {
+              let obj_item = data.find(_ => _.Name === item.series.name);
+              let index = commodityXData.value.findIndex(_ => _.Name === ctx.x);
+
+                //合约显示
+                let haveContract = obj_item.XEdbInfoIdList[index];
+                
+                if(haveContract) {
+                    // 利润曲线指标名
+                    const isEdb=commodityEdbList.value.some(_=>_.EdbInfoId===haveContract)
+                    let edb_name = ChartInfo.Source === 5 
+                    ? (isEdb? obj_item.NameList[index] : `${DataResp.ProfitName}(${obj_item.NameList[index]})`)
+                    : commodityEdbList.value.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbName;
+                    str+=`<b>${ edb_name }</b>`
+
+                    if(!obj_item.NoDataEdbList.includes(obj_item.XEdbInfoIdList[index])) {
+                        str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: ${item.y}<br>`
+                    }else {
+                        str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: 无<br>`
+                    }
+                }
+
+            })
+            return str||'无合约'
+        },
+        shared: true
+    }
+    
+    return {
+        title: {
+            text:''
+        },
+        series: seriesData,
+        yAxis: [ yAxis ],
+        xAxis,
+        tooltip
+    }
+};
+/* 处理无效数据为null */
+const filterInvalidData = (item)=> {
+    let validateArr = item.XEdbInfoIdList.filter(_ =>_&&!item.NoDataEdbList.includes(_));
+
+    let first_index = item.XEdbInfoIdList.findIndex(_ => _ === validateArr[0]);
+    let last_index = item.XEdbInfoIdList.findIndex(_ => _ === validateArr[validateArr.length-1]);
+    console.log('first_index',first_index)
+    console.log('last_index',last_index)
+
+    let arr = item.Value.map((item,index) => {
+    if(index < first_index || index > last_index) {
+        return null
+    }else {
+        return item
+    }
+    })
+    // 根据设置的x轴显示隐藏去除值
+    let temArr=[]
+    commodityXData.value.forEach((i,index)=>{
+        if(i.IsHide!==1){
+            temArr.push(arr[index])
+        }
+    })
+
+    return temArr;
+}
+
+
+
+//相关性图表设置
+function initRelevanceChart(data){
+
+    /* 主题样式*/
+    const chartTheme =  data.ChartInfo.ChartThemeStyle ? JSON.parse(data.ChartInfo.ChartThemeStyle) : null;
+
+    // 处理X轴
+    let xAxis={
+        categories: data.ChartInfo.Source===3 ? data.XEdbIdValue : data.DataResp.XDateTimeValue,
+        tickWidth: 1,
+        title: {
+            text:  data.ChartInfo.Source===3 ? `期数(${data.CorrelationChartInfo.LeadUnit})` : null,
+            align: 'high',
+            rotation: 0,
+            x: 0,
+            y:10,
+            offset: 20,
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            },
+        },
+        labels: {
+            style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        tickInterval: 1,
+        offset:0,
+        tickmarkPlacement:'on'
+    }
+
+    // 处理Y轴
+    let yAxis={
+        ...basicYAxis,
+        title: {
+          text: '相关性系数',
+          textCh: '相关性系数',
+          textEn: 'Correlation coefficient',
+          align: 'high',
+          rotation: 0,
+          y: -15,
+          textAlign: 'left',
+          reserveSpace: false,
+          style:{
+            ...chartTheme&&chartTheme.yAxisOptions.style
+          },
+        },
+        labels: {
+          formatter: function (ctx) {
+            let val = ctx.value;
+            return val;
+          },
+          align: 'center',
+          style:{
+            ...chartTheme&&chartTheme.yAxisOptions.style
+          },
+        },
+        opposite: false,
+        tickWidth: 1,
+    }
+
+    //处理series
+    let seriesData=[]
+    data.YDataList.forEach((item,index)=>{
+        // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+        const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
+        let serie_item = {
+          data: item.Value,
+          type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
+          yAxis: 0,
+          name: item.Name||data.ChartInfo.ChartName,
+          nameCh: item.Name||data.ChartInfo.ChartName,
+          nameEn: item.NameEn||data.ChartInfo.ChartName,
+          color: item.Color||'#00f',
+          chartType: 'linear',
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 3,
+          visible:true,
+          marker: {
+            enabled: false
+          }
+        };
+        seriesData.push(serie_item)
+    })
+
+    const { LeadValue,LeadUnit } = data.CorrelationChartInfo;
+    let tooltip = {
+        formatter: function() {
+          let str = `<p>相关性系数:${this.y.toFixed(4)}</p><br><p>领先${ data.ChartInfo.Source===3 ?this.x+'期' : LeadValue+LeadUnit}</p>`
+          return str
+        }
+    }
+    
+
+  return {
+      isRelevanceChart:data.ChartInfo.Source===3,
+      title: {
+          text:''
+      },
+      series: seriesData,
+      yAxis: [yAxis] ,
+      xAxis:xAxis,
+      tooltip
+  }
+}
+
+
+
+/* 统计频率图 */
+function setStatisticFrequency(data) {
+    const { DataList,LeftMaxValue,LeftMinValue,RightMaxValue,RightMinValue } = data.DataResp;
+    const { ChartInfo } = data;
+
+     /* 主题样式*/
+    const chartTheme =  ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+    
+    let xAxis = {
+        ...scatterXAxis,
+        tickWidth: 1,
+        labels: {
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        }
+    }
+
+    //y和系列
+    let yAxis = [],series = [];
+    DataList.forEach((item,index) => {
+    let y_item = {
+        ...basicYAxis,
+        title: {
+            text: item.Unit,
+            align: 'high',
+            rotation: 0,
+            y: -15,
+            reserveSpace: false,
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        labels: {
+            style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        opposite: item.IsAxis===1?false:true,
+        min: index===0? Number(LeftMinValue):Number(RightMinValue),
+        max: index===0? Number(LeftMaxValue):Number(RightMaxValue),
+        tickWidth: 1,
+    }
+    // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+    const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
+    let series_item = {
+        data: item.Value.map(_ =>[_.X,_.Y]),
+        dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
+        type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'spline',
+        yAxis: index,
+        name: item.Name,
+        color: item.Color,
+        lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth)||3,
+        chartType: 'linear',
+        visible: true,
+        zIndex:1
+    }
+
+    series.push(series_item);
+    yAxis.push(y_item)
+    })
+
+    let tooltip = {
+      formatter: function() {
+          let that = this;
+          let xList = DataList[0].Value.map(_ =>_.X);
+          let step = xList[1]-xList[0];
+          let data_interval = `[${Number(that.x).toFixed(2)},${Number(that.x+step).toFixed(2)}]`;
+
+          let str=`<b>${ data_interval }</b>`;
+          that.points.forEach(item => {
+          str += `<br><span style="color:${item.color}">\u25CF</span>${item.series.name}: ${item.y}%<br>`
+          })
+          return str
+      },
+      shared: true
+    }
+
+    return {
+      title: {
+          text:''
+      },
+      tooltip,
+      series,
+      yAxis,
+      xAxis
+    }
+}
+
+
+/* 跨品种分析 */
+const crossVarietyChartData = ref({})
+const initCrossVarietyChartData = (data) => {
+    const {DataResp,ChartInfo} = data;
+    crossVarietyChartData.value = DataResp;
+
+    hasLeftAxis.value=true;
+
+    axisLimitData.leftMin=ChartInfo.LeftMin ? Number(ChartInfo.LeftMin) : Number(DataResp.YMinValue)
+    axisLimitData.leftMax=ChartInfo.LeftMax ? Number(ChartInfo.LeftMax) : Number(DataResp.YMaxValue)
+    axisLimitData.xMin=ChartInfo.XMin ? Number(ChartInfo.XMin) : Number(DataResp.XMinValue)
+    axisLimitData.xMax=ChartInfo.XMax ? Number(ChartInfo.XMax) : Number(DataResp.XMaxValue)
+
+    return setCrossVarietyChart(data)
+}
+const setCrossVarietyChart = (data) => {
+    const { EdbInfoList,ChartInfo } = data;
+    
+    const { leftMin,leftMax,xMin,xMax }  = axisLimitData;
+
+    const { DataList,XName,YName } = crossVarietyChartData.value;
+     /* 主题样式*/
+    const chartTheme =  ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+
+    //y轴
+    let yAxis = {
+        ...basicYAxis,
+        title: {
+            text: YName,
+            align: 'middle',
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        labels: {
+            style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        opposite: false,
+        reversed: false,
+        min: Number(leftMin),
+        max: Number(leftMax),
+        tickWidth: 1,
+    }
+
+    // x轴
+    let xAxis = {
+        ...scatterXAxis,
+        title: {
+            text: XName,
+            align: 'middle',
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        labels: {
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        min: Number(xMin),
+        max: Number(xMax),
+    }
+
+    //数据列
+    let series = [];
+    const tagMap = { //标签对应文字
+        1: '最新',
+        3: 'Fix'
+    }
+    DataList.forEach(item => {
+        //数据列
+        let series_item = {
+            data: [],
+            type: 'scatter',
+            name: item.Name,
+            color: item.Color,
+            lineWidth: 0,
+            chartType: 'linear',
+            zIndex:1,
+            visible: true
+        }
+        item.CoordinatePointData.forEach(_ => {
+            series_item.data.push({
+                x: _.X,
+                y: _.Y,
+                dataLabels: {
+                enabled: _.ShowTips===1,
+                allowOverlap: true,
+                align: 'left',
+                format: tagMap[_.DateType] || `-${_.DaysAgo}D`,
+                }
+            })
+        })
+        series.push(series_item);
+    })
+
+    let tooltip = {
+        formatter: function() {
+
+            let that = this;
+            let str = '';
+
+            let series_obj = DataList.find(_ => _.Name === that.series.name);
+            let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===that.x && _.Y===that.y);
+            
+            let xEdbInfo = EdbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+            let yEdbInfo = EdbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+            str=`<b>${ that.series.name }</b>`;
+            str += `<br><span style="color:${that.color}">\u25CF</span>${xEdbInfo.EdbName}: ${that.x} ${ponit_obj.XDate}<br>`;
+            str += `<span style="color:${that.color}">\u25CF</span>${yEdbInfo.EdbName}: ${that.y} ${ponit_obj.YDate}`;
+
+            return str
+        }
+    }
+
+    return {
+        title: {
+            text:''
+        },
+        series,
+        yAxis: [yAxis],
+        xAxis,
+        tooltip
+    }
+}
+
+
+
+ /* 处理轴的标识线结构 在指定轴位置上拼接标识线 
+    0:右轴 1:左轴 2:右2轴 x轴固定3
+    axisType表示x轴类型 处理时间轴的值 datetime/null 
+*/
+function setAxisPlotLines(axis,axisType) {
+  const { MarkersLines,ChartType } = chartData.value.ChartInfo;
+  const { EdbInfoList } = chartData.value;
+  if(!MarkersLines) return []
+
+  let markerLines = JSON.parse(MarkersLines);
+
+  let arr = markerLines.filter(_ => _.isShow&&_.axis===axis)
+  let plotLines = arr.map(_ => {
+      //是否是x时间轴
+      let isXDateAxis = axis===3&&axisType==='datetime';
+      let markerValue;
+      if(isXDateAxis) {
+          //季节图x轴额外拼个年份
+          let nowYear = ChartType===2 ? new Date(EdbInfoList[0].DataList[1].DataList
+              [0].DataTimestamp).getFullYear() : '';
+          markerValue = ChartType===2 
+              ? new Date(`${nowYear}-${_.value}`).getTime()
+              : new Date(_.value).getTime()
+      }else {
+          markerValue = Number(_.value)
+      }
+
+      return { 
+      value: markerValue,
+      dashStyle: _.dashStyle,
+      width: Number(_.lineWidth),
+      color: _.color,
+      label: {
+          text: _.text||'',
+          verticalAlign: _.textPosition,
+          style: {
+          color: _.textColor,
+          fontSize: _.textFontSize
+          }
+      }
+      }
+  })
+  return plotLines
+}
+
+/* 处理标识区拼接 axisType表示x轴类型处理时间轴的值 datetime/null */
+function setAxisPlotAreas(axis,axisType) {
+  const { MarkersAreas,ChartType } = chartData.value.ChartInfo;
+  const { EdbInfoList } = chartData.value;
+  if(!MarkersAreas) return []
+
+  let markerAreas = JSON.parse(MarkersAreas);
+
+  let arr = markerAreas.filter(_ => _.isShow&&_.axis===axis)
+  let plotBands = arr.map(_ => {
+      //是否是x时间轴
+      let isXDateAxis = axis===3&&axisType==='datetime';
+      let fromMarkerValue,toMarkerValue;
+      if(isXDateAxis) {
+          //季节图x轴额外拼个年份
+          let nowYear = ChartType===2 ? new Date(EdbInfoList[0].DataList[1].DataList
+              [0].DataTimestamp).getFullYear() : '';
+          fromMarkerValue = ChartType===2 
+              ? new Date(`${nowYear}-${_.fromValue}`).getTime()
+              : new Date(_.fromValue).getTime()
+
+          toMarkerValue = ChartType===2 
+              ? new Date(`${nowYear}-${_.toValue}`).getTime()
+              : new Date(_.toValue).getTime()
+      }else {
+          fromMarkerValue = Number(_.fromValue);
+          toMarkerValue = Number(_.toValue);
+      }
+
+      //默认label有些偏移 重新归正下
+      let positionMapValue = {
+          'top': 12,
+          'middle': 0,
+          'bottom': -10
+      }
+
+      return { 
+          from: fromMarkerValue,
+          to: toMarkerValue,
+          color: _.color,
+          label: {
+              text: _.text||'',
+              verticalAlign: _.textPosition,
+              y: positionMapValue[_.textPosition],
+              style: {
+                  color: _.textColor,
+                  fontSize: _.textFontSize
+              }
+          }
+      }
+  })
+
+  return plotBands
+}
+
+
+/* 预测配置 分区 */
+function getPredictParams ({LatestDate,PredictChartColor}) {
+  return {
+    zoneAxis: 'x',
+    zones: [{
+        value: new Date(LatestDate).getTime()+1
+    }, {
+        dashStyle: 'ShortDot',
+        color: PredictChartColor
+    }]
+  }
+}
+
+/* 季节图预测数据 年份=分割点年份做分割 年份>分割点年份全为预测 */
+function getSeasonPredictParams (timestamp){
+  return timestamp
+    ? {
+        zoneAxis: 'x',
+        zones: [{
+            value: new Date(timestamp).getTime()+1
+        }, {
+            dashStyle: 'ShortDot',
+        }]
+        }
+    : {}
+}
+
+// 查询范围为1年内 x轴显示为月/日 否则默认年/月
+function xTimeDiffer(minTime,maxTime,dateType){
+  //年限差
+  let year_differ=moment(maxTime).diff(moment(minTime),'years',true)
+  // console.log('年限差',year_differ)
+  if ([5, 6].includes(dateType) && year_differ <= 1) {
+      return true
+  } else {
+      return false
+  }
+}
+
+/* 拼接数据列动态name */
+function setDyncmicSerieName (item,dynamic_arr) {
+  const { IsAxis,IsOrder,EdbInfoType,LeadValue,LeadUnit }  = item;
+  // IsAxis左轴1 右轴0 2右2轴 
+    //IsOrder正序false 逆序true 
+    //EdbInfoType是否是领先指标
+  const axisLabelMap = {
+      0: '右轴',
+      2: '右2轴'
+  }
+  const orderLabelMap = {
+      1: '逆序'
+  }
+  const edbInfoMap = {
+      0: '领先'
+  }
+
+  let axis_tag = axisLabelMap[IsAxis] || '';
+    //逆序拼接
+  let order_tag = orderLabelMap[Number(IsOrder)] ? `${axis_tag ? ',': ''}${orderLabelMap[Number(IsOrder)]}` : ''
+    //领先拼接
+  let edb_tag = edbInfoMap[EdbInfoType] ? `${(axis_tag||order_tag) ? ',' : '' }${edbInfoMap[EdbInfoType]}${LeadValue}${LeadUnit}` : '';
+
+  let dynamic_tag = (axis_tag || order_tag || edb_tag) ? `(${axis_tag}${order_tag}${edb_tag})` : '';
+
+  let temName = dynamic_arr.length > 1
+              ? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
+              : `${item.EdbName}${dynamic_tag}`
+  if(temName.length>20){
+      let temArr=[]
+      for(let i=0;i<temName.length/20;i++){
+          temArr.push(temName.slice(i*20,i*20+20))
+      }
+      // console.log(temArr);
+      temName=temArr.join('<br>')
+  }
+
+  return temName
+}
+
+/* 指标顺序调整  IsAxis: 0右轴 1左轴 2右2*/
+function changeEdbOrder (data){
+  // 左轴指标
+  let left_edbs = data.filter(_ => _.IsAxis===1);
+  //右轴指标
+  let right_edbs = data.filter(_ => !_.IsAxis);
+  // 右2轴指标
+  let right_two_edbs = data.filter(_ => _.IsAxis === 2);
+  // 按 左 右 右2顺序排列
+  return [left_edbs,right_edbs,right_two_edbs].flat(Infinity);
+}
+
+//获取RGBA的透明度
+function parseRgbaColor(color='rgba(51, 51, 51, 1)'){
+  const arr = color.match(/(\d(\.\d+)?)+/g) || ['','','',1];
+  return parseFloat(arr[3]||1)
+}
+/* ----自定义上下限相关--- */
+/* 计算y轴上下限 */
+function calcYAxislimit(tableData=[],ChartInfo,DataResp={}){
+  //散点图单独处理
+  if(ChartInfo.ChartType===5){
+      if(tableData[1]){
+          axisLimitData.leftMin = tableData[1].MinData
+          axisLimitData.leftMax = tableData[1].MaxData
+      }
+      return 
+  }
+  //分组
+  const leftData = tableData.filter(i => i.IsAxis === 1).map(i => [Number(i.MinData), Number(i.MaxData)])
+  const rightData = tableData.filter(i => !i.IsAxis).map(i => [Number(i.MinData), Number(i.MaxData)])
+  const rightTwoData = tableData.filter(i => i.IsAxis === 2).map(i => [Number(i.MinData), Number(i.MaxData)])
+  //计算最大最小值
+  if (leftData.length) {
+      const {
+          Max,
+          Min
+      } = calcLimit(leftData.flat())
+      axisLimitData.leftMin = Min
+      axisLimitData.leftMax = Max
+  } 
+  if (rightData.length) {
+      const {
+          Max,
+          Min
+      } = calcLimit(rightData.flat())
+      axisLimitData.rightMin = Min
+      axisLimitData.rightMax = Max
+  }
+  if (rightTwoData.length) {
+      const {
+          Max,
+          Min
+      } = calcLimit(rightTwoData.flat())
+      axisLimitData.rightTwoMin = Min
+      axisLimitData.rightTwoMax = Max
+  }
+  //季节性图-右轴单独处理
+  if(ChartInfo.ChartType===2){
+      if(DataResp.RightAxis&&DataResp.RightAxis.IsAdd&&DataResp.RightAxis.IsShow){
+          if(DataResp.RightAxis.IndicatorType===1){
+              axisLimitData.rightMin = DataResp.RightAxis.EdbInfoList[0].MinData||0
+              axisLimitData.rightMax = DataResp.RightAxis.EdbInfoList[0].MaxData||0
+          }else{
+              axisLimitData.rightMin = tableData[1].MinData||0
+              axisLimitData.rightMax = tableData[1].MaxData||0
+          }
+          
+      }
+  }
+}
+function calcLimit(arr) {
+  return {
+      Max: Math.max(...arr),
+      Min: Math.min(...arr)
+  }
+}
+//图表详情-设置图表上下限
+function setLimitData({EdbInfoList,ChartInfo,DataResp}){
+  const {
+      //左右轴极值字段 
+      LeftMin=0,LeftMax=0,
+      RightMin=0,RightMax=0,
+      Right2Min=0,Right2Max=0,
+      MinMaxSave
+  } = ChartInfo
+  if(MinMaxSave){
+      axisLimitData.leftMin = Number(LeftMin)
+      axisLimitData.leftMax = Number(LeftMax)
+      axisLimitData.rightMin = Number(RightMin)
+      axisLimitData.rightMax = Number(RightMax)
+      axisLimitData.rightTwoMin = Number(Right2Min)
+      axisLimitData.rightTwoMax = Number(Right2Max)
+      //若用户修改过,则检测轴的上下限是否为空,若为空,则需要计算对应轴的上下限
+      checkLimit(EdbInfoList,ChartInfo)
+      console.log('check',axisLimitData.leftMin,axisLimitData.leftMax)
+  }else{
+      calcYAxislimit(EdbInfoList,ChartInfo,DataResp?DataResp:{})
+  }
+}
+function checkLimit(tableData=[],ChartInfo){
+  //散点图单独处理
+  if(ChartInfo.ChartType===5){
+      if(tableData[1]){
+          if(Number(axisLimitData.leftMin)===0&&Number(axisLimitData.leftMax)===0){
+              axisLimitData.leftMin = tableData[1].MinData
+              axisLimitData.leftMax = tableData[1].MaxData
+          }
+      }
+      return 
+  }
+  //若轴的上下限均为0,则不管用户有没有修改过,都重新赋值
+  if(Number(axisLimitData.leftMin)===0&&Number(axisLimitData.leftMax)===0){
+      const leftData = tableData.filter(i=>i.IsAxis===1).map(i=>[Number(i.MinData),Number(i.MaxData)])
+      if(leftData.length){
+          const {Max,Min} = calcLimit(leftData.flat())
+          axisLimitData.leftMin = Min
+          axisLimitData.leftMax = Max
+      }
+  }
+  if(Number(axisLimitData.rightMin)===0&&Number(axisLimitData.rightMax)===0){
+      const rightData = tableData.filter(i => !i.IsAxis).map(i=>[Number(i.MinData),Number(i.MaxData)])
+      if(rightData.length){
+          const {Max,Min} = calcLimit(rightData.flat())
+          axisLimitData.rightMin = Min
+          axisLimitData.rightMax = Max
+      }
+  }
+  if(Number(axisLimitData.rightTwoMin)===0&&Number(axisLimitData.rightTwoMax)===0){
+      const rightTwoData = tableData.filter(i=>i.IsAxis===2).map(i=>[Number(i.MinData),Number(i.MaxData)])
+      if(rightTwoData.length){
+          const {Max,Min} = calcLimit(rightTwoData.flat())
+          axisLimitData.rightTwoMin = Min
+          axisLimitData.rightTwoMax = Max
+      }
+  }
+}
+/*-------------------- */

+ 8 - 6
src/views/hzyb/report/ChapterDetail.vue

@@ -44,11 +44,11 @@
               <span style="color: #e3b377; margin-left: 20px" @click="showDisclaimers = true">免责声明</span>
             </div>
           </div>
+          <span 
+            v-if="!info.report_chapter_item.report_video_url&&info.report_chapter_item.video_url&&info.report_chapter_item.video_play_seconds>0" 
+            style="float:right;background:#E3B377;color:#fff;border-radius:30px;padding:0 10px;font-size:0.9em" @click="handlePlayAudioBG"
+          >背景播放</span>
         </div>
-        <span 
-          v-if="!info.report_chapter_item.report_video_url&&info.report_chapter_item.video_url&&info.report_chapter_item.video_play_seconds>0" 
-          style="float:right;background:#E3B377;color:#fff;border-radius:30px;padding:0 10px;font-size:0.9em" @click="handlePlayAudioBG"
-        >背景播放</span>
         <div id="report-rich-content" class="rich-content" ref="richConBox">
           <div v-if="info.auth_ok">
             <ul>
@@ -450,8 +450,10 @@ export default {
             pars:JSON.stringify({
                 title:imgText,
                 time_format:moment(res.data.report_chapter_item.publish_time).format('YYYY/MM/DD'),
-                background_img:res.data.report_chapter_item.share_bg_img
-            })
+                background_img:res.data.report_chapter_item.share_bg_img,
+            }),
+            report_id:Number(res.data.report_chapter_item.report_id),
+            report_chapter_id:Number(this.chapterId)
         })
         if(rddpImgRes.code===200){
             shareImg=rddpImgRes.data

+ 3 - 2
src/views/hzyb/report/Detail.vue

@@ -561,8 +561,9 @@ export default {
                     pars:JSON.stringify({
                         title:imgText,
                         time_format:moment(res.data.report_info.publish_time).format('YYYY/MM/DD'),
-                        background_img:res.data.report_info.share_bg_img
-                    })
+                        background_img:res.data.report_info.share_bg_img,
+                    }),
+                    report_id:Number(this.reportId),
                 })
                 if(rddpImgRes.code===200){
                     shareImg=rddpImgRes.data

Деякі файли не було показано, через те що забагато файлів було змінено