背景:
测试:你这柱形图做出来咋都成这样了,两侧刻度都没对齐,恭喜你,功德-1,bug+1。
前端:汗流浃背了,小黑子。
echart 双柱状图-技术篇
双柱+折线双y轴刻度对齐
在最近的项目中用到双刻度的柱状图,但是没有优化,导致上了测试环境就产生了这样的问题。
应届小老弟:(火急火燎)哥!这东西真恶心呀,顶不住啦
我:干!
配置项:
pieConf: {
tooltip: {
trigger: 'axis',
backgroundColor: '#fff',
textStyle: {
color: '#48505B',
},
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999',
},
},
},
xAxis: [
{
type: 'category',
triggerEvent: true,
data: [],
axisLabel: {
fontSize: 12,
interval: 0,
rotate: 30,
formatter: function (value) {
if (value !== undefined) {
if (value.length > 5) {
// 超出6个字符显示省略号
return `${value.slice(0, 6)}...`
}
return value
}
},
},
axisPointer: {
type: 'shadow',
},
},
],
yAxis: [
{
type: 'value',
name: '使用项目数(个)',
min: 0,
axisLabel: {
formatter: '{value}',
},
// //网格线
splitLine: {
show: true,
lineStyle: {
type: 'solid', //y轴分割线类型
color: ['rgba(227, 229, 232, 0.5)'],
width: 1,
},
},
},
{
type: 'value',
name: '使用率(%)',
min: 0,
axisLabel: {
formatter: '{value} %',
},
// //网格线
splitLine: {
show: true,
lineStyle: {
type: 'solid', //y轴分割线类型
color: ['rgba(227, 229, 232, 0.5)'],
width: 1,
},
},
},
],
series: [
{
name: '使用项目数(个)',
type: 'bar',
color: '#1AB394',
tooltip: {
valueFormatter: function (value) {
console.log(value)
return value
},
},
data: [],
},
{
name: '未使用项目数(个)',
type: 'bar',
color: '#0081CC',
tooltip: {
valueFormatter: function (value) {
return value
},
},
data: [],
},
{
name: '使用率(%)',
type: 'line',
color: '#FF9900',
yAxisIndex: 1,
tooltip: {
valueFormatter: function (value) {
return value
},
},
data: [],
},
],
}
后端获取数据:
qualityCheckUseRate() {
let params = this.queryParams
qualityCheckUseRate(params).then((res) => {
let data = res.data || []
if (data.length) {
this.hasData = true
let xData = data.map((it) => it.orgName)
this.pieConf.xAxis[0].data = xData
let y1Data = data.map((it) => it.useCount)
let y2Data = data.map((it) => it.notUseCount)
let rateDate = data.map((it) => it.useRate)
this.pieConf.series[0].data = y1Data
this.pieConf.series[1].data = y2Data
this.pieConf.series[2].data = rateDate
let y1max = Math.max(...y1Data)
let y2Max = Math.max(...y2Data)
let yMax1 = y1max > y2Max ? y1max : y2Max
let yMax2 = Math.max(...rateDate)
var divisor = 5
var lcmVal = this.chartlcm(yMax1, yMax2) //获取两条y轴的最大公约数
var Ymaxval_interval = this.YmaxvalAndinterval(
yMax1,
yMax2,
lcmVal,
divisor
) //计算y轴最大值和间隔值
this.pieConf.yAxis[0].max = Ymaxval_interval.max1|| 5 //确保最小项目数量为5,不会出现小数
this.pieConf.yAxis[0].interval = Ymaxval_interval.interval1 || 1 //刚好五等分
this.pieConf.yAxis[1].max = Ymaxval_interval.max2 || 100 //没有值就设置最大值为100
this.pieConf.yAxis[1].interval = Ymaxval_interval.interval2 || 20 //间隔为20,刚好 100/20 五等分
this.initPieEchart(data)
} else {
this.hasData = false
this.rateChart && this.rateChart.dispose()
}
})
},
initPieEchart(data) {
this.rateChart = echarts.init(document.querySelector('.useRate-chart')) //对应的echart dom节点
this.rateChart.setOption(this.pieConf)
},
之后就是比较重要的两个方法:
最好是单独封装然后拿过来用,我这里直接用混入,其他组件需要就直接导入即可
//echarts专用求最大公约数 不含小数
chartlcm(a, b) {
var result = 1
for (var i = 1; i <= a && i <= b; i++) {
if (a % i == 0 && b % i == 0) {
result = i
}
if (result > 1 && i >= 10)
//公约数大于10的时候 直接跳出 避免y轴刻度太多 (如果不介意刻度太多可以把这一段去掉)
break
}
return result
},
//获取echarts 多Y轴的最大值和间隔值 lcmval 最大公约数 divisor 间隔数量
YmaxvalAndinterval(m, n, lcmval, divisor) {
var interval1 = Math.ceil(m / lcmval)
var interval2 = Math.ceil(n / lcmval)
if (lcmval != 1 && lcmval != 0 && lcmval <= 10) {
return { max1: m, max2: n, interval1: interval1, interval2: interval2 }
}
if (divisor == undefined || divisor == null) divisor = 5
m = Math.ceil(m / divisor) * divisor
n = Math.ceil(n / divisor) * divisor
interval1 = Math.ceil(m / divisor)
interval2 = Math.ceil(n / divisor)
return { max1: m, max2: n, interval1: interval1, interval2: interval2 }
},
上菜:
完美实现刻度对齐。
应届生老弟:家人们谁懂啊!!大哥功德+1.