Mark Dyson
Mark Dyson

Reputation: 305

JointJS unable to connect ports, says "getPortSelector" not a function

I am having problems connecting ports on custom elements in JointJS. I define the elements using this code:

function defineElement(id, parentID, type, elementLabel, toolName, timeRequired, userAccessing, IPInfo, notes) {
  this.id = id;
  this.parentID = parentID;
  this.elementType = type;
  this.label = elementLabel;
  this.toolName = toolName;
  this.timeRequired = timeRequired;
  this.userAccessing = userAccessing;
  this.IPInfo = IPInfo;
  this.notes = notes;
}

function makeElement(element) {

    var maxLineLength = _.max(element.label.split('\n'), function(l) { return l.length; }).length;

    var letterSize = 8;
    var width = 1.6 * (letterSize * (0.6 * maxLineLength + 1));
    var height = 2 * ((element.label.split('\n').length + 1) * letterSize);

    var newElement;

    joint.shapes.devs.flowchartProcess = joint.shapes.devs.Model.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {


        markup: '<g class="rotatable"><g class="scalable"><rect class="body"/></g><text class="body-label"/><g class="inPorts"/><g class="outPorts"/></g>',
        portMarkup: '<g class="port port<%= id %>"><circle class="port-body"/><text class="port-label"/></g>',

        defaults: joint.util.deepSupplement({

        type: 'devs.flowchartProcess',
        attrs: {
            '.body': { stroke: 'black' },
            '.body-label': { 'ref-x': .5, 'ref-y': .5, ref: '.body', 'y-alignment': 'middle', 'x-alignment': 'middle' },
            '.port-body': { r: 6, magnet: 'active' },
            '.inPorts .port-body': { stroke: 'gray', fill: 'red' },
            '.outPorts .port-body': { stroke: 'gray', fill: 'green'},
            '.inPorts .port-label': { },
            '.outPorts .port-label': { }
        }

    }, joint.shapes.devs.Model.prototype.defaults),

        getPortAttrs: function(portName, index, total, selector, type) {

            var attrs = {};

            var portClass = 'port' + index;
            var portSelector = selector + '>.' + portClass;
            var portLabelSelector = portSelector + '>.port-label';
            var portBodySelector = portSelector + '>.port-body';

            attrs[portLabelSelector] = { text: portName };
            attrs[portBodySelector] = { port: { id: portName || _.uniqueId(type) , type: type } };

            // CHANGED: swap x and y ports coordinates ('ref-y' => 'ref-x')
            attrs[portSelector] = { ref: '.body', 'ref-x': (index + 0.5) * (1 / total) };
            // ('ref-dx' => 'ref-dy')
            if (selector === '.outPorts') { attrs[portSelector]['ref-dy'] = 0; }
            //

            return attrs;
        }
    }));

    joint.shapes.devs.flowchartProcessView = joint.shapes.devs.ModelView;


            newElement =  new joint.shapes.devs.flowchartProcess ({
                id: element.id,
                size: { width: width, height: height },
                inPorts: ['in'],
                outPorts: ['out'],
                attrs: {
                    text: { text: element.label }
                }
            });
            newElement.attr('rect/fill', { type: 'linearGradient', stops: [{ offset: '0%', color: '#00fdff' },{ offset: '100%', color: '#049a9b' }] });
            newElement.attr('rect/fill/attrs', { x1: '0%', y1: '0%', x2: '0%', y2: '100%' });

    newElement.set('parentID', element.parentID);   
    newElement.set('label', element.label); 

    newElement.attr('text', { fill: '#111111' });   
    newElement.attr('rect/filter', { name: 'dropShadow', args: { dx: 1, dy: 3, blur: 1, opacity: 0.75 } });

    return newElement;

}

Then try linking them using this code:

function makeLink(parent, child) {

    var thislink = new joint.shapes.devs.Link({
        source: { id: parent.id, selector: parent.getPortSelector('out') },
        target: { id: child.id, selector: child.getPortSelector('in')  },
        attrs: { '.marker-target': { d: 'M 8 0 L 0 4 L 8 8 z' } },
        smooth: false
    });

    thislink.set('router', { name: 'metro' });

    return thislink;

}

But I get an error saying "getPortSelector" is not a function. Any ideas? Many thanks in advance!

Upvotes: 3

Views: 523

Answers (1)

Mark Dyson
Mark Dyson

Reputation: 305

So, I caused the problem for myself by adding an unnecessary layer of instantiation so the scope of the methods was not as expected. The defineElement step was not needed and made for muddying the waters.

I simplified my element instantiation code and now all is well.

Upvotes: 1

Related Questions