diff --git a/demos/demo11/index.tsx b/demos/demo11/index.tsx new file mode 100644 index 0000000..5f8a438 --- /dev/null +++ b/demos/demo11/index.tsx @@ -0,0 +1,68 @@ +import { + DiagramEngine, + DefaultNodeFactory, + DefaultLinkFactory, + DiagramModel, + DefaultNodeModel, + LinkModel, + DefaultPortModel, + DiagramWidget +} from "../../src/main"; +import * as React from "react"; + +/** + * + * Simple stress test of the system plus zoom to fit function + * + * @Author Dylan Vorster + */ +export default () => { + //1) setup the diagram engine + var engine = new DiagramEngine(); + engine.registerNodeFactory(new DefaultNodeFactory()); + engine.registerLinkFactory(new DefaultLinkFactory()); + + function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) { + //3-A) create a default node + var node1 = new DefaultNodeModel("Node 1", "rgb(0,192,255)"); + var port1 = node1.addPort(new DefaultPortModel(false, "out-1", "Out")); + node1.x = 100 + offsetX; + node1.y = 100 + offsetY; + + //3-B) create another default node + var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)"); + var port2 = node2.addPort(new DefaultPortModel(true, "in-1", "IN")); + node2.x = 200 + offsetX; + node2.y = 100 + offsetY; + + //3-C) link the 2 nodes together + var link1 = new LinkModel(); + link1.setSourcePort(port1); + link1.setTargetPort(port2); + + //4) add the models to the root graph + model.addNode(node1); + model.addNode(node2); + model.addLink(link1); + } + + //2) setup the diagram model + var model = new DiagramModel(); + + for (var i = 0; i < 8; i++) { + for (var j = 0; j < 8; j++) { + generateNodes(model, i * 200, j * 100); + } + } + + //5) load model into engine + engine.setDiagramModel(model); + + //6) render the diagram! + return ( +
+ + +
+ ); +}; diff --git a/demos/index.tsx b/demos/index.tsx index 468ef7e..e9295c2 100644 --- a/demos/index.tsx +++ b/demos/index.tsx @@ -12,6 +12,7 @@ import demo7 from "./demo7/index"; import demo8 from "./demo8/index"; import demo9 from "./demo9/index"; import demo10 from "./demo10/index"; +import demo11 from "./demo11/index"; import demoDagre from "./demo-dagre/index"; import {Toolkit} from "../src/Toolkit"; @@ -71,4 +72,7 @@ storiesOf("React Diagrams", module) }) .add("Programatically move nodes", () => { return demo10(); + }) + .add("Zoom to fit", () => { + return demo11(); }); diff --git a/src/DiagramEngine.ts b/src/DiagramEngine.ts index 026b0f6..39c9b1b 100644 --- a/src/DiagramEngine.ts +++ b/src/DiagramEngine.ts @@ -238,4 +238,14 @@ export class DiagramEngine extends BaseEntity { setMaxNumberPointsPerLink(max: number) { this.maxNumberPointsPerLink = max; } + + zoomToFit() { + const xFactor = this.canvas.clientWidth / this.canvas.scrollWidth; + const yFactor = this.canvas.clientHeight / this.canvas.scrollHeight; + const zoomFactor = xFactor < yFactor ? xFactor: yFactor; + + this.diagramModel.setZoomLevel(this.diagramModel.getZoomLevel() * zoomFactor); + this.diagramModel.setOffset(0, 0); + this.repaintCanvas(); + } } diff --git a/tests/__snapshots__/2.test.tsx.snap b/tests/__snapshots__/2.test.tsx.snap index fb3bc5a..89b9126 100644 --- a/tests/__snapshots__/2.test.tsx.snap +++ b/tests/__snapshots__/2.test.tsx.snap @@ -9285,3 +9285,7207 @@ exports[`Storyshots React Diagrams Simple Example 1`] = ` `; + +exports[`Storyshots React Diagrams Zoom to fit 1`] = ` +
+
+ +
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+
+
+ Node 1 +
+
+
+
+
+
+
+ Out +
+
+
+
+
+
+
+
+
+
+
+ Node 2 +
+
+
+
+
+
+
+ IN +
+
+
+
+
+
+
+
+
+ +
+`;