| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 | 
							- <template>
 
- 	<view class="lime-echart" :style="customStyle" v-if="canvasId" ref="limeEchart" :aria-label="ariaLabel">
 
- 		<!-- #ifndef APP-NVUE -->
 
- 		<canvas
 
- 			class="lime-echart__canvas"
 
- 			v-if="use2dCanvas"
 
- 			type="2d"
 
- 			:id="canvasId"
 
- 			:style="canvasStyle"
 
- 			:disable-scroll="isDisableScroll"
 
- 			@touchstart="touchStart"
 
- 			@touchmove="touchMove"
 
- 			@touchend="touchEnd"
 
- 		/>
 
- 		<canvas
 
- 			class="lime-echart__canvas"
 
- 			v-else-if="isPc"
 
- 			:style="canvasStyle"
 
- 			:id="canvasId"
 
- 			:canvas-id="canvasId"
 
- 			:disable-scroll="isDisableScroll"
 
- 			@mousedown="touchStart"
 
- 			@mousemove="touchMove"
 
- 			@mouseup="touchEnd"
 
- 		/>
 
- 		<canvas
 
- 			class="lime-echart__canvas"
 
- 			v-else
 
- 			:width="nodeWidth"
 
- 			:height="nodeHeight"
 
- 			:style="canvasStyle"
 
- 			:canvas-id="canvasId"
 
- 			:id="canvasId"
 
- 			:disable-scroll="isDisableScroll"
 
- 			@touchstart="touchStart"
 
- 			@touchmove="touchMove"
 
- 			@touchend="touchEnd"
 
- 		/>
 
- 		<canvas v-if="isOffscreenCanvas" :style="offscreenStyle" :canvas-id="offscreenCanvasId"></canvas>
 
- 		<!-- #endif -->
 
- 		<!-- #ifdef APP-NVUE -->
 
- 		<web-view
 
- 			class="lime-echart__canvas"
 
- 			:id="canvasId"
 
- 			:style="canvasStyle"
 
- 			:webview-styles="webviewStyles"
 
- 			ref="webview"
 
- 			src="/uni_modules/lime-echart/static/index.html"
 
- 			@pagefinish="finished = true"
 
- 			@onPostMessage="onMessage"
 
- 		></web-view>
 
- 		<!-- #endif -->
 
- 	</view>
 
- </template>
 
- <script>
 
- // #ifdef VUE3
 
- // #ifdef APP-PLUS
 
- global = {}
 
- // #endif
 
- // #endif
 
- // #ifndef APP-NVUE
 
- import {Canvas, setCanvasCreator, dispatch} from './canvas';
 
- import {wrapTouch, devicePixelRatio ,sleep, canIUseCanvas2d, getRect} from './utils';
 
- // #endif
 
- // #ifdef APP-NVUE
 
- import { base64ToPath, sleep } from './utils';
 
- import {Echarts} from './nvue'
 
- // #endif
 
- const charts = {}
 
- const echartsObj = {}
 
- export default {
 
- 	name: 'lime-echart',
 
- 	props: {
 
- 		// #ifdef MP-WEIXIN || MP-TOUTIAO
 
- 		type: {
 
- 			type: String,
 
- 			default: '2d'
 
- 		},
 
- 		// #endif
 
- 		// #ifdef APP-NVUE
 
- 		webviewStyles: Object,
 
- 		// hybrid: Boolean,
 
- 		// #endif
 
- 		customStyle: String,
 
- 		isDisableScroll: Boolean,
 
- 		isClickable: {
 
- 			type: Boolean,
 
- 			default: true
 
- 		},
 
- 		enableHover: Boolean,
 
- 		beforeDelay: {
 
- 			type: Number,
 
- 			default: 30
 
- 		}
 
- 	},
 
- 	data() {
 
- 		return {
 
- 			// #ifdef MP-WEIXIN || MP-TOUTIAO || MP-ALIPAY
 
- 			use2dCanvas: true,
 
- 			// #endif
 
- 			// #ifndef MP-WEIXIN || MP-TOUTIAO || MP-ALIPAY
 
- 			use2dCanvas: false,
 
- 			// #endif
 
- 			ariaLabel: '图表',
 
- 			width: null,
 
- 			height: null,
 
- 			nodeWidth: null,
 
- 			nodeHeight: null,
 
- 			// canvasNode: null,
 
- 			config: {},
 
- 			inited: false,
 
- 			finished: false,
 
- 			file: '',
 
- 			platform: '',
 
- 			isPc: false,
 
- 			isDown: false,
 
- 			isOffscreenCanvas: false,
 
- 			offscreenWidth: 0,
 
- 			offscreenHeight: 0
 
- 		};
 
- 	},
 
- 	computed: {
 
- 		canvasId() {
 
- 			return `lime-echart${this._ && this._.uid || this._uid}`
 
- 		},
 
- 		offscreenCanvasId() {
 
- 			return `${this.canvasId}_offscreen`
 
- 		},
 
- 		offscreenStyle() {
 
- 			return `width:${this.offscreenWidth}px;height: ${this.offscreenHeight}px; position: fixed; left: 99999px; background: red`
 
- 		},
 
- 		canvasStyle() {
 
- 			return  this.width && this.height ? ('width:' + this.width + 'px;height:' + this.height + 'px') : ''
 
- 		}
 
- 	},
 
- 	// #ifndef VUE3
 
- 	beforeDestroy() {
 
- 		this.clear()
 
- 		this.dispose()
 
- 		// #ifdef H5
 
- 		if(this.isPc) {
 
- 			document.removeEventListener('mousewheel', this.mousewheel)
 
- 		}
 
- 		// #endif
 
- 	},
 
- 	// #endif
 
- 	// #ifdef VUE3
 
- 	unmounted() {
 
- 		this.clear()
 
- 		this.dispose()
 
- 		// #ifdef H5
 
- 		if(this.isPc) {
 
- 			document.removeEventListener('mousewheel', this.mousewheel)
 
- 		}
 
- 		// #endif
 
- 	},
 
- 	// #endif
 
- 	created() {
 
- 		// #ifdef H5
 
- 		if(!('ontouchstart' in window)) {
 
- 			this.isPc = true
 
- 			document.addEventListener('mousewheel', this.mousewheel)
 
- 		}
 
- 		// #endif
 
- 		// #ifdef MP-WEIXIN || MP-TOUTIAO || MP-ALIPAY
 
- 		const { platform } = uni.getSystemInfoSync();
 
- 		this.isPC = /windows/i.test(platform)
 
- 		// #endif
 
- 		this.use2dCanvas = this.type === '2d' && canIUseCanvas2d()
 
- 	},
 
- 	mounted() {
 
- 		this.$nextTick(() => {
 
- 			this.$emit('finished')
 
- 		})
 
- 	},
 
- 	methods: {
 
- 		// #ifdef APP-NVUE
 
- 		onMessage(e) {
 
- 			const res = e?.detail?.data[0] || null;
 
- 			if (res?.event) {
 
- 				if(res.event === 'inited') {
 
- 					this.inited = true
 
- 				}
 
- 				this.$emit(res.event, JSON.parse(res.data));
 
- 			} else if(res?.file){
 
- 				this.file = res.data
 
- 			} else if(!res[0] && JSON.stringify(res[0]) != '{}'){
 
- 				console.error(res);
 
- 			} else {
 
- 				console.log(...res)
 
- 			}
 
- 		},
 
- 		// #endif
 
- 		setChart(callback) {
 
- 			if(!this.chart) {
 
- 				console.warn(`组件还未初始化,请先使用 init`)
 
- 				return
 
- 			}
 
- 			if(typeof callback === 'function' && this.chart) {
 
- 				callback(this.chart);
 
- 			}
 
- 			// #ifdef APP-NVUE
 
- 			if(typeof callback === 'function') {
 
- 				this.$refs.webview.evalJs(`setChart(${JSON.stringify(callback.toString())}, ${JSON.stringify(this.chart.options)})`);
 
- 			}
 
- 			// #endif
 
- 		},
 
- 		setOption() {
 
- 			if (!this.chart || !this.chart.setOption) {
 
- 				console.warn(`组件还未初始化,请先使用 init`)
 
- 				return
 
- 			}
 
- 			this.chart.setOption(...arguments);
 
- 		},
 
- 		showLoading() {
 
- 			if(this.chart) {
 
- 				this.chart.showLoading(...arguments)
 
- 			}
 
- 		},
 
- 		hideLoading() {
 
- 			if(this.chart) {
 
- 				this.chart.hideLoading()
 
- 			}
 
- 		},
 
- 		clear() {
 
- 			if(this.chart) {
 
- 				this.chart.clear()
 
- 			}
 
- 		},
 
- 		dispose() {
 
- 			if(this.chart) {
 
- 				this.chart.dispose()
 
- 			}
 
- 		},
 
- 		resize(size) {
 
- 			if(size && size.width && size.height) {
 
- 				this.height = size.height
 
- 				this.width = size.width
 
- 				if(this.chart) {this.chart.resize(size)}
 
- 			} else {
 
- 				this.$nextTick(() => {
 
- 					uni.createSelectorQuery()
 
- 						.in(this)
 
- 						.select(`.lime-echart`)
 
- 						.boundingClientRect()
 
- 						.exec(res => {
 
- 							if (res) {
 
- 								let { width, height } = res[0];
 
- 								this.width = width = width || 300;
 
- 								this.height = height = height || 300;
 
- 								this.chart.resize({width, height})
 
- 							}
 
- 						});
 
- 				})
 
- 				
 
- 			}
 
- 			
 
- 		},
 
- 		canvasToTempFilePath(args = {}) {
 
- 			// #ifndef APP-NVUE
 
- 			const { use2dCanvas, canvasId } = this;
 
- 			return new Promise((resolve, reject) => {
 
- 				const copyArgs = Object.assign({
 
- 					canvasId,
 
- 					success: resolve,
 
- 					fail: reject
 
- 				}, args);
 
- 				if (use2dCanvas) {
 
- 					delete copyArgs.canvasId;
 
- 					copyArgs.canvas = this.canvasNode;
 
- 				}
 
- 				uni.canvasToTempFilePath(copyArgs, this);
 
- 			});
 
- 			// #endif
 
- 			// #ifdef APP-NVUE
 
- 			this.file = ''
 
- 			this.$refs.webview.evalJs(`canvasToTempFilePath()`);
 
- 			return new Promise((resolve, reject) => {
 
- 				this.$watch('file', async (file) => {
 
- 					if(file) {
 
- 						const tempFilePath = await base64ToPath(file)
 
- 						resolve(args.success({tempFilePath}))
 
- 					} else {
 
- 						reject(args.fail({error: ``}))
 
- 					}
 
- 				})
 
- 			})
 
- 			// #endif
 
- 		},
 
- 		async init(echarts, ...args) {
 
- 			// #ifndef APP-NVUE
 
- 			if(arguments && arguments.length < 1) {
 
- 				console.error('缺少参数:init(echarts, theme?:string, opts?: object, callback?: function)')
 
- 				return
 
- 			}
 
- 			// #endif
 
- 			let theme=null,opts={},callback;
 
- 			
 
- 			Array.from(arguments).forEach(item => {
 
- 				if(typeof item === 'function') {
 
- 					callback = item
 
- 				}
 
- 				if(['string'].includes(typeof item)) {
 
- 					theme = item
 
- 				}
 
- 				if(typeof item === 'object') {
 
- 					opts = item
 
- 				}
 
- 			})
 
- 			
 
- 			if(this.beforeDelay) {
 
- 				await sleep(this.beforeDelay)
 
- 			}
 
- 			let config = await this.getContext();
 
- 			// #ifndef APP-NVUE
 
- 			setCanvasCreator(echarts, config)
 
- 			this.chart = echarts.init(config.canvas, theme, Object.assign({}, config, opts))
 
- 			if(typeof callback === 'function') {
 
- 				callback(this.chart)
 
- 			} else {
 
- 				return this.chart
 
- 			}
 
- 			// #endif
 
- 			// #ifdef APP-NVUE
 
- 			this.chart = new Echarts(this.$refs.webview)
 
- 			this.$refs.webview.evalJs(`init(null, null, ${JSON.stringify(opts)}, ${theme})`)
 
- 			if(callback) {
 
- 				callback(this.chart)
 
- 			} else {
 
- 				return this.chart
 
- 			}
 
- 			// #endif
 
- 		},
 
- 		getContext() {
 
- 			// #ifdef APP-NVUE
 
- 			if(this.finished) {
 
- 				return Promise.resolve(this.finished)
 
- 			}
 
- 			return new Promise(resolve => {
 
- 				this.$watch('finished', (val) => {
 
- 					if(val) {
 
- 						resolve(this.finished)
 
- 					}
 
- 				})
 
- 			})
 
- 			// #endif
 
- 			// #ifndef APP-NVUE
 
- 			return getRect(`#${this.canvasId}`, {context: this, type: this.use2dCanvas ? 'fields': 'boundingClientRect'}).then(res => {
 
- 				if(res) {
 
- 					let dpr = devicePixelRatio
 
- 					let {width, height, node} = res
 
- 					let canvas;
 
- 					this.width = width = width || 300;
 
- 					this.height = height = height || 300;
 
- 					if(node) {
 
- 						const ctx = node.getContext('2d');
 
- 						canvas = new Canvas(ctx, this, true, node);
 
- 						this.canvasNode = node
 
- 					} else {
 
- 						// #ifdef MP-TOUTIAO
 
- 						dpr = !this.isPC ? devicePixelRatio : 1// 1.25
 
- 						// #endif
 
- 						// #ifndef MP-ALIPAY || MP-TOUTIAO
 
- 						dpr = this.isPC ? devicePixelRatio : 1
 
- 						// #endif
 
- 						// #ifdef MP-ALIPAY || MP-LARK
 
- 						dpr = devicePixelRatio
 
- 						// #endif
 
- 						this.rect = res
 
- 						this.nodeWidth = width * dpr;
 
- 						this.nodeHeight = height * dpr;
 
- 						const ctx = uni.createCanvasContext(this.canvasId, this);
 
- 						canvas =  new Canvas(ctx, this, false);
 
- 					}
 
- 					return { canvas, width, height, devicePixelRatio: dpr, node };
 
- 				} else {
 
- 					return {}
 
- 				}
 
- 			})
 
- 			// #endif
 
- 		},
 
- 		// #ifndef APP-NVUE
 
- 		getRelative(e) {
 
- 			return {x: e.pageX - this.rect.left, y: e.pageY - this.rect.top, wheelDelta: e.wheelDelta}
 
- 		},
 
- 		getTouch(e) {
 
- 			return e.touches && e.touches[0] && e.touches[0].x ? e.touches[0] : this.getRelative(e);
 
- 		},
 
- 		touchStart(e) {
 
- 			this.isDown = true
 
- 			if (this.chart && ((e.touches.length > 0 || e.touches['0'])  && e.type != 'mousemove' || e.type == 'mousedown')) {
 
- 				const touch = this.getTouch(e)
 
- 				this.startX = touch.x
 
- 				this.startY = touch.y
 
- 				this.startT = new Date()
 
- 				const handler = this.chart.getZr().handler;
 
- 				dispatch.call(handler, 'mousedown', touch)
 
- 				dispatch.call(handler, 'mousemove', touch)
 
- 				handler.processGesture(wrapTouch(e), 'start');
 
- 				clearTimeout(this.endTimer);
 
- 			}
 
- 		},
 
- 		touchMove(e) {
 
- 			if(this.isPc && this.enableHover && !this.isDown) {this.isDown = true}
 
- 			if (this.chart && ((e.touches.length > 0 || e.touches['0']) && e.type != 'mousemove' || e.type == 'mousemove' && this.isDown)) {
 
- 				const handler = this.chart.getZr().handler;
 
- 				dispatch.call(handler, 'mousemove', this.getTouch(e))
 
- 				handler.processGesture(wrapTouch(e), 'change');
 
- 			}
 
- 		},
 
- 		touchEnd(e) {
 
- 			this.isDown = false
 
- 			if (this.chart) {
 
- 				const {x} = e.changedTouches && e.changedTouches[0] || {}
 
- 				const touch = (x ? e.changedTouches[0] : this.getRelative(e)) || {};
 
- 				const handler = this.chart.getZr().handler;
 
- 				const isClick = Math.abs(touch.x - this.startX) < 10 && new Date() - this.startT < 200;
 
- 				dispatch.call(handler, 'mouseup', touch)
 
- 				handler.processGesture(wrapTouch(e), 'end');
 
- 				if(isClick) {
 
- 					dispatch.call(handler, 'click', touch)
 
- 				} else {
 
- 					this.endTimer = setTimeout(() => {
 
- 						dispatch.call(handler, 'mousemove', {x: 999999999,y: 999999999});
 
- 						dispatch.call(handler, 'mouseup', {x: 999999999,y: 999999999});
 
- 					},50)
 
- 				}
 
- 			}
 
- 		},
 
- 		// #endif
 
- 		// #ifdef H5
 
- 		mousewheel(e){
 
- 			if(this.chart) {
 
- 				dispatch.call(this.chart.getZr().handler, 'mousewheel', this.getTouch(e))
 
- 			}
 
- 		}
 
- 		// #endif
 
- 	}
 
- };
 
- </script>
 
- <style scoped>
 
- .lime-echart {
 
- 	position: relative;
 
- 	/* #ifndef APP-NVUE */
 
- 	width: 100%;
 
- 	height: 100%;
 
- 	/* #endif */
 
- 	/* #ifdef APP-NVUE */
 
- 	flex: 1;
 
- 	/* #endif */
 
- }
 
- .lime-echart__canvas {
 
- 	/* #ifndef APP-NVUE */
 
- 	width: 100%;
 
- 	height: 100%;
 
- 	/* #endif */
 
- 	/* #ifdef APP-NVUE */
 
- 	flex: 1;
 
- 	/* #endif */
 
- }
 
- </style>
 
 
  |