Skip to content

Release v3.0.0

Compare
Choose a tag to compare
@kumilingus kumilingus released this 08 Jun 10:22
· 666 commits to master since this release
9362e5c

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 called paper.viewport), transformations are applied to paper.layers (parent of paper.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 via cells 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 in xmlns 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 and PortsViewInterface from joint.shapes.basic
details

Use Element Ports API instead.

Notable changes

  • upgrade dependencies (Backbone v1.4.0, Dagre v0.8.4, Graphlib v2.1.6, jQuery v3.4.1)
  • full support for ES Modules
  • support for Link to Link connections
screenshot
  • add Mix Bus demo
screenshot

image

  • dia.Paper - implement viewport matching (remove views from the DOM when not in the viewport) via viewport option and checkViewport()
  • dia.Paper - add freeze(), unfreeze(), isFrozen() and option frozen 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 for scaleContentToFit(), fitToContent(), getContentBBox(), getContentArea()
  • dia.Paper - add contentArea for scaleContentToFit(), fitToContent()
  • dia.Paper - fitToContent() returns area (g.Rect) of the content
  • dia.Graph - add indirect option for getNeighbors(), 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() and getTargetElement() finds also indirect elements
  • dia.Link - add angle, keepGradient and ensureLegibility 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 and cell: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 accepts dx, 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() and divideAtLength()
  • 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()