eCharts双坐标轴,实现刻度一致

遇到的问题:eCharts使用双y轴时,经常出现双线的情况

 需要实现单线

实现方法:添加yAxis刻度的最小值和最大值及间隔即可

yAxis: [
          {
            type: 'value',
            // 左侧的第一个y轴同步数据分割的
            min: 0,
            max: intervalNum1Y * 5,
            interval: intervalNum1Y,
          },
          {
            type: 'value',
            // 第二个y轴同步数据分割的
            min: intervalNum1Min,
            max: intervalNum1Min + intervalNum1 * 5,
            interval: intervalNum1,
          },
],

min和max的值需要提前从数据源里面计算出,实际操作时取刻度的取整方法如下:

// 双坐标。 向上取整十,整百,整千,整万
    ceilNumber(number) {
      let bite = 0
      if (number < 10) {
        return 10
      }
      while (number >= 10) {
        number /= 10
        bite += 1
      }
      return Math.ceil(number) * Math.pow(10, bite)
    },

附: 项目中的实际页面,无参考价值,个人存档

<template>
  <a-card :bordered="false">
    <div class="top-title">Chart-Revenue</div>
    <a-divider />
    <div class="total-wrap">
      <!-- chartRevenue 当月 CSC 各客户实际收入 -->

      
      <div class="chart-line total-ob">
        <div class="left-table" style="margin-top:-15px;">
          <div class="m-b5-5">
            <span> {{ $t('proCost.commonMoneyUnitK') }} </span>
          </div>
          <a-table
            rowKey="item"
            :columns="columnsCSC"
            :dataSource="dataSourceCSC"
            :pagination="false"  :loading="loading"
            bordered
            size="small"
            :scroll="{ x: true }"
          />
        </div>
        <!-- 第一个柱状图的数据, 堆叠图1 -->
        <div class="chart1 chart-outer">
          <div id="RevenueChart" style="height: 500px; width: 600px; margin-left: 50px"></div>
        </div>
      </div>

      <div class="chart-line month-csc">
        <!-- 第二个柱状图的数据,长的柱状图 -->
        <div class="chart2 chart-outer2">
          <div id="RevenueChart2" style="height: 500px; width: 900px"></div>
        </div>
        <div v-show="customerNum > 6" class="chart2 chart-outer2">
          <div id="RevenueChart22" style="height: 500px; width: 1000px"></div>
        </div>
      </div>

      <!-- chartRevenue 当月 SDD 客户实际收入 -->

      <div class="chart-line month-sdd">
        <div class="left-table">
          
          <div class="m-b5-5">
            <span> {{ $t('proCost.commonMoneyUnitK') }} </span>
          </div>
          <a-table
            rowKey="item"
            :columns="columnsCSC1"
            :dataSource="dataSourceCSC1"
            :pagination="false"  :loading="loading"
            bordered
            size="small"
            :scroll="{ x: true }"
          />
        </div>
        <!-- 第三个柱状图的数据, 堆叠图2 -->
        <div class="chart3 chart-outer">
          <div id="RevenueChart3" style="height: 500px; width: 600px; margin-left: 50px"></div>
        </div>
      </div>

      <!-- chartRevenue 当月 SET 客户实际收入 -->

      <div class="m-b5-5">
        <span> {{ $t('proCost.commonMoneyUnitK') }} </span>
      </div>
      <div class="chart-line month-set">
        <div class="left-table">
          <a-table
            rowKey="item"
            :columns="columnsCSC2"
            :dataSource="dataSourceCSC2"
            :pagination="false"  :loading="loading"
            bordered
            size="small"
            :scroll="{ x: true }"
          />
        </div>
        <!-- 第四个柱状图的数据,堆叠图3 -->
        <div class="chart4 chart-outer">
          <div id="RevenueChart4" style="height: 500px; width: 600px; margin-left: 50px"></div>
        </div>
      </div>

      <!-- chartRevenue 全年客户实际收入 -->
      <!-- <div class="m-b5-5">
            <span> {{ $t('proCost.commonMoneyUnitK') }} </span>
          </div> -->
      <div class="chart-line total-csc">
        <div class="left-table">
          <a-table
            rowKey="item"
            :columns="columnsCSC3"
            :dataSource="dataSourceCSC3"
            :pagination="false"  :loading="loading"
            bordered
            size="small"
            :scroll="{ x: true }"
          />
        </div>
      </div>
      <div class="chart-line total-csc">
        <!-- 第五个柱状图的数据,长的柱状图 -->
        <div class="chart5 chart-outer2">
          <div id="RevenueChart5" style="height: 500px; width: 900px; margin-left: 50px"></div>
        </div>
        <div v-show="customerNumYear > 6" class="chart5 chart-outer2">
          <div id="RevenueChart55" style="height: 500px; width: 1000px; margin-left: 50px"></div>
        </div>
      </div>
      <!-- chartRevenue 全年客户实际收入-瀑布图 -->
      <div class="chart-line total-waterfall chart-outer">
        <div id="RevenueWaterFall" style="height: 500px; width: 1200px"></div>
      </div>
    </div>
  </a-card>
</template>

<script>
import { ActChartRevneue } from '@/api/api'
export default {
  components: {},
  name: 'ChartRenvenue',
  data() {
    return {
      loading:false,
      // 表格类数据
      dataSourceCSC: [], //第一个表格数据
      dataSourceCSC1: [], //第二个表格数据
      dataSourceCSC2: [], //第三个表格数据
      dataSourceCSC3: [], //第四个表格数据
      // echarts类数据
      // 表头的动态月份
      monthName: '',
      customerNum: '',
      customerNumYear: '',

      // 双坐标轴的参数
      MinMonth: '', //双坐标,右侧的y轴最小值
      StepMonth: '', //双坐标,右侧的y轴分隔长度
      StepMonthY: '', //双坐标,左侧y轴的最大值
      MinYear: '', //双坐标,全年右侧的y轴最小值
      StepYear: '', //双坐标,全年右侧的y轴最小值
      StepYearY: '', //双坐标,全年右侧的y轴最小值
    }
  },

  watch: {
    // 监听store财年的改变,实时加载数据
    '$store.state.fiscalYear'() {
      this.getData()
    },
  },

  mounted() {
    this.getData()
  },

  methods: {
    // 初始化,接口数据赋值
    getData() {
      this.loading =true
      ActChartRevneue({
        fy: this.$store.getters.fiscalYear,
      }).then((res) => {
        if (res.code == 200 && res.result) {
          // console.log('大接口:' + res.result.month)
          this.monthName = res.result.month
          // 当月的三个表格数据
          this.dataSourceCSC = res.result.revenueMonth.CSC
          this.dataSourceCSC1 = res.result.revenueMonth.SDD
          this.dataSourceCSC2 = res.result.revenueMonth.SET
          // 全年的表格数据
          this.dataSourceCSC3 = res.result.revenueYear.CSC
          // 以上页面表格数据结束,以下页面图表数据开始
          // 瀑布图的数据
          this.RevenueCharts6(res.result.waterfall)
          // 第一,三,四个 echarts 堆叠图 res.result.stackedMonth.CSC
          this.chartsStack(res.result.stackedMonth.CSC, 'RevenueChart')
          this.chartsStack(res.result.stackedMonth.SDD, 'RevenueChart3')
          this.chartsStack(res.result.stackedMonth.SET, 'RevenueChart4')
          // 第二,五个柱形图数据渲染。先分割数组再渲染

          // 先计算双坐标的数值
          this.calculateMonthMinMax(res.result)
          this.calculateYearMinMax(res.result)

          // this.transDataList(res.result.stackedMonth.CSC,'month')
          // this.transDataList(res.result.stackedYear.CSC,'year')
        } else {
          this.monthName = ''
          // 当月的三个表格数据
          this.dataSourceCSC = []
          this.dataSourceCSC1 = []
          this.dataSourceCSC2 = []
          // 全年的表格数据
          this.dataSourceCSC3 = []
          // 瀑布图的数据
          this.RevenueCharts6(null)
          // 第一,三,四个 echarts 堆叠图 res.result.stackedMonth.CSC
          this.chartsStack(null, 'RevenueChart')
          this.chartsStack(null, 'RevenueChart3')
          this.chartsStack(null, 'RevenueChart4')
          // 第二,五个柱形图数据渲染
          this.chartsBar(null, 'RevenueChart2')
          this.chartsBar(null, 'RevenueChart5')
          this.chartsBar(null, 'RevenueChart22')
          this.chartsBar(null, 'RevenueChart55')
        }
      })
      this.loading = false
    },

    calculateMonthMinMax(res) {
      let a1 = res.stackedMonth.CSC[0].obDiff
      let a2 = res.stackedMonth.CSC[0].fctDiff
      let aa = a1.concat(a2)
      let MinMonth = Math.min.apply(null, aa)
      let MaxMonth = Math.max.apply(null, aa)
      var distance = this.ceilNumber(Number(MaxMonth) - Number(MinMonth))
      var step = this.ceilNumber((Number(distance) / 5) * 5)
      this.MinMonth = this.ceilNumber(MinMonth) - distance
      this.StepMonth = step

      let y1 = res.stackedMonth.CSC[0].ob
      let y2 = res.stackedMonth.CSC[0].fct
      let y3 = res.stackedMonth.CSC[0].act
      let yy = y1.concat(y2, y3)
      let MaxMonthY = Math.max.apply(null, yy)
      var distanceY = MaxMonthY
      var stepY = this.ceilNumber(Number(distanceY) / 5)
      this.StepMonthY = stepY

      this.transDataList(res.stackedMonth.CSC, 'month')
    },
    calculateYearMinMax(res) {
      // 右侧的y轴的计算
      let a1 = res.stackedYear.CSC[0].obDiff
      let a2 = res.stackedYear.CSC[0].fctDiff
      let aa = a1.concat(a2)
      let MinYear = Math.min.apply(null, aa)
      let MaxYear = Math.max.apply(null, aa)
      var distance = this.ceilNumber(Number(MaxYear) - Number(MinYear))
      var step = this.ceilNumber((Number(distance) / 5) * 5)
      this.MinYear = this.ceilNumber(MinYear) - distance
      this.StepYear = step

      // 左侧都是从0 开始的最小值默认是0
      let y1 = res.stackedYear.CSC[0].ob
      let y2 = res.stackedYear.CSC[0].fct
      let y3 = res.stackedYear.CSC[0].act
      let yy = y1.concat(y2, y3)
      let MaxYearY = Math.max.apply(null, yy)
      var distanceY = MaxYearY
      var stepY = this.ceilNumber(Number(distanceY) / 5)
      this.StepYearY = stepY

      this.transDataList(res.stackedYear.CSC, 'year')
    },

    // 分割数组的前6位一组,剩余第二组
    transDataList(res, contain) {
      if (res[0].type.length > 6) {
        // 超过6个数组,分割成两个柱状图
        let res1 = []
        let objOneFirst = {}
        let objOneSecond = {}
        objOneFirst['title'] = res[0].title
        let arrTypeOne = []
        let arrActOne = []
        let arrFctOne = []
        let arrFctDiffOne = []
        let arrObOne = []
        let arrObDiffOne = []
        for (let i = 0; i < 6; i++) {
          let key = res[0].type[i]
          arrTypeOne.push(key)
          arrActOne.push(res[0].act[i])
          arrFctOne.push(res[0].fct[i])
          arrFctDiffOne.push(res[0].fctDiff[i])
          arrObOne.push(res[0].ob[i])
          arrObDiffOne.push(res[0].obDiff[i])
          objOneSecond[key] = res[1][key]
        }
        objOneFirst['type'] = arrTypeOne
        objOneFirst['act'] = arrActOne
        objOneFirst['fct'] = arrFctOne
        objOneFirst['fctDiff'] = arrFctDiffOne
        objOneFirst['ob'] = arrObOne
        objOneFirst['obDiff'] = arrObDiffOne
        res1.push(objOneFirst)
        res1.push(objOneSecond)
        // console.log(res1)

        // 第二个数组
        let res2 = []
        let objTwoFirst = {}
        let objTwoSecond = {}
        objTwoFirst['title'] = res[0].title
        let arrTypeTwo = []
        let arrActTwo = []
        let arrFctTwo = []
        let arrFctDiffTwo = []
        let arrObTwo = []
        let arrObDiffTwo = []
        for (let j = 6; j < res[0].type.length; j++) {
          let key = res[0].type[j]
          arrTypeTwo.push(key)
          arrActTwo.push(res[0].act[j])
          arrFctTwo.push(res[0].fct[j])
          arrFctDiffTwo.push(res[0].fctDiff[j])
          arrObTwo.push(res[0].ob[j])
          arrObDiffTwo.push(res[0].obDiff[j])
          objTwoSecond[key] = res[1][key]
        }
        objTwoFirst['type'] = arrTypeTwo
        objTwoFirst['act'] = arrActTwo
        objTwoFirst['fct'] = arrFctTwo
        objTwoFirst['fctDiff'] = arrFctDiffTwo
        objTwoFirst['ob'] = arrObTwo
        objTwoFirst['obDiff'] = arrObDiffTwo
        res2.push(objTwoFirst)
        res2.push(objTwoSecond)
        // console.log(res2)
        if (contain == 'month') {
          this.customerNum = res[0].type.length //客户数量的参数,第二张chart的id确定是否显示
          this.chartsBar(res1, 'RevenueChart2')
          // 动态设置第二个柱形图的宽度
          document.getElementById('RevenueChart22').style.width = 60 + 140 * (this.customerNum - 6) + 'px'
          this.chartsBar(res2, 'RevenueChart22')
        } else {
          this.customerNumYear = res[0].type.length //客户数量的参数,第二张chart的id确定是否显示
          this.chartsBar(res1, 'RevenueChart5')
          // 动态设置第二个柱形图的宽度
          document.getElementById('RevenueChart55').style.width = 60 + 140 * (this.customerNumYear - 6) + 'px'
          this.chartsBar(res2, 'RevenueChart55')
        }
      } else {
        // 不超过6个数组,原样显示
        if (contain == 'month') {
          this.customerNum = ''
          this.chartsBar(res, 'RevenueChart2')
        } else {
          this.customerNumYear = ''
          this.chartsBar(res, 'RevenueChart5')
        }
      }
    },

    //获取通用类 堆叠图渲染数据,res 结构一致。 chart1,3,4
    chartsStack(res, idName) {
      let option = {
        //设置公共option参数
        title: {
          text: '', //图表标题
        },
        color: [
          '#4bacc6',
          '#ffff00',
          '#00b050',
          '#b3a2c7',
          '#ff33cc',
          '#92d050',
          '#d99694',
          '#ff99ff',
          '#f5bc8d',
          '#c4bd97',
          '#93cddd',
          '#ff7a00',
          '#FAC090',
          '#B3A2C7',
          '#C3D69B',
        ], // 色块颜色值
        tooltip: {
          // show: true,
          trigger: 'axis',
          axisPointer: {
            // 坐标轴指示器,坐标轴触发有效
            type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'
          },
          textStyle: {
            align: 'left',
          },
          formatter: (param, ticket, callback) => {
            var str = ''
            for (const item of param) {
              item.seriesName && (str += item.marker + ' ' + item.seriesName + ':' + item.value + '<br>')
            }
            return str
          },
        },
        legend: {
          data: [], //数据标题
          left: '82%',
          top: '10%',
        },
        // 此处的grid是左侧柱状图线条部分
        grid: {
          left: '1%',
          right: '8%',
          top: '9%',
          bottom: '1%',
          width: '80%',
          containLabel: true,
        },
        xAxis: {
          data: [],
        },
        yAxis: {
          type: 'value',
        },
        series: [], // 此处series数据循环
      }
      // 有数据时才执行
      if (res == '' || res == null) {
        // 无数据时就置空图形
        option.legend.data = [] // 这个是色块的参数
        option.xAxis.data = [] // 这个是堆叠总数的参数
        option.series = []
      } else {
        // res 动态的后台数据。 idName charts渲染时的id
        option.legend.data = res[0].type ? res[0].type : '' // 这个是色块的参数
        option.xAxis.data = res[0].title ? res[0].title : '' // 这个是堆叠总数的参数
        for (let i = res[0].type.length - 1; i > -1; i--) {
          // 根据legend中色块的顺序,逐个获取数据中的此key的
          let key = res[0].type[i] //第i个legend对应的客户名
          let objSeries = {
            name: key,
            type: 'bar',
            stack: '总量',
            barWidth: 50,
            label: {
              // show: true,
              color: 'black',
              formatter: function (params) {
                if (params.value == '0' || params.value == null) {
                  return ''
                } else {
                  if (params.value < 200) {
                    return ''
                  } else {
                    return parseFloat(params.value).toLocaleString(undefined, {
                      minimumFractionDigits: 2,
                      maximumFractionDigits: 2,
                    })
                  }
                }
              },
            },
            data: res[1][key], //后台接口中,此客户名下的返回数据 [xx,xx,xx]
          }
          option.series.push(objSeries)
        }

        let numSeries = {
          // 最后一个顶部的total总值系列定义
          name: '',
          type: 'bar',
          data: [0, 0, 0],
          color: 'red',
          stack: '总量',
          barWidth: 50,
          label: {
            show: true,
            position: 'top',
            color: 'black',
            fontWeight: 'bold',
            formatter: function getSum(params) {
              let matchVal = res[0].Total[params.dataIndex] // 已知 res[0].Total,依次将后台返回的total值数组赋给顶部数值标签
              let temp = ''
              if (matchVal == undefined) {
                temp = 0.0
              } else {
                temp = parseFloat(matchVal).toLocaleString(undefined, {
                  minimumFractionDigits: 2,
                  maximumFractionDigits: 2,
                })
              }
              // return '{name|' + temp + '}'
              return temp
            },
            rich: {
              name: {
                color: '#000',
                fontWeight: 'bold',
                //  borderColor:'red',
                //  borderWidth:'2px',
                //  borderBottomWidth:'2px',
                padding: [5, 5, 5, 5],
              },
            },
          },
        }
        option.series.push(numSeries)
      }
      let myChart = this.$echarts.init(document.getElementById(idName))
      myChart.setOption(option, true)
    },

    //通用柱形图渲染数据,res 结构需一致。 chart2,5
    chartsBar(res, idName) {
      if (res == '' || res == null) {
        // 无数据时就置空图形
        res = [
          {
            Total: '',
            act: '',
            fct: '',
            fctDiff: '',
            ob: '',
            obDiff: '',
            title: '',
            type: '',
          },
          {},
        ]
      }
      // 先计算双坐标轴的数值
      if (idName == 'RevenueChart5' || idName == 'RevenueChart55') {
        // 年的柱状
        var intervalNum1 = this.StepYear
        var intervalNum1Min = this.MinYear
        var intervalNum1Y = this.StepYearY
      } else {
        // 月份的柱状图
        var intervalNum1 = this.StepMonth
        var intervalNum1Min = this.MinMonth
        var intervalNum1Y = this.StepMonthY
      }
      // res 动态的后台数据。 idName charts渲染时的id
      let option = {
        //设置公共option参数
        title: {
          text: 'CSC Monthly Revenue', //图表标题
          left: 'center',
        },
        color: ['#558ed5', '#8eb4e3', '#c6d9f1'], // 色块颜色值
        tooltip: {
          show: false,
          trigger: 'axis',
          axisPointer: {
            // 坐标轴指示器,坐标轴触发有效
            type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'
          },
        },
        legend: {
          data: res[0].title, //数据标题
          // data: ['OB','ACT','FCT Prev.','ACT vs. OB','ACT vs. FCT Prev.'] , //数据标题
          bottom: '0%',
        },
        grid: {
          bottom: '5%',
          left: '0%',
          top: '8%',
          width: '100%',
          containLabel: true,
        },
        xAxis: [
          {
            type: 'category',
            // axisTick: { show: true },
            data: res[0].type,
          },
          {
            type: 'category',
            data: res[0].type,
            show: false,
          },
        ],
        yAxis: [
          {
            type: 'value',
            // 左侧的第一个y轴同步数据分割的
            min: 0,
            max: intervalNum1Y * 5,
            interval: intervalNum1Y,
          },
          {
            type: 'value',
            // 第二个y轴同步数据分割的
            min: intervalNum1Min,
            max: intervalNum1Min + intervalNum1 * 5,
            interval: intervalNum1,
          },
        ],
        series: [], // 此处series数据循环
      }
      for (let i = 0; i < res[0].title.length; i++) {
        // 根据legend中色块的顺序,逐个获取数据中的此key的
        let key = res[0].title[i] //第i个legend对应的客户名
        let objSeries = {
          name: key,
          type: 'bar',
          barWidth: 30,
          barGap: '30%', //同系列三个的间距
          barCategoryGap: '20%', //系列间的间距
          // stack: '总量',
          label: {
            show: true,
            position: 'top',
            color: '#333',
            fontWeight: '',
          },
          emphasis: {
            focus: 'series',
          },
          data: [], //后台接口中,此客户名下的返回数据 [xx,xx,xx]
        }
        // 根据title的名字获取数据
        if (key == 'OB') {
          objSeries.data = res[0].ob
        } else if (key == 'ACT' || key == 'FCT') {
          objSeries.data = res[0].act
          objSeries.label.fontWeight = 'bold'
        } else {
          objSeries.data = res[0].fct
        }
        option.series.push(objSeries)
      }

      // 第一个折线图的点
      let objSeriesLineOb = {
        name: 'ACT vs. OB',
        xAxisIndex: 1,
        yAxisIndex: 1,
        id: 'line1',
        name: 'lineL',
        type: 'line',
        symbolOffset: [-40, 0],

        itemStyle: {
          normal: {
            color: '#558ed5',
            lineStyle: {
              width: '',
              // color:'red',
              type: 'solid', //'dashed'虚线 'solid'实线
            },
          },
        },
        label: {
          show: true,
          color: '#fff',
          fontWeight: 'bold',
          formatter: function (params) {
            if (params.value < 0) {
              return '{name|' + params.value + '}'
            } else {
              return params.value
            }
          },
          rich: {
            name: {
              color: 'red',
              fontWeight: 'bold',
            },
          },
          // formatter: function (params) {
          //   return params.value == undefined ? '0.00'
          //     : parseFloat(params.value).toLocaleString(undefined, {
          //         minimumFractionDigits: 2,
          //         maximumFractionDigits: 2,
          //       })
          // },
        },

        data: res[0].obDiff, //后台接口中,此客户名下的返回数据 [xx,xx,xx]
      }
      option.series.push(objSeriesLineOb)
      // 第二个折线图的点
      let objSeriesLineFct = {
        name: 'ACT vs. FCT Prev.',
        xAxisIndex: 1,
        yAxisIndex: 1,
        name: 'lineL2',
        type: 'line',
        symbolOffset: [40, 0],
        itemStyle: {
          normal: {
            color: '#c6d9f1', //折现点的颜色
            lineStyle: {
              width: '',
              type: 'solid', //'dashed'虚线 'solid'实线
              // offset: '50%',
            },
          },
        },
        label: {
          show: true,
          color: '#000',
          fontWeight: 'bold',
          formatter: function (params) {
            if (params.value < 0) {
              return '{name|' + params.value + '}'
            } else {
              return params.value
            }
          },
          rich: {
            name: {
              color: 'red',
              fontWeight: 'bold',
            },
          },
          // formatter: function (params) {
          //   return params.value == undefined ? '0.00'
          //     : parseFloat(params.value).toLocaleString(undefined, {
          //         minimumFractionDigits: 2,
          //         maximumFractionDigits: 2,
          //       })
          // },
        },
        data: res[0].fctDiff, //后台接口中,此客户名下的返回数据 [xx,xx,xx]
      }
      option.series.push(objSeriesLineFct)
      //==============================================

      if (idName == 'RevenueChart5' || idName == 'RevenueChart55') {
        //全年的柱状要修改标题
        option.title.text = 'CSC ' + this.$store.getters.fiscalYear + ' Total Revenue'
      }

      let myChart = this.$echarts.init(document.getElementById(idName))
      myChart.setOption(option, true)
    },

    // 双坐标。 向上取整十,整百,整千,整万
    ceilNumber(number) {
      let bite = 0
      if (number < 10) {
        return 10
      }
      while (number >= 10) {
        number /= 10
        bite += 1
      }
      return Math.ceil(number) * Math.pow(10, bite)
    },

    //获取第6个瀑布图的数据
    RevenueCharts6(res) {
      // 增加了空数据的echarts处理
      if (res == '' || res == null) {
        res = []
        res.negative = []
        res.positive = []
        res.title = []
        res.total = []
      }
      let myChart = this.$echarts.init(document.getElementById('RevenueWaterFall'))
      let colorLinearBlue = new this.$echarts.graphic.LinearGradient(
        1,
        0,
        0,
        0, // 这四个是设置渐变方向的
        [
          { offset: 0, color: '#14B6F1' }, //柱图渐变色
          { offset: 0.4, color: '#edf9fe' }, //柱图渐变色
          { offset: 0.5, color: '#FEFFFF' }, //柱图渐变色
          { offset: 0.6, color: '#edf9fe' }, //柱图渐变色
          { offset: 1, color: '#14B6F1' }, //柱图渐变色
        ]
      )
      let colorLinearRed = new this.$echarts.graphic.LinearGradient(
        1,
        0,
        0,
        0,
        // 这四个是设置渐变方向的
        [
          { offset: 0, color: '#b71a1a' }, //柱图渐变色
          { offset: 0.4, color: '#f7eaea' }, //柱图渐变色
          { offset: 0.5, color: '#FEFFFF' }, //柱图渐变色
          { offset: 0.6, color: '#f7eaea' }, //柱图渐变色
          { offset: 1, color: '#b71a1a' }, //柱图渐变色
        ]
      )
      myChart.setOption({
        title: {
          text: 'CSC TTL Revenue OB vs FCT vs FCT Prev.',
          left: 'center',
          top: '20px',
        },
        tooltip: {
          show: false,
          trigger: 'axis',
          axisPointer: {
            // 坐标轴指示器,坐标轴触发有效
            type: 'line', // 默认为直线,可选为:'line' | 'shadow'
          },
          formatter: function (params) {
            var tar
            if (params[1].value !== null) {
              tar = params[1] + 'aa'
            } else {
              tar = params[0] + 'bb'
            }
            return tar.name + '<br/>' + tar.seriesName + ' : ' + tar.value
          },
        },
        // legend: {
        //   data: ['增加', '减少'],
        //   right: '1%',
        // },
        grid: {
          left: '1%',
          right: '5%',
          bottom: '3%',
          containLabel: true,
        },
        xAxis: {
          type: 'category',
          splitLine: { show: false },
          axisLabel: {
            // interval: 0, //显示所有X轴信息
            rotate: 40, //倾斜度 -90 至 90 默认为0
            // margin: 15, //设置标签与x 轴得距离
            textStyle: {
              // fontWeight: 'bolder',
              color: '#333',
            },
          },
          data: res.title,
        },
        yAxis: {
          type: 'value',
          axisLabel: {
            margin: 10, // 清除默认间距
          },
          // nameTextStyle: {
          // Width: '150px',
          // },
        },
        series: [
          {
            // 辅助-总量
            name: '辅助',
            type: 'bar',
            stack: '总量',
            label: {
              show: false,
            },
            itemStyle: {
              color: 'rgba(0,0,0,0)',
            },
            emphasis: {
              itemStyle: {
                color: 'rgba(0,0,0,0)',
              },
            },
            data: res.total,
          },
          {
            // 总量-增加
            name: '增加',
            type: 'bar',
            stack: '总量',
            label: {
              //设置柱子上的数字的 标签的文字
              show: true,
              position: 'inside',
              // position: 'inside',
              textStyle: {
                color: '#000',
                // fontWeight: 'bolder',
              },
              formatter: function (params) {
                let aa = ''
                if (params.value == undefined) {
                  aa = 0.0
                } else {
                  aa = parseFloat(params.value).toLocaleString(undefined, {
                    minimumFractionDigits: 2,
                    maximumFractionDigits: 2,
                  })
                }
                if (params.name == 'OB' || params.name == 'FCT' || params.name == 'FCT Prev.') {
                  return '{name|' + aa + '}'
                } else {
                  return '{name1|' + aa + '}'
                }
              },
              rich: {
                name: {
                  color: '#000',
                  fontSize: 15,
                  fontWeight: 'bold',
                },
                name1: {
                  color: '#000',
                },
              },
            },
            itemStyle: {
              //设置柱子的通用颜色样式
              // normal: {
              //   color: '#37c1f3',
              // },
              color: function (params) {
                if (params.name == 'OB') {
                  return '#4F81BD'
                } else if (params.name == 'ACT' || params.name == 'FCT') {
                  return '#9BBB59'
                } else if (params.name == 'FCT Prev.') {
                  return '#8064A2'
                } else {
                  return colorLinearBlue
                }
              },
            },
            data: res.positive,
          },
          {
            // 总量-减少
            name: '减少',
            type: 'bar',
            stack: '总量',
            label: {
              //设置柱子上的数字的
              show: true,
              position: 'inside',
              textStyle: {
                color: 'red', // 减少的显示红色
                // fontWeight: 'bolder',
              },
              formatter: function (params) {
                let aa = parseFloat(params.value).toLocaleString(undefined, {
                  minimumFractionDigits: 2,
                  maximumFractionDigits: 2,
                })
                return params.value == undefined ? '0.00' : '-' + aa
              },
            },
            itemStyle: {
              normal: {
                // color: '#b71a1a',
                color: colorLinearRed,
              },
              label: {
                show: true,
                // position : 'top',
                formatter: '{c}',
                textStyle: {
                  color: 'purple',
                },
              },
            },
            data: res.negative,
          },
        ],
      })
    },
  },

  computed: {
    columnsCSC: function () {
      return [
        {
          title: 'Rev.',
          align: 'center',
          children: [
            {
              title: this.monthName,
              dataIndex: 'customerName',
              align: 'center',
            },
          ],
        },
        {
          title: 'CSC Monthly Revenue',
          children: [
            {
              title: 'OB',
              align: 'center',
              dataIndex: 'ob',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'ACT',
              align: 'center',
              dataIndex: 'act',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'FCT Prev.',
              align: 'center',
              dataIndex: 'fct',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'Diff-ACT vs. OB',
              align: 'center',
              dataIndex: 'obDiff',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'Diff-ACT vs. FCT Prev.',
              align: 'center',
              dataIndex: 'fctDiff',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
          ],
        },
      ]
    },
    columnsCSC1: function () {
      return [
        {
          title: 'Rev.',
          align: 'center',
          children: [
            {
              title: this.monthName,
              dataIndex: 'customerName',
              align: 'center',
            },
          ],
        },
        {
          title: 'SDD Monthly Revenue',
          children: [
            {
              title: 'OB',
              align: 'center',
              dataIndex: 'ob',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'ACT',
              align: 'center',
              dataIndex: 'act',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'FCT Prev.',
              align: 'center',
              dataIndex: 'fct',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'Diff-ACT vs. OB',
              align: 'center',
              dataIndex: 'obDiff',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'Diff-ACT vs. FCT Prev.',
              align: 'center',
              dataIndex: 'fctDiff',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
          ],
        },
      ]
    },
    columnsCSC2: function () {
      return [
        {
          title: 'Rev.',
          align: 'center',
          children: [
            {
              title: this.monthName,
              dataIndex: 'customerName',
              align: 'center',
            },
          ],
        },
        {
          title: 'SET Monthly Revenue',
          children: [
            {
              title: 'OB',
              align: 'center',
              dataIndex: 'ob',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'ACT',
              align: 'center',
              dataIndex: 'act',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'FCT Prev.',
              align: 'center',
              dataIndex: 'fct',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'Diff-ACT vs. OB',
              align: 'center',
              dataIndex: 'obDiff',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'Diff-ACT vs. FCT Prev.',
              align: 'center',
              dataIndex: 'fctDiff',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
          ],
        },
      ]
    },
    columnsCSC3: function () {
      return [
        {
          title: 'Rev.',
          align: 'center',
          children: [
            {
              // title: this.monthName,
              dataIndex: 'customerName',
              align: 'center',
            },
          ],
        },
        {
          title: 'CSC ' + this.$store.getters.fiscalYear + ' Total Revenue',
          children: [
            {
              title: 'OB',
              align: 'center',
              dataIndex: 'ob',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'FCT',
              align: 'center',
              dataIndex: 'act',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'FCT Prev.',
              align: 'center',
              dataIndex: 'fct',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'Diff-FCT vs. OB',
              align: 'center',
              dataIndex: 'obDiff',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
            {
              title: 'Diff-FCT vs. FCT Prev.',
              align: 'center',
              dataIndex: 'fctDiff',
              customRender: function (text) {
                return text == undefined
                  ? '0.00'
                  : parseFloat(text).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
              },
            },
          ],
        },
      ]
    },
  },
}
</script>

<style lang="less" scoped>
@import '~@assets/less/common.less';

.m-b20 {
  // margin-bottom: 15px;
  margin-top: 10px;
  margin-bottom: -40px;
}

.chart-line {
  display: flex;
  width: 100%;
  flex-direction: row;
  flex-wrap: wrap;
  margin-bottom: 60px;
}
.chart-outer {
  min-width: 60%;
  overflow-x: auto;
  flex: 1;
  text-align: center;
}
.chart-outer2 {
  // min-width: 50%;
  overflow-x: auto;
  // flex: 1;
  text-align: center;
}
.left-table {
  // margin-top: 55px;
  width: 40%;
  min-width: 500px;
  margin-bottom: 30px;
}
</style>

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值