Back to Deck Gl

RFC: Composite Layer Interface Convention

dev-docs/RFCs/v4.0/composite-layer-prop-forwarding-rfc.md

9.3.25.4 KB
Original Source

RFC: Composite Layer Interface Convention

  • Author: Shaojing Li
  • Date: April 4, 2017
  • Status: Approved and Implemented

Summary

Composite layers are for constructing, processing and rendering complex visualizations through compositing multiple “related” underlying layers.

In deck.gl, there are two types of composite layers,

  1. The “real” or “complex” composite layer that draws multiple different types of primitive layers, such as the GeoJson layer that draws PolygonLayer, PathLayer and ScatterPlotLayer.
  • The “Adaptor” layer that provides a slight specialization / enhancement of an existing layer but otherwise very similar functionality to the underlying layer, such as the S2Layer.

In this document, we are aiming at establishing a convention that guides the API design principles for the first type of composite layers.

In general, we would like the interfaces of the composite layer, including the props and accessors, to be explicitly declared in the defaultProps object. The composite layer, when creating its underlying layers, will NOT automatically forward props it receives to them. The author of the composite layer needs to manually select appropriate props from its prop list (all should be defined in the defaultProps object) and pass them as the specific props of the underlying layers, usually in renderLayers() method.

Remark: This deviates from the general pattern that React components pass their props.

Rationale

The rationale behind this convention is “separation of the interface from the implementation”:

  • Manual prop forwarding hides the underlying implementation of a composite layer completely from its user.
  • All info surfaced through the interface of a composite layer is totally controlled and can be examined 100% by looking at the defaultProps object.
  • The layer developers of composite layers will then have the liberty to change the implementation at will in the future, as long as the layer fulfills its interface contract documented in docs.

In addition, changes of the underlying layer will NOT automatically bubble up to the composite layer. Since the developers of the underlying layer has no way of knowing who is using his/her layer, at the time of creating and modifying it, automatic prop forwarding often leads to unexpected rendering effect on the composite layer that uses it, which diminishes the advantages brought by true “composition” of layers.

As an example, here are the 2 composite layers we would like to change to have them conformant to this convention

GeoJsonLayer

GeoJsonLayer props / accessorsMapped underlying layer props
fp64polygonFillLayer.props.fp64 polygonWireframeLayer.props.fp64 polygonLineLayer.props.fp64 pathLayer.props.fp64 pointLayer.props.fp64
strokedNot forwarded but to switch on/off polygonOutlineLayer
filledNot forwarded but to switch on/off polygonFillLayer
extrudedpolygonFillLayer.extruded
wireframeNot forwarded but to switch on/off polygonWireframeLayer
lineWidthScalepathLayer.props.widthScale polygonLineLayer.props.widthScale
lineWidthMinPixelspathLayer.props.widthMinPixels polygonLineLayer.props.widthScale
lineWidthMaxPixelspathLayer.props.widthMaxPixels polygonLineLayer.props.widthScale
lineJointRoundedpathLayer.props.rounded polygonLineLayer.props.widthScale
lineMiterLimitpathLayer.props.miterLimit polygonLineLayer.props.widthScale
getLineWidthpolygonLineLayer.props.getWidth pathLayer.props.getWidth
getLineColorpolygonWireframeLayer.props.getColor polygonLineLayer.props.getColor pathLayer.props.getColor
getFillColorpointLayer.props.getFillColor polygonFillLayer.props.getFillColor
getRadiuspointLayer.props.getRadius
getElevationpolygonFillLayer.props.getElevation polygonWireframeLayer.props.getElevation
onHoverpolygonFillLayer.props.onHover polygonWireframeLayer.props.onHover polygonLineLayer.props.onHover pathLayer.props.onHover pointLayer.props.onHover
onClickpolygonFillLayer.props.onClick polygonWireframeLayer.props.onClick polygonLineLayer.props.onClick pathLayer.props.onClick pointLayer.props.onClick

PolygonLayer

Instead of using “lineWidthScale” as in the GeoJsonLayer, I feel that the outline prefix is more intuitive as there are no lines in the “Polygon” layer. The lines we draw are logically part of the polygons, so the “outline” sound better to me.

PolygonLayer props / accessorsMapped underlying layer props
fp64polygonLayer.props.fp64 polygonWireframeLayer.props.fp64 polygonLineLayer.props.fp64
lineWidthScalepolygonLineLayer.props.widthScale
lineWidthMinPixelspolygonLineLayer.props.widthMinPixels
lineWidthMaxPixelspolygonLineLayer.props.widthMaxPixels
lineJointRoundedpolygonLineLayer.props.rounded
lineMiterLimitpolygonLineLayer.props.miterLimit
getLineColorpolygonLineLayer.props.getColor polygonWireframeLayer.props.getColor
getFillColorpolygonLayer.props.getColor
getLineWidthpolygonLineLayer.props.getWidth pathLayer.props.getWidth
getElevationpolygonLayer.props.getElevation polygonWireframeLayer.props.getElevation
onHoverpolygonLayer.props.onHover polygonWireframeLayer.props.onHover polygonLineLayer.props.onHover
onClickpolygonLayer.props.onClick polygonWireframeLayer.props.onClick polygonLineLayer.props.onClick