From 95ede102ebab03b46ece818e1b5a49d059ffbbc9 Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Thu, 1 Sep 2022 13:09:36 +0300 Subject: [PATCH] chore(viewer/frontend): determinstic (not that great) colors for string prop filtering --- packages/viewer-sandbox/readme.md | 4 +- packages/viewer/package.json | 1 + packages/viewer/readme.md | 74 ++----------------- .../src/modules/filtering/FilteringManager.ts | 9 ++- yarn.lock | 57 ++++++++++++++ 5 files changed, 73 insertions(+), 72 deletions(-) diff --git a/packages/viewer-sandbox/readme.md b/packages/viewer-sandbox/readme.md index 0297de0dc..bc9f149b1 100644 --- a/packages/viewer-sandbox/readme.md +++ b/packages/viewer-sandbox/readme.md @@ -1,6 +1,6 @@ # @speckle/viewer-sandbox -Sandbox for testing, debugging & developing the viewer package +Sandbox for testing, debugging & developing the viewer package. ## Setup @@ -8,7 +8,7 @@ Sandbox for testing, debugging & developing the viewer package - Node ^16 -### Instructions +### Setup Instructions - `yarn` in the repo root to configure project dependencies - `yarn build` in repo root to build all dependencies diff --git a/packages/viewer/package.json b/packages/viewer/package.json index f0794e482..a30fb32da 100644 --- a/packages/viewer/package.json +++ b/packages/viewer/package.json @@ -47,6 +47,7 @@ "hold-event": "^0.1.0", "lodash-es": "^4.17.21", "rainbowvis.js": "^1.0.1", + "string-to-color": "^2.2.2", "three": "^0.140.0", "tree-model": "1.0.7" }, diff --git a/packages/viewer/readme.md b/packages/viewer/readme.md index 204789c74..625c9bd83 100644 --- a/packages/viewer/readme.md +++ b/packages/viewer/readme.md @@ -6,79 +6,17 @@ We're working to stabilize the 2.0 API, and until then there will be breaking changes. -## Documentation +## Development -Comprehensive developer and user documentation can be found in our: +You can debug and test the viewer is through the `viewer-sandbox` package. Some simple steps to get going: -📚 [Speckle Docs website](https://speckle.guide/dev/) - -## Getting started - -Working with viewer (for more, check `./src/example.js`): - -```js -import { Viewer } from '@speckle/viewer' - -const v = new Viewer({ - container: document.getElementById('renderer'), - showStats: true -}) -``` - -### Development - -For testing purposes you can see viewer in action by running `yarn example`, which will run an example server at 'http://127.0.0.1:3002'. - -To build the library run `yarn build`, to build a dev (unminified w/ sourcemaps) build run `yarn build:dev` and to run a dev build in watch mode run `yarn dev`. +- run `yarn` in the repo root to install and link all required dependencies. +- run `yarn dev` in the viewer package (here) to start a dev build with automatic code refresing of the viewer code. +- run `yarn dev` in the viewer-sandbox package to start the viewer sandbox. ## API -Syntax and examples for supported API methods. The examples assume a `Viewer` instance named `v`. - -### Load/Unload an object - -`v.loadObject( objectUrl )` / `v.unloadObject( objectUrl )` - -Example: `v.loadObject( 'https://speckle.xyz/streams/3073b96e86/objects/e05c5834368931c9d9a4e2087b4da670' )` - -### Get properties of loaded objects - -`v.getObjectsProperties()` - -This returns a dictionary with `{ propertyName: propertyInfo }` elements. The property information provided is: - -- `type` ( == `'string'` / `'number'` / `'boolean'`): the property type -- `objectCount` (int): How many objects in the scene have this property -- `allValues` (array of `objectCount` elements): The values for this property of all objects that have this property -- `minValue` - the smallest value (using `<` operator, works also on strings) -- `maxValue` - the largest value -- `uniqueValues` - a dictionary of `{ uniqueValue: occurenceCount }` elements, secifying how many objects have the property set to that specific value - -### Filtering and coloring - -Those calls filter and color the objects loaded in the scene, and drops the previous applied filters (filtering is not additive). - -Syntax: `await v.applyFilter( { filterBy, colorBy, ghostOthers } )` - -The 3 optional parameters are: - -- `filterBy`: A dictionary that specify the filter. Elements are in the form `{ propertyName: propertyValueFilter }`. The propertyValueFilter can be one of: - - - A specific value: (only objects with that property value pass the filter) - - An array of values: An object passes the filter if its value is in the array - - A range of values, specified by `{ 'gte': value1, 'lte': value2 }` (greater than or equal, lower than or equal) - - An exclusion list, specified by `{ 'not': excludedValuesArray }` - -- `colorBy`: A dictionary that makes all objects colored based on a property value. Two types of coloring are supported: - - - Gradient (from a numeric property): `{ 'type': 'gradient', 'property': propertyName, 'minValue': propertyMinValue, 'maxValue': propertyMaxValue, 'gradientColors': [color1, color2], default: colorForObjectsWithMissingProperty }` - - Category (for coloring each unique value differently): `{ 'type': 'category', 'property': propertyName, 'values': { value1: color1, value2: color2, ... }, 'default': colorForAnyOtherValue }`. The `values` and the `default` parameters are optional: Random colors are generated if they are omitted. - -- `ghostOthers`: A boolean (default `false`). If set to `true`, then the objects that are filtered out are actually shown with very low opacity, so that the remaining objects have a better context. - -For `colorBy`, setting a color to `null` will use the original material instead of coloring it. - -To remove all filters: `await v.applyFilter( null )` +The Viewer's API is [documented here](https://speckle.notion.site/Viewer-API-Documentation-11f7bcbf3d2547c2985b0c988fb9889e). ## Community diff --git a/packages/viewer/src/modules/filtering/FilteringManager.ts b/packages/viewer/src/modules/filtering/FilteringManager.ts index 263978d91..e54b17710 100644 --- a/packages/viewer/src/modules/filtering/FilteringManager.ts +++ b/packages/viewer/src/modules/filtering/FilteringManager.ts @@ -1,4 +1,5 @@ -import { Color, Texture, MathUtils } from 'three' +import { Color, Texture } from 'three' +import stc from 'string-to-color' import { Assets } from '../Assets' import { TreeNode, WorldTree } from '../tree/WorldTree' import { NodeRenderView } from '../tree/NodeRenderView' @@ -231,14 +232,18 @@ export class FilteringManager { return this.setFilters() } + // private hashCode = (str): number => + // str.split('').reduce((s, c) => (Math.imul(31, s) + c.charCodeAt(0)) | 0, 0) + private setStringColorFilter(stringProp: StringPropertyInfo) { this.ColorStringFilterState.currentProp = stringProp const valueGroupColors: ValueGroupColorItemStringProps[] = [] for (const vg of stringProp.valueGroups) { + const col = stc(vg.value) // TODO: smarter way needed. valueGroupColors.push({ ...vg, - color: new Color(MathUtils.randInt(0, 0xffffff)), + color: new Color(col), rvs: [] }) } diff --git a/yarn.lock b/yarn.lock index 78e78dc86..ad0f030b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5597,6 +5597,7 @@ __metadata: rollup-plugin-rebase: ^4.1.1 rollup-plugin-terser: ^7.0.2 rollup-plugin-typescript2: ^0.31.2 + string-to-color: ^2.2.2 three: ^0.140.0 tree-model: 1.0.7 typescript: ^4.5.4 @@ -11220,6 +11221,13 @@ __metadata: languageName: node linkType: hard +"colornames@npm:^1.1.1": + version: 1.1.1 + resolution: "colornames@npm:1.1.1" + checksum: a97df66bde2a0efb592870f790bae2ffcbf2f9e30c0064783a2941be6713f0ac2acfa3bf1baf70bb423d99526f4fc761bf311fac94aa18ed642d77932352f864 + languageName: node + linkType: hard + "colors@npm:^1.1.2": version: 1.4.0 resolution: "colors@npm:1.4.0" @@ -16402,6 +16410,13 @@ __metadata: languageName: node linkType: hard +"hex-rgb@npm:^4.1.0": + version: 4.3.0 + resolution: "hex-rgb@npm:4.3.0" + checksum: e654648db8647446f0111c68690d9b340eb192a93c8b2c6789a2b8deb5c20e757515ae209c5ae67074acfddf8575f9fc645d4ffaa0596d859457b08e180d791d + languageName: node + linkType: hard + "highlight.js@npm:^10.7.1": version: 10.7.3 resolution: "highlight.js@npm:10.7.3" @@ -19299,6 +19314,13 @@ __metadata: languageName: node linkType: hard +"lodash.padend@npm:^4.6.1": + version: 4.6.1 + resolution: "lodash.padend@npm:4.6.1" + checksum: c2e6e789debf83b98f5c085305cdcfff1067e7a31bda2a110fd765d3c11a99edfbeef570d9ef737ab3212006bdb8114e77622e518c18c1fce52b8fdfd9dab685 + languageName: node + linkType: hard + "lodash.sortby@npm:^4.7.0": version: 4.7.0 resolution: "lodash.sortby@npm:4.7.0" @@ -19320,6 +19342,13 @@ __metadata: languageName: node linkType: hard +"lodash.trimstart@npm:^4.5.1": + version: 4.5.1 + resolution: "lodash.trimstart@npm:4.5.1" + checksum: 4b2d37505ac15f501f4f2378928455a40e858fa56c924494dbc21d5d828c55e821cda8543f25fe265e3d552937e915264a2567ba9291a172262c24c33e9ad6b0 + languageName: node + linkType: hard + "lodash.truncate@npm:^4.4.2": version: 4.4.2 resolution: "lodash.truncate@npm:4.4.2" @@ -19334,6 +19363,13 @@ __metadata: languageName: node linkType: hard +"lodash.words@npm:^4.2.0": + version: 4.2.0 + resolution: "lodash.words@npm:4.2.0" + checksum: 287d617ffa3fb453b6925620f04fa195c801590833fd9336c7e80c36ce105d06613ad0455ad368738fb40b36fd5f635b85f837fc7f584b73e03365482acd6e7a + languageName: node + linkType: hard + "lodash@npm:4, lodash@npm:^4.11.2, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.12, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.3, lodash@npm:~4.17.0": version: 4.17.21 resolution: "lodash@npm:4.17.21" @@ -24159,6 +24195,13 @@ __metadata: languageName: node linkType: hard +"rgb-hex@npm:^3.0.0": + version: 3.0.0 + resolution: "rgb-hex@npm:3.0.0" + checksum: 45959f777c9a078230cd20cdef2db159856ab74c1115ec6cb096801fdf223f533439d26555f2b39f2d9e1547f25588c6a3462dc19630a71dc090204b0d9e9d9f + languageName: node + linkType: hard + "rgb-regex@npm:^1.0.1": version: 1.0.1 resolution: "rgb-regex@npm:1.0.1" @@ -25661,6 +25704,20 @@ __metadata: languageName: node linkType: hard +"string-to-color@npm:^2.2.2": + version: 2.2.2 + resolution: "string-to-color@npm:2.2.2" + dependencies: + colornames: ^1.1.1 + hex-rgb: ^4.1.0 + lodash.padend: ^4.6.1 + lodash.trimstart: ^4.5.1 + lodash.words: ^4.2.0 + rgb-hex: ^3.0.0 + checksum: 9ffe859f387f5a2da30794ea4399d43b2f701acc2c0429f9aed9cce52f873f9ec40ad6b64eb5e5f030d602e38dca9a4b8f39f41c33d287b4b9d2043e4a513508 + languageName: node + linkType: hard + "string-width@npm:^1.0.1": version: 1.0.2 resolution: "string-width@npm:1.0.2"