This is an automated email from the ASF dual-hosted git repository. sushuang pushed a commit to branch geo-base-map in repository https://gitbox.apache.org/repos/asf/echarts-handbook.git
commit 9aa85c28e4889556c93da2af5d2e136d97307e6e Author: 100pah <[email protected]> AuthorDate: Sat Aug 23 19:27:08 2025 +0800 Migrate tutorial "geo-svg-map" to handbook. --- .../en/how-to/component-types/geo/svg-base-map.md | 364 +++++++++++++++++++++ contents/en/posts.yml | 8 + .../zh/how-to/component-types/geo/svg-base-map.md | 358 ++++++++++++++++++++ contents/zh/posts.yml | 8 + 4 files changed, 738 insertions(+) diff --git a/contents/en/how-to/component-types/geo/svg-base-map.md b/contents/en/how-to/component-types/geo/svg-base-map.md new file mode 100644 index 0000000..e2318df --- /dev/null +++ b/contents/en/how-to/component-types/geo/svg-base-map.md @@ -0,0 +1,364 @@ +# SVG Base Map + +Since `v5.1.0`, ECharts support to use SVG as the base map in [geo coordinate system](${optionPath}geo) and [map series](${optionPath}series-map), where previously only [GeoJSON](${apiPath}echarts.registerMap) is supported. + +This feature enables ECharts to display SVG in either of the render modes (`canvas` render mode and `svg` render mode), and enables features like [zoom](${optionPath}geo.roam), [pan](${optionPath}geo.roam), [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) on SVG with only simple some ECharts option [...] + +There are several examples where SVG base map is used: +[Beef Cuts](${exampleEditorPath}geo-beef-cuts) | +[Organ Visualization](${exampleEditorPath}geo-organ) | +[Flight Seatmap](${exampleEditorPath}geo-seatmap-flight) | +[SVG Map](${exampleEditorPath}geo-svg-map) | +[SVG Scatter](${exampleEditorPath}geo-svg-scatter-simple) | +[SVG Lines](${exampleEditorPath}geo-svg-lines) | +[SVG Traffic](${exampleEditorPath}geo-svg-traffic) + + +## Basic Usage [[[#basic-usage]]] + +The usage of SVG base map is the same as the usage of [GeoJSON](${apiPath}echarts.registerMap). + +If using it in [geo coordinate system](${optionPath}geo): +```ts +$.get('map/organ.svg', function (svg) { + // Firstly we need to register SVG raw string or parsed SVG DOM + // to echarts with a name: + echarts.registerMap('organ_diagram', {svg: svg}); + + var chart = echarts.init(document.getElementById('main')); + chart.setOption({ + geo: { + // Reference it in echarts option. + map: 'organ_diagram', + ... + } + }); +}); +``` + +If using it in [map series](${optionPath}series-map): +```ts +$.get('map/beef_cuts.svg', function (svg) { + // Firstly we need to register SVG raw string or parsed SVG DOM + // to echarts with a name: + echarts.registerMap('beef_cuts_diagram', {svg: svg}); + + var chart = echarts.init(document.getElementById('main')); + chart.setOption({ + series: { + type: 'map', + // Reference it in echarts option. + map: 'beef_cuts_diagram', + ... + } + }); +}); +``` + + +## Zoom and Pan [[[#zoom-and-pan]]] + +For [Geo coordinate system](${optionPath}geo) +```ts +option = { + geo: { + // Enable zoom and pan. + roam: true, + ... + } +}; +``` +For [map series](${optionPath}series-map) +```ts +option = { + series: { + type: 'map', + // Enable zoom and pan. + roam: true, + ... + } +}; +``` + +See [roam](${optionPath}geo.roam). +See also example [SVG Map](${exampleEditorPath}geo-svg-map). + + +## Named Element [[[#named-element]]] + +If intending to interact with some elements of SVG, we need to mark those elements in SVG firstly. That can be done simply by adding names to the target elements. The interaction related feature like [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) depend on those named elements. + +For example, we add name attribute `name="named_rect"` only to the left SVG `path`. +```xml +<?xml version="1.0" encoding="utf-8"?> +<svg xmlns="http://www.w3.org/2000/svg" version="1.2" fill-rule="evenodd" xml:space="preserve"> + <path name="named_rect" d="M 0,0 L 0,100 100,100 100,0 Z" fill="#765" /> + <path d="M 150,0 L 150,100 250,100 250,0 Z" fill="#567" /> +</svg> +``` +Then hover on the left rect, it can be highlighted, whereas the right one can not. + +<md-example src="doc-example/geo-svg-named-basic" width="100%" height="200"></md-example> + +Option for some certain named elements can be specified in [geo.regions](${optionPath}geo.regions), like: +```ts +option = { + geo: { + map: 'some_svg', + regions: [{ + name: 'element_name_1', + itemStyle: { ... } + }, { + name: 'element_name_2', + itemStyle: { ... } + }] + } +}; +``` + + +Note: ++ These SVG elements can be named and recognized by ECharts: +`rect`, `circle`, `line`, `ellipse`, `polygon`, `polyline`, `path`, `text`, `tspan`, `g`. ++ It is supported that multiple elements are named with the same name, will they will be highlighted/selected together. + + +## Style Customization [[[#style-customization]]] + +Although the style (such as color, font, lineWidth, ...) of SVG Elements can be defined directly in SVG file, style of named elements can also be customized in ECharts option, which will be handy in some scenario. + +Styles can be specified in [geo.itemStyle](${optionPath}geo.itemStyle) and [series-map.itemStyle](${optionPath}series-map.itemStyle) (also includes `emphasis.itemStyle`, `select.itemStyle`, `blur.itemStyle`, `regions[i].itemStyle`, `regions[i].emphasis.itemStyle`, `regions[i].select.itemStyle`, `regions[i].blur.itemStyle`). Some default style of the named elements can also be removed here (e.g., set `emphasis.itemStyle.color: null` to prevent the fill color from changing when mouse hovering.) + +Moreover, named elements can also be styled by [visualMap component](${optionPath}visualMap) if using [series-map](${optionPath}series-map). See [Beef Cuts](${exampleEditorPath}geo-beef-cuts). + + +Note: +Only these named elements can be styled in `itemStyle`: +`rect`, `circle`, `line`, `ellipse`, `polygon`, `polyline`, `path`. + + +## Select [[[#select]]] + +Named elements can adopt "select" feature by setting [geo.selectedMode](${optionPath}geo.selectedMode) or [series-map.selectedMode](${optionPath}series-map.selectedMode) as `'single'` or `'multiple'`. The style of element when selected can be specified in [geo.select](${optionPath}geo.select) or [series-map.select](${optionPath}series-map.select). + +The selected names can be obtained by [geoselectchanged](${apiPath}event.geoselectchanged) event, like: +```ts +myChart.on('geoselectchanged', function (params) { + var selectedNames = params.allSelected[0].name; + console.log('selected', selectedNames); +}); +``` + +See [Flight Seatmap](${exampleEditorPath}geo-seatmap-flight) for more details. + + +## Emphasis and Focus-Blur [[[#emphasis-and-focus-blur]]] + +`emphasis` state (highlight when hovering) can be auto adopted to named elements. + +Especially, [geo.emphasis.focus](${optionPath}geo.emphasis.focus) and be set as `'self'` to enable "focus-blur" feature, where all all of the other elements will be blurred when hovering on an named element. + +See [Organ Visualization](${exampleEditorPath}geo-organ) for more details. + + +## Tooltip [[[#tooltip]]] + +Tooltip can be enabled or disabled on named elements. +```ts +option = { + // Need to declare the root tooltip to + // enable tooltip feature on ECharts. + tooltip: {}, + geo: { + map: 'some_svg', + tooltip: { + // Use `show` to enable/disable tooltip + // on geo coordinate system. + show: true + }, + regions: [{ + name: 'some_name1', + // Set named element specified tooltip option if needed. + tooltip: { + formatter: 'some special tooltip 1' + } + }, { + name: 'some_name2', + tooltip: { + formatter: 'some special tooltip 2' + } + }] + } +}; +``` + +If intending to disable the geo tooltip when hovering a on named elements, just: +```ts +option = { + tooltip: {}, + geo: { + map: 'some_svg', + tooltip: { + show: false + } + } +}; +``` + +See [SVG Map](${exampleEditorPath}geo-svg-map) for more details. + + +## Label [[[#label]]] + +Although text label can be declared in SVG file directly via `<text>`/`<tspan>`, we can also use ECharts built-in label feature on named elements by specifying [geo.label](${optionPath}geo.label) or [series-map.label](${optionPath}series-map.label). + +By default the label feature is enabled when hovering on a named element. If intending to disable it, just: +```ts +option = { + geo: { + map: 'some_svg', + emphasis: { + label: { + show: false + } + } + } +}; +``` + +When multiple elements need to share one label text, we have two choices: ++ Wrap those elements in a named `<g>` (e.g., `<g name="name_a">`), where a single label will be displayed and located based on the bounding rect of the `<g>`. ++ Name those elements with the same name (e.g., `<path name="name_b"/><path name="name_b"/>`), where multiple labels will be displayed and located based on each elements self. + +For example (hover to show the labels): +<md-example src="doc-example/geo-svg-label-basic" width="100%" height="300"></md-example> + +Note: Only these named elements can be labeled via `label` option: +`rect`, `circle`, `line`, `ellipse`, `polygon`, `polyline`, `path`, `g`. + +See also [Organ Visualization](${exampleEditorPath}geo-organ) for the usage of label. + + +## Events [[[#events]]] + +Mouse events or touch events of named elements can be listened simply by: +```ts +// 'name1' is a name of a SVG element. +myChart.on('click', { geoIndex: 0, name: 'name1' }, function (params) { + console.log(params); +}); +``` + + +## Layout of SVG Base Map [[[#layout-of-svg-base-map]]] + +By default ECharts will position the SVG base map in the center of the canvas. If need some adjust, we usually only adjust [layoutCenter](${optionPath}geo.layoutCenter)/[layoutSize](${optionPath}geo.layoutSize), and occasionally `<svg viewBox="...">`/[geo.boundingCoords](${optionPath}geo.boundingCoords) (difference: clip or not). In most cases they are enough. + +If need some advanced precise control of the position and zoom, several concepts below can be noticed. + +The layout rule and options of [geo coordinate system](${optionPath}geo) and [map series](${optionPath}series-map) are the same. So we only demonstrate [geo coordinate system](${optionPath}geo) below. + +<md-example src="doc-example/geo-svg-layout-basic" width="100%" height="600"></md-example> + +The demo above shows six [geo coordinate system](${optionPath}geo) with three SVG files in a single ECharts canvas. Each two [geo](${optionPath}geo) that are in the same column use the same SVG file. + +Firstly, what shapes looks like is determined by SVG file itself. That is, in the demo above, determined by the `<circle>` and `viewBox` attribute (`viewBox` cut (clips) the circle). We can noticed that the final shape outlines in each column are the same (despite the difference in position, size and scratch), since they use the same SVG file. + +Secondly, users can use either of the two option groups below to determine the location and the size of the `geo view port` of [geo coordinate system](${optionPath}geo) according to the entire chart canvas (all of these options are measured in echarts canvas pixel, or percentage value): ++ [layoutCenter](${optionPath}geo.layoutCenter), [layoutSize](${optionPath}geo.layoutSize) (recommended). ++ [top](${optionPath}geo.top), [right](${optionPath}geo.right), [bottom](${optionPath}geo.bottom), [left](${optionPath}geo.left) (which is used in the demo above). + +In the demo above, the six geo `geo view ports` are displayed as six black squares. + +Thirdly, a `bounding rect` of the SVG is determined, which is determined by methods below (all of them are measured in SVG local unit): +1. If [geo.boundingCoords](${optionPath}geo.boundingCoords) is specified, use it as `bounding rect`. +2. Else if `<svg width="..." height="...">` is specified, use `[0, 0, width, height]` as `bounding rect`. (If only `width` or only `height` is specified, only use `[0, width]` or `[0, height]`). +3. Else if `svg viewBox="...">` is specified, use `viewBox` as `bounding rect`. +4. Else use the union bounding rect of all of the SVG elements as the `bounding rect`. +5. If [geo.center](${optionPath}geo.center) or [geo.zoom](${optionPath}geo.zoom) is specified, transform the `bounding rect` determined by `1~4` above. + +Having `bounding rect` determined, it will be placed into its corresponding `geo view port`: ++ If [layoutCenter](${optionPath}geo.layoutCenter), [layoutSize](${optionPath}geo.layoutSize) is used, the `bounding rect` will be placed at the center and as big as possible into the `geo view port` (keep aspect ratio). ++ If [top](${optionPath}geo.top), [right](${optionPath}geo.right), [bottom](${optionPath}geo.bottom), [left](${optionPath}geo.left) is used, the view rect will be stretched to fill the `geo view port` entirely. + + +## Place Series on SVG Base Map [[[#place-series-on-svg-base-map]]] + +Series like [scatter](${optionPath}series-scatter), [effectScatter](${optionPath}series-effectScatter), [lines](${optionPath}series-lines), [custom](${optionPath}series-custom) that are available on [geo coordinate system](${optionPath}geo) can also be positioned and displayed on SVG base map. + +Note that in this kind of usage the unit of series data value is the SVG file local coords. For example: +```ts +option = { + geo: { + map: 'some_svg' + }, + series: { + type: 'effectScatter', + coordinateSystem: 'geo', + geoIndex: 0, + data: [ + // SVG local coords. + [488.2358421078053, 459.70913833075736], + [770.3415644319939, 757.9672194986475], + [1180.0329284196291, 743.6141808346214], + ] + } +}; +``` + +By the way, there is a simple approach to get SVG local coord: +```ts +myChart.setOption({ + geo: { + map: 'some_svg' + } +}); +myChart.getZr().on('click', function (params) { + var pixelPoint = [params.offsetX, params.offsetY]; + var dataPoint = myChart.convertFromPixel({ geoIndex: 0 }, pixelPoint); + // When click, the data in SVG local coords will be printed, + // which can be used in `series.data`. + console.log(dataPoint); +}); +``` + +See also [SVG Scatter](${exampleEditorPath}geo-svg-scatter-simple), [SVG Lines](${exampleEditorPath}geo-svg-lines), [SVG Traffic](${exampleEditorPath}geo-traffic). + + +## Unsupported SVG features [[[#unsupported-svg-features]]] + +Unfortunately it is difficult to implement a complete SVG parser. While the common SVG features are supported, at least these features listed below are not supported yet: + ++ Flip and skew (will be supported `v5.1.2`): + + Not support `transform: skew(...)` (including `transform: matrix(...)` that includes skew). + + Not support `transform: scale(x, y)` that `x`, `y` has different sign while has `rotate` (e.g., `scale: (1, -1), rotate(90)`). ++ Standalone `<style>` tag is not supported. + + But inline style is supported (e.g., `<path style="color:red" />`). ++ Unit: + + Only `px` is supported. Other unit like `width="231.65mm"` is not supported. + + Percentage value like `<svg width="30%" height="40%">` is not supported. ++ `<defs>` tag: + + Only `<linearGradient>`, `<radialGradient>` are supported. + + other elements (e.g., `<pattern>`, `<path>`, ...) defined in `<defs>` are not supported yet. ++ `<linearGradient>`, `<radialGradient>`: + + `fx`, `fy` is not supported. + + `gradientTransform` attribute is not supported. ++ `fill:url(...)`, `stroke:utl(...)`: + + Only `url(#someId)` is supported. + + Other URL patterns are not supported. e.g., + + `url(https://example.com/images/myImg.jpg)`; + + `url(data:image/png;base64,iRxVB0…)`; + + `url(myFont.woff)`; ++ `<switch>` tag: + + All the content inside `<switch>` tag will be displayed. The "switch" feature is not supported. ++ `<text>`: + + `textPath` is not supported. + + [Addressable character](https://www.w3.org/TR/SVG/text.html#TermAddressableCharacter) is not supported. That is, + ```xml + <!-- Not supported: --> + <tspan x="0 4.94 9.89">abc</tspan> + <!-- Supported: --> + <tspan x="0">a</tspan> + <tspan x="4.94">b</tspan> + <tspan x="9.89">c</tspan> + ``` diff --git a/contents/en/posts.yml b/contents/en/posts.yml index e936637..bb6825a 100644 --- a/contents/en/posts.yml +++ b/contents/en/posts.yml @@ -110,6 +110,14 @@ children: - title: Basic Scatter dir: basic-scatter + - title: Common Components + dir: component-types + children: + - title: Geo + dir: geo + children: + - title: SVG Base Map + dir: svg-base-map - title: Mobile dir: mobile draft: true diff --git a/contents/zh/how-to/component-types/geo/svg-base-map.md b/contents/zh/how-to/component-types/geo/svg-base-map.md new file mode 100644 index 0000000..e083b13 --- /dev/null +++ b/contents/zh/how-to/component-types/geo/svg-base-map.md @@ -0,0 +1,358 @@ +# SVG 底图 + +从 `v5.1.0` 开始,ECharts 支持在 [地理坐标系(geo)](${optionPath}geo) 和 [地图系列(map series)](${optionPath}series-map) 中使用 SVG 作为底图。之前只支持 [GeoJSON](${apiPath}echarts.registerMap) 格式的底图。 + +有了这个功能,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)](${op [...] + +这些是使用 SVG 底图的例子: + +[庖丁解牛](${exampleEditorPath}geo-beef-cuts) | +[内脏数据](${exampleEditorPath}geo-organ) | +[航班选座](${exampleEditorPath}geo-seatmap-flight) | +[地图](${exampleEditorPath}geo-svg-map) | +[散点图](${exampleEditorPath}geo-svg-scatter-simple) | +[路径图](${exampleEditorPath}geo-svg-lines) | +[交通](${exampleEditorPath}geo-svg-traffic) + + +## 基本用法 [[[#basic-usage]]] + +SVG 底图的用法与 [GeoJSON](${apiPath}echarts.registerMap) 底图的用法相同。 + +如果在 [地理坐标系(geo)](${optionPath}geo) 中使用: +```ts +$.get('map/organ.svg', function (svg) { + // 首先向 echarts 注册 SVG 字符串或解析过的 SVG DOM + echarts.registerMap('organ_diagram', {svg: svg}); + + var chart = echarts.init(document.getElementById('main'))。 + chart.setOption({ + geo: [{ + // 引用注册过的底图。 + map: 'organ_diagram', + ... + }] + }); +}); +``` + +如果在 [地图系列(map series)](${optionPath}series-map) 中使用: +```ts +$.get('map/beef_cuts.svg', function (svg) { + // 首先向 echarts 注册 SVG 字符串或解析过的 SVG DOM + echarts.registerMap('beef_cuts_diagram', {svg: svg})。 + + var chart = echarts.init(document.getElementById('main'))。 + chart.setOption({ + series: { + type: 'map', + // 引用注册过的底图。 + map: 'beef_cuts_diagram', + ... + } + }); +}); +``` + + +## 缩放和平移 [[[#zoom-and-pan]]] + +[地理坐标系(geo)](${optionPath}geo) +```ts +option = { + geo: { + // 启用缩放和平移。 + roam: true, + ... + } +}; +``` +[地图系列(map series)](${optionPath}series-map) +```ts +option = { + series: { + type: 'map', + // 启用缩放和平移。 + roam: true, + ... + } +}; +``` + +参见例子 [roam](${optionPath}geo.roam)、[SVG 地图](${exampleEditorPath}geo-svg-map)。 + + +## 具名元素 [[[#named-element]]] + +如果要控制 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) 这类交互相关的功能)都依赖于对元素的命名。 + +如下例,我们只在左边的 SVG `path` 上添加名称属性 `name="named_rect"`: +```xml +<?xml version="1.0" encoding="utf-8"?> +<svg xmlns="http://www.w3.org/2000/svg" version="1.2" fill-rule="evenodd" xml:space="preserve"> + <path name="named_rect" d="M 0,0 L 0,100 100,100 100,0 Z" fill="#765" /> + <path d="M 150,0 L 150,100 250,100 250,0 Z" fill="#567" /> +</svg> +``` +这样,鼠标 hover 时能高亮左边的矩形,但是右边的不行。 + +<md-example src="doc-example/geo-svg-named-basic" width="100%" height="200"></md-example> + +我们还可以在 [geo.regions](${optionPath}geo.regions) 中为具名元素指定一些专属配置项: +```ts +option = { + geo: { + map: 'some_svg', + regions: [{ + name: 'element_name_1', + itemStyle: { ... } + }, { + name: 'element_name_2', + itemStyle: { ... } + }] + } +}; +``` + +注意: ++ 只有这些 SVG 元素可以被命名: +`rect`、`circle`、`line`、`ellipse`、`polygon`、`polyline`、`path`、`text`、`tspan`、`g`。 ++ 支持多个元素以相同的名称命名,这样它们能被同时高亮、选中。 + + +## 自定义样式 [[[#style-customization]]] + +虽然 SVG 元素的样式(如颜色、字体、线宽等等)都能直接在 SVG 文件中定义,但 ECharts 也支持在 `option` 中为具名元素定制样式,这能提供不少便利。 + +可以在 [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 时填充色就不会改变)。 + +此外,使用 [series-map](${optionPath}series-map) 时,也可以用 [visualMap 组件](${optionPath}visualMap) 为具名元素赋予样式。参见例子 [庖丁解牛](${exampleEditorPath}geo-beef-cuts)。 + +注意: +只有这些具名元素可以在 `itemStyle` 中设置样式: +`rect`、`circle`、`line`、`ellipse`、`polygon`、`polyline`、`path`。 + + +## 元素的“选中”能力(select) [[[#select]]] + +如果想使具名元素能被“选中”,把 [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) 中设定。 + +可以通过 [geoselectchanged](${apiPath}event.geoselectchanged) 事件获得所有被选中者的名称,例如: +```ts +myChart.on('geoselectchanged', function (params) { + var selectedNames = params.allSelected[0].name; + console.log('selected', selectedNames); +}); +``` + +参见例子 [航班选座](${exampleEditorPath}geo-seatmap-flight)。 + + +## 元素的“高亮强调”(emphasis)和“聚焦-淡出”(focus-blur) [[[#emphasis-and-focus-blur]]] + +具名元素可以自动在鼠标 hover 时有“高亮强调”(emphasis)的能力。 + +此外,可以把 [geo.emphasis.focus](${optionPath}geo.emphasis.focus) 设置为 `'self'` 来启用 “聚焦-淡出”(focus-blur)功能。也就是,当鼠标 hover 在一个具名元素上时,所有其他元素都会被淡出。 + +参见例子 [Organ Visualization](${exampleEditorPath}geo-organ)。 + + +## 提示框(tooltip) [[[#tooltip]]] + +可以在具名元素上启用或禁用提示框(tooltip)功能。 +```ts +option = { + // 在 option 根部声明 tooltip 以整体开启 tooltip 功能。 + tooltip: {}, + geo: { + map: 'some_svg', + tooltip: { + // 用 `show` 来启用/禁用 geo 上的 tooltip。 + show: true + }, + regions: [{ + name: 'some_name1', + // 如果需要的话,可以对特定具名元素指定 tooltip 参数。 + tooltip: { + formatter: '一些特殊的提示 1' + } + }, { + name: 'some_name2', + tooltip: { + formatter: '一些特殊的提示 2' + } + }] + } +}; +``` + +如果想单独禁用 geo 上的 tooltip,只需: +```ts +option = { + tooltip: {}, + geo: { + map: 'some_svg', + tooltip: { + show: false + } + } +}; +``` + +参见例子 [SVG 地图](${exampleEditorPath}geo-svg-map)。 + + +## 标签(label) [[[#label]]] + +虽然可以直接在 SVG 中定义 `<text>`/`<tspan>` 来显示文本标签,但 ECharts 也支持用 [geo.label](${optionPath}geo.label) 或 [series-map.label](${optionPath}series-map.label) 来设置底图上的标签。 + +标签功能默认在鼠标 hover 时是启用的。如果想禁用标签,只需: +```ts +option = { + geo: { + map: 'some_svg', + emphasis: { + label: { + show: false + } + } + } +}; +``` + +当想要多个元素共享一个标签时,我们有两种选择: ++ 将这些元素包裹在一个具名的 `<g>` 中(如 `<g="name_a">`)中,这样只会显示一个标签,并且基于 `<g>` 的 `boundingRect` 定位。 ++ 给这些元素起相同的名字(如 `<path name="name_b"/><path name="name_b"/>`),这样每个元素都会显示一个标签,并且会根据每个元素自身显示和定位。 + +例如(将鼠标 hover 到元素上能显示标签): +<md-example src="doc-example/geo-svg-label-basic" width="100%" height="300"></md-example> + +注意:只有这些具名元素可以设置 `label`: +`rect`、`circle`、`line`、`ellipse`、`polygon`、`polyline`、`path`、`g`。 + +标签的用法也参见示例 [Organ Visualization](${exampleEditorPath}geo-organ)。 + + +## 事件 [[[#events]]] + +可以用如下方式监听具名元素的鼠标事件或者触摸事件: +```ts +// 'name1' 是一个 SVG 元素的名字。 +myChart.on('click', { geoIndex: 0, name: 'name1' }, function (params) { + console.log(params); +}); +``` + + +## SVG 底图的布局 [[[#layout-of-svg-base-map]]] + +在默认情况下,ECharts 会将 SVG 底图放置在画布的中心。如果需要调整的话,一般只调整 [layoutCenter](${optionPath}geo.layoutCenter)/[layoutSize](${optionPath}geo.layoutSize),偶尔也可能要调整 `<svg viewBox="...">`/[geo.boundingCoords](${optionPath}geo.boundingCoords)(它们两个的区别是:是否产生剪裁)。在大多数情况下,用这些已经足够了。 + +如果要做一些精确的位置定制,那么还得了解下面这些概念。 + +[地理坐标系(geo)](${optionPath}geo) 和 [地图系列(map series)](${optionPath}series-map) 的布局规则和选项都是一样的。所以下面我们只讲 [地理坐标系(geo)](${optionPath}geo)。 + +<md-example src="doc-example/geo-svg-layout-basic" width="100%" height="600"></md-example> + +上面的例子只有一个 ECharts 画布,其中三个 SVG 展示在六个 [地理坐标系(geo)](${optionPath}geo) 中。同一列中的两个 [地理坐标系(geo)](${optionPath}geo) 使用相同的 SVG。 + +首先,形状的外观是由 SVG 文件本身决定的。也就是说,在上例中,由 `<circle>` 和 `viewBox` 属性决定(`viewBox` 会切割圆形)。可以注意,每一列的形状轮廓都一样(不管它们的位置、大小是否不同和是否被拉伸),因为它们使用的是同一个 SVG。 + +其次,用户可以用下面任一组选项,指定 [地理坐标系(geo)](${optionPath}geo) 的视口(`view port`)的位置和大小(它们的单位都是 echarts 画布的像素,或者百分比值): ++ [layoutCenter](${optionPath}geo.layoutCenter)、[layoutSize](${optionPath}geo.layoutSize)(最常用)。 ++ [top](${optionPath}geo.top)、[right](${optionPath}geo.right)、[bottom](${optionPath}geo.bottom)、[left](${optionPath}geo.left)(在上例中使用的是这组)。 + +在上例中,六个 `geo view port` 用六个黑色方块表示。 + +第三,确定 SVG 的 `bounding rect`。`bounding rect` 由以下方法决定(它们的单位都是 SVG 内部元素的度量单位): +1. 如果设定了 [geo.boundingCoords](${optionPath}geo.boundingCoords),则用它作 `bounding rect`。 +2. 否则,如果设定了 `<svg width="..." height="...">`,则用 `[0, 0, width, height]` 作为 `bounding rect`。(如果只设定了 `width` 或 `height`,则只使用 `[0, width]` 或 `[0, height]`)。 +3. 否则,如果设定了 `<svg viewBox="...">`,则用 `viewBox` 作 `bounding rect`。 +4. 否则,由整个 SVG 所有元素 `bounding rect` 的并集得到最终 `bounding rect`。 +5. 如果设定了 [geo.center](${optionPath}geo.center) 或 [geo.zoom](${optionPath}geo.zoom),则把上述 `1~4` 得到的 `bounding rect` 进行相应的 `transform`。 + +`bounding rect` 确定后,会放置到相应的 `geo view port` 里: ++ 如果用的是 [layoutCenter](${optionPath}geo.layoutCenter)、[layoutSize](${optionPath}geo.layoutSize),`bounding rect` 会置于 `geo view port` 的中心,并尽量填满 `geo view port`(保持长宽比)。 ++ 如果用的是 [top](${optionPath}geo.top)、[right](${optionPath}geo.right)、[bottom](${optionPath}geo.bottom)、[left](${optionPath}geo.left),`bounding rect` 会被拉伸,完全填充 `geo view port`。 + + +## 在 SVG 底图上绘制系列 [[[#place-series-on-svg-base-map]]] + +[scatter](${optionPath}series-scatter)、[effectScatter](${optionPath}series-effectScatter)、[lines](${optionPath}series-lines)、[custom](${optionPath}series-custom) 这些在 [地理坐标系(geo)](${optionPath}geo) 中可用的系列都可以在 SVG 底图上定位和显示。 + +在这种用法中,`series.data` 的值的单位即为是 SVG 内部元素的度量单位。比如说: +```ts +option = { + geo: { + map: 'some_svg' + }, + series: { + type: 'effectScatter', + coordinateSystem: 'geo', + geoIndex: 0, + data: [ + // SVG local coords. + [488.2358421078053, 459.70913833075736], + [770.3415644319939, 757.9672194986475], + [1180.0329284196291, 743.6141808346214], + ] + } +}; +``` + +另外,有种简便方法可以获得 SVG 的坐标。 +```ts +myChart.setOption({ + geo: { + map: 'some_svg' + } +}); +myChart.getZr().on('click', function (params) { + var pixelPoint = [params.offsetX, params.offsetY]; + var dataPoint = myChart.convertFromPixel({ geoIndex: 0 }, pixelPoint); + // 在 SVG 上点击时,坐标会被打印。 + // 这些坐标可以在 `series.data` 里使用。 + console.log(dataPoint); +}); +``` + +参见示例 [SVG Scatter](${exampleEditorPath}geo-svg-scatter-simple)、[SVG Lines](${exampleEditorPath}geo-svg-lines)、[SVG Traffic](${exampleEditorPath}geo-traffic)。 + + +## 暂不支持的 SVG 功能 [[[#unsupported-svg-features]]] + +实现一个完整的 SVG 解析器有点困难。虽然已经支持了常用的 SVG 功能,但至少下面列出的这些还没支持: + ++ 翻转(flip)和倾斜(skew)(将在 `v5.1.2` 支持): + + 不支持 `transform: skew(...)`(包括包含 skew 的 `transform: matrix(...)`)。 + + 不支持当 `transform: scale(x, y)` 中 `x`/`y` 正负不同且有 `rotate`(例如,`scale: (1, -1), rotate(90)`)。 ++ 不支持 `<style>` 标签。 + + 但内联样式是支持的(例如支持 `<path style="color:red" />`)。 ++ 单位: + + 只支持 `px`。不支持其他单位如 `width="231.65mm"`。 + + 不支持百分比值,如不支持 `<svg width="30%" height="40%">`。 ++ `<defs>` 标签: + + 只支持 `<linearGradient>`、`<radialGradient>`。 + + 还不支持在 `<defs>` 中定义其他元素(如 `<pattern>`、`<path>`、...)。 ++ `<linearGradient>`、`<radialGradient>`: + + 不支持 `fx`、`fy`。 + + 不支持 `gradientTransform`。 ++ `fill:url(..)`, `stroke:utl(..)`: + + 只支持 `url(#someId)`。 + + 不支持其他 URL 模式,例如不支持: + + `url(https://example.com/images/myImg.jpg)`。 + + `url(data:image/png;base64,iRxVB0...)`。 + + `url(myFont.woff)`。 ++ `<switch>` 标签: + + `<switch>` 标签内的所有内容都会显示。不支持“切换”功能。 ++ `<text>`。 + + 不支持 `textPath`。 + + 不支持 [Addressable character](https://www.w3.org/TR/SVG/text.html#TermAddressableCharacter),也就是说: + ```xml + <!-- 不支持: --> + <tspan x="0 4.94 9.89">abc</tspan>。 + <!-- 支持: --> + <tspan x="0">A</tspan> + <tspan x="4.94">b</tspan> + <tspan x="9.89">C</tspan> + ``` diff --git a/contents/zh/posts.yml b/contents/zh/posts.yml index 8850c6c..08c9e74 100644 --- a/contents/zh/posts.yml +++ b/contents/zh/posts.yml @@ -112,6 +112,14 @@ children: - title: 基础散点图 dir: basic-scatter + - title: 常用组件 + dir: component-types + children: + - title: 地理坐标系(Geo) + dir: geo + children: + - title: SVG 底图 + dir: svg-base-map - title: 移动端优化 dir: mobile draft: true --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
