SVG 底图
自 v5.1.0 起,ECharts 支持在 geo 坐标系 和 map 系列 中使用 SVG 作为底图,之前仅支持 GeoJSON。
此功能使得 ECharts 能够在 canvas 渲染模式和 svg 渲染模式下显示 SVG,并支持诸如 缩放、平移、选择、强调、聚焦模糊、标签、labelLayout、tooltip 等功能,只需少量的 ECharts 配置。可在 geo 坐标系 上使用的系列,如 scatter、effectScatter、lines、custom,也可以基于 SVG 底图进行定位和显示。
以下是使用 SVG 底图的几个示例: Beef Cuts | Organ Visualization | Flight Seatmap | SVG Map | SVG Scatter | SVG Lines | SVG Traffic
基本用法
SVG 底图的使用方式与 GeoJSON 的使用方式相同。
如果在 geo 坐标系 中使用
$.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',
...
}
});
});如果在 map 系列 中使用
$.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',
...
}
});
});缩放和平移
针对 Geo 坐标系
option = {
geo: {
// Enable zoom and pan.
roam: true,
...
}
};option = {
series: {
type: 'map',
// Enable zoom and pan.
roam: true,
...
}
};具名元素
如果希望与 SVG 的某些元素进行交互,需要先在 SVG 中标记这些元素。这可以通过为目标元素添加 name 属性来简单实现。诸如 select、emphasis、focus‑blur、label、labelLayout、tooltip 等交互相关特性都依赖这些具名元素。
例如,只在左侧的 SVG path 上添加属性 name="named_rect"。
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="https://w3org.cn/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>对某些具名元素的配置可以在 geo.regions 中指定,例如
option = {
geo: {
map: 'some_svg',
regions: [{
name: 'element_name_1',
itemStyle: { ... }
}, {
name: 'element_name_2',
itemStyle: { ... }
}]
}
};注意
- 这些 SVG 元素可以被 ECharts 命名并识别:
rect、circle、line、ellipse、polygon、polyline、path、text、tspan、g。 - 支持为多个元素使用相同的 name,届时它们会一起被高亮/选中。
样式自定义
虽然 SVG 元素的样式(如颜色、字体、线宽等)可以直接在 SVG 文件中定义,但具名元素的样式也可以在 ECharts 配置中定制,这在某些场景下非常方便。
样式可以在 geo.itemStyle 与 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 设为 null,即可防止鼠标悬停时填充颜色变化。
此外,若使用 series‑map,具名元素还可以通过 visualMap 组件 进行样式映射,详见 Beef Cuts。
注意:只有以下具名元素可以在 itemStyle 中被样式化:rect、circle、line、ellipse、polygon、polyline、path。
选择
具名元素可通过将 geo.selectedMode 或 series‑map.selectedMode 设置为 'single' 或 'multiple' 来启用“选择”特性。选中时的样式可在 geo.select 或 series‑map.select 中指定。
选中的 name 可以通过 geoselectchanged 事件获取,例如
myChart.on('geoselectchanged', function (params) {
var selectedNames = params.allSelected[0].name;
console.log('selected', selectedNames);
});更多细节请参见 Flight Seatmap。
强调与聚焦模糊
emphasis 状态(悬停时高亮)会自动应用到具名元素。
特别是,可将 geo.emphasis.focus 设置为 'self',启用 “focus‑blur” 功能,即在悬停某个具名元素时,其他所有元素都会被模糊。
更多细节请参见 Organ Visualization。
提示框
Tooltip 可以在具名元素上开启或关闭。
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'
}
}]
}
};如果希望在悬停具名元素时关闭 geo 的 tooltip,只需
option = {
tooltip: {},
geo: {
map: 'some_svg',
tooltip: {
show: false
}
}
};更多细节请参见 SVG Map。
标签
虽然可以直接在 SVG 文件中使用 <text>/<tspan> 声明文字标签,但也可以通过在具名元素上指定 geo.label 或 series‑map.label 来使用 ECharts 内置的标签功能。
默认情况下,悬停具名元素时会自动显示标签。若要关闭,只需
option = {
geo: {
map: 'some_svg',
emphasis: {
label: {
show: false
}
}
}
};当多个元素需要共享同一个标签文本时,有两种做法:
- 将这些元素包裹在具名的
<g>中(例如<g name="name_a">),则只显示一个标签,并根据该<g>的外接矩形定位。 - 为这些元素使用相同的 name(例如
<path name="name_b"/><path name="name_b"/>),则会为每个元素各自显示一个标签并分别定位。
示例(悬停可显示标签)
注意:仅以下具名元素可以通过 label 选项进行标注:rect、circle、line、ellipse、polygon、polyline、path、g。
另请参见 Organ Visualization 中标签的使用方式。
活动
可以通过以下方式简单监听具名元素的鼠标或触摸事件:
// 'name1' is a name of a SVG element.
myChart.on('click', { geoIndex: 0, name: 'name1' }, function (params) {
console.log(params);
});SVG 底图布局
默认情况下,ECharts 会将 SVG 底图居中放置在画布内。如需微调,通常只需修改 layoutCenter / layoutSize,偶尔会配合 <svg viewBox="..."> 或 geo.boundingCoords(区别在于是否裁剪)。在大多数情况下,这已足够。
如果需要更精细的定位与缩放控制,可关注下面的几个概念。
geo 坐标系 与 map 系列 的布局规则与选项完全相同。因此以下仅演示 geo 坐标系 的情况。
上面的演示在同一个 ECharts 画布中展示了六个 geo 坐标系,分别使用了三份 SVG 文件。每列的两个 geo 共用同一 SVG 文件。
首先,形状的外观由 SVG 文件本身决定。也就是说,上面演示的形状轮廓取决于 <circle> 与 viewBox(viewBox 对圆形进行裁剪)。我们可以看到每列最终的轮廓是一致的(尽管位置、大小和裁剪方式不同),因为它们使用了相同的 SVG 文件。
其次,用户可以通过以下两组选项之一来确定 geo 坐标系 中 geo 视口 的位置和大小,这些选项均基于整个图表画布(所有数值均以 ECharts 画布像素或百分比计)
- layoutCenter、layoutSize(推荐)。
- top、right、bottom、left(在上面的演示中使用了该方式)。
在上面的演示中,六个 geo 视口 被显示为六个黑色方块。
第三步,会确定 SVG 的 外接矩形,其获取方式如下(均以 SVG 本地单位计)
- 如果指定了 geo.boundingCoords,则直接使用该值作为
外接矩形。 - 否则若在
<svg width="..." height="...">中声明了宽高,则以[0, 0, width, height]作为外接矩形(若只声明了 width 或 height,则分别使用[0, width]或[0, height])。 - 否则若声明了
svg viewBox="...">,则使用viewBox作为外接矩形。 - 否则使用所有 SVG 元素的并集外接矩形作为
外接矩形。 - 如果同时指定了 geo.center 或 geo.zoom,则在前面
1~4步得到的外接矩形基础上进行相应的平移或缩放变换。
确定了 外接矩形 后,将其放入对应的 geo 视口。
- 若使用 layoutCenter、top、right、bottom、left,则视口矩形会被拉伸以完全填满
geo 视口。
在 SVG 底图上放置系列
可以在 scatter、effectScatter、lines、custom 等可用于 geo 坐标系 的系列,同样在 SVG 底图上进行定位和显示。
需注意的是,在此种用法下系列数据值的单位采用的是 SVG 文件的本地坐标。例如
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 本地坐标。
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);
});另请参考 SVG Scatter、SVG Lines、SVG Traffic。
不支持的 SVG 特性
遗憾的是,实现完整的 SVG 解析器相当困难。虽然常用的 SVG 功能已得到支持,但以下列出的特性仍未支持:
- 翻转与倾斜(将在
v5.1.2支持)- 不支持
transform: skew(...)(包括包含倾斜的transform: matrix(...))。 - 不支持在同时存在
rotate的情况下,transform: scale(x, y)中x与y符号相反的情况(例如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:url(...)- 仅支持
url(#someId)这种写法。 - 其它 URL 形式不被支持,例如:
url(https://example.com/images/myImg.jpg);url(data:image/png;base64,iRxVB0…);url(myFont.woff);
- 仅支持
- <switch> 标签
- 所有位于
<switch>标签内的内容都会被渲染,switch功能本身不受支持。
- 所有位于
<text>:textPath不受支持。- 不支持可寻址字符。也就是说,
<!-- 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>