Release v3.0.0
CHANGELOG
Compatibilty warnings
- dia.CellView - support for asynchronous updates and freezing
details
A major breaking change of the release.
When a view needs an update, it requests the update from the paper first. The paper confirms the update immediately (sync
mode) or in the next animation frame (async
mode). The updates may be also held by the paper as long as the paper is frozen
and released when the paper changes its state to unfrozen
.
A CellView
is no longer listening for a specific attribute change (e.g change:size
). It listens to the change
event, which is fired after all attributes have changed.
model.set({ a: 1, b: 2 }); // will trigger `change:a`, `change:b` and `change`.
// PREVIOUSLY
joint.dia.ElementView.extend({
initialize(...args) {
joint.dia.ElementView.prototype.initialize.apply(this, ..args);
this.listenTo(this.model, 'change:faded', this.toggleFade);
},
toggleFade() {
this.el.style.opacity = this.model.get('faded') ? 0.5 : 1;
}
});
// NOW 1. a quick backwards compatible fix which works in `sync` mode
joint.dia.ElementView.extend({
initialize(...args) {
joint.dia.ElementView.prototype.initialize.call(this, ...args);
this.listenTo(this.model, 'change', this.onModelChange);
},
onModelChange() {
if (this.model.hasChanged('faded')) this.toggleFade();
},
toggleFade() {
this.el.style.opacity = this.model.get('faded') ? 0.5 : 1;
}
});
In order to support async
mode the following changes are necessary. The update requests are sent to the paper via flags
(a flag is an arbitrary string or array of strings) and later received back all at once. The paper accumulates flags received and confirms the updates when the right time has come.
// NOW 2. a fix which supports both `sync` and `async` mode and freezing/unfreezing feature
joint.dia.ElementView.extend({
// `addPresentationAttribute()` makes sure that all super class presentation attributes are preserved
presentationAttributes: joint.dia.ElementView.addPresentationAttributes({
// mapping the model attributes to flags
faded: 'flag:opacity'
}),
// this method receives all scheduled flags and based on them updates the view
confirmUpdate(flags, ...args) {
joint.dia.ElementView.prototype.confirmUpdate.call(this, flags, ...args);
if (this.hasFlag(flags, 'flag:opacity')) this.toggleFade();
},
toggleFade() {
this.el.style.opacity = this.model.get('faded') ? 0.5 : 1;
}
});
- dia.CellView - remove deprecated
getStrokeBBox()
details
The implementation of the method above was naive and didn't work in the majority of cases.
// read the actual stroke-width
const strokeWidth = elementView.model.attr('body/strokeWidth');
// add the half of the stroke width to all the sides of the bounding box
const strokeBBox = elementView.getBBox().inflate(strokeWidth / 2);
- dia.Paper - async mode revamped (viewport matching, rendering progress)
details
render:done
event is triggered anytime scheduled updates are done (rendered/updated).
// PREVIOUSLY
paper.on('render:done', () => { /* all rendered */ });
graph.resetCells([el1, el2, l1]);
// NOW 1.
paper.once('render:done', () => { /* all rendered and this callback is removed */ })
graph.resetCells([el1, el2, l1]);
// NOW 2.
paper.freeze();
graph.resetCells(arrayOfCells);
paper.unfreeze({
batchSize: 100,
progress: (done, current, total) => {
if (done) {
paper.unfreeze(); // remove the progress callback
// hide a progress bar
} else {
// update a progress bar (current / total * 100)%
}
}
}) ;
batchSize
in the paper async option is ignored.
// PREVIOUSLY
const paper = new joint.dia.Paper({ async: { batchSize: 200 }});
// NOW
const paper = new joint.dia.Paper({ frozen: true, async: true });
paper.unfreeze({ batchSize: 200 });
- dia.Paper - cells are rendered into the
paper.cells
(previously calledpaper.viewport
), transformations are applied topaper.layers
(parent ofpaper.cells
)
details
A minor change which will allow us to implement other features in the future without breaking changes (layers for cells, labels on top of all other cells)
paper.viewport
is now deprecated and refers to the same node as paper.cells
// PREVIOUSLY
// 1. transforming the paper
V(paper.viewport).scale(2,2);
// 2. reading transformation matrix of the paper
const transformationString = paper.viewport.getAttribute('transformation');
// 3. adding custom nodes to the viewport
const rect = V('rect', { x: 10, y: 10, width: 100, height: 100 });
V(paper.viewport).append(rect);
// NOW
// 1.
paper.scale(2,2);
// 2.
const transformationString = V.matrixToTransformString(paper.matrix());
// 3.
const myLayer = V('g');
V(paper.layers).prepend(myLayer);
/*
All my nodes will be under the elements and links
Alternatively call `V(paper.layers).append(myLayer)` so the nodes will be above the cells
*/
const rect = V('rect', { x: 10, y: 10, width: 100, height: 100 });
myLayer.append(rect);
myLayer.empty() // remove all custom nodes
- dia.Graph -
getBBox()
accepts no parameters and returns the bounding box of the entire graph
details
To retrieve the bounding box of multiple cells use getCellsBBox()
instead
// PREVIOUSLY
const cellsBBox = graph.getBBox([el1, el2, el3]);
// NOW
const cellsBBox = graph.getCellsBBox([el1, el2, el2]);
- dia.Graph -
getCellsBBox(cells)
does not ignore links passed viacells
parameter
details
// PREVIOUSLY
const cellsBBox = graph.getCellsBBox([el1, el2, l1, l2]);
// NOW
// Passing links could lead into a different result (vertices position can affect the resulting bounding box)
const cellsBBox = graph.getCellsBBox([el1, el2]);
- Vectorizer - fix
attr()
for attributes inxmlns
namespace
details
Will not affect you unless you use the namespace below directly.
// `xmlns:link` is now defined with the correct namespace
V(el).attr('xmlns:link', 'http://www.w3.org/1999/xlink');
// PREVIOUSLY
V.namespace.xmlns = 'http://www.w3.org/2000/svg';
// NOW
V.namespace.xmlns = 'http://www.w3.org/2000/xmlns/';
V.namespace.svg = 'http://www.w3.org/2000/svg';
- remove deprecated
PortsModelInterface
andPortsViewInterface
fromjoint.shapes.basic
Notable changes
- upgrade dependencies (Backbone
v1.4.0
, Dagrev0.8.4
, Graphlibv2.1.6
, jQueryv3.4.1
) - full support for ES Modules
- support for Link to Link connections
- add Mix Bus demo
- dia.Paper - implement viewport matching (remove views from the DOM when not in the viewport) via
viewport
option andcheckViewport()
- dia.Paper - add
freeze()
,unfreeze()
,isFrozen()
and optionfrozen
to stop/start views updates - dia.Paper - add
requireView()
,dumpViews()
,updateViews()
to force views to update - dia.Paper - add sorting options (none, approximate, exact)
- dia.Paper - add
anchorNamespace
,linkAnchorNamespace
,connectionPointNamespace
,defaultLinkAnchor
options - dia.Paper - add
useModelGeometry
forscaleContentToFit()
,fitToContent()
,getContentBBox()
,getContentArea()
- dia.Paper - add
contentArea
forscaleContentToFit()
,fitToContent()
- dia.Paper -
fitToContent()
returns area (g.Rect
) of the content - dia.Graph - add
indirect
option forgetNeighbors()
,getConnectedLinks()
,isNeighbor()
for link-link connections - dia.Link - add
priority
attribute for anchors - dia.Link - add
getSourceCell()
,getTargetCell()
,getPolyline()
,getSourcePoint()
,getTargetPoint()
,getBBox()
- dia.Link -
getSourceElement()
andgetTargetElement()
finds also indirect elements - dia.Link - add
angle
,keepGradient
andensureLegibility
options for labels - dia.ElementView - add
findPortNode()
- dia.LinkView - properly revert
pointer-events
attribute after a link interaction - dia.LinkView - add root node selector for string markup
- dia.CellView - keep a dragged view always under the pointer (esp. when
restrictTranslate
in use) - dia.CellView - make sure
cell:mouseleave
andcell:mouseenter
events are always called when the mouse leaves/enters a cell - dia.CellView - fix referenced bounding box for nodes outside the rotatable group
- dia.Cell - add
generateId()
,generatePortId()
- anchors -
modelCenter
anchor acceptsdx
,dy
options - linkAnchors - add anchors for link-link connection (ratio, length, perpendicular, closest)
- linkTools.Vertices - add
stopPropagation
option - shapes.standard - add
standard.InscribedImage
shape - util -
breakText()
prefers breaking words at hyphens - util -
nextFrame()
extra parameters are appended to the arguments the callback receives - Vectorizer - fix
translateAndAutoOrient()
for edge cases - Geometry.Path - add
divideAt()
anddivideAtLength()
- Geometry.Path - fix
closestPoint()
ending in an infinite loop - Geometry.Path - supports scientific notation when defined via SVGPath data
- Geometry.Line - add
angle()
- Geometry.Point - add
chooseClosest()
to find the closest point among an array of points - Geometry - add
containsPoint()
for Polyline, Path, Curve and Line - Geometry - add
random()