How to redraw/visually update a node without triggering a complete redraw of the diagram

I have the following functions:

function refreshText(xhr, status, args) {
    updateNodeText(args.key, args.newText);
    save();
}

function updateNodeText(key, newText){
    var nodeData = myDiagram.findNodeForKey(key).data;
    console.log("Old text: " + nodeData.text);
    nodeData.text = newText;
    console.log("New text: " + nodeData.text);
}

Essentially this makes sure the text in the node is updated, and saves the diagram to the backend. However, it doesn’t redraw the text on the node itself visually even though the model is updated (confirmed through the logs).

I have a load function:

function load() {
    GetModel();
    setTimeout(layout, 1000);
}
function layout() {
    myDiagram.layoutDiagram(true);
}

If I call this the node will be redrawn due to the layout reorganizing itself. However, I want to make the text visually update without actually rearranging the layout. How could I accomplish this?

Footnote: Running GetModel(); alone just clears the diagram completely, I have to run layout() to make it visually appear again. The reason for the timeout is to make sure backing bean calls have finished before trying to redraw the layout.

My first reaction is that you should not be waiting some fixed time to assume that the server request had finished. You must organize your code to only execute when the data from the server has actually finished loading.

My second reaction is that you are not updating the model data correctly. You have to call Model.setDataProperty. (And in 1.8 there is now a synonym for that method, Model.set.)

You are absolutely correct, I’m aware of this. But it’s the only way I made it work. GetModel is a primefaces remotecommand that executes backing bean code. I have no idea how to tell the javascript to wait until it has finished processing.

I’ll be back with result of the setdataproperty in a minute.

Edit: Setdataproperty does indeed update it right away! Thanks!. This solves my problem. Feel free to elaborate if you have an idea of how to fix the other problem.

I know nothing about PrimeFaces, but a quick web search found:

Actually, this particular timeout was an artifact. An oncomplete there does indeed get rid of it, I’m not sure why I didn’t do that right away because I already have a function that runs on oncomplete there (that would be the refreshText-function above). The one I was thinking about is a timeout I have in my setup function:

function setup(index)
{
    if (index != 3)
    {
        return;
    }
    setTimeout(init, 2000);
}

The problem here is that it’s connected to a tabview. So this will run on all tab changes, but only start the initialization of the diagram if it goes to the correct tab (which contains the diagram) after 2 seconds. The problem is that if I do not implement this delay (i.e. just call init() after the if-statement), the diagram doesn’t draw itself. The canvas simply stays blank (no errors anywhere). By putting in a delay like this it works. I can’t be sure because there are no error messages, but I assume it has something to do with the elements not being displayed at the time due to being hidden by the tabview-element.

I also have an extremely rare bug, that fires maybe 1 out of 100 times, where I get a JS error claiming it can’t find myDiagramDiv (the id of the div element the diagram is drawn in) when I change to the diagram-tab. But because I’m unable to reproduce it I can’t really work on ironing it out.

Yes, after the user or page switches tabs to the tab that holds the diagram, the DIV probably changes size. But there is no HTML DOM notification of such a size change, so you have to call Diagram.requestUpdate yourself. Read more at: Resizing Diagrams -- Northwoods Software. See this sample: A GoJS Diagram in a jQuery UI Tab.

Sorry, it seems like I was doing something wrong earlier. When I run the init without a delay now I end up with the following error message (I have no idea why it changed from displaying a blank canvas to this, because I can’t recollect doing anything different now):

“Error: Invalid DIV id; could not get element with id: myDiagramDiv”.

So it does seem like the div itself doesn’t really exist until the new tab is loaded. So I cannot run the init method before it actually exists (because it tries to access the div to initialize the diagram), which the timeout deals with.

That’s plausible too – it depends on how your tabs are implemented in HTML/DOM/JavaScript.

In any case I think you want to do the initialization of the Diagram when the tab is opened. Presumably at that time the DIV will already have the correct size, so a call to requestUpdate will work, and may not do much if the DIV has not changed size since the last time that the tab was open.