diff --git a/packages/mermaid/src/dagre-wrapper/edges.js b/packages/mermaid/src/dagre-wrapper/edges.js index 1581658b0..dc2c3f8fe 100644 --- a/packages/mermaid/src/dagre-wrapper/edges.js +++ b/packages/mermaid/src/dagre-wrapper/edges.js @@ -368,7 +368,20 @@ const cutPathAtIntersect = (_points, boundryNode) => { return points; }; -//(edgePaths, e, edge, clusterDb, diagramtype, graph) +/** + * Calculate the deltas and angle between two points + * @param {{x: number, y:number}} point1 + * @param {{x: number, y:number}} point2 + * @returns {{angle: number, deltaX: number, deltaY: number}} + */ +function calculateDeltaAndAngle(point1, point2) { + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} + export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph) { let points = edge.points; let pointsHasChanged = false; @@ -435,22 +448,56 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph const lineData = points.filter((p) => !Number.isNaN(p.y)); // This is the accessor function we talked about above - let curve; + let curve = curveBasis; // Currently only flowcharts get the curve from the settings, perhaps this should // be expanded to a common setting? Restricting it for now in order not to cause side-effects that // have not been thought through - if (diagramType === 'graph' || diagramType === 'flowchart') { - curve = edge.curve || curveBasis; - } else { - curve = curveBasis; + if (edge.curve && (diagramType === 'graph' || diagramType === 'flowchart')) { + curve = edge.curve; } - // curve = curveLinear; + + const offsets = { + dependency: 6, + composition: 18, + extension: 18, + aggregation: 18, + lollipop: 12, + }; + const lineFunction = line() - .x(function (d) { - return d.x; + .x(function (d, i, data) { + debugger; + let offset = 0; + if (i === 0 && edge.arrowTypeStart !== 'none') { + const { angle, deltaX, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = offsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX <= 0 ? -1 : 1) || 0; + console.log('ffff xstart', { offset, angle, deltaX, deltaY }); + } else if (i === data.length - 1 && edge.arrowTypeEnd !== 'none') { + const { angle, deltaX, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = offsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX <= 0 ? -1 : 1) || 0; + console.log('ffff xend', { offset, angle, deltaX, deltaY }); + } + return d.x + offset; }) - .y(function (d) { - return d.y; + .y(function (d, i, data) { + debugger; + let offset = 0; + if (i === 0 && edge.arrowTypeStart !== 'none') { + const { angle, deltaY, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = offsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) || 0; + console.log('ffff ystart', { offset, angle, deltaX, deltaY, sin: Math.sin(angle) }); + } else if (i === data.length - 1 && edge.arrowTypeEnd !== 'none') { + const { angle, deltaY, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = offsets[edge.arrowTypeEnd] * -Math.abs(Math.sin(angle)) || 0; + console.log('ffff yend', { offset, angle, deltaX, deltaY }); + } + return d.y + offset; }) .curve(curve); @@ -489,15 +536,15 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph .attr('style', edge.style); // DEBUG code, adds a red circle at each edge coordinate - // edge.points.forEach((point) => { - // elem - // .append('circle') - // .style('stroke', 'red') - // .style('fill', 'red') - // .attr('r', 1) - // .attr('cx', point.x) - // .attr('cy', point.y); - // }); + edge.points.forEach((point) => { + elem + .append('circle') + .style('stroke', 'red') + .style('fill', 'red') + .attr('r', 1) + .attr('cx', point.x) + .attr('cy', point.y); + }); let url = ''; // // TODO: Can we load this config only from the rendered graph type? diff --git a/packages/mermaid/src/dagre-wrapper/index.js b/packages/mermaid/src/dagre-wrapper/index.js index 590242b02..894fad55e 100644 --- a/packages/mermaid/src/dagre-wrapper/index.js +++ b/packages/mermaid/src/dagre-wrapper/index.js @@ -155,7 +155,7 @@ export const render = async (elem, graph, markers, diagramtype, id) => { clearClusters(); clearGraphlib(); - log.warn('Graph at first:', graphlibJson.write(graph)); + log.warn('Graph at first:', JSON.stringify(graphlibJson.write(graph))); adjustClustersAndEdges(graph); log.warn('Graph after:', graphlibJson.write(graph)); // log.warn('Graph ever after:', graphlibJson.write(graph.node('A').graph)); diff --git a/packages/mermaid/src/dagre-wrapper/markers.js b/packages/mermaid/src/dagre-wrapper/markers.js index 57d092fdf..ed943aa56 100644 --- a/packages/mermaid/src/dagre-wrapper/markers.js +++ b/packages/mermaid/src/dagre-wrapper/markers.js @@ -16,7 +16,7 @@ const extension = (elem, type, id) => { .append('marker') .attr('id', type + '-extensionStart') .attr('class', 'marker extension ' + type) - .attr('refX', 0) + .attr('refX', 18) .attr('refY', 7) .attr('markerWidth', 190) .attr('markerHeight', 240) @@ -29,7 +29,7 @@ const extension = (elem, type, id) => { .append('marker') .attr('id', type + '-extensionEnd') .attr('class', 'marker extension ' + type) - .attr('refX', 19) + .attr('refX', 1) .attr('refY', 7) .attr('markerWidth', 20) .attr('markerHeight', 28) @@ -44,7 +44,7 @@ const composition = (elem, type) => { .append('marker') .attr('id', type + '-compositionStart') .attr('class', 'marker composition ' + type) - .attr('refX', 0) + .attr('refX', 18) .attr('refY', 7) .attr('markerWidth', 190) .attr('markerHeight', 240) @@ -57,7 +57,7 @@ const composition = (elem, type) => { .append('marker') .attr('id', type + '-compositionEnd') .attr('class', 'marker composition ' + type) - .attr('refX', 19) + .attr('refX', 1) .attr('refY', 7) .attr('markerWidth', 20) .attr('markerHeight', 28) @@ -71,7 +71,7 @@ const aggregation = (elem, type) => { .append('marker') .attr('id', type + '-aggregationStart') .attr('class', 'marker aggregation ' + type) - .attr('refX', 0) + .attr('refX', 18) .attr('refY', 7) .attr('markerWidth', 190) .attr('markerHeight', 240) @@ -84,7 +84,7 @@ const aggregation = (elem, type) => { .append('marker') .attr('id', type + '-aggregationEnd') .attr('class', 'marker aggregation ' + type) - .attr('refX', 19) + .attr('refX', 1) .attr('refY', 7) .attr('markerWidth', 20) .attr('markerHeight', 28) @@ -98,7 +98,7 @@ const dependency = (elem, type) => { .append('marker') .attr('id', type + '-dependencyStart') .attr('class', 'marker dependency ' + type) - .attr('refX', 0) + .attr('refX', 6) .attr('refY', 7) .attr('markerWidth', 190) .attr('markerHeight', 240) @@ -111,7 +111,7 @@ const dependency = (elem, type) => { .append('marker') .attr('id', type + '-dependencyEnd') .attr('class', 'marker dependency ' + type) - .attr('refX', 19) + .attr('refX', 13) .attr('refY', 7) .attr('markerWidth', 20) .attr('markerHeight', 28) @@ -125,14 +125,14 @@ const lollipop = (elem, type) => { .append('marker') .attr('id', type + '-lollipopStart') .attr('class', 'marker lollipop ' + type) - .attr('refX', 0) + .attr('refX', 12) .attr('refY', 7) .attr('markerWidth', 190) .attr('markerHeight', 240) .attr('orient', 'auto') .append('circle') .attr('stroke', 'black') - .attr('fill', 'white') + .attr('fill', 'transparent') .attr('cx', 6) .attr('cy', 7) .attr('r', 6); diff --git a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js index 72ef96965..1e376054d 100644 --- a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js +++ b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js @@ -291,8 +291,8 @@ export const adjustClustersAndEdges = (graph, depth) => { shape: 'labelRect', style: '', }); - const edge1 = JSON.parse(JSON.stringify(edge)); - const edge2 = JSON.parse(JSON.stringify(edge)); + const edge1 = structuredClone(edge); + const edge2 = structuredClone(edge); edge1.label = ''; edge1.arrowTypeEnd = 'none'; edge2.label = ''; diff --git a/packages/mermaid/src/diagrams/class/classRenderer-v2.ts b/packages/mermaid/src/diagrams/class/classRenderer-v2.ts index d9e39912c..a68fd5ee1 100644 --- a/packages/mermaid/src/diagrams/class/classRenderer-v2.ts +++ b/packages/mermaid/src/diagrams/class/classRenderer-v2.ts @@ -130,6 +130,7 @@ export const addClasses = function ( // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release padding: getConfig().flowchart?.padding ?? getConfig().class?.padding, }; + console.log('node', node, structuredClone(node)); g.setNode(vertex.id, node); if (parent) { diff --git a/packages/mermaid/src/diagrams/class/styles.js b/packages/mermaid/src/diagrams/class/styles.js index 15386bf9e..1a391ae53 100644 --- a/packages/mermaid/src/diagrams/class/styles.js +++ b/packages/mermaid/src/diagrams/class/styles.js @@ -91,7 +91,7 @@ g.classGroup line { } #compositionEnd, .composition { - fill: ${options.lineColor} !important; + fill: transparent !important; stroke: ${options.lineColor} !important; stroke-width: 1; }