Search code examples
javascriptjointjs

JointJS Manhattan Router not counting labels as obstacles. How to route link without overlapping labels?


My application automatically routes some connection lines using jointjs's manhattan router. The issue I'm having is:

  • the connection lines are routed too close to other line's labels (Manhattan router is not considering labels from other lines as obstacles)
  • sometimes the connection lines do not go down far enough for my text labels

The file I believe I need to edit is:

https://github.com/clientIO/joint/blob/master/plugins/routers/joint.routers.manhattan.js

Please see these images to get a better idea of what I'm talking about:

Before Manhattan Routing:

before Manhattan routing

After Manhattan Routing:

after Manhattan routing

What my goal is:

goal Manhattan routing

I've tried using the other routers, but they were much worse for my specific application.

My configuration is as follows:

        link.set('router', {
            name: 'manhattan',
            args: {
                startDirections: ['bottom']
            }
        });

I've been looking at joint.routers.manhattan.js but it's pretty complex...

Does anyone know what I can modify in joint.routers.manhattan.js so that labels are considered obstacles?

Possible Solutions:

  • Route with Manhattan first, then determine where to place label so that it is not conflicting with another label.
  • Place labels first, then edit Manhattan so that labels are considered obstacles.

Solution

  • There were a few things I learned that helped me:

    • Links are NOT elements. When you do graph.getElements(), the list will not include any links. Try running this in the javascript console:

          var map = graph.getElements()
          for(var m=0; m<map.length; m++)
          {
              console.log("Type: "+map[m].get('type')+", Bounding Box: "+map[m].getBBox());
          }
      
    • Changing the step or maximumLoops options may help:

          link.set('router', {
              name: 'manhattan',
              args: {
                  startDirections: ['bottom'],
                  step: 10, 
                  maximumLoops: 500
              }
          });
      
    • One way to solve this issue is to increase the getBBox for elements where links are getting too close to.
    • Another way to increase the size of the obstacle is to increase the manhattan router's opt.paddingBox variable. If you look at the source code, it is doing exactly what I need:

          // expand elements boxes by specific padding
          .invoke('moveAndExpand', opt.paddingBox)
      

    I ended up adding extra padding to the manhattan file using the last suggestion listed above.