diff --git a/docs/api-reference/json/json-converter.md b/docs/api-reference/json/json-converter.md index d0d24dd71eb..7d3103cf572 100644 --- a/docs/api-reference/json/json-converter.md +++ b/docs/api-reference/json/json-converter.md @@ -72,7 +72,7 @@ and used to resolve this JSON object: } ``` -will replace the layers discriptor with +will replace the layers descriptor with ```js { @@ -140,3 +140,44 @@ and used to resolve this JSON object: ] } ``` + +### Constants Catalogs + +A map of constants that should be made available to the JSON string resolver. This is also helpful to evaluate a prop that does not need to be instantiated. For example, when this configuration is passed to `JSONConverter`: + +```js +import {MapController} from '@deck.gl/core'; + +const configuration = { + ... + constants: { + MapController + } +}; +``` + +and used to resolve in this JSON object: + +```json +{ + "layers": [ + { + "type": "Tile3DLayer", + "controller": "MapController" + } + ] +} +``` + +will replace the constants' value with the value provided in configuration declaration: + +```js +{ + controller: MapController, // MapController class from '@deck.gl/core' + layers: [ + new ScatterplotLayer({ + ... + }) + ] +} +`` diff --git a/examples/playground/json-examples/3d-heatmap.json b/examples/playground/json-examples/3d-heatmap.json index aaf5c1b6b95..aeaf838bfe3 100644 --- a/examples/playground/json-examples/3d-heatmap.json +++ b/examples/playground/json-examples/3d-heatmap.json @@ -1,6 +1,7 @@ { "description": "The deck.gl website hexagonlayer example in JSON format", "websiteUrl": "https://deck.gl/#/examples/core-layers/hexagon-layer", + "controller": "MapController", "initialViewState": { "longitude": -1.4157267858730052, "latitude": 52.232395363869415, diff --git a/modules/json/src/json-configuration.js b/modules/json/src/json-configuration.js index fbc36389a29..757b8dc1910 100644 --- a/modules/json/src/json-configuration.js +++ b/modules/json/src/json-configuration.js @@ -14,6 +14,7 @@ export default class JSONConfiguration { this.classes = {}; this.reactComponents = {}; this.enumerations = {}; + this.constants = {}; // TODO - this needs to be simpler, function conversion should be built in this.convertFunction = convertFunction; this.preProcessClassProps = (Class, props) => props; @@ -27,7 +28,7 @@ export default class JSONConfiguration { _merge(configuration) { for (const key in configuration) { switch (key) { - // DEPRECATED = For backwards compatibility, add views and layers to classe; + // DEPRECATED = For backwards compatibility, add views and layers to classes; case 'layers': case 'views': Object.assign(this.classes, configuration[key]); diff --git a/modules/json/src/json-converter.js b/modules/json/src/json-converter.js index d3fa34320f5..bb0e68f4ae9 100644 --- a/modules/json/src/json-converter.js +++ b/modules/json/src/json-converter.js @@ -139,13 +139,16 @@ function convertPlainObject(json, configuration) { // TODO - We could also support string syntax for hydrating other types, like regexps... // But no current use case -function convertString(json, key, configuration) { - if (configuration.enumerations[json]) { +function convertString(string, key, configuration) { + if (configuration.constants[string]) { + return configuration.constants[string]; + } + if (configuration.enumerations[string]) { // TODO - look up - return json; + return string; } if (configuration.convertFunction) { - return configuration.convertFunction(json, key, configuration); + return configuration.convertFunction(string, key, configuration); } - return json; + return string; } diff --git a/test/modules/json/data/deck-props.json b/test/modules/json/data/deck-props.json index 40a2f854c5f..a4e2ec1bb5d 100644 --- a/test/modules/json/data/deck-props.json +++ b/test/modules/json/data/deck-props.json @@ -20,6 +20,7 @@ "layers": [ { "type": "ScatterplotLayer", + "MapController": "MapController", "data": [{"position": [-122.45, 37.8]}], "getPosition": "position", "getFillColor": [255, 0, 0, 255], diff --git a/test/modules/json/json-configuration-for-deck.js b/test/modules/json/json-configuration-for-deck.js index cd058a8092e..6b781941ab6 100644 --- a/test/modules/json/json-configuration-for-deck.js +++ b/test/modules/json/json-configuration-for-deck.js @@ -1,8 +1,10 @@ -import {COORDINATE_SYSTEM, MapView, FirstPersonView} from '@deck.gl/core'; +import {COORDINATE_SYSTEM, MapView, FirstPersonView, MapController} from '@deck.gl/core'; import GL from '@luma.gl/constants'; export const log = console; // eslint-disable-line +export const SCATTER_PLOT_LAYER_ID = 'scatter-plot-layer-test'; + export default { log, // a map of all layers that should be exposes as JSONLayers @@ -12,5 +14,8 @@ export default { enumerations: { COORDINATE_SYSTEM, GL + }, + constants: { + MapController } }; diff --git a/test/modules/json/json-converter.spec.js b/test/modules/json/json-converter.spec.js index 1bc53c86bae..e74415e44e8 100644 --- a/test/modules/json/json-converter.spec.js +++ b/test/modules/json/json-converter.spec.js @@ -1,6 +1,7 @@ import test from 'tape-catch'; import {makeSpy} from '@probe.gl/test-utils'; +import {MapController} from '@deck.gl/core'; import {JSONConverter} from '@deck.gl/json'; import configuration, {log} from './json-configuration-for-deck'; import JSON_DATA from './data/deck-props.json'; @@ -24,6 +25,7 @@ test('JSONConverter#convert', t => { t.ok(deckProps, 'JSONConverter converted correctly'); t.is(deckProps.views.length, 2, 'JSONConverter converted views'); + t.is(deckProps.layers[0].props.MapController, MapController, 'Should evaluate constants.'); t.end(); });