11

I want to create a flowchart diagram with a comment:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{tikz}
\usetikzlibrary{shapes,backgrounds,calc}
\begin{document}

\begin{tikzpicture}[node distance = 1.7cm, auto]
\tikzset{
        line/.style = {draw},
        comment/.style = {rectangle, draw, text centered, rounded corners, minimum height=2em,fill=white},
        terminator/.style = {shape=rounded rectangle, draw, inner sep=2mm},
}

\node[terminator] (node-1) {begin};

\node [comment, below of=node-1] (node-2) {comment comment comment};

\begin{scope}[on background layer]
  \draw[fill=gray!40] ($(node-2.south west)+(-2mm,-2mm)$) rectangle ($(node-2.north east)+(2mm, 2mm)$);
\end{scope}

\path [line] (node-1) -- ($(node-2.north)+(0mm,+2mm)$);

\node[terminator, below of=node-2, node distance=1.5cm] (node-3) {end};

\path [line] ($(node-2.south)+(0mm,-2mm)$) -- (node-3);

\end{tikzpicture}
\end{document}

It gives this:

enter image description here

But comment is not a block, but 2 elements: background layer and a rounded rectangle. How to make new shape from it with anchors?

user4035
  • 5,035
  • 6
  • 40
  • 57

2 Answers2

10

It's tricky but it could work. You can draw the background node and place a label node over it with center option.

Problems: you have to adjust main node size repeating same text and fixing inner sep. Advantatge: you can use main node anchors to draw edges.

\documentclass[tikz,border=2mm]{standalone}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usetikzlibrary{shapes}
\begin{document}

\begin{tikzpicture}[node distance = 1.7cm, auto]
\tikzset{
        line/.style = {draw},
        comment/.style = {rectangle, draw, text centered, 
                rounded corners, minimum height=2em,fill=white},
        comment border/.style = {comment, rounded corners=0pt, 
                fill=gray!40, inner sep=4mm, minimum height=2em+4mm},
        terminator/.style = {shape=rounded rectangle, draw, inner sep=2mm},
}

\node[terminator] (node-1) {begin};

\node [comment border, below of=node-1,
       label={[comment]center:comment comment comment}] 
      (node-2) {comment comment comment};

\node[terminator, below of=node-2, node distance=1.5cm] (node-3) {end};

\draw (node-1)--(node-2);
\draw (node-2)--(node-3);

\end{tikzpicture}
\end{document}

enter image description here

If you don't want to use this trick, try with makeshape which today was announced in CTAN.

EDIT: 2on Option

Another not so tricky option would be to use a matrix of nodes node. A matrix is a node which contains other nodes, therefore it's possible to apply different styles to the matrix and every node.

comment/.style = {matrix of nodes, 
% Next lines apply to matrix and all inner nodes
                  draw, fill=gray!40, inner sep=5pt, 
% Next lines define style for inner nodes.
% It's possible to change previous options 
                  nodes={text centered, rounded corners, minimum height=2em, 
                          fill=white, inner sep=3pt}
                  },

All rows inside a matrix has to be finished with '\', then we need to be careful when using comment nodes and include \\ inside the text part:

\node [comment, below of=node-1] 
      (node-2) {comment comment comment\\};

The result will be the same, but the code changes to:

\documentclass[tikz,border=2mm]{standalone}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usetikzlibrary{shapes,matrix} %<- Don't forget matrix library
\begin{document}
\begin{tikzpicture}[node distance = 1.7cm, auto]
\tikzset{
        line/.style = {draw},
        comment/.style = {matrix of nodes, 
        % Next lines apply to matrix and all inner nodes
                           draw, fill=gray!40, inner sep=5pt, 
        % Next lines define style for inner nodes.
        % It's possible to change previous options 
                          nodes={text centered, rounded corners, minimum height=2em, 
                          fill=white, inner sep=3pt}
                          },            
        terminator/.style = {shape=rounded rectangle, draw, inner sep=2mm},
}

\node[terminator] (node-1) {begin};

\node [comment, below of=node-1] 
      (node-2) {comment comment comment\\};

\node[terminator, below of=node-2, node distance=1.5cm] (node-3) {end};

\draw (node-1)--(node-2);
\draw (node-2)--(node-3);

\end{tikzpicture}
Ignasi
  • 136,588
5

Here is a solution via append path picture:

enter image description here

\documentclass[tikz]{standalone}
\usetikzlibrary{positioning}
\tikzset{
        line/.style = {draw},
        comment/.style = {
          draw, text centered,
          minimum height=2em+4mm, inner xsep=.3333em+4mm,
          append after command={\pgfextra{
              \pgfinterruptpath
              % fill white
              \fill[white] (\tikzlastnode.south west)
              rectangle (\tikzlastnode.north east);
              % fill gray region
              \fill[fill=gray,even odd rule,draw]
              (\tikzlastnode.south west) rectangle (\tikzlastnode.north east)
              [rounded corners]
              ([shift={(2mm,2mm)}]\tikzlastnode.south west)
              rectangle ([shift={(-2mm,-2mm)}]\tikzlastnode.north east);
              \endpgfinterruptpath
            }
          },
        },
        terminator/.style = {rounded corners, draw, inner sep=2mm},
}
\begin{document}
\begin{tikzpicture}[on grid,node distance=1.7cm]
\node[terminator] (node-1) {begin};
\node [comment, below=1.7cm of node-1] (node-2) {comment comment comment};
\path [line] (node-1) -- (node-2);
\node[terminator, below=1.5cm of node-2] (node-3) {end};
\path [line] (node-2) -- (node-3);
\end{tikzpicture}
\end{document}
Paul Gaborit
  • 70,770
  • 10
  • 176
  • 283