最近在做项目的时候需要用到echarts中的正负条形图,根据服务端返回的数据进行展示,使用过程中处理了一些自定义展示的方法,现对属性的使用进行总结:
<!-- 正负柱状图 -->
<template>
<div :id="id" :class="className" :style="{ height: newHeight, width: width }" />
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'PlusAndMinusBarChart',
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '85%'
},
height: {
type: String,
default: '350px'
},
chartData: { // 封装的数据集合,通过外部传入
type: Object,
default: () => {
return {};
}
}
},
data() {
return {
chart: null,
newHeight: null
};
},
watch: {
chartData: {
deep: true,
handler(val) {
this.handleHeight();
this.setOptions(val);
}
}
},
created() {
this.handleHeight();
},
mounted() {
this.$nextTick(() => {
this.initChart();
});
},
beforeDestroy() {
if (!this.chart) {
return;
}
this.chart.dispose();
this.chart = null;
},
methods: {
handleHeight() {
if (this.chartData.yAxis.data.length > 7) {
this.newHeight = `${this.chartData.yAxis.data.length * 50}px`;
} else {
this.newHeight = this.height;
}
},
initChart() {
this.chart = echarts.init(document.getElementById(this.id));
this.setOptions(this.chartData);
},
setOptions(data = {}) {
this.chart.setOption({
title: {
text: data.title // 标题
},
tooltip: { // 鼠标经过时,展示的tips
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) { // 处理需要展示的数据
let res = `<div>${params[0].name}</div>`;
let explain = '';
params.forEach((v, i) => {
let newVal = '';
let filterNumLabel = '';
explain = data.series.filterTypeExplain[v.dataIndex];
if (i === 2) {
filterNumLabel = '';
data.series.numeric3.forEach((item) => {
if (Math.abs(item) === Math.abs(v.value)) {
newVal = `${item}%`;
}
});
} else {
filterNumLabel = data.series[`filterNum${i + 1}`][v.dataIndex];
newVal = data.type === 'number' ? v.value : `${v.value}%`;
}
res += `<div style="display:flex;align-items:center">
<span
style="display:inline-block;
margin-right:5px;
border-radius:10px;
width:10px;
height:10px;
background-color:${v.color}"
></span>
<span>${v.seriesName}: ${newVal};</span>
</div>`;
res +=
filterNumLabel || filterNumLabel === 0
? ` <div>过滤数量: ${filterNumLabel};</div>`
: '';
});
res += explain
? ` <div style="white-space: pre-wrap;word-break: break-all;word-wrap: break-word">注释: ${explain};</div>`
: '';
return res;
},
extraCssText: 'max-width:500px;' // 额外附加到浮层的 css 样式,设定宽度,方便注释数据过长时,进行换行展示
},
color: ['rgb(84, 112, 198)', 'rgb(145, 204, 117)', 'rgb(250, 200, 88)'],// 柱状图的颜色,会依次循环从该列表中取颜色作为系列颜色
legend: {
top: '20px', // 图例组件离容器上侧的距离
data: [data.series.name1, data.series.name2, data.series.name3] // 图例的数据数组
},
grid: {
left: '3%', // 组件离容器左侧的距离
right: '10%', // 组件离容器右侧的距离
bottom: '3%', // 组件离容器下侧的距离
containLabel: true // 区域是否包含坐标轴的【刻度标签】
},
xAxis: [ // 横坐标
// 此为:横坐标左右都需要显示不同的名称
{
name: data.yAxis.name,
type: 'value',
nameLocation: 'start', // 坐标轴名称显示在横坐标的最右侧
nameTextStyle: { // 坐标轴名称的样式
fontWeight: 600,
fontSize: 14
},
axisLabel: {
show: true, // 是否显示刻度标签
formatter: (value) => { // 自定义方法,根据不同条件显示不同坐标轴刻度
if (value < 0) {
return `${-value} %`;
} else {
return data.type === 'number' ? value : `${value} %`;
}
}
}
},
{
name: data.xAxis.name,
type: 'value',
position: 'bottom', // 坐标轴名称显示在横坐标的最左侧
nameTextStyle: {
fontWeight: 600,
fontSize: 14
},
axisLabel: {
show: true,
formatter: (value) => {
if (value < 0) {
return `${-value} %`;
} else {
return data.type === 'number' ? value : `${value} %`;
}
}
}
}
],
yAxis: [ // 纵坐标
{
axisTick: {
show: false, // 是否显示坐标轴刻度
length: 50
},
type: 'category', // 为该类型时类目数据可自动从 【series.data】或 【dataset.source】中取,或者可通过 【yAxis.data】设置展示的纵坐标类目数据
data: data.yAxis.data
}
],
series: [
{
name: '图1', // 名称
type: 'bar', // bar:柱状图,line:折线/面积图,pie:饼图 等
label: { // 图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等
show: true, // 是否显示标签
position: 'right', // 标签显示的位置
formatter: (params) => { // 自定义方法,根据不同条件显示不同标签
return data.type === 'number' ? params.value : `${params.value} %`;
}
},
emphasis: {
focus: 'series' // 聚焦当前高亮的数据所在的系列的所有图形
},
itemStyle: { // 当前图形柱状图显示的样式
normal: {
color: 'rgb(84, 112, 198)' // 展示柱状图的颜色
}
},
data: data.series.numeric1 // 柱状图展示的数据集合
},
{
name: '图2',
type: 'bar',
stack: 'Total',
label: {
show: true,
position: 'right',
formatter: (params) => {
return data.type === 'number' ? params.value : `${params.value} %`;
}
},
emphasis: {
focus: 'series'
},
itemStyle: {
normal: {
color: 'rgb(145, 204, 117)'
}
},
data: data.series.numeric2
},
{
name: '相对变化',
type: 'bar',
stack: 'Total',
label: {
show: true,
position: 'left',
formatter: (params) => {
let str = '';
data.series.numeric3.forEach((item) => {
if (Math.abs(item) === Math.abs(params.value)) {
str = `${item} %`;
}
});
return str;
}
},
itemStyle: {
normal: {
color: (params) => {
// 根据不同条件展示不同颜色柱状图
let str = '';
data.series.numeric3.forEach((item) => {
if (Math.abs(item) === Math.abs(params.value)) {
if (item < 0) {
// 值小于0 的时候展示红色
str = '#a90000';
} else {
// 值大于等于0 的时候展示其它颜色
str = 'rgb(250, 200, 88)';
}
}
});
return str;
}
}
},
emphasis: {
focus: 'series'
},
data: data.series.numeric4
}
]
});
}
}
};
</script>
注意:
- 左侧【相对变化】中值为0的时候,显示的标签会在右侧,值的数据量级过大时会出现样式重叠(项目中处理方式:值为0的时候不展示该文本标签的数据信息);
- 图形的高度不要固定,可以给个初始高度值,动态根据要展示的数据来动态获取需要展示的高度;
- 横坐标左右需要显示不同的名称,注意刻度问题,量级不同,刻度不同,展示的数据信息,有的过长,有的过短;