Is it possible to produce data cubes in Latex with reasonable effort?

I want to state from the beginning that this is not supposed to be a “please draw for me” post. I just would like to know if it is possible to produce a data cube similar to this

with reasonable effort in Latex. I would preferable start off with a template if any is available. Reasonable effort shall be defined as two hours work max. My starting point is no knowledge of drawing in Latex. I basically only know that tikz can be used for drawing.

If anyone has done something similar I would appreciate it very much if he or she could post the code here and preferable state what he or she read in order to do it. If anyone knows where a template can be found, I would very much appreciate a link to the template. If it is not possible to produce a data cube with what was defined as reasonable effort but anyone knows some freeware program to produce this kind of data cube, I would like to invite the person to post the link to the program.

• This could help but a lot of tweaking would be needed: tex.stackexchange.com/questions/29877/… – Augustin May 11 '15 at 15:40
• I would say: No. But it's hard to say because, of course, it depends how quickly you read and learn. If you're unfamiliar with TikZ but familiar with some similar syntax (perhaps from programming), it might be easier for you than it was for me ;). Or I may just be an unusually slow learner :(. That is, it is perfectly possible to do this in TikZ (or, I assume, pstricks etc.) but not if you know nothing about the system and have a 2 hour limit. If this is a one-off, use a graphical programme. If you need to draw other cubes or things, it might be worth more than 2 hours to learn a system. – cfr May 11 '15 at 15:41
• "Reasonable effort shall be defined as two hours work max." Uhm... :D – Alenanno May 11 '15 at 15:45
• I will only need one of these data cubes and will most likely use another graphic program if nothing else will come up here. @Alenanno As "reasonable effort" is a rather wide term I have chosen to define it in terms of hours. – Thomas May 11 '15 at 17:23
• @Thomas Please post the edit here as a follow-up question (you can link this question in the new one). It's better that way. This way you're changing this question which has been already been answered. – Alenanno May 13 '15 at 15:24

• the matrix library for the main part, including some auxiliary macros \rd and \rn for some random content in the matrix,
• the calc library for some easy vector calculation,
• my paths.ortho library (code: [1] and [2]) for the connections outside of the matrix,
• my positioning-plus library for the use of left=of |(n1)(n2) which positions a node to the left of the vertical center of (n1) and (n2).

The local cs key (packaged later in the my cs style) is used to create a custom coordinate system that slants the vertical axis for the three-dimension part of the cube. (There are a lot of different ways to achieve this.)

There are also various different ways to achieve specific things in this code:

We could have drawn the lines inside the matrix as part of the inner nodes that lie inside it. We could have used the workarounds in the linked answer to replace my library.

A few explanations:

tight matrix

I have used a style tight matrix defined as

  tight matrix/.style={
matrix of nodes, inner sep=+0pt, outer sep=+0pt,
every cell/.append style={
every node/.append style={
outer sep=+0pt,
inner xsep=+.1em,
inner ysep=+.3333em, % default (overwritten by matrix inner sep)
align=center,
text depth=+0pt, % depth("y"),
text height=height("M"),
text width=width("MMM-00-00"), % possibly other approaches
}}},


that sets up a tight matrix where the matrix’ nodes are set border to border. The text … keys are used so that all nodes have same height, depth and width.

The matrix is then filled just as you would.

A custom coordinate system simulating the third dimension

With my cs/.style={local cs={m.north west}{m.north east}{1}{2}} I'm setting up a coordinate system which origins lie at (m.north west), the x vector points to (m.north east) and the y coordinate is “x-slanted” by the factor of 1 (For every y you go an additionally 1 to the right.) Also, the y is doubled.

I have used the xslanting as a way to use orthogonal parts (like |-, -| or my own -|-) without the need to worry about the third dimension.

However, there is actually a third dimension in TikZ. Its vector can be set with the z key and its default is (-3.85mm, -3.85mm). (So it actually points “out” of the paper.) We cannot use this third dimension in path operators. (It’s just a coordinate specification which maps three values to 2d-vectors.) However the direction of the y vector can be calculated from the xslanting: <direction> = atan(1/<xslant>).

The “third” dimension

With the coordinate system set up, we can draw the cube’s borderuse a usual rectangle path operator and it will draw a slanted rectangle.

The coordinate system also allows us to use the relative coordinate + (up:1) if we want to get into the third dimension anyway.

Lines

With the custom coordinate system set up we can draw the box’s border:

\draw (0,0) |- (1,1) -- (right:1)
(m.south east) -- ++ (up:1) -- (1,1);


In a few loops, we draw the lines:

\foreach \c in {1,2,3}
\draw (m-12-\c.south east) -- (m-1-\c.north east) -- ++ (up:1);
\foreach \c in {1,...,12}
\draw[if={isodd(\c)}{densely dashed}{}]
(m-\c-1.south west) -- (m-\c-4.south east) -- ++(up:1);
\foreach \c in {1,...,7}
\draw[if={isodd(\c)}{densely dashed}{}]
(up:\c/8) coordinate (tl-\c) -- ++ (right:1) -- ([shift=(up:\c/8)]m.south east);


Here, I also define seven coordinates we later use to place the nodes at the top left of the cube.

Even though, in all three paths, the custom coordinate system is active, named nodes/coordinates are not affected as they are referenced absolutely. The ++(up:1) is used to get into the third dimension. The same applies to the shift coordinate at the end.

Nodes

For the placing of the descriptive nodes we either use the matrix’ cells’ nodes’ anchors as in

\foreach \st/\lt[count=\c from 0, evaluate={\d=int(2*\c+1)}]
in {af/Africa, as/Asia, au/Australia, eu/Europe, na/North\\America, sa/South\\America}
\node[continent] (\st) at (m-\d-1.south west) {\lt};


or the previous defined coordinates:

\foreach \st[count=\c from 0, evaluate={\d=int(2*\c+1)}] in {air, sea, road, rail}
\node[continent, left=of (tl-\d)](\st){\st};


• @Qrrbrbirlbel That's brilliant, where do you learn these things?! :D – Alenanno May 12 '15 at 21:25