-
Notifications
You must be signed in to change notification settings - Fork 23
docs: allow classes and async/await in live examples #1543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
e875e37
docs(Cognite3dModel): fix incorrect jsdoc links
maksnester 1ab1472
docs: allow classes and async/await in live examples
maksnester 84ac8c9
Merge branch 'master' into mn/docs-better-react-live
maksnester d8a3f6c
Merge branch 'master' into mn/docs-better-react-live
maksnester 504a739
Merge refs/heads/master into mn/docs-better-react-live
cognite-bulldozer[bot] 36a51df
Merge refs/heads/master into mn/docs-better-react-live
cognite-bulldozer[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,150 +1,155 @@ | ||
| --- | ||
| id: cad-save-viewerstate | ||
| title: Saving viewer state | ||
| description: Demo shows how to save viewerstate of 3d models from CDF with Cognite3DViewer. | ||
| --- | ||
| import { DemoWrapper } from '@site/docs/components/DemoWrapper'; | ||
|
|
||
| Reveal supports saving the camera state and styled filters that have been applied to the loaded model(s). | ||
| This functionality can help support sharing links and local storage of a given view. | ||
| Internally the input to a given filter is stored and is replayed when restoring the view. | ||
| This usually means that substantially less data needs to be serialized in order to share the given state of the viewer. | ||
| The serialized JSON blob also keeps information about styling/filtering of the model by storing all [styled sets](./cad-styling.mdx). | ||
|
|
||
| <DemoWrapper name="Cognite3DViewerDemo" /> | ||
|
|
||
| ## Getting the viewer state | ||
| In the example below we apply some filter to our loaded model using the `NodeCollectionBase` type from [Styling Cad models](./cad-styling.mdx). | ||
| Then we can call the ```viewer.getViewState()``` function which return a serialized JSON blob containing the view state. | ||
| Depending on the application, the view state can be additionally transformed into e.g. a URL parameter and transferred through a link. | ||
|
|
||
| In the example below, we keep simply print it to the developer console. | ||
|
|
||
| ```js runnable | ||
| const allPipes = new PropertyFilterNodeCollection(sdk, model); | ||
| allPipes.executeFilter({'PDMS': {'Type': 'PIPE'}}); | ||
| model.setDefaultNodeAppearance(DefaultNodeAppearance.Ghosted); | ||
| model.assignStyledNodeCollection(allPipes, { renderGhosted: false, color: [40, 200, 20] } ); | ||
|
|
||
| console.log(JSON.stringify(viewer.getViewState(), null, 2)); | ||
| ``` | ||
|
|
||
| ## Setting the viewer state | ||
| Restoring the viewer state is simply a matter of feeding back the JSON blob retrieved from ```const myState = viewer.getViewState()``` into ```viewer.setViewState(myState)```. | ||
| In the example below, a previously stored state is applied which applies a red color to nodes that have an attribute `'PDMS.Type'`. | ||
|
|
||
| :::note | ||
| Setting the viewer state assumes that model has already been loaded. | ||
| An error will be thrown if a given state is loaded for a model which does not exist. | ||
| ::: | ||
|
|
||
| ```js runnable | ||
|
|
||
| const myState = { | ||
| "camera": { | ||
| "position": { | ||
| "x": 165.603, | ||
| "y": 41.649, | ||
| "z": -10.940 | ||
| }, | ||
| "target": { | ||
| "x": 130.537, | ||
| "y": 49.138, | ||
| "z": -119.095 | ||
| } | ||
| }, | ||
| "models": [ | ||
| { | ||
| "defaultNodeAppearance": { | ||
| "renderGhosted": true | ||
| }, | ||
| "modelId": 3356984403684032, | ||
| "revisionId": 6664823881595566, | ||
| "styledSets": [ | ||
| { | ||
| "token": "PropertyFilterNodeCollection", | ||
| "state": { | ||
| "PDMS": { | ||
| "Type": "PIPE" | ||
| } | ||
| }, | ||
| "options": { | ||
| "requestPartitions": 1 | ||
| }, | ||
| "appearance": { | ||
| "renderGhosted": false, | ||
| "color": [ | ||
| 200, | ||
| 40, | ||
| 20 | ||
| ] | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
|
|
||
| viewer.setViewState(myState); | ||
| ``` | ||
|
|
||
| ## Serializing and deserializing custom node colletions | ||
| When working with styled custom node collections, the Reveal viewer needs to know how to serialize and deserialize the set. | ||
| Serialization is handled through the abstract method `serialize` which needs to be implemented when extending `NodeCollectionBase`. | ||
| The output of `serialize` is of type `SerializedNodeCollection` and contains a `token` which is used to recreate | ||
| the `NodeCollectionBase` during deserialization, and a `state` object which contains the data needed to restore | ||
| the `NodeCollectionBase`. It is up to the application developer to fill this state object with any nessesary | ||
| data needed to recreate the state of the `NodeCollectionBase`. An optional `options` object can also be supplied | ||
| containing any metadata for loading data (e.g. the number of API calls to fetch the needed data in parallel). | ||
| The contents returned from `serialize` is contained in the result of `getViewState`. | ||
|
|
||
| In addition to serialization, Reveal also needs to know how to recreate the custom `NodeCollectionBase` during | ||
| deserialization. This is done by calling the free-function `registerCustomNodeCollectionType` with the same `token` | ||
| defined by the custom `NodeCollectionBase` and a lambda function which instantiates and restore the state of | ||
| the `NodeCollectionBase`. The lambda function has two parameters: the `descriptor` containing the state and | ||
| options which should be applied to the `NodeCollectionBase` and the context containing an instance of | ||
| the [CogniteClient from the Cognite SDK](https://docs.cognite.com/dev/guides/sdk/js/) and the `Cognite3DModel` | ||
| which the `NodeCollectionBase` was originally applied to. It is up to the application developer how and if they | ||
| want to use the context and/or descriptor, but it is provided as a convinience. | ||
|
|
||
| An example of a simple custom `NodeCollectionBase` can be seen below. | ||
| For more information on creating a custom `NodeCollectionBase`, see [create custom node collections](cad-styling-custom). | ||
| ```jsx | ||
| // MyNodeCollection.ts | ||
|
|
||
| import { NodeCollectionBase, registerCustomNodeCollectionType } from '@cognite/reveal'; | ||
|
|
||
| class MyNodeCollection extends NodeCollectionBase { | ||
|
|
||
| isLoading = false; | ||
| private _indexSet: IndexSet; | ||
|
|
||
| constructor(model: Cognite3DModel) { | ||
| // token used for serialization / deserialization | ||
| super('MyNodeCollection'); | ||
|
|
||
| this._indexSet = new IndexSet(); | ||
| for (let i = 0; i < model.nodeCount / 2; i++) { | ||
| this._indexSet.add(i); | ||
| } | ||
| } | ||
|
|
||
| getIndexSet() { | ||
| return this._indexSet; | ||
| } | ||
|
|
||
| serialize(): SerializedNodeCollection { | ||
| return { token: this.classToken, state: this._indexSet.toRangeArray()} | ||
| } | ||
|
|
||
| clear() { | ||
| this._indexSet.clear(); | ||
| this.notifyChanged(); | ||
| } | ||
| }; | ||
|
|
||
| // Register deserializer for type | ||
| registerCustomNodeCollectionType<MyNodeCollection>('MyNodeCollection', (descriptor, context) => { | ||
| return Promise.resolve(new MyNodeCollection(context.model)); | ||
| }); | ||
| ``` | ||
| --- | ||
| id: cad-save-viewerstate | ||
| title: Saving viewer state | ||
| description: Demo shows how to save viewerstate of 3d models from CDF with Cognite3DViewer. | ||
| --- | ||
| import { DemoWrapper } from '@site/docs/components/DemoWrapper'; | ||
|
|
||
| Reveal supports saving the camera state and styled filters that have been applied to the loaded model(s). | ||
| This functionality can help support sharing links and local storage of a given view. | ||
| Internally the input to a given filter is stored and is replayed when restoring the view. | ||
| This usually means that substantially less data needs to be serialized in order to share the given state of the viewer. | ||
| The serialized JSON blob also keeps information about styling/filtering of the model by storing all [styled sets](./cad-styling.mdx). | ||
|
|
||
| <DemoWrapper name="Cognite3DViewerDemo" /> | ||
|
|
||
| ## Getting the viewer state | ||
| In the example below we apply some filter to our loaded model using the `NodeCollectionBase` type from [Styling Cad models](./cad-styling.mdx). | ||
| Then we can call the ```viewer.getViewState()``` function which return a serialized JSON blob containing the view state. | ||
| Depending on the application, the view state can be additionally transformed into e.g. a URL parameter and transferred through a link. | ||
|
|
||
| In the example below, we keep simply print it to the developer console. | ||
|
|
||
| ```js runnable | ||
| const allPipes = new PropertyFilterNodeCollection(sdk, model); | ||
| allPipes.executeFilter({'PDMS': {'Type': 'PIPE'}}); | ||
| model.setDefaultNodeAppearance(DefaultNodeAppearance.Ghosted); | ||
| model.assignStyledNodeCollection(allPipes, { renderGhosted: false, color: [40, 200, 20] } ); | ||
|
|
||
| console.log(JSON.stringify(viewer.getViewState(), null, 2)); | ||
| ``` | ||
|
|
||
| ## Setting the viewer state | ||
| Restoring the viewer state is simply a matter of feeding back the JSON blob retrieved from ```const myState = viewer.getViewState()``` into ```viewer.setViewState(myState)```. | ||
| In the example below, a previously stored state is applied which applies a red color to nodes that have an attribute `'PDMS.Type'`. | ||
|
|
||
| :::note | ||
| Setting the viewer state assumes that model has already been loaded. | ||
| An error will be thrown if a given state is loaded for a model which does not exist. | ||
| ::: | ||
|
|
||
| ```js runnable | ||
|
|
||
| const myState = { | ||
| "camera": { | ||
| "position": { | ||
| "x": 165.603, | ||
| "y": 41.649, | ||
| "z": -10.940 | ||
| }, | ||
| "target": { | ||
| "x": 130.537, | ||
| "y": 49.138, | ||
| "z": -119.095 | ||
| } | ||
| }, | ||
| "models": [ | ||
| { | ||
| "defaultNodeAppearance": { | ||
| "renderGhosted": true | ||
| }, | ||
| "modelId": 3356984403684032, | ||
| "revisionId": 6664823881595566, | ||
| "styledSets": [ | ||
| { | ||
| "token": "PropertyFilterNodeCollection", | ||
| "state": { | ||
| "PDMS": { | ||
| "Type": "PIPE" | ||
| } | ||
| }, | ||
| "options": { | ||
| "requestPartitions": 1 | ||
| }, | ||
| "appearance": { | ||
| "renderGhosted": false, | ||
| "color": [ | ||
| 200, | ||
| 40, | ||
| 20 | ||
| ] | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
|
|
||
| viewer.setViewState(myState); | ||
| ``` | ||
|
|
||
| ## Serializing and deserializing custom node collections | ||
|
|
||
| When working with styled custom node collections, the Reveal viewer needs to know how to serialize and deserialize the set. | ||
| Serialization is handled through the abstract method `serialize` which needs to be implemented when extending `NodeCollectionBase`. | ||
| The output of `serialize` is of type `SerializedNodeCollection` and contains a `token` which is used to recreate | ||
| the `NodeCollectionBase` during deserialization, and a `state` object which contains the data needed to restore | ||
| the `NodeCollectionBase`. It is up to the application developer to fill this state object with any nessesary | ||
| data needed to recreate the state of the `NodeCollectionBase`. An optional `options` object can also be supplied | ||
| containing any metadata for loading data (e.g. the number of API calls to fetch the needed data in parallel). | ||
| The contents returned from `serialize` is contained in the result of `getViewState`. | ||
|
|
||
| In addition to serialization, Reveal also needs to know how to recreate the custom `NodeCollectionBase` during | ||
| deserialization. This is done by calling the free-function `registerCustomNodeCollectionType` with the same `token` | ||
| defined by the custom `NodeCollectionBase` and a lambda function which instantiates and restore the state of | ||
| the `NodeCollectionBase`. The lambda function has two parameters: the `descriptor` containing the state and | ||
| options which should be applied to the `NodeCollectionBase` and the context containing an instance of | ||
| the [CogniteClient from the Cognite SDK](https://docs.cognite.com/dev/guides/sdk/js/) and the `Cognite3DModel` | ||
| which the `NodeCollectionBase` was originally applied to. It is up to the application developer how and if they | ||
| want to use the context and/or descriptor, but it is provided as a convinience. | ||
|
|
||
| An example of a simple custom `NodeCollectionBase` can be seen below. | ||
| For more information on creating a custom `NodeCollectionBase`, see [create custom node collections](cad-styling-custom). | ||
|
|
||
| ```js | ||
| // import { IndexSet, NodeCollectionBase, registerCustomNodeCollectionType } from '@cognite/reveal'; | ||
|
|
||
| class MyNodeCollection extends NodeCollectionBase { | ||
|
|
||
| isLoading = false; | ||
| _indexSet = new IndexSet(); | ||
|
|
||
| constructor(model) { | ||
| // token used for serialization / deserialization | ||
| super('MyNodeCollection'); | ||
|
|
||
| for (let i = 0; i < model.nodeCount / 2; i++) { | ||
| this._indexSet.add(i); | ||
| } | ||
| } | ||
|
|
||
| getIndexSet() { | ||
| return this._indexSet; | ||
| } | ||
|
|
||
| serialize() { | ||
| return { | ||
| token: this.classToken, | ||
| state: this._indexSet.toRangeArray() | ||
| } | ||
| } | ||
|
|
||
| clear() { | ||
| this._indexSet.clear(); | ||
| this.notifyChanged(); | ||
| } | ||
| } | ||
|
|
||
| // Register deserializer for type | ||
| registerCustomNodeCollectionType( | ||
| 'MyNodeCollection', | ||
| (descriptor, context) => { | ||
| return Promise.resolve(new MyNodeCollection(context.model)); | ||
| } | ||
| ); | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dafuc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah. It's the branch ofc. Nice!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@larsmoa Fair question. You can specify github
repo#branchinstead of the version number. In that case, during installation the packagenode_modules/react-livewill be downloaded from github repo instead of NPM. That's a temporary hack until PR will be merged. I didn't want to create a fork of react-live under org and maintain it and publish it under new name. I just want my patch to work.Once my referenced PR to react-live will be merged I'll update it here with new patched react-live version.