# Bar graph with bars containing boxed strings

I have a .csv table containing both categorical and numeric data.

• The first column contains the categories, which are expressed as strings.
• The second column contains the number of observations that fall in each category. This is the only numeric data in the table.
• The remaining columns contain the various occurrences of each observation, and these occurrences are strings.

To have a visual glimpse on the structure of the file:

CATEGORIES  NOBS    OCCURRENCE1     OCCURRENCE2     OCCURRENCE3
Street      3       Street A        Street XXXXX    Street YY
Square      2       Square ZZZZ     Square B        ''
Lane        1       Lane XXXXX      ''              ''
Park        1       Park A          ''              ''


Notice that some strings may well be empty. Moreover, the length of the strings is variable.

Starting from this data, I would like to obtain a figure like the one below.

Ideally, I would be interested in having the overall length of each row be coherent with NOBS. This might require to reduce font size in some rows, and I am ready to do this by hand if needed. However the width of the various boxes must be determined so as to generate an overall size of the bar that is coherent with NOBS. An alternative could also be to use a fixed text box size of width equal to the longest string: the overall length of each bar would then be coherent with NOBS by construction.

I have tried to do some research on how to implement this type of figure, but I have so far failed miserably. Have I entirely missed some package or other useful solution? Any help would be greatly appreciated.

Does this go in the right direction?

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{datatable.csv}
CATEGORIES;NOBS;OCCURRENCE1;OCCURRENCE2;OCCURRENCE3
Street;3;Street A;Street XXXXX;Street YY
Square;2;Square ZZZZ;Square B;''
Lane;1;Lane XXXXX;'';''
Park;1;Park A;'';''
\end{filecontents*}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.16}
\newcounter{realitems}
\begin{document}
width=2.4cm,align=left,fill=gray!20,minimum height=8mm,draw,inner xsep=1ex},
funky bar/.cd,inner sep/.initial=1ex,width/.initial=2.1cm]
\edef\none{''}
% load table and figure out how many rows and columns it has
\pgfmathtruncatemacro{\NumRows}{\pgfplotsretval-1}
\pgfmathtruncatemacro{\NumCols}{\pgfplotsretval-1}
% loop
\foreach \Row in {0,...,\NumRows}
{\setcounter{realitems}{0} %measure the items
\foreach \Col in {2,...,\NumCols}
\ifx\pgfplotsretval\none
\else
\stepcounter{realitems}
\ifnum\number\value{realitems}=1
\xdef\CurLst{"\pgfplotsretval"}
\pgfmathsetmacro{\tmpwd}{width("\pgfplotsretval")}
\xdef\tmpwd{\tmpwd}
\else
\xdef\CurLst{\CurLst,"\pgfplotsretval"}
\pgfmathsetmacro{\tmpwd}{\tmpwd+width("\pgfplotsretval")}
\xdef\tmpwd{\tmpwd}
\fi
\fi
}
\typeout{\Row,\CurLst}
\pgfmathsetmacro{\ratio}{\number\value{realitems}*
(\pgfkeysvalueof{/tikz/funky bar/width}-2*\pgfkeysvalueof{/tikz/funky bar/inner sep})/\tmpwd}
\ifnum\Row=0
\else
\fi
\foreach \X [evaluate=\X as \PrevX using {int(\X-1)}] in {1,...,\number\value{realitems}}
{\ifnum\number\value{realitems}=1
\pgfmathsetmacro{\myitem}{\CurLst}
\typeout{\myitem}
\pgfmathsetmacro{\mywidth}{\pgfkeysvalueof{/tikz/funky bar/width}}
\node[anchor=center,inner sep=0pt,scale=\ratio] (n-\Row-\X)
at ([xshift=\mywidth/2]n-\Row-\PrevX.east)  {\myitem};
\draw ([yshift=-\pgflinewidth/2]n-\Row-0.north -| n-\Row-\PrevX.east)
-- ++ (\mywidth pt,0) |- ([yshift=\pgflinewidth/2]n-\Row-0.south -| n-\Row-\PrevX.east);;
\else
\pgfmathsetmacro{\myitem}{{\CurLst}[\X-1]}
\pgfmathsetmacro{\mywidth}{2*\pgfkeysvalueof{/tikz/funky bar/inner sep}+\ratio*width("\myitem")}
\node[anchor=center,inner sep=0pt,scale=\ratio,
right={ifthenelse(\X==1,1,2)*\pgfkeysvalueof{/tikz/funky bar/inner sep}}
of n-\Row-\PrevX] (n-\Row-\X) {\myitem};
\draw ([yshift=-\pgflinewidth/2]n-\Row-0.north -| n-\Row-\PrevX.east)
-- ++ (\mywidth pt,0) |- ([yshift=\pgflinewidth/2]n-\Row-0.south -| n-\Row-\PrevX.east);;
\fi
}
}
\end{tikzpicture}
\end{document}