Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add an image to an element as a decorator?

Tags:

jointjs

Imagine I have Rect element and I wish to decorate it with a small (say 16x16) PNG image in the upper left. I am unable to determine how to achieve that task. I have studied the docs but have (so far) been unable to find a sample or reference on how to achieve that task. Does anyone have a recipe or a sample pointer that they would be willing to share to help me achieve my goal?

like image 832
Kolban Avatar asked Nov 14 '14 02:11

Kolban


2 Answers

Better is to create your own custom shape that has a rectangle, image and text. This gives you much more flexibility and you don't have to have two elements in order to express one shape. Your shape decorated with a little image in the top left corner may look like:

joint.shapes.basic.DecoratedRect = joint.shapes.basic.Generic.extend({

    markup: '<g class="rotatable"><g class="scalable"><rect/></g><image/><text/></g>',

    defaults: joint.util.deepSupplement({

        type: 'basic.DecoratedRect',
        size: { width: 100, height: 60 },
        attrs: {
            'rect': { fill: '#FFFFFF', stroke: 'black', width: 100, height: 60 },
            'text': { 'font-size': 14, text: '', 'ref-x': .5, 'ref-y': .5, ref: 'rect', 'y-alignment': 'middle', 'x-alignment': 'middle', fill: 'black' },
            'image': { 'ref-x': 2, 'ref-y': 2, ref: 'rect', width: 16, height: 16 }
        }

    }, joint.shapes.basic.Generic.prototype.defaults)
});

And you can use it like this in your diagrams:

var decoratedRect = new joint.shapes.basic.DecoratedRect({
    position: { x: 150, y: 80 },
    size: { width: 100, height: 60 },
    attrs: { 
        text: { text: 'My Element' },
        image: { 'xlink:href': 'http://placehold.it/16x16' }
    }
});
graph.addCell(decoratedRect);

Note how is the shape specified, the important bits are the markup, type and the attrs object that references the SVG elements in the markup by normal CSS selectors (here just tag selectors but you can use classes if you want). For the image tag, we take advantage of the JointJS special attributes for relative positioning (ref, ref-x and ref-y). With these attributes, we position the image relatively to the top left corner of the rect element and we offset it by 2px from the top edge (ref-y) and 2px from the left edge (ref-x).

One note: It is important that the type attribute ('basic.DecoratedRect') matches the namespace the shape is defined in (joint.shapes.basic.DecoratedRect). This is because when JointJS re-constructs graphs from JSON, it looks at the type attribute and makes a simple lookup to the joint.shapes namespace to see if there is a shape defined for this type.

like image 99
dave Avatar answered Oct 19 '22 20:10

dave


We can create an element type for an image using the following recipe:

var image = new joint.shapes.basic.Image({
    position : {
        x : 100,
        y : 100
    },
    size : {
        width : 16,
        height : 16
    },
    attrs : {
        image : {
            "xlink:href" : "images/myImage.png",
            width : 16,
            height : 16
        }
    }
});

graph.addCell(image);

This will position the image at x=100,y=100. It is important to make the size width/height match the attrs/image width/height and be the width/height of the image itself.

Although this doesn't decorate a previous element, it can be positioned over a previous element achieving the desired effect.

like image 20
Kolban Avatar answered Oct 19 '22 20:10

Kolban