Skip to content

Commit

Permalink
Documentation Formats (visgl#1722)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress authored Apr 20, 2018
1 parent d0d8369 commit 77a239f
Show file tree
Hide file tree
Showing 79 changed files with 1,515 additions and 1,138 deletions.
2 changes: 2 additions & 0 deletions .markdownlintrc
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{
"default": true,
"colors": true,
"header-increment": false,
"line-length": false,
"ul-style": {"style": "sublist"},
"no-trailing-punctuation": {"punctuation": ".,;:"},
"no-duplicate-header": false,
"no-inline-html": false,
"no-hard-tabs": false,
Expand Down
3 changes: 2 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p align="center">
These docs are for
<a href="https://github.com/uber/deck.gl/blob/5.1-release/docs/README.md">
<a href="https://github.com/uber/deck.gl/blob/5.2-release/docs/README.md">
<img src="https://img.shields.io/badge/deck.gl-v5.1-brightgreen.svg?style=flat-square" />
</a>
Looking for an old version?
Expand All @@ -27,6 +27,7 @@ deck.gl is designed to make visualization of large data sets simple. It enables
The basic idea of using deck.gl is to render a stack of visual overlays, usually (but not always) over maps.

To make this simple concept work, deck.gl handles a number of challenges:

* Handling of large data sets and performant updates
* Interactive event handling such as picking
* Cartographic projections and integration with underlying map
Expand Down
23 changes: 12 additions & 11 deletions docs/advanced/64-bits.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,16 @@ float point numbers. This transfers to ~ `1x10^-15` relative error within

The error bound as tested on 2015 MacBook Pro with AMD Radeon R9 M370X GPU:

```
Addition and subtraction: < 1 ulp
Multiplication: ~1.5 ulps
Division: ~2 ulps
Square root: ~2.6 ulps
Exponential: ~2.6 ulps
Logarithm: ~11.6 ulps
Trigonometry: ~5 ulps
```
| Operation | Error |
| ---- | ---- |
| Addition and subtraction | < 1 ulp |
| Multiplication | ~1.5 ulps |
| Division | ~2 ulps |
| Square root | ~2.6 ulps |
| Exponential | ~2.6 ulps |
| Logarithm | ~11.6 ulps |
| Trigonometry | ~5 ulps |

Note: `ulp` = [unit of least precision](https://en.wikipedia.org/wiki/Unit_in_the_last_place)

## Performance Implications
Expand All @@ -58,5 +59,5 @@ performance benchmark layers in the layer-browser example in deck.gl repo.

## References

- http://crd-legacy.lbl.gov/~dhbailey/mpdist
- https://gmplib.org
* [http://crd-legacy.lbl.gov/~dhbailey/mpdist](http://crd-legacy.lbl.gov/~dhbailey/mpdist)
* [https://gmplib.org](https://gmplib.org)
6 changes: 3 additions & 3 deletions docs/advanced/attribute-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ vertex shader attributes are generated by iteration over a data array,
and updates to these attributes are needed either when the data itself
changes, or when other data relevant to the calculations change.

- First the application registers descriptions of its dynamic vertex
* First the application registers descriptions of its dynamic vertex
attributes using AttributeManager.add().
- Then, when any change that affects attributes is detected by the
* Then, when any change that affects attributes is detected by the
application, the app will call AttributeManager.invalidate().
- Finally before it renders, it calls AttributeManager.update() to
* Finally before it renders, it calls AttributeManager.update() to
ensure that attributes are automatically rebuilt if anything has been
invalidated.

Expand Down
12 changes: 7 additions & 5 deletions docs/advanced/composite-layers.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ A composite layer is a special kind of layer that creates other layers. It enabl
Sometimes an existing layer renders the right thing, but it would be desirable that it accepts another data format, had another interface (different accessors), or performed aggregation on its data.

Examples could be:

* Creating a `LASPointCloudLayer` that accepts `data` as an ArrayBuffer object that is loaded directly from a [LAS](https://www.asprs.org/committee-general/laser-las-file-format-exchange-activities.html)
file, and convert it to the format that `PointCloudLayer` consumes.
* Creating an `S2Layer` with an accessor that takes [S2](https://code.google.com/archive/p/s2-geometry-library/) tokens, uses the S2 library to calculates the polygons corresponding to that cell, and renders it using e.g. the PolygonLayer.
Expand All @@ -27,7 +28,7 @@ A common use case of composite layers is to augment the interface of existing la

A composite layer can be created by extending the `CompositeLayer` class:

```
```js
import {Layer, ScatterplotLayer} from 'deck.gl';

class NiceScatterplotLayer extends CompositeLayer {
Expand All @@ -40,7 +41,7 @@ NiceScatterplotLayer.layerName = 'NiceScatterplotLayer';

We will need to define the layer-specific properties of the new layer. In this example, the new layer's interface is almost identical to that of the ScatterplotLayer, except instead of one `getColor` accessor, you need two accessors `getStrokeColor` and `getFillColor`:

```
```js
NiceScatterplotLayer.defaultProps = {
...ScatterplotLayer.defaultProps,
getFillColor: d => [255, 255, 0],
Expand All @@ -56,7 +57,7 @@ By convention, the `id` of sublayers should be the `id` of the composite layer p

In this example, the idea is to draw two ScatterplotLayers, one for fill and one on top for the outline:

```
```js
class NiceScatterplotLayer extends CompositeLayer {
renderLayers() {
return [
Expand All @@ -83,7 +84,7 @@ We then want to map the user defined `getFillColor` and `getStrokeColor` accesso
Finally, to make [`updateTrigger`](/docs/api-reference/layer.md#-updatetriggers-object-optional-) work when colors need to be recalculated, we will map respective accessor names to `getColor`.
```
```js
class NiceScatterplotLayer extends CompositeLayer {

renderLayers() {
Expand Down Expand Up @@ -124,7 +125,7 @@ By default, the composite layer passes the picking info from its sublayers as-is
In this case, The composite layer may intercept the event info and modify it by implementing the `getPickingInfo()` method:
```
```js
class AwesomeCompositeLayer extends CompositeLayer {

...
Expand All @@ -136,4 +137,5 @@ class AwesomeCompositeLayer extends CompositeLayer {

}
```
For more details, read about [how picking works](/docs/advanced/picking.md).
3 changes: 2 additions & 1 deletion docs/advanced/coordinate-systems.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ The meter offset system on the other hand is very performant, but uses a lineari
The choice of coordinate system can be specified per layer, meaning that different layers can have data with positions specified in "different" coordinate systems. If some care is taken, they can all be rendered and drawn at the same time, and correctly overlaid.

An example of a use case where different coordinate systems are combined:

* Render a layer showing 3D buildings could have vertices specified in longitudes and latitudes (simply because available building data sources tend to be encoded this way)
* Render layer showing cars or pedestrians moving between the buildings with all positions specified using meter offsets from an anchor point somewhere in the city), because meter offsets are more natural encoding for this data.

Expand All @@ -55,7 +56,7 @@ Note: deck.gl always calculates a "meters per pixel" scale, allowing the applica

### The modelMatrix

Note that deck.gl only supports **meter** offsets, with y axis aligned with map north. If you like to work in other units (feet, miles etc) or other orientations (y axis pointing south, or at an angle) you should define a `modelMatrix` and build a 4x4 transformation matrix (e.g. using the [math.gl]() library).
Note that deck.gl only supports **meter** offsets, with y axis aligned with map north. If you like to work in other units (feet, miles etc) or other orientations (y axis pointing south, or at an angle) you should define a `modelMatrix` and build a 4x4 transformation matrix (e.g. using the [math.gl](https://uber-web.github.io/math.gl/#/documentation/overview) library).

The `modelMatrix` is particularly potent when used with meter offset coordinates (and non-geospatial coordinates, of course) and is usually the right solution for pre-processing (flipping, rotating, scaling etc) your data, since these operations will be done essentially for free in the GPU, rather than having to lock up your main thread for seconds after each load to transform your "big data" using JavaScript on the CPU.

Expand Down
4 changes: 4 additions & 0 deletions docs/advanced/custom-layers.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@ There are a couple of ways to build a layer in deck.gl, and it is helpful to con


## Creating The Layer class

Your layer class must be a subclass of [Layer](/docs/api-reference/layer.md).

```js
import {Layer} from 'deck.gl';

class AwesomeLayer extends Layer {...}
```

It can be a direct subclass of `Layer`, or extend another layer.

### Naming Your Layer

Store the layer name in the `layerName` static property on your `Layer` subclass:

```js
AwesomeLayer.layerName = 'AwesomeLayer';
```
Expand Down
8 changes: 4 additions & 4 deletions docs/advanced/layer-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,20 @@ you understand property change management and how to use the
Still, there are a couple of notable differences between the lifecycle
methods provided by the two frameworks:

- deck.gl performs preliminary analysis on certain props and context and
* deck.gl performs preliminary analysis on certain props and context and
provides a `changeFlags` object to your `shouldUpdateState` and
`updateState`.

- deck.gl's `updateState` method is called both on layer initialization and
* deck.gl's `updateState` method is called both on layer initialization and
on when props or context is updated. This is different from React's
`willReceiveProps` that is not called when the component is initially created,
The deck.gl model avoids requiring the same property checks to be performed
twice in both the constructor and `willReceiveProps`.

- deck.gl separates rendering into the `draw` and `renderLayers` methods,
* deck.gl separates rendering into the `draw` and `renderLayers` methods,
where React just needs `render`.

- deck.gl's `pick` and `pickInfo` methods have no correspondence in
* deck.gl's `pick` and `pickInfo` methods have no correspondence in
React's lifecycle.

**Note**: deck.gl uses a simpler component model than React.
Expand Down
6 changes: 5 additions & 1 deletion docs/advanced/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ frequently, buffer generation can cause "stutter" in e.g. animations,
even for layers with just a few thousand items. While it is usually possible to
overcome these issues using special techniques, but it can require extra work.
Before optimizing data updates, make sure that:

* you are not modifying the data prop when it hasn't changed. The layer will
do a shallow equal to determine if it needs to regenerate buffers. So if
nothing has changed, make sure you supply the **same** data object (typically
Expand Down Expand Up @@ -65,6 +66,7 @@ It is good to be aware that excessive overdraw (drawing many objects/pixels on t
deck.gl performs picking by drawing the layer into an off screen picking buffer. This essentially means that every layer that supports picking will be drawn off screen when panning and hovering. The picking is performed using the same GPU code that does the visual rendering, so the performance should be easy to predict.

Picking limitations:

* The picking system can only distinguish between 16M items per layer.
* The picking system can only handle 256 layers with the pickable flag set to true.

Expand All @@ -77,15 +79,17 @@ The layer count of an advanced deck.gl application tends to gradually increase,
## Profiling Ideas

Some profiling techniques:

* Using the `seer` chrome extension you can also get GPU timings for your layers.
* The `layer-browser` example (in the `examples` folder has a couple of performance tests that you can use to get FPS readings on your hardware for Scatterplot layers with 1M and 10M points.

## Common Issues

A couple of particular things to watch out for that tend to have a big impact on performance:
* If not needed disable Retina/High DPI rendering. It generetes 4x the number of pixels (fragments) and can have a big performance impact that depends on which computer or monitor is being used. This feature can be controlled using `useDevicePixels` prop of `DeckGL` component and it is on by default.

* If not needed disable Retina/High DPI rendering. It generetes 4x the number of pixels (fragments) and can have a big performance impact that depends on which computer or monitor is being used. This feature can be controlled using `useDevicePixels` prop of `DeckGL` component and it is on by default.
* Avoid using luma.gl debug mode in production. It queries the GPU error status after each operation which has a big impact on performance.

Smaller considerations:

* Enabling picking can have a small performance penalty so make sure the `pickable` property is `false` in layers that do not need picking (this is the default value).
24 changes: 13 additions & 11 deletions docs/advanced/picking.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ After the picking buffer is rendered, deck.gl looks at the color of the pixel un
[`layer.decodePickingColor()`](/docs/api-reference/layer.md#-decodepickingcolor-) to determine which object of the layer has been picked.

A `hover` event is triggered on a layer if:
- The layer is picked, and the picked object is different from the last frame
- The layer is not picked, but it was in the last frame

* The layer is picked, and the picked object is different from the last frame
* The layer is not picked, but it was in the last frame

A `click` event is triggered on a layer only if it's picked.

Expand All @@ -38,6 +39,7 @@ system, which most layers use.
To take full control of picking, a layer need to take the following steps:

1. Add a picking color attribute during initialization:

```js
initializeState() {
...
Expand All @@ -46,8 +48,9 @@ initializeState() {
});
}
```
- Calculate the attribute by providing a different picking color for every object that
you need to differentiate, such as:

* Calculate the attribute by providing a different picking color for every object that you need to differentiate, such as:

```js
calculatePickingColors(attribute) {
const {data} = this.props;
Expand All @@ -63,20 +66,19 @@ calculatePickingColors(attribute) {
}
```

- The default implementation of [`layer.encodePickingColor()`](/docs/api-reference/layer.md#-encodepickingcolor-) and
[`layer.decodePickingColor()`](/docs/api-reference/layer.md#-decodepickingcolor-) is likely sufficient, but you may need to implement your own pair.
- By default, the `object` field of the picking `info` object is indexed from the layer's `data` prop. Custom layers often need to define on their own terms what constitutes meaningful information to the user's callbacks. A layer can achieve this by overriding [`layer.getPickingInfo()`](/docs/api-reference/layer.md#-getpickinginfo-) to add or modify fields to the `info` object.
* The default implementation of [`layer.encodePickingColor()`](/docs/api-reference/layer.md#-encodepickingcolor-) and [`layer.decodePickingColor()`](/docs/api-reference/layer.md#-decodepickingcolor-) is likely sufficient, but you may need to implement your own pair.
* By default, the `object` field of the picking `info` object is indexed from the layer's `data` prop. Custom layers often need to define on their own terms what constitutes meaningful information to the user's callbacks. A layer can achieve this by overriding [`layer.getPickingInfo()`](/docs/api-reference/layer.md#-getpickinginfo-) to add or modify fields to the `info` object.


## Implementing Picking in Custom Shaders

All core layers (including composite layers) support picking using luma.gl's `picking module`. If you are using custom shaders with any of the core layers or building custom layers with your own shaders following steps are needed to achieve `Picking`.

### Model object creation.
### Model object creation

When creating `Model` object, add picking module to `modules` array.

```
```js
new Model(gl, {
...
vs: CUSTOM_VS,
Expand All @@ -89,7 +91,7 @@ new Model(gl, {

Vertex shader should set current picking color using `picking_setPickingColor` method provided by picking shader module.

```
```glsl
attribute vec3 instancePickingColors;
void main(void) {
Expand All @@ -105,7 +107,7 @@ void main(void) {

Fragment shader should use `picking_filterPickingColor` to update `gl_FragColor`, which outputs picking color if it is the picking pass.

```
```glsl
attribute vec3 instancePickingColors;
void main(void) {
Expand Down
19 changes: 11 additions & 8 deletions docs/advanced/primitive-layers.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ be instanced, or use dynamic geometry:
the same geometry many times. Usually the simplest way to go
when creating layers that renders a lot of similar objects (think
ScatterplotLayer, ArcLayers etc).
```

```js
/// examples/sample-layers/mesh-layer/mesh-layer.js
import {GL, Model, Geometry} from 'luma.gl';

Expand All @@ -72,12 +73,14 @@ be instanced, or use dynamic geometry:
isInstanced: true
}));
}
```
```

* **Dynamic geometry layer** - This is needed when
dealing with data that needs to be rendered using multiple similar but unique
geometries, such as polygons (i.e. the geometries are not copies of each
othat that only differ in terms of.
```

```js
/// examples/trips/trips-layer/trips-layer.js
import {GL, Model, Geometry} from 'luma.gl';

Expand All @@ -92,13 +95,13 @@ be instanced, or use dynamic geometry:
isIndexed: true
});
}
```
```
It sometimes desirable to have a single layer render using multiple geometry primitives
(e.g both circles and lines, or triangles and textured meshes etc),
rather than creating separate layers.
The custom
[AxesLayer example](https://github.com/uber/deck.gl/tree/5.1-release/examples/plot/plot-layer/axes-layer.js)
[AxesLayer example](https://github.com/uber/deck.gl/tree/5.2-release/examples/plot/plot-layer/axes-layer.js)
uses this technique to share attributes between grids and labels.
#### Defining Attributes
Expand All @@ -110,7 +113,7 @@ A layer should also define its attributes during initialization. This allows the
Define attributes by
calling [`attributeManager.add`](/docs/api-reference/attribute-manager.md#-add-):
```
```js
initializeState() {
const {gl} = this.context;
this.setState({
Expand Down Expand Up @@ -194,12 +197,12 @@ that support all three deck.gl projection modes: latlon (default), meters and ne
By always using the following shader functions for handling projections and scaling,
a single layer class can support all projection modes for free:
- All positions must be passed through the `project_position` function
* All positions must be passed through the `project_position` function
(available both in JavaScript and GLSL) to convert non-linear web-mercator
coordinates to linear mercator "world" or "pixel" coordinates,
that can be passed to the projection matrix.
- All offsets must be passed through the `project_scale` function
* All offsets must be passed through the `project_scale` function
(available both in JavaScript and GLSL) to convert distances
to world coordinates (note that that distance scales are latitude dependent
under web mercator projection
Expand Down
4 changes: 3 additions & 1 deletion docs/advanced/prop-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
This article documents the system that deck.gl offers to provide extra type annotations for layer properties.

For a number of reasons it is useful to have access to descriptions of the types of the various properties in a layer.

* Enable specification of advanced (e.g. async) properties
* Transitions and Animation
* Type Checking (during development)
Expand All @@ -32,5 +33,6 @@ const defaultProps = {
```

Tips:

* **Open Ranges** - It's unnecessary use `Math.MAX_` constants for open numeric ranges, just leave the max or min out to specify an open range.
```

Loading

0 comments on commit 77a239f

Please sign in to comment.