Here is one way to do it.
The process is bottum-up
(i.e. starting simple) combined with refactoring
(generalize multiplicates). Any such code can be considered transitory, i.e. as a kind of snapshot, which works and still can be made more universal.
With two typos ...
Bottom-up idea
- draw the three lines AND put nodes there via
pos
- move the nodes names a, b, ... inside the nodes to reduce visual noise
- put the vector-labels
- connect all relevant nodes
- put some extras, like P1..P3
- on the way introduce styles as needed (which is already one act of refactoring)
Universal macro as you intend
Following this approach I suggest using a mixed approach. First, let's have a look at a section where refactoring
/generalization
is simple to do:
% ~~~ refactored ~~~~~~~~~~~
\newcommand\vlab[3]{\foreach \v [count=\j] in {#2}%
\node[#3] at (#1\j) {\v};}
...
% ~~~ vector labels ~~~~~~~~~~~~~~~~
%% BEFORE refactoring
% \foreach \v [count=\j] in {(1,0,0), (2,0,0), (3,1,0),
% (4,1,0), (5,1,2), (6,1,2), (7,1,2)}
% \node[vlu] at (A\j) {\v};
%
% \foreach \v [count=\j] in {(0,1,0), (2,2,0), (6,3,2)}
% \node[vld] at (B\j) {\v};
%
% \foreach \v [count=\j] in {(1,0,1), (0,0,2)}
% \node[vld] at (C\j) {\v};
%% AFTER refactoring
\vlab{A}{((1,0,0), (2,0,0), (3,1,0), (4,1,0), (5,1,2), (6,1,2), (7,1,2))}{vlu}
\vlab{B}{(0,1,0), (2,2,0), (6,3,2)}{vld}
\vlab{C}{(1,0,1), (0,0,2)}{vld}
I started with the 3 \foreach
loops, which could be absorbed easily by macro \vlab
. The order of parameters is historical: it may be better to chose a different order (which is a refactoring
consideration).
Whether or not you want to even absorb the nodes "name" A, B, C also, is a matter of preference. In this place code would look more complicated afterwards with little to no benefit (which is a refactoring
decision).
Second
, a place where it's harder to do:
% ~~~ lines with events ~~~~~~~~~
\draw (0,4) -- node[ev,pos=.1] (A1) {a}
node[ev,pos=.3] (A2) {b}
node[ev,pos=.4] (A3) {c}
node[ev,pos=.6] (A4) {d}
node[ev,pos=.7] (A5) {f}
node[ev,pos=.8] (A6) {g}
node[ev,pos=.95] (A7) {h}
+(10,0);
...
AFAIK, these nodes can't be absorbed by a \foreach
loop from Tikz. But you can use other loop constructs, if you want. My preference would be: use it as-is, copy&paste & modify as needed. I.e. leave as-is (which is a refactoring
decision).
If you follow this approach, with frequent compile, back-up and refactoring, you'll approach the macro you started out more and more, but in an organic way. And it certainly will look very diffent in the end on code level.
By intention I left some places without refactoring:
- this happens anyway
- is both transitory and a demo
Here, moving the nodes options into a style is what a refactor
er can't overlook ;-)
% ~~~ axis labels ~~~~~~~~~
% unrefactored
\node[anchor=east] at (0,4) {P1};
\node[anchor=east] at (0,2) {P2};
\node[anchor=east] at (0,0) {P3};
The rest is pretty straight forward ...
\documentclass[10pt,border=3mm,tikz]{standalone}
\usetikzlibrary{arrows.meta}
% ~~~ refactored ~~~~~~~~~~~
\newcommand\vlab[3]{\foreach \v [count=\j] in {#2}%
\node[#3] at (#1\j) {\v};}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{document}
\begin{tikzpicture}[
ev/.style={circle,fill=white,draw,font=\small},
>={Stealth},
vlu/.style={cyan,yshift=6mm,font=\small}, % task; refactor vlu+vld
vld/.style={cyan,yshift=-6mm,font=\small},
]
% ~~~ lines with events ~~~~~~~~~
\draw (0,4) -- node[ev,pos=.1] (A1) {a}
node[ev,pos=.3] (A2) {b}
node[ev,pos=.4] (A3) {c}
node[ev,pos=.6] (A4) {d}
node[ev,pos=.7] (A5) {f}
node[ev,pos=.8] (A6) {g}
node[ev,pos=.95] (A7) {h}
+(10,0);
\draw (0,2) -- node[ev,pos=.3] (B1) {i}
node[ev,pos=.4] (B2) {j}
node[ev,pos=.88] (B3) {k}
+(10,0);
\draw (0,0) -- node[ev,pos=.2] (C1) {l}
node[ev,pos=.5] (C2) {m}
+(10,0);
% ~~~ vector labels ~~~~~~~~~~~~~~~~
%% BEFORE refactoring
% \foreach \v [count=\j] in {(1,0,0), (2,0,0), (3,1,0),
% (4,1,0), (5,1,2), (6,1,2), (7,1,2)}
% \node[vlu] at (A\j) {\v};
%
% \foreach \v [count=\j] in {(0,1,0), (2,2,0), (6,3,2)}
% \node[vld] at (B\j) {\v};
%
% \foreach \v [count=\j] in {(1,0,1), (0,0,2)}
% \node[vld] at (C\j) {\v};
%% AFTER refactoring
\vlab{A}{((1,0,0), (2,0,0), (3,1,0), (4,1,0), (5,1,2), (6,1,2), (7,1,2))}{vlu}
\vlab{B}{(0,1,0), (2,2,0), (6,3,2)}{vld}
\vlab{C}{(1,0,1), (0,0,2)}{vld}
% ~~~ connectors ~~~~~~~~~~~
\draw[->] (A2) -- (B2);
\draw[->] (B1) -- (A3);
\draw[->] (C2) -- node[pos=.7,anchor=west] {note} (A5);
\draw[->] (A6) -- (B3);
% ~~~ axis labels ~~~~~~~~~
% unrefactored
\node[anchor=east] at (0,4) {P1};
\node[anchor=east] at (0,2) {P2};
\node[anchor=east] at (0,0) {P3};
\end{tikzpicture}
\end{document}
\pgfmathprintmatrix
defined?