Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

With tikz is there any way of having a callout shape that points to more than one place?

I would like to use a callout shape to explain some parts of a graph. This callout shape would point to different elements in the graph, as the explanation is the same for a set of elements.

Here is a minimal working example:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{automata,shapes,arrows}
\begin{document}
\begin{tikzpicture}[node distance=2cm, auto]
  \node[state,initial]   (s0)               {$s_0$};
  \node[state]           (s1) [right of=s0] {$s_1$};
  \node[state,accepting] (s2) [right of=s1] {$s_2$};
  \path[->]
    (s0) edge node {a} (s1)
    (s1) edge node {c} (s2)
         edge [loop above] node {b} ();
  \node[fill=green!20, rectangle callout, callout absolute pointer={(s0.south)}]
       [below of=s0] {
         \parbox{2cm}{Each circle is a \emph{state} of the automaton}};
\end{tikzpicture}
\end{document}

which produces the output

explaining multiple elements

I want the callout pointing to all three nodes of the automaton.

share|improve this question
    
MWE? Two ideas: 1. Modifiying the shape. 2. Two otherwise identical shapes overlaying but with different pointers. 3. Combination of 1. and 2.: A shape that only draws the pointers so that the overlaying would be a little bit more effective. –  Qrrbrbirlbel Apr 18 '13 at 20:46
    
Why was the question down-voted? –  Romildo Apr 18 '13 at 21:31
    
It wasn't. It is still on +2/-0. –  mafp Apr 18 '13 at 22:30
    
@mafp Downvote might be due to the missing MWE and picture image as seen in your Q revision history. Once you posted them all is well. –  texenthusiast Apr 19 '13 at 5:41
    
@texenthusiast Click on the score: +4/-0. There is no downvote. –  mafp Apr 19 '13 at 7:39
add comment

1 Answer

up vote 6 down vote accepted

This updates (→ first revision) includes an improved multiple absolute pointers key.

The to-be-used shape is now taken from the usual shape key (default: rectangle). Do not use the option rectangle callout! It will used automatically.

The un-starred version draws an extra node (but without the pointer). The list of multiple pointers understands now optional options that only affect the callout shape with that pointer.

This obviously doesn’t mix well with any draw option other than none. A border that does not cross any pointers will have to be drawn manually (which is difficult enough for the rectangle callout shape).

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{automata,shapes,arrows}
\makeatletter
\tikzset{
  expand me/.style={#1},
  multiple absolute pointers/.style args={#1[#2]#3#4}{
    insert path={
      \foreach \qrr@tikz@calloutabsolutepointer in {#3} {
        \pgfextra
          \expandafter\pgfutil@ifnextchar\expandafter[%
          \expandafter\qrr@tikz@parse@calloutabsolutepointer\expandafter{%
          \expandafter\qrr@tikz@parse@calloutabsolutepointer\expandafter[\expandafter]\expandafter}\qrr@tikz@calloutabsolutepointer\@qrr@tikz@parse@calloutabsolutepointer
        \endpgfextra
        node[#2, shape/.expanded=\tikz@shape\space callout, expand me/.expanded=\qrr@tikz@calloutabsolutepointer@options, callout absolute pointer={(\qrr@tikz@calloutabsolutepointer@)}] {#4}
      }
      \pgfextra
        \def\pgf@tempa{#1}
        \pgfutil@in@*{#1}
        \ifpgfutil@in@\else
          \pgfkeysalso{insert path={node[#2] {#4}}}
        \fi
      \endpgfextra}}}

\def\qrr@tikz@parse@calloutabsolutepointer[#1]#2\@qrr@tikz@parse@calloutabsolutepointer{%
  \gdef\qrr@tikz@calloutabsolutepointer@options{#1}%
  \gdef\qrr@tikz@calloutabsolutepointer@{#2}%
}
\makeatother
\begin{document}
\begin{tikzpicture}[node distance=2cm, auto]
  \node[state,initial]   (s0)               {$s_0$};
  \node[state]           (s1) [right of=s0] {$s_1$};
  \node[state,accepting] (s2) [right of=s1] {$s_2$};
  \path[->]
    (s0) edge node {a} (s1)
    (s1) edge node {c} (s2)
         edge [loop above] node {b} ();
  \path[multiple absolute pointers={
    [fill=green!20, text width=2.1cm, below of=s0]
    {[fill=blue!20]s1.south,[fill=red!20]s2.south,[fill=yellow!60]s0.south}
    {Each circle is a \emph{state} of the automaton}
  }];
\end{tikzpicture}
\end{document}

Output

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.