Back to Deck Gl

API Evolution Roadmap

dev-docs/roadmaps/api-evolution-roadmap.md

9.3.25.8 KB
Original Source

API Evolution Roadmap

The deck.gl core API will need to be modernized over time. Changes to the core API have a big impact, this roadmap ensures that we have a clear long-term goal to work towards.

Core Principles

ONE API Principle

deck.gl is designed based on a "ONE API" principle, which is intended as a strong encouragement to API designers to ensure that we do not create irreconcilable forks in our API, as we continue to improve support for the React, Pure JS, scripting, JSON etc versions of the deck.gl API. Ideally a program should be portable between versions with very small differences, and learning how to use deck.gl in one version should translate directly to all versions.

Therefore any proposals here need to consider this principle and justify the design in case of deviations. Of course, by taking the conversation one step up, and talking about imperative vs. reactive/functional paradigms we can argue that this support does not cater to one specific API version but rather to ensure that we support multiple programming paradigms. Still, these changes will make programs written in the various deck.gl API incarnations more different, so it is good to exercise constraint when possible.

Basic default tooltip support

Built in tooltip implementation, so that simple apps don't have to start manipulating DOM / HTML for this basic use case. Ideally the default tooltip should somewhat customizable declaratively (without callbacks) for immediate use in JSON layers etc.

Color API

String valued colors

Support color definitions of type #abc and #aabbcc, possibly others.

  new ScatterplotLayer({
  	highlightColor: '#ffee00',
  	getFillColor: '#aa000'
  })

Feature has been requested, and we already have a very efficient string to color array parser (yarn bench to test), and a prop type system that lets us know what props are colors . We could easily apply this color string parser to color props and accessor return values.

Open questions:

  • What string syntaxes to support (performance vs alignment with CSS, SVG etc).
  • Prop type system extension: accessor return value types also need to be specified in prop types so we can apply this at the right time?
  • Possible conflict with overloading string-valued props for other use cases. I.e. we currently still have the freedom to define the semantics of strings returned from accessors (since we don't currently support it), this would limit that.

Floating Point Colors (0 to 1 instead of 0 to 255)

Background: Exposing colors as [0-255] is somewhat clunky/arbitrary. Many applications and frameworks use floats 0-1 to represent components. Misunderstandings (passing in a float) sometimes lead to nothing rendering and lost developer time.

Some thoughts:

  • Need to analyze breaking changes.
  • Use attribute normalization flag, avoid manually dividing colors with 255 in shaders. Would let us mix integer and float attributes.
  • Can we supporting both float and int colors? Autodetection (component > 1 ? 'int' : 'float') is almost but not quite practical. Letting user provide hints: Float32Array vs Uint32Array input would make things clear.

Imperative Programming API Improvements

deck.gl supports both functional (react, json) and imperative (pure-js, scripting) programming paradigms. The original design was laser focused on making sure that the library is optimized "to the bone" for the react/functional programming paradigm. This has lead to an API that is slightly surprising/clunky to use for imperative style programs. This section explores smaller changes that can be done to facilitate imperative programming without compromising performance/support for react/functional programming.

Proposal: Support partially updating layer props (v7.0 API)

Reference: Imperative Programming RFC.

Summary: One could say that React "sets all the props of all the layers all the time". This is how the deck.gl API is designed (the layers prop needs to be completely resupplied whenever any prop in any layer changes). Imperative programs are different, they normally just want to change a few props in one layer.

Proposal: Enforce updateTriggers (v7.0 API)

Reference: Imperative Programming RFC.

Summary: React apps often set accessors again and again, to new copies of identical functions (generated by using "inline" functions). To avoid performance issues, deck.gl provides the updateTriggers mechanism. Imperative programs are different, updateTriggers don't make much sense.

Proposal: Proper LayerState class hierarchy (v7.0 API)

Reference: 7.0 API

This is a partially related (imperative API improvements) idea that would mostly affect/benefit layer writers, rather than layer users

Something that tends to confuse imperative programmers is that the Layer class is a transient descriptor. In React, the React.Component subclass (the most direct equicalent to the deck.gl Layer sublass) is the permanent entity, while the transient descriptors are the React Elements (many React users do not even realize that these Elements are created as this happens transparently by transpiled JSX).

One way to move closer to this model would be to move towards a proper LayerState class/sublass setup.

class LineLayerState extends LayerState { ... }

This would let layer subclass writers focus on the permanent part of the Layer, as opposed to putting all their logic on the "dumb" descriptor.

A number of Layer methods should probably move to the Layer state, and be forwarded for now for backwards compatibility.

Note that this would not break the React JSX style of specifying the layer props? <LineLayer data={...} {...otherProps}/> since those methods are not used directly in this syntax.

More thought would also need to go into how applications could benefit from this change.