From 6322779a785bbf6a9ec7303386508acf8203883b Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Tue, 10 Dec 2019 20:11:26 +0800 Subject: [PATCH] docs: add source docs, fix mapbox marker --- docs/api/layer/pointlayer.zh.md | 8 ++ docs/api/source/csv.en.md | 53 ++++++++ docs/api/source/csv.zh.md | 53 ++++++++ docs/api/source/image.en.md | 25 ++++ docs/api/source/image.zh.md | 25 ++++ docs/api/source/json.en.md | 2 +- docs/api/source/json.zh.md | 4 +- docs/api/source/source.en.md | 87 +----------- docs/api/source/source.zh.md | 100 +++----------- docs/tutorial/quickstart.zh.md | 77 +++++++++++ examples/point/chart/demo/ring.js | 124 +++++++++--------- .../src/services/component/MarkerService.ts | 2 +- .../core/src/services/layer/ILayerService.ts | 1 - .../src/services/source/ISourceService.ts | 1 + packages/layers/src/core/BaseLayer.ts | 31 +---- .../layers/src/plugins/DataSourcePlugin.ts | 11 +- packages/source/__tests__/source.spec.ts | 2 +- packages/source/src/source.ts | 13 +- stories/Components/Components.stories.tsx | 2 + stories/Components/components/chart.tsx | 108 +++++++++++++++ stories/Layers/components/Point.tsx | 4 - 21 files changed, 464 insertions(+), 269 deletions(-) create mode 100644 docs/api/source/csv.en.md create mode 100644 docs/api/source/csv.zh.md create mode 100644 docs/api/source/image.en.md create mode 100644 docs/api/source/image.zh.md create mode 100644 stories/Components/components/chart.tsx diff --git a/docs/api/layer/pointlayer.zh.md b/docs/api/layer/pointlayer.zh.md index 5804e506b9..5dc8c8f83a 100644 --- a/docs/api/layer/pointlayer.zh.md +++ b/docs/api/layer/pointlayer.zh.md @@ -25,6 +25,14 @@ shape 支持 ``` +## source + +点数据类型,根据经纬点绘制图形,目前支持三种数据结构 + +- [GeoJOSN]('../source/geojson/#point') +- [CSV]() +- [JSON](../source/json/#点数据) + **图片标注** 通过 `Scene.addImage()` 可以添加图片资源, diff --git a/docs/api/source/csv.en.md b/docs/api/source/csv.en.md new file mode 100644 index 0000000000..eed20c031c --- /dev/null +++ b/docs/api/source/csv.en.md @@ -0,0 +1,53 @@ +--- +title: CSV +order: 3 +--- + +L7 支持 CSV 以逗号分隔的 CSV 数据加载。 + +CSV 是文本数据结构,很难表达复杂的地理数据结构,因此 CSV 仅支持两种数据结构 + +- 点数据 需要指定经度,纬度坐标 +- 线段,弧线数据 需要指定 起始点的 经度,纬度坐标 + +## parser + +- type string 必选 json +- x string 点数据表示 经度 +- y string 点数据表示 纬度 +- x1 string 经度 +- x2 string 纬度 + +### 点数据通过 CSV 加载 + +```javascript +layer.source(data, { + parser: { + type: 'csv', + x: 'lng', + y: 'lat', + }, +}); +``` + +[CSV 数据 demo 示例](../../../examples/point/bubble#scatter) + +### 线段弧线数据通过 CSV 加载 + +```javascript +layer.source( + data, + { + parser:{ + type:'csv', + x:'lng1', + y:'lat1' , + x1:'lng1', + y1:'lat2' , + } + } +}) + +``` + +[CSV 线段数据 demo 示例](../../../examples/gallery/basic#arcCircle) diff --git a/docs/api/source/csv.zh.md b/docs/api/source/csv.zh.md new file mode 100644 index 0000000000..eed20c031c --- /dev/null +++ b/docs/api/source/csv.zh.md @@ -0,0 +1,53 @@ +--- +title: CSV +order: 3 +--- + +L7 支持 CSV 以逗号分隔的 CSV 数据加载。 + +CSV 是文本数据结构,很难表达复杂的地理数据结构,因此 CSV 仅支持两种数据结构 + +- 点数据 需要指定经度,纬度坐标 +- 线段,弧线数据 需要指定 起始点的 经度,纬度坐标 + +## parser + +- type string 必选 json +- x string 点数据表示 经度 +- y string 点数据表示 纬度 +- x1 string 经度 +- x2 string 纬度 + +### 点数据通过 CSV 加载 + +```javascript +layer.source(data, { + parser: { + type: 'csv', + x: 'lng', + y: 'lat', + }, +}); +``` + +[CSV 数据 demo 示例](../../../examples/point/bubble#scatter) + +### 线段弧线数据通过 CSV 加载 + +```javascript +layer.source( + data, + { + parser:{ + type:'csv', + x:'lng1', + y:'lat1' , + x1:'lng1', + y1:'lat2' , + } + } +}) + +``` + +[CSV 线段数据 demo 示例](../../../examples/gallery/basic#arcCircle) diff --git a/docs/api/source/image.en.md b/docs/api/source/image.en.md new file mode 100644 index 0000000000..153208b5b2 --- /dev/null +++ b/docs/api/source/image.en.md @@ -0,0 +1,25 @@ +--- +title: Image +order: 4 +--- + +Image 数据主要用于在地图根据经纬度范围添加图图片,不如一幅纸制地图扫描版你要放在地图显示。 + +## parser + +- type: image +- extent: 图像的经纬度范围 [minlng, minlat,maxLng, maxLat] + +根据图片的经纬度范围,将图片添加到地图上。 + +```javascript +layer.source( + 'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg', + { + parser: { + type: 'image', + extent: [121.168, 30.2828, 121.384, 30.4219], + }, + }, +); +``` diff --git a/docs/api/source/image.zh.md b/docs/api/source/image.zh.md new file mode 100644 index 0000000000..153208b5b2 --- /dev/null +++ b/docs/api/source/image.zh.md @@ -0,0 +1,25 @@ +--- +title: Image +order: 4 +--- + +Image 数据主要用于在地图根据经纬度范围添加图图片,不如一幅纸制地图扫描版你要放在地图显示。 + +## parser + +- type: image +- extent: 图像的经纬度范围 [minlng, minlat,maxLng, maxLat] + +根据图片的经纬度范围,将图片添加到地图上。 + +```javascript +layer.source( + 'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg', + { + parser: { + type: 'image', + extent: [121.168, 30.2828, 121.384, 30.4219], + }, + }, +); +``` diff --git a/docs/api/source/json.en.md b/docs/api/source/json.en.md index 2a112c3517..6d93a25a89 100644 --- a/docs/api/source/json.en.md +++ b/docs/api/source/json.en.md @@ -1,6 +1,6 @@ --- title: JSON -order: 1 +order: 2 --- GeoJSON 虽然是通用的的地理数据格式,在具体使用场景中,数据服务人员可能并不熟悉 GeoJON,或者没有生成 GeoJON 的工具, 因此 L7 对数据定义了 Parser 的概念,你的数据可以是任何格式,使用指定数据对应的地理信息字段即可。 diff --git a/docs/api/source/json.zh.md b/docs/api/source/json.zh.md index 2a112c3517..5ded5808b8 100644 --- a/docs/api/source/json.zh.md +++ b/docs/api/source/json.zh.md @@ -1,6 +1,6 @@ --- title: JSON -order: 1 +order: 2 --- GeoJSON 虽然是通用的的地理数据格式,在具体使用场景中,数据服务人员可能并不熟悉 GeoJON,或者没有生成 GeoJON 的工具, 因此 L7 对数据定义了 Parser 的概念,你的数据可以是任何格式,使用指定数据对应的地理信息字段即可。 @@ -39,6 +39,8 @@ layer.source(data, { }); ``` +[JOSN 数据 demo 示例](../../../examples/gallery/basic) + ### 通用解析方式 可也解析任意复杂的点,线面 diff --git a/docs/api/source/source.en.md b/docs/api/source/source.en.md index 40289647b4..23d82db659 100644 --- a/docs/api/source/source.en.md +++ b/docs/api/source/source.en.md @@ -40,100 +40,25 @@ layer.source(data); #### JSON -[JSON 数据格式解析](../json) +[JSON 数据格式解析](./json) #### csv -点,线数据配置项同 json 数据类型 +[CSV 数据格式解析](./csv) -```javascript -layer.source(data, { - parser: { - type: 'csv', - x: 'lng1', - y: 'lat1', - x1: 'lng1', - y1: 'lat2', - }, -}); -``` - -**栅格数据类型 ** +栅格数据类型 #### image -根据图片的经纬度范围,将图片添加到地图上。  配置项 - -- type: image -- extent: 图像的经纬度范围 [] - -```javascript -layer.source( - 'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg', - { - parser: { - type: 'image', - extent: [121.168, 30.2828, 121.384, 30.4219], - }, - }, -); -``` - -#### raster - -栅格数据类型,主要表示遥感数据类型 data 栅格数据的二维矩阵数据 parser 配置项 - -- type  raster -- width  数据宽度二维矩阵 columns -- height 数据高度 -- min 数据最大值 -- max 数据最小值 -- extent 经纬度范围 - -```javascript -source(values, { - parser: { - type: 'raster', - width: n, - height: m, - min: 0, - max: 8000, - extent: [73.482190241, 3.82501784112, 135.106618732, 57.6300459963], - }, -}); -``` +[Image 数据格式解析](./image) ### transforms -目前支持三种数据处理方法 map,grid,hexagon transform 配置项 +目前支持两种热力图使用的数据处理方法 grid,hexagon transform 配置项 - type 数据处理类型 - tansform cfg  数据处理配置项 -#### map - -数据处理,支持自定义 callback 函数 - -- callback:function 回调函数 - -```javascript -layer.source(data, { - transforms: [ - { - type: 'map', - callback: function(item) { - const [x, y] = item.coordinates; - item.lat = item.lat * 1; - item.lng = item.lng * 1; - item.v = item.v * 1; - item.coordinates = [x * 1, y * 1]; - return item; - }, - }, - ], -}); -``` - #### grid 生成方格网布局,根据数据字段统计,主要在网格热力图中使用 @@ -163,4 +88,4 @@ layer.source(data, { - type: 'hexagon', - size: 网格半径 - field: 数据统计字段 -- method:聚合方法   count,max,min,sum,mean5 个统计维度 +- method:聚合方法   count,max,min,sum,mean 5 个统计维度 diff --git a/docs/api/source/source.zh.md b/docs/api/source/source.zh.md index 89bef2766b..45b0f47246 100644 --- a/docs/api/source/source.zh.md +++ b/docs/api/source/source.zh.md @@ -7,6 +7,13 @@ order: 0 source 地理数据处理模块,主要包含数据解析(parser),和数据处理(transform); +- data +- option + - cluster **boolean** 是否聚合 + - clusterOption 聚合配置项 + - parser 数据解析配置 + - transforms 数据处理配置 + ### parser 不同数据类型处理成统一数据格式。矢量数据包括 GeoJON, CSV,Json 等不同数据格式,栅格数据,包括 Raster,Image 数据。将来还会支持瓦片格式数据。 @@ -23,6 +30,14 @@ source 地理数据处理模块,主要包含数据解析(parser),和数据 ## API +### cluster 可选 可以只设置 cluster + +### clusterOption 可选 + +- radius 聚合半径 **number** default 40 +- minZoom: 最小聚合缩放等级 **number** default 0 +- maxZoom: 最大聚合缩放等级 **number** default 16 + ### parser **配置项** @@ -40,100 +55,25 @@ layer.source(data); #### JSON -[JSON 数据格式解析](../json) +[JSON 数据格式解析](./json) #### csv -点,线数据配置项同 json 数据类型 +[CSV 数据格式解析](./csv) -```javascript -layer.source(data, { - parser: { - type: 'csv', - x: 'lng1', - y: 'lat1', - x1: 'lng1', - y1: 'lat2', - }, -}); -``` - -**栅格数据类型 ** +栅格数据类型 #### image -根据图片的经纬度范围,将图片添加到地图上。  配置项 - -- type: image -- extent: 图像的经纬度范围 [] - -```javascript -layer.source( - 'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg', - { - parser: { - type: 'image', - extent: [121.168, 30.2828, 121.384, 30.4219], - }, - }, -); -``` - -#### raster - -栅格数据类型,主要表示遥感数据类型 data 栅格数据的二维矩阵数据 parser 配置项 - -- type  raster -- width  数据宽度二维矩阵 columns -- height 数据高度 -- min 数据最大值 -- max 数据最小值 -- extent 经纬度范围 - -```javascript -source(values, { - parser: { - type: 'raster', - width: n, - height: m, - min: 0, - max: 8000, - extent: [73.482190241, 3.82501784112, 135.106618732, 57.6300459963], - }, -}); -``` +[Image 数据格式解析](./image) ### transforms -目前支持三种数据处理方法 map,grid,hexagon transform 配置项 +目前支持两种热力图使用的数据处理方法 grid,hexagon transform 配置项 - type 数据处理类型 - tansform cfg  数据处理配置项 -#### map - -数据处理,支持自定义 callback 函数 - -- callback:function 回调函数 - -```javascript -layer.source(data, { - transforms: [ - { - type: 'map', - callback: function(item) { - const [x, y] = item.coordinates; - item.lat = item.lat * 1; - item.lng = item.lng * 1; - item.v = item.v * 1; - item.coordinates = [x * 1, y * 1]; - return item; - }, - }, - ], -}); -``` - #### grid 生成方格网布局,根据数据字段统计,主要在网格热力图中使用 diff --git a/docs/tutorial/quickstart.zh.md b/docs/tutorial/quickstart.zh.md index 7eaead8843..f8edaff8e0 100644 --- a/docs/tutorial/quickstart.zh.md +++ b/docs/tutorial/quickstart.zh.md @@ -15,8 +15,11 @@ Current version: ![L7 2.0版本号](https://badgen.net/npm/v/@antv/l7/beta) Include the L7 JS JavaScript of your HTML file. +:warning: 如果需要引用第三方地图API,请确保在先引入第三方API,然后引入L7 + ```html + @@ -41,6 +44,7 @@ npm install --save @antv/l7-maps; ``` + ### 初始化地图 #### 使用 高德 底图 @@ -80,3 +84,76 @@ const scene = new Scene({ ``` +### React中使用 + +React 组件待开发,期待和大家共建l7-react 目前可以暂时以 Submodule 方式使用 + +``` +import { Scene, PolygonLayer } from '@antv/l7'; +import { AMap } from '@antv/l7-maps'; +import * as React from 'react'; + +export default class AMapExample extends React.Component { + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const response = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json', + ); + const scene = new Scene({ + id: 'map', + map: new AMap({ + center: [110.19382669582967, 50.258134], + pitch: 0, + style: 'dark', + zoom: 3, + token: 'pg.xxx', // 高德或者 Mapbox 的 token + }), + }); + const layer = new PolygonLayer({}); + + layer + .source(await response.json()) + .size('name', [0, 10000, 50000, 30000, 100000]) + .color('name', [ + '#2E8AE6', + '#69D1AB', + '#DAF291', + '#FFD591', + '#FF7A45', + '#CF1D49', + ]) + .shape('fill') + .style({ + opacity: 0.8, + }); + scene.addLayer(layer); + this.scene = scene; + } + + public render() { + return ( +
+ ); + } +} +``` + +⚠️组件 Unmount 时需要通过 scene.destroy() 手动销毁场景。 + +更多React使用 [示例查看](https://github.com/antvis/L7/tree/master/stories) + +### Vue 欢迎补充 \ No newline at end of file diff --git a/examples/point/chart/demo/ring.js b/examples/point/chart/demo/ring.js index 47541248ca..81b520e40b 100644 --- a/examples/point/chart/demo/ring.js +++ b/examples/point/chart/demo/ring.js @@ -44,67 +44,71 @@ const scene = new Scene({ zoom: 3.802 }) }); -Promise.all([ - fetch( - 'https://gw.alipayobjects.com/os/basement_prod/5b772136-a1f4-4fc5-9a80-9f9974b4b182.json' - ).then(d => d.json()), - fetch( - 'https://gw.alipayobjects.com/os/basement_prod/f3c467a4-9ae0-4f08-bb5f-11f9c869b2cb.json' - ).then(d => d.json()) -]).then(function onLoad([ center, population ]) { - const popobj = {}; - population.forEach(element => { - popobj[element.Code] = - element['Population, female (% of total) (% of total)']; - }); - // 数据绑定 +addChart(); +scene.render(); +function addChart() { + Promise.all([ + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/5b772136-a1f4-4fc5-9a80-9f9974b4b182.json' + ).then(d => d.json()), + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/f3c467a4-9ae0-4f08-bb5f-11f9c869b2cb.json' + ).then(d => d.json()) + ]).then(function onLoad([ center, population ]) { + const popobj = {}; + population.forEach(element => { + popobj[element.Code] = + element['Population, female (% of total) (% of total)']; + }); + // 数据绑定 - center.features = center.features.map(fe => { - fe.properties.female = popobj[fe.properties.id] * 1 || 0; - return fe; - }); - center.features.forEach(point => { - const el = document.createElement('div'); - const coord = point.geometry.coordinates; - const v = point.properties.female * 1; - if (v < 1 || (v > 46 && v < 54)) { - return; - } - const size = 60; - const data = [ - { - type: '男性', - value: 100.0 - v.toFixed(2) - }, - { - type: '女性', - value: v.toFixed(2) * 1 + center.features = center.features.map(fe => { + fe.properties.female = popobj[fe.properties.id] * 1 || 0; + return fe; + }); + center.features.forEach(point => { + const el = document.createElement('div'); + const coord = point.geometry.coordinates; + const v = point.properties.female * 1; + if (v < 1 || (v > 46 && v < 54)) { + return; } - ]; - const chart = new G2.Chart({ - container: el, - width: size, - height: size, - render: 'svg', - padding: 0 + const size = 60; + const data = [ + { + type: '男性', + value: 100.0 - v.toFixed(2) + }, + { + type: '女性', + value: v.toFixed(2) * 1 + } + ]; + const chart = new G2.Chart({ + container: el, + width: size, + height: size, + render: 'svg', + padding: 0 + }); + chart.source(data); + chart.legend(false); + chart.tooltip(false); + chart.coord('theta', { + radius: 0.9, + innerRadius: 0.6 + }); + chart + .intervalStack() + .position('value') + .color('type', [ '#5CCEA1', '#5B8FF9' ]) + .opacity(1); + chart.render(); + const marker = new Marker({ element: el }).setLnglat({ + lng: coord[0], + lat: coord[1] + }); + scene.addMarker(marker); }); - chart.source(data); - chart.legend(false); - chart.tooltip(false); - chart.coord('theta', { - radius: 0.9, - innerRadius: 0.6 - }); - chart - .intervalStack() - .position('value') - .color('type', [ '#5CCEA1', '#5B8FF9' ]) - .opacity(1); - chart.render(); - const marker = new Marker({ element: el }).setLnglat({ - lng: coord[0], - lat: coord[1] - }); - scene.addMarker(marker); }); -}); +} diff --git a/packages/core/src/services/component/MarkerService.ts b/packages/core/src/services/component/MarkerService.ts index e742bef00c..dd30a4b276 100644 --- a/packages/core/src/services/component/MarkerService.ts +++ b/packages/core/src/services/component/MarkerService.ts @@ -11,7 +11,7 @@ export default class MarkerService implements IMarkerService { private markers: IMarker[] = []; private unAddMarkers: IMarker[] = []; public addMarker(marker: IMarker): void { - if (!this.mapsService.map && this.mapsService.getMarkerContainer()) { + if (this.mapsService.map && this.mapsService.getMarkerContainer()) { this.markers.push(marker); marker.addTo(this.scene); } else { diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index 79d362db17..e864586575 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -106,7 +106,6 @@ export interface ILayer { */ addPlugin(plugin: ILayerPlugin): ILayer; getSource(): ISource; - isSourceNeedUpdate(): boolean; setSource(source: ISource): void; setEncodedData(encodedData: IEncodeFeature[]): void; getEncodedData(): IEncodeFeature[]; diff --git a/packages/core/src/services/source/ISourceService.ts b/packages/core/src/services/source/ISourceService.ts index 7d547c2316..2e03b0ac31 100644 --- a/packages/core/src/services/source/ISourceService.ts +++ b/packages/core/src/services/source/ISourceService.ts @@ -61,6 +61,7 @@ export interface ISource { data: IParserData; cluster: boolean; clusterOptions: Partial; + updateClusterData(zoom: number): void; } export interface IRasterCfg { extent: [number, number, number, number]; diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts index 3874894474..ae4463bc56 100644 --- a/packages/layers/src/core/BaseLayer.ts +++ b/packages/layers/src/core/BaseLayer.ts @@ -371,30 +371,6 @@ export default class BaseLayer extends EventEmitter this.buildModels(); return this; } - - public isSourceNeedUpdate() { - const cluster = this.layerSource.cluster; - if (cluster) { - const { zoom = 0, bbox = [0, 0, 0, 0] } = this.layerSource.clusterOptions; - const newZoom = this.mapService.getZoom(); - const bounds = this.mapService.getBounds(); - const newBbox: [number, number, number, number] = [ - bounds[0][0], - bounds[0][1], - bounds[1][0], - bounds[1][1], - ]; - // || - // bbox[0] !== newBbox[0] || - // bbox[2] !== newBbox[2] - if (Math.abs(zoom - newZoom) > 1) { - this.layerSource.updateClusterData(Math.floor(newZoom), newBbox); - return true; - } - } - return false; - } - public style(options: object & Partial): ILayer { const { passes, ...rest } = options; @@ -537,12 +513,7 @@ export default class BaseLayer extends EventEmitter const bounds = this.mapService.getBounds(); const zoom = this.mapService.getZoom(); if (this.layerSource.cluster) { - this.layerSource.updateClusterData(zoom, [ - bounds[0][0], - bounds[0][1], - bounds[1][0], - bounds[1][1], - ]); + this.layerSource.updateClusterData(zoom); } } public getSource() { diff --git a/packages/layers/src/plugins/DataSourcePlugin.ts b/packages/layers/src/plugins/DataSourcePlugin.ts index 4db5efe3ba..e99b486125 100644 --- a/packages/layers/src/plugins/DataSourcePlugin.ts +++ b/packages/layers/src/plugins/DataSourcePlugin.ts @@ -1,10 +1,12 @@ -import { ILayer, ILayerPlugin } from '@antv/l7-core'; +import { ILayer, ILayerPlugin, IMapService, TYPES } from '@antv/l7-core'; import Source from '@antv/l7-source'; import { injectable } from 'inversify'; @injectable() export default class DataSourcePlugin implements ILayerPlugin { + protected mapService: IMapService; public apply(layer: ILayer) { + this.mapService = layer.getContainer().get(TYPES.IMapService); layer.hooks.init.tap('DataSourcePlugin', () => { const { data, options } = layer.sourceOption; layer.setSource(new Source(data, options)); @@ -12,7 +14,12 @@ export default class DataSourcePlugin implements ILayerPlugin { // 检测数据是不否需要更新 layer.hooks.beforeRenderData.tap('DataSourcePlugin', (flag) => { - if (layer.isSourceNeedUpdate()) { + const source = layer.getSource(); + const cluster = source.cluster; + const { zoom = 0, maxZoom = 16 } = source.clusterOptions; + const newZoom = this.mapService.getZoom(); + if (cluster && Math.abs(zoom - newZoom) > 1 && maxZoom > zoom) { + source.updateClusterData(Math.floor(newZoom) + 1); return true; } return false; diff --git a/packages/source/__tests__/source.spec.ts b/packages/source/__tests__/source.spec.ts index 047c150766..baec235c98 100644 --- a/packages/source/__tests__/source.spec.ts +++ b/packages/source/__tests__/source.spec.ts @@ -20,6 +20,6 @@ describe('source constructor', () => { field: 'mag', }, }); - source.updateClusterData(2, [10, 0, 130, 75]); + source.updateClusterData(2); }); }); diff --git a/packages/source/src/source.ts b/packages/source/src/source.ts index 09dfd27f90..86a31b9350 100644 --- a/packages/source/src/source.ts +++ b/packages/source/src/source.ts @@ -1,9 +1,12 @@ import { IClusterOptions, + IMapService, IParserCfg, IParserData, ISourceCFG, ITransform, + lazyInject, + TYPES, } from '@antv/l7-core'; import { extent } from '@antv/l7-utils'; import { @@ -14,13 +17,13 @@ import { Properties, } from '@turf/helpers'; import { EventEmitter } from 'eventemitter3'; +import { Container } from 'inversify'; import { cloneDeep, isFunction, isString } from 'lodash'; import Supercluster from 'supercluster'; import { SyncHook } from 'tapable'; import { getParser, getTransform } from './'; import { statMap } from './utils/statistics'; import { getColumn } from './utils/util'; - export default class Source extends EventEmitter { public data: IParserData; @@ -82,13 +85,9 @@ export default class Source extends EventEmitter { this.init(); } - public updateClusterData( - zoom: number, - bbox: [number, number, number, number], - ): void { + public updateClusterData(zoom: number): void { const { method = 'sum', field } = this.clusterOptions; - let data = this.clusterIndex.getClusters(bbox, zoom); - this.clusterOptions.bbox = bbox; + let data = this.clusterIndex.getClusters(this.extent, zoom); this.clusterOptions.zoom = zoom; data.forEach((p) => { if (!p.id) { diff --git a/stories/Components/Components.stories.tsx b/stories/Components/Components.stories.tsx index 405bf6cbba..0c7bb0b105 100644 --- a/stories/Components/Components.stories.tsx +++ b/stories/Components/Components.stories.tsx @@ -1,5 +1,6 @@ import { storiesOf } from '@storybook/react'; import * as React from 'react'; +import Chart from './components/chart'; import Marker from './components/Marker'; import Popup from './components/Popup'; import Scale from './components/Scale'; @@ -9,4 +10,5 @@ storiesOf('UI 组件', module) .add('Zoom', () => ) .add('Scale', () => ) .add('Marker', () => ) + .add('Chart', () => ) .add('Popup', () => ); diff --git a/stories/Components/components/chart.tsx b/stories/Components/components/chart.tsx new file mode 100644 index 0000000000..095643fe4c --- /dev/null +++ b/stories/Components/components/chart.tsx @@ -0,0 +1,108 @@ +// @ts-ignore +import * as G2 from '@antv/g2'; +import { Marker, Scene } from '@antv/l7'; +import { GaodeMap, Mapbox } from '@antv/l7-maps'; +import * as React from 'react'; + +export default class ChartComponent extends React.Component { + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap({ + pitch: 0, + style: 'dark', + center: [52.21496184144132, 24.121126851768906], + zoom: 3.802, + }), + }); + addChart(); + scene.render(); + function addChart() { + Promise.all([ + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/5b772136-a1f4-4fc5-9a80-9f9974b4b182.json', + ).then((d) => d.json()), + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/f3c467a4-9ae0-4f08-bb5f-11f9c869b2cb.json', + ).then((d) => d.json()), + ]).then(function onLoad([center, population]) { + const popobj: { [key: string]: any } = {}; + population.forEach((element: any) => { + popobj[element.Code] = + element['Population, female (% of total) (% of total)']; + }); + // 数据绑定 + + center.features = center.features.map((fe: any) => { + fe.properties.female = popobj[fe.properties.id] * 1 || 0; + return fe; + }); + center.features.forEach((point: any) => { + const el = document.createElement('div'); + const coord = point.geometry.coordinates; + const v = (point.properties.female * 1) as number; + if (v < 1 || (v > 46 && v < 54)) { + return; + } + const size = 60; + const data = [ + { + type: '男性', + value: 100.0 - Number(v.toFixed(2)), + }, + { + type: '女性', + value: v.toFixed(2), + }, + ]; + const chart = new G2.Chart({ + container: el, + width: size, + height: size, + // render: 'svg', + padding: 0, + }); + chart.source(data); + chart.legend(false); + chart.tooltip(false); + chart.coord('theta', { + radius: 0.9, + innerRadius: 0.6, + }); + chart + .intervalStack() + .position('value') + .color('type', ['#5CCEA1', '#5B8FF9']) + .opacity(1); + chart.render(); + const marker = new Marker({ element: el }).setLnglat({ + lng: coord[0], + lat: coord[1], + }); + scene.addMarker(marker); + }); + }); + } + } + + public render() { + return ( +
+ ); + } +} diff --git a/stories/Layers/components/Point.tsx b/stories/Layers/components/Point.tsx index 5586e9087d..10ce3b4e0f 100644 --- a/stories/Layers/components/Point.tsx +++ b/stories/Layers/components/Point.tsx @@ -36,9 +36,6 @@ export default class Point3D extends React.Component { .scale('point_count', { type: 'quantile', }) - .filter('point_count', (point_count: number) => { - return point_count > 1; - }) .size('point_count', [5, 10, 15, 20, 25]) .color('red') .style({ @@ -46,7 +43,6 @@ export default class Point3D extends React.Component { strokeWidth: 1, }); scene.addLayer(pointLayer); - console.log(pointLayer); } public render() {