UNPKG

uni-echarts

Version:

🪀 适用于uni-app的Apache ECharts组件(仅支持Vue 3)

341 lines (277 loc) 6.99 kB
/* eslint-disable no-undef */ import { defaultTo, isEmpty, lowerFirst, upperFirst } from "./helpers"; import { mitt } from "./mitt"; import { getDeviceInfo } from "./uni"; const SHORT_HEX_REGEX = /#([0-9a-f])([0-9a-f])([0-9a-f])\b/gi; export class UniCanvas { tagName = "canvas"; attrs = {}; constructor(canvasId, context, canvasNode) { this.canvasId = canvasId; this.context = context; this.canvasNode = canvasNode; if (canvasNode == null) { this._setupContext(context); } this._emitter = mitt(); } get width() { if (this.canvasNode == null) { return this.getAttribute("width"); } return this.canvasNode.width; } set width(value) { if (this.canvasNode == null) { this.setAttribute("width", value); return; } this.canvasNode.width = value; } get height() { if (this.canvasNode == null) { return this.getAttribute("height"); } return this.canvasNode.height; } set height(value) { if (this.canvasNode == null) { this.setAttribute("height", value); return; } this.canvasNode.height = value; } _setupContext(context) { const styles = [ "fillStyle", "fontSize", "globalAlpha", "lineCap", "lineDash", "lineJoin", "lineWidth", "miterLimit", "strokeStyle", "textAlign", "textBaseline", "opacity", "shadowOffsetX", "shadowOffsetY", "shadowBlur", "shadowColor", "font" ]; const shadow = { offsetX: 0, offsetY: 0, blur: 0, color: "#000000" }; for (const key of styles) { // eslint-disable-next-line accessor-pairs Object.defineProperty(context, key, { set(value) { if (key === "opacity") { context.setGlobalAlpha(value); return; } if (key === "font") { context.setFontSize(UniCanvas.parseFontSize(value)); return; } if (key.indexOf("shadow") === 0) { if (key !== "shadowColor") { shadow[lowerFirst(key.slice(6))] = value; } else { shadow.color = UniCanvas.normalizeColor(context, value); context.setShadow( shadow.offsetX, shadow.offsetY, shadow.blur, shadow.color ); } return; } if (key === "fillStyle" || key === "strokeStyle") { value = UniCanvas.normalizeColor(context, value); } context[`set${upperFirst(key)}`](value); } }); } const _drawImage = context.drawImage; context.drawImage = (...args) => { _drawImage(args[0].src, ...args.slice(1)); }; if (context.strokeText == null) { context.strokeText = (...args) => { context.fillText(...args); }; } if (context.createRadialGradient == null) { context.createRadialGradient = (...args) => { return context.createCircularGradient(...args.slice(-3)); }; } if (context.measureText == null || getDeviceInfo().osName === "harmonyos") { const strlen = (str) => { let len = 0; for (let i = 0; i < str.length; i += 1) { const unicode = str.charCodeAt(i); if (unicode > 0 && unicode < 128) { len += 1; } else { len += 2; } } return len; }; context.measureText = (text, font) => { const fontSize = defaultTo( context.state && context.state.fontSize, UniCanvas.parseFontSize(font), 12 ) / 2; const factor = fontSize >= 16 ? 1.3 : 1; return { width: strlen(text) * fontSize * factor }; }; } } getContext(type) { if (type === "2d") { return this.context; } } setAttribute(key, value) { this.attrs[key] = value; } getAttribute(key) { return this.attrs[key]; } addEventListener(type, listener) { this._emitter.on(type, listener); } removeEventListener(type, listener) { this._emitter.off(type, listener); } dispatchEvent(type, event) { if (typeof type === "object") { this._emitter.emit(type.type, type); } else { this._emitter.emit(type, event); } return true; } attachEvent() { // noop } detachEvent() { // noop } toTempFilePath(options = {}) { const opts = {}; if (this.canvasNode != null) { opts.canvas = this.canvasNode; } else { opts.canvasId = this.canvasId; } return uni.canvasToTempFilePath({ ...opts, ...options }); } static parseFontSize(font) { return Number.parseFloat(defaultTo(font, "").match(/([\d.]+)px/)[1]); } static normalizeColor(context, color) { if (typeof color === "string") { // #ifdef MP-TOUTIAO SHORT_HEX_REGEX.lastIndex = 0; if (SHORT_HEX_REGEX.test(color)) { return color.replace(SHORT_HEX_REGEX, "#$1$1$2$2$3$3"); } // #endif } return color; } static dispatch(handler, event, touch) { handler.dispatch(event, { zrX: touch.x, zrY: touch.y, zrDelta: touch.wheelDelta, preventDefault: () => {}, stopImmediatePropagation: () => {}, stopPropagation: () => {} }); } } export class UniImage { tagName = "img"; constructor() { this._src = null; this.width = 0; this.height = 0; } get src() { return this._src; } set src(value) { this._src = value; uni.getImageInfo({ src: value, success: (res) => { this.width = res.width; this.height = res.height; if (this.onload) { this.onload(res); } }, fail: (err) => { if (this.onerror) { this.onerror(err); } } }); } } export function setupEchartsCanvas(echarts, { canvas, node }) { echarts.registerPreprocessor((option) => { if (option == null) { return; } if (option.series != null) { if (Array.isArray(option.series)) { if (!isEmpty(option.series)) { for (const item of option.series) { item.progressive = 0; } } } else if (typeof option.series === "object") { option.series.progressive = 0; } } }); const loadImage = (src, onload, onerror) => { if (node != null && node.createImage) { const image = node.createImage(); image.onload = onload; image.onerror = onerror; image.src = src; return image; } const image = new UniImage(); image.onload = onload; image.onerror = onerror; image.src = src; return image; }; echarts.setPlatformAPI({ loadImage: node != null ? loadImage : undefined, createCanvas() { return canvas; } }); }