Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/1893 data flow diagrams #2389

Merged
merged 14 commits into from
Dec 1, 2021

Conversation

maiermic
Copy link
Contributor

@maiermic maiermic commented Oct 9, 2021

📑 Summary

Support data flow diagrams by adding brackets [| and |] for datastore nodes to graph, e.g.

dataflowchart

Resolves #1893

📏 Design Decisions

I extend graph as data flow diagrams are graphs in general. However, the same grammar is used for flowchart, which does not contain such nodes. I use the brackets [| and |] as suggested by the author of the issue. However, if other nodes may be added in the future that are rectangles with borders/strokes on specific sides, the | indicates rather vertical lines than horizontal. We might consider [- and -] instead. Actually, we could support all sides using brackets:

  • [| left, but no top stroke
  • [|- left and top stroke
  • [- no left, but top stroke
  • |] right, but no bottom stroke
  • -|] right and bottom stroke
  • -] no right, but bottom stroke

However, this would be a larger change/extension of the grammar. Hence, I only added one bracket pair, which is sufficient to cover data flow diagrams. What do you think?

📋 Tasks

Make sure you

  • 📖 have read the contribution guidelines
  • 💻 have added unit/e2e tests (if appropriate)
  • 🔖 targeted develop branch

TODO: Add tests when design decisions are final

@knsv
Copy link
Collaborator

knsv commented Oct 14, 2021

Hello and thanks for looking at this issue.

Have the possibilities to make data flow diagrams would be great and you have made a good start. One thing to keep in mind is backwards compatibility as we can not risk existing authored diagrams to break. This basically means that the syntax once added can never change so no pressure 😄

I like your idea with the brackets which would allow many shapes, do you mean to combine them as well?
[| left, but no top stroke and right and bottom stroke -|]

I don't think [| and |] to represent datastore nodes of data flow diagrams is the best way to go and once in they are there to stay. I think we should go with your syntax as long as it does not break existing diagrams.

The parsing tests are your friendly helper to make sure of that, please add your own as well. It will help you both when working with the grammar and make sure no one else does not break the data flow parsing down the line.

Another think to keep in mind is that graph and the original flow renderer are deprecated and should not be added to. Instead add the shapes so that they render with flowchart (which is the default renderer) using flowRenderer-v2.

I will not merge this right now due to the syntax of [| and |] but hope you want to follow you own idea.

Note that you can call these lexical elements the same thing DF_RECT_START and DF_RECT_STOP and infer the detail semantics of which of the shapes the start and stop symbols form in the flowDB. This will keep the grammar from exploding.

@maiermic
Copy link
Contributor Author

Thanks for the feedback 👍

I like your idea with the brackets which would allow many shapes, do you mean to combine them as well?

Yes, but I just realized that my current brackets do not allow to stroke just right and bottom sides like this

border on right and bottom sides

You can use -|] as closing brackets, but what do you use as opening bracket? Maybe just the existing [? But the meaning of [ would depend on the closing bracket, which might not be quite intuitive. The same issue exists for the opposite sides, i.e. left and top.

flowchart LR
  allSides[ stroke all sides ]
  rbSides[ stroke right and bottom sides -|]
  ltSides[|- stroke left and top sides ]

all-sides-vs-opening-and-closing-sides.svg

Another issue may be that [- may break existing diagrams, where the node text starts with -, e.g.

flowchart TB
  minusOne[-1]

Till now, it renders as

minus-one.svg

but due to my suggestion, it would render as

top-one.svg

Another idea/solution are bracket-parameters, e.g. with a syntax like this

nodeName [|parameters| node text ]

For example, the letters l (left border), t (top border), r (right border) and b (bottom border) could be allowed:

flowchart LR
  allSides [ stroke all sides ]
  allSides2 [|ltrb| stroke all sides ]
  rbSides [|rb| stroke right and bottom sides ]
  ltSides [|lt| stroke left and top sides ]

parameter-example.svg

Named parameters should be easier to extend, e.g. the same example could be written with named parameters borders as

flowchart LR
  allSides [ stroke all sides ]
  allSides2 [|borders:ltrb| stroke all sides ]
  rbSides [|borders:rb| stroke right and bottom sides ]
  ltSides [|borders:lt| stroke left and top sides ]

An extension could be thick-borders, e.g.

flowchart LR
  node [|borders:lr,thick-borders:tb| thick horizontal, regular vertical ]

thick-horizontal-and-regular-vertical.svg

What do you think?

@knsv
Copy link
Collaborator

knsv commented Oct 21, 2021

Sorry for the slow delay. Thursdays is Mermaid night here :)

This looks great! 🚀

I like your last suggestion, go for it!

@knsv
Copy link
Collaborator

knsv commented Nov 3, 2021

@maiermic This looks great, is the PR still active?

@maiermic
Copy link
Contributor Author

maiermic commented Nov 3, 2021

@knsv Yes, I just hadn't the time yet to implement my last suggestion. I'm looking forward to do so.

rbSides[|borders:rb| stroke right and bottom sides ];
ltSides[|borders:lt| stroke left and top sides ];
lrSides[|borders:lr| stroke left and right sides ];
noSide[|borders:no| stroke no side ];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no works, since the word does not contain any of the border letters ltrb. It's not a bug, it's a feature 😉

if (node.props?.borders) {
applyNodePropertyBorders(rect, node.props.borders, totalWidth, totalHeight);
propKeys.delete('borders');
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More properties may be added here in the future 🙂


const propKeys = new Set(Object.keys(node.props));
if (node.props?.borders) {
applyNodePropertyBorders(rect, node.props.borders, totalWidth, totalHeight);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If properties are handled here in this function, only the required data has to be passed to each property handler (here applyNodePropertyBorders). I decided to not extract the whole block (handling all properties) as applyNodeProperties to have access to variables of the current function context (e.g. totalWidth). I could have passed them (e.g. bbox), but it is hard to predict, which variables may be of interest to future property handlers (e.g. that do something else than adding borders). I guess, all variables would be passed to applyNodeProperties in the end.

@maiermic
Copy link
Contributor Author

maiermic commented Nov 28, 2021

@knsv I'm confused that the test

XSS
should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre wrapper

fails, since xss8.html uses stateDiagram-v2. The changed files in src/diagrams/flowchart/flowDb.js should have no effect. Hence, I guess that it is caused by my changes to src/dagre-wrapper/nodes.js. I'm not sure, how they should break the sanitization. Unless node.props existed before. I assumed that I introduced a new property with this name. Has it been used before?

Edit: I should have looked at the console output first. It does not break the sanitization. It's just an error that is thrown, because node.prop is undefined in src/dagre-wrapper/nodes.js, since it is never set in case of stateDiagram-v2.

@@ -380,6 +381,8 @@ vertex: idString SQS text SQE
{$$ = $1;yy.addVertex($1,$3,'stadium');}
| idString SUBROUTINESTART text SUBROUTINEEND
{$$ = $1;yy.addVertex($1,$3,'subroutine');}
| idString VERTEX_WITH_PROPS_START ALPHA COLON ALPHA PIPE text SQE
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if there is a better token (or rule) than ALPHA for the identifier and/or value. It does not allow to add a property thick-borders, but thickBorders would work. That's fine to me. Further, the rule could be changed in the future if required.

@knsv
Copy link
Collaborator

knsv commented Nov 29, 2021

Great to see this PR progressing. Is it ready for another review?

@maiermic
Copy link
Contributor Author

Yes, it is ready to review

1 similar comment
@maiermic
Copy link
Contributor Author

Yes, it is ready to review

@knsv knsv merged commit e6cf1f2 into mermaid-js:develop Dec 1, 2021
@knsv
Copy link
Collaborator

knsv commented Dec 1, 2021

Thanks for the PR!

@StevenIsaacs
Copy link

Thank you for the this!

Unfortunately, the implementation is incomplete.

flowchart LR
p((process))
ds[|borders:tb|ds] --> p
ds2[|borders:tb|ds2] --> p
p --> ds2

Renders as:

flowchart LR
  p((process))
  ds[|borders:tb|ds] --> p
  ds2[|borders:tb|ds2] --> p
  p --> ds2
Loading

Borders has no effect when ds2 is referenced.

A problem similar to this is: #3263

I added this to that issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Data Flow Diagram (a la STRIDE Threat Model)
3 participants