diff --git a/bindings/pydeck/pydeck/io/html.py b/bindings/pydeck/pydeck/io/html.py index 0e98387f883..8157b5d394a 100644 --- a/bindings/pydeck/pydeck/io/html.py +++ b/bindings/pydeck/pydeck/io/html.py @@ -21,7 +21,8 @@ def in_jupyter(): def convert_js_bool(py_bool): - if type(py_bool) is bool: + """Serializes Python booleans to JavaScript. Returns non-boolean values unchanged.""" + if type(py_bool) is not bool: return py_bool return "true" if py_bool else "false" diff --git a/docs/api-reference/extensions/data-filter-extension.md b/docs/api-reference/extensions/data-filter-extension.md index a7d25106b27..96888a628b1 100644 --- a/docs/api-reference/extensions/data-filter-extension.md +++ b/docs/api-reference/extensions/data-filter-extension.md @@ -70,8 +70,8 @@ new deck.DataFilterExtension({}); new DataFilterExtension({filterSize, fp64}); ``` -* `filterSize` (number) - the size of the filter (number of columns to filter by). The data filter can show/hide data based on 1-4 numeric properties of each object. Default `1`. -* `categorySize` (number) - the size of the category filter (number of columns to filter by). The category filter can show/hide data based on 1-4 properties of each object. Default `1`. +* `filterSize` (number) - the size of the filter (number of columns to filter by). The data filter can show/hide data based on 1-4 numeric properties of each object. Set to `0` to disable numeric filtering. Default `1`. +* `categorySize` (number) - the size of the category filter (number of columns to filter by). The category filter can show/hide data based on 1-4 properties of each object. Set to `0` to disable category filtering. Default `0`. * `fp64` (boolean) - if `true`, use 64-bit precision instead of 32-bit. Default `false`. See the "remarks" section below for use cases and limitations. * `countItems` (boolean) - if `true`, reports the number of filtered objects with the `onFilteredItemsChange` callback. Default `false`. diff --git a/examples/layer-browser/package.json b/examples/layer-browser/package.json index f9d01f4e050..c495aa09b0a 100644 --- a/examples/layer-browser/package.json +++ b/examples/layer-browser/package.json @@ -8,8 +8,8 @@ "start-local": "vite --config ../vite.config.local.mjs" }, "dependencies": { - "@loaders.gl/ply": "^4.1.4", - "@loaders.gl/gltf": "^4.1.4", + "@loaders.gl/ply": "^4.2.0", + "@loaders.gl/gltf": "^4.2.0", "colorbrewer": "^1.0.0", "d3-request": "^1.0.6", "d3-scale": "^3.1.0", diff --git a/examples/playground/package.json b/examples/playground/package.json index 7ee7eaf1d7e..34c705077ef 100644 --- a/examples/playground/package.json +++ b/examples/playground/package.json @@ -9,11 +9,11 @@ "build": "vite build" }, "dependencies": { - "@loaders.gl/3d-tiles": "^4.1.4", - "@loaders.gl/core": "^4.1.4", - "@loaders.gl/csv": "^4.1.4", - "@loaders.gl/draco": "^4.1.4", - "@loaders.gl/gltf": "^4.1.4", + "@loaders.gl/3d-tiles": "^4.2.0", + "@loaders.gl/core": "^4.2.0", + "@loaders.gl/csv": "^4.2.0", + "@loaders.gl/draco": "^4.2.0", + "@loaders.gl/gltf": "^4.2.0", "@luma.gl/constants": "^9.0.4", "brace": "^0.11.1", "deck.gl": "^9.0.0", diff --git a/examples/website/3d-heatmap/package.json b/examples/website/3d-heatmap/package.json index c1ea12004a3..b2a95680ce4 100644 --- a/examples/website/3d-heatmap/package.json +++ b/examples/website/3d-heatmap/package.json @@ -9,7 +9,7 @@ "build": "vite build" }, "dependencies": { - "@loaders.gl/csv": "^4.1.4", + "@loaders.gl/csv": "^4.2.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "deck.gl": "^9.0.0", diff --git a/examples/website/3d-tiles/package.json b/examples/website/3d-tiles/package.json index e7ab02b7381..e491eca093f 100644 --- a/examples/website/3d-tiles/package.json +++ b/examples/website/3d-tiles/package.json @@ -11,7 +11,7 @@ "dependencies": { "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", - "@loaders.gl/3d-tiles": "^4.1.4", + "@loaders.gl/3d-tiles": "^4.2.0", "deck.gl": "^9.0.0", "maplibre-gl": "^3.0.0", "react": "^18.0.0", diff --git a/examples/website/data-filter/package.json b/examples/website/data-filter/package.json index 87d4e77a5ad..abe1fc2758c 100644 --- a/examples/website/data-filter/package.json +++ b/examples/website/data-filter/package.json @@ -11,7 +11,7 @@ "dependencies": { "@material-ui/core": "^4.10.2", "@material-ui/icons": "^4.9.1", - "@loaders.gl/csv": "^4.1.4", + "@loaders.gl/csv": "^4.2.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "deck.gl": "^9.0.0", diff --git a/examples/website/globe/package.json b/examples/website/globe/package.json index a60e345ad8d..d4980491603 100644 --- a/examples/website/globe/package.json +++ b/examples/website/globe/package.json @@ -9,7 +9,7 @@ "build": "vite build" }, "dependencies": { - "@loaders.gl/csv": "^4.1.4", + "@loaders.gl/csv": "^4.2.0", "@material-ui/core": "^4.10.2", "@material-ui/icons": "^4.9.1", "@types/react": "^18.0.0", diff --git a/examples/website/highway/package.json b/examples/website/highway/package.json index 4dcba2539d0..8144dbcf52a 100644 --- a/examples/website/highway/package.json +++ b/examples/website/highway/package.json @@ -9,7 +9,7 @@ "build": "vite build" }, "dependencies": { - "@loaders.gl/csv": "^4.1.4", + "@loaders.gl/csv": "^4.2.0", "@types/d3-scale": "^4.0.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", diff --git a/examples/website/i3s/package.json b/examples/website/i3s/package.json index da84e3aede1..c9d172fee2c 100644 --- a/examples/website/i3s/package.json +++ b/examples/website/i3s/package.json @@ -9,7 +9,7 @@ "build": "vite build" }, "dependencies": { - "@loaders.gl/i3s": "^4.1.4", + "@loaders.gl/i3s": "^4.2.0", "deck.gl": "^9.0.0" }, "devDependencies": { diff --git a/examples/website/map-pmtile/app.jsx b/examples/website/map-pmtile/app.jsx index 3639f155728..67537527a24 100644 --- a/examples/website/map-pmtile/app.jsx +++ b/examples/website/map-pmtile/app.jsx @@ -29,9 +29,6 @@ const LINK_STYLE = { cursor: 'grab' }; -/* global window */ -const devicePixelRatio = (typeof window !== 'undefined' && window.devicePixelRatio) || 1; - function getTooltip({tile}) { if (tile) { const {x, y, z} = tile.index; @@ -41,7 +38,9 @@ function getTooltip({tile}) { } export default function App({showBorder = false, onTilesLoad = null}) { - const tileLayer = new PMTLayer({url: "https://r2-public.protomaps.com/protomaps-sample-datasets/protomaps-basemap-opensource-20230408.pmtiles"}); + const tileLayer = new PMTLayer({ + url: 'https://r2-public.protomaps.com/protomaps-sample-datasets/protomaps-basemap-opensource-20230408.pmtiles' + }); return ( { this.widgetManager?.finalize(); this.widgetManager = null; - if (!this.props.canvas && !this.props.device && this.canvas) { + if (!this.props.canvas && !this.props.device && !this.props.gl && this.canvas) { // remove internally created canvas this.canvas.parentElement?.removeChild(this.canvas); this.canvas = null; diff --git a/modules/core/src/utils/json-loader.ts b/modules/core/src/utils/json-loader.ts index f4b4300640b..de3b14da922 100644 --- a/modules/core/src/utils/json-loader.ts +++ b/modules/core/src/utils/json-loader.ts @@ -8,6 +8,8 @@ function isJSON(text: string): boolean { // A light weight version instead of @loaders.gl/json (stream processing etc.) export default { + dataType: null as any, + batchType: null as never, id: 'JSON', name: 'JSON', module: '', diff --git a/modules/extensions/src/data-filter/data-filter-extension.ts b/modules/extensions/src/data-filter/data-filter-extension.ts index 279d93cc17f..ab6369a1b04 100644 --- a/modules/extensions/src/data-filter/data-filter-extension.ts +++ b/modules/extensions/src/data-filter/data-filter-extension.ts @@ -22,7 +22,7 @@ import type {Framebuffer} from '@luma.gl/core'; import type {Model} from '@luma.gl/engine'; import type {Layer, LayerContext, Accessor, UpdateParameters} from '@deck.gl/core'; import {_deepEqual as deepEqual, LayerExtension, log} from '@deck.gl/core'; -import {shaderModule, shaderModule64} from './shader-module'; +import {Defines, shaderModule, shaderModule64} from './shader-module'; import * as aggregator from './aggregator'; const defaultProps = { @@ -96,15 +96,15 @@ export type DataFilterExtensionProps = { type DataFilterExtensionOptions = { /** - * The size of the category filter (number of columns to filter by). The category filter can show/hide data based on 1-4 properties of each object. - * @default 1 + * The size of the category filter (number of columns to filter by). The category filter can show/hide data based on 1-4 properties of each object. Set to `0` to disable category filtering. + * @default 0 */ - categorySize?: 1 | 2 | 3 | 4; + categorySize?: 0 | 1 | 2 | 3 | 4; /** - * The size of the filter (number of columns to filter by). The data filter can show/hide data based on 1-4 numeric properties of each object. + * The size of the filter (number of columns to filter by). The data filter can show/hide data based on 1-4 numeric properties of each object. Set to `0` to disable numeric filtering. * @default 1 */ - filterSize?: 1 | 2 | 3 | 4; + filterSize?: 0 | 1 | 2 | 3 | 4; /** * Use 64-bit precision instead of 32-bit. * @default false @@ -118,17 +118,17 @@ type DataFilterExtensionOptions = { }; const defaultOptions: Required = { - categorySize: 1, + categorySize: 0, filterSize: 1, fp64: false, countItems: false }; const DATA_TYPE_FROM_SIZE = { - 1: 'float', - 2: 'vec2', - 3: 'vec3', - 4: 'vec4' + 1: 'float' as const, + 2: 'vec2' as const, + 3: 'vec3' as const, + 4: 'vec4' as const }; /** Adds GPU-based data filtering functionalities to layers. It allows the layer to show/hide objects based on user-defined properties. */ @@ -144,16 +144,17 @@ export default class DataFilterExtension extends LayerExtension< getShaders(this: Layer, extension: this): any { const {categorySize, filterSize, fp64} = extension.opts; + const defines: Defines = {}; + if (categorySize) { + defines.DATACATEGORY_TYPE = DATA_TYPE_FROM_SIZE[categorySize]; + defines.DATACATEGORY_CHANNELS = categorySize; + } + if (filterSize) { + defines.DATAFILTER_TYPE = DATA_TYPE_FROM_SIZE[filterSize]; + defines.DATAFILTER_DOUBLE = Boolean(fp64); + } - return { - modules: [fp64 ? shaderModule64 : shaderModule], - defines: { - DATACATEGORY_TYPE: DATA_TYPE_FROM_SIZE[categorySize], - DATACATEGORY_CHANNELS: categorySize, - DATAFILTER_TYPE: DATA_TYPE_FROM_SIZE[filterSize], - DATAFILTER_DOUBLE: Boolean(fp64) - } - }; + return {modules: [fp64 ? shaderModule64 : shaderModule], defines}; } initializeState(this: Layer, context: LayerContext, extension: this) { @@ -161,37 +162,44 @@ export default class DataFilterExtension extends LayerExtension< const {categorySize, filterSize, fp64} = extension.opts; if (attributeManager) { - attributeManager.add({ - filterValues: { - size: filterSize, - type: fp64 ? 'float64' : 'float32', - accessor: 'getFilterValue', - shaderAttributes: { - filterValues: { - divisor: 0 - }, - instanceFilterValues: { - divisor: 1 + if (filterSize) { + attributeManager.add({ + filterValues: { + size: filterSize, + type: fp64 ? 'float64' : 'float32', + accessor: 'getFilterValue', + shaderAttributes: { + filterValues: { + divisor: 0 + }, + instanceFilterValues: { + divisor: 1 + } } } - }, - filterCategoryValues: { - size: categorySize, - accessor: 'getFilterCategory', - transform: - categorySize === 1 - ? d => extension._getCategoryKey.call(this, d, 0) - : d => d.map((x, i) => extension._getCategoryKey.call(this, x, i)), - shaderAttributes: { - filterCategoryValues: { - divisor: 0 - }, - instanceFilterCategoryValues: { - divisor: 1 + }); + } + + if (categorySize) { + attributeManager.add({ + filterCategoryValues: { + size: categorySize, + accessor: 'getFilterCategory', + transform: + categorySize === 1 + ? d => extension._getCategoryKey.call(this, d, 0) + : d => d.map((x, i) => extension._getCategoryKey.call(this, x, i)), + shaderAttributes: { + filterCategoryValues: { + divisor: 0 + }, + instanceFilterCategoryValues: { + divisor: 1 + } } } - } - }); + }); + } } const {device} = this.context; @@ -240,7 +248,7 @@ export default class DataFilterExtension extends LayerExtension< if (this.state.filterModel) { const filterNeedsUpdate = // attributeManager must be defined for filterModel to be set - attributeManager!.attributes.filterValues.needsUpdate() || + attributeManager!.attributes.filterValues?.needsUpdate() || attributeManager!.attributes.filterCategoryValues?.needsUpdate() || props.filterEnabled !== oldProps.filterEnabled || props.filterRange !== oldProps.filterRange || @@ -294,7 +302,7 @@ export default class DataFilterExtension extends LayerExtension< filterModel.updateModuleSettings(params.moduleParameters); // @ts-expect-error filterValue and filterIndices should always have buffer value filterModel.setAttributes({ - ...filterValues.getValue(), + ...filterValues?.getValue(), ...filterCategoryValues?.getValue(), ...filterIndices?.getValue() }); diff --git a/modules/extensions/src/data-filter/shader-module.ts b/modules/extensions/src/data-filter/shader-module.ts index 8a86ff012ca..5a5f168c4a5 100644 --- a/modules/extensions/src/data-filter/shader-module.ts +++ b/modules/extensions/src/data-filter/shader-module.ts @@ -5,34 +5,80 @@ import {glsl} from '../utils/syntax-tags'; /* * data filter shader module */ +export type Defines = { + // Defines passed externally + /** + * Primitive type of parameter used for category filtering. If undefined, category filtering disabled. + */ + DATACATEGORY_TYPE?: 'float' | 'vec2' | 'vec3' | 'vec4'; + /** + * Number of category filtering channels. Must match dimension of `DATACATEGORY_TYPE` + */ + DATACATEGORY_CHANNELS?: 1 | 2 | 3 | 4; + + /** + * Primitive type of parameter used for numeric filtering. If undefined, numeric filtering disabled. + */ + DATAFILTER_TYPE?: 'float' | 'vec2' | 'vec3' | 'vec4'; + + /** + * Enable 64-bit precision in numeric filter. + */ + DATAFILTER_DOUBLE?: boolean; + + // Defines derived in shader + /** + * Numeric filter attribute + */ + DATAFILTER_ATTRIB?: 'filterValues' | 'instanceFilterValues'; + /** + * Numeric filter attribute (low bits). Only used when `DATAFILTER_DOUBLE = true` + */ + DATAFILTER_ATTRIB_64LOW?: 'filterValues64Low' | 'instanceFilterValues64Low'; + /** + * Category filter attribute + */ + DATACATEGORY_ATTRIB?: 'filterCategoryValues' | 'instanceFilterCategoryValues'; +}; + const vs = glsl` -uniform DATAFILTER_TYPE filter_min; -uniform DATAFILTER_TYPE filter_softMin; -uniform DATAFILTER_TYPE filter_softMax; -uniform DATAFILTER_TYPE filter_max; uniform bool filter_useSoftMargin; uniform bool filter_enabled; uniform bool filter_transformSize; uniform ivec4 filter_categoryBitMask; -#ifdef NON_INSTANCED_MODEL - #define DATAFILTER_ATTRIB filterValues - #define DATAFILTER_ATTRIB_64LOW filterValues64Low - #define DATACATEGORY_ATTRIB filterCategoryValues -#else - #define DATAFILTER_ATTRIB instanceFilterValues - #define DATAFILTER_ATTRIB_64LOW instanceFilterValues64Low - #define DATACATEGORY_ATTRIB instanceFilterCategoryValues +#ifdef DATAFILTER_TYPE + uniform DATAFILTER_TYPE filter_min; + uniform DATAFILTER_TYPE filter_softMin; + uniform DATAFILTER_TYPE filter_softMax; + uniform DATAFILTER_TYPE filter_max; + + #ifdef NON_INSTANCED_MODEL + #define DATAFILTER_ATTRIB filterValues + #define DATAFILTER_ATTRIB_64LOW filterValues64Low + #else + #define DATAFILTER_ATTRIB instanceFilterValues + #define DATAFILTER_ATTRIB_64LOW instanceFilterValues64Low + #endif + + in DATAFILTER_TYPE DATAFILTER_ATTRIB; + #ifdef DATAFILTER_DOUBLE + in DATAFILTER_TYPE DATAFILTER_ATTRIB_64LOW; + + uniform DATAFILTER_TYPE filter_min64High; + uniform DATAFILTER_TYPE filter_max64High; + #endif #endif -in DATAFILTER_TYPE DATAFILTER_ATTRIB; -#ifdef DATAFILTER_DOUBLE - in DATAFILTER_TYPE DATAFILTER_ATTRIB_64LOW; - uniform DATAFILTER_TYPE filter_min64High; - uniform DATAFILTER_TYPE filter_max64High; +#ifdef DATACATEGORY_TYPE + #ifdef NON_INSTANCED_MODEL + #define DATACATEGORY_ATTRIB filterCategoryValues + #else + #define DATACATEGORY_ATTRIB instanceFilterCategoryValues + #endif + in DATACATEGORY_TYPE DATACATEGORY_ATTRIB; #endif -in DATACATEGORY_TYPE DATACATEGORY_ATTRIB; out float dataFilter_value; @@ -48,30 +94,35 @@ float dataFilter_reduceValue(vec3 value) { float dataFilter_reduceValue(vec4 value) { return min(min(value.x, value.y), min(value.z, value.w)); } -void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFromMax, DATACATEGORY_TYPE category) { - if (filter_enabled) { + +#ifdef DATAFILTER_ATTRIB + void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFromMax) { if (filter_useSoftMargin) { dataFilter_value = dataFilter_reduceValue( smoothstep(filter_min, filter_softMin, valueFromMin) * - (1.0 - smoothstep(filter_softMax, filter_max, valueFromMax)) + (1.0 - smoothstep(filter_softMax, filter_max, valueFromMax)) ); } else { dataFilter_value = dataFilter_reduceValue( step(filter_min, valueFromMin) * step(valueFromMax, filter_max) ); } + } +#endif +#ifdef DATACATEGORY_ATTRIB + void dataFilter_setCategoryValue(DATACATEGORY_TYPE category) { #if DATACATEGORY_CHANNELS == 1 // One 128-bit mask - int dataFilter_masks = filter_categoryBitMask[int(category / 32.0)]; + int dataFilter_masks = filter_categoryBitMask[int(category / 32.0)]; #elif DATACATEGORY_CHANNELS == 2 // Two 64-bit masks - ivec2 dataFilter_masks = ivec2( - filter_categoryBitMask[int(category.x / 32.0)], - filter_categoryBitMask[int(category.y / 32.0) + 2] - ); + ivec2 dataFilter_masks = ivec2( + filter_categoryBitMask[int(category.x / 32.0)], + filter_categoryBitMask[int(category.y / 32.0) + 2] + ); #elif DATACATEGORY_CHANNELS == 3 // Three 32-bit masks - ivec3 dataFilter_masks = filter_categoryBitMask.xyz; + ivec3 dataFilter_masks = filter_categoryBitMask.xyz; #else // Four 32-bit masks - ivec4 dataFilter_masks = filter_categoryBitMask; + ivec4 dataFilter_masks = filter_categoryBitMask; #endif // Shift mask and extract relevant bits @@ -79,14 +130,12 @@ void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFrom dataFilter_bits = mod(floor(dataFilter_bits), 2.0); #if DATACATEGORY_CHANNELS == 1 - if(dataFilter_bits == 0.0) dataFilter_value = 0.0; + if(dataFilter_bits == 0.0) dataFilter_value = 0.0; #else if(any(equal(dataFilter_bits, DATACATEGORY_TYPE(0.0)))) dataFilter_value = 0.0; #endif - } else { - dataFilter_value = 1.0; } -} +#endif `; const fs = glsl` @@ -163,15 +212,23 @@ function getUniforms64(opts?: DataFilterModuleSettings | {}): Record { t.is(uniforms.filter_softMax, 160, 'has correct uniforms'); t.is(uniforms.filter_useSoftMargin, false, 'has correct uniforms'); t.is(uniforms.filter_enabled, true, 'has correct uniforms'); + + const attributes = layer.getAttributeManager().getAttributes(); + t.deepEqual( + attributes.filterValues.value, + [120, 140, 0, 0, 0, 0], + 'filterValues attribute is populated' + ); + t.notOk(attributes.filterCategoryValues, 'filterCategoryValues attribute is not populated'); } }, { @@ -86,7 +94,7 @@ test('DataFilterExtension#categories', t => { { props: { data, - extensions: [new DataFilterExtension({categorySize: 2})], + extensions: [new DataFilterExtension({categorySize: 2, filterSize: 0})], getPosition: d => d.position, getFilterCategory: d => [d.field1, d.field2], filterCategories: [['a'], [8]] @@ -98,6 +106,14 @@ test('DataFilterExtension#categories', t => { [2 ** 0, 0, 2 ** 1, 0], 'has correct uniforms' ); + + const attributes = layer.getAttributeManager().getAttributes(); + t.deepEqual( + attributes.filterCategoryValues.value, + [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], + 'filterCategoryValues attribute is populated' + ); + t.notOk(attributes.filterValues, 'filterValues attribute is not populated'); } }, { diff --git a/test/render/golden-images/data-filter-effect-4-categories-filter-2d.png b/test/render/golden-images/data-filter-effect-4-categories-filter-2d.png new file mode 100644 index 00000000000..c1edcc4110a Binary files /dev/null and b/test/render/golden-images/data-filter-effect-4-categories-filter-2d.png differ diff --git a/test/render/golden-images/data-filter-effect-filter-1d.png b/test/render/golden-images/data-filter-effect-filter-1d.png new file mode 100644 index 00000000000..8b8d7435b18 Binary files /dev/null and b/test/render/golden-images/data-filter-effect-filter-1d.png differ diff --git a/test/render/golden-images/data-filter-effect-filter-2d.png b/test/render/golden-images/data-filter-effect-filter-2d.png new file mode 100644 index 00000000000..b0719a020ef Binary files /dev/null and b/test/render/golden-images/data-filter-effect-filter-2d.png differ diff --git a/test/render/test-cases/data-filter-extension.js b/test/render/test-cases/data-filter-extension.js index fd23709d649..6a0df8a84ed 100644 --- a/test/render/test-cases/data-filter-extension.js +++ b/test/render/test-cases/data-filter-extension.js @@ -16,6 +16,25 @@ for (let y = 0; y < 20; y++) { } export default [ + { + name: 'filter-1d', + props: { + extensions: [new DataFilterExtension({filterSize: 1})], + getFilterValue: d => d.column, + filterRange: [3, 8] + } + }, + { + name: 'filter-2d', + props: { + extensions: [new DataFilterExtension({filterSize: 2})], + getFilterValue: d => [d.column, d.row], + filterRange: [ + [3, 8], + [2, 5] + ] + } + }, { name: 'single-category', props: { @@ -27,7 +46,7 @@ export default [ { name: '2-categories', props: { - extensions: [new DataFilterExtension({categorySize: 2})], + extensions: [new DataFilterExtension({categorySize: 2, filterSize: 0})], getFilterCategory: d => [d.index % 128, d.row], filterCategories: [ [3, 4, 5, 15, 50], @@ -50,6 +69,19 @@ export default [ getFilterCategory: ({index}) => [index % 2, index % 3, index % 5, index % 7], filterCategories: [[0], [0], [0], [0]] } + }, + { + name: '4-categories-filter-2d', + props: { + extensions: [new DataFilterExtension({categorySize: 4, filterSize: 2})], + getFilterCategory: ({index}) => [index % 2, index % 3, index % 5, index % 7], + filterCategories: [[0], [0], [0], [0]], + getFilterValue: d => [d.column, d.row], + filterRange: [ + [2, 1000], + [0, 15] + ] + } } ].map(({name, props}) => ({ name: `data-filter-effect-${name}`, diff --git a/website/package.json b/website/package.json index df471e02db7..a779ed35c2e 100644 --- a/website/package.json +++ b/website/package.json @@ -15,10 +15,10 @@ }, "dependencies": { "@googlemaps/js-api-loader": "^1.16.0", - "@loaders.gl/i3s": "^4.1.4", - "@loaders.gl/las": "^4.1.4", - "@loaders.gl/obj": "^4.1.4", - "@loaders.gl/ply": "^4.1.4", + "@loaders.gl/i3s": "^4.2.0", + "@loaders.gl/las": "^4.2.0", + "@loaders.gl/obj": "^4.2.0", + "@loaders.gl/ply": "^4.2.0", "@material-ui/core": "^4.10.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.57",