1

I am looking to change the port colors in a JointJS graph based on some external data once the graph has been generated.

I've tried the following code:

var l_portsIn = this.model.get('inPorts');
if (l_portsIn.length > 0){
    this.portProp ('in1','attrs/rect',{stroke: 'red' });
}

where 'in1' is the ID of my port that I need to change.

This is my joint object:

{
  "type": "html.Element",
  "inPorts": [
    "in1",
    "in2",
    "in3",
    "in4",
    "in5"
  ],
  "outPorts": [
    "out1",
    "out2",
    "out3",
    "out4",
    "out5"
  ],
  "position": {
    "x": 600,
    "y": 500
  },
  "size": {
    "width": 170,
    "height": 100
  },
  "angle": 0,
  "label": "Test step #2.",
  "id": "0d29c814-88d7-4429-9d62-c68537098739",
  "z": 2,
  "attrs": {
    ".label": {
      "text": "Test step #2.",
      "ref-x": 0.5,
      "ref-y": 0.4
    },
    ".inPorts>.port0>circle": {
      "port": {
        "id": "in1",
        "type": "in"
      }
    },
    ".inPorts>.port0": {
      "ref": "rect",
      "ref-x": 0.1
    },
    ".inPorts>.port1>circle": {
      "port": {
        "id": "in2",
        "type": "in"
      }
    },
    ".inPorts>.port1": {
      "ref": "rect",
      "ref-x": 0.30000000000000004
    },
    ".inPorts>.port2>circle": {
      "port": {
        "id": "in3",
        "type": "in"
      }
    },
    ".inPorts>.port2": {
      "ref": "rect",
      "ref-x": 0.5
    },
    ".inPorts>.port3>circle": {
      "port": {
        "id": "in4",
        "type": "in"
      }
    },
    ".inPorts>.port3": {
      "ref": "rect",
      "ref-x": 0.7000000000000001
    },
    ".inPorts>.port4>circle": {
      "port": {
        "id": "in5",
        "type": "in"
      }
    },
    ".inPorts>.port4": {
      "ref": "rect",
      "ref-x": 0.9
    },
    ".outPorts>.port0>circle": {
      "port": {
        "id": "out1",
        "type": "out"
      }
    },
    ".outPorts>.port0": {
      "ref": "rect",
      "ref-x": 0.1,
      "ref-dy": 0
    },
    ".outPorts>.port1>circle": {
      "port": {
        "id": "out2",
        "type": "out"
      }
    },
    ".outPorts>.port1": {
      "ref": "rect",
      "ref-x": 0.30000000000000004,
      "ref-dy": 0
    },
    ".outPorts>.port2>circle": {
      "port": {
        "id": "out3",
        "type": "out"
      }
    },
    ".outPorts>.port2": {
      "ref": "rect",
      "ref-x": 0.5,
      "ref-dy": 0
    },
    ".outPorts>.port3>circle": {
      "port": {
        "id": "out4",
        "type": "out"
      }
    },
    ".outPorts>.port3": {
      "ref": "rect",
      "ref-x": 0.7000000000000001,
      "ref-dy": 0
    },
    ".outPorts>.port4>circle": {
      "port": {
        "id": "out5",
        "type": "out"
      }
    },
    ".outPorts>.port4": {
      "ref": "rect",
      "ref-x": 0.9,
      "ref-dy": 0
    }
  }
}

Unfortunately I'm getting the following error:

joint.js:10852 Uncaught Error: Element: unable to find port with id in1
    at n.portProp (https://localhost:8000/libs/joint/joint.js:10852:23)
    at n.modifyPortColor (https://localhost:8000/editor.js:759:16)
    at https://localhost:8000/editor.js:106:21
    at Array.forEach (native)
    at https://localhost:8000/editor.js:104:17
    at Array.forEach (native)
    at HTMLDocument.<anonymous> (https://localhost:8000/editor.js:91:20)
    at j (https://localhost:8000/javascripts/lib/jquery/jquery.min.js:2:27309)
    at Object.fireWith [as resolveWith] (https://localhost:8000/javascripts/lib/jquery/jquery.min.js:2:28122)
    at Function.ready (https://localhost:8000/javascripts/lib/jquery/jquery.min.js:2:29956)
    at HTMLDocument.J (https://localhost:8000/javascripts/lib/jquery/jquery.min.js:2:30322)
portProp @ joint.js:10852
modifyPortColor @ editor.js:759
(anonymous) @ editor.js:106
(anonymous) @ editor.js:104
(anonymous) @ editor.js:91
j @ jquery.min.js:2
fireWith @ jquery.min.js:2
ready @ jquery.min.js:2
J @ jquery.min.js:2

Digging into the joint js library code, it looks like this function is the culprit (in the joint.js file):

getPortIndex: function(port) {
    var id = _.isObject(port) ? port.id : port;

    if (!this._isValidPortId(id)) {
         return -1;
    }

    return _.findIndex(this.prop('ports/items'), { id: id });

}

When I console.log this.prop('ports/items'), it is undefined.

Does anyone have any thoughts?

Khalid Adil
  • 110
  • 14

2 Answers2

3

You can use the element.portProp(portId, path, value)

demo: http://codepen.io/vladimirtalas/pen/PpoYaX

docs: http://resources.jointjs.com/docs/jointjs/v1.0/joint.html#dia.Element.prototype.portProp

vt.
  • 1,398
  • 7
  • 15
1

did you try to use element.getPort('in1') to return the element with the id and they set the prop you want?

also try to get the list of all the ports just to debug that everything is being properly set.

Also inspect with the debugger that the port is getting the id set correctly. the way that you are setting the ports seems a bit strange to me. But as long as you can get the element with the correct id then you can set its proprieties.

updateNode: function () {
        var currentGraph = this.graph;

        _.each(currentGraph.getElements(), function (node) {
            if (node.attributes.type === 'shape.Circle') {
               node.attr('text/text', getRandomIntInclusive(1, 10).toString());
           }
        }
Astronaut
  • 6,691
  • 18
  • 61
  • 99
  • If I do: --- var firstElement = graph.getElements()[0]; console.log(firstElement.getPort('in1')); --- This is returning `undefined` in the browser console. – Khalid Adil Mar 29 '17 at 19:48
  • You need a reference to your graph... I will post an anwser with an example – Astronaut Mar 30 '17 at 08:39