# 前言
v-charts
基于 Vue2.0 和 echarts 封装的 v-charts 图表组件,可轻松生成常见的图表
曾被 echarts 支配过的恐惧,之前查看文档找配置时让我头皮发麻
今天使用 v-charts
感觉还是记不清有哪些配置,于是就手动整理总结写个小栗子
# 起步
指定版本安装
npm i v-charts echarts@4.9.0 -S |
入口文件引入
// main.js | |
import Vue from 'vue' | |
import VCharts from 'v-charts' | |
import App from './App.vue' | |
Vue.use(VCharts) | |
new Vue({ | |
el: '#app', | |
render: h => h(App) | |
}) |
# 配置
extend:对已配置好的内部属性进行单独的设置
data:数据
colors:组件颜色数组
settings:settings
<ve-pie :extend="chartExtendPie"></ve-pie> | |
<ve-histogram :data="barData" :extend="chartExtendBar" :colors="colors" ></ve-histogram> | |
<ve-line :data="lineData" :settings="chartSettings" :extend="chartExtendLine" :colors="colors" ></ve-line> |
根据我的理解和个人习惯,常用 extend
而不用 settings
也可以只用 extend
属性来写原生 echarts 配置
# 图表数据
饼状图较为特殊
# 饼状图
饼状图会把 pieData.rows: [...]
中每一个元素作为图例
- 仅有一个要绘制的数据系列可以理解为数组
- 要绘制的数值没有负值
- 要绘制的数值几乎没有零值
- 类别数目无限制,展示的是分类的数据
- 各类别分别代表整个饼状图的一部分
- 各个部分需要标注百分比
所以,饼状图的数据格式有一点不同
pieData: { | |
columns: ['name', 'value'], | |
rows: [ | |
{ name: '设备', value: 30 }, | |
{ name: '企业', value: 28 }, | |
{ name: '房屋', value: 26 }, | |
{ name: '车辆', value: 24 }, | |
{ name: '人口', value: 22 } | |
] | |
} |
# 其他
折现和柱状图都是下面的数据格式
barData: { | |
columns: ['日期', '销售额'], | |
rows: [ | |
{ 日期: '1月1日', 销售额: 123 }, | |
{ 日期: '1月2日', 销售额: 1223 }, | |
{ 日期: '1月3日', 销售额: 2123 }, | |
{ 日期: '1月4日', 销售额: 4123 }, | |
{ 日期: '1月5日', 销售额: 3123 }, | |
{ 日期: '1月6日', 销售额: 7123 } | |
] | |
} |
# 图表更新
举个栗子,使用 data
属性定义的数据格式如下
barData: { | |
columns: ['日期', '访问用户'], | |
rows: [ | |
{ 日期: '2018-05-22', 访问用户: 32371 }, | |
{ 日期: '2018-05-23', 访问用户: 12328 }, | |
{ 日期: '2018-05-24', 访问用户: 62381 }, | |
{ 日期: '2018-05-25', 访问用户: 93381 }, | |
{ 日期: '2018-05-26', 访问用户: 52381 }, | |
{ 日期: '2018-05-27', 访问用户: 93281 }, | |
{ 日期: '2018-05-28', 访问用户: 45451 }, | |
{ 日期: '2018-05-29', 访问用户: 45881 }, | |
{ 日期: '2018-05-30', 访问用户: 67381 } | |
] | |
} |
当我们更新数据后,可以使用 this.barData
赋值来更新数据
但是如果只用 extend
属性通过赋值来更新数据那么可能无法渲染重绘图表
因为 Vue 响应式原理无法检测 property 的添加或移除
pieExt2: { | |
series: { | |
// data: [] | |
} | |
} | |
getwarning().then((res) => { | |
// 错误写法,如果 data 对象中定义了就可以这样写 | |
// this.pieExt2.series.data = [ | |
// {name: ' 人口 ', value: res.data.keyBuild}, | |
// {name: ' 房屋 ', value: res.data.keyPerson} | |
// ] | |
// 正确写法,this.$set (object, "propertyName", value) | |
this.$set(this.pieExt2.series, 'data', [ | |
{ name: '人口', value: res.data.keyBuild }, | |
{ name: '房屋', value: res.data.keyPerson } | |
]) | |
}) |
面向百度还会有另一种方法解决这个问题
echarts 通过 echartsInstance. setOption
设置图表实例的配置项以及数据,万能接口,所有参数和数据的修改都可以通过 setOption 完成,ECharts 会合并新的参数和数据,然后刷新图表。如果开启动画的话,ECharts 找到两组数据之间的差异然后通过合适的动画去表现数据的变化
v-charts 同样也有一个方法通过 after-set-option
动态设置数据
<ve-line :extend="lineExt" :after-set-option="getChart" ></ve-line> |
这是定义一个方法,需要在 methods 中声明,返回的是 echarts 实例
在 data 对象中定义 Echart 拿到,这样就可以使用 echarts 方法
getChart(data) { | |
this.Echart = data | |
} |
点击切换选项卡来更换数据
getMonth() { | |
this.isActive = 1 | |
let newOption = this.Echart.getOption() | |
// 这一步是设置 X 轴数据,需要注意:option.xAxis.data 这样不行 | |
newOption.xAxis[0].data = ['1点', '2点', '3点', '4点', '5点', '6点', '7点'] | |
newOption.series[0].data = [100, 144, 243, 382, 888, 699, 900] | |
this.Echart.setOption(newOption, true) | |
} |
封装一个函数
calc(res, str) { | |
let zk_nameArr = [], | |
zk_valueArr = [] | |
for (let i of res) { | |
zk_nameArr.push(i.date) | |
zk_valueArr.push(i.effectiveNum) | |
} | |
let newOption = this.Echart.getOption() | |
str === '日' ? (newOption.series[0].name = '日增量') : (newOption.series[0].name = '月增量') | |
newOption.xAxis[0].data = zk_nameArr | |
newOption.series[0].data = zk_valueArr | |
this.Echart.setOption(newOption, true) | |
} |
另一个项目某组件的部分 code
created() { | |
this.getClean() | |
}, | |
methods: { | |
async getClean() { | |
let params = { month: '0', operation: '采集', day: '0' } | |
let { data } = await getCleanAdd(params) | |
this.cleanData = data | |
let res = data.dayDate | |
this.calc(res, '日') | |
this.$emit('fn', this.cleanData.dayDateTotal) | |
}, | |
getChart(data) { | |
this.Echart = data | |
}, | |
getMonth() { | |
this.isActive = 1 | |
let res = this.cleanData.monthDate | |
this.calc(res, '月') | |
this.$emit('fn', this.cleanData.monthDateTotal) | |
}, | |
getDay() { | |
this.isActive = 0 | |
let res = this.cleanData.dayDate | |
this.calc(res, '日') | |
this.$emit('fn', this.cleanData.dayDateTotal) | |
}, | |
calc(){}, | |
} |
# 图表渐变
echarts 渐变色工具函数
import echarts from 'echarts' | |
//echarts 渐变 | |
export function gradient(s) { | |
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [ | |
{ offset: 1, color: s }, | |
{ offset: 0, color: hexToRGBA(s) } | |
]) | |
} | |
export function gradientTwo(s1, s2) { | |
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [ | |
{ offset: 1, color: s1 }, | |
{ offset: 0, color: s2 } | |
]) | |
} |
# 事件监听
我都不知道文档在说什么,太垃圾了
绑定事件通过传递一个事件名称和对应回调函数的对象实现,回调函数内的参数是 echarts 模块,可以据此做相应的处理。
<ve-pie :data="pieData" :events="clickEvents"></ve-pie> | |
<script> | |
export default { | |
data() { | |
let that = this | |
this.clickEvents = { | |
click: function(e) { | |
that.chartClicked(e) | |
} | |
} | |
return { ... } | |
}, | |
methods: { | |
chartClicked(e) { | |
console.log(e) | |
} | |
} | |
} | |
</script> |
还有一种方法,我更倾向使用这种
<ve-pie :data="pieData" :after-set-option="getChart"></ve-pie> |
后续需要注意 this 指向
methods: { | |
getChart(data) { | |
const that = this | |
this.Echart = data | |
this.Echart.on('click', function(arg) { | |
console.log(arg); | |
}) | |
} | |
} |
# 小结
最后奉上地址,方便日后 ctrlCV