% \iffalse %% File: histogr.dtx Copyright (C) 1987-1997 Rainer Sch\"opf % % It may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of LaTeX % version 2005/12/01 or later. % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{histogr} % [1997/02/13 v1.01 Histogram (RmS)] % %<*driver> \documentclass{ltxdoc} \usepackage{histogr} \GetFileInfo{histogr.sty} \begin{document} \title{Drawing histogram bars inside the \LaTeX\ {\sf picture}--environment\thanks{This file has version number \fileversion, last revised \filedate.}} \author{Rainer Sch\"opf} \date{\filedate} \maketitle \DocInput{histogr.dtx} \end{document} % % \fi % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \CheckSum{92} % % \changes{1.01}{1997/02/13}{Version 1.0a converted to \LaTeXe % documentation format.} % % \begin{abstract} % This article describes an enhancement of the \LaTeX\ % {\sf picture}--environment to draw histogram bars. % \end{abstract} % % \section{User interface} % % \DescribeMacro{\histogram} % This is a macro collection to draw histogram bars inside a % {\sf picture}--environment. Use is as follows: % % \verb+\histogram+($x_0$,$y_0$)($x_1$,$y_1$)...($x_n$,$y_n$) % % The coordinate pairs specify the upper left corner of % the histogram bars, i.e. % this will draw a horizontal line from $(x_i,y_i)$ to $(x_{i+1},y_i)$, % then a vertical line from $(x_{i+1},y_{i})$ to $(x_{i+1},y_{i+1})$ % \DescribeMacro{\noverticallines} % \DescribeMacro{\verticallines} % if \verb+\noverticallines+ was specified, % else from $(x_{i+1},y_{0})$ to $(x_{i+1},\max(y_{i},y_{i+1}))$. % % Default is \verb+\verticallines+. % $y_{0}$ should be less or equal the minimum of all the ${y_i}$ % (i.e. other cases have not been tested). % % Let's start with an example: to get the following picture: % %\begin{center} %\setlength{\unitlength}{1mm} %\begin{picture}(100,65)(-10,-15) % %\thicklines %\put(0,-3){\vector(0,1){50}} %\put(-3,0){\vector(1,0){90}} %\thinlines % %\put(0,0){\line(0,-1){2}} %\put(2,0){\line(0,-1){2}} %\put(20,0){\line(0,-1){2}} %\put(22,0){\line(0,-1){2}} %\put(40,0){\line(0,-1){2}} %\put(42,0){\line(0,-1){2}} %\put(60,0){\line(0,-1){2}} %\put(62,0){\line(0,-1){2}} %\put(0,-1){\makebox(2,0)[t]{\small 1}} %\put(20,-1){\makebox(2,0)[t]{\small 2}} %\put(40,-1){\makebox(2,0)[t]{\small 3}} %\put(60,-1){\makebox(2,0)[t]{\small 4}} %\put(70,-1){\makebox(0,0)[t]{ml}} %\put(0,10){\line(-1,0){2}} %\put(0,20){\line(-1,0){2}} %\put(-3,8){\makebox(0,4)[r]{5}} %\put(-3,18){\makebox(0,4)[r]{10}} %\put(-3,30){\makebox(0,4)[r]{n}} %\put(15,-10){Behandler 1} %\histogram(0,0)(0,4)(2,4)(4,4)(6,0)(8,10)(10,8)(12,6)(14,4) % (16,14)(18,8)(20,18)(22,18)(24,8)(26,0)(28,10)(30,2) % (32,12)(34,4)(36,6)(38,6)(40,18)(42,10)(44,14)(46,4) % (48,8)(50,4)(52,6)(54,4)(56,6)(58,2)(60,2)(62,0) %\end{picture} %\end{center} % I used these \LaTeX\ commands: % \begin{verbatim} % \setlength{\unitlength}{1mm} % \begin {picture}(100,65)(-10,-15) % % \thicklines % \put(0,-3){\vector(0,1){50}} % \put(-3,0){\vector(1,0){90}} % \thinlines % % \put(0,0){\line(0,-1){2}} % \put(2,0){\line(0,-1){2}} % \put(20,0){\line(0,-1){2}} % \put(22,0){\line(0,-1){2}} % \put(40,0){\line(0,-1){2}} % \put(42,0){\line(0,-1){2}} % \put(60,0){\line(0,-1){2}} % \put(62,0){\line(0,-1){2}} % % \put(0,-1){\makebox(2,0)[t]{\small 1}} % \put(20,-1){\makebox(2,0)[t]{\small 2}} % \put(40,-1){\makebox(2,0)[t]{\small 3}} % \put(60,-1){\makebox(2,0)[t]{\small 4}} % \put(70,-1){\makebox(0,0)[t]{ml}} % % \put(0,10){\line(-1,0){2}} % \put(0,20){\line(-1,0){2}} % % \put(-3,8){\makebox(0,4)[r]{5}} % \put(-3,18){\makebox(0,4)[r]{10}} % \put(-3,30){\makebox(0,4)[r]{n}} % % \put(15,-10){Behandler 1} % % \histogram(0,0)(0,4)(2,4)(4,4)(6,0)(8,10)(10,8)(12,6)(14,4) % (16,14)(18,8)(20,18)(22,18)(24,8)(26,0)(28,10)(30,2) % (32,12)(34,4)(36,6)(38,6)(40,18)(42,10)(44,14)(46,4) % (48,8)(50,4)(52,6)(54,4)(56,6)(58,2)(60,2)(62,0) % \end{picture} %\end{verbatim} % % \StopEventually{} % % \section{Implementation} % % \begin{macrocode} %<*package> % \end{macrocode} % % \begin{macro}{\hist@x} % \begin{macro}{\hist@y} % \begin{macro}{\hist@ystart} % Here's how it is implemented: first we allocate three counters that % are needed later on. \verb+\hist@x+ and \verb+\hist@y+ are the % $x$ and $y$ coordinate of the {\em current point}, i.e. the point % that serves as a start for the next box of the histogram. % \verb+\hist@ystart+ holds the $y$ coordinate of the first point, % i.e. $y_{0}$. % \begin{macrocode} \newcount\hist@x \newcount\hist@y \newcount\hist@ystart % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\noverticallines} % \begin{macro}{\verticallines} % We need a switch to decide if the vertical lines of the histogram % boxes are to be drawn from $y_{i}$ to $y_{i+1}$ or from $y_{0}$ % to $\max(y_{i}, y_{i+1})$. Default is the latter. % \begin{macrocode} \newif\ifhist@vert \let\verticallines\hist@verttrue \let\noverticallines\hist@vertfalse \hist@verttrue % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\histogram} % The \verb+\histogram+ command % takes the starting point as argument and initializes the counters. % \verb+\hist@x+, \verb+\hist@y+ and \verb+\hist@ystart+ are set to % $x_{0}$, $y_{0}$ and $y_{0}$, respectively. % \begin{macrocode} \def\histogram(#1,#2){\hist@x #1 \hist@y #2 \hist@ystart\hist@y % \end{macrocode} % Then the macro \verb+\hist@next+ is used. % \begin{macrocode} \hist@next} % \end{macrocode} % \end{macro} % \begin{macro}{\hist@next} % \verb+\hist@next+ looks at the next token to see if there is % another % open parentheses. If this is the case it calls \verb+\hist@box+, % otherwise \verb+\hist@end+. % \begin{macrocode} \def\hist@next{\@ifnextchar ({\hist@box}{\hist@end}} % \end{macrocode} % \end{macro} % \begin{macro}{\hist@box} % The macro \verb+\hist@box+ does nearly all the work. % The first thing to do is to set the temporary counter % \verb+\@tempcnta+ % to $x_{i+1} - x_{i}$. Remember that \verb+\hist@x+ is the $x$ % coordinate of the last point (i.e. $x_{i}$) whereas the macros % first argument is $x_{i+1}$. So we write % \begin{macrocode} \def\hist@box(#1,#2){\@tempcnta -\hist@x \advance\@tempcnta #1 % \end{macrocode} % The next step is easy: draw the horizontal part of the histogram % box. % The line starts at $(x_{i},y_{i})$ and has length % \verb+\@tempcnta\unitlength+. % \begin{macrocode} \ifnum \@tempcnta >\z@ \put(\hist@x,\hist@y){\line(1,0){\@tempcnta}}\else \put(\hist@x,\hist@y){\line(-1,0){-\@tempcnta}}\fi % \end{macrocode} % Now set \verb+\hist@x+ to $x_{i+1}$: % \begin{macrocode} \hist@x #1 % \end{macrocode} % If \verb+\verticallines+ was set we % first set \verb+\@tempcnta+ to $\max(y_{i},y_{i+1})$: % \begin{macrocode} \ifhist@vert \ifnum \hist@y >#2 \@tempcnta\hist@y \else \@tempcnta #2 \fi % \end{macrocode} % then we set \verb+\@tempcntb+ to the same value and % \verb+\@tempcnta+ to the length of the line to draw. % \begin{macrocode} \@tempcntb\@tempcnta \advance\@tempcnta -\hist@ystart % \end{macrocode} % We draw the line % \begin{macrocode} \put(\hist@x,\@tempcntb){\line(0,-1){\@tempcnta}}% % \end{macrocode} % which finishes this case. % \begin{macrocode} \else % \end{macrocode} % In the other case (i.e. if \verb+\noverticallines+ was set) % we have to draw a line from $y_{i}$ to $y_{i+1}$. % We set \verb+\@tempcnta+ to $y_{i+1} - y_{i}$ % \begin{macrocode} \@tempcnta -\hist@y \advance\@tempcnta #2 % \end{macrocode} % and draw the line. % \begin{macrocode} \ifnum \@tempcnta >\z@ \put(\hist@x,\hist@y){\line(0,1){\@tempcnta}}\else \put(\hist@x,\hist@y){\line(0,-1){-\@tempcnta}}\fi % \end{macrocode} % Thus endeth the drawing. % \begin{macrocode} \fi % \end{macrocode} % Finally we set \verb+\hist@y+ to $y_{i+1}$ and call % \verb+\hist@next+ to look for the next coordinate pair. % \begin{macrocode} \hist@y #2\hist@next} % \end{macrocode} % \end{macro} % \begin{macro}{hist@end} % There is only one thing we left out: what if there is no more % open parenthesis? That's the easy part: do nothing. % \begin{macrocode} \def\hist@end{} % \end{macrocode} % \end{macro} % Frank Mittelbach suggested that the $x$--coordinate should % specify the midpoint of the histogram bar, not the upper left % corner. However, I don't see how this will work if the bars % have different widths. What do you think about it? % % Well, that's all. Use it and enjoy. % % \Finale %