Working experimental version using markers

This commit is contained in:
Adrian Hall 2020-03-08 22:22:33 +00:00
parent 061045016f
commit 9aacc85a16
2 changed files with 287 additions and 3 deletions

View File

@ -0,0 +1,174 @@
import * as d3 from 'd3';
const ERMarkers = {
ONLY_ONE_START: 'ONLY_ONE_START',
ONLY_ONE_END: 'ONLY_ONE_END',
ZERO_OR_ONE_START: 'ZERO_OR_ONE_START',
ZERO_OR_ONE_END: 'ZERO_OR_ONE_END',
ONE_OR_MORE_START: 'ONE_OR_MORE_START',
ONE_OR_MORE_END: 'ONE_OR_MORE_END',
ZERO_OR_MORE_START: 'ZERO_OR_MORE_START',
ZERO_OR_MORE_END: 'ZERO_OR_MORE_END'
};
/**
* Put the markers into the svg DOM for use in paths
*/
const insertMarkers = function(elem, conf) {
let marker;
const markerWidth =
elem
.append('defs')
.append('marker')
.attr('id', ERMarkers.ONLY_ONE_START)
.attr('refX', 0)
.attr('refY', 9)
.attr('markerWidth', 18)
.attr('markerHeight', 18)
.attr('orient', 'auto')
.append('path')
.attr('stroke', conf.stroke)
.attr('fill', 'none')
.attr('d', 'M9,0 L9,18 M15,0 L15,18');
elem
.append('defs')
.append('marker')
.attr('id', ERMarkers.ONLY_ONE_END)
.attr('refX', 18)
.attr('refY', 9)
.attr('markerWidth', 18)
.attr('markerHeight', 18)
.attr('orient', 'auto')
.append('path')
.attr('stroke', conf.stroke)
.attr('fill', 'none')
.attr('d', 'M3,0 L3,18 M9,0 L9,18');
marker = elem
.append('defs')
.append('marker')
.attr('id', ERMarkers.ZERO_OR_ONE_START)
.attr('refX', 0)
.attr('refY', 9)
.attr('markerWidth', 30)
.attr('markerHeight', 18)
.attr('orient', 'auto');
marker
.append('circle')
.attr('stroke', conf.stroke)
.attr('fill', 'white')
.attr('cx', 21)
.attr('cy', 9)
.attr('r', 6);
marker
.append('path')
.attr('stroke', conf.stroke)
.attr('fill', 'none')
.attr('d', 'M9,0 L9,18');
marker = elem
.append('defs')
.append('marker')
.attr('id', ERMarkers.ZERO_OR_ONE_END)
.attr('refX', 30)
.attr('refY', 9)
.attr('markerWidth', 30)
.attr('markerHeight', 18)
.attr('orient', 'auto');
marker
.append('circle')
.attr('stroke', conf.stroke)
.attr('fill', 'white')
.attr('cx', 9)
.attr('cy', 9)
.attr('r', 6);
marker
.append('path')
.attr('stroke', conf.stroke)
.attr('fill', 'none')
.attr('d', 'M21,0 L21,18');
elem
.append('defs')
.append('marker')
.attr('id', ERMarkers.ONE_OR_MORE_START)
.attr('refX', 0)
.attr('refY', 9)
.attr('markerWidth', 18)
.attr('markerHeight', 18)
.attr('orient', 'auto')
.append('path')
.attr('stroke', conf.stroke)
.attr('fill', 'none')
.attr('d', 'M0,0 L9,9 L0,18 M15,0 L15,18');
elem
.append('defs')
.append('marker')
.attr('id', ERMarkers.ONE_OR_MORE_END)
.attr('refX', 18)
.attr('refY', 9)
.attr('markerWidth', 21)
.attr('markerHeight', 18)
.attr('orient', 'auto')
.append('path')
.attr('stroke', conf.stroke)
.attr('fill', 'none')
.attr('d', 'M3,0 L3,18 M18,0 L9,9 L18,18');
marker = elem
.append('defs')
.append('marker')
.attr('id', ERMarkers.ZERO_OR_MORE_START)
.attr('refX', 0)
.attr('refY', 9)
.attr('markerWidth', 30)
.attr('markerHeight', 18)
.attr('orient', 'auto');
marker
.append('circle')
.attr('stroke', conf.stroke)
.attr('fill', 'white')
.attr('cx', 21)
.attr('cy', 9)
.attr('r', 6);
marker
.append('path')
.attr('stroke', conf.stroke)
.attr('fill', 'none')
.attr('d', 'M0,0 L9,9 L0,18');
marker = elem
.append('defs')
.append('marker')
.attr('id', ERMarkers.ZERO_OR_MORE_END)
.attr('refX', 30)
.attr('refY', 9)
.attr('markerWidth', 30)
.attr('markerHeight', 18)
.attr('orient', 'auto');
marker
.append('circle')
.attr('stroke', conf.stroke)
.attr('fill', 'white')
.attr('cx', 9)
.attr('cy', 9)
.attr('r', 6);
marker
.append('path')
.attr('stroke', conf.stroke)
.attr('fill', 'none')
.attr('d', 'M30,0 L21,9 L30,18');
return;
};
export default {
ERMarkers,
insertMarkers
};

View File

@ -5,6 +5,7 @@ import erParser from './parser/erDiagram';
import dagre from 'dagre';
import { getConfig } from '../../config';
import { logger } from '../../logger';
import erMarkers from './erMarkers';
const conf = {};
export const setConf = function(cnf) {
@ -99,10 +100,119 @@ const addRelationships = function(relationships, g) {
const drawRelationships = function(diagram, relationships, g) {
relationships.forEach(function(rel) {
drawRelationship(diagram, rel, g);
//drawRelationship(diagram, rel, g);
drawRelationshipFromLayout(diagram, rel, g);
});
}; // drawRelationships
const drawRelationshipFromLayout = function(diagram, rel, g) {
// Find the edge relating to this relationship
const edge = g.edge({ v: rel.entityA, w: rel.entityB });
// Using it's points, generate a line function
edge.points = edge.points.filter(p => !Number.isNaN(p.y)); // TODO: why is necessary?
// Get a function that will generate the line path
const lineFunction = d3
.line()
.x(function(d) {
return d.x;
})
.y(function(d) {
return d.y;
})
.curve(d3.curveBasis);
// Append the line to the diagram node
const svgPath = diagram
.append('path')
.attr('d', lineFunction(edge.points))
.attr('stroke', conf.stroke)
.attr('fill', 'none');
// TODO: Understand this
let url = '';
if (conf.arrowMarkerAbsolute) {
url =
window.location.protocol +
'//' +
window.location.host +
window.location.pathname +
window.location.search;
url = url.replace(/\(/g, '\\(');
url = url.replace(/\)/g, '\\)');
}
// TODO: change the way enums are imported
// Decide which start and end markers it needs
switch (rel.cardinality) {
case erDb.Cardinality.ONLY_ONE_TO_ONE_OR_MORE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_END + ')');
break;
case erDb.Cardinality.ONLY_ONE_TO_ZERO_OR_MORE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_END + ')');
break;
case erDb.Cardinality.ZERO_OR_ONE_TO_ZERO_OR_MORE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_END + ')');
break;
case erDb.Cardinality.ZERO_OR_ONE_TO_ONE_OR_MORE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_END + ')');
break;
case erDb.Cardinality.ONE_OR_MORE_TO_ONLY_ONE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_END + ')');
break;
case erDb.Cardinality.ZERO_OR_MORE_TO_ONLY_ONE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_END + ')');
break;
case erDb.Cardinality.ZERO_OR_MORE_TO_ZERO_OR_ONE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_END + ')');
break;
case erDb.Cardinality.ONE_OR_MORE_TO_ZERO_OR_ONE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_END + ')');
break;
case erDb.Cardinality.ZERO_OR_ONE_TO_ONLY_ONE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_END + ')');
break;
case erDb.Cardinality.ONLY_ONE_TO_ONLY_ONE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_END + ')');
break;
case erDb.Cardinality.ONLY_ONE_TO_ZERO_OR_ONE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_END + ')');
break;
case erDb.Cardinality.ZERO_OR_ONE_TO_ZERO_OR_ONE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_END + ')');
break;
case erDb.Cardinality.ZERO_OR_MORE_TO_ZERO_OR_MORE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_END + ')');
break;
case erDb.Cardinality.ZERO_OR_MORE_TO_ONE_OR_MORE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_END + ')');
break;
case erDb.Cardinality.ONE_OR_MORE_TO_ZERO_OR_MORE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_END + ')');
break;
case erDb.Cardinality.ONE_OR_MORE_TO_ONE_OR_MORE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_START + ')');
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_END + ')');
break;
}
};
const drawRelationship = function(diagram, relationship, g) {
// Set the from and to co-ordinates using the graph vertices
@ -406,7 +516,7 @@ export const draw = function(text, id) {
const diagram = d3.select(`[id='${id}']`);
// Add cardinality 'marker' definitions to the svg
//insertMarkers(diagram);
erMarkers.insertMarkers(diagram, conf);
// Create the graph
let g;
@ -451,8 +561,8 @@ export const draw = function(text, id) {
//const element = d3.select('#' + id + ' g');
//render(element, g);
//drawFeet(diagram, relationships, g);
drawRelationships(diagram, relationships, g);
drawFeet(diagram, relationships, g);
drawEntities(diagram, entities, g, id);
const padding = 8;