7

I would like to make a Zwicky Box by using tabular combined with an overlaying tikzpicture. How can I (semi-)automatically align nodes to the vertical and horizontal center of their corresponding cells?

I understand it would probably work with a matrix which is aligned to the top left corner of the tabular and whose row and column seperation somehow relate to the sizes of the cells (which all have fixed width and height).

Example of what a Zwicky Box could look like

Example of how diamond nodes could look like, made in Excel

So my questions are:

  1. how do I align a tikzpicture exactly with the upper left corner of a tabular?
  2. how do I calculate seperation sizes of columns and rows by knowledge of cell width and height of my tabular environment?
  3. how do I tell a node in which cell of a matrix it shall be placed and that it shall be aligned to the cell's v/h center?
  4. should I actually use a tikzpicture overlaying a tabular? Or would it be better to drop the tabular and put everything into the matrix?
  • Could you provide a link to an image of a Zwicky Box? It seems like there's different ways of drawing them. – Jake May 24 '13 at 13:45
  • BTW, what is a Zwicky Box ? –  May 24 '13 at 13:46
  • 1
    A morphological box. Here's a link to a picture: http://www.salemmarafi.com/wp-content/uploads/2011/10/the_new_cookie.png – Hendrik Wiese May 24 '13 at 13:51
  • @HendrikWiese That looks like a simple tabular, maybe with tikzmarks to draw the red line. – Qrrbrbirlbel May 24 '13 at 13:52
  • However, in addition, I'd like to have diamond nodes at the corner points of the poly lines (which actually can be more than just one, in different colors, sharing nodes and crossing each other).

    @Qrrbrbirlbel: Yeah, but I'd like to have the marks/nodes aligned to the cells. They shall move correspondingly when I change the content of a cell.

    – Hendrik Wiese May 24 '13 at 13:54
  • @HendrikWiese Could you provide a image (even if drawn in Paint) how those diamond nodes would fit in with the otherwise orthogonal table? – Qrrbrbirlbel May 24 '13 at 14:10
  • I can... but on Monday at the earliest. There is a complete example in my office which I don't have access to over the weekend. – Hendrik Wiese May 24 '13 at 23:59
  • I've added a picture of how the diamond nodes could look like. However they aren't aligned to anything but the position of the corresponding cell. That's why it looks a bit chaotic. I'd like to have them aligned to the center of the cell and - if at all possible - behind the text. – Hendrik Wiese May 27 '13 at 07:56

2 Answers2

6

I would do it with a simple tabular using a few tikzmark macros.

Code

\documentclass[convert=false]{standalone}
\usepackage{tikz,booktabs,array}
\makeatletter
\newcommand{\markZwicky}[1][]{\pgfutil@ifnextchar({\mark@Zwicky{#1}}{\mark@Zwicky{#1}()}}
\def\mark@Zwicky#1(#2)#3{%
   \tikz[every Zwicky picture,#1]{%
     \node[every Zwicky node,draw=none,inner sep=+\z@,outer sep=+\z@] {#3};
     \def\tikz@Mark@name{#2}%
     \ifx\tikz@Mark@name\pgfutil@empty\else
       \tikzset{every Zwicky node/.append style={name={#2}}}%
     \fi
     \node[every Zwicky node,overlay] {\phantom{#3}};
   }%
}
\newcommand{\tikzZwicky}[1][]{%
  \def\tikz@Zwicky@args{#1}%
  \let\tikz@Zwicky@list\pgfutil@gobble
  \let\tikz@Zwicky@first\pgfutil@empty
  \pgfutil@ifnextchar(\tikz@Zwicky@collect\tikz@Zwicky@finish
}
\def\tikz@Zwicky@collect(#1){%
  \ifx\tikz@Zwicky@first\pgfutil@empty
    \edef\tikz@Zwicky@first{#1}%
  \else
    \edef\tikz@Zwicky@list{\tikz@Zwicky@list,#1}%
  \fi
  \pgfutil@ifnextchar(\tikz@Zwicky@collect\tikz@Zwicky@finish
}
\def\tikz@Zwicky@finish{%
  \tikz[remember picture,overlay]
    \draw[every Zwicky connector,/expanded=\tikz@Zwicky@args]
      (\tikz@Zwicky@first) [/expanded={@Zwicky@list/.list={\tikz@Zwicky@list}}] [every Zwicky connect finish/.try];
}
\pgfkeys{/expanded/.code={\edef\pgfkeys@temp{{#1}}\expandafter\pgfkeysalso\pgfkeys@temp}}
\makeatother
\tikzset{
  @Zwicky@list/.style={insert path={to[every Zwicky connector how/.try] (#1)}},
  every Zwicky picture/.style={
    baseline,
    remember picture,
  },
  every Zwicky node/.style={
    remember picture,
    anchor=base,
    inner sep=+2pt
  },
  every Zwicky connector/.style={
    ultra thick,
    red!80!black,
    draw opacity=.5,
    line cap=round,
    line join=round
  }
}
\begin{document}
\begin{tabular}{>{\bfseries}lcccc}
    \toprule
                &                                       \multicolumn{4}{c}{\bfseries Configurations}                                        \\ \cmidrule{2-5}
    Parameters  &   \bfseries Cookie A    &        \bfseries Cookie B         &      \bfseries Cookie C      &      \bfseries Cookie D      \\ \midrule
    Texture     &         Smooth          &               Soft                &   \markZwicky(1-3){Chunky}   &             Soft             \\
    Consistency & \markZwicky(2-1){Chewy} &               Goowy               &           Crunchy            &            Chewy             \\
    Size        &         Medium          &               Small               &            Large             &    \markZwicky(3-4){Huge}    \\
    Base        &          Plain          &               Plain               & \markZwicky(4-3){Chocholate} &           Oatmeal            \\
    Topping     &          Sugar          &               None                &            Icing             & \markZwicky(5-4){Chocholate} \\
    Stuffing    &       Chocholate        & \markZwicky(6-2){Dates and Harda} &          Macadamia           &          Chocholate          \\ \bottomrule
\end{tabular}
\tikzZwicky(1-3)(2-1.east)(3-4.west)(4-3.east)(5-4.west)(6-2)
\tikzZwicky[blue](2-1.east)(5-4.west)(3-4.west)(1-3.center)(4-3.center)(6-2)
\end{document}

Output

enter image description here

Moriambar
  • 11,466
Qrrbrbirlbel
  • 119,821
  • Still trying to wrap my head around this... but it look promising. Is there a way to automatically mark every cell so that I just would have to add \tiksZwicky at the end with the appropriate mark indices? In larger tables it quickly gets a little bit confusing. – Hendrik Wiese May 27 '13 at 11:58
2

The environment {NiceTabular} of nicematrix is similar to the classical environment {tabular} (as defined by the package array) but creates PGF/TikZ nodes under the cells, rows and columns.

It's possible to use these nodes to draw whatever rule you want with TikZ array the construction of the main array but also before (in the so-called \CodeBefore).

However, you need several compilations.

\documentclass{article}
\usepackage{nicematrix,booktabs,tikz}

\begin{document}

\begin{NiceTabular}{@{}>{\bfseries}lcccc@{}} \CodeBefore [create-cell-nodes] \tikz \draw [red!50, line width=2pt, line join = round] plot [samples at={3-4, 4-2, 5-5, 6-4, 7-5, 8-3}] (\x) ; \Body \toprule \RowStyle[nb-rows=2]{\bfseries}
& \Block{1-4}{Configurations} \ \cmidrule{2-5} Parameters & Cookie A & Cookie B & Cookie C & Cookie D \ \midrule Texture & Smooth & Soft & Chunky & Soft \ Consistency & Chewy & Goowy & Crunchy & Chewy \ Size & Medium & Small & Large & Huge \ Base & Plain & Plain & Chocholate & Oatmeal \ Topping & Sugar & None & Icing & Chocholate \ Stuffing & Chocholate & Dates and Harda & Macadamia & Chocholate \ \bottomrule \end{NiceTabular}

\end{document}

Output of the above code

F. Pantigny
  • 40,250
  • 2
    \tikz\draw[red!50, line width=2pt, line join = round] plot[samples at={3-4, 4-2, 5-5, 6-4, 7-5, 8-3}](\x); is probably less clunky to write and can easily be used in a macro that just takes a list of cells. – Qrrbrbirlbel Oct 21 '23 at 18:11
  • @Qrrbrbirlbel: Good suggestion. I have modified my answer. – F. Pantigny Oct 21 '23 at 18:25