This commit is contained in:
Clément GOUIN
2019-07-10 16:41:23 +02:00
parent 98a5d18a46
commit 86cace4b43
5 changed files with 157 additions and 12 deletions
+5 -5
View File
@@ -7,16 +7,16 @@
* [Install](#install)
* [CDN](#cdn)
* [Static script](#static-script)
* [Static scripts](#static-scripts)
* [NPM](#npm)
* [Build from sources](#build-from-sources)
* [Usage](#usage)
* [Node module](#node-module)
* [Html script](#script
* [Html script](#html-script)
## Install
### Static script
### Static scripts
Get the scripts from this repository `dist` folder
@@ -62,7 +62,7 @@ node build.sh
### Node module
```javascript
const diag = require('fa-diagrams');
const faDiagrams = require('fa-diagrams');
const data = {
options: {
@@ -91,7 +91,7 @@ const data = {
]
};
const svg = diag.compute(data); // string containing xml data
const svg = faDiagrams.compute(data); // string containing xml data
```
Will produce the following diagram :
+14 -4
View File
@@ -5142,8 +5142,7 @@
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"semver": {
"version": "5.7.0",
@@ -5379,7 +5378,8 @@
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"source-map-resolve": {
"version": "0.5.2",
@@ -5841,6 +5841,7 @@
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
"integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
"dev": true,
"requires": {
"commander": "~2.13.0",
"source-map": "~0.6.1"
@@ -5849,7 +5850,8 @@
"commander": {
"version": "2.13.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
"integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA=="
"integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
"dev": true
}
}
},
@@ -6184,6 +6186,14 @@
"async-limiter": "~1.0.0"
}
},
"xml-js": {
"version": "1.6.11",
"resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz",
"integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==",
"requires": {
"sax": "^1.2.4"
}
},
"xml-name-validator": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+1 -1
View File
@@ -28,7 +28,7 @@
},
"homepage": "https://github.com/Klemek/fa-diagrams#readme",
"dependencies": {
"xml-js": "^1.6.11"
},
"jest": {
"collectCoverageFrom": [
+134 -2
View File
@@ -1,12 +1,144 @@
const xml = require('xml-js');
let list = {};
try {
list = require('../svg_list.json');
}catch(err){
} catch (err) {
console.error('fa-diagrams: SVG list could not be loaded', err);
}
/**
* Merge resources by reading object keys and keeping reference value only if it's type is different from the source
* @param ref - reference object/value
* @param src - source object/value
* @returns {*}
*/
const merge = (ref, src) => {
if (typeof ref !== typeof src) {
return ref;
} else if (ref.length && !src.length) {
return ref;
} else if (ref.length && src.length) {
return src;
} else if (typeof ref === 'object') {
const out = {};
Object.keys(ref).forEach((key) => out[key] = merge(ref[key], src[key]));
return out;
} else {
return src;
}
};
const DEFAULT_OPTIONS = {};
const self = {
list: list
compute: (data) => {
const options = merge(DEFAULT_OPTIONS, data['options']);
/**
* @type {Object<string,{name: string, icon: string}>}
*/
const nodes = {};
const nodeList = (data['nodes'] || []).filter(n => n.name);
nodeList.forEach((n, i) => n.order = i);
nodeList.forEach(n => nodes[n.name] = n);
/**
* @type {[{from: string, to: string, direction: string?}]}
*/
let links = (data['links'] || []).filter(l => l.from && l.to);
links.filter(l => !nodes[l.from]).forEach(l => console.warn(`unknown source node "${l.from}"`));
links.filter(l => !nodes[l.to]).forEach(l => console.warn(`unknown destination node "${l.to}"`));
links = links.filter(l => nodes[l.from] && nodes[l.to]);
Object.values(nodes).forEach(node => {
node.beforeX = undefined;
node.beforeY = undefined;
});
links.forEach(link => {
if (link.direction) {
switch (link.direction) {
case 'up':
case 'top':
nodes[link.from].beforeY = link.to;
break;
case 'down':
case 'bottom':
nodes[link.to].beforeY = link.from;
break;
case 'left':
nodes[link.from].beforeX = link.to;
break;
case 'right':
nodes[link.to].beforeX = link.from;
break;
}
}
});
const grid = [[false]];
const expand = (y) => {
if (y)
grid.push(new Array(grid[0].length).fill(false));
else
grid.forEach(row => row.push(false));
};
const findPlace = (cx, cy, minx, miny) => {
const width = grid[0].length;
const height = grid.length;
for (let x = (cx || 0); x <= (cx || (width - 1)); x++) {
for (let y = (cy || 0); y <= (cy || (height - 1)); y++) {
if (!grid[y][x] && x >= (minx || -1) && y >= (miny || -1)) {
grid[y][x] = true;
return {x: x, y: y};
}
}
}
expand(height < width);
return findPlace(cx, cy, minx, miny);
};
const updateLinked = node1 => node2 => {
let p;
if (node2.beforeX === node1.name) {
if (!node2.beforeY) {
p = findPlace(null, node1.y, node1.x + 1, null);
} else if (nodes[node2.beforeY].x) {
p = findPlace(nodes[node2.beforeY].x, node1.y, null, null);
}
}
if (node2.beforeY === node1.name) {
if (!node2.beforeX) {
p = findPlace(node1.x, null, null, node1.y + 1);
} else if (nodes[node2.beforeX].y) {
p = findPlace(node1.x, nodes[node2.beforeX].y, null, null);
}
}
if (p) {
node2.x = p.x;
node2.y = p.y;
Object.values(nodes).forEach(updateLinked(node2));
}
};
let first;
while ((first = Object.values(nodes).filter(n => n.x === undefined && !n.beforeX && !n.beforeY).sort((n1, n2) => n1.order - n2.order)).length) {
const node = first[0];
const p = findPlace();
node.x = p.x;
node.y = p.y;
Object.values(nodes).forEach(updateLinked(node));
}
console.log(JSON.stringify(nodes, null, 2));
}
};
module.exports = self; // Node
+3
View File
@@ -0,0 +1,3 @@
test('sample test', () => {
});