From 86cace4b43e4f367796a2dd9baa891b94f091f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20GOUIN?= Date: Wed, 10 Jul 2019 16:41:23 +0200 Subject: [PATCH] tmp dev --- README.md | 10 ++-- package-lock.json | 18 ++++-- package.json | 2 +- src/index.js | 136 ++++++++++++++++++++++++++++++++++++++++++++- test/index.test.js | 3 + 5 files changed, 157 insertions(+), 12 deletions(-) create mode 100644 test/index.test.js diff --git a/README.md b/README.md index 1062ae1..db4b85e 100644 --- a/README.md +++ b/README.md @@ -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 : diff --git a/package-lock.json b/package-lock.json index 8c43a1c..477a10b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 1630929..30d82e8 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ }, "homepage": "https://github.com/Klemek/fa-diagrams#readme", "dependencies": { - + "xml-js": "^1.6.11" }, "jest": { "collectCoverageFrom": [ diff --git a/src/index.js b/src/index.js index 5d0c29a..54ae428 100644 --- a/src/index.js +++ b/src/index.js @@ -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} + */ + 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 diff --git a/test/index.test.js b/test/index.test.js new file mode 100644 index 0000000..fd8fbfa --- /dev/null +++ b/test/index.test.js @@ -0,0 +1,3 @@ +test('sample test', () => { + +}); \ No newline at end of file