Explorar el Código

Merge branch 'master' into custom

Karsa hace 6 meses
padre
commit
850bf96e0b
Se han modificado 2 ficheros con 245 adiciones y 45 borrados
  1. 203 41
      src/hooks/chart/useChartRender.ts
  2. 42 4
      src/views/sheetShow/index.vue

+ 203 - 41
src/hooks/chart/useChartRender.ts

@@ -11,6 +11,11 @@ import { defaultOpts, seasonOptions } from "@/utils/chartOptions";
 import moment from "moment";
 import router from '@/router'
 
+//获取RGBA的透明度
+const parseRgbaColor = (color='rgba(51, 51, 51, 1)') => {
+    const arr = color.match(/(\d(\.\d+)?)+/g) || ['','','',1];
+    return parseFloat((arr[3]||1)+'')
+}
 // 散点x
 const scatterXAxis = {
   tickPosition: "inside",
@@ -97,7 +102,7 @@ export const useChartRender = (Data,lang='zh',) => {
 
   //eta图
   if ([1,11].includes(Data.ChartInfo.Source)) {
-    setLimitData(state.dataList)
+    setLimitData(state.dataList,Data)
     const typeMap = {
       1: setDefaultLineOptions,
       2: setSeasonOptions,
@@ -232,15 +237,22 @@ const setDefaultLineOptions = () => {
 
     //预测指标配置
     let predict_params = item.EdbInfoCategoryType === 1 ? getPredictParams(item) : {};
-
+    //图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+    const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
     let obj = {
       data: [] as any[],
-      type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
-      dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+      type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'spline',
+      dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
       yAxis: sameSideIndex,
       name,
       color: item.ChartColor,
-      lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptions.lineWidth)||1,
+      lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth)||1,
+      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 || []
@@ -320,8 +332,8 @@ const setDefaultLineOptions = () => {
 
 /* 季节图 */
 const screen = ref(document.body.clientWidth < 1200 ? 'phone' : 'pc');
-const setSeasonOptions = () => {
-  
+const setSeasonOptions = (data:any) => {
+  const {RightAxis:SeasonRightConfig={}} = data.DataResp||{}
   const chartData = state.dataList[0];
   // 农历数据需要去除第一项 在ETA1.0.5之后,除了这里 农历和公历处理逻辑一样
   if(!chartData.DataList){
@@ -335,25 +347,41 @@ const setSeasonOptions = () => {
     seasonData:any[] = [];
 
     //获取对应轴的上下限
-    let minLimit = 0,maxLimit = 0
+    let minLimit = 0,maxLimit = 0,rightMin = 0,rightMax = 0
     minLimit = state.chartLimit.min||0
     maxLimit = state.chartLimit.max||0
+    if(SeasonRightConfig.IsShow){
+        rightMin = state.chartLimit.rightMin||0
+        rightMax = state.chartLimit.rightMax||0
+    }
 
     /* 主题样式*/
   const chartTheme =  state.chartInfo.ChartThemeStyle ? JSON.parse(state.chartInfo.ChartThemeStyle) : null;
+  // 跟颜色对应
+  chartTheme && (chartTheme.lineOptionList=chartTheme.lineOptionList.reverse().slice(-chartDataHandle.length))
 
-  /*处理数据列*/
-  for (let j of chartDataHandle) {
+  /*处理数据列 常规左轴*/
+  for (let index in chartDataHandle) {
+    console.log(index,'index');
+    
+    let j = chartDataHandle[index]
     //预测指标配置
     let predict_params =  chartData.EdbInfoCategoryType === 1 ? getSeasonPredictParams(j.CuttingDataTimestamp) : {};
-
+    // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+    const lineIndex = chartTheme ? Number(index)%chartTheme.lineOptionList.length : index
     let serie_item = {
       data: [] as any[],
-      type: (chartTheme&&chartTheme.lineOptions.lineType) || chartData.ChartStyle,
-      dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+      type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || chartData.ChartStyle,
+      dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
       yAxis: 0,
       name: j.ChartLegend,
-      lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 1,
+      lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 1,
+      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
     };
     const data_array = _.cloneDeep(j.DataList);
@@ -363,7 +391,81 @@ const setSeasonOptions = () => {
       });
     seasonData.push(serie_item);
   }
-
+  //同期上下限/均线/标准差
+  const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = data.DataResp||{}
+  if(MaxMinLimits.IsShow&&MaxMinLimits.List&&MaxMinLimits.List.length){
+    let serieItem = {
+        type:'arearange',//上下限是一个范围
+        data:[] as any[],
+        name:MaxMinLimits.Legend||'同期上下限',
+        color:MaxMinLimits.Color||'#075EEE',
+        fillOpacity:parseRgbaColor(MaxMinLimits.Color||'')>0.75?0.75:parseRgbaColor(MaxMinLimits.Color||'') //透明度最高0.75 
+    }
+    console.log('serieItem?',serieItem.fillOpacity)
+    MaxMinLimits.List.forEach((item:any)=>{
+        serieItem.data.push([item.DataTimestamp,item.MinValue,item.MaxValue])
+    })
+    seasonData.push(serieItem)
+  }
+  if(SamePeriodAverage.IsShow&&SamePeriodAverage.List){
+    let serieItem = {
+        type:'line',
+        data:[] as any [],
+        lineWidth:SamePeriodAverage.LineWidth,
+        dashStyle:SamePeriodAverage.LineType,
+        name:SamePeriodAverage.Legend||'同期均值',
+        color:SamePeriodAverage.Color||'#075EEE'
+    }
+    SamePeriodAverage.List.forEach((item:any)=>{
+        serieItem.data.push([item.DataTimestamp,item.Value])
+    })
+    seasonData.push(serieItem)
+  }
+  if(SamePeriodStandardDeviation.IsShow&&SamePeriodStandardDeviation.List){
+    let serieItem = {
+        type:'arearange',//标准差也是一个范围
+        data:[] as any [],
+        name:SamePeriodStandardDeviation.Legend||'同期标准差',
+        color:SamePeriodStandardDeviation.Color||'#075EEE',
+        fillOpacity:parseRgbaColor(SamePeriodStandardDeviation.Color||'')>0.75?0.75:parseRgbaColor(SamePeriodStandardDeviation.Color||'')
+    }
+    SamePeriodStandardDeviation.List.forEach((item:any)=>{
+        serieItem.data.push([item.DataTimestamp,item.MinValue,item.MaxValue])
+    })
+    seasonData.push(serieItem)
+  }
+  //右轴
+  if(SeasonRightConfig.IsShow){
+    //右轴的设置
+    let serieConfig = SeasonRightConfig.Style==='column'?{
+        //柱形
+        type:'column',
+        color:SeasonRightConfig.ChartColor
+    }:{
+        //标记点
+        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
+        },
+    }
+    let serieItem = {
+        ...serieConfig,
+        name:SeasonRightConfig.Legend||'右轴',
+        data:[] as any[],
+        yAxis:1,
+    }
+    const DataList = (SeasonRightConfig.IndicatorType===1?SeasonRightConfig.EdbInfoList[0].DataList:state.dataList[1].DataList)||[]
+    DataList.forEach((item:any)=>{
+        serieItem.data.push([item.DataTimestamp,item.Value])
+    })
+    seasonData.push(serieItem)
+  }
   //y轴
   const textZh = chartData.ConvertUnit||chartData.Unit
   const textEn = textZh?chartData.ConvertEnUnit||chartData.UnitEn||chartData.ConvertUnit||chartData.Unit:''
@@ -396,6 +498,44 @@ const setSeasonOptions = () => {
     plotBands: setAxisPlotAreas(1),
     plotLines: setAxisPlotLines(1)
   }];
+  //如果有右轴,seasonYdata加上右轴
+  if(SeasonRightConfig.IsShow){
+    const rightEdb = (SeasonRightConfig.IndicatorType===1?SeasonRightConfig.EdbInfoList[0]:state.dataList[1])||{unit:''}
+    //左轴同比:text为空或% 右轴指标:取指标单位
+    if(SeasonRightConfig.IndicatorType===1){
+        rightEdb.Unit = SeasonRightConfig.NumFormat===1?'%':''
+    }else{
+        rightEdb.Unit = state.dataList[1]&&(state.dataList[1].ConvertUnit||state.dataList[1].Unit)||''
+    }
+    seasonYdata.push({
+        ...defaultOpts.yAxis,
+        opposite: true,//右轴
+        labels: {
+            formatter: function (ctx: any) {
+                let val = ctx.value;
+                return val;
+            },
+            align: 'center',
+            style: {
+              ...chartTheme&&chartTheme.yAxisOptions.style
+            }
+          },
+          title: {
+            text: rightEdb.Unit||'',
+            style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+            align: 'high',
+            rotation: 0,
+            y: -12,
+            x: 0 ,
+            textAlign: 'right',
+            reserveSpace: false,
+          },
+          max: Number(rightMax),
+          min: Number(rightMin),
+    })
+  }
 
   // 季节图x轴显示月/日
   const xAxis = {
@@ -553,14 +693,15 @@ const setStackOrCombinChart = () => {
 
     //预测指标配置
     let predict_params = item.EdbInfoCategoryType === 1 ? getPredictParams(item,chartStyle) : {};
-
+    //图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+    const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
     let obj = {
       data: [] as any[],
       type: chartStyle || item.ChartStyle,
       yAxis: serie_yIndex,
       name,
       color: item.ChartColor,
-      lineWidth:  Number(item.ChartWidth),
+      lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 1,
       fillColor: (chartInfo.ChartType === 3 || (chartInfo.ChartType === 6 && item.ChartStyle === 'areaspline')) ? item.ChartColor : undefined,
       zIndex: (chartInfo.ChartType === 6 && ['line','spline'].includes(item.ChartStyle)) ? 1 : 0, //防止组合图曲线被遮住
       borderWidth: 1,
@@ -727,7 +868,7 @@ const setScatterChartOptions = () => {
     color: ChartColor,
     chartType: 'linear',
     marker: {
-      radius: (chartTheme&&chartTheme.lineOptions.radius)||5,
+      radius: (chartTheme&&chartTheme.lineOptionList[0].radius)||5,
     },
   }
   real_data.forEach(_ => {
@@ -957,7 +1098,9 @@ const setSectionScatterChart = () => {
 
     //数据列
     let series: any[] = [];
-    DataList.forEach(item => {
+    DataList.forEach((item:any,index:number) => {
+        // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+        const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
         //数据列
         let series_item = {
             data: [] as any[],
@@ -968,7 +1111,7 @@ const setSectionScatterChart = () => {
             chartType: 'linear',
             zIndex:1,
             marker: {
-              radius: (chartTheme&&chartTheme.lineOptions.radius)||5,
+              radius: (chartTheme&&chartTheme.lineOptionList[lineIndex].radius)||5,
             },
             visible: true
         }
@@ -1155,19 +1298,20 @@ const setCommodityChart = () => {
   }
 
   //数据列
-  data.forEach((item: { Value: number[]; Name: string; Date: string; Color: string;NameEn: string,XEdbInfoIdList: number[],NoDataEdbList: number[] }) => {
+  data.forEach((item: { Value: number[]; Name: string; Date: string; Color: string;NameEn: string,XEdbInfoIdList: number[],NoDataEdbList: number[] },index:number) => {
     //处理首或/尾全是无效数据的以null填充
     let filterData = filterInvalidData(item)
-
+    // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+    const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
     let serie_item = {
       data: filterData,
-      type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
-      dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+      type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'spline',
+      dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
       yAxis: 0,
       name: language.value === 'zh' ? item.Name : item.NameEn,
       color: item.Color,
       chartType: 'linear',
-      lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 3,
+      lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 3,
       marker: {
         enabled: false
       }
@@ -1328,16 +1472,18 @@ const initRelevanceChartData=(data)=>{
 
   //处理series
   let seriesData:any[]=[]
-  data.YDataList.forEach(item=>{
+  data.YDataList.forEach((item:any,index:number)=>{
+    // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
+    const lineIndex = chartTheme ? index%chartTheme.lineOptionList.length : index
     let serie_item = {
       data: item.Value,
-      type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
-      dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+      type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'spline',
+      dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
       yAxis: 0,
-      name: language.value=='zh'?data.ChartInfo.ChartName:data.ChartInfo.ChartNameEn,
+      name: language.value=='zh'?item.Name:item.NameEn||item.Name,
       color: item.Color,
       chartType: 'linear',
-      lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 3,
+      lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 3,
       marker: {
         enabled: false
       }
@@ -1436,15 +1582,16 @@ const setStatisticFrequency = () => {
       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.lineOptions.dashStyle)||'Solid',
-      type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
+      dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
+      type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'spline',
       yAxis: index,
       name: language.value === 'zh' ? item.Name : item.NameEn,
       color: item.Color,
-      lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth)||3,
+      lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth)||3,
       chartType: 'linear',
       zIndex:1
     }
@@ -1715,16 +1862,18 @@ const setRadarChart = () => {
 
     //系列
     let series:any[] = [];
-    YDataList.forEach(item => {
+    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.lineOptions.lineType) || 'line',
-        dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+        type: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineType) || 'line',
+        dashStyle: (chartTheme&&chartTheme.lineOptionList[lineIndex].dashStyle)||'Solid',
         yAxis: 0,
         name: language.value==='zh' ? (item.Name || item.Date) : item.Date,
         color: item.Color,
-        lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 1,
+        lineWidth: (chartTheme&&chartTheme.lineOptionList[lineIndex].lineWidth) || 1,
         chartType: 'linear'
       };
       series.push(serie_item)
@@ -1992,7 +2141,7 @@ const setAxisPlotAreas = (axis: number, axisType: any = null) => {
 };
 
 /* ----自定义上下限相关--- */
-const setLimitData = (tableData:any=[])=>{
+const setLimitData = (tableData:any=[],data:{DataResp:any})=>{
     const {
         //左右轴极值字段 
         LeftMin=0,LeftMax=0,
@@ -2010,7 +2159,7 @@ const setLimitData = (tableData:any=[])=>{
         //若用户修改过,则检测轴的上下限是否为空,若为空,则需要计算对应轴的上下限
         checkLimit(tableData)
     }else{
-        calcYAxislimit(tableData)
+        calcYAxislimit(tableData,data.DataResp?data.DataResp:{})
     }
 }
 const checkLimit = (tableData:any=[])=>{
@@ -2060,7 +2209,7 @@ const checkLimit = (tableData:any=[])=>{
     }
 }
 /* 计算y轴上下限 */
-const calcYAxislimit = (tableData:any=[])=>{
+const calcYAxislimit = (tableData:any=[],DataResp:any={})=>{
     //散点图单独处理
     if(state.chartInfo.ChartType===5){
         if(tableData[1]){
@@ -2107,6 +2256,19 @@ const calcYAxislimit = (tableData:any=[])=>{
         state.chartLimit.rightTwoMin = 0
         state.chartLimit.rightTwoMax = 0
     }
+    //季节性图-右轴单独处理
+    if(state.chartInfo.ChartType===2){
+        if(DataResp.RightAxis&&DataResp.RightAxis.IsAdd&&DataResp.RightAxis.IsShow){
+            if(DataResp.RightAxis.IndicatorType===1){
+                state.chartLimit.rightMin = DataResp.RightAxis.EdbInfoList[0].MinData||0
+                state.chartLimit.rightMax = DataResp.RightAxis.EdbInfoList[0].MaxData||0
+            }else{
+                state.chartLimit.rightMin = tableData[1].MinData||0
+                state.chartLimit.rightMax = tableData[1].MaxData||0
+            }
+            
+        }
+    }
 }
 const calcLimit = (arr:any)=>{
     return {

+ 42 - 4
src/views/sheetShow/index.vue

@@ -20,6 +20,17 @@ interface InfoType extends IUnknowObject {
 const showData = ref(false);
 const info = ref<InfoType|any>({});
 const loading = ref(false);
+
+
+const setDefaultSource=(sourceText:string)=>{
+  return JSON.stringify({
+    isShow: true,
+    text: sourceText,
+    color: "#606266",
+    fontSize: 9
+  })
+}
+
 const getInfo = async(type='') => {
   loading.value = true;
   const { Data,Ret } = await SheetApi.getInfo({  UniqueCode: code.value, FromScene: Number(route.query.fromScene||'') });
@@ -28,6 +39,9 @@ const getInfo = async(type='') => {
   if(Ret !== 200) return
 
   info.value = Data;
+  if(!info.value.SourcesFrom){
+    info.value.SourcesFrom = Data.ExcelSource?setDefaultSource(Data.ExcelSource):''
+  }
   showData.value = true; 
   type==='refresh'&&ElMessage.success('刷新成功')
   nextTick(() => {
@@ -64,11 +78,22 @@ const refreshSheet = async()=>{
     element-loading-spinner="el-icon-loading"
     element-loading-text="加载中..."
   >
-    <h3 class="title">{{info.ExcelName}}</h3>
+    <!-- <h3 class="title">{{info.ExcelName}}</h3> -->
     
     <sheet :data="info.TableInfo.TableDataList" :config="info.Config"/>
-    <div class="tool">
-        <span @click="refreshSheet">刷新</span>
+    <div class="tool sheet-bottom">
+      <div class="sheet-source" 
+        v-if="info.SourcesFrom&&JSON.parse(info.SourcesFrom).isShow"
+        :style="`
+            color: ${ JSON.parse(info.SourcesFrom).color };
+            font-size: ${ JSON.parse(info.SourcesFrom).fontSize }px;
+        `"
+      >
+          source:<em>{{ JSON.parse(info.SourcesFrom).text}}</em>
+      </div>
+      <!-- 占位 -->
+      <div v-else></div>
+      <span @click="refreshSheet" style="color: #666;">刷新</span>
     </div>
   </div>
 </template>
@@ -88,11 +113,24 @@ const refreshSheet = async()=>{
     margin-bottom: 8px;
   }
   .tool{
-    text-align: right;
+    // text-align: right;
     margin-top: 5px;
     span{
         cursor: pointer;
     }
   }
+  .sheet-bottom{
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    white-space: nowrap;
+    padding: 0 10px;
+    .sheet-source{
+      width: 30%;
+      min-width: 150px;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+  }
 }
 </style>