Khalid Adil
Khalid Adil

Reputation: 110

Change JointJS Port color dynamically

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?

Upvotes: 1

Views: 2237

Answers (2)

Astronaut
Astronaut

Reputation: 7031

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());
           }
        }

Upvotes: 1

vt.
vt.

Reputation: 1428

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

Upvotes: 3

Related Questions