I’ve been working with some highly interactive user interfaces lately and wanted to build them in a reactive style rather than the imperative way I have created such applications in the past. I found that Angular combined with NGRX (Angular’s redux pattern) makes this type of architecture a breeze. It is extremely scalable and performant because once you get the desired content in the store, you can references it in various parts of the UI with very little effort. Having the ‘Single Source of Truth‘ allows you to ditch all of the manually “update-then-retrieve-and-display” coding you would normally have to handle.
One thing that was a bit counter-intuitive was making the UI render based upon the contents of the NGRX store rather than using the traditional imperative instructions. In the case of an interactive diagram, when the user moves something on the screen, instead of updating the DOM elements in the UI, we instead update the NGRX store, which in turn applies the updates to the elements on the screen to reflect the current state.
The benefits of this are tremendous. First, you get massive scalability with a redux-style application. For example, if you have a detail section on the screen, the ‘title’ field will always show the same value as the shape that is selected in the diagram since that value is coming from a single place in the store.
You also get the ability to add application-wide features lie undo/redo with very little effort. For this demo, I have implemented a simple “undo move” function that simply rolls back the initial move action. However, there exists several NGRX undo/redo libraries that can be added to an application to extend that capability beyond just a single action.
Below you can see a demo of what I am describing. At first glance, it looks fairly simple and generic. You move a shape and drag it around. You also see the current details in the form on the right. No big deal right? However, if you take a look at the code, you will find that there is more going on here. The mouse listeners essentially determine what the new x/y position of the selected shape that is being dragged will be and then an NGRX action is created and dispatched. This action updates those values in the NGRX store. The store determines what is displayed on the screen at any given time. Thus, updating the store will in turn update the shape’s position on the screen. It feels like you are moving the shape, but in reality you are just updating the NGRX store.
This diagram show the sequence of what is occurring:
So why is this interesting? Well, first it opens up a whole lot of possibilities when it comes to your designs. You can see that the shape information form on the right is always in sync with the currently selected shape. That type of updating and syncing takes minimal effort once the information is in the store. It is nothing to add another diagram that mirrors the first. You can see below (and in the code) that I have added a read only diagram that always reflects what you see in the main diagram. Both diagrams reflect the store so both diagrams are always in sync:
For those who are well versed in reactive programming, this is nothing new. I just wanted to share this technique for those who are interested in ways of using reactive design to handle intensive interaction with a graph, visualization, or editor-style UI. 🙂