From 66624dfda0e67a18365985d6904ff3be517ebd28 Mon Sep 17 00:00:00 2001 From: Joe Jiang Date: Sat, 9 Mar 2019 18:09:41 +0800 Subject: [PATCH] Layer type and README implementation (#6) * update: LOGO * update: delete Globe point visualization types in demo configs * 0.0.1 * update: README EN * update: README CN * update: implement README CN * update: README with video link * merge branch from master * update: implement README with more concrete Demo Running Guidance * update: implement README with Medium article and Blog link * update: implement README with Learning Resources part * update: README * update: add Hexagon Primitive Layer * update: README and Hexagon Primitive filter functionality --- CN.md | 91 ++++++++++++++++++++++++--- README.md | 83 +++++++++++++++++++++++-- src/layers/HexagonLayer/index.js | 12 +++- src/layers/HexagonLayer/primitive.js | 92 ++++++++++++++++++++++++++++ 4 files changed, 263 insertions(+), 15 deletions(-) create mode 100644 src/layers/HexagonLayer/primitive.js diff --git a/CN.md b/CN.md index 4f8298d..f6f273a 100644 --- a/CN.md +++ b/CN.md @@ -29,6 +29,8 @@ glmaps 是一个包含多个时空数据可视化示例代码集与学习教程 我录制了一段短视频用于展现 `glmaps` 的可视化示例效果,你可以在 [YouTube](https://youtu.be/dddmamIAYj8) 或者[腾讯视频](https://v.qq.com/x/page/x0841840qwl.html)查看。 +从零开始学习时空数据可视化的第一篇文章已经发布,文中全面介绍了这个项目都包含什么。你可以根据你的阅读习惯在 [Meidum](https://medium.com/@hijiangtao/data-visualization-examples-and-tutorials-from-scratch-with-glmaps-2b93f478607f),[知乎](https://zhuanlan.zhihu.com/p/57548743)或者[我的博客](https://hijiangtao.github.io/2019/02/24/Learn-Spatio-Temporal-Data-Visualization-with-glmaps-from-Scratch/)进行查看。 + ## 目录 1. [概览](#概览) - 快速查阅 `glmaps` 都包含哪些数据可视化形式 @@ -39,8 +41,7 @@ glmaps 是一个包含多个时空数据可视化示例代码集与学习教程 6. [用法](#用法) - 用法示例 7. [文档](#文档) - `glmaps` API 文档(TBD) 8. [背后的故事](#背后的故事) -9. [联系方式](#联系方式) -10. [协议](#协议) +9. [其他学习资源](#其他学习资源) - 社区其他开放的学习资源推荐,供进一步学习阅读 ## 概览 @@ -57,6 +58,7 @@ glmaps 是一个包含多个时空数据可视化示例代码集与学习教程 |2.5D / Hexagon|支持排序筛选| [![](./assets/screenshots/HexagonLayer.jpeg)](./src/layers/HexagonLayer/index.js) | Yes | Yes | |2.5D / Grid|支持排序筛选| [![](./assets/screenshots/ScreenGridLayer.jpeg)](./src/layers/ScreenGridLayer/index.js) | No | Yes | |2.5D / Trip|与 deck 示例一致,无更改| [![](./assets/screenshots/TripLayer.jpeg)](./src/layers/TripLayer/index.js) | Yes | No | +|[2.5D / Cube](./src/layers/HexagonLayer/primitive.js)|支持排序筛选| [![]()](./src/layers/HexagonLayer/primitive.js) | No | No | |Other / Segment|与飞线动画效果一致| [![](./assets/screenshots/Globe-CurveSegment.jpeg)](./src/globe/index.js) | No | No | |Other / Moon|地月系统| [![](./assets/screenshots/Globe-Moon.jpeg)](./src/globe/index.js) | No | No | @@ -72,13 +74,15 @@ glmaps 是一个包含多个时空数据可视化示例代码集与学习教程 **Q2: 可视化初学者该如何利用这个项目学习?** -I highly recommend you follows these steps in using `glmaps`: - - Learn how to install three.js and deck.gl from scratch, and code your first "Hello World" with them; - - Run official demos and get familiar with their API; - - Follow the tutorials step by step to make your visualization examples more powerful, or check `glmaps` codes in `src` folder directly; - - (Optional) Use `glmaps` in your demo application; - - Rewrite `glmaps` example with your own codes; - - Congratulations on mastering basics of spatio-temporal visualization, you can use `three.js` and `deck.gl` to draw a more fantastic world with spatio-temporal data! +我比较建议你采用如下顺序配合 `glmaps` 进行学习: + - 先学习如何在你的项目中引入 three.js 以及 deck.gl,了解基本的使用、项目创建,这部分内容直接在 three.js 与 deck.gl 官网便可找到。尝试根据教程,试试画出你的第一个图形; + - 大概扫一下这两个框架的主 API 都有哪些,并试试下些官方 demo 在本地运行,感受下这些框架在实现可视化上的巨大能力; + - 跟着「从零开始学习时空数据可视化系列」教程一步步把 glmaps 中涉及到的可视化案例都实现一遍;如果你对 three.js 与 deck.gl 有过一定的尝试,你也可以直接参考我在 `src` 文件夹中抽象出的代码; + - (可选)尝试通过 `npm install glmaps --save` 在你的 demo 中引入 glmaps 进行展现; + - 按照你的理解重写 `glmaps` 示例代码,并为他添加更多特性; + - 恭喜你已经成功入门基本的时空数据可视化编程!你现在可以更加深入地了解 three.js 或者 deck.gl,并更加自信地创作出更好的可视化作品。 + +在完成这些学习后,你将可以独立实现如上列出的几种可视化形式作品,而个人认为这些形式已经大致包含了基本的时空可视化类型。 **Q3: 如何参与到 `glmaps` 项目中来?** @@ -105,9 +109,30 @@ I highly recommend you follows these steps in using `glmaps`: git clone git@github.com:hijiangtao/glmaps.git cd glmaps npm install +touch devconfigs.js +``` + +由于2.5D地图底图由 Mapbox 提供,所以该处需要自行配置一个 Mapbox Token,存在以上生成的 `devconfigs.js` 文件中,文件中内容格式如下(将 pk 开头的那一长串字符串替换为实际 Token 即可,Mapbox Token 配置请移步[这里](https://account.mapbox.com/access-tokens/)): + +``` +// devconfigs.js +const MAPBOX_TOKEN = 'pk.eyJ1IjoiaGlqaWFuZ3RhbyIsImEiOiJjampxcjFnb3E2NTB5M3BvM253ZHV5YjhjIn0.WneUon5qFigfJRJ3oaZ3Ow'; + +export { + MAPBOX_TOKEN, +} +``` + +*注:虽然这样说不太好,但是当你懒得自己申请 TOKEN 的时候,可以巧妙的利用搜索引擎通过关键字搜到别人的不小心传到往上的 TOKEN。比如 ,排在第一的可用 TOKEN 长成这样 'pk.eyJ1IjoiY3NuIiwiYSI6ImNpdnRvam1qeDAwMXgyenRlZjZiZWc1a2wifQ.Gr5pLJzG-1tucwY4h-rGdA'...* + +以上文件配置完成之后,打开命令行继续: + +``` npm run start ``` +构建完成后会自动打开浏览器页面,你便可以看到效果啦。 + ## 从零开始学习时空数据可视化系列教程 暂定八篇教程,如有需要可以提 [issue]((https://github.com/hijiangtao/glmaps/issues/new)) 讨论。 @@ -182,6 +207,54 @@ const Demo = (props) => { 3. Cube 4. Moon +``` +src +├── globe +│   ├── CubeMesh.js +│   ├── Curve.js +│   ├── Mover.js +│   ├── README.md +│   ├── SceneManager.js +│   ├── Tube.js +│   ├── constants.js +│   ├── index.js +│   ├── index.less +│   └── utils.js +├── index.js +└── layers + ├── AnimationLayer + │   └── index.js + ├── ArcLayer + │   ├── animate.js + │   └── index.js + ├── HexagonLayer + │   └── index.js + ├── IconLayer + │   ├── cluster.js + │   ├── icon-mapping.js + │   └── index.js + ├── README.md + ├── ScatterplotLayer + │   └── index.js + ├── ScreenGridLayer + │   └── index.js + └── TripLayer + └── index.js +``` + +## 其他学习资源 + +如果你在学习过程中有发现任何有价值的学习资料,欢迎提交 PR 完善本部分,让我们一起把它建设的更好。 + +### 1. 在线图书 + +* CN/EN - [WebGL 理论基础](https://webglfundamentals.org/) +* EN - [WebGL2 理论基础](https://webgl2fundamentals.org/) + +### 2. 视频教程 + +TBD + ## 背后的故事 TBD diff --git a/README.md b/README.md index 21783cc..61f7ba1 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,9 @@ Spatio-temporal data visualization example codes and tutorials from scratch. Watch online demo video at [YouTube](https://youtu.be/dddmamIAYj8) or [Tencent Video](https://v.qq.com/x/page/x0841840qwl.html). -## MENU +A brief introduction of thie project is now available at [Meidum](https://medium.com/@hijiangtao/data-visualization-examples-and-tutorials-from-scratch-with-glmaps-2b93f478607f), [Zhihu](https://zhuanlan.zhihu.com/p/57548743) and my [blog](https://hijiangtao.github.io/2019/02/24/Learn-Spatio-Temporal-Data-Visualization-with-glmaps-from-Scratch/). + +## Table of Contents 1. [Overview](#Overview) - Check all visualization types that `glmaps` contains. 2. [ZERO](#ZERO) - Some thoughts from me that you may pay attention before have future reading. @@ -39,8 +41,7 @@ Watch online demo video at [YouTube](https://youtu.be/dddmamIAYj8) or [Tencent V 6. [Usage](#Usage) - Usage for how to include `glmaps` in your application. 7. [Documents](#Documents) - API document for `glmaps`. TBD. 8. [Stories](#Stories) - Stories behind this repositry. -9. [Contact](#Contact) -10. [LICENSE](#LICENSE) +9. [Resources](#Resources) - Resources for further learning in Spatio-temporal Data Visualization, WebGL, etc. ## Overview @@ -57,6 +58,7 @@ Check all visualization types that `glmaps` contains, `2.5D` means you can draw |[2.5D / Hexagon](./src/layers/HexagonLayer/index.js)|Support Coverage Filter Conditions| [![](./assets/screenshots/HexagonLayer.jpeg)](./src/layers/HexagonLayer/index.js) | Yes | Yes | |[2.5D / Grid](./src/layers/ScreenGridLayer/index.js)|Support Coverage Filter Conditions| [![](./assets/screenshots/ScreenGridLayer.jpeg)](./src/layers/ScreenGridLayer/index.js) | No | Yes | |[2.5D / Trip](./src/layers/TripLayer/index.js)|No modification from deck| [![](./assets/screenshots/TripLayer.jpeg)](./src/layers/TripLayer/index.js) | Yes | No | +|[2.5D / Cube](./src/layers/HexagonLayer/primitive.js)|No modification from deck| [![]()](./src/layers/HexagonLayer/primitive.js) | No | No | |[Other / Segment](./src/globe/index.js)|The same as curve animation| [![](./assets/screenshots/Globe-CurveSegment.jpeg)](./src/globe/index.js) | No | No | |[Other / Moon](./src/globe/index.js)|Earth-Moon System| [![](./assets/screenshots/Globe-Moon.jpeg)](./src/globe/index.js) | No | No | @@ -76,7 +78,7 @@ I highly recommend you follows these steps in using `glmaps`: - Learn how to install three.js and deck.gl from scratch, and code your first "Hello World" with them; - Run official demos and get familiar with their API; - Follow the tutorials step by step to make your visualization examples more powerful, or check `glmaps` codes in `src` folder directly; - - (Optional) Use `glmaps` in your demo application; + - (Optional) Use `glmaps` in your demo application, start with `npm install glmaps --save`; - Rewrite `glmaps` example with your own codes; - Congratulations on mastering basics of spatio-temporal visualization, you can use `three.js` and `deck.gl` to draw a more fantastic world with spatio-temporal data! @@ -97,9 +99,32 @@ Open browser and enter to check the demo locally. Pleas git clone git@github.com:hijiangtao/glmaps.git cd glmaps npm install +touch devconfigs.js +``` + +To use any of Mapbox's APIs, you'll need a Mapbox access token. Mapbox uses access tokens to associate requests to API resources with your account. Since TOKEN is a private key, glmaps doesn't provide it in codes, you need to specify it in file `devconfigs.js`. + +Here's what an access token looks like (focus on the string starts with `pk.`, replace it with your own token. You can create your mapbox Token [here](https://account.mapbox.com/access-tokens/)) and the `devconfigs.js` file format: + +``` +// devconfigs.js +const MAPBOX_TOKEN = 'pk.eyJ1IjoiaGlqaWFuZ3RhbyIsImEiOiJjampxcjFnb3E2NTB5M3BvM253ZHV5YjhjIn0.WneUon5qFigfJRJ3oaZ3Ow'; + +export { + MAPBOX_TOKEN, +} +``` + +*Tips: You can utilize Search engine to get other's mapbox tokens if you don't want to create a new one, here's one token I got from GitHub Search: 'pk.eyJ1IjoiY3NuIiwiYSI6ImNpdnRvam1qeDAwMXgyenRlZjZiZWc1a2wifQ.Gr5pLJzG-1tucwY4h-rGdA', though it's not recommend to "steal" other's token…* + +Save changes in `devconfigs.js` and go on: + +``` npm run start ``` +When `glmaps` is ready, it will open browser automatically, and render demos for you. + ## Tutorials A series of spatio-temporal data visualization tutorials that guide you how to code these visualization examples step by step. TBD. @@ -174,11 +199,59 @@ This part is still under constructing, however, you can access full codes in `sr 3. Cube 4. Moon +``` +src +├── globe +│   ├── CubeMesh.js +│   ├── Curve.js +│   ├── Mover.js +│   ├── README.md +│   ├── SceneManager.js +│   ├── Tube.js +│   ├── constants.js +│   ├── index.js +│   ├── index.less +│   └── utils.js +├── index.js +└── layers + ├── AnimationLayer + │   └── index.js + ├── ArcLayer + │   ├── animate.js + │   └── index.js + ├── HexagonLayer + │   └── index.js + ├── IconLayer + │   ├── cluster.js + │   ├── icon-mapping.js + │   └── index.js + ├── README.md + ├── ScatterplotLayer + │   └── index.js + ├── ScreenGridLayer + │   └── index.js + └── TripLayer + └── index.js +``` + +## Resources + +You are welcome to raise PR to add more contents of this part, let's contribute together to make it more valuable. + +### 1. Online Book/Series + +* [WebGL Fundamentals](https://webglfundamentals.org/) +* [WebGL2 Fundamentals](https://webgl2fundamentals.org/) + +### 2. Video Tutorials + +TBD + ## Stories **Q: Why I create this repositry?** -A: I am really impressed by many open source developers when I learning how to visualize data on Web. They had contributed a lof of codes and resources in guiding beginners. I want to record what I learned and coded with these visualization frameworks, and hope that can raise your interests in data visualization, too. +A: I am really impressed by many open source developers when I learning how to visualize data on Web. They had contributed a lof of codes and resources in guiding beginners. This year, I want to take visualization as a serious work to do in my spare time. I will keep on record what I learned in my blog, at the same time I want to share more and hope my notes and codes can raise your interests in data visualization, too. Keep Simple and Love Visualization. ## Contact diff --git a/src/layers/HexagonLayer/index.js b/src/layers/HexagonLayer/index.js index 715ecae..ee4b04d 100644 --- a/src/layers/HexagonLayer/index.js +++ b/src/layers/HexagonLayer/index.js @@ -5,7 +5,9 @@ * @Last Modified time: 2019-01-14 17:44:05 */ +import React, { memo } from 'react'; import {HexagonLayer, CompositeLayer} from 'deck.gl'; +import HexagonPrimitiveLayer from './primitive'; const ELEVATION_SCALE = {min: 1, max: 500}; const OVERFLOW_FLAG = 9999; @@ -173,4 +175,12 @@ AugmentHexagonLayer.defaultProps = { } }; -export default AugmentHexagonLayer; +const HexagonCollection = (props) => { + if (props.primitive) { + return ; + } else { + return ; + } +} + +export default HexagonCollection; diff --git a/src/layers/HexagonLayer/primitive.js b/src/layers/HexagonLayer/primitive.js new file mode 100644 index 0000000..f2f4d4f --- /dev/null +++ b/src/layers/HexagonLayer/primitive.js @@ -0,0 +1,92 @@ +/* + * @Author: hijiangtao (hijiangtao@gmail.com) + * @Date: 2019-03-09 14:51:42 + * @Desc: Hexagon Primitive Layer + * @Last Modified time: 2019-03-09 14:51:42 + */ + +import {HexagonCellLayer, CompositeLayer} from 'deck.gl'; + +const DEFAULT_COLOR = [255, 0, 255, 255]; + +// const COLOR_MAP = [ +// [35, 255, 222], +// [75, 255, 35], +// [164, 255, 35], +// [255,140,0], +// [255,56,0], +// [255,0,0], +// ]; + +const MOCK_DATA = [ + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, + { COORDINATES: [-122.4, 37.7], COLOR: [255, 0, 0], SPACES: 100 }, +] + +class HexagonPrimitiveLayer extends CompositeLayer { + renderLayers() { + const { + radius = 20000, + angle = 0, + upperPercentile = 100, + coverage = 1, + extruded, + elevationScale = 100, + data = MOCK_DATA, + colorRange, + showAnimation, + ...otherProps + } = this.props; + + // calculate the maximum value for item.SPACES + data.sort((a, b) => { + return b.SPACES - a.SPACES; + }); + let max = data[0].SPACES; + let filterDataset = data.slice(0, Math.max(Number.parseInt(data.length*coverage), data.length)); + + const layerProps = { + ...otherProps, + id: `${this.id}-hp-child`, + data: filterDataset, + radius, + angle, + elevationScale, + getColor: x => x.COLOR + } + + return [ + new HexagonCellLayer(layerProps), + ]; + } +} + +HexagonPrimitiveLayer.layerName = 'HexagonPrimitiveLayer'; +HexagonPrimitiveLayer.defaultProps = { + ...HexagonCellLayer.defaultProps, + getColor: {type: 'accessor', value: DEFAULT_COLOR}, + getElevation: {type: 'accessor', value: x => x.SPACES}, + getCentroid: {type: 'accessor', value: x => x.COORDINATES}, + lightSettings: { + type: 'accessor', + value: { + lightsPosition: [-0.144528, 49.739968, 8000, -3.807751, 54.104682, 8000], + ambientRatio: 0.4, + diffuseRatio: 0.6, + specularRatio: 0.2, + lightsStrength: [0.8, 0.0, 0.8, 0.0], + numberOfLights: 2, + }, + }, + radius: {type: 'number', min: 0, value: 20000}, +}; + +export default HexagonPrimitiveLayer; \ No newline at end of file