Last week I mentioned the effort to update Dasher 360 to use v4.2 of the Forge viewer (the most recent version, at the time of writing, and a fairly big jump from our previously-used version, v3.2.1). Here’s how Dasher 360 is now looking after these various changes:
In this post I’m going to give more details of what specifically was involved in refreshing Dasher 360 to the latest Forge viewer, in the hope it’ll help people make decisions around their own use of the viewer and hopw/when they migrate their applications.
As we’ve developed Dasher 360, we’ve done our best to keep our code nicely modularised, even if the application is still tightly coupled with Forge. For instance, most of our features have been implemented as independent Forge viewer extensions that can be enabled or disabled depending on the needs of the project. There are inter-dependencies, of course, but we’ve done our best to keep these to a minimum. Architecturally-speaking, Dasher 360 implements the MVC design pattern. Which is all well and good, but as we have such tight coupling with the Forge viewer – which implements big chunks of our model, our viewer and our controller – it’s just a way of adding some manner of organisation to the problem at hand.
It’s our tight coupling with Forge that gives us the ability to create nicely integrated, performant features, but it’s also what gives us some occasional pain when we don’t keep up with platform changes. I think this resonates with any of you who have developed a deeply integrated product on a platform of any kind (whether desktop or cloud), so I don’t think this kind of occasional pain is news to anyone.
Frankly I was pleased my colleague Simon Beslav had taken the time to get us up to v3.2.1, while I was away: there was a breaking change relating to using Promises to load extensions that must have taken him some time to work through.
The DockingPanel has gained a solid footer at its bottom, which is actually a good thing, visually. It also highlighted a problem we had in our sensor list where we have a set of filter buttons that magically appear when you enable them – effectively moving the treeview containing all our sensors downwards. This always happened, but was more obviously visible with this new design. We just had to manipulate the height style to edit the calc(100% – n px) value.
Something that drove me completely mad for a half day (possibly more) was some new stying that was applied to the treeview in that panel. However had I might try, I couldn’t find a way to override the styling for the focused item: the standard highlighting gave it an alpha value of 0.4 or 0.6, wherease we needed something much less transparent, such as 0.9.
This had been set in the standard viewer stylesheet using the !important suffix, and I just couldn’t get it to override. I thought it related to stylesheet load order, so went down a rabbithole of forcing a separate stylesheet to load at the end. Nothing related to load order helped, in any way.
It turns out the way to force this was to get really specific. CSS precedence rules are tricky, and it turns out the specificity is a really good tool to use.
The standard CSS selector for that particular style was:
.adsk-viewing-viewer.dark-theme .treeview group>lmvheader:hover
More specificity wins, so I added a selector for our specific panel:
.adsk-viewing-viewer.dark-theme .SensorPanel .treeview group>lmvheader:hover
This worked irrespective of load order, etc.
Some more CSS-related fun was created by the introduction of the dark theme in the viewer. The .adsk-viewing-viewer.dark-theme selector now shows up all over the place (there’s .adsk-viewing-viewer.light-theme too, but we so far haven’t worried about supporting the light theme… first things first). We had to adjust a numberof our own custom selectors to deal with this appropriately. Again, just a result of tight integration.
Losing mouse events in vis.js
A really obscure migration issue related to our timeline implementation. This has some moveable items in it that define the currently-displayed time window – and the current “historical” time. With the new viewer these could no longer be moved, at all. After quite a bit of debugging, it turns out that vis.js uses the same component as the Forge viewer to handle mouse and pointer events: Hammer.js. Having a unified event managed component is a really good thing: the problem is that we have decided to disable a certain class of events for the Forge viewer. This was apparently meant to have been done just for IE11/Edge, but I saw the behaviour on Chrome, so go figure.
The real issue is that the Forge viewer has a custom cut of Hammer.js, and this modified version is set globally. Vis.js picks the changes up, too, as I’m sure many other components using Hammer.js would. This is a bad thing.
The hands-free scripted demo of Dasher 360 features – what we ‘ve called “kiosk mode” – basically fakes the movement of a cursor around the screen, pretending that it clicks on various UI elements. To make this trickery work, we need to copy a bunch of hover and focus effects across from the Forge viewer and create some classes that we can set on objects we’re fake-hovering over or fake-selecting. It works really nicely, but there’s quite a bit of work to maintain this implementation, especially when the viewer implements a whole set of different effects for highlighting hovered-over and selected elements. I do consider it worthwhile, though, as this is a killer feature for demos.
One gorgeous change we saw when upgrading to Forge viewer v4.2 relates to text quality. The CSS text-rendering property has been set to geometricPrecision throughout the viewer, which really improves the visual quality of Forge viewer apps. No doubt there’s a performance trade-off, here, but it seems likely the inflection point has arrived where browsers are able to do this without having a huge impact. In any case, to make sure our own UI elements didn’t “let the side down” by appearing old and clunky by comparison, we had to make sure that this property was set properly for our various UI elements.
It turns out this is an old problem, but one that needed addressing. We have an extension that allows you to overlay a logo on top of the Forge viewer. It took me some time to realise, but there was a problem with the Z-Index of the logo: it would appear above the viewer (great) but also above any UI panels that we being displayed on it (less great). Some might see this as a feature, rather than a bug, but to my eyes this was a clear bug. This led me to investigating the crazy world of stacking contexts. It turns out that we needed to force an element containing both the logo overlay and the viewer to create a stacking context (something you can do my setting its opacity to 0.999, for instance), at which point it’s possible for the two to have relative Z-Index values between their two sets of elements. I also had to unset the Z-Index property of the viewer itself, but hopefully that’s not going to cause any problems.
All of this works well, but I do still need to work out an issue with relative Z-Index values between the viewer and the timeline. Right now drop-downs with excessive numbers of items get hidden by the timeline. It’s rare, but it can happen. But that’s something I’m leaving for another day.
It took quite a lot of work to get Dasher 360 onto the latest & greatest Forge viewer. I will say, though, that it looks way better now. (You’ll get to try it, too, on Dasher360.com once it’s gone through a few more rounds of testing). Hopefully some of the time I took to make it happen will save others of you effort, should you hit similar problems.