Netzplan in TikZ - matrix of nodes mit Multispalten Nodes?

Tabellen und Grafiken erstellen und anordnen


TeXtastisch
Forum-Newbie
Forum-Newbie
Beiträge: 2
Registriert: Mo 14. Sep 2020, 10:43

Netzplan in TikZ - matrix of nodes mit Multispalten Nodes?

Beitrag von TeXtastisch »

Hallo, ich arbeite momentan an einer Ausarbeitung zu Projektmanagement Methoden. Ich konnte bereits erfolgreich ein Ornanigramm in tikz darstellen. Auch einen Phasenplan konnte ich mit dem TikZ Layer pgfgantt relativ fix erstellen. Aber bei einem sogenannten "Netzplan" verzweifle ich grade. Meine Internetrecherche hat mir da auch keine wirklich brauchbaren Ergebnisse geliefert. Wahrscheinlich ist der Begriff Netzplan auch zu genereisch.
Der Netzplan den ich machen möchte besteht aus mehreren "Vorgängen", welche mit Pfeilen verknüpft sind. Ein Vorgang kann beliebig viele vorherige oder Folgevorgänge haben. Ein Vorgang besteht aus 10 Feldern. Wobei in der ersten Reihe auch 2 Felder zusammen gefasst werden können. In der 2. Reihe ist dann ein Feld, welches sich über die Länge von 3 Feldern erstreckt und den Namen enthält. Darunter dann noch mal 2 Reihen mit jeweils 3 Feldern, welche Zahlen enthalten. Wenn ein Feld länger wird, sollte sich die ganze Matrix dem Anpassen und nicht nur eine Node entarten. (Siehe Anhang)
Ich hatte die Idee das mit einer Matrix of Nodes zu realisieren und diese mit chains zu verbinden. Aber ich scheitere daran eine Node zu erstellen, welche sich über die Länge von 3 Nodes erstreckt.

Hier einmal folgendes Minimalbeispiel (Erklärung folgt danach):

\documentclass[fontsize=11pt]{scrartcl}
\usepackage[demo]{graphicx}
\usepackage{tikz}
\usetikzlibrary{matrix,fit,chains,scopes}
\begin{document}
	\begin{tikzpicture}[
		vorgang/.style={matrix of nodes},
		nodes={rectangle, draw},
		namerow/.style={white}]
		\matrix[vorgang] (vorgang1) 
		{
			0 & X & 0\\
			&Vorgang1&\\
			0 & 0 & 0\\
			0 & 0 & 0\\
		};
		
	\matrix[vorgang, right = of vorgang1] (vorgang2) 
	{
		2 & X & 7\\
		|[namerow]|.&|[namerow]|.&|[namerow]|.&\\
		0 & 0 & 7\\
		0 & 0 & 7\\
	};
	
	{	[start chain,every on chain/.style={join=by ->}]
		\chainin (vorgang1);
		\chainin (vorgang2);
	}
	
	\node[rectangle, draw, fit=(vorgang2-2-1)(vorgang2-2-2)(vorgang2-2-3)] {Vorgang2};
\end{tikzpicture}
\end{document}

Bei der Matrix vorgang1 habe ich die äußeren Felder in der 2. Reihe leer gelassen, dann weitet sich die Node aus schiebt die anderen beiseite, definitiv nicht das was ich möchte.
Bei der Matrix vorgang2 habe ich versucht die 3 Nodes zu erstellen und mit fit eine andere darüber zu legen, das ist aber weder schön, noch bringt es das gewünschte Ergebnis. Dies funktioniert nicht, wenn ich nur Leerzeichen in die Nodes schreibe, weswegen ich einfach Punkte dort eingefügt und diese weiß gefärbt habe. Nicht die schönste Lösung, und fit wirkt auch nicht ideal dafür.

Hat jemand eine Idee wie ich den Beschriebenen Netzplan in TikZ erstellen kann?

Oder gibt es ein Paket, welches eine einfache Lösung bereit stellt, wie z. B. pgfgantt für Phasenpläne?

Die letzte alternative wäre ein externes Programm, was ich aber gerne vermeiden würde. Aber ich wüsste auch nicht welches externe Programm, wichtig wäre das es mir eine Vektorgrafik erstellt.

Dateianhänge
Hier das Ergebnis des Codes. Bei Vorgang1 ist zu sehen wie die anderen Nodes beiseite geschoben werden. Bei Vorgang 2 habe ich mit fit eine Node über die 3 anderen Nodes gelegt, führt aber auch nicht zum gewünschten Ergebnis. Auch sind hier zwischen den Nodes in der 3. und 4. Reihe abstände, welche in der ersten Reihe nicht sind.
Hier das Ergebnis des Codes. Bei Vorgang1 ist zu sehen wie die anderen Nodes beiseite geschoben werden. Bei Vorgang 2 habe ich mit fit eine Node über die 3 anderen Nodes gelegt, führt aber auch nicht zum gewünschten Ergebnis. Auch sind hier zwischen den Nodes in der 3. und 4. Reihe abstände, welche in der ersten Reihe nicht sind.
Ein Beispiel wie ein Netzplan aussehen könnte. In LibreOffice Calc erstellt.
Ein Beispiel wie ein Netzplan aussehen könnte. In LibreOffice Calc erstellt.
netzplanBeispiel.png (10.96 KiB) 2584 mal betrachtet

cis
Forum-Anfänger
Forum-Anfänger
Beiträge: 47
Registriert: Mi 22. Jul 2020, 20:14

Re: Netzplan in TikZ - matrix of nodes mit Multispalten Nodes?

Beitrag von cis »

Mir ist das offengestanden zu viel Roman für vermutlich wenig Problem. Tip: Versuche, wenn möglich, auf Einzelprobleme runterzubrechen (mit einfachen Beispielcodes), die man nicht nicht seitenweise erklären muss.

Dein Hauptproblem in einem Satz scheint: Du willst eine multicolumn in einer TikZ-matrix.
Diese gibt es nicht von Haus aus, man muss sie sich basteln:
nodes in empty cells, % <---- 1/2
row 2 column 2/.style={overlay}, % <---- 2/2 verhindert das "Aufspalten"

Ansonsten scheinen mir die Anpassungen sinnvoll:
minimum size=2em, % <---- !
text height=\ht\strutbox, text depth=\dp\strutbox, % <---- !

Im Folgenden muss die 2. Matrix in ähnlicher Weise angepasst werden:

55555a5.png
\documentclass[fontsize=11pt]{scrartcl}
\usepackage[demo]{graphicx}
\usepackage{tikz}
\usetikzlibrary{matrix,fit,chains,scopes}
\begin{document}
\begin{tikzpicture}[
vorgang/.style={matrix of nodes, 
minimum size=2em, % <---- !
text height=\ht\strutbox, text depth=\dp\strutbox, % <---- !
},
row 2/.style={nodes={draw=none}}, % <---- !
nodes in empty cells, % <---- 1/2
row 2 column 2/.style={overlay}, % <---- 2/2 verhindert das "Aufspalten"
nodes={rectangle, draw},
namerow/.style={white}
]
\matrix[vorgang,
row 4 column 1/.style={nodes={fill=red}}, % <---- Bsp. einer Füllung
] (vorgang1) 
{
0 & X & 0\\
&  Vorgang1 & \\ % <---- !
0 & 0 & 0\\
0 & 0 & 0\\
};
% Linien nachzeichnen
\draw[blue, transform canvas={xshift=0.5\pgflinewidth}] (vorgang1-1-1.south west) -- (vorgang1-3-1.north west);
\draw[red, transform canvas={xshift=-0.5\pgflinewidth}] (vorgang1-1-3.south east) -- (vorgang1-3-3.north east);


% Ähnlich anpassen: 
	\matrix[vorgang, right = of vorgang1] (vorgang2) 
	{
		2 & X & 7\\
		|[namerow]|.&|[namerow]|.&|[namerow]|.&\\
		0 & 0 & 7\\
		0 & 0 & 7\\
	};
	
{	[start chain,every on chain/.style={join=by ->}]
	\chainin (vorgang1);
	\chainin (vorgang2);
}

\node[rectangle, draw, fit=(vorgang2-2-1)(vorgang2-2-2)(vorgang2-2-3)] {Vorgang2};
\end{tikzpicture}
\end{document}

TeXtastisch
Forum-Newbie
Forum-Newbie
Beiträge: 2
Registriert: Mo 14. Sep 2020, 10:43

Re: Netzplan in TikZ - matrix of nodes mit Multispalten Nodes?

Beitrag von TeXtastisch »

Deine Antwort hat mir sehr geholfen, danke. Um ein bisschen an die Community zurück zu geben, möchte ich zeigen was ich daraus gemacht habe, vielleicht hilft es noch jemanden.

\documentclass[fontsize=11pt]{scrartcl}
\usepackage[demo]{graphicx}
\usepackage{tikz}
\usetikzlibrary{matrix,fit,chains,scopes,arrows.meta}
% Color definitions
\colorlet{criticalPathColor}{red!20}
\colorlet{casualPathColor}{green!20}
% Size definitions
\newcommand{\varNetzplanParboxSize}{3cm}
\newcommand{\varCoordHDist}{0.4cm}
\newcommand{\varArrowHDist}{0.1cm}
\begin{document}
	\begin{tikzpicture}
		% Voreinstellungen
		[
		vorgang/.style={matrix of nodes,
			minimum size=2em,
			text height=\ht\strutbox, text depth=\dp\strutbox,
		},
		row 2/.style={nodes={draw=none}, minimum height = 1cm},
		nodes in empty cells,
		row 2 column 2/.style={overlay},
		nodes={rectangle, draw,minimum width=1.1cm},
		arrowdesc/.style={rectangle}
		]
		
	%Startvorgang
	\matrix[vorgang,
	row 3 column 2/.style={nodes={fill=criticalPathColor}}
	] (start) 
	{
		0 & X & 0\\
		&Start&\\
		0 & 0 & 0\\
		0 & 0 & 0\\
	};
	\draw[transform canvas={xshift=0.5\pgflinewidth}] (start-1-1.south west) -- (start-3-1.north west);
	\draw[transform canvas={xshift=-0.5\pgflinewidth}] (start-1-3.south east) -- (start-3-3.north east);
	
	%Vorgang 1
	\matrix[vorgang, right = of start,
	row 3 column 2/.style={nodes={fill=criticalPathColor}}
	] (vorgang1) 
	{
		1 & X & 1\\
		&\parbox{\varNetzplanParboxSize}{\centering Vorgang 1}&\\
		0 & 0 & 1\\
		0 & 0 & 1\\
	};
	\draw[transform canvas={xshift=0.5\pgflinewidth}] (vorgang1-1-1.south west) -- (vorgang1-3-1.north west);
	\draw[transform canvas={xshift=-0.5\pgflinewidth}] (vorgang1-1-3.south east) -- (vorgang1-3-3.north east);
	
	%Vorgang2
	\matrix[vorgang, right = of vorgang1,
	row 3 column 2/.style={nodes={fill=casualPathColor}}
	] (vorgang2) 
	{
		2 & X & 10\\
		&\parbox{\varNetzplanParboxSize}{\centering Vorgang 2}&\\
		1 & 10  & 11\\
		6&  10 & 16\\
	};
	\draw[transform canvas={xshift=0.5\pgflinewidth}] (vorgang2-1-1.south west) -- (vorgang2-3-1.north west);
	\draw[transform canvas={xshift=-0.5\pgflinewidth}] (vorgang2-1-3.south east) -- (vorgang2-3-3.north east);
	
	%Vorgang3
	\matrix[vorgang, below = of vorgang1,
	row 3 column 2/.style={nodes={fill=criticalPathColor}}
	] (vorgang3) 
	{
		3 & X & 20\\
		&\parbox{\varNetzplanParboxSize}{\centering Vorgang 3}&\\
		1 & 0 & 21\\
		1 & 0 & 21\\
	};
	\draw[transform canvas={xshift=0.5\pgflinewidth}] (vorgang3-1-1.south west) -- (vorgang3-3-1.north west);
	\draw[transform canvas={xshift=-0.5\pgflinewidth}] (vorgang3-1-3.south east) -- (vorgang3-3-3.north east);
	
	%Ende
	\matrix[vorgang, right = of vorgang3,
	row 3 column 2/.style={nodes={fill=criticalPathColor}}
	] (ende) 
	{
		4 & X & 0\\
		&\parbox{\varNetzplanParboxSize}{\centering Ende}&\\
		21 & 0 & 21\\
		21 & 0 & 21\\
	};
	\draw[transform canvas={xshift=0.5\pgflinewidth}] (ende-1-1.south west) -- (ende-3-1.north west);
	\draw[transform canvas={xshift=-0.5\pgflinewidth}] (ende-1-3.south east) -- (ende-3-3.north east);
	
	% Verbindungen mit Beschriftungen.
	% Start -> 1: NF
	\draw[-{Latex[length=3mm,width=5mm]},red] (start) -- (vorgang1);
	\coordinate[right = 0.4cm of start] (test);
	\node[above=0.1cm of test, draw=none] (testmore) {NF};
	
	%1 -> 2: NF
	\draw[-{Latex[length=3mm,width=5mm]}] (vorgang1) -- (vorgang2);
	\coordinate[right = \varCoordHDist of vorgang1] (coord1_2);
	\node[above=\varArrowHDist of coord1_2, draw=none] (between1_2) {NF};
	
	%1 -> 3: NF
	\draw[-{Latex[length=3mm,width=5mm]},red] (vorgang1) -- (vorgang3);
	\coordinate[below = \varCoordHDist of vorgang1] (coord1_3);
	\node[right=-0.2cm of coord1_3, draw=none] (between1_3) {NF};
	
	%2 -> ende: EF
	\draw[-{Latex[length=3mm,width=5mm]}] (vorgang2) -- (ende);
	\coordinate[below = \varCoordHDist of vorgang2] (coord2_ende);
	\node[right=0.1 of coord2_ende, draw=none] (between2_ende) {NF -5};
	
	%3 -> ende: NF
	\draw[-{Latex[length=3mm,width=5mm]},red] (vorgang3) -- (ende);
	\coordinate[right = \varCoordHDist of vorgang3] (coord3_ende);
	\node[above=\varArrowHDist of coord3_ende, draw=none] (between3_ende) {NF};
\end{tikzpicture}
\end{document}

Ich habe die Größe der Nodes angepasst und Pfeile aus der arrow.meta tikzlibrary benutzt und diese beschriftet. Das Ergebnis ist im Anhang zu sehen.

Dateianhänge
Netzplan_fertig.png

Bartman
Forum-Meister
Forum-Meister
Beiträge: 2456
Registriert: Do 16. Jul 2009, 21:41
Wohnort: Hessische Provinz

Re: Netzplan in TikZ - matrix of nodes mit Multispalten Nodes?

Beitrag von Bartman »

Beim Übergang zwischen den Matrixzellen ist nur eine Linie zu sehen, wenn man die Optionen der Umgebung tikzpicture um

row sep=-\pgflinewidth,
column sep=-\pgflinewidth,
%ultra thick

erweitert. Die Entfernung des Kommentars in der letzten Zeile hebt deutlicher hervor, was ohne die Ergänzung passiert.

Anstelle des Befehls \varNetzplanParboxSize und der \parbox-Befehle könnte man auch den Befehl \makebox benutzen, aber wegen der Option overlay wird beides nicht gebraucht.

Die Einstellung der Pfeile kann man noch zusammenfassen.

Wenn das Zeichen vor der Zahl 5 in der Beschriftung des Pfeils zwischen den Matrizen "Vorgang 2" und "Ende" ein negatives Vorzeichen sein soll, dann kann man in den mathematischen Modus wechseln oder -- nehmen.

\documentclass[tikz, border=5pt]{standalone}
\usetikzlibrary{matrix,fit,chains,scopes,arrows.meta}

% Color definitions
\colorlet{criticalPathColor}{red!20}
\colorlet{casualPathColor}{green!20}

% Size definitions
%\newcommand{\varNetzplanParboxSize}{3cm}
\newcommand{\varCoordHDist}{0.4cm}
\newcommand{\varArrowHDist}{0.1cm}

\begin{document}
	\begin{tikzpicture}[
		% Voreinstellungen
		>={Latex[length=3mm,width=5mm]},
		every matrix/.style={
                    draw,
                    nodes=draw,
                    matrix of nodes,
                    minimum width=1.1cm,
                    text height=\ht\strutbox, 
                    text depth=\dp\strutbox
		},
		row 3 column 2/.style={nodes={fill=criticalPathColor}},
		row 2/.style={nodes={draw=none}, minimum height = 1cm},
		nodes in empty cells,
		row 2 column 2/.style={overlay},
		arrowdesc/.style={rectangle},
		row sep=-\pgflinewidth,
		column sep=-\pgflinewidth,
%		ultra thick
	]
		
%Startvorgang
\matrix (start) {
	0 & X & 0\\
	&Start&\\
	0 & 0 & 0\\
	0 & 0 & 0\\
};

%Vorgang 1
\matrix[
    right = of start
] (vorgang1) {
	1 & X & 1\\
	&Vorgang 1&\\
	0 & 0 & 1\\
	0 & 0 & 1\\
};

%Vorgang2
\matrix[
    right = of vorgang1
] (vorgang2) {
	2 & X & 10\\
	&Vorgang 2&\\
	1 & |[fill=casualPathColor]| 10  & 11\\
	6&  10 & 16\\
};

%Vorgang3
\matrix[
    below = of vorgang1
] (vorgang3) {
	3 & X & 20\\
	&Vorgang 3&\\
	1 & 0 & 21\\
	1 & 0 & 21\\
};

%Ende
\matrix[
    right = of vorgang3
] (ende) {
	4 & X & 0\\
	&Ende&\\
	21 & 0 & 21\\
	21 & 0 & 21\\
};

\foreach \vorgang in {start,vorgang1,vorgang2,vorgang3,ende}{
    \draw[transform canvas={xshift=0.5\pgflinewidth}] 
        (\vorgang-1-1.south west) -- (\vorgang-3-1.north west)
    ;
    \draw[transform canvas={xshift=-0.5\pgflinewidth}] 
        (\vorgang-1-3.south east) -- (\vorgang-3-3.north east)
    ;
}

% Verbindungen mit Beschriftungen.
% Start -> 1: NF
\draw[->,red] (start) -- (vorgang1);
\coordinate[right = \varCoordHDist of start] (coord_start_1);
\node[above=\varArrowHDist of coord_start_1] (between_start_1) {NF};

%1 -> 2: NF
\draw[->] (vorgang1) --  (vorgang2);
\coordinate[right = \varCoordHDist of vorgang1] (coord1_2);
\node[above=\varArrowHDist of coord1_2] (between1_2) {NF};

%1 -> 3: NF
\draw[->,red] (vorgang1) -- (vorgang3);
\coordinate[below = \varCoordHDist of vorgang1] (coord1_3);
\node[right=0.1cm of coord1_3] (between1_3) {NF};

%2 -> ende: EF
\draw[->] (vorgang2) -- (ende);
\coordinate[below = \varCoordHDist of vorgang2] (coord2_ende);
\node[right=0.1cm of coord2_ende] (between2_ende) {NF -5};

%3 -> ende: NF
\draw[->,red] (vorgang3) -- (ende);
\coordinate[right = \varCoordHDist of vorgang3] (coord3_ende);
\node[above=\varArrowHDist of coord3_ende] (between3_ende) {NF};
\end{tikzpicture}
\end{document}

Antworten