Skip to main content
Version: 4.1

Cell

The basic model for diagram cells. It's an mvc.Model with a few additional properties and methods. Most importantly, every cell has a unique ID that is stored in the id property.

To learn about cells and their features in detail, see the shapes learn section.

constructor​

new Cell([attributes], [options])

When creating an instance of a cell, you can pass in the initial values of the attributes, which will be set on the model.

If you pass a { mergeArrays: true } as the options, all the arrays defined as class defaults will be merged instead of overridden.

const MyRect = shapes.standard.Rectangle.define('Rect', { array: [1,2] });

const rect1 = new MyRect({ array: [3] });
console.log(rect1.get('array')); // [3] array was overridden

const rect2 = new MyRect({ array: [3] }, { mergeArrays: true });
console.log(rect2.get('array')); // [3,2] array was merged

Methods​

addTo()​

cell.addTo(graph)

Add the cell to the graph (an instance of dia.Graph). This is equivalent to calling graph.addCell(cell).

attr()​

cell.attr(path);
cell.attr(path, value [, opt]);
cell.attr(attrs [, opt])

Set presentation attributes (SVG and JointJS attributes) on view subelements. attrs can either be an object or string representing a path to a nested attribute. If it is an object, the keys of the attrs object are selectors (JSON Markup Selector or CSS Selector) matching the subelements. The values are objects containing SVG attributes and their values. attrs object will be mixed with attrs property of the shape model. This is a convenient way of rewriting only some of the attributes of the subelements. For overwriting all attributes of all subelements, use cell.set('attrs', attrs).

element.attr({
// selectors as defined in the JSON markup
body: { width: 'calc(w)', height: 'calc(h)' },
label: { text: 'My Label' },
// using CSS selectors is significantly slower
rect: { fill: 'blue' },
text: { fill: 'white', fontSize: 15 },
'.myrect2': { fill: 'red' }
});

link.attr({
// selector as defined in JSON markup
line: {
stroke: 'red',
targetMarker: {
type: 'circle',
r: 5
}
}
});

The method is not suitable for storing custom data on the model. For that, use prop() or set() methods. You can learn about it more in the following learn section.

shape.set('confirmed', true);
shape.prop('data/count', 10);
An alternative call using a string/array path and a value:​
element.attr(path, value [, opt])
element.attr('body/fill', 'red');
element.attr(['label', 'fontSize'], 12);
// Note: an equivalent expression is also
element.prop('attrs/label/fontSize', 12);

link.attr('line/stroke', 'red');
link.attr(['line', 'targetMarker', 'type'], 'path');
Get attribute value defined by a path.​
element.attr([path])

If no path provided the whole attrs object is returned.

element.attr('body/fill') === 'red';
element.attr(['label', 'fontSize']) === 12;

const color = link.attr('line/stroke');
const targetMarkerType = link.attr(['line', 'targetMarker', 'type']);

clone()​

cell.clone(options)

Returns a new instance of the cell with identical attributes. If options.deep === true, then all the embedded cells (elements, links) of the cell are cloned as well. In this case, the return value is an array of instances rather then a single instance.

embed()​

cell.embed(cell, [opt])
cell.embed(cells, [opt])

Embed a cell, or an array of cells into the cell. The cell then becomes a parent of the embedded cell. When a parent is moved (translated), all cells embedded into that parent will move as well. If links are embedded, their vertices move with the parent. This way both options are available: if a link is not embedded but its source/target elements are and their parent moves, the embedded elements move with the parent but the link vertices stay at the same position. If the link is embedded with its source/target cells, its vertices move as the parent moves.

The opt.reparent option can be set to true to transfer embedded cells from their current parent to a new parent. By default, if opt.reparent is not set to true, reparenting will result in an exception: Embedding of already embedded cells is not allowed.

Any additional option or custom property provided in the options object will be accessible in the callback function of the cell 'change:embeds' event.

const rect1 = new shapes.standard.Rectangle({
position: { x: 100, y: 100 },
size: { width: 90, height: 30 },
attrs: { label: { text: 'Rect' } }
});

const rect2 = rect1.clone();
rect2.translate(100, 0);

graph.addCells([rect1, rect2]);

rect1.on('change:embeds', function(element, newEmbeds, opt) {
console.log(opt); // {testOption: true}
});

// Add custom 'testOption' property
rect1.embed(rect2, { testOption: true });

findView()​

cell.findView(paper)

Find view (dia.CellView) for the shape model in the paper. This is a shortcut to the equivalent call paper.findViewByModel(cell)

getAncestors()​

cell.getAncestors()

Return an array of all the ancestors of this cell starting from the immediate parent all the way up to the most distant ancestor.

getEmbeddedCells()​

cell.getEmbeddedCells([opt])

Return an array of all the embedded cells of a cell.

note

If all you need is id's of all the embedded cells, use cell.get('embeds') instead.

If opt.deep is true, all the deeply embedded cells will be returned. The order in which the cells are returned depends on the search algorithm used. By default, Depth-first search (DFS) algorithm is used. If opt.breadthFirst is true, the Breadth-first search algorithm will be used instead.

getParentCell()​

cell.getParentCell()

Return the parent cell of cell or null if there is none.

getTransitions()​

cell.getTransitions()

Return an array of all active transitions (their paths).

isElement()​

cell.isElement()

Check if the cell is an element. This method is useful if you don't know what the cell is. Calling cell.isElement() is equivalent to cell instanceof dia.Element. Example:

const cell = graph.getCell(myId)
if (cell.isElement()) {
// Do something if the cell is an element.
}

isEmbedded()​

cell.isEmbedded()

Return true if the cell is embedded in another cell.

isEmbeddedIn()​

cell.isEmbeddedIn(cell [, opt])

Return true if the cell is embedded in a cell.

If opt.deep is false, only direct parentage will be checked. opt.deep is true by default.

element.isLink()

Check if the cell is a link. This method is useful if you don't know what the cell is. Calling cell.isLink() is equivalent to cell instanceof dia.Link. Example:

const cell = graph.getCell(myId)
if (cell.isLink()) {
// Do something if the cell is a link.
}

parent()​

cell.parent()

Return the parent property of the cell.

If the cell is a part of an embedding, the id of the parent cell is returned as a string.

If you need to be sure that a Cell is returned (and not its id), use the cell.getParentCell function instead.

prop()​

cell.prop(path);
cell.prop(path, value [, opt]);
cell.prop(object [, opt]);

Set properties, possibly nested, on the shape model. This is equivalent to the attr() method but this time for model properties. You can learn about it more in the following learn section.

cell.prop('name/first', 'John')
cell.prop('name/first') // 'John'
cell.prop({ name: { first: 'John' } })
// Nested arrays are supported too:
cell.prop('mylist/0/data/0/value', 50)
cell.prop({ mylist: [ { data: [ { value: 50 } ] } ] })

remove()​

cell.remove()

Remove the cell from the graph.

removeAttr()​

cell.removeAttr(path [, opt])

Remove a previously set attribute from the cell. path can either be a string that specifies the path to the (possibly nested) attribute to be removed, or a path array. The associated cell view makes sure the cell gets re-rendered properly.

If opt is passed, it can contain data that is passed over to the event listeners for the change:attrs event triggered on the cell itself and also on the graph the cell is in.

removeProp()​

cell.removeProp(path [, opt])

Remove a previously set property from the cell. path can either be a string that specifies the path to the (possibly nested) property to be removed, or a path array.

cell.removeProp('name');
cell.removeProp('name/first');
cell.removeProp(['mylist', 0, 'data', 0, 'value']);
info

How this method differs from removeAttr()

The removeAttr() is used to remove presentation attributes from the cell view.

The removeProp() is more general and is used to remove properties from the cell model.

The following expressions are equivalent:

cell.removeProp('attrs/body/rx');
cell.removeAttr('body/rx');

stopTransitions()​

cell.stopTransitions([path])

Stops all running transitions. If parameter path is provided, it will stop only transitions specified by this path.

toBack()​

cell.toBack([opt])

Move the cell so it is behind all other cells. If opt.deep is true, all the embedded cells of this cell will be updated in a Breadth-first search (BFS) fashion.

If opt.foregroundEmbeds is true (as by default), all the embedded cells will get a higher z index than that of this cell. This is especially useful in hierarchical diagrams where if you want to send a cell to the back, you don't want its children (embedded cells) to be hidden behind that cell. If opt.foregroundEmbeds is false, the original order within the group is preserved, allowing children to remain behind their parents.

Set opt.breadthFirst to false to index the cells using Depth-first search (DFS).

toFront()​

cell.toFront([opt])

Move the cell so it is on top of all other cells. If opt.deep is true, all the embedded cells of this cell will be updated in a Breadth-first search (BFS) fashion.

If opt.foregroundEmbeds is true (as by default), all the embedded cells will get a higher z index than that of this cell. This is especially useful in hierarchical diagrams where if you want to send a cell to the front, you don't want its children (embedded cells) to be hidden behind that cell. If opt.foregroundEmbeds is false, the original order within the group is preserved, allowing children to remain behind their parents.

Set opt.breadthFirst to false to index the cells using Depth-first search (DFS).

All cells have a z property defining their z-level in the graph. This z property can even be set directly by cell.set('z', 123). This change will be automatically handled by the dia.Paper object associated with the dia.Graph object this cell is part of and all the SVG elements will get resorted so that their position in the DOM reflects the z level.

container.embed(el1);
container.embed(el2);
container.toFront({ deep: true });

toJSON()​

cell.toJSON([opt])

Return a copy of the cell's attributes for JSON serialization. This can be used for persistance or serialization. Note that this method doesn't return a JSON string but rather an object that can be then serialized to JSON with JSON.stringify().

By default, opt.ignoreDefaults is set to ['attrs']. This setting ensures that only non-default attributes in the attrs object are returned, as it compares the attrs object to its defaults. To include all attributes of dia.Cell without filtering out defaults, set opt.ignoreDefaults to false. Alternatively, setting opt.ignoreDefaults to true will compare all attributes to their defaults, returning only those that differ. You can also provide an array of strings for opt.ignoreDefaults, specifying a list of attributes to compare against their defaults.

Additionally, opt.ignoreEmptyAttributes defaults to false, which may include empty objects in the JSON output. To exclude empty objects, set opt.ignoreEmptyAttributes to true.

const rectangle = new shapes.standard.Rectangle();

rectangle.toJSON();
// {
// "type": "standard.Rectangle",
// "attrs": {},
// "position": {
// "x": 0,
// "y": 0
// },
// "size": {
// "width": 1,
// "height": 1
// },
// "angle": 0,
// "id": "..."
// }

rectangle.toJSON({ ignoreDefaults: true });
// {
// "type": "standard.Rectangle",
// "attrs": {},
// "position": {},
// "size": {},
// "id": "..."
// }

rectangle.toJSON({ ignoreDefaults: true, ignoreEmptyAttributes: true });
// {
// "type": "standard.Rectangle",
// "id": "..."
// }

rectangle.toJSON({ ignoreDefaults: ['attrs', 'size'] });
// {
// "type": "standard.Rectangle",
// "attrs": {},
// "position": {
// "x": 0,
// "y": 0
// },
// "size": {},
// "angle": 0,
// "id": "..."
// }

transition()​

cell.transition(path, value [, opt])

Allows to change the cell's property gradually over a period of time. This method lets you specify what property to change (path), when the transition will start (opt.delay), how long the transition will last (opt.duration), how the transition will run (opt.timingFunction), and how to interpolate the property value (opt.valueFunction).

element.transition('position/x', 250, {
delay: 100,
duration: 500,
timingFunction: function(t) { return t*t; },
valueFunction: function(a, b) { return function(t) { return a + (b - a) * t }}
});
// will start changing the cell's x-coordinate in 100ms, for period of 500ms.

link.transition('target', { x: 250, y: 250 }, {
delay: 100,
duration: 500,
timingFunction: joint.util.timing.bounce,
valueFunction: joint.util.interpolate.object
});
// will start changing the link target coordinates in 100ms, for period of 500ms and performing a bounce effect.

JointJS comes pre-built with some common timing and interpolating functions. The timing functions are defined in the util.timing namespace and the interpolating functions in the util.interpolate namespace. The predefined timing functions are:

  • linear
  • quad
  • cubic
  • inout
  • exponential
  • bounce

and the predefined interpolating functions are:

  • number
  • object
  • hexColor
  • unit
element.transition('attrs/text/font-size', '1em', {
valueFunction: joint.util.interpolate.unit,
timingFunction: joint.util.timing.bounce
});
// will start changing the current font size value to 1em in the bounce fashion.

link.transition('target', { x: 250, y: 250 }, {
delay: 100,
duration: 500,
timingFunction: joint.util.timing.bounce,
valueFunction: joint.util.interpolate.object
});
// will start changing the link target coordinates in 100ms, for period of 500ms and performing a bounce effect.

unembed()​

cell.unembed(cell, [opt])
cell.unembed(cells, [opt])

Free up an embedded cell or an array of cells from its parent cell.

z()​

cell.z()

Return z – the stacking order (an equivalent to HTML z-index).

When z is undefined or null, function returns 0.

Static methods​

define()​

define(type [, defaultAttributes, prototypeProperties, staticProperties])

Helper to define a new Cell class or extend an existing one. You can learn how to create new shapes in our custom shapes learn section.

The type must be a unique identifier of the class, which determines the location of the class definition in the joint.shapes namespace (type is the path to the class definition delimited by dots: .). When creating an instance of the cell, attributes will be set to the value from the defaultAttributes, unless overridden by subclass or instance attributes.

// Define a new Ellipse class in `joint.shapes.examples` namespace
// Inherits from generic Element class
var Ellipse = joint.dia.Element.define('examples.Ellipse', {
// default attributes
markup: [{
tagName: 'ellipse',
selector: 'ellipse' // not necessary but faster
}],
attrs: {
ellipse: {
fill: 'white',
stroke: 'black',
strokeWidth: 4,
rx: 'calc(0.5*w)',
ry: 'calc(0.5*h)',
cx: 'calc(0.5*w)',
cy: 'calc(0.5*h)'
}
}
});

// Instantiate an element
var ellipse = (new Ellipse()).position(100, 100).size(120, 50).addTo(graph);

// Define a new ColoredEllipse class
// Inherits from Ellipse
var ColoredEllipse = Ellipse.define('examples.ColoredEllipse', {
// overridden Ellipse default attributes
// other Ellipse attributes preserved
attrs: {
ellipse: {
fill: 'lightgray'
}
}
}, {
// prototype properties
// accessible on `this.(...)` - as well as, more precisely, `this.prototype.(...)`
// useful for custom methods that need access to this instance
// shared by all instances of the class
randomizeStrokeColor: function() {
var randomColor = '#' + ('000000' + Math.floor(Math.random() * 16777215).toString(16)).slice(-6);
return this.attr('ellipse/stroke', randomColor);
}
}, {
// static properties
// accessible on `this.constructor.(...)`
// useful for custom methods and constants that do not need an instance to operate
// however, a new set of static properties is generated every time the constructor is called
// (try to only use static properties if absolutely necessary)
createRandom: function() {
return (new ColoredEllipse()).randomizeStrokeColor();
}
});

// Instantiate an element
var coloredEllipse = ColoredEllipse.createRandom().position(300, 100).size(120, 50).addTo(graph);

Properties​

markup​

Either an XML string or JSON markup specifying an array of JSON elements. Also JSON markup can be described using an svg tagged template. Used as a template to build DOM Elements on the fly when the associated cellView is rendered. More on this topic in our learn section on markup.