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?
8
  • 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, 2013 at 13:45
  • BTW, what is a Zwicky Box ?
    – user13907
    May 24, 2013 at 13:46
  • 1
    A morphological box. Here's a link to a picture: salemmarafi.com/wp-content/uploads/2011/10/the_new_cookie.png May 24, 2013 at 13:51
  • @HendrikWiese That looks like a simple tabular, maybe with tikzmarks to draw the red line. May 24, 2013 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. May 24, 2013 at 13:54

2 Answers 2

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

1
  • 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. May 27, 2013 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

2
  • 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. Oct 21, 2023 at 18:11
  • @Qrrbrbirlbel: Good suggestion. I have modified my answer. Oct 21, 2023 at 18:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .