| (window.webpackJsonp=window.webpackJsonp||[]).push([[136],{437:function(e,n,t){"use strict";t.r(n),n.default='# SVG 底图\n\n从 `v5.1.0` 开始,ECharts 支持在 [地理坐标系(geo)](${optionPath}geo) 和 [地图系列(map series)](${optionPath}series-map) 中使用 SVG 作为底图。之前只支持 [GeoJSON](${apiPath}echarts.registerMap) 格式的底图。\n\n有了这个功能,ECharts 能在任一种渲染模式(`canvas` 渲染模式和 `svg` 渲染模式)中绘制 SVG 底图,并且能够只用简单的 ECharts 配置项(option)就带来 [放大](${optionPath}geo.roam)、[平移](${optionPath}geo.roam)、[点选(select)](${optionPath}geo.select)、[高亮强调(emphasis)](${optionPath}geo.roam)、[聚焦-淡出(focus-blur)](${optionPath}geo.emphasis.focus)、[标签(label)](${optionPath}geo.label)、[标签布局(labelLayout)](${optionPath}series-map.labelLayout)、[提示框(tooltip)](${optionPath}geo.tooltip) 等特性。ECharts 中的所有在 [地理坐标系(geo)](${optionPath}geo) 中可用系列(如 [散点图(scatter)](${optionPath}series-scatter)、[特效散点图(effectScatter)](${optionPath}series-effectScatter),[路径图(lines)](${optionPath}series-lines),[自定义系列(custom)](${optionPath}series-custom))也能显示在 SVG 底图上。\n\n这些是使用 SVG 底图的例子:\n\n[庖丁解牛](${exampleEditorPath}geo-beef-cuts) |\n[内脏数据](${exampleEditorPath}geo-organ) |\n[航班选座](${exampleEditorPath}geo-seatmap-flight) |\n[地图](${exampleEditorPath}geo-svg-map) |\n[散点图](${exampleEditorPath}geo-svg-scatter-simple) |\n[路径图](${exampleEditorPath}geo-svg-lines) |\n[交通](${exampleEditorPath}geo-svg-traffic)\n\n\n## 基本用法 [[[#basic-usage]]]\n\nSVG 底图的用法与 [GeoJSON](${apiPath}echarts.registerMap) 底图的用法相同。\n\n如果在 [地理坐标系(geo)](${optionPath}geo) 中使用:\n```ts\n$.get(\'map/organ.svg\', function (svg) {\n // 首先向 echarts 注册 SVG 字符串或解析过的 SVG DOM\n echarts.registerMap(\'organ_diagram\', {svg: svg});\n\n var chart = echarts.init(document.getElementById(\'main\'))。\n chart.setOption({\n geo: [{\n // 引用注册过的底图。\n map: \'organ_diagram\',\n ...\n }]\n });\n});\n```\n\n如果在 [地图系列(map series)](${optionPath}series-map) 中使用:\n```ts\n$.get(\'map/beef_cuts.svg\', function (svg) {\n // 首先向 echarts 注册 SVG 字符串或解析过的 SVG DOM\n echarts.registerMap(\'beef_cuts_diagram\', {svg: svg})。\n\n var chart = echarts.init(document.getElementById(\'main\'))。\n chart.setOption({\n series: {\n type: \'map\',\n // 引用注册过的底图。\n map: \'beef_cuts_diagram\',\n ...\n }\n });\n});\n```\n\n\n## 缩放和平移 [[[#zoom-and-pan]]]\n\n[地理坐标系(geo)](${optionPath}geo)\n```ts\noption = {\n geo: {\n // 启用缩放和平移。\n roam: true,\n ...\n }\n};\n```\n[地图系列(map series)](${optionPath}series-map)\n```ts\noption = {\n series: {\n type: \'map\',\n // 启用缩放和平移。\n roam: true,\n ...\n }\n};\n```\n\n参见例子 [roam](${optionPath}geo.roam)、[SVG 地图](${exampleEditorPath}geo-svg-map)。\n\n\n## 具名元素 [[[#named-element]]]\n\n如果要控制 SVG 中的某些元素,或者让某些元素能交互,我们首先要在 SVG 中标记这些元素:在这些元素上添加 `name` 属性(下文称此类添加过 `name` 属性的元素为:“具名元素”)。许多功能(如 [select](${optionPath}geo.select)、[emphasis](${optionPath}geo.emphasis)、[focus-blur](${optionPath}geo.emphasis.focus)、[label](${optionPath}geo.label)、[labelLayout](${optionPath}series-map.labelLayout) 和 [tooltip](${optionPath}geo.tooltip) 这类交互相关的功能)都依赖于对元素的命名。\n\n如下例,我们只在左边的 SVG `path` 上添加名称属性 `name="named_rect"`:\n```xml\n<?xml version="1.0" encoding="utf-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" version="1.2" fill-rule="evenodd" xml:space="preserve">\n <path name="named_rect" d="M 0,0 L 0,100 100,100 100,0 Z" fill="#765" />\n <path d="M 150,0 L 150,100 250,100 250,0 Z" fill="#567" />\n</svg>\n```\n这样,鼠标 hover 时能高亮左边的矩形,但是右边的不行。\n\n<md-example src="doc-example/geo-svg-named-basic" width="100%" height="200"></md-example>\n\n我们还可以在 [geo.regions](${optionPath}geo.regions) 中为具名元素指定一些专属配置项:\n```ts\noption = {\n geo: {\n map: \'some_svg\',\n regions: [{\n name: \'element_name_1\',\n itemStyle: { ... }\n }, {\n name: \'element_name_2\',\n itemStyle: { ... }\n }]\n }\n};\n```\n\n注意:\n+ 只有这些 SVG 元素可以被命名:\n`rect`、`circle`、`line`、`ellipse`、`polygon`、`polyline`、`path`、`text`、`tspan`、`g`。\n+ 支持多个元素以相同的名称命名,这样它们能被同时高亮、选中。\n\n\n## 自定义样式 [[[#style-customization]]]\n\n虽然 SVG 元素的样式(如颜色、字体、线宽等等)都能直接在 SVG 文件中定义,但 ECharts 也支持在 `option` 中为具名元素定制样式,这能提供不少便利。\n\n可以在 [geo.itemStyle](${optionPath}geo.itemStyle) 或 [series-map.itemStyle](${optionPath}series-map.itemStyle) 中设置样式(也包括 `emphasis.itemStyle`、`select.itemStyle`、`blur.itemStyle`、`regions[i].itemStyle`、`regions[i].emphasis.itemStyle`、`regions[i].select.itemStyle`、`regions[i].blur.itemStyle`)。也能在这里删除一些具名元素的默认样式(例如,设置 `emphasis.itemStyle.color: null` 后,鼠标 hover 时填充色就不会改变)。\n\n此外,使用 [series-map](${optionPath}series-map) 时,也可以用 [visualMap 组件](${optionPath}visualMap) 为具名元素赋予样式。参见例子 [庖丁解牛](${exampleEditorPath}geo-beef-cuts)。\n\n注意:\n只有这些具名元素可以在 `itemStyle` 中设置样式:\n`rect`、`circle`、`line`、`ellipse`、`polygon`、`polyline`、`path`。\n\n\n## 元素的“选中”能力(select) [[[#select]]]\n\n如果想使具名元素能被“选中”,把 [geo.selectedMode](${optionPath}geo.selectedMode) 或 [series-map.selectedMode](${optionPath}series-map.selectedMode) 设置为 `\'single\'` 或者 `\'multiple\'` 即可。元素被选中时的样式可以在 [geo.select](${optionPath}geo.select) 或 [series-map.select](${optionPath}series-map.select) 中设定。\n\n可以通过 [geoselectchanged](${apiPath}event.geoselectchanged) 事件获得所有被选中者的名称,例如:\n```ts\nmyChart.on(\'geoselectchanged\', function (params) {\n var selectedNames = params.allSelected[0].name;\n console.log(\'selected\', selectedNames);\n});\n```\n\n参见例子 [航班选座](${exampleEditorPath}geo-seatmap-flight)。\n\n\n## 元素的“高亮强调”(emphasis)和“聚焦-淡出”(focus-blur) [[[#emphasis-and-focus-blur]]]\n\n具名元素可以自动在鼠标 hover 时有“高亮强调”(emphasis)的能力。\n\n此外,可以把 [geo.emphasis.focus](${optionPath}geo.emphasis.focus) 设置为 `\'self\'` 来启用 “聚焦-淡出”(focus-blur)功能。也就是,当鼠标 hover 在一个具名元素上时,所有其他元素都会被淡出。\n\n参见例子 [Organ Visualization](${exampleEditorPath}geo-organ)。\n\n\n## 提示框(tooltip) [[[#tooltip]]]\n\n可以在具名元素上启用或禁用提示框(tooltip)功能。\n```ts\noption = {\n // 在 option 根部声明 tooltip 以整体开启 tooltip 功能。\n tooltip: {},\n geo: {\n map: \'some_svg\',\n tooltip: {\n // 用 `show` 来启用/禁用 geo 上的 tooltip。\n show: true\n },\n regions: [{\n name: \'some_name1\',\n // 如果需要的话,可以对特定具名元素指定 tooltip 参数。\n tooltip: {\n formatter: \'一些特殊的提示 1\'\n }\n }, {\n name: \'some_name2\',\n tooltip: {\n formatter: \'一些特殊的提示 2\'\n }\n }]\n }\n};\n```\n\n如果想单独禁用 geo 上的 tooltip,只需:\n```ts\noption = {\n tooltip: {},\n geo: {\n map: \'some_svg\',\n tooltip: {\n show: false\n }\n }\n};\n```\n\n参见例子 [SVG 地图](${exampleEditorPath}geo-svg-map)。\n\n\n## 标签(label) [[[#label]]]\n\n虽然可以直接在 SVG 中定义 `<text>`/`<tspan>` 来显示文本标签,但 ECharts 也支持用 [geo.label](${optionPath}geo.label) 或 [series-map.label](${optionPath}series-map.label) 来设置底图上的标签。\n\n标签功能默认在鼠标 hover 时是启用的。如果想禁用标签,只需:\n```ts\noption = {\n geo: {\n map: \'some_svg\',\n emphasis: {\n label: {\n show: false\n }\n }\n }\n};\n```\n\n当想要多个元素共享一个标签时,我们有两种选择:\n+ 将这些元素包裹在一个具名的 `<g>` 中(如 `<g="name_a">`)中,这样只会显示一个标签,并且基于 `<g>` 的 `boundingRect` 定位。\n+ 给这些元素起相同的名字(如 `<path name="name_b"/><path name="name_b"/>`),这样每个元素都会显示一个标签,并且会根据每个元素自身显示和定位。\n\n例如(将鼠标 hover 到元素上能显示标签):\n<md-example src="doc-example/geo-svg-label-basic" width="100%" height="300"></md-example>\n\n注意:只有这些具名元素可以设置 `label`:\n`rect`、`circle`、`line`、`ellipse`、`polygon`、`polyline`、`path`、`g`。\n\n标签的用法也参见示例 [Organ Visualization](${exampleEditorPath}geo-organ)。\n\n\n## 事件 [[[#events]]]\n\n可以用如下方式监听具名元素的鼠标事件或者触摸事件:\n```ts\n// \'name1\' 是一个 SVG 元素的名字。\nmyChart.on(\'click\', { geoIndex: 0, name: \'name1\' }, function (params) {\n console.log(params);\n});\n```\n\n\n## SVG 底图的布局 [[[#layout-of-svg-base-map]]]\n\n在默认情况下,ECharts 会将 SVG 底图放置在画布的中心。如果需要调整的话,一般只调整 [layoutCenter](${optionPath}geo.layoutCenter)/[layoutSize](${optionPath}geo.layoutSize),偶尔也可能要调整 `<svg viewBox="...">`/[geo.boundingCoords](${optionPath}geo.boundingCoords)(它们两个的区别是:是否产生剪裁)。在大多数情况下,用这些已经足够了。\n\n如果要做一些精确的位置定制,那么还得了解下面这些概念。\n\n[地理坐标系(geo)](${optionPath}geo) 和 [地图系列(map series)](${optionPath}series-map) 的布局规则和选项都是一样的。所以下面我们只讲 [地理坐标系(geo)](${optionPath}geo)。\n\n<md-example src="doc-example/geo-svg-layout-basic" width="100%" height="600"></md-example>\n\n上面的例子只有一个 ECharts 画布,其中三个 SVG 展示在六个 [地理坐标系(geo)](${optionPath}geo) 中。同一列中的两个 [地理坐标系(geo)](${optionPath}geo) 使用相同的 SVG。\n\n首先,形状的外观是由 SVG 文件本身决定的。也就是说,在上例中,由 `<circle>` 和 `viewBox` 属性决定(`viewBox` 会切割圆形)。可以注意,每一列的形状轮廓都一样(不管它们的位置、大小是否不同和是否被拉伸),因为它们使用的是同一个 SVG。\n\n其次,用户可以用下面任一组选项,指定 [地理坐标系(geo)](${optionPath}geo) 的视口(`view port`)的位置和大小(它们的单位都是 echarts 画布的像素,或者百分比值):\n+ [layoutCenter](${optionPath}geo.layoutCenter)、[layoutSize](${optionPath}geo.layoutSize)(最常用)。\n+ [top](${optionPath}geo.top)、[right](${optionPath}geo.right)、[bottom](${optionPath}geo.bottom)、[left](${optionPath}geo.left)(在上例中使用的是这组)。\n\n在上例中,六个 `geo view port` 用六个黑色方块表示。\n\n第三,确定 SVG 的 `bounding rect`。`bounding rect` 由以下方法决定(它们的单位都是 SVG 内部元素的度量单位):\n1. 如果设定了 [geo.boundingCoords](${optionPath}geo.boundingCoords),则用它作 `bounding rect`。\n2. 否则,如果设定了 `<svg width="..." height="...">`,则用 `[0, 0, width, height]` 作为 `bounding rect`。(如果只设定了 `width` 或 `height`,则只使用 `[0, width]` 或 `[0, height]`)。\n3. 否则,如果设定了 `<svg viewBox="...">`,则用 `viewBox` 作 `bounding rect`。\n4. 否则,由整个 SVG 所有元素 `bounding rect` 的并集得到最终 `bounding rect`。\n5. 如果设定了 [geo.center](${optionPath}geo.center) 或 [geo.zoom](${optionPath}geo.zoom),则把上述 `1~4` 得到的 `bounding rect` 进行相应的 `transform`。\n\n`bounding rect` 确定后,会放置到相应的 `geo view port` 里:\n+ 如果用的是 [layoutCenter](${optionPath}geo.layoutCenter)、[layoutSize](${optionPath}geo.layoutSize),`bounding rect` 会置于 `geo view port` 的中心,并尽量填满 `geo view port`(保持长宽比)。\n+ 如果用的是 [top](${optionPath}geo.top)、[right](${optionPath}geo.right)、[bottom](${optionPath}geo.bottom)、[left](${optionPath}geo.left),`bounding rect` 会被拉伸,完全填充 `geo view port`。\n\n\n## 在 SVG 底图上绘制系列 [[[#place-series-on-svg-base-map]]]\n\n[scatter](${optionPath}series-scatter)、[effectScatter](${optionPath}series-effectScatter)、[lines](${optionPath}series-lines)、[custom](${optionPath}series-custom) 这些在 [地理坐标系(geo)](${optionPath}geo) 中可用的系列都可以在 SVG 底图上定位和显示。\n\n在这种用法中,`series.data` 的值的单位即为是 SVG 内部元素的度量单位。比如说:\n```ts\noption = {\n geo: {\n map: \'some_svg\'\n },\n series: {\n type: \'effectScatter\',\n coordinateSystem: \'geo\',\n geoIndex: 0,\n data: [\n // SVG local coords.\n [488.2358421078053, 459.70913833075736],\n [770.3415644319939, 757.9672194986475],\n [1180.0329284196291, 743.6141808346214],\n ]\n }\n};\n```\n\n另外,有种简便方法可以获得 SVG 的坐标。\n```ts\nmyChart.setOption({\n geo: {\n map: \'some_svg\'\n }\n});\nmyChart.getZr().on(\'click\', function (params) {\n var pixelPoint = [params.offsetX, params.offsetY];\n var dataPoint = myChart.convertFromPixel({ geoIndex: 0 }, pixelPoint);\n // 在 SVG 上点击时,坐标会被打印。\n // 这些坐标可以在 `series.data` 里使用。\n console.log(dataPoint);\n});\n```\n\n参见示例 [SVG Scatter](${exampleEditorPath}geo-svg-scatter-simple)、[SVG Lines](${exampleEditorPath}geo-svg-lines)、[SVG Traffic](${exampleEditorPath}geo-traffic)。\n\n\n## 暂不支持的 SVG 功能 [[[#unsupported-svg-features]]]\n\n实现一个完整的 SVG 解析器有点困难。虽然已经支持了常用的 SVG 功能,但至少下面列出的这些还没支持:\n\n+ 翻转(flip)和倾斜(skew)(将在 `v5.1.2` 支持):\n + 不支持 `transform: skew(...)`(包括包含 skew 的 `transform: matrix(...)`)。\n + 不支持当 `transform: scale(x, y)` 中 `x`/`y` 正负不同且有 `rotate`(例如,`scale: (1, -1), rotate(90)`)。\n+ 不支持 `<style>` 标签。\n + 但内联样式是支持的(例如支持 `<path style="color:red" />`)。\n+ 单位:\n + 只支持 `px`。不支持其他单位如 `width="231.65mm"`。\n + 不支持百分比值,如不支持 `<svg width="30%" height="40%">`。\n+ `<defs>` 标签:\n + 只支持 `<linearGradient>`、`<radialGradient>`。\n + 还不支持在 `<defs>` 中定义其他元素(如 `<pattern>`、`<path>`、...)。\n+ `<linearGradient>`、`<radialGradient>`:\n + 不支持 `fx`、`fy`。\n + 不支持 `gradientTransform`。\n+ `fill:url(..)`, `stroke:utl(..)`:\n + 只支持 `url(#someId)`。\n + 不支持其他 URL 模式,例如不支持:\n + `url(https://example.com/images/myImg.jpg)`。\n + `url(data:image/png;base64,iRxVB0...)`。\n + `url(myFont.woff)`。\n+ `<switch>` 标签:\n + `<switch>` 标签内的所有内容都会显示。不支持“切换”功能。\n+ `<text>`。\n + 不支持 `textPath`。\n + 不支持 [Addressable character](https://www.w3.org/TR/SVG/text.html#TermAddressableCharacter),也就是说:\n ```xml\n \x3c!-- 不支持: --\x3e\n <tspan x="0 4.94 9.89">abc</tspan>。\n \x3c!-- 支持: --\x3e\n <tspan x="0">A</tspan>\n <tspan x="4.94">b</tspan>\n <tspan x="9.89">C</tspan>\n ```\n'}}]); |