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; 
 | 
        scope.ssr = this._opts.ssr; 
 | 
        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; 
 |