遇到的问题: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>