Here is the third revision of my approach to programmatically create such diagrams, using TiKZ.
Sample code
Preamble and definitions follow below: this code is meant to demonstrate the interface to the environments/macros which I define.
\begin{document}
\begin{assessmentTable}{%
\newcommand\ItemTitle {L\"osungsvariante (Lv) eintragen:}
\newcommand\ItemHeading {Lv}
\newcommand\AssessmentTitle {Entscheidung}
\newcommand\RemarksTitle {Bemerkungen (Hinweise, Begr\"undungen)}
\AddCriterion {A}{Vertr\"aglichkeit gegeben}
\AddCriterion {B}{Forderungen der Anforderungsliste erf\"ult}
\AddCriterion {C}{Grunds\"atzlich realisiebar}
\AddCriterion {D}{Aufwand zul\"assig}
\AddCriterion {E}{Unmittelbare Sicherheitstechnik gegeben}
\AddCriterion {F}{Im eigenen Bereich bevorzugt}
}%
1 & + & + & + & ? & & & Anzahl er Me{\ss}stellen & ? \\
2 & + & - & & & & & Unterbringung der Masse & - \\
3 & - & & & & & & Radioaktivit\"at & - \\
4 & + & + & + & + & & (+) & (Weiterentwicklung bisheriger L\"osungen) & + \\
5 & + & + & + & + & & & & + \\
6 & - & & & & & & Fl\"ussigkeit nicht Leitend & - \\
7 & + & + & + & + & & & & + \\
8 & + & + & + & + & & & s.\ Lv 7 & +
\end{assessmentTable}
\end{document}
Sample output.

Remarks.
The table is constructed by making simple macro calls, and inputting the contents of the table as one would a normal table in LaTeX. This allows for the easy construction and customization of the output.
The code admittedly has some idiosyncracies. Some adjustment to the lengths may be necessary to prevent some of the text in the table from overlapping, for example. Also, some of the ways I chose to code this environment were to avoid mysterious errors: for example, it would appear that if any TiKZ code appears in the tikzpicture
environment after the final \foreach
loop, the routine which defines paths produces an error as a result of \A
no longer being defined. (I do not know why this should happen.)
Having said that, this code should produce reasonable results for simple inputs, and is hopefully robust to minor tweaks.
Below is the code to produce the above example document.
Helper definitions
\documentclass[a4paper,10pt]{article}
\usepackage{pbox,tikz}
\usetikzlibrary{matrix,calc,fit,intersections}
\newlength\criterionwidth % width for criterion table columns
\newlength\labelheight % height for labels for assessment criteria
\newlength\labeldepth % depth for labels for assessment criteria
\newlength\itemcolwidth % width for the left-most column
\newlength\criterionlabelskip % vert. skip between legend and first criterion label
\newlength\criterionlabelindent % left indend for criterion labels from their columns
\newlength\assessmentdiagtopstretch % vert.dist. upwards to pull top of the diagonal
\newlength\assessmentdiagbotstretch % vert.dist. downwards to pull bottom of the diagonal
\newlength\remarkswidth % absolute width of remarks column
\newlength\remarksxsep % inner horiz. separation of remarks from column edge
\setlength\criterionwidth {1.5em}
\setlength\labelheight {3ex}
\setlength\labeldepth {1ex}
\setlength\itemcolwidth {3em}
\setlength\criterionlabelskip {2ex}
\setlength\criterionlabelindent {0ex}
\setlength\assessmentdiagtopstretch {5mm}
\setlength\assessmentdiagbotstretch {2mm}
\setlength\remarkswidth {80mm}
\setlength\remarksxsep {1em}
\newcommand\labeltypeface {\itshape} % face for description labels in the table
\newcommand\celltypesize {\footnotesize} % size of evalutation cell contents
\newcommand\remarktypeface {\small} % size of remark cell contents
The various lengths can be varied to taste, and the typefaces can be used to control the appearance of the text in the table.
\makeatletter
\newcount\@RemarkCol % Counter for position of the Remarks column
\newtoks\@CriterionNameToks % Token list for labels of the criteria to asses
\@CriterionNameToks{}
\newcommand\AddCriterion[2]{% Macro to define a new criterion column / label
\edef\@tempa{\the\@CriterionNameToks}%
\ifx\empty\@tempa\@CriterionNameToks{{#1}/{#2}}\else
\expandafter\@CriterionNameToks\expandafter{\the\@CriterionNameToks,{#1}/{#2}}
\fi}
The macro \AddCriterion
is meant to be the user interface to define the criteria of assessment in the table. We also define a counter to keep track of the position of the Remarks column, depending on the number of criteria to be assessed.
Table environment definition
\newenvironment{assessmentTable}[1]{%
\@CriterionNameToks{}%
\@RemarkCol=2\relax
#1%
\begin{tikzpicture}
\expandafter\def\expandafter\@CriterionNames\expandafter{\the\@CriterionNameToks}
\node (CriterionLegend) [inner sep=1em] {\parbox{\paperwidth}{\CriterionLegend}};
\coordinate (Criterion-first-anchor) at ($(CriterionLegend.south west) + (0,-\criterionlabelskip)$);
\def\CriterionAnchor{Criterion-first-anchor}
\foreach \A/\critLabel in \@CriterionNames {
\global\advance\@RemarkCol by 1\relax
\node [anchor=north west, text width=\criterionwidth, minimum height=\labelheight+\labeldepth, inner sep=0pt]
(\A-anchor) at (\CriterionAnchor) {};
\node [anchor=west, text height=\labelheight, text depth=\labeldepth]
(\A-label) at ($(\A-anchor.east) + (\criterionlabelindent,0)$)
{\labeltypeface\critLabel};
\xdef\CriterionAnchor{\A-anchor.south east}%
}
\node [anchor=north west, inner xsep=\remarksxsep, inner ysep=0pt, text height=\labelheight, text depth=\labeldepth,
text width=\remarkswidth-2*\pgfkeysvalueof{/pgf/inner xsep}]
(Remarks-title) at (\CriterionAnchor)
{\labeltypeface\RemarksTitle};
\node [anchor=south west, minimum height=\itemcolwidth,rotate=90]
(ItemTitle) at (Remarks-title.north -| CriterionLegend.west)
{\ItemTitle};
\node [inner sep=0pt, fit=(ItemTitle)(ItemTitle |- CriterionLegend.north)]
(ItemTitle) {};
\def\CriterionAnchor{ItemTitle.west}
\node [anchor=north west, text height=\labelheight, text depth=\labeldepth, inner ysep=0pt]
(ItemHeading) at (ItemTitle.south west) {\ItemHeading};
\foreach \A/\critLabel in \@CriterionNames {%
\node [inner sep=0pt, anchor=south, minimum width=\criterionwidth, text height=\labelheight, text depth=\labeldepth]
(\A-heading) at (ItemHeading.south -| \A-anchor) {\A};
}
\node [anchor=north west, rotate=90, minimum height=\criterionwidth, inner ysep=0pt]
(AssessmentTitle) at (Remarks-title.south east) {\AssessmentTitle};
\node [inner sep=0pt, fit=(AssessmentTitle)] (AssessmentTitle) {};
\node [anchor=north east]
(AssessmentLegend) at (CriterionLegend.north -| AssessmentTitle.east)
{\pbox{\paperwidth}{\AssessmentLegend}};
\def\@GridFinalRow{0}
\matrix [%
anchor=north west, matrix of nodes,%
nodes in empty cells,
inner sep=0pt,
nodes={%
draw=white, inner sep=0pt,
execute at begin node=\celltypesize$,
execute at end node=$\xdef\@GridFinalRow{\pgfmatrixcurrentrow},\iffalse$ Fix some syntax hilighting problems\fi
text height=3ex, text depth=1ex, minimum width=\criterionwidth},
column 1/.style={%
execute at begin node=\expandafter\@gobble\@gobble,
execute at end node=\@gobble,
nodes={minimum width=\itemcolwidth}},
column \the\@RemarkCol/.style={%
execute at begin node=\remarktypeface\expandafter\@gobble\@gobble,
execute at end node=\@gobble,
nodes={%
minimum width=\remarkswidth,
inner xsep=\remarksxsep,
text width=\remarkswidth-2*\pgfkeysvalueof{/pgf/inner xsep}}}
] (Grid) at (ItemHeading.south west)
\bgroup
}{%
\\ \egroup;
\expandafter\ifnum\@GridFinalRow>0
\foreach \row in {1,...,\@GridFinalRow} {%
\draw (Grid-\row-1.south west) -- (Grid-\row-1.south west -| Grid.east);
}
\fi
\draw (ItemTitle.north west) -- (AssessmentLegend.north east)
-- (AssessmentTitle.south east)
-- (ItemHeading.south west) -- cycle;
\draw (Grid.north east) -- (Grid.south east) -- (Grid.south west) -- (Grid.north west);
\draw (CriterionLegend.north west) -- (Criterion-first-anchor);
\draw [name path=AssessmentLegendBoundary]
(AssessmentLegend.north west) -- ($(AssessmentLegend.south west) + (0mm,\assessmentdiagtopstretch)$)
-- ($(AssessmentTitle.north west) + (0mm,-\assessmentdiagbotstretch)$)
-- (AssessmentTitle.south west |- Grid.south);
\path [name path=Remarks-north-boundary] (Remarks-title.north west) -- ($(Remarks-title.north east) + (\paperwidth,0mm)$);
\path [name intersections={of=AssessmentLegendBoundary and Remarks-north-boundary, by={Remarks-north-east-boundary}}];
\draw (Remarks-north-east-boundary) -- (Remarks-title.north west) -- (Remarks-title.north west |- Grid.south);
\foreach \A/\critLabel in \@CriterionNames {%
\path [name path=\A-north-boundary] (\A-anchor.north west) -- ($(\A-anchor.north east) + (\paperwidth,0mm)$);
\path [name intersections={of=AssessmentLegendBoundary and \A-north-boundary, by={\A-north-east-boundary}}];
\draw (\A-north-east-boundary) -- (\A-anchor.north west) -- (\A-anchor.north west |- Grid.south);
}
\end{tikzpicture}%
}
\makeatother
The environment clears the list of criteria and resets the number of the remarks column, and then allows the user to specify a list of commands to initialize the parameters of the table (e.g. the criteria list, the item title, etc.). It then constructs the table using the "legend" (the large table cell in your example containing the descriptions of the labels (+)
, (-)
, etc.) as the foundation.
The columns and the labels for the criteria are constructed iteratively from the lower-left corner of the legend, with each subsequent criterion column constructed further downwards and to the right. (The length \criterionlabelskip
determines how much further down the first label is, from the lower-left corner of the legend.)
The label for Remarks column is defined relative to the position of the last criterion, and defines the bottom of the table-headers.
The position of the Legend cell and the Remarks column determines the position of the header of the left-most column, and its title.
The position of the Legend cell and the Remarks column also determines the position of the Assessment column, and its legend, which may in principle overlap some of the criteria labels.
The rest of the table is provided as the contents of the environment, and consists of a TiKZ matrix of nodes. The number of criteria columns determines which column is the "Remarks" column, which is given its own style; aside from this and the first column, every cell by default is in math-mode. (The code at the beginning of cells in the first column and the remarks column are to remove the math-mode and the resizing which is the default for all other nodes.)
At the end of the environment, all of the divider lines of the table are drawn.
Customization
Macros for the Legend and the description of the Assessment are likely to be the same for several tables: these are contained in \pbox
es whose size will shrink down to the size of their contents.
\newcommand\CriterionLegend{%
%
L\"osungsvariante {( Lv )} nach \\
\underline{\MakeUppercase{Auswahlkriterien}} beurteilen: \\[2ex]
\begin{tabular}{@{(}c@{)\quad}l}
$+$ & ja
\\
$-$ & nein
\\
? & Informationsmangel
\\
! & Anforderungliste \"uberpr\"ufen
\end{tabular}
%
}
\newcommand\AssessmentLegend{%
%
\begin{tabular}{c@{\quad}l}
\multicolumn{2}{c}{\MakeUppercase{Entscheiden}}
\\
\hline
& L\"osungsvarianten (Lv) \\ & kennzeichnen:
\\[2ex]
($+$) & L\"osung weiter verfolgen
\\
($-$) & L\"osung scheidet aus
\\
(?) & Information beschaffen \\& (L\"osung erneut beurteilen)
\\
(!) & Anforderungliste auf \\& \"Anderung pr\"ufen
\end{tabular}
%
}
All other customizations presumably should be done on a table-by-table basis (and so should be done as part of the argument to the table), or involve the helper macros and lengths defined above.
\slashbox
package.