我就用这篇文章来说说我是如何简单实现自己的Echarts的封装的吧
首先你得先去官网下载插件 我是根据npm install echarts --save 下载到我的项目的
1.然后自己封装代码
废话少说,上代码:
<template>
<div>
<div :style="styleE ? styleE : 'width:50%;height:200px;'" :ref="eRef"></div>
</div>
</template>
<script>
import echarts from 'echarts';
export default {
props: {
styleE: {
default: ''
},
chartData: {
type: Object,
default: () => {}
},
eRef: {
default: ''
},
method: {
// 自定义点击事件
default: ''
}
},
data() {
return {
count: 1,
myChart: ''
};
},
methods: {
drawChart() {
// 基于准备好的dom,初始化echarts实例
this.myChart = echarts.init(this.$refs[this.eRef]);
// 绘制图表
this.myChart.setOption(this.chartData);
},
reloadEcharts(val) {
this.myChart.setOption(val, true);
this.myChart.on('click', this.method);
}
},
mounted() {
const vm = this;
vm.$nextTick(() => {
vm.drawChart();
});
},
created: () => {}
};
</script>
<style scoped></style>
- 这样我们的 echrats 算是单独封装成了一个组件~怎么样?简单吧?
- 那么我么来第二步,引入到需要的文件中去
废话不多说,上代码~
<template>
<div>
<!-- echarts图表 -->
<my-echarts eRef="echarts"
ref="barByYear1"
:styleE="styleE"
:chartData="chartDataByYear1"></my-echarts>
<!-- 饼图 -->
<div style="width:650px;height:650px;">
<my-echarts :styleE="stylePie"
eRef="pie2"
:method="clickProductLine1"
ref="pieByProductLine1"
:chartData="pieByProductLine1"></my-echarts>
</div>
</div>
</template>
js部分做了引入的配置,所以分开来写:
2.编写对应的 js 逻辑
这里以年份的图表为例!!
上代码:
<script>
import myEcharts from '@/components/echarts'; // 引入自己封装echarts
import {
echartsColor, //图表的颜色
echartsFeature, //柱状图 堆叠柱状图 的数据视图
echartsAxisLabel, //Y轴数据过大 转成k M B结尾
pieTooltip, //饼状图的tooltip
formatterThousands, //柱状图显示数据千分符格式
grid, // 控制图的大小
barsGrid, // 控制堆叠柱状图的大小
labelFormatter, //饼状图 label formatter且保留一位小数
formatterThousandsAndPercentage, // 柱状图tooltip 显示数据千分符格式和百分比格式
formatterPercentage, //堆叠柱状图tooltip 显示数据百分比格式
tableListByYearMonth, // 表格数据 tableListByYear
tableListByCountry, // 表格数据 tableListByCountry
getDataByYear, // 获取ByYear表格和柱状图的方法
getDataByCountry, // 获取ByCountry表格和柱状图的方法
} from './common.js';
export default {
components: {
myEcharts
},
data () {
return {
// echarts配置
// 年份图表
chartDataByYear1: {
color: echartsColor(),
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
},
formatter: formatterThousandsAndPercentage()
},
toolbox: {
top: 45,
show: true,
feature: echartsFeature(this)
},
title: {
// 图表标题
show: true,
text: '图表标题',
textAlign: 'center',
left: '50%',
textStyle: {
fontSize: 14,
lineHeight: 20
}
},
legend: {
// 图表按钮
data: [
'图表按钮1',
'图表按钮2',
'图表按钮3',
'图表按钮4'
],
top: '25'
},
xAxis: [
// x 轴
{
type: 'category',
data: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ], // 这里也可以不填
nameLocation: 'start', //坐标轴名称显示位置。
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
// y 轴
{
type: 'value',
axisLabel: echartsAxisLabel(),
splitLine: {
show: false
}
},
{
type: 'value',
axisLabel: {
show: true,
interval: 'auto',
formatter: '{value}%'
},
splitLine: {
show: false
},
show: true
}
],
grid: grid(),
series: [
// 表格中点击按钮的地方
{
name: '图表按钮1',
type: 'bar',
data: [],
label: {
normal: {
position: 'top',
show: true,
formatter: formatterThousands()
}
}
},
{
name: '图表按钮2',
type: 'bar',
barGap: '0', //缩小柱子之间的缝隙 默认20%
data: [],
label: {
normal: {
position: 'top',
show: true,
formatter: formatterThousands()
}
}
},
{
name: '图表按钮3',
type: 'line',
yAxisIndex: 1,
data: [],
label: {
normal: {
position: 'top',
show: true,
formatter: '{c}%'
}
}
},
{
name: '图表按钮4',
type: 'line',
yAxisIndex: 1,
data: [],
label: {
normal: {
position: 'top',
show: true,
formatter: '{c}%'
}
}
}
]
},
// 饼图配置
pieByProductLine1: {
title: {
text: '饼图标题',
subtext: '',
left: 'center',
textStyle: {
fontSize: 14,
lineHeight: 20
}
},
tooltip: pieTooltip(),
color: echartsColor(),
series: [
{
name: '饼图附标题',
type: 'pie',
radius: '55%',
center: [ '50%', '50%' ],
data: [ 0 ],
label: labelFormatter(),
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
},
// 柱状图配置
bars1: {
tooltip: {
trigger: 'axis',
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
},
formatter: formatterPercentage()
},
title: {
show: true,
text: '柱状图标题',
subtext: '每月销量占比走势(金额维度)',
textAlign: 'center',
left: '50%',
textStyle: {
fontSize: 14,
lineHeight: 20
}
},
toolbox: {
top: 50,
show: true,
feature: echartsFeature(this)
},
color: echartsColor(),
legend: {
// type: 'scroll',
data: [],
bottom: 0
},
xAxis: {
type: 'category',
data: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ]
},
yAxis: [
{
type: 'value',
axisLabel: {
show: true,
interval: 'auto',
formatter: '{value}%'
}
}
],
grid: barsGrid(),
series: []
},
}
}
</script>
完美~这样我们就引用好自己封装好的图表了
那么我们把图表文件配置项给配置一下:
- 1.柱状图 堆叠柱状图 的数据视图
export function echartsFeature (that) {
return {
myFull: {
show: true,
title: '查看大图',
icon: '你自己的icon图标',
onclick (e) {
that.dialogFullVisible = true
let opts = e.getOption()
opts.toolbox[0].feature.myFull.show = false
setTimeout(() => {
that.$refs.fullEchart.reloadEcharts(opts)
window.onresize = that.$refs.fullEchart.myChart.resize()
}, 1000)
}
},
dataView: {
readOnly: true,
show: true,
title: '数据视图',
optionToContent (opt) {
let axisData = opt.xAxis[0].data;
let series = opt.series;
let tdHeads = '<td style="padding:0 10px;border:1px solid #ccc;">名称</td>';
series.forEach(function (item) {
tdHeads +=
'<td style="padding: 0 10px;border:1px solid #ccc;">' + item.name + '</td>';
});
let table =
'<table style="border:1px solid #ccc;margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center"><tbody><tr>' +
tdHeads +
'</tr>';
let tdBodys = '';
for (let i = 0, l = axisData.length; i < l; i++) {
for (let j = 0; j < series.length; j++) {
tdBodys += '<td style="padding: 0 10px;border:1px solid #ccc;">' + series[j].data[i] + '</td>';
}
table += '<tr><td style="padding: 0 10px;border:1px solid #ccc;">' + axisData[i] + '</td>' + tdBodys + '</tr>';
tdBodys = '';
}
table += '</tbody></table>';
return table;
}
},
mark: {
show: true
},
magicType: {
show: true,
type: [ 'line', 'bar' ]
},
restore: {
show: true
},
saveAsImage: {
show: true
}
}
}
- 2.图表的公共颜色
export function echartsColor () {
return [ '#666666', '#003399', '#FFB6C1', '#77DDFF', '#66CC99', '#339999', '#006699', '#000066', '#999999', '#66CC66',
'#009966', '#660066', '#330099', '#556B2F', '#778899', '#003377', '#6A5ACD', '#D8BFD8' ]
}
- 3.Y轴数据过大 转成k M B结尾 (ps:这里完全看个人是否需求决定)
export function echartsAxisLabel () {
return {
margin: 2,
formatter (value) {
if (value >= 1000 && value < 1000000) {
value = value / 1000 + 'K ';
} else if (value >= 1000000 && value < 1000000000) {
value = value / 1000000 + 'M ';
} else if (value >= 1000000000) {
value = value / 1000000000 + 'B ';
}
if (value > -1000000 && value <= -1000) {
value = value / 1000 + 'K ';
} else if (value > -1000000000 && value <= -1000000) {
value = value / 1000000 + 'M ';
} else if (value <= -1000000000) {
value = value / 1000000000 + 'B ';
}
return ' ' + value + ' ';
}
}
}
- 4.饼状图的tooltip
export function pieTooltip () {
return {
trigger: 'item',
// formatter: '{a} <br/>{b} : {c} ({d}%)'
formatter (data) {
// console.log(data, 'data')
return data.seriesName + '<br/>' + data.name + ' : ' + data.value + ' (' + data.percent.toFixed(2) + '%)';
}
}
}
- 5.grid
export function grid () {
return { // 控制图的大小,调整下面这些值就可以,
// show:true,//是否显示直角坐标系网格。[ default: false ]
left: '10%',//grid 组件离容器左侧的距离。
right: '10%',
// borderColor:"#c45455",//网格的边框颜色
bottom: '25%', //
top: '17%'
}
}
export function barsGrid () {
return { // 控制图的大小,调整下面这些值就可以,
// show:true,//是否显示直角坐标系网格。[ default: false ]
left: '10%',//grid 组件离容器左侧的距离。
right: '10%',
// borderColor:"#c45455",//网格的边框颜色
bottom: '25%', //
top: '17%'
}
}
- 6.柱状图显示数据千分符格式 (ps:这里完全看个人是否需求决定)
export function formatterThousands () {
return function (a) {
let value = []
if (a.data > 0) {
value = a.data
if (value > 999) {
// 数值加千分号
let parts = value.toString().split('.')
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
value = parts.join('.')
}
}
return value
}
}
- 7.柱状图tooltip 显示数据千分符格式和百分比格式
export function formatterThousandsAndPercentage () {
return function (params) {
let html = params[0].name + '<br>';
for (let i = 0; i < params.length; i++) {
html += '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' + params[i].color + ';"></span>'
if (params[i].seriesName == 'Growth Rate Year-on-Year' || params[i].seriesName == 'Growth Rate Month-on-Month') {
html += params[i].seriesName + ': ' + params[i].value + '%<br>';
} else {
html += params[i].seriesName + ': ' + Number(params[i].value).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + '<br>';
}
}
return html;
}
}
- 8.饼状图 label formatter且保留一位小数( 一般我们的数值大道一定程度会用分隔符分开,这里也同一封装起来,还是看个人需求决定)
export function labelFormatter () {
return {
normal: {
show: true,
formatter (data) {
return data.name + ' : ' + data.percent.toFixed(2) + '%';
}
}
}
}
接下来就是划重点了!!!
我们接受参数来回显图表:
- 表格数据 ByYear (获取年份 显示这个表格数据)
- 这里举三个例子数据来演示
export function tableListByYearMonth () {
return [
{
prop: '', // <String> 对应属性名1
label: '', // <String> 表头标签
label2: '', // <String> 表头标签
width: 60
},
{
prop: '', // <String> 对应属性名2
label: '', // <String> 表头标签
label2: '', // <String> 表头标签
width: 70
},
{
prop: '', // <String> 对应属性名3
label: '', // <String> 表头标签
label2: '', // <String> 表头标签
width: 70
},
]
}
最后这里获取传进来的数据
export function getDataByYear (that, params) {
let monthList = [];
let preYearSale = [];
let curYearSale = [];
let yearOnYear = [];
let monthOnMonth = [];
that.Loading = true;
that.$store.dispatch('url', params).then((res) => {
that.Loading = false;
if (res && res.data && res.code == 200) {
let dataList = res.data;
if (dataList.length != 0) {
dataList.map((item, index) => {
item.id = index + 1
monthList.push(item.month);
preYearSale.push(item.参数1 ? item.参数1 : 0)
curYearSale.push(item.参数2)
yearOnYear.push(item.参数3 != null ? item.参数3 : '-')
monthOnMonth.push(item.参数4 != null ? item.参数4 : '-')
});
// 填充数据
that.chartDataByYear1.xAxis[0].data = monthList;
that.chartDataByYear1.series[0].data = preYearSale;
that.chartDataByYear1.series[1].data = curYearSale;
that.chartDataByYear1.series[2].data = yearOnYear;
that.chartDataByYear1.series[3].data = monthOnMonth;
that.$refs.barByYear1.reloadEcharts(that.chartDataByYear1); // 渲染图像
} else {
that.timeOut = true;
that.$message.closeAll();
}
})
.catch(() => {
that.Loading = false;
that.timeOut = true;
});
}
这样我们就完成了整个的渲染
喜欢的小伙伴请一件三联,关注支持博主,不定期更新,如果有不正确的地方,请多多指正....