diff --git a/cypress/platform/current.html b/cypress/platform/current.html index c79769cee..2352c061e 100644 --- a/cypress/platform/current.html +++ b/cypress/platform/current.html @@ -11,17 +11,17 @@ font-family: 'Arial'; } h1 { color: white;} - .arrowheadPath {fill: red;} - - .edgePath .path {stroke: red;} .mermaid2 { display: none; } + .mermaid-apa #pointEnd { + fill: green !important; + }

info below

-
+
flowchart LR a --> b @@ -34,14 +34,30 @@ G-->H G-->c
-
+
flowchart LR subgraph id1 [Test] b end a-->id1
-
+
+ stateDiagram-v2 + [*] --> Still + [*] --> Moving + Still --> [*] + Moving --> [*] +
+
+ stateDiagram-v2 + [*] --> Still + Still --> [*] + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] +
+
stateDiagram-v2 [*]-->TV diff --git a/src/dagre-wrapper/edges.js b/src/dagre-wrapper/edges.js index dc90c30c6..41ba9ea90 100644 --- a/src/dagre-wrapper/edges.js +++ b/src/dagre-wrapper/edges.js @@ -113,7 +113,7 @@ const intersection = (node, outsidePoint, insidePoint) => { } }; -export const insertEdge = function(elem, edge, clusterDb) { +export const insertEdge = function(elem, edge, clusterDb, diagramType) { logger.info('\n\n\n\n'); let points = edge.points; if (edge.toCluster) { @@ -219,25 +219,32 @@ export const insertEdge = function(elem, edge, clusterDb) { // logger.info('arrowType', edge.arrowType); switch (edge.arrowType) { case 'arrow_cross': - svgPath.attr('marker-end', 'url(' + url + '#' + 'crossEnd' + ')'); + svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-crossEnd' + ')'); break; case 'double_arrow_cross': - svgPath.attr('marker-end', 'url(' + url + '#' + 'crossEnd' + ')'); - svgPath.attr('marker-start', 'url(' + url + '#' + 'crossStart' + ')'); + svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-crossEnd' + ')'); + svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-crossStart' + ')'); break; case 'arrow_point': - svgPath.attr('marker-end', 'url(' + url + '#' + 'pointEnd' + ')'); + svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-pointEnd' + ')'); break; case 'double_arrow_point': - svgPath.attr('marker-end', 'url(' + url + '#' + 'pointEnd' + ')'); - svgPath.attr('marker-start', 'url(' + url + '#' + 'pointStart' + ')'); + svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-pointEnd' + ')'); + svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-pointStart' + ')'); + break; + case 'arrow_barb': + svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-barbEnd' + ')'); + break; + case 'double_arrow_barb': + svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-barnEnd' + ')'); + svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-barbStart' + ')'); break; case 'arrow_circle': - svgPath.attr('marker-end', 'url(' + url + '#' + 'circleEnd' + ')'); + svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-circleEnd' + ')'); break; case 'double_arrow_circle': - svgPath.attr('marker-end', 'url(' + url + '#' + 'circleEnd' + ')'); - svgPath.attr('marker-start', 'url(' + url + '#' + 'circleStart' + ')'); + svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-circleEnd' + ')'); + svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-circleStart' + ')'); break; default: } diff --git a/src/dagre-wrapper/index.js b/src/dagre-wrapper/index.js index 610cb5508..8f5a5c731 100644 --- a/src/dagre-wrapper/index.js +++ b/src/dagre-wrapper/index.js @@ -12,8 +12,8 @@ const translateClusterId = id => { return id; }; -export const render = (elem, graph, markers) => { - insertMarkers(elem, markers); +export const render = (elem, graph, markers, diagramtype, id) => { + insertMarkers(elem, markers, diagramtype, id); clusterDb = {}; clearNodes(); clearEdges(); @@ -88,7 +88,7 @@ export const render = (elem, graph, markers) => { const edge = graph.edge(e); logger.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge); - insertEdge(edgePaths, edge, clusterDb); + insertEdge(edgePaths, edge, clusterDb, diagramtype); positionEdgeLabel(edge); }); }; diff --git a/src/dagre-wrapper/markers.js b/src/dagre-wrapper/markers.js index 2850b6714..3bf95cfe3 100644 --- a/src/dagre-wrapper/markers.js +++ b/src/dagre-wrapper/markers.js @@ -2,18 +2,18 @@ * Setup arrow head and define the marker. The result is appended to the svg. */ // Only add the number of markers that the diagram needs -const insertMarkers = (elem, markerArray) => { +const insertMarkers = (elem, markerArray, type, id) => { markerArray.forEach(markerName => { - markers[markerName](elem); + markers[markerName](elem, type, id); }); }; -const extension = elem => { +const extension = (elem, type, id) => { elem .append('defs') .append('marker') .attr('id', 'extensionStart') - .attr('class', 'extension') + .attr('class', 'extension ' + type) .attr('refX', 0) .attr('refY', 7) .attr('markerWidth', 190) @@ -25,7 +25,8 @@ const extension = elem => { elem .append('defs') .append('marker') - .attr('id', 'extensionEnd') + .attr('id', 'extensionEnd ' + type) + .attr('class', 'extension ' + type) .attr('refX', 19) .attr('refY', 7) .attr('markerWidth', 20) @@ -35,12 +36,12 @@ const extension = elem => { .attr('d', 'M 1,1 V 13 L18,7 Z'); // this is actual shape for arrowhead }; -const composition = elem => { +const composition = (elem, type, id) => { elem .append('defs') .append('marker') .attr('id', 'compositionStart') - .attr('class', 'extension') + .attr('class', 'extension ' + type) .attr('refX', 0) .attr('refY', 7) .attr('markerWidth', 190) @@ -53,6 +54,7 @@ const composition = elem => { .append('defs') .append('marker') .attr('id', 'compositionEnd') + .attr('class', 'extension ' + type) .attr('refX', 19) .attr('refY', 7) .attr('markerWidth', 20) @@ -61,12 +63,12 @@ const composition = elem => { .append('path') .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z'); }; -const aggregation = elem => { +const aggregation = (elem, type, id) => { elem .append('defs') .append('marker') .attr('id', 'aggregationStart') - .attr('class', 'extension') + .attr('class', 'extension ' + type) .attr('refX', 0) .attr('refY', 7) .attr('markerWidth', 190) @@ -79,6 +81,7 @@ const aggregation = elem => { .append('defs') .append('marker') .attr('id', 'aggregationEnd') + .attr('class', type) .attr('refX', 19) .attr('refY', 7) .attr('markerWidth', 20) @@ -87,12 +90,12 @@ const aggregation = elem => { .append('path') .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z'); }; -const dependency = elem => { +const dependency = (elem, type, id) => { elem .append('defs') .append('marker') .attr('id', 'dependencyStart') - .attr('class', 'extension') + .attr('class', 'extension ' + type) .attr('refX', 0) .attr('refY', 7) .attr('markerWidth', 190) @@ -105,6 +108,7 @@ const dependency = elem => { .append('defs') .append('marker') .attr('id', 'dependencyEnd') + .attr('class', type) .attr('refX', 19) .attr('refY', 7) .attr('markerWidth', 20) @@ -113,10 +117,11 @@ const dependency = elem => { .append('path') .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z'); }; -const point = elem => { +const point = (elem, type, id) => { elem .append('marker') - .attr('id', 'pointEnd') + .attr('id', type + '-pointEnd') + .attr('class', type) .attr('viewBox', '0 0 10 10') .attr('refX', 10) .attr('refY', 5) @@ -126,12 +131,13 @@ const point = elem => { .attr('orient', 'auto') .append('path') .attr('d', 'M 0 0 L 10 5 L 0 10 z') - .attr('class', 'arrowheadPath') + .attr('class', 'arrowMarkerPath') .style('stroke-width', 1) .style('stroke-dasharray', '1,0'); elem .append('marker') - .attr('id', 'pointStart') + .attr('id', type + '-pointStart') + .attr('class', type) .attr('viewBox', '0 0 10 10') .attr('refX', 0) .attr('refY', 5) @@ -141,14 +147,15 @@ const point = elem => { .attr('orient', 'auto') .append('path') .attr('d', 'M 0 5 L 10 10 L 10 0 z') - .attr('class', 'arrowheadPath') + .attr('class', 'arrowMarkerPath') .style('stroke-width', 1) .style('stroke-dasharray', '1,0'); }; -const circle = elem => { +const circle = (elem, type, id) => { elem .append('marker') .attr('id', 'circleEnd') + .attr('class', type) .attr('viewBox', '0 0 10 10') .attr('refX', 11) .attr('refY', 5) @@ -160,13 +167,14 @@ const circle = elem => { .attr('cx', '5') .attr('cy', '5') .attr('r', '5') - .attr('class', 'arrowheadPath') + .attr('class', 'arrowMarkerPath') .style('stroke-width', 1) .style('stroke-dasharray', '1,0'); elem .append('marker') .attr('id', 'circleStart') + .attr('class', type) .attr('viewBox', '0 0 10 10') .attr('refX', -1) .attr('refY', 5) @@ -178,14 +186,15 @@ const circle = elem => { .attr('cx', '5') .attr('cy', '5') .attr('r', '5') - .attr('class', 'arrowheadPath') + .attr('class', 'arrowMarkerPath') .style('stroke-width', 1) .style('stroke-dasharray', '1,0'); }; -const cross = elem => { +const cross = (elem, type, id) => { elem .append('marker') .attr('id', 'crossEnd') + .attr('class', type) .attr('viewBox', '0 0 11 11') .attr('refX', 12) .attr('refY', 5.2) @@ -196,13 +205,14 @@ const cross = elem => { .append('path') .attr('stroke', 'black') .attr('d', 'M 1,1 l 9,9 M 10,1 l -9,9') - .attr('class', 'arrowheadPath') + .attr('class', 'arrowMarkerPath') .style('stroke-width', 2) .style('stroke-dasharray', '1,0'); elem .append('marker') .attr('id', 'crossStart') + .attr('class', type) .attr('viewBox', '0 0 11 11') .attr('refX', -1) .attr('refY', 5.2) @@ -213,11 +223,59 @@ const cross = elem => { .append('path') .attr('stroke', 'black') .attr('d', 'M 1,1 l 9,9 M 10,1 l -9,9') - .attr('class', 'arrowheadPath') + .attr('class', 'arrowMarkerPath') .style('stroke-width', 2) .style('stroke-dasharray', '1,0'); }; +const barb = (elem, type, id) => { + elem + .append('defs') + .append('marker') + .attr('id', type + '-barbEnd') + .attr('refX', 19) + .attr('refY', 7) + .attr('markerWidth', 20) + .attr('markerHeight', 14) + .attr('markerUnits', 0) + .attr('orient', 'auto') + .append('path') + .attr('d', 'M 19,7 L9,13 L14,7 L9,1 Z'); + // .append('marker') + // .attr('id', 'barbEnd') + // .attr('class', type) + // .attr('viewBox', '0 0 11 11') + // .attr('refX', 12) + // .attr('refY', 5.2) + // .attr('markerUnits', 'strokeWidth') + // .attr('markerWidth', 7) + // .attr('markerHeight', 7) + // .attr('orient', 'auto') + // .append('path') + // .attr('stroke', 'black') + // .attr('d', 'M 1,1 l 9,9 M 10,1 l -9,9') + // .attr('class', 'arrowMarkerPath') + // .style('stroke-width', 2) + // .style('stroke-dasharray', '1,0'); + + // elem + // .append('marker') + // .attr('id', 'barbStart') + // .attr('class', type) + // .attr('viewBox', '0 0 11 11') + // .attr('refX', -1) + // .attr('refY', 5.2) + // .attr('markerUnits', 'strokeWidth') + // .attr('markerWidth', 7) + // .attr('markerHeight', 7) + // .attr('orient', 'auto') + // .append('path') + // .attr('stroke', 'black') + // .attr('d', 'M 1,1 l 9,9 M 10,1 l -9,9') + // .attr('class', 'arrowMarkerPath') + // .style('stroke-width', 2) + // .style('stroke-dasharray', '1,0'); +}; // TODO rename the class diagram markers to something shape descriptive and semanitc free const markers = { extension, @@ -226,6 +284,7 @@ const markers = { dependency, point, circle, - cross + cross, + barb }; export default insertMarkers; diff --git a/src/dagre-wrapper/nodes.js b/src/dagre-wrapper/nodes.js index ed897a5bf..21ffc77f4 100644 --- a/src/dagre-wrapper/nodes.js +++ b/src/dagre-wrapper/nodes.js @@ -375,6 +375,34 @@ const start = (parent, node) => { return shapeSvg; }; +const end = (parent, node) => { + const shapeSvg = parent + .insert('g') + .attr('class', 'node default') + .attr('id', node.id); + 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) { + return intersect.circle(node, point); + }; + + return shapeSvg; +}; const shapes = { question, @@ -390,7 +418,7 @@ const shapes = { rect_right_inv_arrow, cylinder, start, - end: start + end }; let nodeElems = {}; diff --git a/src/diagrams/flowchart/flowRenderer-v2.js b/src/diagrams/flowchart/flowRenderer-v2.js index 29f892975..e8915fc08 100644 --- a/src/diagrams/flowchart/flowRenderer-v2.js +++ b/src/diagrams/flowchart/flowRenderer-v2.js @@ -350,7 +350,7 @@ export const draw = function(text, id) { // Run the renderer. This is what draws the final graph. const element = d3.select('#' + id + ' g'); - render(element, g, ['point', 'circle', 'cross']); + render(element, g, ['point', 'circle', 'cross'], 'flowchart', id); dagre.layout(g); element.selectAll('g.node').attr('title', function() { diff --git a/src/diagrams/state/stateRenderer-v2.js b/src/diagrams/state/stateRenderer-v2.js index 99009c2e9..622b878f0 100644 --- a/src/diagrams/state/stateRenderer-v2.js +++ b/src/diagrams/state/stateRenderer-v2.js @@ -71,10 +71,8 @@ const setupNode = (g, parent, node) => { shape: nodeDb[node.id].shape, label: node.id, labelText: nodeDb[node.id].description, - // label: nodeDb[node.id].description || node.id, - // labelText: nodeDb[node.id].description || node.id, - rx: 0, - ry: 0, + rx: 5, + ry: 5, class: 'default', //classStr, style: '', //styles.style, id: node.id, @@ -107,28 +105,17 @@ const setupDoc = (g, parent, doc) => { setupNode(g, parent, item.state2); const edgeData = { arrowhead: 'normal', - arrowType: 'arrow_point', + arrowType: 'arrow_barb', style: 'fill:none', labelStyle: '', arrowheadStyle: 'fill: #333', labelpos: 'c', labelType: 'text', - label: '', - // curve: d3.curveNatural, - curve: d3.curveStep - // curve: d3.curveMonotoneX + label: '' }; let startId = item.state1.id; let endId = item.state2.id; - // if (parent && startId === '[*]') { - // startId = parent.id + '_start'; - // } - - // if (parent && endId === '[*]') { - // startId = parent.id + '_end'; - // } - g.setEdge(startId, endId, edgeData, cnt); cnt++; } @@ -141,7 +128,7 @@ const setupDoc = (g, parent, doc) => { * @param id */ export const draw = function(text, id) { - logger.trace('Drawing state diagram (v2)'); + logger.info('Drawing state diagram (v2)', id); stateDb.clear(); const parser = state.parser; parser.yy = stateDb; @@ -188,30 +175,48 @@ export const draw = function(text, id) { // Run the renderer. This is what draws the final graph. const element = d3.select('#' + id + ' g'); - render(element, g, ['point', 'circle', 'cross']); + render(element, g, ['barb'], 'statediagram', id); const padding = 8; - const svgBounds = svg.node().getBBox(); - const width = svgBounds.width + padding * 2; - const height = svgBounds.height + padding * 2; - logger.debug( - `new ViewBox 0 0 ${width} ${height}`, - `translate(${padding - g._label.marginx}, ${padding - g._label.marginy})` + // const svgBounds = svg.node().getBBox(); + // const width = svgBounds.width + padding * 2; + // const height = svgBounds.height + padding * 2; + // logger.debug( + // `new ViewBox 0 0 ${width} ${height}`, + // `translate(${padding + g._label.marginx}, ${padding + g._label.marginy})` + // ); + + // if (conf.useMaxWidth) { + // svg.attr('width', '100%'); + // svg.attr('style', `max-width: ${width}px;`); + // } else { + // svg.attr('height', height); + // svg.attr('width', width); + // } + + // svg.attr('viewBox', `0 0 ${width} ${height}`); + // svg + // .select('g') + // .attr('transform', `translate(${padding - g._label.marginx}, ${padding - svgBounds.y})`); + + const bounds = svg.node().getBBox(); + + const width = bounds.width + padding * 2; + const height = bounds.height + padding * 2; + + // diagram.attr('height', '100%'); + // diagram.attr('style', `width: ${bounds.width * 3 + conf.padding * 2};`); + // diagram.attr('height', height); + + // Zoom in a bit + svg.attr('width', width * 1.75); + svg.attr('class', 'statediagram'); + // diagram.attr('height', bounds.height * 3 + conf.padding * 2); + svg.attr( + 'viewBox', + `${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + ' ' + height ); - if (conf.useMaxWidth) { - svg.attr('width', '100%'); - svg.attr('style', `max-width: ${width}px;`); - } else { - svg.attr('height', height); - svg.attr('width', width); - } - - svg.attr('viewBox', `0 0 ${width} ${height}`); - svg - .select('g') - .attr('transform', `translate(${padding - g._label.marginx}, ${padding - svgBounds.y})`); - // Add label rects for non html labels if (!conf.htmlLabels) { const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); diff --git a/src/themes/state.scss b/src/themes/state.scss index ab16ce68e..8c142d794 100644 --- a/src/themes/state.scss +++ b/src/themes/state.scss @@ -71,4 +71,12 @@ g.stateGroup line { .node circle.state-start { fill: black; stroke: black; +} +.node circle.state-end { + fill: black; + stroke: white; + stroke-width: 1.5 +} +#statediagram-barbEnd { + fill: $nodeBorder } \ No newline at end of file