dev-docs/deckgl-api-guidelines.md
An evolving set of design guidelines intended to ensure that deck.gl is a consistent framework that is easy-to-learn as new layers and features keep being added.
The design principles listed here reflects deck.gl's general API design philosophy.
This is a list of design rules that general applies to everything in the framework. However, exceptions are sometimes necessary when there is an actual need and justification for it. Whenever this is happening, it needs to be documented somewhere, in code comments, docs, or other places that are easy to track.
A general ambition is that all deck.gl layers should accept any "ES6 container"
in the data prop. This includes ES6 Sets and Maps, as well as Immutable.js
containers. For most layers the only requirement is that iteration
over data is performed using general functions:
for (const object of this.props.data) { ... } // GOOD
this.props.data.forEach((object, index) => ...) // GOOD
Note that the following will NOT work on general containers:
for (let i = 0; i < this.props.data.length; i++) { // NOT GOOD
const object = this.props.data[i];
...
}
Special attention is normally only required when accessing elements using
keys or indices. deck.gl provides internal functions get and count to
handle such cases:
for (let i = 0; i < count(this.props.data); i++) { // GOOD
const object = get(this.props.data, i); // instead of this.props.data[i]
const value = get(object, 'value'); // instead of object.value
}
Remarks:
data.Summary: Custom layer props usually corresponds to either attributes or uniforms of the underlying shaders. An accessor (like "getColor") always sets a WebGL attribute (whether a value or a function), and a normal prop (like "color") always sets a uniform (either to a value, or a value returned by calling the supplied function).
An attribute is called instancePositions or positions, instanceColors or
colors, etc.
The property associated with that attribute is called getPosition, getColor etc:
the attribute name with instance and the plural removed.
Such property is called an accessor. Its value must be a function, in which case it is applied to every element in data to extract the data.
The updateTrigger for that accessor is named after the accessor:
getColor, getPosition.
A property that controls shader uniforms should typically be named the same as the uniform it intends to set. A uniform related property typically takes only one value (either a number or a short array)
Special care should be applied when naming a uniform that modifies an attribute (e.g. as a multiplier, or additive element), to ensure that the semantics of the property is easily understood by the user.
Naming For some well-known modifier concepts, like opacity
(which modifies the fourth component of the value returned by the getColor accessor),
it is natural to stay with the well-accepted term.
Naming Otherwise it is recommended to use a composite noun that
indicates that the attribute in question is being modified. We use the
...Scale suffix for multiplicative modifiers and ...Offset suffix
for additive modifier props (e.g: radiusScale, or elevationOffset).
Justification Carefully consider if the layer really needs a modifier. Is the use case common enough that it makes sense, or is there another way to achieve the same effect.
Documentation Extra care must be taken with documentation to make
sure that the layer user understands the interaction between the modifying
props and accessors (E.g. getRadius vs. radiusScale), as well as the
making clear what units the value being scaled is in (meters etc.)
Default values Unless with exceptional and well-documented reasons,
multiplicative props (e.g. radiusScale) should always default to 1,
and additive props to 0.
Pixels, e.g. widthPixels, radiusMinPixels,
unless the prop has a name that clearly indicates that the unit is pixels,
such as strokeWidth, i.e. stroke is generally assumed to be in pixels.width, radius). In cartographic projection
modes, world space distances will be interpreted in meters according to the
local projection scale in other projection modes world space distances will
be taken as unit coordinates.lightDirection, lightColorAmbient,
lightColorDirectional, …)settings object. (e. g. lightSettings)It is important that properties are consistent between layers, especially between layers in a layer group, as this can dramatically affect the user's ability to learn and work with deck.gl.
Update triggers should be named the same as the accessor property for the vertex attribute.
The attribute manager now accepts an accessor field that can be a string
or an array of strings - these will be automatically be used as update triggers
for that attribute.
new Layer({
updateTriggers: {
getColor: {...},
instanceColors: {...} // deprecated, backwards compatibility
}
});