You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2021/03/09 17:58:23 UTC
[echarts] 05/06: feature: [geo] support geo svg named elements have
the same behavior as regions of geoJSON
This is an automated email from the ASF dual-hosted git repository.
sushuang pushed a commit to branch fix/geo-svg
in repository https://gitbox.apache.org/repos/asf/echarts.git
commit ca5817445241ab7ccc55853ac8049b662b632449
Author: 100pah <su...@gmail.com>
AuthorDate: Tue Mar 9 12:51:20 2021 +0800
feature: [geo] support geo svg named elements have the same behavior as regions of geoJSON
---
src/component/helper/MapDraw.ts | 386 +++++++++++++++++++++++-----------------
src/coord/geo/GeoModel.ts | 1 -
src/coord/geo/GeoSVGResource.ts | 6 +-
test/geo-svg.html | 170 ++++++++++++++++++
4 files changed, 398 insertions(+), 165 deletions(-)
diff --git a/src/component/helper/MapDraw.ts b/src/component/helper/MapDraw.ts
index 1ca9ad9..a7176bf 100644
--- a/src/component/helper/MapDraw.ts
+++ b/src/component/helper/MapDraw.ts
@@ -39,11 +39,24 @@ import { getECData } from '../../util/innerStore';
import { createOrUpdatePatternFromDecal } from '../../util/decal';
import { ViewCoordSysTransformInfoPart } from '../../coord/View';
import { GeoSVGResource } from '../../coord/geo/GeoSVGResource';
+import Displayable from 'zrender/src/graphic/Displayable';
+import Element, { ElementTextConfig } from 'zrender/src/Element';
+import List from '../../data/List';
interface RegionsGroup extends graphic.Group {
}
+interface ViewBuildContext {
+ api: ExtensionAPI;
+ geo: Geo;
+ mapOrGeoModel: GeoModel | MapSeries;
+ data: List;
+ isVisualEncodedByVisualMap: boolean;
+ isGeo: boolean;
+ transformInfoRaw: ViewCoordSysTransformInfoPart;
+}
+
function getFixedItemStyle(model: Model<GeoItemStyleOption>) {
const itemStyle = model.getItemStyle();
const areaColor = model.get('areaColor');
@@ -78,12 +91,14 @@ class MapDraw {
*/
private _mouseDownFlag: boolean;
- private _mapName: string;
+ private _svgMapName: string;
private _regionsGroup: RegionsGroup;
private _svgGroup: graphic.Group;
+ private _svgNamedElements: Displayable[];
+
constructor(api: ExtensionAPI) {
const group = new graphic.Group();
@@ -117,7 +132,6 @@ class MapDraw {
const geo = mapOrGeoModel.coordinateSystem;
-
const regionsGroup = this._regionsGroup;
const group = this.group;
@@ -125,8 +139,6 @@ class MapDraw {
const transformInfoRaw = transformInfo.raw;
const transformInfoRoam = transformInfo.roam;
- this._updateSVG(geo, transformInfoRaw);
-
// No animation when first draw or in action
const isFirstDraw = !regionsGroup.childAt(0) || payload;
@@ -141,17 +153,44 @@ class MapDraw {
graphic.updateProps(group, transformInfoRoam, mapOrGeoModel);
}
- regionsGroup.removeAll();
-
- const nameMap = zrUtil.createHashMap<RegionsGroup>();
-
-
const isVisualEncodedByVisualMap = data
&& data.getVisual('visualMeta')
&& data.getVisual('visualMeta').length > 0;
+ const viewBuildCtx = {
+ api,
+ geo,
+ mapOrGeoModel,
+ data,
+ isVisualEncodedByVisualMap,
+ isGeo,
+ transformInfoRaw
+ };
+
+ this._buildGeoJSON(viewBuildCtx);
+ this._buildSVG(viewBuildCtx);
+
+ this._updateController(mapOrGeoModel, ecModel, api);
+
+ this._updateMapSelectHandler(mapOrGeoModel, regionsGroup, api, fromView);
+ }
+
+ private _buildGeoJSON(viewBuildCtx: ViewBuildContext): void {
+ const nameMap = zrUtil.createHashMap<RegionsGroup>();
+ const regionsGroup = this._regionsGroup;
+ const transformInfoRaw = viewBuildCtx.transformInfoRaw;
+
+ const transformPoint = function (point: number[]): number[] {
+ return [
+ point[0] * transformInfoRaw.scaleX + transformInfoRaw.x,
+ point[1] * transformInfoRaw.scaleY + transformInfoRaw.y
+ ];
+ };
+
+ regionsGroup.removeAll();
- zrUtil.each(geo.regions, function (region) {
+ // Only when the resource is GeoJSON, there is `geo.regions`.
+ zrUtil.each(viewBuildCtx.geo.regions, function (region) {
// Consider in GeoJson properties.name may be duplicated, for example,
// there is multiple region named "United Kindom" or "France" (so many
@@ -169,50 +208,6 @@ class MapDraw {
});
regionGroup.add(compoundPath);
- const regionModel = mapOrGeoModel.getRegionModel(region.name) || mapOrGeoModel;
-
- // @ts-ignore FIXME:TS fix the "compatible with each other"?
- const itemStyleModel = regionModel.getModel('itemStyle');
- // @ts-ignore FIXME:TS fix the "compatible with each other"?
- const emphasisModel = regionModel.getModel('emphasis');
- const emphasisItemStyleModel = emphasisModel.getModel('itemStyle');
- // @ts-ignore FIXME:TS fix the "compatible with each other"?
- const blurItemStyleModel = regionModel.getModel(['blur', 'itemStyle']);
- // @ts-ignore FIXME:TS fix the "compatible with each other"?
- const selectItemStyleModel = regionModel.getModel(['select', 'itemStyle']);
-
- // NOTE: DONT use 'style' in visual when drawing map.
- // This component is used for drawing underlying map for both geo component and map series.
- const itemStyle = getFixedItemStyle(itemStyleModel);
- const emphasisItemStyle = getFixedItemStyle(emphasisItemStyleModel);
- const blurItemStyle = getFixedItemStyle(blurItemStyleModel);
- const selectItemStyle = getFixedItemStyle(selectItemStyleModel);
-
- let dataIdx;
- // Use the itemStyle in data if has data
- if (data) {
- dataIdx = data.indexOfName(region.name);
- // Only visual color of each item will be used. It can be encoded by visualMap
- // But visual color of series is used in symbol drawing
- //
- // Visual color for each series is for the symbol draw
- const style = data.getItemVisual(dataIdx, 'style');
- const decal = data.getItemVisual(dataIdx, 'decal');
- if (isVisualEncodedByVisualMap && style.fill) {
- itemStyle.fill = style.fill;
- }
- if (decal) {
- itemStyle.decal = createOrUpdatePatternFromDecal(decal, api);
- }
- }
-
- const transformPoint = function (point: number[]): number[] {
- return [
- point[0] * transformInfoRaw.scaleX + transformInfoRaw.x,
- point[1] * transformInfoRaw.scaleY + transformInfoRaw.y
- ];
- };
-
zrUtil.each(region.geometries, function (geometry) {
if (geometry.type !== 'polygon') {
return;
@@ -243,149 +238,218 @@ class MapDraw {
}
});
- compoundPath.setStyle(itemStyle);
- compoundPath.style.strokeNoScale = true;
- compoundPath.culling = true;
-
- compoundPath.ensureState('emphasis').style = emphasisItemStyle;
- compoundPath.ensureState('blur').style = blurItemStyle;
- compoundPath.ensureState('select').style = selectItemStyle;
-
- let showLabel = false;
- for (let i = 0; i < DISPLAY_STATES.length; i++) {
- const stateName = DISPLAY_STATES[i];
- // @ts-ignore FIXME:TS fix the "compatible with each other"?
- if (regionModel.get(
- stateName === 'normal' ? ['label', 'show'] : [stateName, 'label', 'show']
- )) {
- showLabel = true;
- break;
- }
- }
+ const centerPt = transformPoint(region.center);
- const isDataNaN = data && isNaN(data.get(data.mapDimension('value'), dataIdx) as number);
- const itemLayout = data && data.getItemLayout(dataIdx);
-
- // In the following cases label will be drawn
- // 1. In map series and data value is NaN
- // 2. In geo component
- // 4. Region has no series legendSymbol, which will be add a showLabel flag in mapSymbolLayout
- if (
- (isGeo || isDataNaN && (showLabel))
- || (itemLayout && itemLayout.showLabel)
- ) {
- const query = !isGeo ? dataIdx : region.name;
- let labelFetcher;
-
- // Consider dataIdx not found.
- if (!data || dataIdx >= 0) {
- labelFetcher = mapOrGeoModel;
- }
+ this._resetSingleRegionGraphic(
+ viewBuildCtx, compoundPath, regionGroup, region.name, centerPt, null
+ );
- const centerPt = transformPoint(region.center);
- const textEl = new graphic.Text({
- x: centerPt[0],
- y: centerPt[1],
- z2: 10,
- silent: true
- });
- textEl.afterUpdate = labelTextAfterUpdate;
-
- setLabelStyle<typeof query>(
- textEl, getLabelStatesModels(regionModel),
- {
- labelFetcher: labelFetcher,
- labelDataIndex: query,
- defaultText: region.name
- },
- { normal: {
- align: 'center',
- verticalAlign: 'middle'
- } }
- );
-
- compoundPath.setTextContent(textEl);
- compoundPath.setTextConfig({
- local: true
- });
-
- (compoundPath as ECElement).disableLabelAnimation = true;
+ regionsGroup.add(regionGroup);
- }
+ }, this);
+ }
+
+ private _buildSVG(viewBuildCtx: ViewBuildContext): void {
+ const mapName = viewBuildCtx.geo.map;
+ const transformInfoRaw = viewBuildCtx.transformInfoRaw;
+
+ this._svgGroup.x = transformInfoRaw.x;
+ this._svgGroup.y = transformInfoRaw.y;
+ this._svgGroup.scaleX = transformInfoRaw.scaleX;
+ this._svgGroup.scaleY = transformInfoRaw.scaleY;
+
+ if (this._svgResourceChanged(mapName)) {
+ this._freeSVG();
+ this._useSVG(mapName);
+ }
- // setItemGraphicEl, setHoverStyle after all polygons and labels
- // are added to the rigionGroup
- if (data) {
- data.setItemGraphicEl(dataIdx, regionGroup);
+ zrUtil.each(this._svgNamedElements, function (namedElement) {
+ this._resetSingleRegionGraphic(
+ viewBuildCtx, namedElement, namedElement, namedElement.name, [0, 0], 'inside'
+ );
+ }, this);
+ }
+
+ private _resetSingleRegionGraphic(
+ viewBuildCtx: ViewBuildContext,
+ displayable: Displayable,
+ elForStateChange: Element,
+ regionName: string,
+ labelXY: number[],
+ labelPosition: ElementTextConfig['position']
+ ): void {
+
+ const mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
+ const data = viewBuildCtx.data;
+ const isVisualEncodedByVisualMap = viewBuildCtx.isVisualEncodedByVisualMap;
+ const isGeo = viewBuildCtx.isGeo;
+
+ const regionModel = mapOrGeoModel.getRegionModel(regionName) || mapOrGeoModel;
+
+ // @ts-ignore FIXME:TS fix the "compatible with each other"?
+ const itemStyleModel = regionModel.getModel('itemStyle');
+ // @ts-ignore FIXME:TS fix the "compatible with each other"?
+ const emphasisModel = regionModel.getModel('emphasis');
+ const emphasisItemStyleModel = emphasisModel.getModel('itemStyle');
+ // @ts-ignore FIXME:TS fix the "compatible with each other"?
+ const blurItemStyleModel = regionModel.getModel(['blur', 'itemStyle']);
+ // @ts-ignore FIXME:TS fix the "compatible with each other"?
+ const selectItemStyleModel = regionModel.getModel(['select', 'itemStyle']);
+
+ // NOTE: DONT use 'style' in visual when drawing map.
+ // This component is used for drawing underlying map for both geo component and map series.
+ const itemStyle = getFixedItemStyle(itemStyleModel);
+ const emphasisItemStyle = getFixedItemStyle(emphasisItemStyleModel);
+ const blurItemStyle = getFixedItemStyle(blurItemStyleModel);
+ const selectItemStyle = getFixedItemStyle(selectItemStyleModel);
+
+ let dataIdx;
+ // Use the itemStyle in data if has data
+ if (data) {
+ dataIdx = data.indexOfName(regionName);
+ // Only visual color of each item will be used. It can be encoded by visualMap
+ // But visual color of series is used in symbol drawing
+ //
+ // Visual color for each series is for the symbol draw
+ const style = data.getItemVisual(dataIdx, 'style');
+ const decal = data.getItemVisual(dataIdx, 'decal');
+ if (isVisualEncodedByVisualMap && style.fill) {
+ itemStyle.fill = style.fill;
}
- else {
- const regionModel = mapOrGeoModel.getRegionModel(region.name);
- // Package custom mouse event for geo component
- getECData(compoundPath).eventData = {
- componentType: 'geo',
- componentIndex: mapOrGeoModel.componentIndex,
- geoIndex: mapOrGeoModel.componentIndex,
- name: region.name,
- region: (regionModel && regionModel.option) || {}
- };
+ if (decal) {
+ itemStyle.decal = createOrUpdatePatternFromDecal(decal, viewBuildCtx.api);
}
+ }
+ displayable.setStyle(itemStyle);
+ displayable.style.strokeNoScale = true;
+ displayable.culling = true;
+
+ displayable.ensureState('emphasis').style = emphasisItemStyle;
+ displayable.ensureState('blur').style = blurItemStyle;
+ displayable.ensureState('select').style = selectItemStyle;
+
+
+ let showLabel = false;
+ for (let i = 0; i < DISPLAY_STATES.length; i++) {
+ const stateName = DISPLAY_STATES[i];
// @ts-ignore FIXME:TS fix the "compatible with each other"?
- regionGroup.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode');
- enableHoverEmphasis(regionGroup, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
+ if (regionModel.get(
+ stateName === 'normal' ? ['label', 'show'] : [stateName, 'label', 'show']
+ )) {
+ showLabel = true;
+ break;
+ }
+ }
- regionsGroup.add(regionGroup);
- });
+ const isDataNaN = data && isNaN(data.get(data.mapDimension('value'), dataIdx) as number);
+ const itemLayout = data && data.getItemLayout(dataIdx);
+
+ // In the following cases label will be drawn
+ // 1. In map series and data value is NaN
+ // 2. In geo component
+ // 4. Region has no series legendSymbol, which will be add a showLabel flag in mapSymbolLayout
+ if (
+ (isGeo || isDataNaN && (showLabel))
+ || (itemLayout && itemLayout.showLabel)
+ ) {
+ const query = !isGeo ? dataIdx : regionName;
+ let labelFetcher;
+
+ // Consider dataIdx not found.
+ if (!data || dataIdx >= 0) {
+ labelFetcher = mapOrGeoModel;
+ }
- this._updateController(mapOrGeoModel, ecModel, api);
+ const textEl = new graphic.Text({
+ x: labelXY[0],
+ y: labelXY[1],
+ z2: 10,
+ silent: true
+ });
+ textEl.afterUpdate = labelTextAfterUpdate;
+
+ setLabelStyle<typeof query>(
+ textEl, getLabelStatesModels(regionModel),
+ {
+ labelFetcher: labelFetcher,
+ labelDataIndex: query,
+ defaultText: regionName
+ },
+ { normal: {
+ align: 'center',
+ verticalAlign: 'middle'
+ } }
+ );
+
+ displayable.setTextContent(textEl);
+ displayable.setTextConfig({
+ local: true,
+ insideFill: textEl.style.fill,
+ position: labelPosition
+ });
+
+ (displayable as ECElement).disableLabelAnimation = true;
+ }
+
+
+ // setItemGraphicEl, setHoverStyle after all polygons and labels
+ // are added to the rigionGroup
+ if (data) {
+ data.setItemGraphicEl(dataIdx, elForStateChange);
+ }
+ else {
+ const regionModel = mapOrGeoModel.getRegionModel(regionName);
+ // Package custom mouse event for geo component
+ getECData(displayable).eventData = {
+ componentType: 'geo',
+ componentIndex: mapOrGeoModel.componentIndex,
+ geoIndex: mapOrGeoModel.componentIndex,
+ name: regionName,
+ region: (regionModel && regionModel.option) || {}
+ };
+ }
+
+ // @ts-ignore FIXME:TS fix the "compatible with each other"?
+ elForStateChange.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode');
+ enableHoverEmphasis(elForStateChange, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
- this._updateMapSelectHandler(mapOrGeoModel, regionsGroup, api, fromView);
}
remove(): void {
this._regionsGroup.removeAll();
this._svgGroup.removeAll();
this._controller.dispose();
- this._freeSVG(this._mapName);
- this._mapName = null;
+ this._freeSVG();
this._controllerHost = null;
}
- private _updateSVG(geo: Geo, transformInfoRaw: ViewCoordSysTransformInfoPart): void {
- const mapName = geo.map;
-
- this._svgGroup.x = transformInfoRaw.x;
- this._svgGroup.y = transformInfoRaw.y;
- this._svgGroup.scaleX = transformInfoRaw.scaleX;
- this._svgGroup.scaleY = transformInfoRaw.scaleY;
-
- if (this._mapName !== mapName) {
- this._freeSVG(this._mapName);
- this._useSVG(mapName);
- this._mapName = mapName;
- }
+ private _svgResourceChanged(mapName: string): boolean {
+ return this._svgMapName !== mapName;
}
- private _useSVG(mapName: string) {
- if (mapName == null) {
- return;
- }
+ private _useSVG(mapName: string): void {
const resource = geoSourceManager.getGeoResource(mapName);
if (resource && resource.type === 'svg') {
const svgGraphic = (resource as GeoSVGResource).useGraphic(this.uid);
this._svgGroup.add(svgGraphic.root);
+ this._svgNamedElements = svgGraphic.namedElements;
+ this._svgMapName = mapName;
}
}
- private _freeSVG(mapName: string) {
+ private _freeSVG(): void {
+ const mapName = this._svgMapName;
if (mapName == null) {
return;
}
const resource = geoSourceManager.getGeoResource(mapName);
if (resource && resource.type === 'svg') {
(resource as GeoSVGResource).freeGraphic(this.uid);
- this._svgGroup.removeAll();
}
+ this._svgGroup.removeAll();
+ this._svgNamedElements = null;
+ this._svgMapName = null;
}
private _updateController(
diff --git a/src/coord/geo/GeoModel.ts b/src/coord/geo/GeoModel.ts
index 3705304..78054c6 100644
--- a/src/coord/geo/GeoModel.ts
+++ b/src/coord/geo/GeoModel.ts
@@ -163,7 +163,6 @@ class GeoModel extends ComponentModel<GeoOption> {
},
itemStyle: {
- // color: 各异,
borderWidth: 0.5,
borderColor: '#444',
color: '#eee'
diff --git a/src/coord/geo/GeoSVGResource.ts b/src/coord/geo/GeoSVGResource.ts
index 0a3a4ec..43c18fa 100644
--- a/src/coord/geo/GeoSVGResource.ts
+++ b/src/coord/geo/GeoSVGResource.ts
@@ -24,11 +24,11 @@ import {assert, createHashMap, HashMap} from 'zrender/src/core/util';
import BoundingRect from 'zrender/src/core/BoundingRect';
import { GeoResource, GeoSVGSourceInput } from './geoTypes';
import { parseXML } from 'zrender/src/tool/parseXML';
-import Element from 'zrender/src/Element';
+import Displayable from 'zrender/src/graphic/Displayable';
export interface GeoSVGGraphic {
root: Group;
- namedElements: Element[];
+ namedElements: Displayable[];
}
export class GeoSVGResource implements GeoResource {
@@ -115,7 +115,7 @@ function buildGraphic(
): {
root: Group;
boundingRect: BoundingRect;
- namedElements: Element[]
+ namedElements: Displayable[]
} {
let result;
let root;
diff --git a/test/geo-svg.html b/test/geo-svg.html
new file mode 100644
index 0000000..d7568d5
--- /dev/null
+++ b/test/geo-svg.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <script src="lib/esl.js"></script>
+ <script src="lib/config.js"></script>
+ <script src="lib/jquery.min.js"></script>
+ <script src="lib/facePrint.js"></script>
+ <script src="lib/testHelper.js"></script>
+ <!-- <script src="ut/lib/canteen.js"></script> -->
+ <link rel="stylesheet" href="lib/reset.css" />
+ </head>
+ <body>
+ <style>
+ </style>
+
+
+
+ <div id="main0"></div>
+ <div id="main1"></div>
+
+
+
+
+
+
+ <script>
+ require(['echarts'/*, 'map/js/china' */], function (echarts) {
+ const testGeoJson1 = {
+ 'type': 'FeatureCollection',
+ 'features': [
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Polygon',
+ 'coordinates': [
+ [[2000, 2000], [5000, 2000], [5000, 5000], [2000, 5000]]
+ ]
+ },
+ 'properties': {
+ 'name': 'Afghanistan',
+ 'childNum': 1
+ }
+ }
+ ]
+ };
+
+ echarts.registerMap('testGeoJson1', testGeoJson1);
+
+ option = {
+ geo: {
+ map: 'testGeoJson1',
+ roam: true,
+ // height: '100%',
+ // center
+ // layoutCenter: ['30%', 40],
+ // layoutSize: 40,
+ // boundingCoords
+ zoom: 1,
+ aspectScale: 1
+ }
+ };
+
+ var chart = testHelper.create(echarts, 'main0', {
+ title: [
+ 'geoJSON location:',
+ 'Should be a square and 80% of canvas height.',
+ 'At the center of the canvas.'
+ ],
+ option: option,
+ height: 300
+ });
+
+
+ });
+ </script>
+
+
+
+ <script>
+ require(['echarts'/*, 'map/js/china' */], function (echarts) {
+ var option;
+ $.ajax({
+ url: '../../vis-data/map/svg/seats/seatmap-example.svg', // 剧场例子
+ // url: '../../vis-data/map/svg/seats/Ethiopian_Airlines_Flight_961_seating_plan.svg', // 飞机例子
+ // url: '../../vis-data/map/svg/seats/oracle-seating-map-2017-2.svg', // 渲染错误
+ // url: '../../vis-data/map/svg/seats/DC-10-30_seat_configuration_chart.svg', // 渲染错误
+ // url: '../../vis-data/map/svg/seats/Airbus_A300B4-622R_seat_configuration_chart.svg', // 渲染错误
+ dataType: 'text'
+ }).done(function (svg) {
+
+ echarts.registerMap('seatmap', {
+ svg: svg
+ });
+
+ option = {
+ geo: {
+ map: 'seatmap',
+ roam: true,
+ // height: 100,
+ // zoom: 1.5
+ emphasis: {
+ // itemStyle: {
+ // color: 'red'
+ // },
+ label: {
+ // color: '#fff',
+ textBorderColor: '#fff',
+ textBorderWidth: 2
+ }
+ },
+ // itemStyle: {
+ // color: 'red'
+ // },
+ // label: {
+ // color: '#fff'
+ // }
+ },
+ // series: {
+ // type: 'scatter',
+ // coordinateSystem: 'geo',
+ // // ?????????????????????????
+ // geoIndex: 0,
+ // data: [[11, 22], [33, 44]]
+ // }
+ };
+
+ var chart = testHelper.create(echarts, 'main1', {
+ title: [
+ 'Test Case Description of main0',
+ '(Muliple lines and **emphasis** are supported in description)'
+ ],
+ option: option,
+ height: 300
+ // buttons: [{text: 'btn-txt', onclick: function () {}}],
+ // recordCanvas: true,
+ });
+
+ });
+
+ });
+ </script>
+
+
+
+
+ </body>
+</html>
+
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org