vue echarts图表组建封装,实现折线图饼图联动
基于vue封装的柱状图,饼图,条形图,以及折线图饼图联动
效果展示
详细代码如下
折线图组件
<template> <div :class="className" :style="{height:height,width}" /> </template> <script> import echarts from 'echarts' require('echarts/theme/macarons') // echarts theme import resize from './mixins/resize' export default { mixins: [resize], props: { className: { type: String, default: 'chart' }, { type: String, default: '100%' }, height: { type: String, default: '350px' }, autoResize: { type: Boolean, default: true }, chartData: { type: Object, required: true } }, data() { return { chart: null } }, watch: { chartData: { deep: true, handler(val) { this.setOptions(val) } } }, mounted() { this.$nextTick(() => { this.initChart() }) }, beforeDestroy() { if (!this.chart) { return } this.chart.dispose() this.chart = null }, methods: { initChart() { this.chart = echarts.init(this.$el, 'macarons') this.setOptions(this.chartData) }, setOptions({ expectedData, actualData } = {}) { this.chart.setOption({ xAxis: { data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], boundaryGap: false, axisTick: { show: false } }, grid: { left: 10, right: 10, bottom: 20, top: 30, containLabel: true }, tooltip: { trigger: 'axis', axisPointer: { type: 'cross' }, padding: [5, 10] }, yAxis: { axisTick: { show: false } }, legend: { data: ['expected', 'actual'] }, series: [{ name: 'expected', itemStyle: { normal: { color: '#FF005A', lineStyle: { color: '#FF005A', 2 } } }, smooth: true, type: 'line', data: expectedData, animationDuration: 2800, animationEasing: 'cubicInOut' }, { name: 'actual', smooth: true, type: 'line', itemStyle: { normal: { color: '#3888fa', lineStyle: { color: '#3888fa', 2 }, areaStyle: { color: '#f3f8ff' } } }, data: actualData, animationDuration: 2800, animationEasing: 'quadraticOut' }] }) } } } </script>
面板组件
<template> <el-row :gutter="40" class="panel-group"> <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> <div class="card-panel" @click="handleSetLineChartData('newVisitis')"> <div class="card-panel-icon-wrapper icon-people"> <svg-icon icon-class="peoples" class-name="card-panel-icon" /> </div> <div class="card-panel-description"> <div class="card-panel-text"> New Visits </div> <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" /> </div> </div> </el-col> <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> <div class="card-panel" @click="handleSetLineChartData('messages')"> <div class="card-panel-icon-wrapper icon-message"> <svg-icon icon-class="message" class-name="card-panel-icon" /> </div> <div class="card-panel-description"> <div class="card-panel-text"> Messages </div> <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" /> </div> </div> </el-col> <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> <div class="card-panel" @click="handleSetLineChartData('start')"> <div class="card-panel-icon-wrapper icon-money"> <svg-icon icon-class="star" class-name="card-panel-icon" /> </div> <div class="card-panel-description"> <div class="card-panel-text"> Purchases </div> <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" /> </div> </div> </el-col> <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> <div class="card-panel" @click="handleSetLineChartData('zip')"> <div class="card-panel-icon-wrapper icon-money"> <svg-icon icon-class="zip" class-name="card-panel-icon" /> </div> <div class="card-panel-description"> <div class="card-panel-text"> Purchases </div> <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" /> </div> </div> </el-col> </el-row> </template> <script> import CountTo from 'vue-count-to' export default { components: { CountTo }, methods: { handleSetLineChartData(type) { this.$emit('handleSetLineChartData', type) } } } </script> <style lang="scss" scoped> .panel-group { margin-top: 18px; .card-panel-col { margin-bottom: 32px; } .card-panel { height: 108px; cursor: pointer; font-size: 12px; position: relative; overflow: hidden; color: #666; background: #fff; box-shadow: 4px 4px 40px rgba(0, 0, 0, .05); border-color: rgba(0, 0, 0, .05); &:hover { .card-panel-icon-wrapper { color: #fff; } .icon-people { background: #40c9c6; } .icon-message { background: #36a3f7; } .icon-money { background: #f4516c; } .icon-shopping { background: #34bfa3 } } .icon-people { color: #40c9c6; } .icon-message { color: #36a3f7; } .icon-money { color: #f4516c; } .icon-shopping { color: #34bfa3 } .card-panel-icon-wrapper { float: left; margin: 14px 0 0 14px; padding: 16px; transition: all 0.38s ease-out; border-radius: 6px; } .card-panel-icon { float: left; font-size: 48px; } .card-panel-description { float: right; font-weight: bold; margin: 26px; margin-left: 0px; .card-panel-text { line-height: 18px; color: rgba(0, 0, 0, 0.45); font-size: 16px; margin-bottom: 12px; } .card-panel-num { font-size: 20px; } } } } @media (max-550px) { .card-panel-description { display: none; } .card-panel-icon-wrapper { float: none !important; width: 100%; height: 100%; margin: 0 !important; .svg-icon { display: block; margin: 14px auto !important; float: none !important; } } } </style>