diff --git a/.eslintrc b/.eslintrc index 2741a6f628..b6d3fb664f 100755 --- a/.eslintrc +++ b/.eslintrc @@ -3,14 +3,8 @@ "eslint-config-egg" ], "globals": { - "$": true, "AMap": true, "L7": true, - "AMapUI": true, - "DataSet": true, - "G2": true, - "_": true, - "mapboxgl":true, }, "env": { "browser": true, diff --git a/README.md b/README.md index ad122ae480..96abb3a96c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ L7 Large-scale WebGL-powered Geospatial data visualization analysis framework ### Installation ``` - npm install @l7/l7 + npm install @antv/l7 ``` diff --git a/README.zh.md b/README.zh.md new file mode 100644 index 0000000000..36ff1a9f91 --- /dev/null +++ b/README.zh.md @@ -0,0 +1,125 @@ +## L7 地理空间数据可视分析引擎 + +L7 是由蚂蚁金服 AntV 数据可视化团队推出的基于 WebGL 的开源大规模地理空间数据可视分析开发框架。L7 中的 L 代表 Location,7 代表世界七大洲,寓意能为全球位置数据提供可视分析的能力。L7 以图形符号学为理论基础,将抽象复杂的空间数据转化成 2D、3D 符号,通过颜色、大小、体积、纹理等视觉变量实现丰富的可视化表达。 + + + + +### Installation + +``` + npm install @antv/l7 + +``` + + +## 核心特性 + +### 🌏 数据驱动可视化展示 + +数据驱动,从数到形,支持丰富的地图可视化类型,更好洞察数据。 + +### 🌏 2D,3D 一体化的海量数据高性能渲染 + +百万级空间数据实时,动态渲染。 + +### 🌏简单灵活的数据接入 + +支持CSV,JSON,geojson等数据格式接入,可以根据需求自定义数据格式,无需复杂的空间数据转换。 + +### 🌏 多地图底图支持,支持离线内网部署 + +高德地图国内合法合规的地理底图,Mapbox 满足国际化业务需求。 + +## 支持丰富的图表类型 + +### 点图层 + + - 气泡图 + - 散点图 + - 符号地图 + - 3D柱状地图 + - 聚合地图 + - 复合图表地图 + - 自定义Marker + +### 线图层 + +- 路径地图 +- 弧线,支持2D弧线、3D弧线以及大圆航线 +- 等值线 + +### 面图层 + +- 填充图 +- 3D填充图 + +### 热力图 + +- 经典热力图 +- 蜂窝热力图 +- 网格热力图 + +### 栅格地图 +- 图片 +- Raster + +## L7 2.0 Roadmap + +![L7 Road Map](https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*3j9HTLTQT2MAAAAAAAAAAABkARQnAQ) + +## Development + +使用 Yarn Workspace 完成依赖安装以及各包之间的 link 工作: +```bash +yarn install +``` + +开发模式: +```bash +yarn watch +``` + +运行 Demo +```bash +yarn storybook +``` + +代替 `git commit` 提交: +```bash +yarn commit +``` + +## view doc example + +```bash + npm start +``` +visit http://localhost:8000/ + +## Add Package + +add new package: +```bash +lerna create my-pack -y +``` + +将 ui-lib 作为 my-pack 的依赖: +```bash +yarn workspace my-pack add ui-lib/1.0.0 +``` + +将 lodash 添加为所有 package 的依赖(不包含root) +```bash +yarn workspaces run add lodash +``` + +将 typescript 设置为 root 的开发依赖 +```bash +yarn add -W -D typescript jest +``` \ No newline at end of file diff --git a/babel.config.js b/babel.config.js index 28f37dbc47..439b91afb5 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,5 +1,5 @@ // @see https://babeljs.io/docs/en/next/config-files#project-wide-configuration -module.exports = (api) => { +module.exports = api => { api.cache(() => process.env.NODE_ENV); const isSite = api.env('site'); @@ -10,16 +10,16 @@ module.exports = (api) => { if (isSite) { // return { - "presets": [ - "babel-preset-gatsby" + presets: [ + 'babel-preset-gatsby' ], - "plugins": [ - '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-proposal-nullish-coalescing-operator', + plugins: [ + '@babel/plugin-proposal-optional-chaining', + '@babel/plugin-proposal-nullish-coalescing-operator', [ '@babel/plugin-proposal-decorators', { - legacy: true, + legacy: true } ], [ @@ -29,10 +29,10 @@ module.exports = (api) => { extensions: [ // 由于使用了 TS 的 resolveJsonModule 选项,JSON 可以直接引入,不需要当作纯文本 // '.json', - '.glsl', + '.glsl' ] } - ], + ] ] }; } @@ -43,20 +43,20 @@ module.exports = (api) => { { targets: { browsers: 'Last 2 Chrome versions, Firefox ESR', - node: 'current', + node: 'current' }, // set `modules: false` when building CDN bundle, let rollup do commonjs works // @see https://github.com/rollup/rollup-plugin-babel#modules - modules: (isCDNBundle || isESModule) ? false : 'auto', - }, + modules: (isCDNBundle || isESModule) ? false : 'auto' + } ], [ '@babel/preset-react', { - development: isCommonJS, - }, + development: isCommonJS + } ], - '@babel/preset-typescript', + '@babel/preset-typescript' ], plugins: [ '@babel/plugin-proposal-optional-chaining', @@ -64,14 +64,14 @@ module.exports = (api) => { [ '@babel/plugin-proposal-decorators', { - legacy: true, + legacy: true } ], [ '@babel/plugin-proposal-class-properties', { // @see https://github.com/storybookjs/storybook/issues/6069#issuecomment-472544973 - loose: true, + loose: true } ], '@babel/plugin-syntax-dynamic-import', @@ -87,7 +87,7 @@ module.exports = (api) => { extensions: [ // 由于使用了 TS 的 resolveJsonModule 选项,JSON 可以直接引入,不需要当作纯文本 // '.json', - '.glsl', + '.glsl' ] } ], @@ -95,13 +95,13 @@ module.exports = (api) => { // @see https://github.com/babel/babel/issues/8741#issuecomment-509041135 'const-enum', { - transform: 'constObject', + transform: 'constObject' } ], // 按需引用 @see https://github.com/lodash/babel-plugin-lodash 'lodash', // 内联 WebGL 常量 @see https://www.npmjs.com/package/babel-plugin-inline-webgl-constants - isCDNBundle ? 'inline-webgl-constants' : {}, + isCDNBundle ? 'inline-webgl-constants' : {} ], ignore: [ 'node_modules', @@ -113,8 +113,8 @@ module.exports = (api) => { '__tests__', '__stories__', '**/*/__snapshots__', - '**/*/__tests__', - ]: [], - ], + '**/*/__tests__' + ] : [] + ] }; -} +}; diff --git a/commitlint.config.js b/commitlint.config.js index 051a74ea10..dc0adae16c 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1,5 +1,5 @@ module.exports = { extends: [ - "@commitlint/config-conventional" + '@commitlint/config-conventional' ] -}; \ No newline at end of file +}; diff --git a/docs/API/L7.zh.md b/docs/API/L7.zh.md index 17a728d969..4a64d36219 100644 --- a/docs/API/L7.zh.md +++ b/docs/API/L7.zh.md @@ -18,19 +18,20 @@ L7 是由蚂蚁金服 AntV 数据可视化团队推出的基于 WebGL 的开源 ## 核心特性 -### 数据驱动可视化展示 + +### 🌏 数据驱动可视化展示 数据驱动,从数到形,支持丰富的地图可视化类型,更好洞察数据。 -### 2D,3D 一体化的海量数据高性能渲染 +### 🌏 2D,3D 一体化的海量数据高性能渲染 百万级空间数据实时,动态渲染。 -### 简单灵活的数据接入 +### 🌏 简单灵活的数据接入 支持CSV,JSON,geojson等数据格式接入,可以根据需求自定义数据格式,无需复杂的空间数据转换。 -### 多地图底图支持,支持离线内网部署 +### 🌏 多地图底图支持,支持离线内网部署 高德地图国内合法合规的地理底图,Mapbox 满足国际化业务需求。 diff --git a/docs/API/Scene.zh.md b/docs/API/Scene.zh.md index bec9cb3181..a0eb5cc2eb 100644 --- a/docs/API/Scene.zh.md +++ b/docs/API/Scene.zh.md @@ -16,10 +16,12 @@ L7 地理可视化 地图,图层,组件,以及可视化所需要的资源 只需要通过Scene传入地图配置项即可。 目前L7 支持两种地图底图 + - 高德地图 国内业务场景 合规中国地图 - MapBox 国际业务,或者内网离线部署场景 + 示例代码 ```javascript @@ -35,49 +37,12 @@ const scene =new L7.Scene({ ### 构造函数 -**Scene**
支持两种实例化方式 - -- 独立实例化 内部根据id自动穿件地图实例 -- 传入地图实例 +**Scene** -#### 独立实例化 Scene - -```javascript -const scene = new L7.Scene({ - id: 'map', - mapStyle: 'dark', - center: [ 120.19382669582967, 30.258134 ], - pitch: 0, - zoom: 12, - maxZoom:20, - minZoom:0 -}); -``` - - -#### 根据map 实例创建Sence - -L7 基于高德地图3D模式开发的,因此传入Map实例 __viewModes需要设置成3d_
_ -```javascript -var mapinstance = new AMap.Map('map',{ - center: [ 120.19382669582967, 30.258134 ], - viewMode: '3D', - pitch: 0, - zoom: 12, - maxZoom:20, - minZoom:0, - }); - -const scene = new L7.Scene({ - mapStyle: 'dark', - map:mapinstance -}); -``` - ## map L7 在scene 下保留了高德地图实例,可以通过scene.map 调用高德地图的map方法。
map 实例方法见[高德地图文档](https://lbs.amap.com/api/javascript-api/reference/map) @@ -86,24 +51,10 @@ L7 在scene 下保留了高德地图实例,可以通过scene.map 调用高德 scene.map ``` - -## 构造类 - -### PointLayer -新建点图层 - -### PolylineLayer -新建线图层 - -### PolygonLayer -新建面图层 - -### ImageLayer -新建图片图层 - - ## 配置项 +### 地图配置项 + ### id 需传入 dom 容器或者容器 id  {domObject || string} [必选] @@ -118,6 +69,12 @@ scene.map 地图初始俯仰角度 {number}  default 0 ### mapSyle + +简化地图样式设置,L7 内置了三种主题默认样式 +- dark +- light +- normal + 地图样式 {style} 目前仅支持高德地图。 default 'dark'
L7 内置三种种默认地图样式 dark | light|blank 空地图 设置地图的显示样式,目前支持两种地图样式:
第一种:自定义地图样式,如`"amap://styles/d6bf8c1d69cea9f5c696185ad4ac4c86"`
可前往[地图自定义平台](https://lbs.amap.com/dev/mapstyle/index)定制自己的个性地图样式;
第二种:官方样式模版,如`"amap://styles/grey"`。
其他模版样式及自定义地图的使用说明见[开发指南](https://lbs.amap.com/api/javascript-api/guide/create-map/mapstye/) diff --git a/docs/API/layer/heatmap.zh.md b/docs/API/layer/heatmap.zh.md index c092214c9a..d0fa1f946f 100644 --- a/docs/API/layer/heatmap.zh.md +++ b/docs/API/layer/heatmap.zh.md @@ -1,4 +1,203 @@ --- title: HeatmapLayer order: 5 ---- \ No newline at end of file +--- +# heatmapLayer + + +### 简介 + +热力图图层,包含三种类型的, +- 方格热力图 + +将一组点数据按照等大小的正方形网格进行聚合,一个正方形网格代表网格内所有点的统计值。方格热力图特点以方格网布局。 + +- 六边形热力图 + +将一组点数据按照等大小的六边形网格进行聚合,一个六边形网格代表网格内所有点的统计值。蜂窝热力图特点以六边形热力图网格布局 + +- 经典热力图 + + + +⚠️ 网格热力图和蜂窝热力图需要对数据聚合处理,使用之前需要在source方法设置数据聚合方法 + +### source + +热力图只支持点数据作为数据源 + +布局方法 通过source的 tansforms属性配置 + +- type  数据聚合类型 grid、hexagon +- size  网格半径 单位 米 +- field  聚合字段 +- method 聚合方法  count,max,min,sum,mean5个统计维度 + +```javascript + +layer.source(data, { + parser: { + type: 'csv', + x: 'lng', + y: 'lat' + }, + transforms:[ + { + type: 'grid', + size: 15000, + field:'v', + method:'sum' + } + ] + } +``` + +### shape + +不同类型热力图shape支持 + +| | 2D | 3d | +| --- | --- | --- | +| 网格格热力图 | circle,triangle,square,heaxgon | cylinder,triangleColumn,hexagonColum,squareColumn | +| 蜂窝热力图 | circle,triangle,square,heaxgon | circle,triangle,square,heaxgon | +| 普通热力图 | heatmap | heatmap | + + +热力图布局下只shape方法只支持常量的可视化。 + +```javascript +HeatmapLayer.shape('square'); +HeatmapLayer.shape('hexagon'); +// 默认类型可以不设置 +``` + +### size +当前版本 shape 为grid,hexagon不需要设置 size 映射 + +default 类型需要设置size映射 详细参数见[Size](https://www.yuque.com/antv/l7/layer#size) + +**size(field,values) ** + +- field: 热力图权重字段 +- values: 数据映射区间 热力图显示 [0, 1] 效果最佳 + +```javascript +HeatmapLayer.size ('field', [0, 1]) +``` + + +### color +default heatMap 类型不需设置 color映射 + +color 配置项同 [**color**](https://www.yuque.com/antv/l7/layer#color) + + + +### style + +grid hexagon 可以通过style 设置透明度 + +default热力图需要通过style配置参数热力图参数 + +- intensity   全局热力权重   推荐权重范围 1-5 +- radius  热力半径,单位像素 +- rampColors 色带参数 + - colors  颜色数组 + - positions 数据区间 + +```javascript + HeatmapLayer.style({ + intensity: 3, + radius: 20, + rampColors: { + colors: [ 'rgba(33,102,172,0.0)', 'rgb(103,169,207)', 'rgb(209,229,240)', 'rgb(253,219,199)', 'rgb(239,138,98)', 'rgb(178,24,43,1.0)' ], + positions: [ 0, 0.2, 0.4, 0.6, 0.8, 1.0 ] + } + }) +``` + + +### 完整代码示例 + +#### 普通热力图 + +```javascript +// 测试数据 url https://gw.alipayobjects.com/os/basement_prod/08c6ea00-dc5f-4bb0-b0b5-52bde5edf0a3.json + + HeatmapLayer({ + zIndex: 2 + }) + .source(data) + .size('mag', [ 0, 1 ]) // weight映射通道 + .style({ + intensity: 3, + radius: 20, + rampColors: { + colors: [ 'rgba(33,102,172,0.0)', 'rgb(103,169,207)', 'rgb(209,229,240)', 'rgb(253,219,199)', 'rgb(239,138,98)', 'rgb(178,24,43,1.0)' ], + positions: [ 0, 0.2, 0.4, 0.6, 0.8, 1.0 ] + } + }) +``` + + + +#### 网格热力图 + +```javascript +var layer = scene.HeatmapLayer({ + zIndex: 2 + }) + .source(data, { + parser: { + type: 'csv', + x: 'lng', + y: 'lat' + }, + transforms:[ + + { + type: 'grid', + size: 15000, + field:'v', + method:'sum' + } + ] + }) + .shape('grid') + .style({ + coverage: 0.8 + }) + .color('count', + ["#002466","#105CB3","#2894E0","#CFF6FF","#FFF5B8","#FFAB5C","#F27049","#730D1C"]) + +``` + + +#### 六边形热力图 + +```javascript + var layer = scene.HeatmapLayer({ + zIndex: 2 + }). + souce(data,{ + parser:{ + type:'csv', + x:lng, + y:lat, + }, + transforms:[ + type:'hexgon', + size:1500, + field:'count' + operation: 'sum' + } + ] + }) + .shape('hexgon') + .size(1000) + .color('sum') + .style({ + coverage:0.8 + }) +render() +``` \ No newline at end of file diff --git a/docs/API/layer/imagelayer.zh.md b/docs/API/layer/imagelayer.zh.md index 7563898fbc..4d0c122617 100644 --- a/docs/API/layer/imagelayer.zh.md +++ b/docs/API/layer/imagelayer.zh.md @@ -1,4 +1,23 @@ --- title: ImageLayer order: 5 ---- \ No newline at end of file +--- +# ImageLayer + +## 简介 +将图片添加到地图上,需要指定图片的经纬度范围 + +### 代码示例 + +```javascript +const layer = new ImageLayer({}); +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/layer/layer.zh.md b/docs/API/layer/layer.zh.md index e78b592c76..dfefab69a6 100644 --- a/docs/API/layer/layer.zh.md +++ b/docs/API/layer/layer.zh.md @@ -107,7 +107,7 @@ layer.source(data, { ### scale -#### scale('field', scaleConfig) +cscle('field', scaleConfig) (field: string, scaleConfig: object) @@ -127,9 +127,12 @@ layer.source(data, { ``` ### size + 将数据值映射到图形的大小上的方法。 -**注意:** 不同图层的 size 的含义有所差别: +**注意:**  + +不同图层的 size 的含义有所差别: - point 图形的 size 影响点的半径大小和高度; @@ -153,6 +156,7 @@ pointLayer.size('type', (type) => { // 回调函数 #### size(value) + 传入数字常量,如 `pointLayer.size(20)` #### size(field) @@ -196,6 +200,8 @@ layer.color('type*value', (type, value) => { //多个参数,通过回调函数 #### color(value) + + 参数:`value` :string 只支持接收一个参数,value 可以是: @@ -212,6 +218,7 @@ layer.color('white') // 指定颜色 #### color(field, colors) + 参数: - `field`: stringfield 为映射至颜色属性的数据源字段名,也支持指定多个参数。 @@ -248,7 +255,8 @@ layer.color('gender*age', (gender, age) => { ### shape 将数据值映射到图形的形状上的方法。 -#### shape(shape) +**shape(shape)** + 参数`shape` string 只支持接收一个参数,指定几何图像对象绘制的形状。下表列出了不同的 图层 几何图形对象支持的 shape 形状 @@ -260,9 +268,9 @@ layer.color('gender*age', (gender, age) => { | polygon | fill,line, extrude | | -#### shape(field, shapes) +**shape(field, shapes)** -#### shape(field, callback) +**shape(field, callback)** ### style @@ -287,50 +295,6 @@ layer.style({ ``` - - -### filter - -2.0 beta 版本还为支持,正式版本支持 - -数据过滤 - -#### filter(field,callback) -参数: -- field 数据源字段名,根据源数据字段过滤数据,也支持指定多个参数。 - -- callback 回调函数,回调函数的参数为对应字段的数值,具体使用如下,当 filter 映射为多个字段时,参数按照字段声明的顺序传入.显示数据返回true ,需要过滤掉的返回false - - -```javascript - -layer.filter('gender',(gender)=>{ - if(gender==="男") - return true; // 显示男性的数据 - else - return false; // 非男性将过滤掉 -}) -layer.filter('gender*age',(gender,age)=>{ - if(gender === '男' && age < 20) // 根据年龄和性别过滤数据 - return true; - else - return false; -}) -``` - -### active - - -开启或者关闭 shape 对于鼠标 hover 时的响应效果,L7 默认为各个 shape 内置了 active 效果 。 - -```javascript -layer.active(false); // 关闭默认响应 -layer.active(true); // 开启默认响应 -layer.active({fill:'red'}); -``` - - - ### show 图层显示 @@ -354,15 +318,5 @@ layer.hide(); ```javascript layer.fitBounds() -``` -### setActive - -- id 要素ID,一般来自 click,和 mousemove事件返回值 -- color 指定高亮颜色 - -设置指定要素的 - -```javascript -layer.setActive(id,color) -``` +``` \ No newline at end of file diff --git a/docs/API/layer/linelayer.zh.md b/docs/API/layer/linelayer.zh.md index c78c99b653..90d7b56a43 100644 --- a/docs/API/layer/linelayer.zh.md +++ b/docs/API/layer/linelayer.zh.md @@ -1,4 +1,72 @@ --- title: LineLayer order: 2 ---- \ No newline at end of file +--- +## 线图层 + +### shape + +线图层支持4种 shape + +- line 绘制路径图, +- arc 绘制弧线 通过贝塞尔曲线算法技术弧线 +- greatcircle 大圆航线,地图两个点的最近距离不是两个点连线,而是大圆航线 +- arc3d 3d弧线地图 3D视角 + +⚠️ 弧线只需要设置起始点坐标即可 + +``` + new LineLayer() + .source(data, { + parser: { + type: 'csv', + x: 'lng1', + y: 'lat1', + x1: 'lng2', + y1: 'lat2', + }, + }) +``` + +如果geojson 数据绘制弧线图 coordinates 第一对坐标为起点,第二对为终点 +``` +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 106.5234375, + 57.51582286553883 + ], + [ + 136.40625, + 61.77312286453146 + ] + ] + } + } + ] +} + +``` + +### size + +线图层 可以设置高度 + +- size 类型为number 则表示 line的宽度 +- size 类型为 [number , number] 分别表示宽度和高度 + +```javascript + +lineLayer.size(1); // 线的宽度为 1 +lineLayer.size([1,2]); // 宽度为1,高度2 + +``` + + diff --git a/docs/API/layer/pointlayer.zh.md b/docs/API/layer/pointlayer.zh.md index 029939baf5..1381b60128 100644 --- a/docs/API/layer/pointlayer.zh.md +++ b/docs/API/layer/pointlayer.zh.md @@ -1,4 +1,78 @@ --- title: PointLayer order: 1 ---- \ No newline at end of file +--- + +# PointLayer + + +## 简介 +点数据的展示,数据源支持JSON,GeoJSON,CSV 三种数据格式。 + +shape 支持 + +**3D类型 柱图** + +``` +'cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn' + +``` + +**2D 符号图** + +``` +'circle', 'square', 'hexagon', 'triangle', 'pentagon', 'octogon', 'hexagram','rhombus', 'vesica', + +``` + +**图片标注** + +通过 ```Scene.addImage()``` 可以添加图片资源, + + +### 代码示例 + + +#### 基本图形显示示例 + +```javascript +import { PointLayer } from "@antv/l7" + +const layer = PointLayer({ + zIndex: 2 + }) + .source(data.list, { + type: 'array', + x: 'j', + y: 'w', + }) + .shape('cylinder') + .size('t',(level)=> { + return [4,4,(level+40)]; + }) + .color('t', ["#002466","#105CB3","#2894E0","#CFF6FF","#FFF5B8","#FFAB5C","#F27049","#730D1C"]) + +``` + + +#### 符号图 + +使用图片添加地图标注 + +```javascript + +scene.addImage('local', 'https://gw.alipayobjects.com/zos/rmsportal/xZXhTxbglnuTmZEwqQrE.png'); + + +const layer = new PointLayer({ + zIndex: 4 + }) + .source(city) + .size(20.0) + .shape('local') + .color('#0D408C') + +``` + + + diff --git a/docs/API/layer/polygonlayer.zh.md b/docs/API/layer/polygonlayer.zh.md index 8f3fc671ac..bbfe14d1a3 100644 --- a/docs/API/layer/polygonlayer.zh.md +++ b/docs/API/layer/polygonlayer.zh.md @@ -1,4 +1,26 @@ --- title: PolygonLayer order: 3 ---- \ No newline at end of file +--- +# 填充图 + +绘制 2D 多边形以及沿 Z 轴拉伸后的 3D 图形。 + +### shape + +填充图支持3种shape + +- fill 绘制填充面 不支持数据映射 +- line 绘制填充图描边 不支持数据映射 +- extrude 对填充图3D拉伸 不支持数据映射 + +``` javascript + PolyonLayer.shape('fill'); + PolyonLayer.shape('line').size(1); // size 表示线宽度 + PolyonLayer.shape('extrude'); // size 表示高度 + +``` + +其他方法,事件,同基类 [Layer](/zh/docs/api/layer/layer) + + diff --git a/docs/manual/tutorial/quickstart.en.md b/docs/API/quickstart.en.md similarity index 100% rename from docs/manual/tutorial/quickstart.en.md rename to docs/API/quickstart.en.md diff --git a/docs/API/quickstart.zh.md b/docs/API/quickstart.zh.md new file mode 100644 index 0000000000..447a6baadc --- /dev/null +++ b/docs/API/quickstart.zh.md @@ -0,0 +1,174 @@ +--- +title: 快速上手 +order: 0 +redirect_from: + - /zh/docs/tutorial +--- +# 使用方法 + +L7 提供三种使用方式:CDN、Submodule 以及 React 组件。 + +## 通过 CDN 使用 + +首先在 `` 中引入 L7 CDN 版本的 JS 和 CSS 文件: +```html + + + + +``` + +如果使用 Mapbox,还需要额外引入 Mapbox 的 JS 和 CSS 文件,这一步可以参考 [Mapbox 文档](https://docs.mapbox.com/mapbox-gl-js/overview/#quickstart): +```html + + + + + +``` +⚠️高德采用异步加载,因此不需要引入任何额外静态文件。 + +然后在 `` 中定义一个容器并设置一个 `id`。通过全局 `L7` 这个命名空间可以获取场景 `L7.Scene` 和图层 `L7.PolygonLayer`: +⚠️需要获取高德或者 Mapbox 的使用 token 并传入 `L7.Scene` 的构造函数,获取方式如下: +* 高德地图开发者 Key [申请方法](https://lbs.amap.com/dev/key/) +* [Mapbox Access Tokens](https://docs.mapbox.com/help/how-mapbox-works/access-tokens/#creating-and-managing-access-tokens) + +## 通过 Submodule 使用 + +首先通过 `npm/yarn` 安装 `@l7/scene` 和 `@l7/layers`: +```bash +npm install --save @l7/scene @l7/layers +// or +yarn add @l7/scene @l7/layers +``` + +然后就可以使用其中包含的场景和各类图层: +```typescript +import { Scene } from '@l7/scene'; +import { PolygonLayer } from '@l7/layers'; + +(async function() { + // 获取数据 + const response = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json', + ); + const data = await response.json(); + + // 创建场景 + const scene = new Scene({ + center: [110.19382669582967, 50.258134], + id: 'map', + pitch: 0, + style: 'dark', + type: 'amap', + zoom: 3, + token: 'pg.xxx', // 高德或者 Mapbox 的 token + }); + + // 创建图层 + const layer = new PolygonLayer({}); + layer + .source(data) + .size('name', [0, 10000, 50000, 30000, 100000]) + .color('name', [ + '#2E8AE6', + '#69D1AB', + '#DAF291', + '#FFD591', + '#FF7A45', + '#CF1D49', + ]) + .shape('fill') + .style({ + opacity: 0.8, + }); + + // 添加图层到场景中 + scene.addLayer(layer); + + // 渲染场景 + scene.render(); +})(); +``` + +最后在 `` 中引入 L7 CDN 版本的 CSS 文件: +```html + + + +``` + +L7 目前的文档都通过这种方式使用,可以参考项目中的 stories: +* [高德地图](https://github.com/antvis/L7/blob/next/stories/MapAdaptor/components/AMap.tsx) +* [Mapbox](https://github.com/antvis/L7/blob/next/stories/MapAdaptor/components/Mapbox.tsx) + + +## [WIP] React + +React 组件待开发,目前可以暂时以 Submodule 方式使用: +```tsx +import { Scene } from '@l7/scene'; +import { PolygonLayer } from '@l7/layers'; +import * as React from 'react'; + +export default class AMap 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({ + center: [110.19382669582967, 50.258134], + id: 'map', + pitch: 0, + style: 'dark', + type: 'amap', + 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); + scene.render(); + this.scene = scene; + } + + public render() { + return ( +
+ ); + } +} +``` + +⚠️组件 Unmount 时需要通过 `scene.destroy()` 手动销毁场景。 + diff --git a/docs/manual/tutorial/quickstart.zh.md b/docs/manual/tutorial/quickstart.zh.md deleted file mode 100644 index c503ca42b4..0000000000 --- a/docs/manual/tutorial/quickstart.zh.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: 快速上手 -order: 0 -redirect_from: - - /zh/docs/tutorial ---- - -内容 diff --git a/gatsby-browser.js b/gatsby-browser.js index d775e14ac0..d8b2a8344b 100644 --- a/gatsby-browser.js +++ b/gatsby-browser.js @@ -1,9 +1,9 @@ require('./site/css/demo.css'); require('./packages/component/src/css/l7.css'); -window.geotiff = require('geotiff/dist/geotiff.bundle.min.js') +window.geotiff = require('geotiff/dist/geotiff.bundle.min.js'); window.scene = require('./packages/scene/src'); -window.layers= require('./packages/layers/src'); -window.component= require('./packages/component/src'); +window.layers = require('./packages/layers/src'); +window.component = require('./packages/component/src'); window.g2 = require('@antv/g2'); // diff --git a/gatsby-config.js b/gatsby-config.js index e00f70ff9a..94405ca5e5 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -4,9 +4,9 @@ module.exports = { resolve: '@antv/gatsby-theme-antv', options: { GATrackingId: 'UA-148148901-7', - pathPrefix: '/L7', - }, - }, + pathPrefix: '/L7' + } + } ], siteMetadata: { title: 'L7', @@ -17,51 +17,44 @@ module.exports = { slug: 'docs/api', title: { zh: '文档', - en: 'Document', + en: 'Document' }, - redirect: 'api/l7', - }, - { - slug: 'docs/tutorial', - title: { - zh: '教程', - en: 'Tutorial', - }, - redirect: 'tutorial/quickstart', + redirect: 'api/l7' }, { slug: 'examples', title: { zh: '图表演示', - en: 'Examples', + en: 'Examples' }, - redirect: 'gallery/basic', - }, - // target: '_blank', + redirect: 'gallery/basic' + } + // target: '_blank', ], docs: [ - { - slug: 'manual/tutorial', - title: { - zh: '教程', - en: 'Tutorial', - }, - }, { slug: 'api/l7', title: { zh: '简介 L7', - en: 'Introduction', + en: 'Introduction' }, - order:0, + order: 0 + }, + { + slug: 'api/quickstart', + title: { + zh: '快速入门', + en: 'quickstart' + }, + order: 0 }, { slug: 'api/scene', title: { zh: '场景 Scene', - en: 'Scene', + en: 'Scene' }, - order:1, + order: 1 }, { slug: 'api/layer', @@ -69,24 +62,24 @@ module.exports = { zh: '图层 Layer', en: 'Layer' }, - order:2, + order: 2 }, { slug: 'api/source', title: { zh: '数据 Source', - en: 'Source', + en: 'Source' }, - order:3, + order: 3 }, { slug: 'api/component', title: { zh: '组件 Component', - en: 'Component', + en: 'Component' }, - order:4, - }, + order: 4 + } ], examples: [ { @@ -94,61 +87,61 @@ module.exports = { icon: 'gallery', title: { zh: 'Gallery', - en: 'Gallery', - }, + en: 'Gallery' + } }, { slug: 'point', icon: 'point', title: { zh: '点图层', - en: 'Point Layer', - }, + en: 'Point Layer' + } }, { slug: 'line', icon: 'line', title: { zh: '线图层', - en: 'Line Layer', - }, + en: 'Line Layer' + } }, { slug: 'polygon', icon: 'polygon', title: { zh: '面图层', - en: 'Polygon Layer', - }, + en: 'Polygon Layer' + } }, { slug: 'heatmap', icon: 'heatmap', title: { zh: '热力图', - en: 'HeatMap Layer', + en: 'HeatMap Layer' }, - order:5, + order: 5 }, { slug: 'raster', icon: 'raster', title: { zh: '栅格图层', - en: 'Raster Layer', - }, + en: 'Raster Layer' + } }, { slug: 'tutorial', icon: 'map', title: { zh: '教程示例', - en: 'Tutorial demo', - }, - }, + en: 'Tutorial demo' + } + } ], playground: { - container: '
', - }, - }, + container: '
' + } + } }; diff --git a/gatsby-node.js b/gatsby-node.js index 6ee9be1d04..6c3b894361 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -1,5 +1,5 @@ const path = require('path'); -exports.onCreateWebpackConfig = ({ getConfig, stage, plugins }) => { +exports.onCreateWebpackConfig = ({ getConfig }) => { const config = getConfig(); config.resolve.extensions.push('.glsl'); config.resolve.alias = { @@ -11,6 +11,6 @@ exports.onCreateWebpackConfig = ({ getConfig, stage, plugins }) => { '@l7/renderer': path.resolve(__dirname, 'packages/renderer/src'), '@l7/scene': path.resolve(__dirname, 'packages/scene/src'), '@l7/source': path.resolve(__dirname, 'packages/source/src'), - '@l7/utils': path.resolve(__dirname, 'packages/utils/src'), + '@l7/utils': path.resolve(__dirname, 'packages/utils/src') }; }; diff --git a/jest.config.js b/jest.config.js index c1da91f2f2..5eb81a6ac9 100644 --- a/jest.config.js +++ b/jest.config.js @@ -8,14 +8,14 @@ module.exports = { '!**/*.d.ts' ], coverageDirectory: 'coverage', - coverageReporters: ['text', 'clover'], + coverageReporters: [ 'text', 'clover' ], coverageThreshold: { global: { branches: 80, functions: 80, lines: 80, - statements: 80, - }, + statements: 80 + } }, // globals: { // 'ts-jest': { @@ -23,20 +23,20 @@ module.exports = { // babelConfig: require('./babel.config.js'), // }, // }, - moduleFileExtensions: ['ts', 'tsx', 'js'], - modulePathIgnorePatterns: ['dist'], + moduleFileExtensions: [ 'ts', 'tsx', 'js' ], + modulePathIgnorePatterns: [ 'dist' ], moduleNameMapper: { - '@l7/(.+)$': 'packages/$1/src', + '@l7/(.+)$': 'packages/$1/src' }, notify: true, notifyMode: 'always', - roots: ['packages'], - testMatch: ['**/__tests__/*.spec.+(ts|tsx|js)', '**/*.test.+(ts|tsx|js)','**/__tests__/*/*.spec.+(ts|tsx|js)'], + roots: [ 'packages' ], + testMatch: [ '**/__tests__/*.spec.+(ts|tsx|js)', '**/*.test.+(ts|tsx|js)', '**/__tests__/*/*.spec.+(ts|tsx|js)' ], transform: { // '^.+\\.(ts|tsx)$': 'ts-jest', // @see https://github.com/kulshekhar/ts-jest/issues/1130 - '^.+\\.(ts|tsx)$': 'babel-jest', + '^.+\\.(ts|tsx)$': 'babel-jest' }, - setupFilesAfterEnv: ['jest/setupTests.ts'], - snapshotSerializers: ['enzyme-to-json/serializer'], + setupFilesAfterEnv: [ 'jest/setupTests.ts' ], + snapshotSerializers: [ 'enzyme-to-json/serializer' ] }; diff --git a/packages/layers/src/line/models/line.ts b/packages/layers/src/line/models/line.ts index c4c8bcd0c3..24cee5dff2 100644 --- a/packages/layers/src/line/models/line.ts +++ b/packages/layers/src/line/models/line.ts @@ -63,7 +63,7 @@ export default class LineModel extends BaseModel { vertex: number[], attributeIdx: number, ) => { - const { size } = feature; + const { size = 1 } = feature; return Array.isArray(size) ? [size[0], size[1]] : [size as number, 0]; }, }, diff --git a/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts b/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts index ea709b6952..35cfced0d3 100644 --- a/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts +++ b/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts @@ -60,8 +60,8 @@ export default class RegisterStyleAttributePlugin implements ILayerPlugin { }, size: 4, update: (feature: IEncodeFeature, featureIdx: number) => { - const { color } = feature; - return !color || !color.length ? [0, 0, 0, 0] : color; + const { color = [1.0, 1.0, 1.0, 1.0] } = feature; + return color; }, }, }); diff --git a/packages/layers/src/polygon/models/index.ts b/packages/layers/src/polygon/models/index.ts index cf0495ccca..dd27c23e3c 100644 --- a/packages/layers/src/polygon/models/index.ts +++ b/packages/layers/src/polygon/models/index.ts @@ -1,10 +1,12 @@ +import LineModel from '../../line/models/line'; import ExtrudeModel from './extrude'; import FillModel from './fill'; -export type PolygonModelType = 'fill' | 'extrude'; +export type PolygonModelType = 'fill' | 'extrude' | 'line'; const PolygonModels: { [key in PolygonModelType]: any } = { fill: FillModel, + line: LineModel, extrude: ExtrudeModel, }; diff --git a/packages/layers/src/polygon/polygon3D.ts b/packages/layers/src/polygon/polygon3D.ts deleted file mode 100644 index a320d45145..0000000000 --- a/packages/layers/src/polygon/polygon3D.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core'; -import BaseLayer from '../core/BaseLayer'; -import { PolygonExtrudeTriangulation } from '../core/triangulation'; -import polygonExtrudeFrag from './shaders/polygon_extrude_frag.glsl'; -import polygonExtrudeVert from './shaders/polygon_extrude_vert.glsl'; -interface IPointLayerStyleOptions { - opacity: number; -} -export default class PolygonLayer extends BaseLayer { - public name: string = 'PolygonLayer'; - - protected getConfigSchema() { - return { - properties: { - opacity: { - type: 'number', - minimum: 0, - maximum: 1, - }, - }, - }; - } - - protected renderModels() { - const { opacity } = this.getStyleOptions(); - this.models.forEach((model) => - model.draw({ - uniforms: { - u_opacity: opacity || 1.0, - }, - }), - ); - return this; - } - - protected buildModels() { - this.registerBuiltinAttributes(this); - this.models = [ - this.buildLayerModel({ - moduleName: 'polygonExtrude', - vertexShader: polygonExtrudeVert, - fragmentShader: polygonExtrudeFrag, - triangulation: PolygonExtrudeTriangulation, - }), - ]; - } - - private registerBuiltinAttributes(layer: ILayer) { - // point layer size; - layer.styleAttributeService.registerStyleAttribute({ - name: 'normal', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Normal', - buffer: { - // give the WebGL driver a hint that this buffer may change - usage: gl.STATIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 3, - update: ( - feature: IEncodeFeature, - featureIdx: number, - vertex: number[], - attributeIdx: number, - normal: number[], - ) => { - return normal; - }, - }, - }); - - layer.styleAttributeService.registerStyleAttribute({ - name: 'size', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Size', - buffer: { - // give the WebGL driver a hint that this buffer may change - usage: gl.DYNAMIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 1, - update: ( - feature: IEncodeFeature, - featureIdx: number, - vertex: number[], - attributeIdx: number, - ) => { - const { size } = feature; - return Array.isArray(size) ? [size[0]] : [size as number]; - }, - }, - }); - } -} diff --git a/site/locale.json b/site/locale.json index 9787de2cdc..cc16452ec4 100644 --- a/site/locale.json +++ b/site/locale.json @@ -2,9 +2,9 @@ "L7 地理空间数据可视分析引擎": "L7 Geospatial Visualization Analysis", "地理空间数据可视化": "Geospatial Data Visualization Analysis Framework", "L7 是由蚂蚁金服 AntV 数据可视化团队推出的基于WebGL的开源大规模地理空间数据可视分析开发框架。": "Large-scale WebGL-powered Geospatial data visualization analysis framework", - "架构上灵活可扩展":"Flexible and Scalable", - "业务上简洁且通用":"Simple and Universal", - "可视化上酷炫动感":"Cool and Dynamic", + "架构灵活且自由":"Flexible and Scalable", + "业务专业且通用":"Simple and Universal", + "视觉酷炫且动感":"Cool and Dynamic", "支持地图底图,渲染引擎,图层自由定制、扩展,组合":"Support many basemap, many rendering engine, and layer free customization, extension, combination", "以图形符号学地理设计体系理论基础,易用、易理解、专业、专注":"Base on Semiology of Graphics , easy to use, easy to understand, professional, focused", "支持海量数据,2D、3D,动态,可交互,高性能渲染":"Support multiple basemaps, rendering engines, layers can be customized, expanded and combined freely", @@ -14,5 +14,5 @@ "下载使用":"Download", "浅色色板": "Light Theme", "深色色板": "Dark Theme", - "一个个真实的数据可视化案例,复杂的地理数据,简单,易用的API接口,让用户达到开箱即用的效果." : "many real data visualization case" + "一个个真实的地理数据可视化案例,将复杂的地理数据,通过简单,易用的API接口,让用户达到开箱即用的效果。" : "We have summarized a series of story design templates from lots of real geospatial data visualization cases, so that users can use them directly." } diff --git a/site/pages/index.zh.tsx b/site/pages/index.zh.tsx index 9ff9048f00..1e1aa70d8e 100644 --- a/site/pages/index.zh.tsx +++ b/site/pages/index.zh.tsx @@ -15,13 +15,13 @@ const IndexPage = () => { { icon: 'https://gw.alipayobjects.com/zos/basement_prod/ca2168d1-ae50-4929-8738-c6df62231de3.svg', - title: t('架构上灵活可扩展'), + title: t('架构灵活且自由'), description: t('支持地图底图,渲染引擎,图层自由定制、扩展,组合'), }, { icon: 'https://gw.alipayobjects.com/zos/basement_prod/0ccf4dcb-1bac-4f4e-8d8d-f1031c77c9c8.svg', - title: t('业务上简洁且通用'), + title: t('业务专业且通用'), description: t( '以图形符号学地理设计体系理论基础,易用、易理解、专业、专注', ), @@ -29,7 +29,7 @@ const IndexPage = () => { { icon: 'https://gw.alipayobjects.com/zos/basement_prod/fd232581-14b3-45ec-a85c-fb349c51b376.svg', - title: t('可视化上酷炫动感'), + title: t('视觉酷炫且动感'), description: t('支持海量数据,2D、3D,动态,可交互,高性能渲染'), }, ]; @@ -58,7 +58,7 @@ const IndexPage = () => { { logo:'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*gjBmT56SDgsAAAAAAAAAAABkARQnAQ', title: t('浅色色板'), - description: t('一个个真实的数据可视化案例,复杂的地理数据,通过简单,易用的API接口,让用户达到开箱即用的效果。'), + description: t('将复杂的地理数据,通过简单易用的API,转化成一个个真实的可视化案例,达到开箱即用的效果。'), link: `/${i18n.language}/examples/gallery/basic`, image: 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*RPxeQZ8Uk7EAAAAAAAAAAABkARQnAQ', @@ -66,7 +66,7 @@ const IndexPage = () => { { logo:'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*gjBmT56SDgsAAAAAAAAAAABkARQnAQ', title: t('深色色板'), - description: t('一个个真实的数据可视化案例,复杂的地理数据,通过简单,易用的API接口,让用户达到开箱即用的效果'), + description: t('一个个真实的地理数据可视化案例,将复杂的地理数据,通过简单,易用的API接口,让用户达到开箱即用的效果。'), link: `/${i18n.language}/examples/gallery/basic`, image: 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*B8rtTpvkqTgAAAAAAAAAAABkARQnAQ',