mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-22 00:40:22 +02:00
add implementation/realization edge type, fix arrow heads to be hollow
This commit is contained in:
@@ -469,6 +469,7 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph
|
|||||||
default:
|
default:
|
||||||
strokeClasses = '';
|
strokeClasses = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (edge.pattern) {
|
switch (edge.pattern) {
|
||||||
case 'solid':
|
case 'solid':
|
||||||
strokeClasses += ' edge-pattern-solid';
|
strokeClasses += ' edge-pattern-solid';
|
||||||
@@ -533,6 +534,9 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph
|
|||||||
case 'extension':
|
case 'extension':
|
||||||
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-extensionStart' + ')');
|
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-extensionStart' + ')');
|
||||||
break;
|
break;
|
||||||
|
case 'realization':
|
||||||
|
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-realizationStart' + ')');
|
||||||
|
break;
|
||||||
case 'composition':
|
case 'composition':
|
||||||
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-compositionStart' + ')');
|
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-compositionStart' + ')');
|
||||||
break;
|
break;
|
||||||
@@ -563,6 +567,9 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph
|
|||||||
case 'extension':
|
case 'extension':
|
||||||
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-extensionEnd' + ')');
|
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-extensionEnd' + ')');
|
||||||
break;
|
break;
|
||||||
|
case 'realization':
|
||||||
|
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-realizationEnd' + ')');
|
||||||
|
break;
|
||||||
case 'composition':
|
case 'composition':
|
||||||
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-compositionEnd' + ')');
|
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-compositionEnd' + ')');
|
||||||
break;
|
break;
|
||||||
|
@@ -2,6 +2,43 @@
|
|||||||
|
|
||||||
import { log } from '../logger.js';
|
import { log } from '../logger.js';
|
||||||
|
|
||||||
|
const getSvgParent = (elem) => {
|
||||||
|
let container = elem;
|
||||||
|
|
||||||
|
// the intent here is to find the first parent element that is NOT part of the SVG element
|
||||||
|
// I know there has to be a better way, but could not find one that worked
|
||||||
|
// tried using checking if elem was instanceof SVGGraphicsElement or SVGElement, but it failed to detect correctly
|
||||||
|
if (container._groups) {
|
||||||
|
container = container._groups[0][0];
|
||||||
|
}
|
||||||
|
if (container.tagName.toLowerCase() === 'g') {
|
||||||
|
container = container.parentElement;
|
||||||
|
}
|
||||||
|
if (container.localName.toLowerCase() === 'svg') {
|
||||||
|
container = container.parentElement;
|
||||||
|
}
|
||||||
|
return container;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getBackgroundColor = (elem) => {
|
||||||
|
let parent = getSvgParent(elem);
|
||||||
|
|
||||||
|
let backgroundColor;
|
||||||
|
while (parent && parent.tagName.toLowerCase() !== 'body') {
|
||||||
|
if(parent instanceof Element) {
|
||||||
|
const computedStyle = getComputedStyle(parent);
|
||||||
|
backgroundColor = computedStyle.backgroundColor;
|
||||||
|
|
||||||
|
if (backgroundColor !== 'rgba(0, 0, 0, 0)') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent = parent.parentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return backgroundColor === 'rgba(0, 0, 0, 0)' ? 'white' : backgroundColor;
|
||||||
|
};
|
||||||
|
|
||||||
// Only add the number of markers that the diagram needs
|
// Only add the number of markers that the diagram needs
|
||||||
const insertMarkers = (elem, markerArray, type, id) => {
|
const insertMarkers = (elem, markerArray, type, id) => {
|
||||||
markerArray.forEach((markerName) => {
|
markerArray.forEach((markerName) => {
|
||||||
@@ -11,6 +48,8 @@ const insertMarkers = (elem, markerArray, type, id) => {
|
|||||||
|
|
||||||
const extension = (elem, type, id) => {
|
const extension = (elem, type, id) => {
|
||||||
log.trace('Making markers for ', id);
|
log.trace('Making markers for ', id);
|
||||||
|
let backgroundColor = getBackgroundColor(elem);
|
||||||
|
|
||||||
elem
|
elem
|
||||||
.append('defs')
|
.append('defs')
|
||||||
.append('marker')
|
.append('marker')
|
||||||
@@ -22,7 +61,8 @@ const extension = (elem, type, id) => {
|
|||||||
.attr('markerHeight', 240)
|
.attr('markerHeight', 240)
|
||||||
.attr('orient', 'auto')
|
.attr('orient', 'auto')
|
||||||
.append('path')
|
.append('path')
|
||||||
.attr('d', 'M 1,7 L18,13 V 1 Z');
|
.attr('d', 'M 1,7 L18,13 V 2 Z')
|
||||||
|
.attr('fill', backgroundColor);
|
||||||
|
|
||||||
elem
|
elem
|
||||||
.append('defs')
|
.append('defs')
|
||||||
@@ -35,7 +75,41 @@ const extension = (elem, type, id) => {
|
|||||||
.attr('markerHeight', 28)
|
.attr('markerHeight', 28)
|
||||||
.attr('orient', 'auto')
|
.attr('orient', 'auto')
|
||||||
.append('path')
|
.append('path')
|
||||||
.attr('d', 'M 1,1 V 13 L18,7 Z'); // this is actual shape for arrowhead
|
.attr('d', 'M 1,1 V 13 L18,7 Z')
|
||||||
|
.attr('fill', backgroundColor); // this is actual shape for arrowhead
|
||||||
|
};
|
||||||
|
|
||||||
|
const realization = (elem, type, id) => {
|
||||||
|
log.trace('Making markers for ', id);
|
||||||
|
let backgroundColor = getBackgroundColor(elem);
|
||||||
|
|
||||||
|
elem
|
||||||
|
.append('defs')
|
||||||
|
.append('marker')
|
||||||
|
.attr('id', type + '-realizationStart')
|
||||||
|
.attr('class', 'marker realization ' + type)
|
||||||
|
.attr('refX', 0)
|
||||||
|
.attr('refY', 7)
|
||||||
|
.attr('markerWidth', 190)
|
||||||
|
.attr('markerHeight', 240)
|
||||||
|
.attr('orient', 'auto')
|
||||||
|
.append('path')
|
||||||
|
.attr('d', 'M 1,7 L18,13 V 2 Z')
|
||||||
|
.attr('fill', backgroundColor);
|
||||||
|
|
||||||
|
elem
|
||||||
|
.append('defs')
|
||||||
|
.append('marker')
|
||||||
|
.attr('id', type + '-realizationEnd')
|
||||||
|
.attr('class', 'marker realization ' + type)
|
||||||
|
.attr('refX', 19)
|
||||||
|
.attr('refY', 7)
|
||||||
|
.attr('markerWidth', 20)
|
||||||
|
.attr('markerHeight', 28)
|
||||||
|
.attr('orient', 'auto')
|
||||||
|
.append('path')
|
||||||
|
.attr('d', 'M 1,1 V 13 L18,7 Z')
|
||||||
|
.attr('fill', backgroundColor); // this is actual shape for arrowhead
|
||||||
};
|
};
|
||||||
|
|
||||||
const composition = (elem, type) => {
|
const composition = (elem, type) => {
|
||||||
@@ -265,6 +339,7 @@ const barb = (elem, type) => {
|
|||||||
// TODO rename the class diagram markers to something shape descriptive and semantic free
|
// TODO rename the class diagram markers to something shape descriptive and semantic free
|
||||||
const markers = {
|
const markers = {
|
||||||
extension,
|
extension,
|
||||||
|
realization,
|
||||||
composition,
|
composition,
|
||||||
aggregation,
|
aggregation,
|
||||||
dependency,
|
dependency,
|
||||||
|
@@ -362,6 +362,7 @@ export const relationType = {
|
|||||||
COMPOSITION: 2,
|
COMPOSITION: 2,
|
||||||
DEPENDENCY: 3,
|
DEPENDENCY: 3,
|
||||||
LOLLIPOP: 4,
|
LOLLIPOP: 4,
|
||||||
|
REALIZATION: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
const setupToolTips = function (element: Element) {
|
const setupToolTips = function (element: Element) {
|
||||||
|
@@ -361,7 +361,7 @@ export const draw = async function (text: string, id: string, _version: string,
|
|||||||
await render(
|
await render(
|
||||||
element,
|
element,
|
||||||
g,
|
g,
|
||||||
['aggregation', 'extension', 'composition', 'dependency', 'lollipop'],
|
['aggregation', 'extension', 'realization', 'composition', 'dependency', 'lollipop'],
|
||||||
'classDiagram',
|
'classDiagram',
|
||||||
id
|
id
|
||||||
);
|
);
|
||||||
@@ -413,6 +413,9 @@ function getArrowMarker(type: number) {
|
|||||||
case 4:
|
case 4:
|
||||||
marker = 'lollipop';
|
marker = 'lollipop';
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
marker = 'realization';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
marker = 'none';
|
marker = 'none';
|
||||||
}
|
}
|
||||||
|
@@ -124,7 +124,7 @@ Function arguments are optional: 'call <callback_name>()' simply executes 'callb
|
|||||||
<*>"_top" return 'LINK_TARGET';
|
<*>"_top" return 'LINK_TARGET';
|
||||||
|
|
||||||
<*>\s*\<\| return 'EXTENSION';
|
<*>\s*\<\| return 'EXTENSION';
|
||||||
<*>\s*\|\> return 'EXTENSION';
|
<*>\s*\|\> return 'REALIZATION';
|
||||||
<*>\s*\> return 'DEPENDENCY';
|
<*>\s*\> return 'DEPENDENCY';
|
||||||
<*>\s*\< return 'DEPENDENCY';
|
<*>\s*\< return 'DEPENDENCY';
|
||||||
<*>\s*\* return 'COMPOSITION';
|
<*>\s*\* return 'COMPOSITION';
|
||||||
@@ -370,6 +370,7 @@ relation
|
|||||||
relationType
|
relationType
|
||||||
: AGGREGATION { $$=yy.relationType.AGGREGATION;}
|
: AGGREGATION { $$=yy.relationType.AGGREGATION;}
|
||||||
| EXTENSION { $$=yy.relationType.EXTENSION;}
|
| EXTENSION { $$=yy.relationType.EXTENSION;}
|
||||||
|
| REALIZATION { $$=yy.relationType.REALIZATION;}
|
||||||
| COMPOSITION { $$=yy.relationType.COMPOSITION;}
|
| COMPOSITION { $$=yy.relationType.COMPOSITION;}
|
||||||
| DEPENDENCY { $$=yy.relationType.DEPENDENCY;}
|
| DEPENDENCY { $$=yy.relationType.DEPENDENCY;}
|
||||||
| LOLLIPOP { $$=yy.relationType.LOLLIPOP;}
|
| LOLLIPOP { $$=yy.relationType.LOLLIPOP;}
|
||||||
|
@@ -9,6 +9,8 @@ export const drawEdge = function (elem, path, relation, conf, diagObj) {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case diagObj.db.relationType.AGGREGATION:
|
case diagObj.db.relationType.AGGREGATION:
|
||||||
return 'aggregation';
|
return 'aggregation';
|
||||||
|
case diagObj.db.relationType.REALIZATION:
|
||||||
|
return 'realization';
|
||||||
case diagObj.db.relationType.EXTENSION:
|
case diagObj.db.relationType.EXTENSION:
|
||||||
return 'extension';
|
return 'extension';
|
||||||
case diagObj.db.relationType.COMPOSITION:
|
case diagObj.db.relationType.COMPOSITION:
|
||||||
|
Reference in New Issue
Block a user