1.下载echarts
- 使用npm或cnpm
npm install echarts --save
- 引入echarts模块在main.js中
// 全量引入
- import echarts from 'echarts'
- // 按需引入
- // 引入 ECharts 主模块
- var echarts = require('echarts/lib/echarts');
- // 引入柱状图
- require('echarts/lib/chart/bar');
- // 引入提示框和标题组件
- require('echarts/lib/component/tooltip');
- require('echarts/lib/component/title');
- 可以按需引入的模块列表见 常见模块地址
2.新建charts.vue
demo.vue 调用echarts实例
<div>
<bar-chart :data="data" />
</div>
</template>
<script>
import BarChart from './components/charts.vue'
export default {
name: '',
components: { BarChart },
props: {},
data() {
return {
data: {}
}
},
computed: {},
methods: {},
mounted() {}
}
</script>
charts.vue 组件
<template>
<div ref="chart"
style="width:300px;height:300px"></div>
</template>
<script>
import echarts from 'echarts'
import resize from 'mixins/echartsResize'
import * as BARCONFIG from 'config/echarts'
export default {
name: 'BarChart',
props: {
data: {
type: Array,
default() {
return []
}
}
},
watch: {
data: {
handler() {
this.initChart()
},
deep: true
}
},
mixins: [resize],
computed: {},
methods: {
initChart() {
const that = this
// 坐标轴配置
const xyAxisConfig = {
// 坐标轴轴线
axisLine: {
lineStyle: {
color: '#98A9C4'
}
},
// 坐标轴刻度
axisTick: {
lineStyle: {
color: '#DEE6FD'
}
},
// 坐标轴刻度标签
axisLabel: {
lineStyle: {
color: '#DEE6FD'
},
interval: 0
// rotate: 30
},
nameTextStyle: {
color: '#98A9C4'
}
}
const option = {
// color: BARCONFIG.THEME,
color: ['#ff0', 'f0f'],
title: {
text: '部门数据对比',
// textStyle: BARCONFIG.TITLE
},
legend: {
// data: ['过滤率', '成功发送率', '点击率', '转化率']
data: [
{
name: '过滤率',
icon: 'circle'
},
{
name: '成功发送率',
icon: 'circle'
},
{
name: '点击率',
icon: 'circle'
},
{
name: '转化率',
icon: 'circle'
}
],
top: 'top',
left: 'right',
textStyle: BARCONFIG.LEGEND
},
grid: {
top: 60,
left: 40,
right: 20,
bottom: 40
},
tooltip: {
trigger: 'axis',
...BARCONFIG.TOOLTIP,
// axisPointer: {
// type: 'shadow'
// },
formatter: function(params) {
let str = `<div style="${BARCONFIG.TOOLTIP_BOXSHADOW}">`
params.map(item => {
str += `<div>${item.marker} ${item.seriesName}${
item.value[item.seriesIndex + 1]
}%</div>`
})
str += '</div>'
return str
}
},
dataset: {
source: that.normalize()
},
xAxis: { type: 'category', ...xyAxisConfig },
yAxis: {
...xyAxisConfig,
name: '百分比',
splitLine: {
lineStyle: {
color: '#F2F5FE'
}
}
},
series: [
{
type: 'bar',
barCategoryGap: '60%',
itemStyle: { barBorderRadius: [8, 8, 0, 0] }
},
{
type: 'bar',
barCategoryGap: '60%',
itemStyle: { barBorderRadius: [8, 8, 0, 0] }
},
{
type: 'bar',
barCategoryGap: '60%',
itemStyle: { barBorderRadius: [8, 8, 0, 0] }
},
{
type: 'line',
barCategoryGap: '60%',
itemStyle: { barBorderRadius: [8, 8, 0, 0] }
}
]
}
if (!this.echarts) {
this.echarts = echarts.init(this.$refs.chart)
}
this.echarts.setOption(option)
},
normalize() {
// [
// ['department', '过滤率', '成功发送率', '点击率', '转化率'],
// ['部门一', 43.3, 85.8, 93.7, 81.5],
// ['部门二', 83.1, 73.4, 55.1, 61.2],
// ['部门三', 86.4, 65.2, 82.5, 51.3],
// ['部门四', 72.4, 53.9, 39.1, 71.4],
// ['部门五', 62.4, 57.9, 69.1, 51.4]
// ]
let data = this.data.map(item => {
return [
item.name,
item.filterRate,
item.successCountRate,
item.clickRate,
item.successClickRate
]
})
data.unshift(['department', '过滤率', '成功发送率', '点击率', '转化率'])
return data
}
},
mounted() {
this.initChart()
}
}
</script>
<style lang='stylus' scoped></style>
BARCONFIG.js 图表配置
// 主题样式 ( 可到官网定制主题,暂未定制 )
export const THEME = ['#3B98FF', '#00D2B3', '#FBA900', '#F96E5E', '#00C6FF']
export const MAP_THEME = ['#2F91FF', '#CCE6FE']
// 主内容 —— 黑色
export const BLACK = '#2D405E'
// 主内容 —— 灰色颜色
export const GRAY = '#98A9C4'
// 主内容 —— 白色
export const WHITE = '#ffffff'
// 字体大小
export const NORMAL = 16
export const SMALL = 14
export const THIN = 12
// 标题 样式
export const TITLE = {
color: BLACK,
fontSize: NORMAL
}
// 图例 样式
export const LEGEND = {
color: GRAY,
fontSize: THIN
}
// tooltip formater样式
export const TOOLTIP = {
padding: 0,
backgroundColor: WHITE,
textStyle: {
color: BLACK
},
}
export const TOOLTIP_BOXSHADOW = 'box-shadow: 0px 0px 10px rgba(135,138,193,0.49);padding:5px;'
echartsResize.js 适配窗口大小变化
import { debounce } from 'utils/utils'
export default {
mounted() {
this.__resizeHandler = debounce(() => {
if (this.echarts) {
console.log('resize')
this.echarts.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler)
},
beforeDestroy() {
if (!this.echarts) {
return
}
window.removeEventListener('resize', this.__resizeHandler)
this.echarts.dispose()
this.echarts = null
}
}
// 下面是 utils/utils 中 debounce 的相关代码
/**
* @param {Function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function () {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function (...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}
return result
}
}