Page-like app - fake pages with a single diagram

This question concerns a page-style / paging app and how to fake pages in a single diagram using node visibility switching.


I am working on an app that lets the user work on a number of diagrams which can be thought of as pages in a virtual document. Only one page / diagram should be visible at any time, and there are UI controls to step through the pages.


My server side generates a model for all pages in one hit, so there is no server-side requirement to round-trip as the user navigates the pages.

It seems to me that there are 2 options to fake-up pages,

1 - instantiate a new diagram per page, loading the model for that page as the user switches to the page, unload when they switch away to the next / prev page;

or

2 - use a single diagram and somehow indicate which diagram parts / nodes are on what page number, then manipulate visibility of the diagram parts in line with the page number that is on display.

I prefer option 2 for performance and lower complexity reasons but I will be happy to receive advice on option 1.

Re option 2, if this were a pure HTML solution I could assign a dummy CSS class to the nodes, e.g. ‘pageNo_1’ for all nodes on P1, and use something like JQuery to switch visibility of all elements not on the current page number. Does gojs have something like this.

This is kind of the approach I had in mind but I don’t know how to set a piece of arbitrary data on the nodes to represent the page no.

function showPage( pageNo ) {
<span =“Apple-tab-span” style=“white-space:pre”> for (var it = myDiagram.nodes; it.next(); ) {
<span =“Apple-tab-span” style=“white-space:pre”> var n = it.value; // n is now a Node or a Group
<span =“Apple-tab-span” style=“white-space:pre”>
<span =“Apple-tab-span” style=“white-space:pre”> if (n.<pageno?> !== pageNo) {
<span =“Apple-tab-span” style=“white-space:pre”> n.visible = false
<span =“Apple-tab-span” style=“white-space:pre”> }<span =“Apple-tab-span” style=“white-space:pre”>
<span =“Apple-tab-span” style=“white-space:pre”> else {
<span =“Apple-tab-span” style=“white-space:pre”> n.visible = true
<span =“Apple-tab-span” style=“white-space:pre”> }<span =“Apple-tab-span” style=“white-space:pre”>
<span =“Apple-tab-span” style=“white-space:pre”> }
}

Or should I be using the a pageNo property on the model element that represents the node ?

[For future searchers: keywords page paging paged arbitrary variable visible visibility]

After thinking about this for a while, there were too many possible interpretations for what you could be trying to do, for me to give a single answer.

What is the spatial relationship between these pages? None, or should they be organized like the pages of a large two-dimensional document? If the latter, did you also want the option of showing more or all of the pages at once, just like a print preview? (By the way, http://gojs.net/latest/intro/printing.html.)

How many pages might there be, and how many parts might there be in total? Do you need/want to implement virtualization, to improve startup time?

Did you want users to be able to navigate through the pages by using the scrollbar(s) and paging commands? Should zooming be disabled (Diagram.allowZoom)?

Thanks. It’s tough in these forums to try to keep to the point so as to make the question too broad.

More description: If it helps, consider that the diagrams are each org charts of divisions within a corporation. Page 1 is NY, page 2 Boston, page 3 Seattle, etc.


It is not necessary for the pages to be viewed like a book. The app displays one-page at a time. The full org chart data for all pages is delivered via JSON when the app loads. The data includes the sequence of pages and the org chart data for each page. There are ‘previous’ and ‘next’ buttons to click. The app initially displays the diagram contents of page 1, and if the user clicks ‘next page’ then the page 1 diagram is replaced with the page 2 diagram. The app does not round-trip between pages. The buttons and other UI items are not an issue in regard to this question as we already have all that from previous dev - therefore provision of such buttons within the diagrams is out of scope.

I’m not sure about your question re visualisation, but overall I want start-up of the app to be fast and each transition from page to page to be optimised too.

My current solution is to include two properties in the model for each node, pageNo and curPageNo. The first is set to the page number that the node is on. The second is set via an iteration of all nodes when a page navigation button is clicked to go forward or backward in the pages. On the node templates I use the following data binding

new go.Binding(“visible”, “”, function(data) { if (data.pageNo === data.curPageNo) {return true} else {return false} })

which is a working solution. However it involves an iteration and call to setDataProperty() for every node which ‘feels’ more expensive than it should be.

Aother possibility is that in version 1.5 there is a not-yet-documented feature that would allow data binding to the shared Model.modelData object. The iteration still has to happen, but we do it internally.
Yet another possibility is to assign each node to a separate Layer, by setting or binding Part.layerName. Of course you would need to create all of the possible Layers first. Then you can just set Layer.visible as you please.

However I think it would be more natural to use separate Models for each page. Changing pages just means replacing the Diagram.model. This is basically an easy and effective way to implement virtualization too, so start-up time is quick.

Ah - thanks for the pointers - layers could work as I know the number of pages and could easily assign a layer per page.

But also the idea of a model per page and simply replacing models as the user navigates from page-to-page is possible to.

Great thinking and hopefully something to light the way for others in the future.

Another advantage of using separate models is that it might make automatic layout easier/simpler. But that might not be an issue for your app.

Hi - just an update for others who might find this thread.

Layers works well. For each page I create a layer and then as I create the nodes on the pages I set the layerName to the appropriate layer. All layers are set invisible, then I make the ‘current’ page visible and switch layer visibility across the pages as the user clicks the buttons to step through them.


The model-per-page suggestion could also have worked, I did not try it.


Thanks