Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

How can I account for the space taken by the y-axis labels? Can I somehow \setbox the axis labels, or something similar? Because now, the y-axis labels stick out of the text block width (because I have not been able to account for them).

Macro:

\newcount\itemcount \newcount\maximumvalue
\def\chartfour#1#2#3#4#5{%
  % 1. divide the given width (#1) with the number of items (#2)
  % 2. divide the result (width of item) with the number of bars
  % 3. shift the bars
  % 4. TODO: account for the y-axis labels
  \itemcount=0
  \maximumvalue=0
  \tikzpicture[yscale=#4,xscale=#5]
    \foreach \x/\y/\z/\t/\p in {#2}{
      \global\advance\itemcount by1
      \pgfmathparse{max(\maximumvalue,\y)}
      \pgfmathparse{max(\pgfmathresult,\z)}
      \pgfmathparse{max(\pgfmathresult,\t)}
      \pgfmathparse{max(\pgfmathresult,\p)}
      \global\maximumvalue=\pgfmathresult
    }
    \pgfmathparse{#1/\itemcount}\let\itemwidth=\pgfmathresult
    \pgfmathparse{sqrt(\itemwidth)}\let\barwidth=\pgfmathresult
    \itemcount=0
    \pgfmathparse{(\maximumvalue+1*#3)/#3}\let\ytop=\pgfmathresult
    \useasboundingbox (0,-\baselineskip) rectangle (#1,\ytop);
    \foreach \y in {0,1,...,\ytop}{
      \pgfmathparse{int(\y*#3)}\let\label=\pgfmathresult
      \draw[help lines] (0,\y) -- +(#1,0);
      \node[left,inner xsep=0pt,outer xsep=0pt] at (-0.2,\y) {\label};
    }
    \foreach \x/\y/\z/\t/\p in {#2}{
      \global\advance\itemcount by1
      \pgfmathparse{\itemcount*\itemwidth-\itemwidth/2 pt}\let\xpos=\pgfmathresult
      \pgfmathparse{\y/#3}\let\yheight=\pgfmathresult
      \draw[xshift=-\barwidth*1.5,ycomb,color=blue,line width=\barwidth]
        plot coordinates{(\xpos pt,\yheight)};% node[above] {\y};
      \pgfmathparse{\z/#3}\let\zheight=\pgfmathresult
      \draw[xshift=-\barwidth/2,ycomb,color=red,line width=\barwidth]
        plot coordinates{(\xpos pt,\zheight)};% node[above] {\z};
      \pgfmathparse{\t/#3}\let\aheight=\pgfmathresult
      \draw[xshift=\barwidth/2,ycomb,color=green,line width=\barwidth]
        plot coordinates{(\xpos pt,\aheight)};% node[above] {\t};
      \pgfmathparse{\p/#3}\let\bheight=\pgfmathresult
      \draw[xshift=\barwidth*1.5,ycomb,color=magenta,line width=\barwidth]
        plot coordinates{(\xpos pt,\bheight)};% node[above] {\p};
      \node[below] at (\xpos pt,0) {\x};
      }
    \draw (#1,0) -- (0,0) -- (0,\ytop);
  \endtikzpicture
}

Usage:

\noindent\chartfour{1\hsize}{
  2000/21/8/6/5,
  2001/26/10/7/6,
  2002/20/8/3/0,
  2003/23/8/5/2,
  2004/25/12/0/1,
  2005/19/10/9/5,
  2006/53/30/30/1,
  2007/70/16/10/4,
  2008/48/2/4/1
  }{20}{.8}{1}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec nisi
arcu. In rutrum felis eget neque posuere sodales. Aenean interdum diam sed nisi
condimentum semper. Suspendisse quis urna imperdiet quam malesuada sagittis ut
sed velit. Suspendisse cursus tincidunt dui pharetra varius. Aliquam mollis
lacus ac diam gravida quis venenatis lacus suscipit. Cras et nisl est, aliquam
iaculis ligula. Nulla consequat, odio a adipiscing lacinia, leo lectus feugiat
dui, a molestie sapien massa sit amet magna. Duis commodo lectus sit amet
tellus tempus mollis. Duis nec tortor id enim suscipit porttitor ac et libero.
Duis urna turpis, lobortis quis pretium nec, scelerisque eget est. Praesent
malesuada dapibus urna sed porttitor.

Ut tincidunt venenatis nisl ac faucibus. Curabitur quis pellentesque leo. Donec
at odio ac neque mollis vestibulum eget sed elit. Morbi hendrerit pulvinar
ligula, nec sagittis est tempus vel. Nulla non purus et sapien egestas
elementum et a tellus. Nullam tempor pulvinar ornare. Fusce neque nisl, viverra
at tincidunt quis, elementum vitae arcu. Sed lectus magna, adipiscing et cursus
non, facilisis at dolor. Aenean luctus mattis mauris, vitae sodales urna
ultricies eget. Fusce nec elit in nulla condimentum pretium nec vel metus.
\raggedbottom\bye

EDIT: Following on the advise of being able to \setbox the labels, I tried several things; first, I tried to \setbox inside the tikzpicture, only to realize that TeX can't know anything about the width of the box until tikz is done. Then I made the following shortened macro to "dry-run" first to get the y-axis label width:

\input tikz
\newcount\itemcount \newcount\ymax \newcount\ytop
\newdimen\ylabelwidth \newdimen\totalwidth
\smash{\vrule depth\vsize height 0pt}
\def\chartfour#1#2#3#4#5{%
  \itemcount=0 \ymax=0 \ytop=0 \totalwidth=#1
  \setbox0\hbox{\tikzpicture[yscale=#4,xscale=#5]
    \foreach \a/\b/\c/\d/\e in {#2}{
      \global\advance\itemcount by1
      \pgfmathparse{max(\ymax,\b)}
      \pgfmathparse{max(\pgfmathresult,\c)}
      \pgfmathparse{max(\pgfmathresult,\d)}
      \pgfmathparse{max(\pgfmathresult,\e)}
      \global\ymax=\pgfmathresult
    }
    \pgfmathparse{(\ymax+1*#3)/#3}\global\ytop=\pgfmathresult
    \foreach \y in {0,1,...,\ytop}{
      \pgfmathparse{int(\y*#3)}\let\ylabel=\pgfmathresult
      \node[left,inner sep=0pt,outer sep=0pt,fill=red]
        at (0,\y) {\ylabel $\;$};
    }
    \endtikzpicture}
  \ylabelwidth=\the\wd0
  \box0 \the\ylabelwidth
}

Which produces:

So even after all this trouble, there appears to be some mystery whitespace left of the label. Where does it come from?

share|improve this question
    
+1 for the work on this macro. But I wonder why you didn't do the whole thing with »pgfplots«. –  Thorsten Donig Nov 26 '10 at 8:56
    
@Thorsten Donig: thank you for the tip, I'm grateful for any and all advice on how to improve this macro. I'll look into pgfplots. –  morbusg Nov 26 '10 at 10:48

1 Answer 1

up vote 2 down vote accepted

You could adjust this line in your code:

\useasboundingbox (0,-\baselineskip) rectangle (#1,\ytop);

For example, using

\useasboundingbox (-1em,-\baselineskip) rectangle (#1,\ytop);

and \chartfour{.92\hsize}{...} to stay in the text area, I get:

The y labels don't stick out any more. And yes, you may use \setbox to calculate the width if you don't like to set it manually.

alt text

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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