diff --git a/CHANGELOG.md b/CHANGELOG.md index 14ee78cf..8c6d61bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) - Aggregated data filtering in widgets ([#96](https://github.com/CartoDB/web-sdk/pull/96)) +### Changed +- Rename `beforeLayerId|afterLayerId` options in `carto.viz.Layer.addTo` to a more clear `overLayerId|underLayerId`. + ### Fixed - Fix `dataReady` event in `carto.viz.Layer` ([#99](https://github.com/CartoDB/web-sdk/pull/99/)) diff --git a/examples/_debug/basic/severalLayersWithCustomOrder.html b/examples/_debug/basic/severalLayersWithCustomOrder.html new file mode 100644 index 00000000..d2919c63 --- /dev/null +++ b/examples/_debug/basic/severalLayersWithCustomOrder.html @@ -0,0 +1,110 @@ + + + + + + Add several layers + + + + + + + + + +
+
+
+ +
+ + +
+
+

Add several layers

+

+ Add several CARTO layers to your map, using just multiple carto.viz.Layer.addTo calls +

+
+
+
+
+ + + + + + + + diff --git a/examples/basic/severalLayers.html b/examples/basic/severalLayers.html index 1453abfd..8803de33 100644 --- a/examples/basic/severalLayers.html +++ b/examples/basic/severalLayers.html @@ -82,6 +82,11 @@

const ports = new carto.viz.Layer('world_ports'); ports.addTo(deckMap); + /* + Another option to control the layer order is using 'overLayerId|underLayerId' options in addTo + methods. See the reference for a description on how to use it. + */ + /* A note on async/await. Modern JS code tries to use async/await pattern to better manage Promises and in general asynchronous code (vs the 'callback hell'). If you are not used to id, have diff --git a/src/lib/viz/__tests__/Layer.spec.ts b/src/lib/viz/__tests__/Layer.spec.ts index 76d6dfd0..ff07f9d8 100644 --- a/src/lib/viz/__tests__/Layer.spec.ts +++ b/src/lib/viz/__tests__/Layer.spec.ts @@ -91,34 +91,34 @@ describe('Layer', () => { expect(deckInstanceMock.props.layers[1].id).toBe('layer2'); }); - it('should allow adding before a layer', async () => { + it('should allow adding over a layer', async () => { const layer1 = new Layer(DEFAULT_DATASET, {}, { id: 'layer1' }); await layer1.addTo(deckInstanceMock); const layer2 = new Layer(DEFAULT_DATASET, {}, { id: 'layer2' }); - await layer2.addTo(deckInstanceMock, { beforeLayerId: 'layer1' }); + await layer2.addTo(deckInstanceMock, { overLayerId: 'layer1' }); await layer1.replaceDeckGLLayer(); expect(deckInstanceMock.props.layers.length).toBe(2); - expect(deckInstanceMock.props.layers[0].id).toBe('layer2'); - expect(deckInstanceMock.props.layers[1].id).toBe('layer1'); + expect(deckInstanceMock.props.layers[0].id).toBe('layer1'); + expect(deckInstanceMock.props.layers[1].id).toBe('layer2'); }); - it('should allow adding after a layer', async () => { + it('should allow adding under a layer', async () => { const layer1 = new Layer(DEFAULT_DATASET, {}, { id: 'layer1' }); await layer1.addTo(deckInstanceMock); const layer2 = new Layer(DEFAULT_DATASET, {}, { id: 'layer2' }); - await layer2.addTo(deckInstanceMock, { beforeLayerId: 'layer1' }); + await layer2.addTo(deckInstanceMock, { overLayerId: 'layer1' }); const layer3 = new Layer(DEFAULT_DATASET, {}, { id: 'layer3' }); - await layer3.addTo(deckInstanceMock, { afterLayerId: 'layer2' }); + await layer3.addTo(deckInstanceMock, { underLayerId: 'layer2' }); await layer1.replaceDeckGLLayer(); expect(deckInstanceMock.props.layers.length).toBe(3); - expect(deckInstanceMock.props.layers[0].id).toBe('layer2'); + expect(deckInstanceMock.props.layers[0].id).toBe('layer1'); expect(deckInstanceMock.props.layers[1].id).toBe('layer3'); - expect(deckInstanceMock.props.layers[2].id).toBe('layer1'); + expect(deckInstanceMock.props.layers[2].id).toBe('layer2'); }); }); }); diff --git a/src/lib/viz/layer/Layer.ts b/src/lib/viz/layer/Layer.ts index 90a84b15..826ef14d 100644 --- a/src/lib/viz/layer/Layer.ts +++ b/src/lib/viz/layer/Layer.ts @@ -151,7 +151,7 @@ export class Layer extends WithEvents implements StyledLayer { /** * Add the current layer to a Deck map instance. * By default the layer will be the last positioned (on top). - * To achieve a custom ordering, `beforeLayerId` or `afterLayerId` options can be used (and then the + * To achieve a custom ordering, `overLayerId` or `underLayerId` options can be used (and then the * referenced layer must have an `id`) * * Example: @@ -160,7 +160,7 @@ export class Layer extends WithEvents implements StyledLayer { * await layer1.addTo(deckMap); * * const layer2 = new Layer('dataset2', {}, { id: 'layer2' }); - * await layer2.addTo(deckMap, { beforeLayerId: 'layer1' }); + * await layer2.addTo(deckMap, { overLayerId: 'layer1' }); * * // at this point, the order would be 'layer2' < 'layer1' and not the opposite * ``` @@ -171,7 +171,7 @@ export class Layer extends WithEvents implements StyledLayer { * add more layers or to use it in a `DataView` then you must use `await` for it to finish. * * @param {Deck} instance of the map to add the layer to - * @param {{ beforeLayerId?: string; afterLayerId?: string }} [opts={}] options to control relative layer position + * @param {{ overLayerId?: string; underLayerId?: string }} [opts={}] options to control relative layer position * @memberof Layer */ public async addTo(deckInstance: Deck, opts: LayerPosition = {}) { @@ -613,26 +613,30 @@ function ensureRelatedStyleProps(layerProps: any) { // eslint-disable-next-line @typescript-eslint/no-explicit-any function addInTheRightPosition(deckglLayer: any, layers: any[], opts: LayerPosition = {}) { - const { beforeLayerId, afterLayerId } = opts; + const { overLayerId, underLayerId } = opts; - if (beforeLayerId && afterLayerId) { + if (overLayerId && underLayerId) { throw new CartoLayerError( - 'Cannot use beforeLayerId and afterLayerId at the same time', + 'Cannot use overLayerId and underLayerId at the same time', layerErrorTypes.DEFAULT ); } - if (beforeLayerId || afterLayerId) { - const beforeAfterLayerIdx = layers.findIndex(l => l.id === beforeLayerId || afterLayerId); + const baseLayerId = overLayerId || underLayerId; - if (beforeAfterLayerIdx !== -1) { - if (beforeLayerId) { - layers.splice(beforeAfterLayerIdx, 0, deckglLayer); - } else if (afterLayerId) { - layers.splice(beforeAfterLayerIdx + 1, 0, deckglLayer); + if (baseLayerId) { + const layerIdx = layers.findIndex(l => l.id === baseLayerId); + + const baseLayerFound = layerIdx !== -1; + + if (baseLayerFound) { + if (overLayerId) { + layers.splice(layerIdx + 1, 0, deckglLayer); // higher index = nearer the top + } else if (underLayerId) { + layers.splice(layerIdx, 0, deckglLayer); // lower index = nearer the bottom } } else { - layers.push(deckglLayer); + layers.push(deckglLayer); // place latest layer on top by default } } else { layers.push(deckglLayer); @@ -640,6 +644,6 @@ function addInTheRightPosition(deckglLayer: any, layers: any[], opts: LayerPosit } interface LayerPosition { - beforeLayerId?: string; - afterLayerId?: string; + overLayerId?: string; + underLayerId?: string; }