Draw links on leaflet map without moving the map

Hello GoJS team,

I am currently working on a GoJS leaflet map in Angular and I am having a problem drawing new links between nodes because the map is moved every time I start to draw.

Therefore, I added some code to the leaflet map sample to add ports to the nodes and made them a little bigger (see code below).
I wanted to listen to an event like “drawBegin” and “drawEnd” to make the map not movable in the mean time, but I mainly found events that occur after a certain action.

Is there another way to achieve this?

Thanks in regard,
Jonas Czeslik

CODE:
ngOnInit(){

var defaultZoom = 6;
var mapOrigin: L.LatLngTuple = [50.02185841773444, 0.15380859375];
var myLeafletMap = L.map("map", {}).setView(mapOrigin, defaultZoom);
L.tileLayer("https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}", {
  attribution: '&copy; <a href="https://www.mapbox.com/about/maps/">Mapbox</a> &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
  maxZoom: 18,
  tileSize: 512,
  zoomOffset: -1,
  id: "mapbox/streets-v11",
  accessToken: "pk.eyJ1IjoiZ29qcyIsImEiOiJjaXppcnNkbDgwMzQ3MnFsNDFnY2phb2QwIn0.7AuVKrWdxQnJxa_W7qC3-w"
}).addTo(myLeafletMap);
myLeafletMap.on("moveend", function(e) {
  myUpdatingGoJS = true;
  myDiagram.updateAllTargetBindings("latlong"); // Without virtualization this can be slow if there are many nodes
  myDiagram.redraw(); // At the expense of performance, this will make sure GoJS positions are updated immediately
  myUpdatingGoJS = false;
});
var myUpdatingGoJS = false;  // prevent modifying data.latlong properties upon Leaflet "move" events

var myDiagram = $(go.Diagram, "myDiagramDiv",
  {
    "dragSelectingTool.isEnabled": false,
    "animationManager.isEnabled": false,
    scrollMode: go.Diagram.InfiniteScroll,
    allowZoom: false,
    allowHorizontalScroll: false,
    allowVerticalScroll: false,
    hasHorizontalScrollbar: false,
    hasVerticalScrollbar: false,
    initialPosition: new go.Point(0, 0),
    padding: 0,
    "toolManager.hoverDelay": 100  // how quickly tooltips are shown
  });

var toolTipTemplate =
  $("ToolTip",
    $(go.TextBlock, { margin: 4 },
      new go.Binding("text", "", function(d) {
        return d.key + "\nlocation: [" + d.latlong.join(", ") + "]"
      }))
  );
// the node template describes how each Node should be constructed
myDiagram.nodeTemplate = 
// myDiagram.nodeTemplate =
$(go.Node, "Auto",
  {
    toolTip: toolTipTemplate,
    locationSpot: go.Spot.Center
  },
  $(go.Shape, "Circle",
    {
      fill: "rgba(0, 255, 0, .4)",
      stroke: "#082D47",
      width: 40,
      height: 40,
      strokeWidth: 1,
      fromLinkable: true, fromLinkableSelfNode: true, fromLinkableDuplicates: true,
      toLinkable: true, toLinkableSelfNode: true, toLinkableDuplicates: true,
      portId: "",
      cursor: "pointer"
    }),
  new go.Binding("location", "latlong", function(data) {
    var point = myLeafletMap.latLngToContainerPoint(data);
    return new go.Point(point.x, point.y);
  }).makeTwoWay(function(pt, data) {
    if (myUpdatingGoJS) {
      return data.latlong;
    } else {
      var ll = (myLeafletMap.containerPointToLatLng([pt.x, pt.y]));
      return [ll.lat, ll.lng];
    }
  })
);
myDiagram.linkTemplate =
  $(go.Link,
    {
      layerName: "Background",
      curve: go.Link.Bezier,
      curviness: 2
    },
    $(go.Shape, { strokeWidth: 3, stroke: "rgba(100,100,255,.7)" })
  );
myDiagram.toolManager.draggingTool.doActivate = function() {
  myLeafletMap.dragging.disable();
  go.DraggingTool.prototype.doActivate.call(this);
}
myDiagram.toolManager.draggingTool.doDeactivate = function() {
  myLeafletMap.dragging.enable();
  go.DraggingTool.prototype.doDeactivate.call(this);
}
// create the model data that will be represented by Nodes and Links
myDiagram.model = new go.GraphLinksModel(
  [
    // France
    { key: "Paris", latlong: [48.876569, 2.359017] },
    { key: "Brest", latlong: [48.387778, -4.479921] },
    { key: "Rennes", latlong: [48.103375, -1.672809] },
    { key: "Le Mans", latlong: [47.995562, 0.192413] },
    { key: "Nantes", latlong: [47.217579, -1.541839] },
    { key: "Tours", latlong: [47.388502, 0.694500] },
    { key: "Le Havre", latlong: [49.492755, 0.125278] },
    { key: "Rouen", latlong: [49.449031, 1.094128] },
    { key: "Lille", latlong: [50.636379, 3.070620] },
    // Belgium
    { key: "Brussels", latlong: [50.836271, 4.333963] },
    { key: "Antwerp", latlong: [51.217495, 4.421204] },
    { key: "Liege", latlong: [50.624168, 5.566008] },
    // UK
    { key: "London", latlong: [51.531132, -0.125132] },
    { key: "Bristol", latlong: [51.449541, -2.581118] },
    { key: "Birmingham", latlong: [52.477405, -1.898494] },
    { key: "Liverpool", latlong: [53.408396, -2.978809] },
    { key: "Manchester", latlong: [53.476346, -2.229651] },
    { key: "Leeds", latlong: [53.795480, -1.548345] },
    { key: "Glasgow", latlong: [55.863287, -4.250989] },
  ],
  [
    { from: "Brest", to: "Rennes" },
    { from: "Rennes", to: "Le Mans" },
    { from: "Nantes", to: "Le Mans" },
    { from: "Le Mans", to: "Paris" },
    { from: "Tours", to: "Paris" },
    { from: "Le Havre", to: "Rouen" },
    { from: "Rouen", to: "Paris" },
    { from: "Lille", to: "Paris" },
    { from: "London", to: "Lille" },
    { from: "Lille", to: "Brussels" },
    { from: "Brussels", to: "Antwerp" },
    { from: "Brussels", to: "Liege" },
    { from: "Bristol", to: "London" },
    { from: "Birmingham", to: "London" },
    { from: "Leeds", to: "London" },
    { from: "Liverpool", to: "Birmingham" },
    { from: "Manchester", to: "Liverpool" },
    { from: "Manchester", to: "Leeds" },
    { from: "Glasgow", to: "Manchester" },
    { from: "Glasgow", to: "Leeds" }
  ]);
}

If you want to use the LinkingTool, you need to customize it so that when it activates it temporarily disables the Leaflet map. You can see how the DraggingTool does the same thing to allow users to move nodes.

Just add these lines:

    myDiagram.toolManager.linkingTool.doActivate = function() {
      myLeafletMap.dragging.disable();
      go.LinkingTool.prototype.doActivate.call(this);
    }

    myDiagram.toolManager.linkingTool.doDeactivate = function() {
      myLeafletMap.dragging.enable();
      go.LinkingTool.prototype.doDeactivate.call(this);
    }

Hello Walter,

thanks a lot, it works perfectly fine!

Best regards
Jonas Czeslik