Skip to content

Commit e37ce9e

Browse files
authored
Update RFCs (visgl#1322)
1 parent dd8b848 commit e37ce9e

2 files changed

Lines changed: 140 additions & 55 deletions

File tree

dev-docs/RFCs/v6.0/data-url-rfc.md

Lines changed: 89 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,120 @@
11
# RFC: dataUrl Layer property
22

33
* **Authors**: Xiaoji Chen and Ib Green
4-
* **Date**: Aug 2017
5-
* **Status**: Initial draft, not ready for review
4+
* **Date**: Aug 2017, updated Jan 2018
5+
* **Status**: Initial draft, issues need decision
66

77
Notes:
8-
* Broken out from the [Off-thread Attribute Generation RFC]().
8+
* Originally broken out from the [Off-thread Attribute Generation RFC]().
99

1010

11-
# Motivation
11+
## Abstract
1212

13-
deck.gl makes it incredibly easy to visualize big data, just instantiate a layer with a `data` prop pointing to your data, and supply a few simple accessors to describe the structure of your data, and you are done.
13+
This RFC makes the proposal that we allow deck.gl layers to be instantiated directly with URLs (and optionally when required some additional request options such as headers, CORS flags etc), and deck.gl will then handle the async loading on behalf of the user, automatically displaying the data when loaded.
1414

15-
However, the user still needs to load the data in the first place before he or she can pass it to the layer. Depending on a users skill level, this can be anything from a minor 5-minute routine exercise, to a multi-day knock-out blow (learning about requests and XHR, installing and tinkering with npm modules, figuring out how to deal with an async loading in Redux, etc).
1615

17-
This RFC makes the proposal that we allow deck.gl layers to be instantiated directly with URLs (and optionally when required some additional request options such as headers, CORS flags etc), and deck.gl will then handle the async loading on behalf of the user, automatically displaying the data when loaded.
16+
## Motivation
17+
18+
deck.gl makes it easy to visualize big data, just instantiate a layer with a `data` prop pointing to your data, and supply a few simple accessors to describe the structure of your data, and you are done.
19+
20+
However, the user still needs to load the data in the first place before he or she can pass it to the layer. Depending on a users skill level, this can be anything from a minor 5-minute routine exercise, to something of a knock-out blow (learning about requests and XHR, installing and tinkering with npm modules, figuring out how to deal with an async loading in Redux, etc).
1821

1922

20-
## Proposed Implementation
23+
## What's New
2124

22-
* **Request function** - Hard to make one request function that fits all cases, can we:
23-
* Make the request function replacable
24-
* Use built-in (luma-gl's) request function as default to avoid duplicating code?
25+
### Layer Class now accepts data URLs
2526

26-
* Request parameters - Often special headers and options must be set on the request for it to succeed. How should these be supplied? Especially if we want to support different request modules?
27+
* **data** - Can now accept `Array`, `String` (URL) or `Promise` (that resolves to string).
28+
* **dataTransform** - `Function` that receives the value of data and returns an Array. Default to IDENTITY.
29+
* **fetch** (`Function`|`String`) (Default: 'json') - function used to load data. Defaults to `fetch` with JSON parsing.
30+
- `Function` returning `Promise` that resolves to data.
31+
- `String` specifying 'json', 'text' or 'binary'. A default fetch function converting data accordingly will be used.
2732

28-
* Data transformation - If the raw data is not an array that maps 1-to-1 with layer geometries (which is, most of the time), pre-processing is necessary before passing it into the data prop. Offering a prop that allows the user to specify a transformation function could extend the applicability of the `dataUrl` prop to more use cases.
33+
Remarks:
34+
* Request parameters - Often special headers and options must be set on the request for it to succeed. By supplying your own function in the `fetch` prop you gain full control.
35+
* Data transformation - If your raw data is not an array that maps directly to layer geometries, the `dataConverted` prop allows you to do any necessary post-processing on the loaded data.
2936

3037

3138
### Layer class API changes
3239

3340
| Prop | Current | Proposed |
3441
| --- | --- | --- |
35-
| `dataUrl` or `dataRequest` | - | URL String or request options |
36-
| `dataConverter` | - | Function that receives the value of data and returns an Array or Object. Default to IDENTITY. |
3742

3843

39-
### Layer life cycle changes
44+
## Impact Analysis
45+
46+
| Area | Impact |
47+
| --- | --- |
48+
| updateTriggers | No impact identified |
49+
| transitions | Minimal impact. The result of a load should trigger a transition as usual. |
50+
51+
52+
### Load process
4053

41-
* If a layer’s `dataRequest` prop is specified, when it changes, LayerManager creates a one-time Promise that downloads it. Mark the layer’s life cycle as `PENDING_LOAD` and skip rendering.
54+
* If data url is specified (a `String` or a `Promise`), when it is set, or when it changes, LayerManager records a Promise for the download.
55+
* Prop override keeps returning the old data value.
56+
* Promise is completed.
4257
* Transform the result with dataConverter.
4358
* Use the transformed result instead of the data prop of the layer, and initialize it.
4459

4560

46-
## Open Issues?
61+
## Challenges
62+
63+
### Async Deep Layer Updates (Open)
64+
65+
Concerns:
66+
* Currently "deep" layer updates (i.e attribute updates) are only triggered when a new layer list is supplied to the layer manager.
67+
* A layer can "dirty" itself to force a redraw to reflect updated uniforms, but can not trigger an update of its attributes / rerender of its sublayers.
68+
69+
Solution:
70+
* Implement a mechanism allowing layers to trigger a deep update.
71+
* Ideally should work with change flags system.
72+
* Ideally avoid doing long updates inside animation timer. Need to trigger outside, or set a flag/timer and handle outside.
73+
74+
75+
### Prop Overriding? (Solved)
76+
77+
Concerns:
78+
* Without prop overriding, support data urls would require all layers to "opt in" by switching to a new method `layer.getData()` can be confusing and error prone (wrong data shown).
79+
* Without prop overriding, allowing `data` to contain urls directly (i.e. instead of `dataUrl`) can cause crashes for non participating layers
80+
81+
Solution:
82+
* The reason for these problems is that current layers look for `props.data`. It is necessary to override this prop. The proof-of-concept PR change the props object to a class and defining accessors that refer to layer state.
83+
84+
85+
86+
### Changing the URL, while still loading data (Solved)
87+
88+
Concerns:
89+
* quick changing of a URL could cause exessive/incorrectly ordered updates.
90+
91+
Solution: We ignore any results except the last.
92+
* Maintain a counter, bump it each time we initiate a load.
93+
* Capture the counter value in the promise (function closure)
94+
* Only update data if promise matches counter. Maybe issue a warning if multiple promises are pending?
95+
96+
Note:
97+
* Not clear that we can cancel pending fetches (the fetch cancel API is a bit complex, maybe we can call a cancel callback to let the app handle it) but at least we can ignore their results.
98+
99+
100+
### Node vs Browser (Open, lower priority)
101+
102+
* isomorphic fetch
103+
* luma.gl has functions that work on both sides...
104+
105+
106+
# Ideas
107+
108+
## Automatic Type Analysis
109+
110+
Integrate type analyzer library (support an `auto` fetch prop to autodetect JSON / CSV etc)?
111+
* Add `csv`, `tsv` etc values to `DeckGL.fetch` prop (maybe using d3-dsv)?
112+
47113

48-
* Where to implement - inside `AttributeManager`?
49-
* Changing the URL, while loading data
50-
* updateTriggers - should not be an issue
51-
* New prop (`dataUrl`) vs overloading `data` to handle strings as URLs?
52-
* Node vs Browser
114+
## Support other Async Props
53115

116+
Make the loading mechanisms here available to other props that are typically asynchronously loaded
117+
* Bitmaps -
118+
* Texture Atlases -
119+
* Fonts -
54120

dev-docs/RFCs/v6.0/view-class-rfc.md

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -52,65 +52,68 @@ Secondary Requirements:
5252

5353
## Feature Proposals
5454

55-
### Proposed: New `View` ES6 Class
55+
* Proposed: New `View` ES6 Class
5656

57-
* `type` (`Viewport` subclass, default `Viewport`) - Can be any existing `Viewport` class type...
58-
* viewport specific params?
59-
* `id` - (String) - for filtering and child component layout
60-
* `x` - (Number|String, default 0)
61-
* `y` - (Number|String, default 0)
62-
* `width` - (Number|String, default `100%`)
63-
* `height` - (Number|String, default `100%`)
64-
* `layerFilter({layer, view, isPicking})` - Similar to the `layerFilter` on the main DeckGL class, this filter allows control of which layers are rendered in this viewport.
65-
* `onBeforeRender({gl, view, ...})` - called just before this view is rendered
66-
* `onAfterRender({gl, view, ...})` - called just before this view is rendered
67-
68-
69-
70-
### Viewport Autosizing: Relative Positions and Dimensions
57+
* Viewport Autosizing: Relative Positions and Dimensions - Ability to specify viewport `x`, `y`, `width`, `height` as relative values (percentages) in addition to numbers.
7158

72-
Ability to specify viewport `x`, `y`, `width`, `height` as relative values (percentages) in addition to numbers.
7359

74-
Note: `View` class instances use the "CSS" (top-left, window, non-device-pixel) coordinate system to interpreset `x`,`y`, `width` and `height` properties and automatically convert to WebGL (`gl.viewport`) coordinates under the hood.
7560

61+
## What's New
7662

77-
### Viewport: Support for x, y
63+
### New `View` Class
7864

79-
Should we be able to unproject coordinates in a viewport from a position on the canvas? If so, we may need to add x,y support to Viewport unproject.
65+
A descriptor for one view (window or viewport) into your date. Contains `id`, `type` (WebMercatorViewport etc), relative size (`x`, `y`, `width`, `height`).
8066

81-
Specifying x,y coordinates in the `Viewport` class was a small addition to the current set of parameters which already includes width and height and it is suggested that we keep it and use it for this purpose.
8267

68+
### DeckGL can displays Multiple Views
8369

84-
## API Proposals
70+
A new `views` property lets the `DeckGL` component to render multiple views of your based on a list of `View` "descriptors".
8571

72+
* Support `flattenArray`, it will allow a single `View` or nested `View` array to be passed to `views`.
8673

87-
### Proposed: New `View` ES6 Class
8874

89-
For detailed Properties see feature proposal above
90-
* type, id, relative view coordinates.
75+
## Upgrade Guide
9176

77+
### DeckGL Class
9278

93-
### Proposed: Changed `DeckGL.layerFilter` property
79+
##### Changed `DeckGL.layerFilter` property
9480

9581
Change signature `layerFilter({layer, view, isPicking})` instead of `layerFilter({layer, viewport, isPicking})`
9682

9783
We could still provide the derived viewport instance, but it may no longer have the `id` property the app most likely is looking for.
9884

9985

100-
### Proposed: New `DeckGL.views` Property
86+
| Old Method | New Method | Comment |
87+
| --- | --- | --- |
88+
| `viewports` | `views` | `viewports` was an experimental prop |
89+
| `viewport` | `views` | |
10190

102-
Allows the main `DeckGL` component to accept a list of Views (and/or viewport descriptors).
10391

104-
* Support `flattenArray`, it will allow a single `View` or nested `View` array to be passed to `views`.
92+
#### Viewport Class
93+
94+
| Old Method | New Method | Comment |
95+
| --- | --- | --- |
96+
| `id` | N/A | Removed |
97+
| `x` | N/A | TBD - keep and use as offset in projections? |
98+
| `y` | N/A | TBD - keep and use as offset in projections? |
99+
105100

101+
## View Class Docs
106102

107-
### Proposed: `DeckGL.viewports` prop deprecated, use `DeckGL.views`
103+
> Note: `View` class instances use the "CSS" (top-left, window, non-device-pixel) coordinate system to interpreset `x`,`y`, `width` and `height` properties and automatically convert to WebGL (`gl.viewport`) coordinates under the hood.
108104
109-
### Proposed: `DeckGL.viewport` prop deprecated, use `DeckGL.views`
105+
* `type` (`Viewport` subclass, default `Viewport`) - Can be any existing `Viewport` class type...
106+
* viewport specific params?
107+
* `id` - (String) - for filtering and child component layout
108+
* `x` - (Number|String, default 0)
109+
* `y` - (Number|String, default 0)
110+
* `width` - (Number|String, default `100%`)
111+
* `height` - (Number|String, default `100%`)
112+
* `layerFilter({layer, view, isPicking})` - Similar to the `layerFilter` on the main DeckGL class, this filter allows control of which layers are rendered in this viewport.
113+
* `onBeforeRender({gl, view, ...})` - called just before this view is rendered
114+
* `onAfterRender({gl, view, ...})` - called just before this view is rendered
110115

111-
### Proposed: `Viewport.id` - remove property
112116

113-
### Proposed: `Viewport.x,y` - keep, and use in (un)projections
114117

115118

116119
## Proposals that Need More Work
@@ -129,12 +132,28 @@ In this discussion, view parameter refer to a controller/viewport specific set o
129132

130133
While we can absolutely add view parameters to the View class, it is desirable to decouple "view parameters" from "view descriptors" since all other properties of view descriptors change very rarely, if at all.
131134

135+
## Impact Analysis
136+
137+
| Area | Impact |
138+
| --- | --- |
139+
| updateTriggers | No impact identified |
140+
| transitions | No impact identified |
141+
142+
143+
## Ideas
144+
145+
* Viewport: Support for x, y - Should we be able to unproject coordinates in a viewport from a position on the canvas? If so, we may need to add x,y support to Viewport unproject.
132146

133147

134148
## Extensibility
135149

136150
> Note: The purpose of this section is to show that in contrast to `Viewport`, the `View` class can support considerable functional API extensions in a natural way. The actual features are not considered part of this RFC and may need to be approved in a separate RFC before implementation.
137151
152+
### Controller
153+
154+
Specify per viewport controller (see separate RFC).
155+
156+
138157
### Advanced Render Parameters
139158

140159
Viewports and multi-view functionality is likely to keep evolving and an important aspect is that this proposal should allow for future feature growth in a natural way.

0 commit comments

Comments
 (0)