| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- <template>
- <!-- #ifdef APP -->
- <web-view class="lime-echart" ref="chartRef" @load="loaded" :style="[lStyle]" :webview-styles="[webviewStyles]"
- src="/uni_modules/lime-echart/static/app/uvue.html?v=10112">
- </web-view>
- <!-- #endif -->
- <!-- #ifdef WEB -->
- <div class="lime-echart" ref="chartRef"></div>
- <!-- #endif -->
- <!-- #ifndef WEB || APP-->
- <view class="lime-echart">
- <canvas style="width:100%; height:100%" v-if="canvasid" :id="canvasid" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"></canvas>
- </view>
- <!-- #endif -->
- </template>
- <script lang="uts" setup>
- // @ts-nocheck
- import { echartsProps } from './type';
- import { Echarts } from './uvue';
- // #ifdef WEB
- import { dispatch } from './canvas';
- import * as echartsLibrary from '@/uni_modules/lime-echart/static/web/echarts.esm.min.js';
- // #endif
- // #ifndef APP || WEB
- import { Canvas, setCanvasCreator, dispatch } from './canvas';
- import { wrapTouch, convertTouchesToArray, devicePixelRatio, sleep, canIUseCanvas2d, getRect } from './utils';
- // #endif
- type EChartsResolveCallback = (value : Echarts) => void
-
- const emits = defineEmits(['finished'])
- const props = withDefaults(defineProps<echartsProps>(), {
- isDisableScroll: false,
- isClickable: true,
- autoHideTooltip: false,
- enableHover: false,
- landscape: false,
- beforeDelay: 30,
- })
- const instance = getCurrentInstance()!;
- const canvasid = `lime-echart-${instance.uid}`
- const finished = ref(false)
- const initializationQueue = [] as EChartsResolveCallback[]
- const callbackQueue = [] as EChartsResolveCallback[]
- // let context = null as UniWebViewElement | null
- let chartInstance = null as Echarts | null
- let chartRef = ref<UniWebViewElement | null>(null)
- let canvasNode:any|null = null
- const processInitializationQueue = () => {
- // #ifdef APP
- if (finished.value) {
- if (chartInstance == null) {
- chartInstance = new Echarts(chartRef.value!)
- }
- while (initializationQueue.length > 0) {
- const resolve = initializationQueue.pop() as EChartsResolveCallback
- resolve(chartInstance!)
- }
- }
- // #endif
- // #ifndef APP
- while (initializationQueue.length > 0) {
- if (chartInstance != null) {
- const resolve = initializationQueue.pop() as EChartsResolveCallback
- resolve(chartInstance!)
- }
- }
- // #endif
- if (chartInstance != null) {
- while (callbackQueue.length > 0) {
- const callback = callbackQueue.pop() as EChartsResolveCallback
- callback(chartInstance!)
- }
- }
- }
- // #ifdef APP
- const loaded = (event : UniWebViewLoadEvent) => {
- event.stopPropagation()
- event.preventDefault()
- nextTick(()=> {
- chartRef.value?.getBoundingClientRectAsync()?.then(res => {
- if(res.width > 0 && res.height > 0) {
- finished.value = true
- processInitializationQueue()
- emits('finished')
- } else {
- console.warn('【lime-echart】获取尺寸失败,请检查代码样式')
- }
- })
- })
- }
- // #endif
- const checkInitialization = () : boolean => {
- if (chartInstance == null) {
- console.warn(`组件还未初始化,请先使用 init`)
- return true
- }
- return false
- }
- const setOption = (option : UTSJSONObject) => {
- if (checkInitialization()) return
- chartInstance!.setOption(option);
- }
- const showLoading = () => {
- if (checkInitialization()) return
- chartInstance!.showLoading();
- }
- const hideLoading = () => {
- if (checkInitialization()) return
- chartInstance!.hideLoading();
- }
- const clear = () => {
- if (checkInitialization()) return
- chartInstance!.clear();
- }
- const dispose = () => {
- if (checkInitialization()) return
- chartInstance!.dispose();
- }
- const resize = (size : UTSJSONObject) => {
- if (checkInitialization()) return
- chartInstance!.resize(size);
- }
- const canvasToTempFilePath = (opt : UTSJSONObject) => {
- if (checkInitialization()) return
- // #ifdef APP
- chartInstance!.canvasToTempFilePath(opt);
- // #endif
- // #ifdef WEB
- opt.success?.({
- // @ts-ignore
- tempFilePath: chartInstance!._api.getDataURL()
- })
- // #endif
- // #ifndef WEB || APP
- if(canvasNode) {
- opt.success?.({
- tempFilePath: canvasNode.toDataURL()
- })
- } else {
- uni.canvasToTempFilePath({
- ...opt,
- canvasId
- }, instance.proxy);
- }
- // #endif
- }
- // #ifdef APP
- function init(callback : ((chartInstance : Echarts) => void) | null) : Promise<Echarts> {
- if (callback != null) {
- callbackQueue.push(callback)
- }
- return new Promise<Echarts>((resolve) => {
- initializationQueue.push(resolve)
- processInitializationQueue()
- })
- }
- // #endif
- // #ifndef APP
- // #ifndef WEB
- let use2dCanvas = canIUseCanvas2d()
- const getContext = async () => {
- return new Promise((resolve, reject)=>{
- uni.createCanvasContextAsync({
- id: canvasid,
- component: instance.proxy!,
- success: (context : CanvasContext) => {
- canvasNode = context
- const canvasContext = context.getContext('2d')!;
- const canvas = canvasContext.canvas;
- let uniCanvas;
- const width = canvas.offsetWidth
- const height = canvas.offsetHeight
- // 处理高清屏逻辑
- const dpr = devicePixelRatio//uni.getDeviceInfo().devicePixelRatio ?? 1;
- canvas.width = canvas.offsetWidth * dpr;
- canvas.height = canvas.offsetHeight * dpr;
- canvasContext.scale(dpr, dpr); // 仅需调用一次,当调用 reset 方法后需要再次 scale
- if(use2dCanvas) {
- uniCanvas = new Canvas(canvasContext, instance.proxy, true, context);
- } else {
- uniCanvas = new Canvas(canvasContext, instance.proxy, false);
- }
- resolve({ canvas: uniCanvas, width, height, devicePixelRatio: dpr, node: context});
- },
- fail(err) {
- reject(err)
- console.log('err', err)
- }
- })
- })
- }
- // #endif
- const getTouch = (e) => {
- const touches = e.touches[0]
- // #ifdef WEB
- // @ts-ignore
- const rect = chart!.getZr().dom.getBoundingClientRect();
- const touch = {
- x: touches.clientX - rect.left,
- y: touches.clientY - rect.top
- }
- // #endif
- // #ifndef WEB
- const touch = {
- x: touches.x,
- y: touches.y
- }
- // #endif
- return touch
- }
- const touchstart = (e) => {
- if (chartInstance == null) return
- // @ts-ignore
- const handler = chartInstance.getZr().handler;
- const touch = getTouch(e)
- dispatch.call(handler, 'mousedown', touch)
- dispatch.call(handler, 'click', touch)
- }
- const touchmove = (e) => {
- if (chartInstance == null) return
- // @ts-ignore
- const handler = chartInstance.getZr().handler;
- const touch = getTouch(e)
- dispatch.call(handler, 'mousemove', touch)
- }
- const touchend = (e) => {
- if (chartInstance == null || !props.autoHideTooltip) return
- // @ts-ignore
- const handler = chartInstance.getZr().handler;
- const touch = {
- x: 999999999,
- y: 999999999
- }
- dispatch.call(handler, 'mousemove', touch)
- dispatch.call(handler, 'touchend', touch)
- }
- async function init(echarts : any, ...args : any[]) : Promise<Echarts> {
- const library = echarts || echartsLibrary
- if (library == null) {
- console.error('请确保已经引入了 ECharts 库');
- return Promise.reject('请确保已经引入了 ECharts 库');
- }
- let theme : string | null = null
- let opts = {}
- let callback : Function | null = null;
- args.forEach(item => {
- if (typeof item === 'function') {
- callback = item
- } else if (['string'].includes(typeof item)) {
- theme = item
- } else if (typeof item === 'object') {
- opts = item
- }
- })
- // #ifdef WEB
- library.env.domSupported = true
- library.env.hasGlobalWindow = true
- library.env.node = false
- library.env.pointerEventsSupported = false
- library.env.svgSupported = true
- library.env.touchEventsSupported = true
- library.env.transform3dSupported = true
- library.env.transformSupported = true
- library.env.worker = false
- library.env.wxa = false
- chartInstance = library.init(chartRef.value, theme, opts)
- // window.addEventListener('touchstart', touchstart)
- // window.addEventListener('touchmove', touchmove)
- // window.addEventListener('touchend', touchend)
- // #endif
- // #ifndef WEB
- let config = await getContext();
- setCanvasCreator(library, config)
- chartInstance = library.init(config.canvas, theme, Object.assign({}, config, opts))
- // #endif
- if (callback != null && typeof callback == 'function') {
- callbackQueue.push(callback)
- }
- return new Promise<Echarts>((resolve) => {
- initializationQueue.push(resolve)
- processInitializationQueue()
- })
- }
- onMounted(() => {
- nextTick(() => {
- finished.value = true
- processInitializationQueue()
- emits('finished')
- })
- })
- onUnmounted(() => {
- // #ifdef WEB
- // window.removeEventListener('touchstart', touchstart)
- // window.removeEventListener('touchmove', touchmove)
- // window.removeEventListener('touchend', touchend)
- // #endif
- })
- // #endif
- defineExpose({
- init,
- setOption,
- showLoading,
- hideLoading,
- clear,
- dispose,
- resize,
- canvasToTempFilePath
- })
- </script>
- <style lang="scss">
- .lime-echart {
- flex: 1;
- width: 100%;
- }
- </style>
|