Search code examples
jointjs

How can I add an image to ports?


I've tried to add an image to rectangle port with JointJS, check my jsfiddle project. I need 2 images, one in my rectangle shape, I did that and one inside shape port. I don't know why, but when I add <image/> tag in "portMarkup" somehow that duplicates first image (that one from my rectangle shape)..... I don't need that, I need 2 distinct images. Someone have any suggestions? Thanks!


Solution

  • In your JSFiddle you don't differentiate between image attributes. When you make the instance of your shape hmi = new joint.shapes.devs.Model, the image attributes here override the image attributes when you defined joint.shapes.devs.Model in the first place.

    If you comment out the following in the instance, you will see both images become links, and much smaller.

    image: {
         'xlink:href': "https://cdn2.iconfinder.com/data/icons/electronics-139/56/rj45__connector__Ethernet__port__connection-512.png", 
         width: 83,
         height: 68,
         'ref-x': .5,
         'ref-y': .5,
         ref: 'rect',
         'x-alignment': 'middle',
         'y-alignment': 'middle',
         id: 'hmi_image_ID_'
    }
    

    When you define joint.shapes.devs.Model, you could add a class to the image in portsMarkup, and then use that class in the attributes. That will make the image in the portsMarkup unique.

    portMarkup: '<g class="port port<%= id %>"><circle id="hmi_circle" class="port-body" style="stroke: #338264; fill: #6DC0A0; fill-opacity: 1;"/><text class="port-label"/><image class="port-image"/></g>',,
    ---------------
    '.port-body': {
            r: 15,
            magnet: true,
            stroke: '#338264'
    },
    '.port-image': {
            href: 'https://via.placeholder.com/150'
    },
    

    This doesn't solve the issue that all the image attributes in the instance override the image attributes in the definition, so you will have to rearrange some code I guess.

    Also, in JointJS the devs shape is deprecated, and it's not the recommended way to create ports now. This tutorial explains how to create ports with the PORT API in JointJS.

    To create a Port with an image in JointJS now, you should create something like the following port definition.

        const port = {
            label: {
                position: {
                    name: 'left'
                },
                markup: [{
                    tagName: 'text',
                    selector: 'label'
                }]
            },
            attrs: { 
                portBody: { 
                    magnet: true,
                    width: 16,
                    height: 16,
                    x: -8,
                    y: -8,
                    fill:  '#03071E',
                    stroke: 'none'
                },
                imgSrc: {
                    width: 16,
                    height: 16,
                    x: -8,
                    y: -8,
                    href: 'https://via.placeholder.com/16.png/09f/fff'
                }, 
                label: { 
                    text: 'port' 
                }
            },
            markup: [{
                tagName: 'rect',
                selector: 'portBody'
            }, {
                tagName: 'image',
                selector: 'imgSrc'
            }]
        };