iModel.js meets CSV (Part 3/3)
In the previous two posts, we read a list of gaskets from a CSV file and got their positions from our iModel.
Now we will use this information to highlight these components on the viewport. I can think of a few ways to do that:
- Select elements.
- Change element colors.
- Use markers.
I personally like the idea of markers in this case since these components are tiny and markers retain their size when you zoom in/out of the view. For example:
That is the closest Taco Bell to me right now.
Man, I shouldn't have used that example. Now I want some tacos.
When I looked up the marker documentation, it was dense! Here’s an abstract (feel free to zone out):
Markers in iModel.js are canvas decorations drawn on the 2D canvas on top of the ScreenViewport. They can be added by using a decorator class. A decorator class implements the decorate method that adds these decorations to a supplied viewport context.
If that was a lot, I am about to break it down.
Let’s get silly.
We will pretend our viewport is a Christmas tree. We have a bunch of decorations we want to put on it. Each decoration needs to be individually added onto the tree. And we have a person designated in the family who does all the work, let’s call them the decorator and they know how to decorate ie. perform the action of putting each decoration on our tree.
These are the three things we are looking for: decoration, decorator, and decorate.
First, we will define our decoration, ie. what we are putting on our Viewport. In this case, we are adding markers. What should they look like? Let’s search for an image…
I found this map pin in the iModel.js repository. It should do well. Let’s copy that over to our public folder so we can pull it directly from our code.
Now let’s define our marker. We’ll call it the GasketMarker and derive it from the Marker class. Let’s set it up to use the map_pin.svg image above. That will give us our decoration.
Next, let’s create our decorator class which will be responsible for putting our decorations on the viewport. It will take in the info we obtained from the previous sections and use it to create our GasketMarkers. It needs to hold onto this list of _markers to use later when we decorate.
Now we have a decorator and we have gathered all our decorations. The last thing we need to do is to decorate. Let’s go ahead and add the decorator interface on this class and implement our decorate method (line 19):
Within this method, as discussed, we simply add each individual decoration to the viewport. In this case, we do that by calling the addDecoration method on the marker and passing in our viewport’s DecorateContext.
All we need to do now is to instantiate our GasketDecorator by passing in the info (from the previous post). And then we add it to the viewManager which will take care of making the actual decorate call.
We are ready to build and run. Let’s see what we get:
Nice! We have some markers going.
We can now start customizing them to display the component status. One way to do that would be to color code them. Let’s look back at our different status types:
We have YES/NO/OPEN ENDED. It would make sense to color them as follows:
- “YES” = green.
- “NO” = red.
- “OPEN ENDED” = yellow.
We already have that red marker SVG. We can just pop that open, change the fill color and save new copies for green and yellow.
I’ll add these files to our public folder. Now when we instantiate the GasketMarker, we simply need to pass in the status and select the appropriate image. Let’s go ahead and do that:
Of course, we’ll update the place where this marker is being instantiated to pass in the status in addition to the component position. And that is all we should need. Let’s go ahead and build and launch:
Hallelujah! We have our demo. Along the way, we learned how to write a custom RPC interface, compose ECSql queries, use the console app and add markers.
In other words, we took our iModel and another data source (CSV) and linked them together using iModel.js to enhance the value of a digital twin. We made an immersive connection!
Thank you to everyone who stuck with me till the end.
Alright, time for some tacos.
-Roop, leaving the basement.