最近项目开发需求时,需要用到echart中的bar柱状图,本来想封装一个完整可复用的ehcart组件,后面发现options中内容基本不可能都适用,最后自己封装了一个较为好用的组件共享
// legend图例放在template中因为更好定位,样式也更加多变化
<template>
<div class="bus-group-chart">
<div
ref="chart"
class="chart"
/>
<p
v-if="sum"
class="sum"
>
累计:
<strong>{{ sum }}</strong>
{{ unit }}
</p>
<div class="legend-list">
<div
v-for="(item, index) in data"
:key="index"
class="legend-item"
>
<div v-if="item.name">
<i
class="color"
:style="{background: colorList[index]}"
/>
<span>{{ item.name }}</span>
</div>
</div>
</div>
</div>
</template>
<script>
/**
* 普通面板
*
* @prop {Array} [data] echart上的渲染数据
* @prop {Number} [sum] 页面上的累计值
* @prop {String} [unit] 数值单位
* @prop {Boolean} [xyExchange] 交互xy轴位置
* @prop {String, Number} [barWidth] 柱形宽度,可用数字和百分比
* @prop {Boolean} [sameColor] 同一种类柱形颜色是否为同色
*
*/
import * as echarts from "@/components/chart/echarts";
// COLOR_LIST是作为柱形图颜色库,取色按照顺序依次使用
const COLOR_LIST = ["#0091FF", "#0AC79D", "#9BE74C", "#F99151"]
export default {
props: {
data: {
type: Array,
default () {
return []
}
},
sum: {
type: Number,
default: 0
},
unit: {
type: String,
default: ""
},
xyExchange: {
type: Boolean,
default: false
},
// barWidth柱状宽度,可以为数字也可以是百分比
barWidth: {
type: [Number, String],
default () {
return ""
}
},
sameColor: {
type: Boolean,
default: true
}
},
data () {
return {
colorList: COLOR_LIST
}
},
watch: {
data () {
this.update()
}
},
mounted () {
this.initChart()
this.update()
},
beforeDestroy () {
this.chart && this.chart.dispose()
},
methods: {
// 声明chart变量
initChart () {
this.chart = echarts.init(this.$refs.chart)
},
// 每次data值改变都会触发update函数,让echart视图更新
update () {
if (!this.data.length) {
return
}
const categoryList = this.data[0].data.map((item) => {
return item.name
})
// 默认为y轴
const valAxis = [
{
type: "value",
// axisLine: 坐标轴轴线设置
axisLine: { show: false },
// axisLine: 坐标轴刻度线设置
axisTick: { show: false },
// axisLine: 坐标轴刻度标签设置
axisLabel: {
align: "right",
fontSize: 10
},
// splitLine: 坐标轴在 [grid](直角坐标系内绘图网格) 区域中的分隔线
splitLine: {
lineStyle: {
opacity: 0.1
}
}
}
]
// 默认为x轴
const cateAxis = {
type: "category",
axisTick: { show: false },
axisLine: {
lineStyle: {
width: 1,
opacity: 0.5
}
},
axisLabel: {
// 坐标轴刻度标签的显示间隔,0为强制显示所有标签,1为隔一个显示一个标签
interval: 0,
},
data: categoryList,
};
const series = this.data.map((category, index) => {
const { name, data } = category
// valueList: 柱形图的data来源
const valueList = data.map((item) => {
return item.value
})
// color: 每条柱形使用的颜色,如果this.sameColor使用同色,则从颜色库中获取单一颜色,否则获取多样颜色,params为多条柱形数据
const color = (params) => {
if (this.sameColor) {
return this.colorList[index]
} else {
return this.colorList[params.dataIndex]
}
}
const series = {
name: name,
type: "bar",
// barWidth: 如果外部不传barWidth则显示默认值
barWidth: this.barWidth || "",
// barGap: 不同系列的柱间距离
barGap: 0,
labelOption: {
show: true,
},
// itemStyle:柱形图样式
itemStyle: {
color
},
data: valueList,
}
return series
})
const option = {
textStyle: {
color: "#fff"
},
// tooltip:提示框组件
tooltip: {
// trigger触发类型:'item'数据项图形触发,'axis'坐标轴触发
trigger: "axis",
backgroundColor: "rgba(31,76,117,0.9)",
borderColor: "#1F9CB4",
padding: [8, 12],
textStyle: {
color: "#FFF",
fontSize: 14
},
// axisPointer: 坐标轴指示器配置项,shadow为选中显示阴影
axisPointer: {
type: "shadow"
},
// formatter: 提示框浮层内容格式器,支持字符串模板和回调函数两种形式。
formatter: (params) => {
let toolTip = `${params[0].name}${params.length > 1 ? "<br>" : ""}`;
params.forEach((item, index) => {
toolTip += `${item.seriesName}:${item.value}${this.unit}<br>`
})
return toolTip
}
},
// grid: 直角坐标系内绘图网格
grid: {
top: 58,
bottom: 0,
left: 0,
right: 5,
containLabel: true,
borderWidth: 0,
},
// this.xyExchange: 更换xy轴位置
xAxis: this.xyExchange ? valAxis : cateAxis,
yAxis: this.xyExchange ? cateAxis : valAxis,
series: series,
}
this.chart.setOption(option)
}
}
}
</script>
<style lang="scss">
.bus-group-chart {
position: relative;
height: 100%;
.chart {
height: 100%;
}
.sum {
position: absolute;
top: -40px;
right: 10px;
font-size: 13px;
color: #FFF;
}
.legend-list {
position: absolute;
left: 0;
width: 100%;
bottom: -40px;
display: flex;
justify-content: flex-end;
font-size: $font-size-small;
.legend-item {
margin-right: 16px;
.color {
display: inline-block;
width: 10px;
height: 10px;
vertical-align: baseline;
margin-right: 8px;
}
}
}
}
</style>
组件使用:
<bar-group-chart
:data="inforChartData"
unit="s"
bar-width="30"
:same-color="false"
/>
inforChartData: [
data: [
[name: "驻站", value: 1000],
[name: "车速", value: 1500],
[name: "信号", value: 2500],
[name: "交通", value: 4500]
],
name: ""
]