vue-echarts的使用示例
前一个项目刚好用到的vue-echarts,但不是纯vue项目,现在这个项目刚好是纯前端vue项目,总结下使用的方法,避免以后忘记,也希望对大家有帮助。
有什么问题请给我留言,大家一起进步!
参考:技术文档
1. npm添加echarts和vue-echarts
我使用的是npm方式,如果不一样,可以百度下其他方式
npm install echarts -S // 添加 echarts
npm install echarts vue-echarts // 添加 vue-echarts
2. 在main.js中引入并注册
import ECharts from 'vue-echarts'
import 'echarts/lib/chart/line'
import 'echarts/lib/component/polar'
import 'echarts' // 去掉这个会没有动态效果
Vue.component('v-chart', ECharts)
3. 实列
1.autoresize属性默认为false,主要是设置图表跟页面一起自动缩放
2.下面是一个网上的实列,我稍微做点修改
<template>
<v-chart :options="polar" autoresize/>
</template>
<style>
.echarts {
width: 100%;
height: 100%;
}
</style>
<script>
// 组件的注册,放在的main.js中进行全局注册
// import ECharts from 'vue-echarts'
// import 'echarts/lib/chart/line'
// import 'echarts/lib/component/polar'
export default {
// components: {
// 'v-chart': ECharts
// },
data () {
let data = []
for (let i = 0; i <= 360; i++) {
let t = i / 180 * Math.PI
let r = Math.sin(2 * t) * Math.cos(2 * t)
data.push([r, i])
}
return {
polar: {
title: {
text: '极坐标双数值轴'
},
legend: {
data: ['line']
},
polar: {
center: ['50%', '54%']
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
angleAxis: {
type: 'value',
startAngle: 0
},
radiusAxis: {
min: 0
},
series: [
{
coordinateSystem: 'polar',
name: 'line',
type: 'line',
showSymbol: false,
data: data
}
],
animationDuration: 2000
}
}
}
}
</script>
- 这是我之前的代码, 因为不是纯前端项目,所以主要看看从后台获取数据和重新渲染图表部分就行,介绍几个重点方法,具体见代码
- var chart = this.$refs.chart // 通过句柄拿到图
- chart.hideLoading() // 加载动画
- chart.refresh(); // 刷新
- chart.mergeOptions(this.buildChartOption(res.data)) // 动态加载
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../static/css/muse-ui.css">
<link rel="stylesheet" href="../static/css/material-icons.css">
<script type="text/javascript" src='../static/plugins/echart/echarts.min.js'></script>
<script type="text/javascript" src='../static/plugins/vue/vue.min.js'></script>
<script src="../static/js/vue-echarts-4.0.2.js"></script>
<script src="../static/js/muse-ui.js"></script>
<script src="../static/js/muse-ui-message.js"></script>
<script src="../static/js/muse-ui-toast.js"></script>
<script src="../static/js/axios.min.js"></script>
<script type="text/javascript" src="../static/js/html2canvas.js"></script>
<script type="text/javascript" src="../static/js/jsPdf.debug.js"></script>
<style>
html,body{
height:100%;
width:100%;
overflow:hidden;
}
.title {
font-size: 1.55vw;
color: white
}
/*调整按钮样式*/
.mu-raised-button {
font-size: 0.8vw !important;
height: 2vw !important;
min-width: 2.5vw !important;
width:7vw !important;
}
.mu-raised-button .mu-button-wrapper {
padding: 0 0px !important;
}
.mu-input {
font-size: 0.8vw !important;
width: 16vw !important;
}
.mu-text-field-input {
height: 1.6vw !important;
}
</style>
</head>
<body>
<div id="app">
<mu-flex class="flex-wrapper" justify-content="center">
<mu-flex class="title" justify-content="center" >产品单耗分析</mu-flex>
</mu-flex>
<mu-flex class="flex-wrapper" justify-content="end">
<mu-date-input prefix="开始日期:" v-model="begin" format="YYYY年MM月DD日"></mu-date-input>
<mu-date-input prefix="结束日期:" v-model="end" format="YYYY年MM月DD日"></mu-date-input>
<mu-button style="margin-right: 0.5vw " @click="onQuery" color="primary">
<mu-icon size="20" value="search" ></mu-icon>查询
</mu-button>
<mu-button color="primary" style="margin-right: 0.5vw; text-align: center;" @click="exportPdf">
<mu-icon size="15" value="reply"></mu-icon>导出PDF
</mu-button>
</mu-flex>
<div style="width:100%" :style="{height: chartHeight + 'px'}">
<v-chart style="width:100%; height:100%" ref="chart" autoresize :options="chartOption" />
</div>
</div>
</body>
<script>
"use strict"
MuseUI.theme.use('dark')
var app = new Vue({
el: 'div#app',
components: {
'v-chart': VueECharts,
},
data: {
chartHeight: 600,
begin: (() => {
var curTime = new Date().getTime();
var startDate = curTime - (6 * 3600 * 24 * 1000);
return new Date(startDate);
})(),
end: new Date(),
chartOption: {
title: {
text: '产品单耗分析',
x: 'center',
textStyle: {
fontSize: 30,
fontWeight: 'bolder',
color: 'white'
},
},
grid: {
x: fontSize(2.5),
x2: fontSize(1)
},
tooltip: {
show: true,
trigger: 'axis'
},
legend: {},
toolbox: {
show: true,
backgroundColor: 'rgba(0,0,0,0)',
feature: {
mark: {
show: true
},
dataView: {
show: true,
readOnly: false
},
magicType: {
show: true,
type: ['line', 'bar']
},
restore: {
show: true
},
saveAsImage: {
show: true
}
}
},
calculable: true,
xAxis: {
type: 'category',
axisTick: {
inside: true,
show: false
},
axisLine:{
show:true,
lineStyle:{
color:'#696969', //更改坐标轴颜色
}
},
axisLabel: { //设置坐标轴字体
show:true,
rotate:45,
interval:'0',
textStyle:{
color:"white",
fontSize:fontSize(0.16)
}
}
},
yAxis: {
type: 'value',
axisTick: {
show:false
},
splitLine:{ //设置网格线型
show:true,
lineStyle:{
type:"solid",
color:"#696969",
}
},
axisLine:{
show:true,
lineStyle:{
color:'#696969', //更改坐标轴颜色
}
},
axisLabel: { //设置坐标轴字体
show:true,
interval:'0',
textStyle:{
color:"white",
fontSize:fontSize(0.16)
}
}
},
series: []
},
},
methods: {
buildChartOption(data) {
var series = [],
materials = {},
legend = {
data: [],
selected: {},
orient: 'vertical',
y: 'center',
x: '1%',
itemWidth: fontSize(0.18),
itemHeight: fontSize(0.10),
itemGap: fontSize(0.05),
textStyle: {
color: '#FFFFFF',
fontSize: fontSize(0.13)
}
};
for (var l of data) {
for (var u of l.usages) {
if (!materials[u.name]) {
var s = {
name: u.name,
type: 'bar',
smooth: true,
data: [],
itemStyle: {
normal: {
lineStyle: {
width: fontSize(0.05) //设置线的粗细
},
barBorderRadius: fontSize(0.06),
label : {
show: true,
position: 'inside',
formatter:function(params){
return params.valuel;
},
textStyle: {
fontSize: fontSize(0.12)
}
}
}
},
}
series.push(s)
materials[u.name] = s
legend.data.push({
name: u.name
})
legend.selected[u.name] = (u.name == '薄荷脑' || u.name == '樟脑' || u.name == '醋酸地塞米松')
}
}
}
for (var i = 0; i < data.length; i++) {
for (var s of series)
s.data.push(0)
for (var u of data[i].usages)
materials[u.name].data[i] = Math.round((data[i].production == 0 ? 0:u.amount / data[i].production) * 100) / 100;
}
return {
xAxis: {
data: data.map(l => l.lotId)
},
series: series,
legend: legend,
}
},
onQuery() {
var firstDay = this.begin.getFullYear() * 10000 + (this.begin.getMonth() + 1) * 100 + this.begin.getDate()
var lastDay = this.end.getFullYear() * 10000 + (this.end.getMonth() + 1) * 100 + this.end.getDate()
if( firstDay > lastDay ) {
this.$toast.error("开始日期必须早于结束日期。")
return;
}
var chart = this.$refs.chart
chart.showLoading({
text: '加载中,请稍侯...',
color: 'white',
textColor: 'white',
maskColor: 'rgba(0, 0, 0, 0)',
})
axios.get("lot/query-material-usage?firstDay=" + firstDay + "&lastDay=" + lastDay)
.then((res) => {
chart.hideLoading()
res = res.data
if (!res.success) {
this.$toast.error(res.meta.message)
return
}
chart.refresh();
chart.mergeOptions(this.buildChartOption(res.data))
})
.catch((err) => {
chart.hideLoading()
this.$toast.error("图表请求数据失败:" + err.message);
})
},
exportPdf() {
html2canvas(document.querySelector("#app"), {
onrendered:function(canvas) {
var pageData = canvas.toDataURL('image/jpeg', 1.0);
var pdf = new jsPDF('l', 'pt', [window.innerWidth, window.innerHeight]);
pdf.addImage(pageData, 'JPEG', 0, 0, window.innerWidth, window.innerHeight);
pdf.save('产品单耗分析.pdf');
}
})
}
},
mounted(){
var search = window.location.search
if(search) {
var params = search.replace('?','').split('&')
params.forEach(param=>{
if( param.substring(0,param.indexOf('=')) == 'begin' ) {
this.begin = new Date(param.substring(param.indexOf('=') + 1, param.length))
}else if( param.substring(0,param.indexOf('=')) == 'end' ){
this.end = new Date(param.substring(param.indexOf('=') + 1, param.length))
}
})
}
this.onQuery()
}
})
function fontSize(res) {
// const docEl = document.documentElement
const clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
if (!clientWidth) return
const fontSize = 100 * (clientWidth / 1920)
return res * fontSize
};
app.chartHeight = window.innerHeight - 130;
window.onresize = function(e) {
app.chartHeight = window.innerHeight - 130;
}
</script>
</html>