5

A document I'm working on has a table that was complicated enough for me to try and make it using a pgf matrix of nodes. However, the resulting matrix ended up being slightly too big for the page.

I'm fine with it extending slightly outside the margins, since making it smaller would probably only make it harder to read. But it won't do to have it coming off the margins and off-centre. So I've been trying to reposition it to the centre of the page. However, my usual approaches are useless here: [xy]shift won't work and I've tried anchoring its centre to the current page.center node to no avail.

So, how do I position a matrix that is too large for the page?

MWE follows:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgf}
\usetikzlibrary{matrix}

\begin{document}

\begin{tikzpicture}
  \matrix [matrix of nodes,
      nodes={
        text depth=4em,
        text height=5em,
        minimum width=10em,
        draw
      },
      row sep=-\pgflinewidth,
      column sep=-\pgflinewidth,
    ]
  {
    A & B & C & D \\
    A & B & C & D \\
    A & B & C & D \\
    A & B & C & D \\
  };
\end{tikzpicture}

\end{document}

2 Answers 2

5

You can define a new environment:

\documentclass{article}
\usepackage[pass,showframe]{geometry} % just to show the margins

\usepackage{tikz}
\usetikzlibrary{matrix}

\newenvironment{xcenter}
 {\par\setbox0=\hbox\bgroup\ignorespaces}
 {\unskip\egroup\noindent\makebox[\textwidth]{\box0}\par}

\begin{document}

\begin{xcenter}
\begin{tikzpicture}
  \matrix [matrix of nodes,
      nodes={
        text depth=4em,
        text height=5em,
        minimum width=10em,
        draw
      },
      row sep=-\pgflinewidth,
      column sep=-\pgflinewidth,
    ]
  {
    A & B & C & D \\
    A & B & C & D \\
    A & B & C & D \\
    A & B & C & D \\
  };
\end{tikzpicture}
\end{xcenter}

\end{document}

enter image description here

5
  • Nice! Could you elaborate why this works but not a plain \makebox[\textwidth]? I tried that originally, but found that it produces a ton of errors. This, however, works perfectly.
    – jja
    Aug 15, 2013 at 22:45
  • @jja For putting it in a \makebox you have to use the key ampersand replacement, see section 17.5 in the manual.
    – egreg
    Aug 15, 2013 at 22:56
  • Thanks for pointing that out. However, I haven't been able to get xcenter to work with the actual document. In it, the chart is actually inside a landscape environment (from lscape), and this seems to mess with the alignment. If I remove the landscape the chart is centered, but too wide to fit on the page; with the landscape the alignment is off, with the chart too close to the left (=bottom). Any ideas? Or should I start a new question, since this one has been answered?
    – jja
    Aug 15, 2013 at 23:25
  • @jja That's a different problem. The landscape environment doesn't update \textwidth, so in that case you should use \hsize (or maybe \textheight, I don't remember if it works).
    – egreg
    Aug 16, 2013 at 9:07
  • Brilliant! I had tried with textheight, but hsize did the trick.
    – jja
    Aug 16, 2013 at 9:30
2

This approach uses a stacking command to stack the overwide box atop a null argument. The key to its success is \def\useanchorwidth{T} which tells the stackengine to define the width of the stack by the anchor, and not what is stacked on the anchor. Because the anchor is a null argument, the stackwidth is 0pt, and has no problem being typset with centering, such that it spills into both margins.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgf}
\usetikzlibrary{matrix}
\usepackage{stackengine}
\begin{document}
\newsavebox\toowide
\setbox0=\hbox{%
\begin{tikzpicture}
  \matrix [matrix of nodes,
      nodes={
        text depth=4em,
        text height=5em,
        minimum width=10em,
        draw
      },
      row sep=-\pgflinewidth,
      column sep=-\pgflinewidth,
    ]
  {
    A & B & C & D \\
    A & B & C & D \\
    A & B & C & D \\
    A & B & C & D \\
  };
\end{tikzpicture}
\unskip}
\sbox\toowide{\box0}

\def\useanchorwidth{T}
\def\stacktype{L}
{\centering
\stackon[0pt]{}{\usebox{\toowide}}

}

\noindent\rule{\textwidth}{1ex}
\end{document}

enter image description here

If one were to want this feature often, the command

\newcommand\zerowidth[2][c]{\stackengine{0pt}{}{#2}{O}{#1}{F}{T}{L}}

would allow usage as (using the syntax of this MWE):

\centering\zerowidth{\usebox{\toowide}}

to achieve the same result. The optional argument to \zerowidth specifies whether the contents of the zero-width item are flush-left, centered, or flush-right relative to the zero-width "marker". You can think of \zerowidth as \hsmash.

3
  • I hadn't heard of the stackengine package, but reading the documentation now it does look like it could come in handy in the future. It'll take some time to familiarize myself with it though... :)
    – jja
    Aug 16, 2013 at 11:54
  • 1
    @jja See revised answer which provides \zerowidth macro. Thanks to your question, I think I may add \zerowidth to the package, as it seems a useful feature to be able to create a non-null item of zero width. Perhaps I should call it \hsmash Aug 16, 2013 at 12:04
  • It does make it easier; I bet such a macro would see some use. I'll give it a shot in a bit to see how it behaves on my document, but now I need to stop procrastinating with LaTeX alignment and get some work done!
    – jja
    Aug 16, 2013 at 12:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.