Canvas shift on palette drop

The Floor Plan Editor example shows some behavior I am currently also observing in my own application. When dropping an item from a palette, the canvas shifts down and the menu bar disappears. How can I remove this?

In my own application, the problem is worse: I have created a panel on the left side of the window. When I drag something from the palette to the canvas on the right side, everything shifts left and the palette completely disappears. However, this happens only in Internet Explorer, but not in Chrome, Safari or Firefox, there the behavior is as expected.

Is this a bug or am I missing a setting?

Kind regards,

Joop

Could you tell us how to reproduce the problem? Perhaps in a CodePen or jsFiddle, if not in your own app?

I cannot reproduce it in any browser, including IE9, when running the Floor Plan Editor sample.

Hi Walter,

I simply opened the Floor Plan Editor in my browser and dragged a template from the palette and dropped it on the canvas. For clarity: the menu bar does not really disappear, but the window scrolls down so that the top of the canvas is on the top of the window.

I have attached a screen capture gif that demonstrates the problem in Internet Explorer 11.

The problem exists on Chrome 44, Safari 8, Internet Explorer 11, but not in Firefox 39 for some reason.

Regards Steven

This happens because dropping from one Diagram (or Palette) to another calls the DOM method .focus() on the target Diagram’s canvas. This method attempts to scroll the focused DOM element into view if it is not already 100% in view.

The Diagram is so large its partially off the page in that sample, so the call to .focus() scrolls as much of it into view as possible (makes the top flush with the top of the browser)

Calling .focus() on the DOM element is necessary because we want keyboard commands to work immediately on the target diagram after a drop. In the case of the floor plan sample, we could probably rewrite it so that the Diagram area is not so large (or scales with the page size) so that it does not require a scrollbar.

I fixed the “Floor Plan Editor” issue with:

var _top=0;
var _scroll=false;

$(document).on("focus", "div#myDiagram", function (event) {
	var doc = document.documentElement;
	_top = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);
	_scroll=true;
});

$(window).scroll(function(e) { //to avoid diagram scroll issue when editing nodes
	if(_scroll){
		window.scrollTo(0,_top);
		_scroll=false;
	}
});

myDiagram.addDiagramListener("ExternalObjectsDropped", function(e) {

	window.scrollTo(0,_top); //to avoid diagram focus error
});

Thanks for the improvements.

We’re also seeing this problem - the supplied fix didn’t help. Is there anyway to change this behavior? It basically causes the user to need to click once, then click again if they were trying to select something. It definitely only occurs when the canvas extends below the screen. Thoughts?

Giving focus to the HTML Canvas forcibly scrolls the page (this is a browser feature and not something we do) and the canvas cannot receive certain kinds of events (such as keyboard events) until it has focus.

Like I said above if you didn’t give it focus, your user wouldn’t be able to drop a node and then press Delete, or CTRL+C, or F2 to edit its text, etc.

It is possible to stop GoJS from giving focus to the canvas, but you have to be careful if that’s what you really want.

You can explicitly override Diagram.doFocus()

myDiagram.doFocus = function() {
  // sometimes, maybe when a flag is set, disallow focus
  if (/* some condition that you set */) return;

  // otherwise do the default focus behavior:
  go.Diagram.prototype.doFocus.call(this);
}

Hi Simon,
Can you give me one example on when to pass flag as true or false.

For 1.7 and after, try:

myDiagram.doFocus = function() {
  var x = window.scrollX || window.pageXOffset;
  var y = window.scrollY || window.pageYOffset;
  go.Diagram.prototype.doFocus.call(this);
  window.scrollTo(x, y);
}

This will let it focus, but stop the scrolling. It seems to work on Chrome, Firefox, IE11, and iOS Safari

Hi Simon,
Thanks for your reply. I am using 1.6.21 version.

  1. Instead of doFoucs I have used Diagram.focus() method. Is that ok?.
  2. Another question: As you posted in previous post " your user wouldn’t be able to drop a node and then press Delete…It is possible to stop GoJS from giving focus to the canvas, but you have to be careful if that’s what you really want." Is there any side effect of using this? I hope it’s not(because in the code we are not stopping focus of diagram). Just for clarification I am asking.

I don’t think that trying to override Diagram.focus will work reliably in 1.6.21. Alas, you cannot override Diagram.doFocus in 1.6.21 either.

In 1.7 all of the places in the library that try to get the diagram the focus will call Diagram.doFocus, which in turn will call Diagram.focus to actually get the focus. This will allow overriding Diagram.doFocus to change the behavior in some circumstances.

Actually I don’t find v1.6.21 typescript file(even in github) that’s why I am using myDiagram.Focus() method.
Can you send me the link for v1.6.21 or greater typescript file.

It’s in the same directory as the go.js library, named go.d.ts.

And it’s undocumented unexposed functionality in 1.6, so you won’t find it in the go.d.ts file there. Use the 1.7 library and TypeScript definition file, at http://gojs.net/beta.

I tried :

    this.diagram.doFocus = function() {
      const x = window.scrollX || window.pageXOffset;
      const y = window.scrollY || window.pageYOffset;
      go.Diagram.prototype.doFocus.call(this);
      window.scrollTo(x, y);
    };

or even just

    this.diagram.doFocus = function() {
      return;
    };

But the canvas would still scroll up and hide the toolbar when I dragged a node from the palette and drop the node onto the main canvas. More precisely, from the animated .gif you can see that the scrolling occured even before the node is dropped.

Any further suggestions?

More precisely, from the animated .gif you can see that the scrolling occured even before the node is dropped.

I believe what you are seeing @wleung is a function of the browser focusing a non-Diagram element, so adding that code won’t change anything. The browser always tries to focus as much of an HTML element as possible if it is partly off-screen, and the elements on the right seem to be moving it.