2020-04-25 17:01:20 +02:00
|
|
|
import { select } from 'd3';
|
2021-02-06 15:56:05 +05:30
|
|
|
import { log } from '../logger'; // eslint-disable-line
|
2020-03-29 14:20:49 +02:00
|
|
|
import { labelHelper, updateNodeBounds, insertPolygonShape } from './shapes/util';
|
2020-05-27 20:41:59 +02:00
|
|
|
import { getConfig } from '../config';
|
2020-07-21 15:25:16 +02:00
|
|
|
import intersect from './intersect/index.js';
|
2020-04-25 17:01:20 +02:00
|
|
|
import createLabel from './createLabel';
|
2020-03-29 14:20:49 +02:00
|
|
|
import note from './shapes/note';
|
2020-08-13 21:06:33 +02:00
|
|
|
import { parseMember } from '../diagrams/class/svgDraw';
|
2020-03-08 09:49:41 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const question = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const w = bbox.width + node.padding;
|
|
|
|
const h = bbox.height + node.padding;
|
2020-05-16 19:58:22 +02:00
|
|
|
const s = w + h;
|
2020-03-18 22:08:19 +01:00
|
|
|
const points = [
|
|
|
|
{ x: s / 2, y: 0 },
|
|
|
|
{ x: s, y: -s / 2 },
|
|
|
|
{ x: s / 2, y: -s },
|
|
|
|
{ x: 0, y: -s / 2 }
|
|
|
|
];
|
|
|
|
|
2021-02-06 15:56:05 +05:30
|
|
|
log.info('Question main (Circle)');
|
2020-05-30 18:04:46 +02:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const questionElem = insertPolygonShape(shapeSvg, s, s, points);
|
2021-01-23 18:10:21 +01:00
|
|
|
questionElem.attr('style', node.style);
|
2020-03-18 22:08:19 +01:00
|
|
|
updateNodeBounds(node, questionElem);
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
node.intersect = function(point) {
|
2021-02-06 15:56:05 +05:30
|
|
|
log.warn('Intersect called');
|
2020-05-16 19:58:22 +02:00
|
|
|
return intersect.polygon(node, points, point);
|
2020-03-18 22:08:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
|
|
|
|
|
|
|
const hexagon = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const f = 4;
|
|
|
|
const h = bbox.height + node.padding;
|
|
|
|
const m = h / f;
|
|
|
|
const w = bbox.width + 2 * m + node.padding;
|
|
|
|
const points = [
|
|
|
|
{ x: m, y: 0 },
|
|
|
|
{ x: w - m, y: 0 },
|
|
|
|
{ x: w, y: -h / 2 },
|
|
|
|
{ x: w - m, y: -h },
|
|
|
|
{ x: m, y: -h },
|
|
|
|
{ x: 0, y: -h / 2 }
|
|
|
|
];
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const hex = insertPolygonShape(shapeSvg, w, h, points);
|
2021-01-23 18:10:21 +01:00
|
|
|
hex.attr('style', node.style);
|
2020-03-18 22:08:19 +01:00
|
|
|
updateNodeBounds(node, hex);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2021-01-24 21:33:15 +01:00
|
|
|
return intersect.polygon(node, points, point);
|
2020-03-18 22:08:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
|
|
|
|
|
|
|
const rect_left_inv_arrow = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const w = bbox.width + node.padding;
|
|
|
|
const h = bbox.height + node.padding;
|
|
|
|
const points = [
|
|
|
|
{ x: -h / 2, y: 0 },
|
|
|
|
{ x: w, y: 0 },
|
|
|
|
{ x: w, y: -h },
|
|
|
|
{ x: -h / 2, y: -h },
|
|
|
|
{ x: 0, y: -h / 2 }
|
|
|
|
];
|
|
|
|
|
|
|
|
const el = insertPolygonShape(shapeSvg, w, h, points);
|
2021-01-23 18:10:21 +01:00
|
|
|
el.attr('style', node.style);
|
2021-01-24 21:33:15 +01:00
|
|
|
|
|
|
|
node.width = w + h;
|
|
|
|
node.height = h;
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2021-01-24 21:33:15 +01:00
|
|
|
return intersect.polygon(node, points, point);
|
2020-03-18 22:08:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const lean_right = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const w = bbox.width + node.padding;
|
|
|
|
const h = bbox.height + node.padding;
|
|
|
|
const points = [
|
|
|
|
{ x: (-2 * h) / 6, y: 0 },
|
|
|
|
{ x: w - h / 6, y: 0 },
|
|
|
|
{ x: w + (2 * h) / 6, y: -h },
|
|
|
|
{ x: h / 6, y: -h }
|
|
|
|
];
|
|
|
|
|
|
|
|
const el = insertPolygonShape(shapeSvg, w, h, points);
|
2021-01-23 18:10:21 +01:00
|
|
|
el.attr('style', node.style);
|
2020-03-18 22:08:19 +01:00
|
|
|
updateNodeBounds(node, el);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2021-01-24 21:33:15 +01:00
|
|
|
return intersect.polygon(node, points, point);
|
2020-03-18 22:08:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
|
|
|
|
|
|
|
const lean_left = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const w = bbox.width + node.padding;
|
|
|
|
const h = bbox.height + node.padding;
|
|
|
|
const points = [
|
|
|
|
{ x: (2 * h) / 6, y: 0 },
|
|
|
|
{ x: w + h / 6, y: 0 },
|
|
|
|
{ x: w - (2 * h) / 6, y: -h },
|
|
|
|
{ x: -h / 6, y: -h }
|
|
|
|
];
|
|
|
|
|
|
|
|
const el = insertPolygonShape(shapeSvg, w, h, points);
|
2021-01-23 18:10:21 +01:00
|
|
|
el.attr('style', node.style);
|
2020-03-18 22:08:19 +01:00
|
|
|
updateNodeBounds(node, el);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2021-01-24 21:33:15 +01:00
|
|
|
return intersect.polygon(node, points, point);
|
2020-03-18 22:08:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
|
|
|
|
|
|
|
const trapezoid = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const w = bbox.width + node.padding;
|
|
|
|
const h = bbox.height + node.padding;
|
|
|
|
const points = [
|
|
|
|
{ x: (-2 * h) / 6, y: 0 },
|
|
|
|
{ x: w + (2 * h) / 6, y: 0 },
|
|
|
|
{ x: w - h / 6, y: -h },
|
|
|
|
{ x: h / 6, y: -h }
|
|
|
|
];
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const el = insertPolygonShape(shapeSvg, w, h, points);
|
2021-01-23 18:10:21 +01:00
|
|
|
el.attr('style', node.style);
|
2020-03-18 22:08:19 +01:00
|
|
|
updateNodeBounds(node, el);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2021-01-24 21:33:15 +01:00
|
|
|
return intersect.polygon(node, points, point);
|
2020-03-18 22:08:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
|
|
|
|
|
|
|
const inv_trapezoid = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const w = bbox.width + node.padding;
|
|
|
|
const h = bbox.height + node.padding;
|
|
|
|
const points = [
|
|
|
|
{ x: h / 6, y: 0 },
|
|
|
|
{ x: w - h / 6, y: 0 },
|
|
|
|
{ x: w + (2 * h) / 6, y: -h },
|
|
|
|
{ x: (-2 * h) / 6, y: -h }
|
|
|
|
];
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const el = insertPolygonShape(shapeSvg, w, h, points);
|
2021-01-23 18:10:21 +01:00
|
|
|
el.attr('style', node.style);
|
2020-03-18 22:08:19 +01:00
|
|
|
updateNodeBounds(node, el);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2021-01-24 21:33:15 +01:00
|
|
|
return intersect.polygon(node, points, point);
|
2020-03-18 22:08:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const rect_right_inv_arrow = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const w = bbox.width + node.padding;
|
|
|
|
const h = bbox.height + node.padding;
|
|
|
|
const points = [
|
|
|
|
{ x: 0, y: 0 },
|
|
|
|
{ x: w + h / 2, y: 0 },
|
|
|
|
{ x: w, y: -h / 2 },
|
|
|
|
{ x: w + h / 2, y: -h },
|
|
|
|
{ x: 0, y: -h }
|
|
|
|
];
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const el = insertPolygonShape(shapeSvg, w, h, points);
|
2021-01-23 18:10:21 +01:00
|
|
|
el.attr('style', node.style);
|
2020-03-18 22:08:19 +01:00
|
|
|
updateNodeBounds(node, el);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2021-01-24 21:33:15 +01:00
|
|
|
return intersect.polygon(node, points, point);
|
2020-03-18 22:08:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const cylinder = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const w = bbox.width + node.padding;
|
|
|
|
const rx = w / 2;
|
|
|
|
const ry = rx / (2.5 + w / 50);
|
|
|
|
const h = bbox.height + ry + node.padding;
|
|
|
|
|
|
|
|
const shape =
|
|
|
|
'M 0,' +
|
|
|
|
ry +
|
|
|
|
' a ' +
|
|
|
|
rx +
|
|
|
|
',' +
|
|
|
|
ry +
|
|
|
|
' 0,0,0 ' +
|
|
|
|
w +
|
|
|
|
' 0 a ' +
|
|
|
|
rx +
|
|
|
|
',' +
|
|
|
|
ry +
|
|
|
|
' 0,0,0 ' +
|
|
|
|
-w +
|
|
|
|
' 0 l 0,' +
|
|
|
|
h +
|
|
|
|
' a ' +
|
|
|
|
rx +
|
|
|
|
',' +
|
|
|
|
ry +
|
|
|
|
' 0,0,0 ' +
|
|
|
|
w +
|
|
|
|
' 0 l 0,' +
|
|
|
|
-h;
|
|
|
|
|
|
|
|
const el = shapeSvg
|
|
|
|
.attr('label-offset-y', ry)
|
|
|
|
.insert('path', ':first-child')
|
2021-01-23 18:10:21 +01:00
|
|
|
.attr('style', node.style)
|
2020-03-18 22:08:19 +01:00
|
|
|
.attr('d', shape)
|
|
|
|
.attr('transform', 'translate(' + -w / 2 + ',' + -(h / 2 + ry) + ')');
|
|
|
|
|
|
|
|
updateNodeBounds(node, el);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
|
|
|
const pos = intersect.rect(node, point);
|
|
|
|
const x = pos.x - node.x;
|
|
|
|
|
|
|
|
if (
|
|
|
|
rx != 0 &&
|
|
|
|
(Math.abs(x) < node.width / 2 ||
|
|
|
|
(Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry))
|
|
|
|
) {
|
|
|
|
// ellipsis equation: x*x / a*a + y*y / b*b = 1
|
|
|
|
// solve for y to get adjustion value for pos.y
|
|
|
|
let y = ry * ry * (1 - (x * x) / (rx * rx));
|
|
|
|
if (y != 0) y = Math.sqrt(y);
|
|
|
|
y = ry - y;
|
|
|
|
if (point.y - node.y > 0) y = -y;
|
|
|
|
|
|
|
|
pos.y += y;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pos;
|
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
|
|
|
|
|
|
|
const rect = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, 'node ' + node.classes, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
2021-02-06 15:56:05 +05:30
|
|
|
log.trace('Classes = ', node.classes);
|
2020-03-18 22:08:19 +01:00
|
|
|
// add the rect
|
|
|
|
const rect = shapeSvg.insert('rect', ':first-child');
|
|
|
|
|
2020-03-08 09:49:41 +01:00
|
|
|
rect
|
2020-05-06 18:51:12 +02:00
|
|
|
.attr('class', 'basic label-container')
|
2020-09-23 19:51:16 +02:00
|
|
|
.attr('style', node.style)
|
2020-03-08 09:49:41 +01:00
|
|
|
.attr('rx', node.rx)
|
|
|
|
.attr('ry', node.ry)
|
|
|
|
.attr('x', -bbox.width / 2 - halfPadding)
|
|
|
|
.attr('y', -bbox.height / 2 - halfPadding)
|
|
|
|
.attr('width', bbox.width + node.padding)
|
|
|
|
.attr('height', bbox.height + node.padding);
|
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
updateNodeBounds(node, rect);
|
2020-03-08 09:49:41 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
node.intersect = function(point) {
|
|
|
|
return intersect.rect(node, point);
|
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-04-25 17:01:20 +02:00
|
|
|
const rectWithTitle = (parent, node) => {
|
|
|
|
// const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, 'node ' + node.classes);
|
|
|
|
|
|
|
|
let classes;
|
|
|
|
if (!node.classes) {
|
|
|
|
classes = 'node default';
|
|
|
|
} else {
|
|
|
|
classes = 'node ' + node.classes;
|
|
|
|
}
|
|
|
|
// Add outer g element
|
|
|
|
const shapeSvg = parent
|
|
|
|
.insert('g')
|
|
|
|
.attr('class', classes)
|
2020-09-10 20:58:16 +02:00
|
|
|
.attr('id', node.domId || node.id);
|
2020-04-25 17:01:20 +02:00
|
|
|
|
|
|
|
// Create the title label and insert it after the rect
|
|
|
|
const rect = shapeSvg.insert('rect', ':first-child');
|
|
|
|
// const innerRect = shapeSvg.insert('rect');
|
|
|
|
const innerLine = shapeSvg.insert('line');
|
|
|
|
|
|
|
|
const label = shapeSvg.insert('g').attr('class', 'label');
|
|
|
|
|
2021-04-30 13:50:21 +02:00
|
|
|
const text2prim = node.labelText.flat ? node.labelText.flat() : node.labelText;
|
|
|
|
const text2 = typeof text2prim === 'object' ? text2prim[0] : text2prim;
|
2020-04-26 16:01:17 +02:00
|
|
|
|
2021-04-30 13:50:21 +02:00
|
|
|
log.info('Label text', text2);
|
|
|
|
|
|
|
|
const text = label.node().appendChild(createLabel(text2, node.labelStyle, true, true));
|
2020-05-27 20:41:59 +02:00
|
|
|
let bbox;
|
|
|
|
if (getConfig().flowchart.htmlLabels) {
|
|
|
|
const div = text.children[0];
|
|
|
|
const dv = select(text);
|
|
|
|
bbox = div.getBoundingClientRect();
|
|
|
|
dv.attr('width', bbox.width);
|
|
|
|
dv.attr('height', bbox.height);
|
|
|
|
}
|
2021-02-06 15:56:05 +05:30
|
|
|
log.info('Text 2', text2);
|
2020-04-26 16:01:17 +02:00
|
|
|
const textRows = text2.slice(1, text2.length);
|
2020-04-25 17:01:20 +02:00
|
|
|
let titleBox = text.getBBox();
|
|
|
|
const descr = label
|
|
|
|
.node()
|
2021-04-30 13:50:21 +02:00
|
|
|
.appendChild(
|
|
|
|
createLabel(textRows.join ? textRows.join('<br/>') : textRows, node.labelStyle, true, true)
|
|
|
|
);
|
2020-04-25 17:01:20 +02:00
|
|
|
|
2020-05-27 22:18:59 +02:00
|
|
|
if (getConfig().flowchart.htmlLabels) {
|
|
|
|
const div = descr.children[0];
|
|
|
|
const dv = select(descr);
|
|
|
|
bbox = div.getBoundingClientRect();
|
|
|
|
dv.attr('width', bbox.width);
|
|
|
|
dv.attr('height', bbox.height);
|
|
|
|
}
|
|
|
|
// bbox = label.getBBox();
|
2021-02-06 15:56:05 +05:30
|
|
|
// log.info(descr);
|
2020-04-25 17:01:20 +02:00
|
|
|
const halfPadding = node.padding / 2;
|
2020-05-27 22:18:59 +02:00
|
|
|
select(descr).attr(
|
|
|
|
'transform',
|
|
|
|
'translate( ' +
|
|
|
|
// (titleBox.width - bbox.width) / 2 +
|
|
|
|
(bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) +
|
|
|
|
', ' +
|
|
|
|
(titleBox.height + halfPadding + 5) +
|
|
|
|
')'
|
|
|
|
);
|
|
|
|
select(text).attr(
|
|
|
|
'transform',
|
|
|
|
'translate( ' +
|
|
|
|
// (titleBox.width - bbox.width) / 2 +
|
|
|
|
(bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) +
|
|
|
|
', ' +
|
|
|
|
0 +
|
|
|
|
')'
|
|
|
|
);
|
2020-04-25 17:01:20 +02:00
|
|
|
// Get the size of the label
|
|
|
|
|
|
|
|
// Bounding box for title and text
|
2020-05-27 20:41:59 +02:00
|
|
|
bbox = label.node().getBBox();
|
2020-04-25 17:01:20 +02:00
|
|
|
|
|
|
|
// Center the label
|
|
|
|
label.attr(
|
|
|
|
'transform',
|
|
|
|
'translate(' + -bbox.width / 2 + ', ' + (-bbox.height / 2 - halfPadding + 3) + ')'
|
|
|
|
);
|
|
|
|
|
|
|
|
rect
|
|
|
|
.attr('class', 'outer title-state')
|
|
|
|
.attr('x', -bbox.width / 2 - halfPadding)
|
|
|
|
.attr('y', -bbox.height / 2 - halfPadding)
|
|
|
|
.attr('width', bbox.width + node.padding)
|
|
|
|
.attr('height', bbox.height + node.padding);
|
2020-04-26 10:07:25 +02:00
|
|
|
|
2020-04-25 17:01:20 +02:00
|
|
|
innerLine
|
|
|
|
.attr('class', 'divider')
|
|
|
|
.attr('x1', -bbox.width / 2 - halfPadding)
|
|
|
|
.attr('x2', bbox.width / 2 + halfPadding)
|
|
|
|
.attr('y1', -bbox.height / 2 - halfPadding + titleBox.height + halfPadding)
|
|
|
|
.attr('y2', -bbox.height / 2 - halfPadding + titleBox.height + halfPadding);
|
|
|
|
|
|
|
|
updateNodeBounds(node, rect);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
|
|
|
return intersect.rect(node, point);
|
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const stadium = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
|
|
|
|
const h = bbox.height + node.padding;
|
|
|
|
const w = bbox.width + h / 4 + node.padding;
|
|
|
|
|
|
|
|
// add the rect
|
|
|
|
const rect = shapeSvg
|
|
|
|
.insert('rect', ':first-child')
|
2021-01-23 18:10:21 +01:00
|
|
|
.attr('style', node.style)
|
2020-03-18 22:08:19 +01:00
|
|
|
.attr('rx', h / 2)
|
|
|
|
.attr('ry', h / 2)
|
|
|
|
.attr('x', -w / 2)
|
|
|
|
.attr('y', -h / 2)
|
|
|
|
.attr('width', w)
|
|
|
|
.attr('height', h);
|
|
|
|
|
|
|
|
updateNodeBounds(node, rect);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
|
|
|
return intersect.rect(node, point);
|
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const circle = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, undefined, true);
|
2020-03-18 22:08:19 +01:00
|
|
|
const circle = shapeSvg.insert('circle', ':first-child');
|
|
|
|
|
|
|
|
// center the circle around its coordinate
|
|
|
|
circle
|
2021-01-23 18:10:21 +01:00
|
|
|
.attr('style', node.style)
|
2020-03-18 22:08:19 +01:00
|
|
|
.attr('rx', node.rx)
|
|
|
|
.attr('ry', node.ry)
|
|
|
|
.attr('r', bbox.width / 2 + halfPadding)
|
|
|
|
.attr('width', bbox.width + node.padding)
|
|
|
|
.attr('height', bbox.height + node.padding);
|
|
|
|
|
2021-02-06 15:56:05 +05:30
|
|
|
log.info('Circle main');
|
2020-05-30 18:04:46 +02:00
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
updateNodeBounds(node, circle);
|
2020-03-08 09:49:41 +01:00
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2021-02-06 15:56:05 +05:30
|
|
|
log.info('Circle intersect', node, bbox.width / 2 + halfPadding, point);
|
2020-05-30 18:04:46 +02:00
|
|
|
return intersect.circle(node, bbox.width / 2 + halfPadding, point);
|
2020-03-08 09:49:41 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
2020-05-03 21:52:44 +02:00
|
|
|
|
|
|
|
const subroutine = (parent, node) => {
|
2020-05-27 20:41:59 +02:00
|
|
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
2020-05-03 21:52:44 +02:00
|
|
|
|
|
|
|
const w = bbox.width + node.padding;
|
|
|
|
const h = bbox.height + node.padding;
|
|
|
|
const points = [
|
|
|
|
{ x: 0, y: 0 },
|
|
|
|
{ x: w, y: 0 },
|
|
|
|
{ x: w, y: -h },
|
|
|
|
{ x: 0, y: -h },
|
|
|
|
{ x: 0, y: 0 },
|
|
|
|
{ x: -8, y: 0 },
|
|
|
|
{ x: w + 8, y: 0 },
|
|
|
|
{ x: w + 8, y: -h },
|
|
|
|
{ x: -8, y: -h },
|
|
|
|
{ x: -8, y: 0 }
|
|
|
|
];
|
2021-01-23 18:10:21 +01:00
|
|
|
|
2020-05-03 21:52:44 +02:00
|
|
|
const el = insertPolygonShape(shapeSvg, w, h, points);
|
2021-01-23 18:10:21 +01:00
|
|
|
el.attr('style', node.style);
|
2020-05-03 21:52:44 +02:00
|
|
|
updateNodeBounds(node, el);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2021-01-24 21:33:15 +01:00
|
|
|
return intersect.polygon(node, points, point);
|
2020-05-03 21:52:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
|
|
|
|
2020-03-25 20:16:27 +01:00
|
|
|
const start = (parent, node) => {
|
|
|
|
const shapeSvg = parent
|
|
|
|
.insert('g')
|
|
|
|
.attr('class', 'node default')
|
2020-09-10 20:58:16 +02:00
|
|
|
.attr('id', node.domId || node.id);
|
2020-03-25 20:16:27 +01:00
|
|
|
const circle = shapeSvg.insert('circle', ':first-child');
|
|
|
|
|
|
|
|
// center the circle around its coordinate
|
|
|
|
circle
|
|
|
|
.attr('class', 'state-start')
|
|
|
|
.attr('r', 7)
|
|
|
|
.attr('width', 14)
|
|
|
|
.attr('height', 14);
|
|
|
|
|
|
|
|
updateNodeBounds(node, circle);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2020-05-17 09:34:56 +02:00
|
|
|
return intersect.circle(node, 7, point);
|
2020-03-25 20:16:27 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
2020-04-26 10:07:25 +02:00
|
|
|
|
2020-04-26 12:57:45 +02:00
|
|
|
const forkJoin = (parent, node, dir) => {
|
2020-04-26 10:07:25 +02:00
|
|
|
const shapeSvg = parent
|
|
|
|
.insert('g')
|
|
|
|
.attr('class', 'node default')
|
2020-09-10 20:58:16 +02:00
|
|
|
.attr('id', node.domId || node.id);
|
2020-04-26 10:07:25 +02:00
|
|
|
|
2020-04-26 12:57:45 +02:00
|
|
|
let width = 70;
|
|
|
|
let height = 10;
|
|
|
|
|
|
|
|
if (dir === 'LR') {
|
|
|
|
width = 10;
|
|
|
|
height = 70;
|
|
|
|
}
|
|
|
|
|
2020-04-26 10:07:25 +02:00
|
|
|
const shape = shapeSvg
|
|
|
|
.append('rect')
|
|
|
|
.style('stroke', 'black')
|
|
|
|
.style('fill', 'black')
|
2020-04-26 12:57:45 +02:00
|
|
|
.attr('x', (-1 * width) / 2)
|
|
|
|
.attr('y', (-1 * height) / 2)
|
|
|
|
.attr('width', width)
|
|
|
|
.attr('height', height)
|
2020-04-26 10:07:25 +02:00
|
|
|
.attr('class', 'fork-join');
|
|
|
|
|
|
|
|
updateNodeBounds(node, shape);
|
|
|
|
node.height = node.height + node.padding / 2;
|
2020-04-26 12:57:45 +02:00
|
|
|
node.width = node.width + node.padding / 2;
|
2020-04-26 10:07:25 +02:00
|
|
|
node.intersect = function(point) {
|
|
|
|
return intersect.rect(node, point);
|
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
|
|
|
|
2020-03-28 13:59:41 +01:00
|
|
|
const end = (parent, node) => {
|
|
|
|
const shapeSvg = parent
|
|
|
|
.insert('g')
|
|
|
|
.attr('class', 'node default')
|
2020-09-10 20:58:16 +02:00
|
|
|
.attr('id', node.domId || node.id);
|
2020-03-28 13:59:41 +01:00
|
|
|
const innerCircle = shapeSvg.insert('circle', ':first-child');
|
|
|
|
const circle = shapeSvg.insert('circle', ':first-child');
|
|
|
|
|
|
|
|
circle
|
|
|
|
.attr('class', 'state-start')
|
|
|
|
.attr('r', 7)
|
|
|
|
.attr('width', 14)
|
|
|
|
.attr('height', 14);
|
|
|
|
|
|
|
|
innerCircle
|
|
|
|
.attr('class', 'state-end')
|
|
|
|
.attr('r', 5)
|
|
|
|
.attr('width', 10)
|
|
|
|
.attr('height', 10);
|
|
|
|
|
|
|
|
updateNodeBounds(node, circle);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
2020-05-17 09:34:56 +02:00
|
|
|
return intersect.circle(node, 7, point);
|
2020-03-28 13:59:41 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
2020-03-08 09:49:41 +01:00
|
|
|
|
2020-07-21 15:25:16 +02:00
|
|
|
const class_box = (parent, node) => {
|
|
|
|
const halfPadding = node.padding / 2;
|
|
|
|
const rowPadding = 4;
|
|
|
|
const lineHeight = 8;
|
|
|
|
|
|
|
|
let classes;
|
|
|
|
if (!node.classes) {
|
|
|
|
classes = 'node default';
|
|
|
|
} else {
|
|
|
|
classes = 'node ' + node.classes;
|
|
|
|
}
|
|
|
|
// Add outer g element
|
2020-09-12 10:56:23 +02:00
|
|
|
const shapeSvg = parent
|
2020-07-21 15:25:16 +02:00
|
|
|
.insert('g')
|
|
|
|
.attr('class', classes)
|
2020-09-10 20:58:16 +02:00
|
|
|
.attr('id', node.domId || node.id);
|
|
|
|
|
2020-07-21 15:25:16 +02:00
|
|
|
// Create the title label and insert it after the rect
|
|
|
|
const rect = shapeSvg.insert('rect', ':first-child');
|
|
|
|
const topLine = shapeSvg.insert('line');
|
|
|
|
const bottomLine = shapeSvg.insert('line');
|
|
|
|
let maxWidth = 0;
|
|
|
|
let maxHeight = rowPadding;
|
|
|
|
|
|
|
|
const labelContainer = shapeSvg.insert('g').attr('class', 'label');
|
|
|
|
let verticalPos = 0;
|
|
|
|
const hasInterface = node.classData.annotations && node.classData.annotations[0];
|
|
|
|
|
|
|
|
// 1. Create the labels
|
2020-08-13 20:08:09 +02:00
|
|
|
const interfaceLabelText = node.classData.annotations[0]
|
2020-08-13 21:06:33 +02:00
|
|
|
? '«' + node.classData.annotations[0] + '»'
|
2020-08-13 20:08:09 +02:00
|
|
|
: '';
|
2020-07-21 15:25:16 +02:00
|
|
|
const interfaceLabel = labelContainer
|
|
|
|
.node()
|
2020-08-13 20:08:09 +02:00
|
|
|
.appendChild(createLabel(interfaceLabelText, node.labelStyle, true, true));
|
2020-08-19 20:46:24 +02:00
|
|
|
let interfaceBBox = interfaceLabel.getBBox();
|
|
|
|
if (getConfig().flowchart.htmlLabels) {
|
|
|
|
const div = interfaceLabel.children[0];
|
|
|
|
const dv = select(interfaceLabel);
|
|
|
|
interfaceBBox = div.getBoundingClientRect();
|
|
|
|
dv.attr('width', interfaceBBox.width);
|
|
|
|
dv.attr('height', interfaceBBox.height);
|
|
|
|
}
|
2020-07-21 15:25:16 +02:00
|
|
|
if (node.classData.annotations[0]) {
|
|
|
|
maxHeight += interfaceBBox.height + rowPadding;
|
|
|
|
maxWidth += interfaceBBox.width;
|
|
|
|
}
|
|
|
|
|
2020-08-27 20:14:26 +02:00
|
|
|
let classTitleString = node.classData.id;
|
|
|
|
|
|
|
|
if (node.classData.type !== undefined && node.classData.type !== '') {
|
|
|
|
classTitleString += '<' + node.classData.type + '>';
|
|
|
|
}
|
2020-07-21 15:25:16 +02:00
|
|
|
const classTitleLabel = labelContainer
|
|
|
|
.node()
|
2020-08-27 20:14:26 +02:00
|
|
|
.appendChild(createLabel(classTitleString, node.labelStyle, true, true));
|
2020-08-27 20:43:37 +02:00
|
|
|
select(classTitleLabel).attr('class', 'classTitle');
|
2020-08-19 20:46:24 +02:00
|
|
|
let classTitleBBox = classTitleLabel.getBBox();
|
|
|
|
if (getConfig().flowchart.htmlLabels) {
|
|
|
|
const div = classTitleLabel.children[0];
|
|
|
|
const dv = select(classTitleLabel);
|
|
|
|
classTitleBBox = div.getBoundingClientRect();
|
|
|
|
dv.attr('width', classTitleBBox.width);
|
|
|
|
dv.attr('height', classTitleBBox.height);
|
|
|
|
}
|
2020-07-21 15:25:16 +02:00
|
|
|
maxHeight += classTitleBBox.height + rowPadding;
|
|
|
|
if (classTitleBBox.width > maxWidth) {
|
|
|
|
maxWidth = classTitleBBox.width;
|
|
|
|
}
|
|
|
|
const classAttributes = [];
|
|
|
|
node.classData.members.forEach(str => {
|
2020-08-13 21:06:33 +02:00
|
|
|
const parsedText = parseMember(str).displayText;
|
|
|
|
const lbl = labelContainer
|
|
|
|
.node()
|
|
|
|
.appendChild(createLabel(parsedText, node.labelStyle, true, true));
|
2020-08-19 20:46:24 +02:00
|
|
|
let bbox = lbl.getBBox();
|
|
|
|
if (getConfig().flowchart.htmlLabels) {
|
|
|
|
const div = lbl.children[0];
|
|
|
|
const dv = select(lbl);
|
|
|
|
bbox = div.getBoundingClientRect();
|
|
|
|
dv.attr('width', bbox.width);
|
|
|
|
dv.attr('height', bbox.height);
|
|
|
|
}
|
2020-07-21 15:25:16 +02:00
|
|
|
if (bbox.width > maxWidth) {
|
|
|
|
maxWidth = bbox.width;
|
|
|
|
}
|
|
|
|
maxHeight += bbox.height + rowPadding;
|
|
|
|
classAttributes.push(lbl);
|
|
|
|
});
|
|
|
|
|
2020-08-13 21:06:33 +02:00
|
|
|
maxHeight += lineHeight;
|
|
|
|
|
2020-07-21 15:25:16 +02:00
|
|
|
const classMethods = [];
|
|
|
|
node.classData.methods.forEach(str => {
|
2020-08-13 21:06:33 +02:00
|
|
|
const parsedText = parseMember(str).displayText;
|
|
|
|
const lbl = labelContainer
|
|
|
|
.node()
|
|
|
|
.appendChild(createLabel(parsedText, node.labelStyle, true, true));
|
2020-08-19 20:46:24 +02:00
|
|
|
let bbox = lbl.getBBox();
|
|
|
|
if (getConfig().flowchart.htmlLabels) {
|
|
|
|
const div = lbl.children[0];
|
|
|
|
const dv = select(lbl);
|
|
|
|
bbox = div.getBoundingClientRect();
|
|
|
|
dv.attr('width', bbox.width);
|
|
|
|
dv.attr('height', bbox.height);
|
|
|
|
}
|
2020-07-21 15:25:16 +02:00
|
|
|
if (bbox.width > maxWidth) {
|
|
|
|
maxWidth = bbox.width;
|
|
|
|
}
|
|
|
|
maxHeight += bbox.height + rowPadding;
|
|
|
|
|
|
|
|
classMethods.push(lbl);
|
|
|
|
});
|
|
|
|
|
|
|
|
maxHeight += lineHeight;
|
|
|
|
|
|
|
|
// 2. Position the labels
|
|
|
|
|
|
|
|
// position the interface label
|
|
|
|
if (hasInterface) {
|
2020-08-13 20:08:09 +02:00
|
|
|
let diffX = (maxWidth - interfaceBBox.width) / 2;
|
2020-07-21 15:25:16 +02:00
|
|
|
select(interfaceLabel).attr(
|
|
|
|
'transform',
|
2020-08-13 20:08:09 +02:00
|
|
|
'translate( ' + ((-1 * maxWidth) / 2 + diffX) + ', ' + (-1 * maxHeight) / 2 + ')'
|
2020-07-21 15:25:16 +02:00
|
|
|
);
|
|
|
|
verticalPos = interfaceBBox.height + rowPadding;
|
|
|
|
}
|
|
|
|
// Positin the class title label
|
2020-07-22 21:25:01 +02:00
|
|
|
let diffX = (maxWidth - classTitleBBox.width) / 2;
|
2020-07-21 15:25:16 +02:00
|
|
|
select(classTitleLabel).attr(
|
|
|
|
'transform',
|
2020-07-22 21:25:01 +02:00
|
|
|
'translate( ' +
|
|
|
|
((-1 * maxWidth) / 2 + diffX) +
|
|
|
|
', ' +
|
|
|
|
((-1 * maxHeight) / 2 + verticalPos) +
|
|
|
|
')'
|
2020-07-21 15:25:16 +02:00
|
|
|
);
|
|
|
|
verticalPos += classTitleBBox.height + rowPadding;
|
|
|
|
|
|
|
|
topLine
|
|
|
|
.attr('class', 'divider')
|
|
|
|
.attr('x1', -maxWidth / 2 - halfPadding)
|
|
|
|
.attr('x2', maxWidth / 2 + halfPadding)
|
|
|
|
.attr('y1', -maxHeight / 2 - halfPadding + lineHeight + verticalPos)
|
|
|
|
.attr('y2', -maxHeight / 2 - halfPadding + lineHeight + verticalPos);
|
|
|
|
|
|
|
|
verticalPos += lineHeight;
|
|
|
|
|
|
|
|
classAttributes.forEach(lbl => {
|
|
|
|
select(lbl).attr(
|
|
|
|
'transform',
|
|
|
|
'translate( ' +
|
|
|
|
-maxWidth / 2 +
|
|
|
|
', ' +
|
|
|
|
((-1 * maxHeight) / 2 + verticalPos + lineHeight / 2) +
|
|
|
|
')'
|
|
|
|
);
|
|
|
|
verticalPos += classTitleBBox.height + rowPadding;
|
|
|
|
});
|
|
|
|
|
2020-08-13 21:06:33 +02:00
|
|
|
verticalPos += lineHeight;
|
2020-07-21 15:25:16 +02:00
|
|
|
bottomLine
|
|
|
|
.attr('class', 'divider')
|
|
|
|
.attr('x1', -maxWidth / 2 - halfPadding)
|
|
|
|
.attr('x2', maxWidth / 2 + halfPadding)
|
|
|
|
.attr('y1', -maxHeight / 2 - halfPadding + lineHeight + verticalPos)
|
|
|
|
.attr('y2', -maxHeight / 2 - halfPadding + lineHeight + verticalPos);
|
|
|
|
|
|
|
|
verticalPos += lineHeight;
|
|
|
|
|
|
|
|
classMethods.forEach(lbl => {
|
|
|
|
select(lbl).attr(
|
|
|
|
'transform',
|
|
|
|
'translate( ' + -maxWidth / 2 + ', ' + ((-1 * maxHeight) / 2 + verticalPos) + ')'
|
|
|
|
);
|
|
|
|
verticalPos += classTitleBBox.height + rowPadding;
|
|
|
|
});
|
|
|
|
//
|
2020-08-19 20:46:24 +02:00
|
|
|
// let bbox;
|
|
|
|
// if (getConfig().flowchart.htmlLabels) {
|
|
|
|
// const div = interfaceLabel.children[0];
|
|
|
|
// const dv = select(interfaceLabel);
|
|
|
|
// bbox = div.getBoundingClientRect();
|
|
|
|
// dv.attr('width', bbox.width);
|
|
|
|
// dv.attr('height', bbox.height);
|
|
|
|
// }
|
2020-07-21 15:25:16 +02:00
|
|
|
// bbox = labelContainer.getBBox();
|
|
|
|
|
2021-02-06 15:56:05 +05:30
|
|
|
// log.info('Text 2', text2);
|
2020-07-21 15:25:16 +02:00
|
|
|
// const textRows = text2.slice(1, text2.length);
|
|
|
|
// let titleBox = text.getBBox();
|
|
|
|
// const descr = label
|
|
|
|
// .node()
|
|
|
|
// .appendChild(createLabel(textRows.join('<br/>'), node.labelStyle, true, true));
|
|
|
|
|
|
|
|
// if (getConfig().flowchart.htmlLabels) {
|
|
|
|
// const div = descr.children[0];
|
|
|
|
// const dv = select(descr);
|
|
|
|
// bbox = div.getBoundingClientRect();
|
|
|
|
// dv.attr('width', bbox.width);
|
|
|
|
// dv.attr('height', bbox.height);
|
|
|
|
// }
|
|
|
|
// // bbox = label.getBBox();
|
2021-02-06 15:56:05 +05:30
|
|
|
// // log.info(descr);
|
2020-07-21 15:25:16 +02:00
|
|
|
// select(descr).attr(
|
|
|
|
// 'transform',
|
|
|
|
// 'translate( ' +
|
|
|
|
// // (titleBox.width - bbox.width) / 2 +
|
|
|
|
// (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) +
|
|
|
|
// ', ' +
|
|
|
|
// (titleBox.height + halfPadding + 5) +
|
|
|
|
// ')'
|
|
|
|
// );
|
|
|
|
// select(text).attr(
|
|
|
|
// 'transform',
|
|
|
|
// 'translate( ' +
|
|
|
|
// // (titleBox.width - bbox.width) / 2 +
|
|
|
|
// (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) +
|
|
|
|
// ', ' +
|
|
|
|
// 0 +
|
|
|
|
// ')'
|
|
|
|
// );
|
|
|
|
// // Get the size of the label
|
|
|
|
|
|
|
|
// // Bounding box for title and text
|
|
|
|
// bbox = label.node().getBBox();
|
|
|
|
|
|
|
|
// // Center the label
|
|
|
|
// label.attr(
|
|
|
|
// 'transform',
|
|
|
|
// 'translate(' + -bbox.width / 2 + ', ' + (-bbox.height / 2 - halfPadding + 3) + ')'
|
|
|
|
// );
|
|
|
|
|
|
|
|
rect
|
|
|
|
.attr('class', 'outer title-state')
|
|
|
|
.attr('x', -maxWidth / 2 - halfPadding)
|
|
|
|
.attr('y', -(maxHeight / 2) - halfPadding)
|
|
|
|
.attr('width', maxWidth + node.padding)
|
|
|
|
.attr('height', maxHeight + node.padding);
|
|
|
|
|
|
|
|
// innerLine
|
|
|
|
// .attr('class', 'divider')
|
|
|
|
// .attr('x1', -bbox.width / 2 - halfPadding)
|
|
|
|
// .attr('x2', bbox.width / 2 + halfPadding)
|
|
|
|
// .attr('y1', -bbox.height / 2 - halfPadding + titleBox.height + halfPadding)
|
|
|
|
// .attr('y2', -bbox.height / 2 - halfPadding + titleBox.height + halfPadding);
|
|
|
|
|
|
|
|
updateNodeBounds(node, rect);
|
|
|
|
|
|
|
|
node.intersect = function(point) {
|
|
|
|
return intersect.rect(node, point);
|
|
|
|
};
|
|
|
|
|
|
|
|
return shapeSvg;
|
|
|
|
};
|
|
|
|
|
2020-03-18 22:08:19 +01:00
|
|
|
const shapes = {
|
|
|
|
question,
|
|
|
|
rect,
|
2020-04-25 17:01:20 +02:00
|
|
|
rectWithTitle,
|
2020-03-18 22:08:19 +01:00
|
|
|
circle,
|
|
|
|
stadium,
|
|
|
|
hexagon,
|
|
|
|
rect_left_inv_arrow,
|
|
|
|
lean_right,
|
|
|
|
lean_left,
|
|
|
|
trapezoid,
|
|
|
|
inv_trapezoid,
|
|
|
|
rect_right_inv_arrow,
|
2020-03-25 20:16:27 +01:00
|
|
|
cylinder,
|
|
|
|
start,
|
2020-03-29 14:20:49 +02:00
|
|
|
end,
|
2020-04-26 10:07:25 +02:00
|
|
|
note,
|
2020-05-03 21:52:44 +02:00
|
|
|
subroutine,
|
2020-04-26 10:07:25 +02:00
|
|
|
fork: forkJoin,
|
2020-07-21 15:25:16 +02:00
|
|
|
join: forkJoin,
|
|
|
|
class_box
|
2020-03-18 22:08:19 +01:00
|
|
|
};
|
2020-03-08 09:49:41 +01:00
|
|
|
|
2020-03-14 17:38:35 +01:00
|
|
|
let nodeElems = {};
|
2020-03-08 09:49:41 +01:00
|
|
|
|
2020-04-26 12:57:45 +02:00
|
|
|
export const insertNode = (elem, node, dir) => {
|
2020-09-12 10:56:23 +02:00
|
|
|
let newEl;
|
|
|
|
let el;
|
|
|
|
|
|
|
|
// Add link when appropriate
|
|
|
|
if (node.link) {
|
|
|
|
newEl = elem
|
|
|
|
.insert('svg:a')
|
|
|
|
.attr('xlink:href', node.link)
|
|
|
|
.attr('target', node.linkTarget || '_blank');
|
|
|
|
el = shapes[node.shape](newEl, node, dir);
|
|
|
|
} else {
|
|
|
|
el = shapes[node.shape](elem, node, dir);
|
|
|
|
newEl = el;
|
|
|
|
}
|
|
|
|
if (node.tooltip) {
|
|
|
|
el.attr('title', node.tooltip);
|
|
|
|
}
|
2020-09-20 12:14:04 +02:00
|
|
|
if (node.class) {
|
|
|
|
el.attr('class', 'node default ' + node.class);
|
|
|
|
}
|
2020-09-12 10:56:23 +02:00
|
|
|
|
|
|
|
nodeElems[node.id] = newEl;
|
|
|
|
|
2020-09-10 20:58:16 +02:00
|
|
|
if (node.haveCallback) {
|
|
|
|
nodeElems[node.id].attr('class', nodeElems[node.id].attr('class') + ' clickable');
|
|
|
|
}
|
2020-03-08 09:49:41 +01:00
|
|
|
};
|
2020-04-11 17:16:01 +02:00
|
|
|
export const setNodeElem = (elem, node) => {
|
|
|
|
nodeElems[node.id] = elem;
|
|
|
|
};
|
2020-03-14 17:38:35 +01:00
|
|
|
export const clear = () => {
|
|
|
|
nodeElems = {};
|
|
|
|
};
|
2020-03-08 09:49:41 +01:00
|
|
|
|
|
|
|
export const positionNode = node => {
|
|
|
|
const el = nodeElems[node.id];
|
2021-02-06 15:56:05 +05:30
|
|
|
log.trace(
|
2020-04-16 19:44:11 +02:00
|
|
|
'Transforming node',
|
|
|
|
node,
|
|
|
|
'translate(' + (node.x - node.width / 2 - 5) + ', ' + (node.y - node.height / 2 - 5) + ')'
|
|
|
|
);
|
|
|
|
const padding = 8;
|
|
|
|
if (node.clusterNode) {
|
|
|
|
el.attr(
|
|
|
|
'transform',
|
|
|
|
'translate(' +
|
|
|
|
(node.x - node.width / 2 - padding) +
|
|
|
|
', ' +
|
|
|
|
(node.y - node.height / 2 - padding) +
|
|
|
|
')'
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
|
|
|
|
}
|
2020-03-08 09:49:41 +01:00
|
|
|
};
|