vue3 echarts多图自适应封装
vue3使用echarts。一个页面多个echarts。自适应
·
npm install echarts -S
封装echarts插件
src/components/echarts.vue
<template>
<div :id="echartsDomId"></div>
</template>
<script>
import * as echarts from 'echarts';
import {EleResize} from "@/assets/js/esresize";
import {watch, onMounted, ref,onUnmounted} from 'vue';
export default {
name: "rxp-echarts",
props: {
option: {
type: Object,
required: true,
}
},
setup(props) {
//存储echarts的实例
var instance = null;
// 监听props是否改变
watch(props, (newValue, oldValue) => {
instance.dispose(); //先销毁
init(); //再创建好了
//重绘不生效啊
// instance.setOption(newValue);
},{deep:true})
//计算属性 自动分配echarts的ID 。防止一个页面的echarts出现相同id
const echartsDomId = 'echarts' + Math.random() * 100000;
function init() {
instance = echarts.init(document.getElementById(echartsDomId));
instance.setOption(props.option); //设置option
//添加监听事件,如果页面宽度和高度变化, 重新绘制echarts
EleResize.on(document.getElementById(echartsDomId), () => {
instance.resize();
})
}
//组件一旦挂载,运行echarts初始化
onMounted(() =>init());
//组件卸载,销毁echarts实例
onUnmounted(()=>instance.dispose());
/**
* 父节点通过ref拿到此组件的实例,调用downloadPic函数,触发图片下载。
*/
const downloadPic = (name)=>{
let content = instance.getDataURL(); // 这个方法是经过封装之后的,id就是我们最终经过init(),setOptions的echart图表,它具有getDataURL()方法
let aLink = document.createElement('a');
let blob = base64ToBlob(content);
let evt = document.createEvent("HTMLEvents");
evt.initEvent("click", true, true);
aLink.download = `${name}.png`;
aLink.href = URL.createObjectURL(blob);
aLink.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
}
function base64ToBlob(code) {
let parts = code.split(';base64,');
let contentType = parts[0].split(':')[1];
let raw = window.atob(parts[1]);
let rawLength = raw.length;
let uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
return {
echartsDomId,
//父节点通过ref拿到此组件的实例,调用downloadPic函数,触发图片下载。
downloadPic
}
}
}
</script>
<style scoped>
div{
width: 100%;
height: 100%;
}
</style>
再封装监听窗口变化触发方法
src/assets/js/esresize.js
//EleResize('domId',回调函数)
//echarts resize
var EleResize = {
_handleResize: function (e) {
var ele = e.target || e.srcElement
var trigger = ele.__resizeTrigger__
if (trigger) {
var handlers = trigger.__z_resizeListeners
if (handlers) {
var size = handlers.length
for (var i = 0; i < size; i++) {
var h = handlers[i]
var handler = h.handler
var context = h.context
handler.apply(context, [e])
}
}
}
},
_removeHandler: function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (handlers) {
var size = handlers.length
for (var i = 0; i < size; i++) {
var h = handlers[i]
if (h.handler === handler && h.context === context) {
handlers.splice(i, 1)
return
}
}
}
},
_createResizeTrigger: function (ele) {
var obj = document.createElement('object')
obj.setAttribute('style',
'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden;opacity: 0; pointer-events: none; z-index: -1;')
obj.onload = EleResize._handleObjectLoad
obj.type = 'text/html'
ele.appendChild(obj)
obj.data = 'about:blank'
return obj
},
_handleObjectLoad: function () {
this.contentDocument.defaultView.__resizeTrigger__ = this.__resizeElement__
this.contentDocument.defaultView.addEventListener('resize', EleResize._handleResize)
}
}
if (document.attachEvent) { // ie9-10
EleResize.on = function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (!handlers) {
handlers = []
ele.__z_resizeListeners = handlers
ele.__resizeTrigger__ = ele
ele.attachEvent('onresize', EleResize._handleResize)
}
handlers.push({
handler: handler,
context: context
})
}
EleResize.off = function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (handlers) {
EleResize._removeHandler(ele, handler, context)
if (handlers.length === 0) {
ele.detachEvent('onresize', EleResize._handleResize)
delete ele.__z_resizeListeners
}
}
}
} else {
EleResize.on = function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (!handlers) {
handlers = []
ele.__z_resizeListeners = handlers
if (getComputedStyle(ele, null).position === 'static') {
ele.style.position = 'relative'
}
var obj = EleResize._createResizeTrigger(ele)
ele.__resizeTrigger__ = obj
obj.__resizeElement__ = ele
}
handlers.push({
handler: handler,
context: context
})
}
EleResize.off = function (ele, handler, context) {
var handlers = ele.__z_resizeListeners
if (handlers) {
EleResize._removeHandler(ele, handler, context)
if (handlers.length === 0) {
var trigger = ele.__resizeTrigger__
if (trigger) {
trigger.contentDocument.defaultView.removeEventListener('resize', EleResize._handleResize)
ele.removeChild(trigger)
delete ele.__resizeTrigger__
}
delete ele.__z_resizeListeners
}
}
}
}
export {EleResize}
使用echarts (vue2搬来的,vue3使用同理)
<template>
<div style="width: 100%;height: 100%;">
<div style="width: 80%;height: 70%;background-color: #888888">
<!--
注意:option是echarts的配置选项,
在为空时,不要初始化组件,所以添加v-if判断option的值存在
-->
<echarts v-if="config && flag" :option="config"></echarts>
</div>
<button @click="flag=!flag">隐藏echarts</button>
<button @click="update">修改option参数</button>
<button @click="upData">修改option中的数组</button>
</div>
</template>
<script>
import echarts from "@/components/echarts";
export default {
name: "helloWord",
components:{echarts},
data() {
return {
config:null, //echarts中的配置参数
flag:true, //手动切换是否隐藏
}
},
created() {
this.reset();
},
methods:{
reset(){
setTimeout(()=>{
this.config={
title: {
text: "我是初始化数据",
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [500, 230, 224, 218, 135, 147, 260],
type: 'line'
}
]
}
},2000)
},
update(){
this.config={
title: {
text: "我是修改后的数据",
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [ //随机数据
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
],
type: 'line'
}
]
}
},
upData(){
this.config.series={
data: [ //随机数据
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
parseInt(Math.random()*100),
],
type: 'line'
}
}
}
}
</script>
<style scoped>
</style>
``
vue echarts多图自适应封装
更多推荐
所有评论(0)