# Problem with “append after command” and “insert path”

I have an example to explain my problem but if the code compiles and if I get a good result, I don't understand why !

The idea is to split a circle node like in this question . I want to fill the node with two colors.

It's not possible to use the same code but perhaps I'm wrong.

1) first with insert path, I think I can't use \tikzlastnode because this macro is not defined. \pgf@node@name seems to be defined only for multipart node.

2) I try with append after command but the code is strange. I need to use a scope with the background layer. But

     \node[ circle,
draw=blue,
text=white,
font=\bfseries,
append after command={
\pgfextra{%
\pgfpointdiff{\pgfpointanchor{\tikzlastnode}{center}}%
{\pgfpointanchor{\tikzlastnode}{east}}%
\begin{scope}[on background layer]
\fill[orange] (\tikzlastnode.center)
([xshift=\pgflinewidth]\tikzlastnode.west)  arc
\fill[red]    (\tikzlastnode.center)
([xshift=-\pgflinewidth]\tikzlastnode.east) arc
\end{scope}
}
},text opacity=1] (last name) {big label};


gives

and if I remove the scope environment, the same code

        \fill[orange] (\tikzlastnode.center)
([xshift=\pgflinewidth]\tikzlastnode.west)  arc
\fill[red]  (\tikzlastnode.center)
([xshift=-\pgflinewidth]\tikzlastnode.east) arc


give a bad result too :

The only code correct seems to be :

 \documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{shapes,backgrounds,calc}

\begin{document}

\makeatletter
\begin{tikzpicture}[line width=3mm]
\node[ circle,
draw=blue,
text=white,
font=\bfseries,
append after command={
\pgfextra{%
\pgfpointdiff{\pgfpointanchor{\tikzlastnode}{center}}%
{\pgfpointanchor{\tikzlastnode}{east}}%
\fill[orange] (\tikzlastnode.center)
([xshift=\pgflinewidth]\tikzlastnode.west)  arc
\begin{scope}[on background layer]
\fill[red]  (\tikzlastnode.center)
([xshift=-\pgflinewidth]\tikzlastnode.east) arc
\end{scope}
}
},text opacity=1] (last name) {big label};

\end{tikzpicture}
\end{document}


and I get :

My question is why I need to use like this the scope. A second question is to know if there is another way to get the name of the last node than \pgf@node@name and \tikzlastnode.

Perhaps someone knows another method to get the same result.

Remark :

In the link (multipart node given above) I realized at the end that I could remove the environment scopebut it was a surprise for me. It seems that the text is placed at the end of the construction of the shape.

-

What's causing the strange behaviour here is the fact that you are nesting path constructions. As I'm sure you know, when TikZ constructs a path then it handles nodes in a slightly special way. They are processed as they are encountered (since information about them is needed later) but they aren't placed until after the path has been constructed. To do this, TikZ stores the nodes in a box, \tikz@figbox, until it is time to place them.

The append after command key sticks a bit extra in the current path after the node command has been processed. The important thing to note is that this is before the actual node has been placed. This is what you want since you want the two half circles to be placed behind the node. However, what TikZ is expecting from the append after command is an extension of the current path, not a whole new path construction! So it doesn't do anything special to protect the current path from whatever you do in the append after command code. In this case, what you do is create a whole new path! In fact, you create two of them.

It's the two of them that is causing the immediate problem, but I can imagine situations where even one would be problematic. The problem is that the node box, \tikz@figbox, is being used inside the first path: TikZ thinks that the nodes from the parent path are actually nodes on the first child path. They get used there, then the box is cleared, and the second child path is drawn therefore on top of the node.

The remedy is to protect the node box from the child paths. Looking at the TikZ code, there are other places where this has to be done: preactions and postactions. There, the code is:

\def\tikz@extra@preaction#1{%
{%
\pgfsys@beginscope%
\setbox\tikz@figbox=\box\pgfutil@voidb@x%
\path[#1];% do extra path
\pgfsyssoftpath@setcurrentpath\tikz@actions@path% restore
\tikz@restorepathsize%
\pgfsys@endscope%
}%
}


As you're doing a node, not a path, you probably don't need to worry about the actual path or any details of the scope (though it may be safest to put them in for a more complicated example). All you actually need is the grouping and the \tikz@figbox declaration. Hence the following works:

\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usepackage{trace-pgfkeys}
\usetikzlibrary{shapes,backgrounds,calc}

\begin{document}
\makeatletter
\begin{tikzpicture}[line width=3mm]
\node[ circle,
draw=blue,
text=white,
font=\bfseries,
append after command={
\pgfextra{%
\pgfpointdiff{\pgfpointanchor{\tikzlastnode}{center}}%
{\pgfpointanchor{\tikzlastnode}{east}}%
{
\setbox\tikz@figbox=\box\pgfutil@voidb@x
\fill[orange] (\tikzlastnode.center)
([xshift=\pgflinewidth]\tikzlastnode.west)  arc
\fill[red]  (\tikzlastnode.center)
([xshift=-\pgflinewidth]\tikzlastnode.east) arc
}
}
},text opacity=1] {big label};
\end{tikzpicture}
\end{document}


with result:

-
\setbox\tikz@figbox=\box\pgfutil@voidb@x  great idea. Intuitively I thought that you expressed very well in your answer but I was not able to organize my ideas. Now it's more clearer and clever. Thanks for this great answer and thanks for \tikz@figbox !! –  Alain Matthes May 14 '12 at 11:47
Yet another great explanation! –  percusse May 14 '12 at 13:05

One peculiar detail about the append after command usage is that it has to sit inside a path construction command. In other words, the node must be interrupting a path construction so that whenever it is declared the path construction can continue. But you are using it inside a node command hence things get weird.

You can place your node inside a path command while calculation of the radius can be done via a let operation. I have filled the background with a light blue color and placed the half filled node on top of it. It is still puzzling for me how we can fill the other half with a different color. This is difficult since the color is dictated by the \path[fill=red] and I don't know how to change inside a path command. Another option would be going to the lower level and using \pgfpositionnodelater type of commands to set up the whole node creation process.

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,backgrounds,calc}
\begin{document}
\begin{tikzpicture}
\begin{scope}
\clip (0,0) circle (2.65cm);
\fill[blue!25] (-5cm,-5cm) rectangle (5cm,5cm);
\path[fill=red] node[circle,
line width=3mm,
minimum height=5cm,
draw=blue,
text=white,
font=\bfseries,
append after command={
let \p1=(a.east),\p2=(a.center),\n1={veclen(\x1-\x2,0)}
in (a.east) arc (0:180:\n1) -- cycle
}
] at (0,0) (a) {\huge big label};
\end{scope}
\end{tikzpicture}
\end{document}


It's not quite portable as it is but via defining a new style this can probably float.

-
Or you can directly create a new shape by inheriting from circle and adding a \behindbackgroundpath{} code –  percusse May 14 '12 at 2:32
It's not exactly what I want. My style works. I want to find an explanation about the need of \begin{scope}[on background layer] inside the  append after command. It's not satisfactory to have a code and do not understand. –  Alain Matthes May 14 '12 at 6:56
I added the results when I move the scopes. I would like to understand these three codes. –  Alain Matthes May 14 '12 at 7:03
@Altermundus If you put your node over a colored surface it would lose the top color. –  percusse May 14 '12 at 10:43