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.
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.
isLink()β
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']);
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.