公司有图表需求,简单记录一下echart使用方法。
动态刷新需要用到setOption中的notMerge 属性,设置true会去除多余数据。
getDataURL()方法,可以导出联动的图表图片。
把Echart稍微简单封装成一个组件
<template>
<div class="echarts-base">
<div :id="echartsData.id" :style="echartsData.style || defaultStyle"></div>
</div>
</template>
<script>
import * as echarts from 'echarts';
export default {
props: {
echartsData: {
type: Object,
default: () => {
return {
id: '',
style: null,
option: null,
}
}
}
},
data() {
return {
defaultStyle: {width: '300px', height: '300px'}
}
},
created() {
},
mounted() {
this.drawEchart()
},
methods: {
// 获取echart节点
getElementEchart() {
return echarts.init(document.getElementById(this.echartsData.id))
},
// 绘制
drawEchart() {
let baseEchart = this.getElementEchart()
//notMerge 可选。是否不跟之前设置的 option 进行合并。默认为 false。即表示合并。合并的规则,详见 组件合并模式。如果为 true,表示所有组件都会被删除,然后根据新 option 创建所有新组件。
baseEchart.setOption(this.echartsData.option, {notMerge: true})
},
// 显示loading
showLoading() {
let baseEchart = this.getElementEchart()
baseEchart.showLoading()
},
// 隐藏loading
hiddenLoading() {
let baseEchart = this.getElementEchart()
baseEchart.hideLoading()
},
// 将图标导出为base64 图片格式
// echarts提供getDataURL()方法,将图片转成base64图片格式
getImageBase64() {
let myChart = this.$echarts.init(document.getElementById(this.echartData.id));
let picInfo = myChart.getDataURL({
type: 'png',
pixelRatio: 2,
excludeComponents: ['toolbox'],
})
return picInfo
},
}
}
</script>
<style scoped lang="scss">
.echarts-base {
display: flex;
justify-content: center;
align-items: center;
}
</style>
调用组件
<template>
<div id="app">
<echarts-base ref="firstEchart" :echartsData="echartData"></echarts-base>
</div>
</template>
<script>
import EchartsBase from "@/components/EchartsBase/index.vue"
export default {
name: 'App',
components: {EchartsBase},
data() {
return {
echartData: {
id: 'firstEchart',
style: {width: '600px', height: '500px'},
option: {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: []
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: []
}
]
}
}
}
},
mounted() {
this.getList()
},
methods: {
getList() {
this.$refs.firstEchart.showLoading()
setTimeout(() => {
let title = {
text: '哈哈哈哈'
}
let xAxisData = ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子', '帽子', '军大衣']
let seriesData = [
{
name: '销量',
type: 'bar',
data: [10, 20, 30, 40, 50 , 60 ,70, 15]
}
]
this.$set(this.echartData.option, 'series', seriesData)
this.$set(this.echartData.option.xAxis, 'data', xAxisData)
this.$set(this.echartData.option, 'title', title)
this.$refs.firstEchart.drawEchart()
this.$refs.firstEchart.hiddenLoading()
// 获取图表图片
this.$refs.firstEchart.getImageBase64()
}, 2000);
}
}
}
</script>
------------新需求-------------
动态折线图实时数据,做一次简单封装
写的优点乱,有时间在整理
实时获取数据
创建组件:lineEchart.vue
<template>
<div class="lineChart">
<div class="select">
<p>{{ title }}</p>
<div v-if="isShowSelect" class="sift">
<el-select
v-model="companyGroupList"
size="small"
multiple
collapse-tags
clearable
placeholder="可选择"
>
<el-option
v-for="item in companyGroups"
:key="item.subEntry"
:label="item.dictPrompt"
:value="item.subEntry"
/>
</el-select>
// 这就是一个放大缩小的按钮,坐放大全屏处理
<ZoomInOut style="margin-left: 16px;" :is-full="!isFullScreen" @click="handleZoom" />
</div>
</div>
<div :id="chartId" class="line" />
</div>
</template>
<script>
import * as echarts from 'echarts'
import ZoomInOut from '@/components/zoomInOut/index.vue'
export default {
components: { ZoomInOut },
props: {
chartId: {
type: String,
default: ''
},
title: {
type: String,
default: ''
},
companyGroups: {
type: Array,
default: () => []
},
isShowSelect: {
type: Boolean,
default: true
}
},
data() {
return {
isFullScreen: false,
lineChart: null,
lineOption: null,
companyGroupList: [],
// xAxisArr: this.xAxisData,
// dataArr: this.chartData
}
},
mounted() {
// this.drawEchart()
},
methods: {
// 放大按钮的操作事件
handleZoom() {
// this.isFullScreen = !this.isFullScreen
this.$emit('clickZoom', this.isFullScreen)
},
// 需求里是大小是可以动态编辑的,所以需要按照size重新绘制
resetSize() {
this.lineChart.resize()
},
// 动态添加数据的方法,传入相应数据
// notMerge:false: 动态新增x,y轴数据,true: 重新请求或者折线条数增减,需要去除多余的组件
addData(chartData, xAxisData, keyArr, notMerge = false) {
const seriesArr = []
chartData.forEach(item => {
seriesArr.push({
name: item.name,
type: 'line',
smooth: true,
emphasis: {
focus: 'series'
},
data: item.data
})
})
if (notMerge) {
// 相当于重新绘制
this.chartSetOption(keyArr, xAxisData, seriesArr, notMerge)
} else {
// 实时获取数据,动态添加
this.lineChart.setOption({
legend: {
data: keyArr
},
xAxis: {
data: xAxisData
},
series: seriesArr
})
}
},
// 绘制
drawEchart(val) {
this.lineChart = echarts.init(document.getElementById(this.chartId))
if (val) {
const { xAxis, dataArr, keyArr } = val
const seriesArr = []
dataArr.forEach(item => {
seriesArr.push({
name: item.name,
type: 'line',
smooth: true,
emphasis: {
focus: 'series'
},
data: item.data
})
})
this.chartSetOption(keyArr, xAxis, seriesArr, true)
} else {
this.chartSetOption()
}
},
chartSetOption(legendArr = [], xAxisData = [], seriesData = [{
name: '',
type: 'line',
emphasis: {
focus: 'series'
},
data: []
}], notMerge = false) {
this.lineChart.setOption({
title: {
text: ''
},
// 颜色选项
color: ['#1E90FF', '#FFE4B5', '#ee6666', '#73c0de', '#fc8452', '#9a60B4', '#ea7ccc', '#FFD700', '#FF8247', '#9370DB'],
tooltip: {
order: 'valueDesc',
trigger: 'axis'
},
// 折线分类
legend: {
data: legendArr,
type: 'scroll' // 内容超出显示滚动条
},
xAxis: {
type: 'category',
boundaryGap: false, // x轴,数据会在x轴刻度对齐
nameLocation: 'middle', // 坐标轴名称显示位置
data: xAxisData
},
yAxis: {
// 最小间隔大小
minInterval: 1,
type: 'value'
},
// 区域缩放
dataZoom: [
{
type: 'inside',
start: 0,
end: 100,
filterMode: 'none' // 区域放大,折现没有完全连接
},
{
start: 0,
end: 100,
filterMode: 'none' // 区域放大,折现没有完全连接
}
],
series: seriesData
}, notMerge)
}
}
}
</script>
<style lang="scss" scoped>
.lineChart {
width: 100%;
height: 100%;
border: 2px solid #eeeeee;
border-radius: 8px;
display: flex;
flex-direction: column;
background: #fff;
}
.line {
flex: 1;
}
.select {
display: flex;
padding: 8px 8px 0 8px;
align-items: center;
p{
flex: 1;
margin: 0;
font-size: 18px;
font-weight: 800;
color: #303133;
}
.sift {
display: flex;
}
}
</style>
index.vue
<lineChart
ref="entrustLine"
chart-id="entrustLineID"
title="当日委托笔数"
:company-groups="companyGroups"
@clickZoom="handleZoom(1)"
/>
// 绘制
this.$refs.entrustLine.drawEchart()
// 添加动态数据
this.$refs.entrustLine.addData(dataArr, xAxis, keyArr, val)