The reason is that you have specified the foo
style with a default key which kicks in if none given.
What you need to realize is that a style only applies to the current segment of code. \draw[foo] ...
and \draw[color=black]
is equivalent in your case.
Usage of keys
When you use keys you have to explicitly use them or redefine them.
Consider this:
\tikzset{
foo/.style={#1},
bar/.style={foo={#1}}
}
This will let foo
have an empty style! It will simply do nothing unless you add an argument.
\draw[foo={color=green,thick}]
is thus equivalent to \draw[color=green,thick]
. Also \draw[bar={color=green,thick}]
is equivalent to \draw[foo={color=green,thick}]
. It is just another alias for the same key.
If you however do the styles like this:
\tikzset{
foo/.style={#1},
bar/.style={foo/.append style={#1}}
}
You will collect styles in to the key foo
by using style bar
. This is very good in cases where scoped environments are used:
\begin{tikzpicture} % Now all styles who uses foo will do nothing
\draw[foo] (0,0) -- ++(1,0);
\begin{scope}[foo=very thick,bar={color=red},yshift=-1ex]
\draw[foo] (0,0) -- ++(1,0); % Will be red and thick
\draw[foo=dotted] (0,-1ex) -- ++(1,0); % Will be red and thick and dashed
\end{scope}
\end{tikzpicture}
However, as you can see using bar
has the effect of adding to the foo
style until the end of the environment.
In your case
What goes wrong?
If we use the following definitions and the following code it is seen that other behaviour is taking place
\tikzset{
foo/.style={color=#1},
foo/.default=black, % If no argument is given then this kicks in as argument.
bar/.style={foo/.append style={#1}}
}
\begin{tikzpicture}[foo=red] % Now everything will have the style red attached
\draw (0,0) -- ++(1,0); % red
\draw[foo] (0,-1ex) -- ++(1,0); % will have black color as foo is called without an argument, so /.default kicks in!
\begin{scope}[bar=very thick,yshift=-2ex]
\draw[foo] (0,0) -- ++(1,0); % Will be thick, but not red
\draw[foo=red] (0,-1ex) -- ++(1,0); % Will be red and thick
\end{scope}
\end{tikzpicture}
Remember everytime you define default
this will be the argument passed if none is given. Thus it could potentially overwrite what you have done.
However as you will see here everything that is not related to the argument #1
is handled properly
\tikzset{
foo/.style={dashed,color=#1},
foo/.default=black, % If no argument is given then this kicks in as argument.
bar/.style={foo/.append style={#1}}
}
\begin{tikzpicture}[foo=red] % Now everything will have the style red and dashed attached
\draw (0,0) -- ++(1,0); % red, dashed
\draw[foo] (0,-1ex) -- ++(1,0); % will have black color and dashed as foo is called with out an argument, so /.default kicks in!
\begin{scope}[bar=very thick,yshift=-2ex]
\draw[foo] (0,0) -- ++(1,0); % Will be dashed, thick, but not red
\draw[foo=red] (0,-1ex) -- ++(1,0); % Will be red and thick and dashed
\end{scope}
\end{tikzpicture}
Keys are read consecutively
If you write dashed,very thick,dotted,thick
it will only be dotted and thick, not very thick, nor combined dashed and dotted.
Solution to your problem
The solution is to use another key as the style, but which you never should need to use otherwise.
\tikzset{
foo hidden/.style={}, % Provide a hidden style
foo/.style={foo hidden/.append style={color=#1}}, % foo changes `foo hidden`
foo/.default=orange,
bar hidden/.style={},
bar/.style={bar hidden/.append style={color=#1}}, % bar changes `bar hidden`
bar/.default=green,
}
\NewDocumentCommand{\drawthing}{o}{
\tikz[#1]{\draw[thick,foo hidden] (0,1)--(1,0);
\draw[thick,foo hidden] (0,0)--(1,1);
\draw[thick,bar hidden] (0,0) -- (0,1);
}
}
Blue and red: \drawthing[foo=red,bar=blue]
Green and blue: \drawthing[foo=blue,bar]
Black and orange: \drawthing[foo]
If you want it to always have the default you are then allowed to do:
\NewDocumentCommand{\drawthing}{o}{
\tikz[foo,bar,#1]{\draw[thick,foo hidden] (0,1)--(1,0);
\draw[thick,foo hidden] (0,0)--(1,1);
\draw[thick,bar hidden] (0,0) -- (0,1);
}
}