Arguments of link.router() are ignored

This issue has been tracked since 2021-12-15.

I've tried to set the arguments of the router, but they are ignored:

    link.router(orthogonal,
      {
        elementPadding: 0,
        padding: 0
      }
    );

(orthogonal is a function and the customization of the JointJS orthogonal router.)

I found out that when getPaddingBox(opt) of the orthogonal router is called, opt is always an empty object. So I dug a bit deeper: The router function is called by the link view when the route is calculated:

export const LinkView = CellView.extend({
    // ...
    findRoute: function(vertices) {

        vertices || (vertices = []);

        var namespace = this.paper.options.routerNamespace || routers;
        var router = this.model.router();
        var defaultRouter = this.paper.options.defaultRouter;

        if (!router) {
            if (defaultRouter) router = defaultRouter;
            else return vertices.map(Point); // no router specified
        }

        var routerFn = isFunction(router) ? router : namespace[router.name];
        if (!isFunction(routerFn)) {
            throw new Error('dia.LinkView: unknown router: "' + router.name + '".');
        }

        var args = router.args || {};

        var route = routerFn.call(
            this, // context
            vertices, // vertices
            args, // options
            this // linkView
        );

        if (!route) return vertices.map(Point);
        return route;
    },
    // ...
});

But router.args is always undefined. It seems that the args property is never set:

export const Link = Cell.extend({
  // ...
  router: function(name, args, opt) {

    // getter
    if (name === undefined) {
      var router = this.get('router');
      if (!router) {
        if (this.get('manhattan')) return { name: 'orthogonal' }; // backwards compatibility
        return null;
      }
      if (typeof router === 'object') return util.clone(router);
      return router; // e.g. a function
    }

    // setter
    var isRouterProvided = ((typeof name === 'object') || (typeof name === 'function'));
    var localRouter = isRouterProvided ? name : { name: name, args: args };
    var localOpt = isRouterProvided ? args : opt;

    return this.set('router', localRouter, localOpt);
  }
  // ...
});

Maybe I am missing some Backbone.js magic knowledge? But unfortunately the specified arguments don’t work out as expected.

jamesgeorgewilliams wrote this answer on 2021-12-15

Hi, for custom routers, the following two signatures exist for functions:

joint.routers.orthogonal = function(vertices, args, linkView) {

    var PADDING = args.padding || 20;

    // Your customization 

    return vertices;
}

var link = new joint.shapes.standard.Link();
link.source(source);
link.target(target);

link.router('orthogonal', {
    padding: 0
});
var link = new joint.shapes.standard.Link();
link.source(source);
link.target(target);

link.router(function(vertices, args, linkView) {

    var PADDING = 20;

   // Your customization 

    return vertices;
});

Method number 2 does not enable passing custom args.
https://resources.jointjs.com/docs/jointjs/v3.4/joint.html#routers.custom

If you are trying something similar to method 2, that could be the reason.

kumilingus wrote this answer on 2021-12-22

You should refer to the router via its name, not passing the router function itself.

If it is a custom router you can define a new router (or override existing) via routerNamespace.

Another option is to wrap your customized router with another function.

link.router((vertices, _, linkView) => {
  return orthogonal.call(linkView,  vertices, {  elementPadding: 0,  padding: 0 }, linkView);
});
More Details About Repo
Owner Name clientIO
Repo Name joint
Full Name clientIO/joint
Language JavaScript
Created Date 2009-09-11
Updated Date 2022-12-06
Star Count 3717
Watcher Count 155
Fork Count 817
Issue Count 53

YOU MAY BE INTERESTED

Issue Title Created Date Updated Date