51

I need this table:

table

(each row and column should have the same height and length, last cell should be divided by diagonal line). I tried the following code:

\documentclass[11pt]{article}
\usepackage[T1]{fontenc}
\usepackage{array}
\usepackage{makecell}
\newcolumntype{x}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}p{#1}}
\begin{document}
\setlength{\extrarowheight}{0.1cm}
\begin{tabular}{|x{0.5cm}|x{0.5cm}|x{0.5cm}|x{0.5cm}|x{0.5cm}|}\hline
&&&&20\\ \hline
&&&&30\\ \hline
&&&&45\\ \hline
15&12&18&50&\diaghead(-3,2){\hskip \hsize}{$a_i$}{$b_j$}\\ \hline
\end{tabular}
\end{document}

but text in the last cell is displayed incorrectly and cells are not the same.

table - latex

How can I change that?

LiN
  • 1,361
  • 2
    Use slashbox instead. – Leo Liu May 08 '11 at 15:18
  • 3
    possible duplicate of Tables of numbers – Leo Liu May 08 '11 at 15:18
  • I tried 'slashbox' but it doesn't give a good result. – LiN May 08 '11 at 15:31
  • I'm sorry I didn't look your question very carefully. slashbox and makecell both have some limitations due to LaTeX's picture env and their own algorithm. I'll provide a manual solution later. – Leo Liu May 08 '11 at 15:46
  • 3
    @leoliu: are you the same person as the author of diagbox, which seems to me to do the job noticeably better than slashbox? i know it's not "sexy" any more to be using pict2e graphics, but it does do this job pretty well... – wasteofspace Nov 21 '12 at 09:48
  • @wasteofspace: Yes, I'm the author of diagbox. This example is a bit different, the spacing is very small. But I would rather use larger cell with diagbox. – Leo Liu Nov 21 '12 at 10:52
  • 6
    @LeoLiu Based on that comment, perhaps we could have an answer using diagbox (for completeness)? – Joseph Wright Jan 07 '13 at 16:19
  • @JosephWright: I would update diagbox to add some new options first, then the problem can be solved by diagbox. And I find that \extrarowheight is not quite easy to handle. – Leo Liu Jul 03 '14 at 03:17

6 Answers6

33

Editor's note: The solution below has an inaccuracy because of the line width, refer to https://tex.stackexchange.com/a/89840/250119 for a fix.


Exact solution with TikZ:

\documentclass[11pt]{article}
\usepackage[T1]{fontenc}
\usepackage{array}
\usepackage{makecell}
\newcolumntype{x}[1]{>{\centering\arraybackslash}p{#1}}

\usepackage{tikz} \newcommand\diag[4]{% \multicolumn{1}{p{#2}|}{\hskip-\tabcolsep $\vcenter{\begin{tikzpicture}[baseline=0,anchor=south west,inner sep=#1] \path[use as bounding box] (0,0) rectangle (#2+2\tabcolsep,\baselineskip); \node[minimum width={#2+2\tabcolsep},minimum height=\baselineskip+\extrarowheight] (box) {}; \draw (box.north west) -- (box.south east); \node[anchor=south west] at (box.south west) {#3}; \node[anchor=north east] at (box.north east) {#4}; \end{tikzpicture}}$\hskip-\tabcolsep}}

\begin{document} \setlength{\extrarowheight}{0.1cm} \begin{tabular}{|x{0.5cm}|x{0.5cm}|x{0.5cm}|x{0.5cm}|x{0.5cm}|}\hline &&&&20\ \hline &&&&30\ \hline &&&&45\ \hline 15&12&18&50&\diag{.1em}{.5cm}{$a_i$}{$b_j$}\ \hline \end{tabular} \end{document}

enter image description here

Also it is a reimplementation of \diaghead.

user202729
  • 7,143
Leo Liu
  • 77,365
  • The code is similar to slashbox and makecell. For a general macro \diag, the code \multicolumn{1}{p{#2}|} may be changed. – Leo Liu May 08 '11 at 16:38
  • 4
    it would be great if you made that into a package; this is a common requirement, and it would be nice to do the job in "some other" way – wasteofspace Nov 21 '12 at 09:45
  • There is a question discussing the issues all solutions that aren't all-TikZ seem to have http://tex.stackexchange.com/questions/89745/why-is-diaghead-from-makecell-so-ugly-sometimes Your solution was also highlighted so maybe you want to join :) – Christian Jan 08 '13 at 10:55
  • 1
    If I understand the comments correctly, this solution has been implemented as the diagbox package, which is now part of the TeX live distribution. I recommend editing this answer to reflect the simple call to diagbox that is now possible (thanks for that). – EL_DON Jun 03 '22 at 04:42
19

Okay as this seems to be the question that all duplicates link to eventually, I want to include @Leo Liu's solution from here as well as this seems to solve the problem in the easiest way.

In short: Use the @Leo Liu's package diagbox.

MWE (coming from a different context and does not exactly answer to this question) shamelessly copied from Leo's answer (link above):

\documentclass{article}

\usepackage{diagbox}

\begin{document}

\begin{tabular}{|l|c|c|}\hline
\diagbox[width=10em]{Diag\\Column Head I}{Diag Column\\Head II}&
  Second & Third \\ \hline
& foo & bar \\ \hline
\end{tabular}

\end{document}

Resulting in
Compiled result of MWE

If you like this solution make sure you go ahead and show Leo's original answer some love.


Admittedly this solution doesn't work so well (out of the box) with the provided MWE but if one uses normal column types instead of the custom ones, one gets a really good result:

\documentclass{standalone}
\usepackage{diagbox}

\begin{document}
    \begin{tabular}{|c|c|c|c|c|}
        \hline
           &    &    &    &           20           \\ \hline
           &    &    &    &           30           \\ \hline
           &    &    &    &           45           \\ \hline
        15 & 12 & 18 & 50 & \diagbox{$a_i$}{$b_j$} \\ \hline
    \end{tabular}
\end{document}

Results in
Compiled result of the MWE2

Raven
  • 3,023
  • Side note, you must manually specify the width/height of the diagbox to be at least the width/height of cells on the same column/row. There's another answer below https://tex.stackexchange.com/a/278162/250119 that sets the width/height automatically (but need 2 compilation passes). – user202729 Mar 29 '23 at 02:35
  • \diagbox can be used with the original MWE as well, write \diagbox[width=0.5cm+2\tabcolsep]{$a_i$}{$b_j$}. – user202729 Mar 05 '24 at 23:45
10

It might be possible to draw a diagonal line which fits exactly in a table cell, but it might be easier to draw the whole table as a picture.

Here my attempt using tikz. For large tables the need for nodes for each cell might be quite an effort, but it should be OK for smaller ones.

\documentclass[11pt]{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[x=.75cm,y=.5cm]
    \draw (0,0) grid [step=1] (5,4);
    \node at (0.5,0.5) {15};
    \node at (1.5,0.5) {12};
    \node at (2.5,0.5) {18};
    \node at (3.5,0.5) {50};
    \node at (4.5,3.5) {20};
    \node at (4.5,2.5) {30};
    \node at (4.5,1.5) {45};
    \draw (4,1) -- (5,0);
    \node at (5.0,1.0) [below left,inner sep=1pt] {\small$a_i$};
    \node at (4.0,0.0) [above right,inner sep=1pt] {\small$b_j$};
\end{tikzpicture}
\end{document}

Result

Martin Scharrer
  • 262,582
7

Here's a solution using TikZ:

\documentclass[11pt]{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}

\begin{tikzpicture}%[thick]
  \matrix (mat) [%
    matrix of nodes,
    nodes in empty cells,
    text width=0.8cm,
    text height=10pt,
    text depth=2pt,
    text badly centered
  ] 
  {%
     & & & & 20 \\
     & & & & 30  \\
     & & & & 45  \\
    15 & 12 & 18 & 50 & \raisebox{5pt}{$a_i$}\hspace{-15pt}\llap{\raisebox{-1pt}{$b_j$}}\\
  };
  % horizontal lines
  \foreach \i in {1,2,3,4}
        \draw (mat-\i-1.north west) -- (mat-\i-5.north east);
  \draw (mat-4-1.south west) -- (mat-4-5.south east);
  % vertical lines
  \foreach \j in {1,2,3,4,5}
    \draw (mat-1-\j.north west) -- (mat-4-\j.south west);
  \draw (mat-1-5.north east) -- (mat-4-5.south east);
  % diagonal line    
  \draw (mat-4-5.north west) -- (mat-4-5.south east);
\end{tikzpicture}

\end{document}

EDIT: in the solution I initially gave, the last cell contents was not what the OP wanted. I corrected it.

Moriambar
  • 11,466
Gonzalo Medina
  • 505,128
5

A solution with {NiceTabular} of nicematrix which has a built-in command \diagbox. Moreover, you can draw all the rules with only one key hvlines.

\documentclass{article}
\usepackage{nicematrix}

\begin{document} \setlength{\extrarowheight}{1mm} \begin{NiceTabular}{ccccc}[hvlines] & & & & 20 \ & & & & 30 \ & & & & 45 \ 15 & 12 & 18 & 50 & \diagbox{$a_i$}{$b_j$} \ \end{NiceTabular} \end{document}

Ouput of the above code

F. Pantigny
  • 40,250
4

Here's another solution using Tikz and based on a given solution by Heiko Oberdiek.

\documentclass{article}
\pagestyle{empty}% for cropping
\usepackage{array}
\usepackage{makecell}
\newcolumntype{x}[1]{>{\centering\arraybackslash}p{#1}}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{zref-savepos}

\newcounter{DiagonalizedEntry}
\renewcommand*{\theDiagonalizedEntry}{NTE-\the\value{DiagonalizedEntry}}

\newcommand*{\diagonalize}[2]{%
  \multicolumn{1}{@{}c@{}|}{%
    \stepcounter{DiagonalizedEntry}%
    \vadjust pre{\zsavepos{\theDiagonalizedEntry t}}% top
    \vadjust{\zsavepos{\theDiagonalizedEntry b}}% bottom
    \zsavepos{\theDiagonalizedEntry l}% left
    \hspace{0pt plus 1filll}%
    \zsavepos{\theDiagonalizedEntry r}% right
    \tikz[overlay]{%
      \draw[red]
        let
          \n{llx}={\zposx{\theDiagonalizedEntry l}sp-\zposx{\theDiagonalizedEntry r}sp}, % x left
          \n{urx}={0}, % x right
          \n{lly}={\zposy{\theDiagonalizedEntry b}sp-\zposy{\theDiagonalizedEntry r}sp}, % y bottom
          \n{ury}={\zposy{\theDiagonalizedEntry t}sp-\zposy{\theDiagonalizedEntry r}sp} %  y top
    in
        (\n{llx}, \n{ury}) -- (\n{urx}, \n{lly})
    node[anchor=south west] at (\n{llx}, \n{lly}) {#1}
    node[anchor=north east] at (\n{urx}, \n{ury}) {#2}
    ;
    }% 
  }%
}

\begin{document}
\renewcommand{\arraystretch}{2}
\renewcommand\tabcolsep{10pt}
\begin{tabular}{|x{0.5cm}|x{0.5cm}|x{0.5cm}|x{0.5cm}|x{0.5cm}|}\hline
&&&&20\\ \hline
&&&&30\\ \hline
&&&&45\\ \hline
15&12&18&50&\diagonalize{$a_i$}{$b_j$} \\ \hline
\end{tabular}
\end{document}

enter image description here

Hamed
  • 569