柱状图多维条形图vue_Vue组件(1)使用Echarts绘制图表-柱状图/折线图

前言

​ 最近工作中需要做一个自动配置报表的功能,需求目的是可以通过配置来适应产品对于报表需求的变更,不用重复更改代码。

配置实现流程如下:配置报表所需的数据源

选择筛选报表数据的参数

生成报表页面

生成展示页面(生成的报表通过选择放入展示页面)

项目是通过前后端分离实现的,前端框架是Vue,配合Echart绘制相关图表,因为我也是第一次尝试写前端组件,所以这里写下文章记录下。

特别提示:这里的组件不是通过webpack打包生成的插件,而是放在src/components文件夹下的组件

生成vue项目

这里通过vue-cli工具初始化一个项目,开始这里,默认你都已经安装好vue相关环境以及工具,如果没有,请自行百度vue环境搭建教程

初始化项目

新建一个存放新项目的文件夹,例如我这里在d盘下建了一个名为VueAndEcharts的文件夹

在上图中的地址框中直接输入cmd,则在当前路径下打开cmd.exe

在上图中输入初始化项目的命令:vue init webpack vue_project(最后这个是我创建的项目文件夹的名字),具体操作如下图:

上面依次的步骤会让你输入:项目名称:我这里输入echartsdemo

项目描述:this is a vue/echart demo

项目作者:martin

安装vue-route:选yes即可

安装eslint到你的代码,这个是检查代码格式的,选yes即可

后面的几个我暂时没管他,都选了no,不停回车,项目就创建成功了

生成成功后项目结构如下:

切换到项目根目录下,我这里是cd vueEchartsForReport 然后在在命令提示符中输入:npm i 此步骤安装vue项目需要的相关依赖包,(这一步也可以省略,直接输入npm run dev,也会安装相关依赖包)这部分依赖包在项目根目录下的package.json中可以看到,

再输入:npm run dev,就可以启动项目了,

上图代表已经启动项目成功,在浏览器输入http://localhost:8080就可以看到项目helloworld页面了

组件开发

在项目src/components文件夹下新建一个vue文件,

因为是一个demo,所以我这里命名为bardemo.vue,

1.模板文件代码

以上代码是为绘制图表准备一个具备高宽的 DOM 容器,具体明细可参考echarts官方文档,传送门:echarts官方文档

2.安装echarts插件

在项目根目录下,输入命令:npm install echarts --save,安装成功后,在bardemo.vue文件中引入

let echarts = require('echarts')

import _ from 'lodash'

我这里因为要使用lodash工具库的方法,所以这里也安装了lodash工具库,输入命令: npm install lodash --save即可安装,导入loadsh如上图:import _ from 'lodash'

export default {

name: 'bar-report',

props: {

data: {

required: true, // 若是横轴,则此部分为x轴"数值"数据,若为纵轴,则此部分为y轴"数值"数据,此部分数据必传 type: Object

},

title: {

type: Object | String // 标题,可以只传入标题,其他属性使用默认值,也可自定义title属性,默认无标题 },

theme: {

type: String // dom参数属性,传入theme字符串,theme暂时支持dark和light两种,默认light },

width: String, // dom的宽度,默认600 height: String, // dom的高度,默认400 barType: {

type: String // 柱状图类型/值为xAxis则显示横轴柱状图,值为yAxis则为纵轴柱状图,默认是yAxis },

category: {

required: true, // 图表分类,如是纵轴,则是x轴的值 type: Object

},

legend: {

required: true, // 必传,图表上方标识每个颜色柱/线代表什么意思 type: Array

},

dataView: {

type: Boolean // 是否显示数据视图功能,默认不开启 },

magicType: {

type: Array | String // 是否显示图表之间切换显示功能,默认不开启 },

restore: {

type: Boolean // 是否显示图表还原功能,默认不开启 },

saveAsImage: {

type: Boolean // 是否显示图表图表保存为图片功能,默认不开启 },

stack: {

type: String // 柱状图是否堆叠属性,默认不堆叠 },

seriesType: {

type: String // 控制是绘制柱状图,还是绘制折线图,”bar“:柱状图,”line“:折线图 }

},

data () {

// 默认title属性 let baseTitle = {

text: '', // 主标题 subtext: '', // 副标题 left: 'left', // 标题位置:left,center,right textStyle: {

// 文字颜色 color: '#000000',

// 字体风格,'normal','italic','oblique' fontStyle: 'normal',

// 字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400... fontWeight: 'bold',

// 字体系列 fontFamily: 'sans-serif',

// 字体大小 fontSize: 18

}

}

// 如果传入了title的值,则判断处理后重新赋值给baseTitle const tempTitle = this.title

if (tempTitle) {

debugger

if (typeof (tempTitle) === 'string') {

baseTitle.text = tempTitle

} else if (typeof (tempTitle) === 'object') {

if (tempTitle.text) {

baseTitle.text = tempTitle.text

}

if (tempTitle.subtext) {

baseTitle.subtext = tempTitle.subtext

}

if (tempTitle.left) {

baseTitle.left = tempTitle.left

}

if (tempTitle.textStyle) {

// 标题字体颜色 if (tempTitle.textStyle.color) {

baseTitle.textStyle.color = tempTitle.textStyle.color

}

// 字体风格,'normal','italic','oblique' if (tempTitle.textStyle.fontStyle) {

baseTitle.textStyle.fontStyle = tempTitle.textStyle.fontStyle

}

// 字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400... if (tempTitle.textStyle.fontWeight) {

baseTitle.textStyle.fontWeight = tempTitle.textStyle.fontWeight

}

// 字体系列 if (tempTitle.textStyle.fontFamily) {

baseTitle.textStyle.fontFamily = tempTitle.textStyle.fontFamily

}

// 字体大小 if (tempTitle.textStyle.fontSize) {

baseTitle.textStyle.fontSize = tempTitle.textStyle.fontSize

}

}

}

}

// 默认dom属性 let baseDom = {

theme: 'light',

renderer: 'canvas',

opts: {

width: 600,

height: 400

}

}

// 判断处理是否传入dom属性值 if (this.theme) {

baseDom.theme = this.theme

}

if (this.width) {

baseDom.opts.width = parseInt(this.width)

}

if (this.height) {

baseDom.opts.height = parseInt(this.height)

}

let baseType = 'yAxis'

if (this.barType) {

baseType = this.barType

}

// 默认toolbox值 var baseToolbox = {

show: false,

feature: {

mark: {show: true},

dataView: {show: false, readOnly: false}, // 数据视图 magicType: {show: false, type: []}, // 切换为折线图/柱状图 restore: {show: false}, // 还原 saveAsImage: {show: false} // 保存为图片 }

}

// 判断处理传入toolbox属性值 if (this.dataView) {

baseToolbox.show = true

baseToolbox.feature.dataView.show = true

}

if (this.magicType) {

baseToolbox.show = true

baseToolbox.feature.magicType.show = true

if (typeof (this.magicType) === 'string') {

baseToolbox.feature.magicType.type = [this.magicType]

} else {

baseToolbox.feature.magicType.type = this.magicType

}

}

if (this.restore) {

baseToolbox.show = true

baseToolbox.feature.restore.show = true

}

if (this.saveAsImage) {

baseToolbox.show = true

baseToolbox.feature.saveAsImage.show = true

}

return {

titleProperty: baseTitle, // title属性值 domProperty: baseDom, // dom属性值 type: baseType, // 图表横纵类型 toolboxProperty: baseToolbox// toolbox属性 }

},

// 页面加载 mounted () {

this.setEchart()

},

methods: {

// 绘制图表方法 setEchart () {

const _this = this

let domInit = this.$refs.mychart

this.myChart = echarts.init(domInit, _this.domProperty.theme, {width: _this.domProperty.opts.width, height: _this.domProperty.opts.height})

// 指定图表的配置项和数据 let option = {

title: {

text: _this.titleProperty.text,

subtext: _this.titleProperty.subtext,

left: _this.titleProperty.left,

textStyle: _this.titleProperty.textStyle

},

tooltip: {

trigger: 'axis'

},

toolbox: this.toolboxProperty,

legend: {

data: this.legend

},

series: [

]

}

// 判断传入图表类型是横轴图表还是纵轴图表 if (this.type === 'xAxis') {

const tempx = {

type: 'value'

}

option.xAxis = tempx

option.yAxis = this.category

} else if (this.type === 'yAxis') {

const tempy = {

type: 'value'

}

option.yAxis = tempy

option.xAxis = this.category

}

// series数据赋值并判断是否是堆叠图表 const seriesData = this.data

if (seriesData) {

_.forEach(this.legend, function (value) {

var myBarData = _.get(seriesData, value)

console.log(value)

if (_.hasIn(seriesData, value)) {

var tempSeries = {

name: value,

type: _this.seriesType,

data: myBarData

}

if (_this.stack) {

tempSeries.stack = _this.stack

}

option.series.push(tempSeries)

}

})

}

this.myChart.setOption(option)

}

}

}

上面三个代码片段在一起,就是这个测试demo的全部组件,具体实现,请看代码注释,下面说说在其他页面如何使用该组件

4.组件的使用

打开hellowork.vue文件,删除

内的所有代码,在其中加入下面代码:

:data="barData"

:category="categoryData"

:legend="legendData">

import barEcharts from './bardemo' //导入组件export default {

name: 'HelloWorld',

data () {

return {

// 图表数据 barData: {

'2011': [18203, 23489, 29034, 104970, 131744, 630230],

'2012': [19325, 23438, 31000, 121594, 134141, 681807]

},

focusType: 1,

//定义组件,在上面用:is使用,不需要components注册 currentView: barEcharts,

categoryData: {

data: ['巴西', '印尼', '美国', '印度', '中国', '世界人口(万)']

},

legendData: ['2011', '2012'],

}

}

}

上图是最基本使用,上图三个是必传的三个参数:保存文件,刷新页面后如下图:

下面我们加上标题,并且将表格展示区放大一点

修改为上面代码后,绘制的表格如下:

可看出图表多出了标题,并且宽度明显拉长了

如果我们需要修改标题颜色和字体,则需要传入一个json对象,具体实现如下:

:data="barData"

:title="echarttitle"

width="1000"

height="400"

:category="categoryData"

:legend="legendData">

import barEcharts from './bardemo' //导入组件export default {

name: 'HelloWorld',

data () {

return {

// 图表数据 barData: {

'2011': [18203, 23489, 29034, 104970, 131744, 630230],

'2012': [19325, 23438, 31000, 121594, 134141, 681807]

},

focusType: 1,

//定义组件,在上面用:is使用,不需要components注册 currentView: barEcharts,

categoryData: {

data: ['巴西', '印尼', '美国', '印度', '中国', '世界人口(万)']

},

legendData: ['2011', '2012'],

echarttitle: {

text: '世界人口总量',

left: 'right',

textStyle: {

color: '#FF0000',

// 字体大小 fontSize: 20 // 默认大小是18 }

}

}

}

}

上面代码将图表标题字体颜色设置为红色,并修改字体大小为20,位置为靠右,展示结果如下图:

还可以设置字体的风格、字体的粗细、字体系列等样式:具体配置如下

import barEcharts from './bardemo' // 导入组件export default {

name: 'HelloWorld',

data () {

return {

// 图表数据 barData: {

'2011': [18203, 23489, 29034, 104970, 131744, 630230],

'2012': [19325, 23438, 31000, 121594, 134141, 681807]

},

focusType: 1,

// 定义组件,在上面用:is使用,不需要components注册 currentView: barEcharts,

categoryData: {

data: ['巴西', '印尼', '美国', '印度', '中国', '世界人口(万)']

},

legendData: ['2011', '2012'],

echarttitle: {

text: '世界人口总量',

left: 'right',

textStyle: {

color: '#FF0000',

// 字体风格,'normal','italic','oblique' fontStyle: 'normal',

// 字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400... fontWeight: 'bold',

// 字体系列 fontFamily: 'sans-serif',

// 字体大小 fontSize: 18

}

}

}

}

}

下面我们开启数据视图、折线图/柱状图切换、还原、保存图表为图片:

组件代码修改为如下,新增了四个prop属性赋值:dataView、magicType、restore、saveAsImage

:data="barData"

:title="echarttitle"

width="1000"

height="400"

:category="categoryData"

:legend="legendData"

:dataView="openMagicType"

:magicType="openMagicType"

:restore="openRestore"

:saveAsImage="openSaveAsImage">

定义数据代码如下:

import barEcharts from './bardemo' // 导入组件export default {

name: 'HelloWorld',

data () {

return {

// 图表数据 barData: {

'2011': [18203, 23489, 29034, 104970, 131744, 630230],

'2012': [19325, 23438, 31000, 121594, 134141, 681807]

},

focusType: 1,

// 定义组件,在上面用:is使用,不需要components注册 currentView: barEcharts,

categoryData: {

data: ['巴西', '印尼', '美国', '印度', '中国', '世界人口(万)']

},

legendData: ['2011', '2012'],

echarttitle: {

text: '世界人口总量',

left: 'left',

textStyle: {

color: '#FF0000',

// 字体风格,'normal','italic','oblique' fontStyle: 'normal',

// 字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400... fontWeight: 'bold',

// 字体系列 fontFamily: 'sans-serif',

// 字体大小 fontSize: 18

}

},

openDataView: true, // dataView openMagicType: 'line', // magicType可以是字符串,也可以是字符串数组,例如传入['bar','line']就是可以切换为折线图和柱状图 openRestore: true, // restore openSaveAsImage: true // saveAsImage }

}

}

运行结果展示:

点击数据视图:

点击切换为折线图:

点击还原:上面的折线图又切换回柱状图

点击保存为图片:下载一张当前图表的图片

也可以设置柱状图使用堆叠模式展示,堆叠模式需要设置stack属性,设置stack=“总量”,则会展示堆叠的柱状图:

:data="barData"

:title="echarttitle"

width="1000"

height="400"

:category="categoryData"

:legend="legendData"

:dataView="openMagicType"

:magicType="openMagicType"

:restore="openRestore"

:saveAsImage="openSaveAsImage"

stack="总量"

seriesType="bar">

保存展示结果如下:

如果要使用该组件默认绘制折线图,则需要设置stack属性,这里stack属性默认是柱状图,设置seriesType=“line”,则会绘制折线图

:data="barData"

:title="echarttitle"

width="1000"

height="400"

:category="categoryData"

:legend="legendData"

:dataView="openMagicType"

:magicType="openMagicType"

:restore="openRestore"

:saveAsImage="openSaveAsImage"

seriesType="line">

保存后页面刷新如下:

你可能感兴趣的:(柱状图多维条形图vue)