| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 | import { brush, setClipPath, setGradient, setPattern } from './graphic.js';import { createElement, createVNode, vNodeToString, getCssString, createBrushScope, createSVGVNode } from './core.js';import { normalizeColor, encodeBase64, isGradient, isPattern } from './helper.js';import { extend, keys, logError, map, noop, retrieve2 } from '../core/util.js';import patch, { updateAttrs } from './patch.js';import { getSize } from '../canvas/helper.js';var svgId = 0;var SVGPainter = (function () {    function SVGPainter(root, storage, opts) {        this.type = 'svg';        this.refreshHover = createMethodNotSupport('refreshHover');        this.configLayer = createMethodNotSupport('configLayer');        this.storage = storage;        this._opts = opts = extend({}, opts);        this.root = root;        this._id = 'zr' + svgId++;        this._oldVNode = createSVGVNode(opts.width, opts.height);        if (root && !opts.ssr) {            var viewport = this._viewport = document.createElement('div');            viewport.style.cssText = 'position:relative;overflow:hidden';            var svgDom = this._svgDom = this._oldVNode.elm = createElement('svg');            updateAttrs(null, this._oldVNode);            viewport.appendChild(svgDom);            root.appendChild(viewport);        }        this.resize(opts.width, opts.height);    }    SVGPainter.prototype.getType = function () {        return this.type;    };    SVGPainter.prototype.getViewportRoot = function () {        return this._viewport;    };    SVGPainter.prototype.getViewportRootOffset = function () {        var viewportRoot = this.getViewportRoot();        if (viewportRoot) {            return {                offsetLeft: viewportRoot.offsetLeft || 0,                offsetTop: viewportRoot.offsetTop || 0            };        }    };    SVGPainter.prototype.getSvgDom = function () {        return this._svgDom;    };    SVGPainter.prototype.refresh = function () {        if (this.root) {            var vnode = this.renderToVNode({                willUpdate: true            });            vnode.attrs.style = 'position:absolute;left:0;top:0;user-select:none';            patch(this._oldVNode, vnode);            this._oldVNode = vnode;        }    };    SVGPainter.prototype.renderOneToVNode = function (el) {        return brush(el, createBrushScope(this._id));    };    SVGPainter.prototype.renderToVNode = function (opts) {        opts = opts || {};        var list = this.storage.getDisplayList(true);        var width = this._width;        var height = this._height;        var scope = createBrushScope(this._id);        scope.animation = opts.animation;        scope.willUpdate = opts.willUpdate;        scope.compress = opts.compress;        scope.emphasis = opts.emphasis;        var children = [];        var bgVNode = this._bgVNode = createBackgroundVNode(width, height, this._backgroundColor, scope);        bgVNode && children.push(bgVNode);        var mainVNode = !opts.compress            ? (this._mainVNode = createVNode('g', 'main', {}, [])) : null;        this._paintList(list, scope, mainVNode ? mainVNode.children : children);        mainVNode && children.push(mainVNode);        var defs = map(keys(scope.defs), function (id) { return scope.defs[id]; });        if (defs.length) {            children.push(createVNode('defs', 'defs', {}, defs));        }        if (opts.animation) {            var animationCssStr = getCssString(scope.cssNodes, scope.cssAnims, { newline: true });            if (animationCssStr) {                var styleNode = createVNode('style', 'stl', {}, [], animationCssStr);                children.push(styleNode);            }        }        return createSVGVNode(width, height, children, opts.useViewBox);    };    SVGPainter.prototype.renderToString = function (opts) {        opts = opts || {};        return vNodeToString(this.renderToVNode({            animation: retrieve2(opts.cssAnimation, true),            emphasis: retrieve2(opts.cssEmphasis, true),            willUpdate: false,            compress: true,            useViewBox: retrieve2(opts.useViewBox, true)        }), { newline: true });    };    SVGPainter.prototype.setBackgroundColor = function (backgroundColor) {        this._backgroundColor = backgroundColor;    };    SVGPainter.prototype.getSvgRoot = function () {        return this._mainVNode && this._mainVNode.elm;    };    SVGPainter.prototype._paintList = function (list, scope, out) {        var listLen = list.length;        var clipPathsGroupsStack = [];        var clipPathsGroupsStackDepth = 0;        var currentClipPathGroup;        var prevClipPaths;        var clipGroupNodeIdx = 0;        for (var i = 0; i < listLen; i++) {            var displayable = list[i];            if (!displayable.invisible) {                var clipPaths = displayable.__clipPaths;                var len = clipPaths && clipPaths.length || 0;                var prevLen = prevClipPaths && prevClipPaths.length || 0;                var lca = void 0;                for (lca = Math.max(len - 1, prevLen - 1); lca >= 0; lca--) {                    if (clipPaths && prevClipPaths                        && clipPaths[lca] === prevClipPaths[lca]) {                        break;                    }                }                for (var i_1 = prevLen - 1; i_1 > lca; i_1--) {                    clipPathsGroupsStackDepth--;                    currentClipPathGroup = clipPathsGroupsStack[clipPathsGroupsStackDepth - 1];                }                for (var i_2 = lca + 1; i_2 < len; i_2++) {                    var groupAttrs = {};                    setClipPath(clipPaths[i_2], groupAttrs, scope);                    var g = createVNode('g', 'clip-g-' + clipGroupNodeIdx++, groupAttrs, []);                    (currentClipPathGroup ? currentClipPathGroup.children : out).push(g);                    clipPathsGroupsStack[clipPathsGroupsStackDepth++] = g;                    currentClipPathGroup = g;                }                prevClipPaths = clipPaths;                var ret = brush(displayable, scope);                if (ret) {                    (currentClipPathGroup ? currentClipPathGroup.children : out).push(ret);                }            }        }    };    SVGPainter.prototype.resize = function (width, height) {        var opts = this._opts;        var root = this.root;        var viewport = this._viewport;        width != null && (opts.width = width);        height != null && (opts.height = height);        if (root && viewport) {            viewport.style.display = 'none';            width = getSize(root, 0, opts);            height = getSize(root, 1, opts);            viewport.style.display = '';        }        if (this._width !== width || this._height !== height) {            this._width = width;            this._height = height;            if (viewport) {                var viewportStyle = viewport.style;                viewportStyle.width = width + 'px';                viewportStyle.height = height + 'px';            }            if (!isPattern(this._backgroundColor)) {                var svgDom = this._svgDom;                if (svgDom) {                    svgDom.setAttribute('width', width);                    svgDom.setAttribute('height', height);                }                var bgEl = this._bgVNode && this._bgVNode.elm;                if (bgEl) {                    bgEl.setAttribute('width', width);                    bgEl.setAttribute('height', height);                }            }            else {                this.refresh();            }        }    };    SVGPainter.prototype.getWidth = function () {        return this._width;    };    SVGPainter.prototype.getHeight = function () {        return this._height;    };    SVGPainter.prototype.dispose = function () {        if (this.root) {            this.root.innerHTML = '';        }        this._svgDom =            this._viewport =                this.storage =                    this._oldVNode =                        this._bgVNode =                            this._mainVNode = null;    };    SVGPainter.prototype.clear = function () {        if (this._svgDom) {            this._svgDom.innerHTML = null;        }        this._oldVNode = null;    };    SVGPainter.prototype.toDataURL = function (base64) {        var str = this.renderToString();        var prefix = 'data:image/svg+xml;';        if (base64) {            str = encodeBase64(str);            return str && prefix + 'base64,' + str;        }        return prefix + 'charset=UTF-8,' + encodeURIComponent(str);    };    return SVGPainter;}());function createMethodNotSupport(method) {    return function () {        if (process.env.NODE_ENV !== 'production') {            logError('In SVG mode painter not support method "' + method + '"');        }    };}function createBackgroundVNode(width, height, backgroundColor, scope) {    var bgVNode;    if (backgroundColor && backgroundColor !== 'none') {        bgVNode = createVNode('rect', 'bg', {            width: width,            height: height,            x: '0',            y: '0'        });        if (isGradient(backgroundColor)) {            setGradient({ fill: backgroundColor }, bgVNode.attrs, 'fill', scope);        }        else if (isPattern(backgroundColor)) {            setPattern({                style: {                    fill: backgroundColor                },                dirty: noop,                getBoundingRect: function () { return ({ width: width, height: height }); }            }, bgVNode.attrs, 'fill', scope);        }        else {            var _a = normalizeColor(backgroundColor), color = _a.color, opacity = _a.opacity;            bgVNode.attrs.fill = color;            opacity < 1 && (bgVNode.attrs['fill-opacity'] = opacity);        }    }    return bgVNode;}export default SVGPainter;
 |