| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| import { parseSVG, makeViewBoxTransform } from 'zrender/src/tool/parseSVG'; |
| import Group from 'zrender/src/container/Group'; |
| import Rect from 'zrender/src/graphic/shape/Rect'; |
| import { assert, createHashMap } from 'zrender/src/core/util'; |
| import BoundingRect from 'zrender/src/core/BoundingRect'; |
| import { makeInner } from '../../util/model'; |
| var inner = makeInner(); |
| export default { |
| /** |
| * @param {string} mapName |
| * @param {Object} mapRecord {specialAreas, geoJSON} |
| * @return {Object} {root, boundingRect} |
| */ |
| load: function (mapName, mapRecord) { |
| var originRoot = inner(mapRecord).originRoot; |
| |
| if (originRoot) { |
| return { |
| root: originRoot, |
| boundingRect: inner(mapRecord).boundingRect |
| }; |
| } |
| |
| var graphic = buildGraphic(mapRecord); |
| inner(mapRecord).originRoot = graphic.root; |
| inner(mapRecord).boundingRect = graphic.boundingRect; |
| return graphic; |
| }, |
| makeGraphic: function (mapName, mapRecord, hostKey) { |
| // For performance consideration (in large SVG), graphic only maked |
| // when necessary and reuse them according to hostKey. |
| var field = inner(mapRecord); |
| var rootMap = field.rootMap || (field.rootMap = createHashMap()); |
| var root = rootMap.get(hostKey); |
| |
| if (root) { |
| return root; |
| } |
| |
| var originRoot = field.originRoot; |
| var boundingRect = field.boundingRect; // For performance, if originRoot is not used by a view, |
| // assign it to a view, but not reproduce graphic elements. |
| |
| if (!field.originRootHostKey) { |
| field.originRootHostKey = hostKey; |
| root = originRoot; |
| } else { |
| root = buildGraphic(mapRecord, boundingRect).root; |
| } |
| |
| return rootMap.set(hostKey, root); |
| }, |
| removeGraphic: function (mapName, mapRecord, hostKey) { |
| var field = inner(mapRecord); |
| var rootMap = field.rootMap; |
| rootMap && rootMap.removeKey(hostKey); |
| |
| if (hostKey === field.originRootHostKey) { |
| field.originRootHostKey = null; |
| } |
| } |
| }; |
| |
| function buildGraphic(mapRecord, boundingRect) { |
| var svgXML = mapRecord.svgXML; |
| var result; |
| var root; |
| |
| try { |
| result = svgXML && parseSVG(svgXML, { |
| ignoreViewBox: true, |
| ignoreRootClip: true |
| }) || {}; |
| root = result.root; |
| assert(root != null); |
| } catch (e) { |
| throw new Error('Invalid svg format\n' + e.message); |
| } |
| |
| var svgWidth = result.width; |
| var svgHeight = result.height; |
| var viewBoxRect = result.viewBoxRect; |
| |
| if (!boundingRect) { |
| boundingRect = svgWidth == null || svgHeight == null ? // If svg width / height not specified, calculate |
| // bounding rect as the width / height |
| root.getBoundingRect() : new BoundingRect(0, 0, 0, 0); |
| |
| if (svgWidth != null) { |
| boundingRect.width = svgWidth; |
| } |
| |
| if (svgHeight != null) { |
| boundingRect.height = svgHeight; |
| } |
| } |
| |
| if (viewBoxRect) { |
| var viewBoxTransform = makeViewBoxTransform(viewBoxRect, boundingRect.width, boundingRect.height); |
| var elRoot = root; |
| root = new Group(); |
| root.add(elRoot); |
| elRoot.scale = viewBoxTransform.scale; |
| elRoot.position = viewBoxTransform.position; |
| } |
| |
| root.setClipPath(new Rect({ |
| shape: boundingRect.plain() |
| })); |
| return { |
| root: root, |
| boundingRect: boundingRect |
| }; |
| } |