diff --git a/.gitignore b/.gitignore index 4394e082cc..7c9d7b019e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/* bower_components/ *.sublime-project -*.sublime-workspace \ No newline at end of file +*.sublime-workspace +.DS_Store diff --git a/README.md b/README.md index 4e60738136..93d043648c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -mermaid [![Build Status](https://travis-ci.org/knsv/mermaid.svg?branch=master)](https://travis-ci.org/knsv/mermaid) +mermaid [![Build Status](https://travis-ci.org/knsv/mermaid.svg?branch=master)](https://travis-ci.org/knsv/mermaid) [![Code Climate](https://codeclimate.com/github/knsv/mermaid/badges/gpa.svg)](https://codeclimate.com/github/knsv/mermaid) ======= Generation of diagrams and flowcharts from text in a similar manner as markdown. @@ -21,56 +21,14 @@ would render this lovely chart: ![Example 1](http://www.sveido.com/mermaid/img/ex1.png) -A page with a live example can be seen [here](http://www.sveido.com/mermaid/demo/html/web.html). You can also look at mermaid in action using [jsbin](http://jsbin.com/faxunexeku/1/edit?html,output). If you want a live demo, there is aan editor provided in mermaid the mermaid project or you can simply look at this [great editor](http://danielmschmidt.github.io/mermaid-demo/) -#Installation +A page with a live example can be seen [here](http://www.sveido.com/mermaid/demo/html/web.html). You can also look at mermaid in action using [jsbin](http://jsbin.com/faxunexeku/1/edit?html,output). If you want a live demo, there is an editor provided in the mermaid project or you can simply look at this [great editor](http://danielmschmidt.github.io/mermaid-demo/) -Either use the bower package manager as per below: -``` -bower install mermaid --save-dev -``` - -Or download javascript files: - -* [mermaid including dependencies](http://www.sveido.com/mermaid/dist/mermaid.full.min.js) - -This file bundles mermaid with d3 and dagre-d3. - -* [mermaid without dependencies](http://www.sveido.com/mermaid/dist/mermaid.slim.min.js) - -With this file you will need to include d3 and dagre-d3 yourself. - -# Usage - -Include mermaid on your web page: - -``` - -``` - -Further down on your page mermaid will look for tags with ```class="mermaid"```. From these tags mermaid will try to -read the chart definiton which will be replaced with the svg chart. - - -A chart defined like this: -``` -
- CHART DEFINITION GOES HERE -
-``` +# [The main documentation is located in the wiki](https://github.com/knsv/mermaid/wiki) -Would end up like this: -``` -
- - Chart ends up here - -
-``` -An id is also added to mermaid tags without id. -# A graph example +# Another graph example ``` graph LR; @@ -83,209 +41,7 @@ graph LR; ![Example 2](http://www.sveido.com/mermaid/img/ex2.png) -#Syntax -## Graph -This statement declares a new graph and the direction of the graph layout. - -``` -graph TD -``` - -This declares a graph oriented from top to bottom. - -![Example 3](http://www.sveido.com/mermaid/img/ex3.png) - -``` -graph LR -``` - -This declares a graph oriented from left to right. - -Possible directions are: - -* TB - top bottom -* BT - bottom top -* RL - right left -* LR - left right -* TD - same as TB - -![Example 4](http://www.sveido.com/mermaid/img/ex4.png) - -## Nodes - -### A node (default) -``` -id1; -``` - -![Single node](http://www.sveido.com/mermaid/img/ex5.png) - -Note that the id is what is displayed in the box. - -### A node with text -It is also possible to set text in the box that differs from the id. If this is done several times, it is the last text -found for the node that will be used. Also if you define edges for the node later on, you can omit text definitions. The -one previously defined will be used when rendering the box. - -``` -id1[This is the text in the box]; -``` - -![Text in node](http://www.sveido.com/mermaid/img/ex6.png) - - -### A node with round edges -``` -id1(This is the text in the box); -``` - -![Node with round edges](http://www.sveido.com/mermaid/img/ex7.png) - -### A node in the form of a circle -``` -id1((This is the text in the box)); -``` - -![Node with round edges](http://www.sveido.com/mermaid/img/ex12.png) - -### A node in an asymetric shape -``` -id1>This is the text in the box]; -``` - -![Node with round edges](http://www.sveido.com/mermaid/img/ex13.png) - - -### A node (rhombus) -``` -id1{This is the text in the box}; -``` - -![Decision box](http://www.sveido.com/mermaid/img/ex8.png) - -### Styling a node -It is possible to apply specific styles such as a thicker border or a different background color to a node. - -``` -graph LR; - id1(Start)-->id2(Stop); - style id1 fill:#f9f,stroke:#333,stroke-width:4px; - style id2 fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5; -``` - -![Node with styles](http://www.sveido.com/mermaid/img/ex9.png) - -#### Classes -More convenient then defining the style everytime is to define a class of styles and attach this class to the nodes that -should have a different look. - -a class definition looks like the example below: - -``` - classDef className fill:#f9f,stroke:#333,stroke-width:4px; -``` - -Attachment of a class to a node is done as per below: - -``` - class nodeId1 className; -``` - -It is also possible to attach a class to a list of nodes in one statement: - -``` - class nodeId1,nodeId2 className; -``` - -#### Default class - -If a class is named default it will be assigned to all classes without specific class definitions. - -``` - classDef default fill:#f9f,stroke:#333,stroke-width:4px; -``` - - -## Links between nodes - -Nodes can be connected with links/edges. It is possible to have different types of links or attach a text string to a link. - -### A link with arrow head -``` -A-->B; -``` - -![Link with arrowhead](http://www.sveido.com/mermaid/img/ex4.png) - -### An open link - -``` -A---B; -``` - -![Open link](http://www.sveido.com/mermaid/img/ex10.png) - -### Text on links - -``` -A---|This is the text|B; -``` - -![Text on links](http://www.sveido.com/mermaid/img/ex11.png) - -### Styling links -It is possible to style links, for instance you might want to style a link that is going backwards in the flow. As links -has no ids in the same way as nodes, some other way of deciding what link the style should be attached to is required. -Instead of ids the order number of when the link was defined in the graph is used. In the example below the style -defined in the linkStyle statement will belong to the forth link in the graph: - -``` -linkStyle 3 stroke:#ff3,stroke-width:4px; -``` - -## Interaction - -It is possible to bind a click event to a node: - -``` -click nodeId callback -``` - -* nodeId is the id of the node -* callback is the name of a javascript function defined on the page displaying the graph, the function will be called with the nodeId as parameter. - -## Usage of the parser as a seperate module - -### Setup -``` -var graph = require('./graphDb'); -var flow = require('./parser/flow'); -flow.parser.yy = graph; -``` - -### Parsing - -``` -flow.parser.parse(text); -``` - -### Data extraction -``` -graph.getDirection(); -graph.getVertices(); -graph.getEdges(); -``` - -The parser is also exposed in the mermaid api by calling: -``` -var parser = mermaid.getParser(); -``` -Note that the parse needs a graph object to store the data as per: -``` -flow.parser.yy = graph; -``` -Look at graphDb.js for more details on that object. # Credits Many thanks to the [d3](http://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries! Thanks also to the [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. diff --git a/dist/mermaid.full.js b/dist/mermaid.full.js index b7ca9c56c6..a4b2dba0e3 100644 --- a/dist/mermaid.full.js +++ b/dist/mermaid.full.js @@ -15828,7 +15828,8 @@ exports.clear = function(){ exports.LINETYPE = { SOLID : 0, - DOTTED : 1 + DOTTED : 1, + NOTE : 2 }; exports.ARROWTYPE = { @@ -15846,6 +15847,7 @@ exports.addNote = function (actor, placement, message){ var note = {actor:actor, placement: placement, message:message}; notes.push(note); + messages.push({from:actor, to:actor, message:message, type:exports.LINETYPE.NOTE}); }; @@ -15861,6 +15863,57 @@ exports.parseError = function(err, hash) { var sq = require('./parser/sequenceDiagram').parser; sq.yy = require('./sequenceDb'); +/** + * Draws an actor in the diagram with the attaced line + * @param center - The center of the the actor + * @param pos The position if the actor in the liost of actors + * @param description The text in the box + */ +var drawNote = function(elem, startX, verticalPos, msg){ + var insertLinebreaks = function (d) { + var el = d3.select(this); + var words = d.split(' '); + el.text(''); + + for (var i = 0; i < words.length; i++) { + var tspan = el.append('tspan').text(words[i]); + if (i > 0) + tspan.attr('x', 0).attr('dy', '15'); + } + }; + + var g = elem.append("g"); + var rectElem = g.append("rect") + .attr("x", startX + 25) + .attr("y", verticalPos -25) + .attr("fill", '#EDF2AE') + .attr("stroke", '#666') + .attr("width", 150) + .attr("height", 100) + .attr("rx", 0) + .attr("ry", 0); + var textElem = g.append("text") + .attr("x", startX + 10) + .attr("y", verticalPos - 15) + .style("text-anchor", "start"); + msg.message.split('
').forEach(function(rowText){ + textElem.append("tspan") + .attr("x", startX + 35) + .attr("dy", '1em') + .text(rowText); + }); + + console.log('textElem.height'); + console.log(textElem[0][0].getBBox()); + rectElem.attr('height',textElem[0][0].getBBox().height+20); + //console.log(textElem.getBBox().height); + + //.text(msg.message + '\n' + msg.message) + + + return verticalPos + textElem[0][0].getBBox().height - 10; +}; + /** * Draws a flowchart in the tag with id: id based on the graph definition in text. * @param text @@ -15929,37 +15982,46 @@ module.exports.draw = function (text, id) { var g = elem.append("g"); //Make an SVG Container //Draw the line - if(msg.type===1){ - g.append("line") - .attr("x1", startx) - .attr("y1", verticalPos) - .attr("x2", stopx) - .attr("y2", verticalPos) - .attr("stroke-width", 2) - .attr("stroke", "black") - .style("stroke-dasharray", ("3, 3")) - .attr("class", "link") - .attr("marker-end", "url(#arrowhead)"); - //.attr("d", diagonal); + if(msg.type !== 2) { + if (msg.type === 1) { + g.append("line") + .attr("x1", startx) + .attr("y1", verticalPos) + .attr("x2", stopx) + .attr("y2", verticalPos) + .attr("stroke-width", 2) + .attr("stroke", "black") + .style("stroke-dasharray", ("3, 3")) + .attr("class", "link") + .attr("marker-end", "url(#arrowhead)"); + //.attr("d", diagonal); + } + else { + g.append("line") + .attr("x1", startx) + .attr("y1", verticalPos) + .attr("x2", stopx) + .attr("y2", verticalPos) + .attr("stroke-width", 2) + .attr("stroke", "black") + .attr("class", "link") + .attr("marker-end", "url(#arrowhead)"); + //.attr("d", diagonal); + } + + g.append("text") // text label for the x axis + .attr("x", txtCenter) + .attr("y", verticalPos - 10) + .style("text-anchor", "middle") + .text(msg.message); } else{ - g.append("line") - .attr("x1", startx) - .attr("y1", verticalPos) - .attr("x2", stopx) - .attr("y2", verticalPos) - .attr("stroke-width", 2) - .attr("stroke", "black") - .attr("class", "link") - .attr("marker-end", "url(#arrowhead)"); - //.attr("d", diagonal); + g.append("text") // text label for the x axis + .attr("x", txtCenter) + .attr("y", verticalPos - 10) + .style("text-anchor", "middle") + .text(msg.message); } - - g.append("text") // text label for the x axis - .attr("x", txtCenter) - .attr("y", verticalPos-10) - .style("text-anchor", "middle") - .text(msg.message); }; // Fetch data from the parsing @@ -16001,7 +16063,15 @@ module.exports.draw = function (text, id) { var startx = actors[msg.from].x + width/2; var stopx = actors[msg.to].x + width/2; var txtCenter = startx + (stopx-startx)/2; - drawMessage(diagram, startx, stopx, verticalPos, txtCenter, msg); + if(msg.type === 2){ + console.log('VP before:',verticalPos); + verticalPos = drawNote(diagram, startx, verticalPos, msg); + console.log('VP after:',verticalPos); + } else { + drawMessage(diagram, startx, stopx, verticalPos, txtCenter, msg); + // Keep track of width for with setting on the svg + maxX = Math.max(maxX,startx + 176); + } }); diff --git a/dist/mermaid.slim.js b/dist/mermaid.slim.js index 6585de7141..44efdaf23e 100644 --- a/dist/mermaid.slim.js +++ b/dist/mermaid.slim.js @@ -15796,7 +15796,8 @@ exports.clear = function(){ exports.LINETYPE = { SOLID : 0, - DOTTED : 1 + DOTTED : 1, + NOTE : 2 }; exports.ARROWTYPE = { @@ -15814,6 +15815,7 @@ exports.addNote = function (actor, placement, message){ var note = {actor:actor, placement: placement, message:message}; notes.push(note); + messages.push({from:actor, to:actor, message:message, type:exports.LINETYPE.NOTE}); }; @@ -15829,6 +15831,57 @@ exports.parseError = function(err, hash) { var sq = require('./parser/sequenceDiagram').parser; sq.yy = require('./sequenceDb'); +/** + * Draws an actor in the diagram with the attaced line + * @param center - The center of the the actor + * @param pos The position if the actor in the liost of actors + * @param description The text in the box + */ +var drawNote = function(elem, startX, verticalPos, msg){ + var insertLinebreaks = function (d) { + var el = d3.select(this); + var words = d.split(' '); + el.text(''); + + for (var i = 0; i < words.length; i++) { + var tspan = el.append('tspan').text(words[i]); + if (i > 0) + tspan.attr('x', 0).attr('dy', '15'); + } + }; + + var g = elem.append("g"); + var rectElem = g.append("rect") + .attr("x", startX + 25) + .attr("y", verticalPos -25) + .attr("fill", '#EDF2AE') + .attr("stroke", '#666') + .attr("width", 150) + .attr("height", 100) + .attr("rx", 0) + .attr("ry", 0); + var textElem = g.append("text") + .attr("x", startX + 10) + .attr("y", verticalPos - 15) + .style("text-anchor", "start"); + msg.message.split('
').forEach(function(rowText){ + textElem.append("tspan") + .attr("x", startX + 35) + .attr("dy", '1em') + .text(rowText); + }); + + console.log('textElem.height'); + console.log(textElem[0][0].getBBox()); + rectElem.attr('height',textElem[0][0].getBBox().height+20); + //console.log(textElem.getBBox().height); + + //.text(msg.message + '\n' + msg.message) + + + return verticalPos + textElem[0][0].getBBox().height - 10; +}; + /** * Draws a flowchart in the tag with id: id based on the graph definition in text. * @param text @@ -15897,37 +15950,46 @@ module.exports.draw = function (text, id) { var g = elem.append("g"); //Make an SVG Container //Draw the line - if(msg.type===1){ - g.append("line") - .attr("x1", startx) - .attr("y1", verticalPos) - .attr("x2", stopx) - .attr("y2", verticalPos) - .attr("stroke-width", 2) - .attr("stroke", "black") - .style("stroke-dasharray", ("3, 3")) - .attr("class", "link") - .attr("marker-end", "url(#arrowhead)"); - //.attr("d", diagonal); + if(msg.type !== 2) { + if (msg.type === 1) { + g.append("line") + .attr("x1", startx) + .attr("y1", verticalPos) + .attr("x2", stopx) + .attr("y2", verticalPos) + .attr("stroke-width", 2) + .attr("stroke", "black") + .style("stroke-dasharray", ("3, 3")) + .attr("class", "link") + .attr("marker-end", "url(#arrowhead)"); + //.attr("d", diagonal); + } + else { + g.append("line") + .attr("x1", startx) + .attr("y1", verticalPos) + .attr("x2", stopx) + .attr("y2", verticalPos) + .attr("stroke-width", 2) + .attr("stroke", "black") + .attr("class", "link") + .attr("marker-end", "url(#arrowhead)"); + //.attr("d", diagonal); + } + + g.append("text") // text label for the x axis + .attr("x", txtCenter) + .attr("y", verticalPos - 10) + .style("text-anchor", "middle") + .text(msg.message); } else{ - g.append("line") - .attr("x1", startx) - .attr("y1", verticalPos) - .attr("x2", stopx) - .attr("y2", verticalPos) - .attr("stroke-width", 2) - .attr("stroke", "black") - .attr("class", "link") - .attr("marker-end", "url(#arrowhead)"); - //.attr("d", diagonal); + g.append("text") // text label for the x axis + .attr("x", txtCenter) + .attr("y", verticalPos - 10) + .style("text-anchor", "middle") + .text(msg.message); } - - g.append("text") // text label for the x axis - .attr("x", txtCenter) - .attr("y", verticalPos-10) - .style("text-anchor", "middle") - .text(msg.message); }; // Fetch data from the parsing @@ -15969,7 +16031,15 @@ module.exports.draw = function (text, id) { var startx = actors[msg.from].x + width/2; var stopx = actors[msg.to].x + width/2; var txtCenter = startx + (stopx-startx)/2; - drawMessage(diagram, startx, stopx, verticalPos, txtCenter, msg); + if(msg.type === 2){ + console.log('VP before:',verticalPos); + verticalPos = drawNote(diagram, startx, verticalPos, msg); + console.log('VP after:',verticalPos); + } else { + drawMessage(diagram, startx, stopx, verticalPos, txtCenter, msg); + // Keep track of width for with setting on the svg + maxX = Math.max(maxX,startx + 176); + } }); diff --git a/src/diagrams/sequenceDiagram/sequenceDb.js b/src/diagrams/sequenceDiagram/sequenceDb.js index 4ece1c24bb..c6b0512764 100644 --- a/src/diagrams/sequenceDiagram/sequenceDb.js +++ b/src/diagrams/sequenceDiagram/sequenceDb.js @@ -42,7 +42,8 @@ exports.clear = function(){ exports.LINETYPE = { SOLID : 0, - DOTTED : 1 + DOTTED : 1, + NOTE : 2 }; exports.ARROWTYPE = { @@ -60,6 +61,7 @@ exports.addNote = function (actor, placement, message){ var note = {actor:actor, placement: placement, message:message}; notes.push(note); + messages.push({from:actor, to:actor, message:message, type:exports.LINETYPE.NOTE}); }; diff --git a/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js b/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js index f098c4514a..9aeeda50e7 100644 --- a/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js +++ b/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js @@ -52,11 +52,11 @@ describe('when parsing a sequenceDiagram',function() { var messages = sq.yy.getMessages(); - expect(messages.length).toBe(2); + expect(messages.length).toBe(3); //console.log('messages'); //console.log(messages); expect(messages[0].from).toBe('Alice'); - expect(messages[1].from).toBe('Bob'); + expect(messages[2].from).toBe('Bob'); }); }); \ No newline at end of file diff --git a/src/diagrams/sequenceDiagram/sequenceRenderer.js b/src/diagrams/sequenceDiagram/sequenceRenderer.js index dd824d8594..b2325527a9 100644 --- a/src/diagrams/sequenceDiagram/sequenceRenderer.js +++ b/src/diagrams/sequenceDiagram/sequenceRenderer.js @@ -6,6 +6,57 @@ var sq = require('./parser/sequenceDiagram').parser; sq.yy = require('./sequenceDb'); +/** + * Draws an actor in the diagram with the attaced line + * @param center - The center of the the actor + * @param pos The position if the actor in the liost of actors + * @param description The text in the box + */ +var drawNote = function(elem, startX, verticalPos, msg){ + var insertLinebreaks = function (d) { + var el = d3.select(this); + var words = d.split(' '); + el.text(''); + + for (var i = 0; i < words.length; i++) { + var tspan = el.append('tspan').text(words[i]); + if (i > 0) + tspan.attr('x', 0).attr('dy', '15'); + } + }; + + var g = elem.append("g"); + var rectElem = g.append("rect") + .attr("x", startX + 25) + .attr("y", verticalPos -25) + .attr("fill", '#EDF2AE') + .attr("stroke", '#666') + .attr("width", 150) + .attr("height", 100) + .attr("rx", 0) + .attr("ry", 0); + var textElem = g.append("text") + .attr("x", startX + 10) + .attr("y", verticalPos - 15) + .style("text-anchor", "start"); + msg.message.split('
').forEach(function(rowText){ + textElem.append("tspan") + .attr("x", startX + 35) + .attr("dy", '1em') + .text(rowText); + }); + + console.log('textElem.height'); + console.log(textElem[0][0].getBBox()); + rectElem.attr('height',textElem[0][0].getBBox().height+20); + //console.log(textElem.getBBox().height); + + //.text(msg.message + '\n' + msg.message) + + + return verticalPos + textElem[0][0].getBBox().height - 10; +}; + /** * Draws a flowchart in the tag with id: id based on the graph definition in text. * @param text @@ -74,37 +125,46 @@ module.exports.draw = function (text, id) { var g = elem.append("g"); //Make an SVG Container //Draw the line - if(msg.type===1){ - g.append("line") - .attr("x1", startx) - .attr("y1", verticalPos) - .attr("x2", stopx) - .attr("y2", verticalPos) - .attr("stroke-width", 2) - .attr("stroke", "black") - .style("stroke-dasharray", ("3, 3")) - .attr("class", "link") - .attr("marker-end", "url(#arrowhead)"); - //.attr("d", diagonal); + if(msg.type !== 2) { + if (msg.type === 1) { + g.append("line") + .attr("x1", startx) + .attr("y1", verticalPos) + .attr("x2", stopx) + .attr("y2", verticalPos) + .attr("stroke-width", 2) + .attr("stroke", "black") + .style("stroke-dasharray", ("3, 3")) + .attr("class", "link") + .attr("marker-end", "url(#arrowhead)"); + //.attr("d", diagonal); + } + else { + g.append("line") + .attr("x1", startx) + .attr("y1", verticalPos) + .attr("x2", stopx) + .attr("y2", verticalPos) + .attr("stroke-width", 2) + .attr("stroke", "black") + .attr("class", "link") + .attr("marker-end", "url(#arrowhead)"); + //.attr("d", diagonal); + } + + g.append("text") // text label for the x axis + .attr("x", txtCenter) + .attr("y", verticalPos - 10) + .style("text-anchor", "middle") + .text(msg.message); } else{ - g.append("line") - .attr("x1", startx) - .attr("y1", verticalPos) - .attr("x2", stopx) - .attr("y2", verticalPos) - .attr("stroke-width", 2) - .attr("stroke", "black") - .attr("class", "link") - .attr("marker-end", "url(#arrowhead)"); - //.attr("d", diagonal); + g.append("text") // text label for the x axis + .attr("x", txtCenter) + .attr("y", verticalPos - 10) + .style("text-anchor", "middle") + .text(msg.message); } - - g.append("text") // text label for the x axis - .attr("x", txtCenter) - .attr("y", verticalPos-10) - .style("text-anchor", "middle") - .text(msg.message); }; // Fetch data from the parsing @@ -146,7 +206,15 @@ module.exports.draw = function (text, id) { var startx = actors[msg.from].x + width/2; var stopx = actors[msg.to].x + width/2; var txtCenter = startx + (stopx-startx)/2; - drawMessage(diagram, startx, stopx, verticalPos, txtCenter, msg); + if(msg.type === 2){ + console.log('VP before:',verticalPos); + verticalPos = drawNote(diagram, startx, verticalPos, msg); + console.log('VP after:',verticalPos); + } else { + drawMessage(diagram, startx, stopx, verticalPos, txtCenter, msg); + // Keep track of width for with setting on the svg + maxX = Math.max(maxX,startx + 176); + } }); diff --git a/test/web.html b/test/web.html index 1acd2812c1..3640306348 100644 --- a/test/web.html +++ b/test/web.html @@ -39,7 +39,7 @@

Shapes

di{Diamond is
broken}-->ro(Rounded
square
shape); di-->ro2(Rounded square shape); %% Comments after double percent signs - e((Inner circle))-->f(,.?!+-*ز); + e((Inner / circle))-->f(,.?!+-*ز); cyr[Cyrillic]-->cyr2((Circle shape Начало)); style e red; @@ -58,7 +58,7 @@

Sequence diagrams (experimental)

sequenceDiagram Alice->Bob: Hello Bob, how are you? - Note right of Bob: Bob thinks + Note right of Bob: Bob thinks about
things
to think about Bob-->Alice: I am good thanks! Bob-->John the Long: How about you John? Bob-->Alice: Checking with John...