From 7550a40711358021c4e6028deb4aa9d11fc503e4 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Tue, 1 Oct 2019 11:31:05 +0900
Subject: add bargraph-js

---
 .../latex/bargraph-js/examples/bgjs-examples.dtx   | 1451 ++++++++++++++++++++
 1 file changed, 1451 insertions(+)
 create mode 100644 texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.dtx

(limited to 'texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.dtx')

diff --git a/texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.dtx b/texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.dtx
new file mode 100644
index 00000000..01c103af
--- /dev/null
+++ b/texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.dtx
@@ -0,0 +1,1451 @@
+%\iffalse
+% makeindex -s gglo.ist -o bgjs-examples.gls bgjs-examples.glo
+% makeindex -s gind.ist -o bgjs-examples.ind bgjs-examples.idx
+%<*copyright>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Example documentation for the bargraph-js package,    %%
+%% Copyright (C) 2019                                    %%
+%%   dpstory@uakron.edu                                  %%
+%%                                                       %%
+%% This program can redistributed and/or modified under  %%
+%% the terms of the LaTeX Project Public License         %%
+%% Distributed from CTAN archives in directory           %%
+%% macros/latex/base/lppl.txt; either version 1.2 of the %%
+%% License, or (at your option) any later version.       %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%</copyright>
+%<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01]
+%<package> [2019/04/29 v1.0 bgjs-examples: Documentation and examples for bargraph-js]
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{xcolor}
+\usepackage[colorlinks,hyperindex=false,bookmarksopen=true]{hyperref}
+%\pdfstringdefDisableCommands{\let\\\textbackslash}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\gdef\brpr#1{\texttt{\char123\relax#1\char125\relax}}
+\let\darg\brpr
+\let\env\texttt
+\let\opt\texttt
+\let\app\textsf
+\let\pkg\textsf
+\def\visispace{\symbol{32}}
+\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
+\def\meta#1{\textsl{\texttt{#1}}}
+\def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}}
+%\def\cs#1{\texttt{\bslash#1}}
+\DeclareRobustCommand{\tmspace}[3]{%
+  \ifmmode\mskip#1#2\else\kern#1#3\fi\relax}
+\renewcommand{\,}{\tmspace+\thinmuskip{.1667em}}
+\let\thinspace\,
+\renewcommand{\!}{\tmspace-\thinmuskip{.1667em}}
+\let\negthinspace\!
+\renewcommand{\:}{\tmspace+\medmuskip{.2222em}}
+\let\medspace\:
+\newcommand{\negmedspace}{\tmspace-\medmuskip{.2222em}}
+\renewcommand{\;}{\tmspace+\thickmuskip{.2777em}}
+\let\thickspace\;
+\newcommand{\negthickspace}{\tmspace-\thickmuskip{.2777em}}
+\makeatletter
+\renewcommand{\paragraph}
+    {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt}
+    {\normalfont\normalsize\bfseries}}
+\renewenvironment{quote}[1][]
+   {\def\@rgi{#1}\ifx\@rgi\@empty
+    \let\rghtm\@empty\else\def\rghtm{\rightmargin\leftmargin}\fi
+    \list{}{\rghtm} %{\rightmargin\leftmargin}%
+    \item\relax}
+   {\endlist}
+\makeatother
+\InputIfFileExists{aebdocfmt.def}{\PackageInfo{bgjs-examples}{Inputting aebdocfmt.def}}
+    {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
+     \PackageInfo{bgjs-examples}{aebdocfmt.def cannot be found}}
+\begin{document}
+\def\CMD#1{\textbackslash#1}
+  \title{\textsf{bgjs-examples}:
+    Documentation and examples for the \textsf{bargraph-js} package}
+  \author{D. P. Story\\
+    Email: \texttt{dpstory@acrotex.net}}
+  \date{processed \today}
+  \maketitle
+  \tableofcontents
+  \let\Email\texttt
+  \DocInput{bgjs-examples.dtx}
+\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute
+    \texttt{makeindex -s gind.ist -o bgjs-examples.ind bgjs-examples.idx}\\on the command line and recompile
+    \texttt{bgjs-examples.dtx}.}
+\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute
+    \texttt{makeindex -s gglo.ist -o bgjs-examples.gls bgjs-examples.glo}\\on the command line and recompile
+    \texttt{bgjs-examples.dtx}.}
+\end{document}
+%</driver>
+% \fi
+% \MakeShortVerb{|}
+% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{web}{Inputting aebdonotindex.def}}
+%    {\PackageInfo{web}{cannot find aebdonotindex.def}}
+%    \begin{macrocode}
+%<*package>
+%    \end{macrocode}
+%    \section{The Examples}
+%    This \textsf{DTX} file contains the source files for the examples of the \pkg{bargraph-js} package.
+%    It has the added advantage of enabling me to provide verbose comments without messing up
+%    the source files.
+%    \begin{macrocode}
+%</package>
+%<*basic1>
+%    \end{macrocode}
+%    \subsection{\texttt{bgjs-basic1.tex}}
+%    This is a minimal example, it
+%    illustrates the basic capability of the package: horizontal and vertical bars are shown.
+%    \begin{macrocode}
+\documentclass{article}
+%    \end{macrocode}
+%    Use of the \pkg{web} package is optional, my favorite package. If loaded, you can remove
+%    |\hypersetup{pdfpagemode=UseNone}| below, as \pkg{web} does not show the bookmarks by default.
+%    \begin{macrocode}
+ % \usepackage{web}
+%    \end{macrocode}
+%    Input ``the package''
+%    \begin{macrocode}
+\usepackage{bargraph-js}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+%    \end{macrocode}
+%    When developing the document use |\previewOn\pmpvOn|, the latter command is new (to \pkg{eforms}). It provides
+%    captions for the buttons. With this combination, outlines of form fields and captions for
+%    push buttons are seen in \app{SumatraPDF}, for example.
+%    \begin{macrocode}
+ % \previewOn\pmpvOn
+%    \end{macrocode}
+%    For the \pkg{bargraph-js} package, I prefer to specify |\makePDasXon| (from \pkg{eforms}), this attempts to make
+%    the dimensions of form fields correspond to the true dimensions, as \app{xelatex} does.
+%    \begin{macrocode}
+\makePDasXOn
+%    \end{macrocode}
+%    Below is ``sample'' document JavaScript to provide labeling to bars that do not have
+%    a |\TU| key specified (tool tip). There is a default labeling system, this overwrites
+%    that.
+%    \begin{macrocode}
+\begin{insDLJS}{lbl}{Labeling function}
+%%   fld="<bgenv-name>@<bg-name>.<bar-name>"
+%%   v=value of field
+function customLabelsForBars(fld,v){
+var pos=fld.indexOf(".");
+var bargraph=fld.substring(0,pos);
+var bar=fld.substring(pos+1);
+  switch(bargraph) {
+    case "vehiclesH@hBar":
+      switch(bar) {
+        case "auto":
+          return "Automobiles: "+v;
+        case "truck":
+         return "Pickup trucks: "+v;
+        case "suv":
+          return "SUV types: "+v+", costing big \$\$s";
+        case "van":
+          return "Family vans: "+v
+            +", these cost some serious \u20AC\u20ACs";
+        default:
+          return simpleBarLabels(fld,v);
+      }
+// other cases can be included
+    default:
+      return simpleBarLabels(fld,v);
+  }
+}
+\end{insDLJS}
+%    \end{macrocode}
+%    The \DescribeMacro\barLabelsTU\cs{barLabelsTU} takes either a string argument or a JavaScript function name.
+%    \cs{barLabelsTU} applies to all bars with a \cs{TU} key. The \cs{barLabelsTU} can be used within the body of
+%    the document to change the method of assigning labels to bars. When the argument is a (JavaScript) string,
+%    use the variables \texttt{@env@}, \texttt{@barname@}, \texttt{@bar@}, and \texttt{@v@}
+%    to compose the string, as seen below. When a string is provided, \emph{the \cs{TU} key is ignored}.
+%    \begin{macrocode}
+ % \barLabelsTU{"Within the \\"@env@\\" environment, within the
+ %   \\"@barname@\\" environment, the bar \\"@bar@\\"
+ %   has a value of @v@"}
+%    \end{macrocode}
+%     When the argument is a JavaScript function, you can specify the built-in function
+%     \texttt{customBarLabels}, or define your own. The function is expected to take two
+%     arguments, fld and v, eg, \texttt{customBarLabels(fld,v)}. Such a function should return
+%     a string.
+%    \begin{macrocode}
+\barLabelsTU{customBarLabels} % applies to all bars with a \TU key
+%    \end{macrocode}
+%    The \DescribeMacro\barLabelsNoTU\cs{barLabelsNoTU} takes a string or a function as its argument.
+%    The command \cs{barLabelsNoTU} is specified in the preamble and cannot be changed in the body of the document.
+%    This labeling system applies to all bars with no \cs{TU} key.
+%    When the argument is a string, use \texttt{o.barname}, \texttt{o.bar}, and \texttt{o.value} to compose
+%    the string. For example,
+%    \begin{macrocode}
+ % \barLabelsNoTU{"Vehicle Data: "+o.barname+": "
+ %    + o.bar+", Value: "+o.value}
+%    \end{macrocode}
+%     When the argument is a JavaScript function, the referenced function must be written. In this demo,
+%     \texttt{customLabelsForBars(fld,v)} is reference below; however, we choose the default, which
+%     is |\barLabelsNoTU{""}| (or |barLabelsNoTU{}|). The results are the same; however, the difference
+%     is that you can write your own handler.
+%    \begin{macrocode}
+\barLabelsNoTU{customLabelsForBars} % applies to all other bars
+
+\parindent0pt
+\begin{document}
+
+\textbf{Comments.} The bar graphs here are based on count data.
+Input natural numbers into the text fields. If the width of a horizontal
+bar or the height of a vertical bar goes outside the graphing area, the
+bar graph is \emph{automatically re-scaled} so the widest one (for
+horizontal) or highest one (for vertical) now fits. Try the
+\textsf{Optimize} buttons as well.\medskip
+
+\textbf{Instructions:} Stand at an intersection for one hour and count
+the number of vehicles of each of the specified types passing you going
+in one direction. Enter your results in the fields below.\medskip
+
+%% Here we use the default method of labeling the bar graphs
+\fbox{\begin{bargraphenv}[width=.67\linewidth,height=2in,
+  o=horiz]{vehiclesH}
+\presetsbarfor{hBar}{auto}{\BG{red}}
+\presetsbarfor{hBar}{truck}{\BG{green}}
+\presetsbarfor{hBar}{suv}{\BG{yellow}}
+\presetsbarfor{hBar}{van}{\BG{magenta}}
+\begin{bargraph}[nbars=4,gap=3]{hBar}
+\barfor{auto}\barfor{truck}\barfor{suv}\barfor{van}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {.33\linewidth-2\fboxsep-2\fboxrule-10pt}\kern0pt\parskip3pt
+\makebox[\widthof{Truck:}][l]{Auto:}
+  \inputFor{vehiclesH}{hBar}{auto}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Truck:}
+  \inputFor{vehiclesH}{hBar}{truck}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{SUV:}
+  \inputFor{vehiclesH}{hBar}{suv}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Van:}
+  \inputFor{vehiclesH}{hBar}{van}{.5in}{11bp}\vcgBdry[3bp]
+  \pushButton[\TU{This button re-scales the bar graph so that the
+  longest bar takes the entire width of the region.}\CA{Optimize}
+  \AAmouseup{optimizeScaling("vehiclesH");}]{optimize1}{}{13bp}
+\end{minipage}\medskip
+
+Reset horizontal bar graph: \pushButton[\CA{Reset}
+  \AAmouseup{resetBargraphs("vehiclesH");}]{reset}{}{13bp}\bigskip
+
+\fbox{\begin{bargraphenv}[width=2in,height=2in,o=vert]{vehiclesV}
+\presetsbarfor{vBar}{auto}{\BG{red}
+  \TU{There were @v@ automobiles observed}}
+\presetsbarfor{vBar}{truck}{\BG{green}
+  \TU{There were @v@ pickups observed during time period}}
+\presetsbarfor{vBar}{suv}{\BG{yellow}
+  \TU{There were @v@ SUVs observed, costing big
+    \textdollar\textdollar s}}
+\presetsbarfor{vBar}{van}{\BG{magenta}
+  \TU{There were @v@ family vans filled with happy people;
+    reminds me of J\"{u}rgen's family}}
+\begin{bargraph}[nbars=4,gap=3]{vBar}
+\barfor{auto}\barfor{truck}\barfor{suv}\barfor{van}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {\linewidth-2\fboxsep-2\fboxrule-2in-10pt}\kern0pt\parskip3pt
+\makebox[\widthof{Truck:}][l]{Auto:}
+  \inputFor{vehiclesV}{vBar}{auto}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Truck:}
+  \inputFor{vehiclesV}{vBar}{truck}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{SUV:}
+  \inputFor{vehiclesV}{vBar}{suv}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Van:}
+  \inputFor{vehiclesV}{vBar}{van}{.5in}{11bp}\vcgBdry[4bp]
+\pushButton[\TU{This button re-scales the bar graph so that the
+tallest bar takes the entire height of the region.}\CA{Optimize}
+  \AAmouseup{optimizeScaling("vehiclesV");
+}]{optimize2}{}{13bp}
+\end{minipage}\medskip
+
+Reset vertical bar graph:
+  \pushButton[\CA{Reset}\AAmouseup{resetBargraphs("vehiclesV");}
+]{reset}{}{13bp}\vcgBdry[6bp]
+Reset all bar graphs:
+  \pushButton[\CA{Reset}
+    \AAmouseup{resetBargraphs("vehiclesH","vehiclesV");}
+]{reset}{}{13bp}
+\end{document}
+%</basic1>
+%<*basic2>
+%    \end{macrocode}
+%    \subsection{\texttt{bgjs-basic2.tex}}
+%    This is the same as \texttt{bgjs-basic1.tex}, additionally, this example illustrates
+%    hard-wired (typeset) labels of the bars.
+%    \begin{macrocode}
+\documentclass{article}
+ % \usepackage{web}
+\usepackage{bargraph-js}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+%    \end{macrocode}
+%    In this file we use \cs{rotatebox}, so \pkg{graphicx} is required.
+%    \begin{macrocode}
+\usepackage{graphicx}
+ % \previewOn\pmpvOn
+\makePDasXOn
+
+\begin{insDLJS}{lbl}{Labeling function}
+%%   fld="<bgenv-name>@<bg-name>.<bar-name>"
+%%   v=value of field
+function customLabelsForBars(fld,v){
+var pos=fld.indexOf(".");
+var bargraph=fld.substring(0,pos);
+var bar=fld.substring(pos+1);
+  switch(bargraph) {
+    case "vehiclesH@hBar":
+      switch(bar) {
+        case "auto":
+          return "Automobiles: "+v;
+        case "truck":
+         return "Pickup trucks: "+v;
+        case "suv":
+          return "SUV types: "+v+", costing big \$\$s";
+        case "van":
+          return "Family vans: "+v
+            +", these cost some serious \u20AC\u20ACs";
+        default:
+          return simpleBarLabels(fld,v);
+      }
+// other cases can be included
+    default:
+      return simpleBarLabels(fld,v);
+  }
+}
+\end{insDLJS}
+ % \barLabelsTU{"Within the \\"@env@\\" environment,
+ %  within the \\"@barname@\\" environment, the bar \\"@bar@\\" has a
+ %  value of @v@"}
+\barLabelsTU{customBarLabels} % applies to all bars with a \TU key
+
+ % \barLabelsNoTU{customLabelsForBars} % applies to all other bars
+\barLabelsNoTU{"Vehicle Data: "+o.barname+": "
+  +o.bar+", Value: "+o.value}
+
+\parindent0pt
+\begin{document}
+
+The bar graphs here are based on count data. Input natural numbers
+into the text fields. If the width of a horizontal bar or the height
+of a vertical bar goes outside the graphing area, the bar graph is
+\emph{automatically re-scaled} so the widest one (for horizontal)
+or highest one (for vertical) now fits. Try the Optimize buttons as
+well.\medskip
+
+%% These bars have no \TU key, so current value of \barLabelsTU
+%% applies.
+\fbox{\begin{bargraphenv}
+  [width=.67\linewidth,height=2in,o=horiz]{vehiclesH}
+\presetsbarfor{hBar}{auto}{\BG{red}}
+\presetsbarfor{hBar}{truck}{\BG{green}}
+\presetsbarfor{hBar}{suv}{\BG{yellow}}
+\presetsbarfor{hBar}{van}{\BG{magenta}}
+\begin{bargraph}[nbars=4,gap=3]{hBar}
+\barfor{auto}
+\cmd{\vs{-2bp}{\small{Automobile (two or four door)}}\vs{3bp}}
+\barfor{truck}
+\cmd{\vs{-2bp}{\small{Pickup truck}}\vs{3bp}}
+\barfor{suv}
+\cmd{\vs{-2bp}{\small{Sport utility vehicle (SUV)}}\vs{3bp}}
+\barfor{van}
+\cmd{\vs{1bp}{\small{Passenger van}}}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {.33\linewidth-2\fboxsep-2\fboxrule-10pt}\kern0pt\parskip3pt
+\makebox[\widthof{Truck:}][l]{Auto:}
+  \inputFor{vehiclesH}{hBar}{auto}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Truck:}
+  \inputFor{vehiclesH}{hBar}{truck}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{SUV:}
+  \inputFor{vehiclesH}{hBar}{suv}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Van:}
+  \inputFor{vehiclesH}{hBar}{van}{.5in}{11bp}\vcgBdry[3bp]
+\pushButton[\TU{This button re-scales the bar graph so that the
+longest bar takes the entire width of the region.}\CA{Optimize}
+\AAmouseup{optimizeScaling("vehiclesH");}]{optimize1}{}{13bp}
+\end{minipage}\medskip
+
+Reset horizontal bar graph: \pushButton[\CA{Reset}
+  \AAmouseup{resetBargraphs("vehiclesH");}]{reset}{}{13bp}
+
+\bigskip
+
+\fbox{\begin{bargraphenv}[width=2in,height=2in,o=vert]{vehiclesV}
+\presetsbarfor{vBar}{auto}{\BG{red}
+  \TU{There were @v@ automobiles observed}}
+\presetsbarfor{vBar}{truck}{\BG{green}
+  \TU{There were @v@ pickups observed during time period}}
+\presetsbarfor{vBar}{suv}{\BG{yellow}
+  \TU{There were @v@ SUVs observed, costing big
+  \textdollar\textdollar s}}
+\presetsbarfor{vBar}{van}{\BG{magenta}
+  \TU{There were @v@ family vans filled with happy people;
+    reminds me of J\"{u}rgen's family}}
+\begin{bargraph}[nbars=4,gap=3]{vBar}
+\barfor{auto}
+\cmd{\hs{-2bp}\smash{\rotatebox[origin=lb]{90}
+  {\small{{Automobile (two or four door)}}}}\hs{3bp}}
+\barfor{truck}
+\cmd{\hs{-2bp}\smash{\rotatebox[origin=lb]{90}
+  {\small{Pickup truck}}}\hs{3bp}}
+\barfor{suv}
+\cmd{\hs{-2bp}\smash{\rotatebox[origin=lb]{90}
+  {\small{Sport utility vehicle (SUV)}}}\hs{3bp}}
+\barfor{van}
+\cmd{\hs{1bp}\smash{\rotatebox[origin=lb]{90}
+  {\small{Passenger van}}}}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {\linewidth-2\fboxsep-2\fboxrule-2in-10pt}\kern0pt\parskip3pt
+\makebox[\widthof{Truck:}][l]{Auto:}
+  \inputFor{vehiclesV}{vBar}{auto}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Truck:}
+  \inputFor{vehiclesV}{vBar}{truck}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{SUV:}
+  \inputFor{vehiclesV}{vBar}{suv}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Van:}
+  \inputFor{vehiclesV}{vBar}{van}{.5in}{11bp}\vcgBdry[4bp]
+\pushButton[\TU{This button re-scales the bar graph so that the
+tallest bar takes the entire height of the region.}\CA{Optimize}
+\AAmouseup{optimizeScaling("vehiclesV");}]{optimize2}{}{13bp}
+\end{minipage}\medskip
+
+Reset vertical bar graph:
+  \pushButton[\CA{Reset}
+    \AAmouseup{resetBargraphs("vehiclesV");}
+  ]{reset}{}{13bp}\vcgBdry[6bp]
+Reset all bar graphs:
+  \pushButton[\CA{Reset}
+    \AAmouseup{resetBargraphs("vehiclesH","vehiclesV");}]{reset}{}{13bp}
+
+\end{document}
+%</basic2>
+%<*basic3>
+%    \end{macrocode}
+%    \subsection{\texttt{bgjs-basic3.tex}}
+%    This example illustrates using form fields to label each bar; the captions appear or are hidden
+%    depending on whether there are any data.
+%    \begin{macrocode}
+\documentclass{article}
+ % \usepackage{web}
+\usepackage[usealtadobe]{eforms}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\usepackage{bargraph-js}
+ % \previewOn\pmpvOn
+\makePDasXOn
+
+\begin{insDLJS}{lbl}{Labeling function}
+%%   fld="<bgenv-name>@<bg-name>.<bar-name>"
+%%   v=value of field
+function customLabelsForBars(fld,v){
+var pos=fld.indexOf(".");
+var bargraph=fld.substring(0,pos);
+var bar=fld.substring(pos+1);
+  switch(bargraph) {
+    case "vehiclesH@hBar":
+      switch(bar) {
+        case "auto":
+          return "Automobiles: "+v;
+        case "truck":
+         return "Pickup trucks: "+v;
+        case "suv":
+          return "SUV types: "+v+", costing big \$\$s";
+        case "van":
+          return "Family vans: "+v
+            +", these cost some serious \u20AC\u20ACs";
+        default:
+          return simpleBarLabels(fld,v);
+      }
+// other cases can be included
+    default:
+      return simpleBarLabels(fld,v);
+  }
+}
+\end{insDLJS}
+  % applies to all bars with a \TU key
+  % \barLabelsTU{customBarLabels}
+  % applies to all other bars
+  % \barLabelsNoTU{customLabelsForBars}
+
+\parindent0pt
+\begin{document}
+
+In this example, we label the bar graph using text fields (using the
+\verb~\labelFld~ command defined in this package). The fields are
+initially hidden, then made visible when data is entered into the
+input fields.\par\medskip
+%    \end{macrocode}
+% The syntax for \cs{labelFld}\marginpar{\small\itshape\raggedleft\cs{labelFld}} is as follows:
+% \begin{flushleft}\ttfamily
+% \cs{labelFld}[\ameta{options}]\darg{\ameta{text}}\darg{\ameta{bg-name}.\ameta{bar-name}}{\ameta{width}}.\darg{\ameta{height}}
+% \end{flushleft}
+% Where, \ameta{text} is the labeling text this is to appear with this bar. See the examples below. When
+% the bars are vertical (\texttt{o=vert}) then amongst the \ameta{options} for the field is
+% key-value pair \cs{R\darg{90}}, again, see below for examples.
+%    \begin{macrocode}
+%% Here we use the default method of labeling the bar graphs
+%% This bar graph is horizontally oriented
+\fbox{\begin{bargraphenv}[width=.67\linewidth,height=2in,
+  o=horiz]{vehiclesH}\def\WD{2in}
+\presetsbarfor{hBar}{auto}{\BG{red}}
+\presetsbarfor{hBar}{truck}{\BG{green}}
+\presetsbarfor{hBar}{suv}{\BG{yellow}}
+\presetsbarfor{hBar}{van}{\BG{magenta}}
+\begin{bargraph}[nbars=4,gap=3]{hBar}
+\barfor{auto}
+\cmd{\vs{-3bp}\labelFld[\textSize{10}]
+  {Automobiles (two or four door)}{hBar.auto}{\WD}{13bp}\vs{3bp}}
+\barfor{truck}
+\cmd{\vs{-3bp}\labelFld[\textSize{10}]
+  {Pickup trucks}{hBar.truck}{\WD}{13bp}\vs{3bp}}
+\barfor{suv}
+\cmd{\vs{-3bp}\labelFld[\textSize{10}]
+  {Sport utility vehicle (SUV)}{hBar.suv}{\WD}{13bp}\vs{3bp}}
+\barfor{van}
+\cmd{\vs{0bp}\labelFld[\textSize{10}]
+  {Passenger van}{hBar.van}{\WD}{13bp}}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {.33\linewidth-2\fboxsep-2\fboxrule-10pt}\kern0pt\parskip3pt
+%    \end{macrocode}
+%    To get the field to appear and hide in synchronization
+%    with the data input by the \cs{inputFor} commands, we
+%    create a custom \cs{presetinputfor} command. We use
+%    a built-in JavaScript function \texttt{toggleFldVisibility}\marginpar{\small\itshape\raggedleft\texttt{toggleFldVisibility()}},
+%    the argument of which is the field name of the targeted bar:
+%    the full name is \texttt{\ameta{bg-name}.\ameta{bar-name}@\ameta{bgenv-name}}.
+%    \begin{macrocode}
+\def\presetinputfor#1#2{%
+%    \end{macrocode}
+%    The arguments for the \cs{presetinputfor} command are,
+%    \begin{description}
+%    \item[]\texttt{\#1=\ameta{bgenv-name}}
+%    \item[] \texttt{\#2=\ameta{bg-name}.\ameta{bar-name}}
+%    \end{description}
+%    \begin{macrocode}
+  \AAkeystroke{EFNumber_Keystroke(0, 0, 0, 0, "", true);}
+  \AAformat{try{EFNumber_Format(0, 0, 0, 0, "", true);\r
+  if(event.rc)toggleFldVisibility("#2@#1",%
+(event.value!=0));}catch(e){}}
+  \AAvalidate{EFRange_Validate(true, 0, false, 0);}
+}
+\makebox[\widthof{Truck:}][l]{Auto:}
+  \inputFor{vehiclesH}{hBar}{auto}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Truck:}
+  \inputFor{vehiclesH}{hBar}{truck}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{SUV:}
+  \inputFor{vehiclesH}{hBar}{suv}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Van:}
+  \inputFor{vehiclesH}{hBar}{van}{.5in}{11bp}\vcgBdry[3bp]
+\pushButton[\TU{This button re-scales the bar graph so that the
+  longest bar takes the entire width of the region.}\CA{Optimize}
+  \AAmouseup{optimizeScaling("vehiclesH");}]{optimize1}{}{13bp}
+\end{minipage}\medskip
+
+Reset horizontal bar graph: \pushButton[\CA{Reset}
+  \AAmouseup{resetBargraphs("hBar","vehiclesH");\r
+}]{reset}{}{13bp}
+
+\bigskip
+
+%% This bar graph is vertical so we must insert \R{90} in the
+%% options argument of \labelFld.
+\fbox{\begin{bargraphenv}[width=2in,height=2in,%
+  o=vert]{vehiclesV}\def\WD{2in}
+\presetsbarfor{vBar}{auto}{\BG{red}
+  \TU{There were @v@ automobiles observed}}
+\presetsbarfor{vBar}{truck}{\BG{green}
+  \TU{There were @v@ pickups observed during time period}}
+\presetsbarfor{vBar}{suv}{\BG{yellow}
+  \TU{There were @v@ SUVs observed, costing big
+    \textdollar\textdollar s}}
+\presetsbarfor{vBar}{van}{\BG{magenta}
+  \TU{There were @v@ family vans filled with happy people;
+    reminds me of J\"{u}rgen's family}}
+\begin{bargraph}[nbars=4,gap=3]{vBar}
+\barfor{auto}
+\cmd{\hs{-3bp}\labelFld[\R{90}\textSize{10}]
+  {Automobiles (two or four door)}{vBar.auto}{\WD}{13bp}\hs{3bp}}
+\barfor{truck}
+\cmd{\hs{-3bp}\labelFld[\R{90}\textSize{10}]
+  {Pickup trucks}{vBar.truck}{\WD}{13bp}\hs{3bp}}
+\barfor{suv}
+\cmd{\hs{-3bp}\labelFld[\R{90}\textSize{10}]
+  {Sport utility vehicle (SUV)}{vBar.suv}{\WD}{13bp}\hs{3bp}}
+\barfor{van}
+\cmd{\hs{0bp}\labelFld[\R{90}\textSize{10}]
+  {Passenger van}{vBar.van}{\WD}{13bp}}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {\linewidth-2\fboxsep-2\fboxrule-2in-10pt}\kern0pt\parskip3pt
+%    \end{macrocode}
+%    To get the field to appear and hide in synchronization
+%    with the data input by the \cs{inputFor} commands, we
+%    create a custom \cs{presetinputfor} command. We use
+%    a built-in JavaScript function \texttt{toggleFldVisibility}\marginpar{\small\itshape\raggedleft\texttt{toggleFldVisibility()}},
+%    the argument of which is the field name of the targeted bar:
+%    the full name is \texttt{\ameta{bg-name}.\ameta{bar-name}@\ameta{bgenv-name}}.
+%    \begin{macrocode}
+\def\presetinputfor#1#2{%
+%    \end{macrocode}
+%    The arguments for the \cs{presetinputfor} command are,
+%    \begin{description}
+%    \item[]\texttt{\#1=\ameta{bgenv-name}}
+%    \item[] \texttt{\#2=\ameta{bg-name}.\ameta{bar-name}}
+%    \end{description}
+%    \begin{macrocode}
+  \AAkeystroke{EFNumber_Keystroke(0, 0, 0, 0, "", true);}
+  \AAformat{try{EFNumber_Format(0, 0, 0, 0, "", true);\r
+  if(event.rc)toggleFldVisibility("#2@#1",%
+(event.value!=0));}catch(e){}}
+  \AAvalidate{EFRange_Validate(true, 0, false, 0);}
+}
+\makebox[\widthof{Truck:}][l]{Auto:}
+  \inputFor{vehiclesV}{vBar}{auto}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Truck:}
+  \inputFor{vehiclesV}{vBar}{truck}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{SUV:}
+  \inputFor{vehiclesV}{vBar}{suv}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Van:}
+  \inputFor{vehiclesV}{vBar}{van}{.5in}{11bp}\vcgBdry[4bp]
+\pushButton[\TU{This button re-scales the bar graph so that the
+  tallest bar takes the entire height of the region.}\CA{Optimize}
+  \AAmouseup{optimizeScaling("vehiclesV");}
+]{optimize2}{}{13bp}
+\end{minipage}\medskip
+
+Reset vertical bar graph:
+  \pushButton[\CA{Reset}
+    \AAmouseup{resetBargraphs("vBar","vehiclesV");}
+]{reset}{}{13bp}\vcgBdry[6bp]
+Reset all bar graphs:
+  \pushButton[\CA{Reset}
+    \AAmouseup{resetBargraphs("hBar","vBar","vehiclesH","vehiclesV");}
+]{reset}{}{13bp}
+\end{document}
+%</basic3>
+%<*basic4>
+%    \end{macrocode}
+%    \subsection{\texttt{bgjs-basic4.tex}}
+%    This example highlights the options \texttt{origin=.5} and \texttt{showaxis=true}. Try changing
+%    \texttt{o=vert} to \texttt{o=horiz}.
+%    \begin{macrocode}
+\documentclass{article}
+ % \usepackage{web}
+\usepackage{bargraph-js}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+ % \previewOn\pmpvOn
+\makePDasXOn
+%    \end{macrocode}
+%    Here we develop a custom JavaScript string to label each bar
+%    when the user runs the mouse over a bar in the bar graph.
+%    \begin{macrocode}
+\barLabelsNoTU{"Profits ("+o.barname.substring(1) +") for "
+    + o.bar +": "+((o.value<0)?"-\$":"\$")+Math.abs(o.value)
+    + " (million)"}
+
+\parindent0pt
+\begin{document}
+
+\textbf{Instructions:} Enter the profits for the year 2018, enter
+a negative number if there was a loss for a particular quarter.\medskip
+
+%% origin=.5,showaxis=true : change o=vert to o=horiz
+\fbox{\begin{bargraphenv}[width=2in,height=2in,o=vert,%
+  origin=.5,showaxis=true]{profits}
+\presetsbarfor{y2018}{Q1}{\BG{red}}
+\presetsbarfor{y2018}{Q2}{\BG{green}}
+\presetsbarfor{y2018}{Q3}{\BG{yellow}}
+\presetsbarfor{y2018}{Q4}{\BG{magenta}}
+\begin{bargraph}[nbars=4,gap=3]{y2018}
+\barfor{Q1}\barfor{Q2}\barfor{Q3}\barfor{Q4}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {\linewidth-2\fboxsep-2\fboxrule-2in-10pt}\kern0pt\parskip3pt
+\def\presetinputfor#1#2{%
+  \AAkeystroke{AFNumber_Keystroke(0, 0, 0, 0, "", true);}
+  \AAformat{AFNumber_Format(0, 0, 0, 0, "", true);}
+}
+\makebox[\linewidth][l]{\textbf
+  {Profits for year 2018 (in millions)}}\\[3pt]
+\makebox[\widthof{Q1:}][l]{Q1:}
+  \inputFor{profits}{y2018}{Q1}{.5in}{13bp}\vcgBdry[3bp]
+\makebox[\widthof{Q1:}][l]{Q2:}
+  \inputFor{profits}{y2018}{Q2}{.5in}{13bp}\vcgBdry[3bp]
+\makebox[\widthof{Q1:}][l]{Q3:}
+  \inputFor{profits}{y2018}{Q3}{.5in}{13bp}\vcgBdry[3bp]
+\makebox[\widthof{Q1:}][l]{Q4:}
+  \inputFor{profits}{y2018}{Q4}{.5in}{13bp}\vcgBdry[4bp]
+\pushButton[\TU{This button re-scales the bar graph so that the
+tallest bar takes the entire height of the region.}\CA{Optimize}
+  \AAmouseup{optimizeScaling("profits");}
+]{optimize2}{}{13bp}
+%    \end{macrocode}
+%    Supply manual re-scaling text field and push button
+%    \begin{macrocode}
+\displaysfFor{profits}{.5in}{13bp}\olBdry
+\manualsfFor[\CA{Rescale}\TU{Enter a new scale factor in the
+  text field, then press this button}
+]{profits}{}{13bp}
+\end{minipage}\medskip
+
+Reset vertical bar graph:
+  \pushButton[\CA{Reset}\AAmouseup{resetBargraphs("profits");}
+]{reset}{}{13bp}
+\end{document}
+%</basic4>
+%<*adv1>
+%    \end{macrocode}
+%    \subsection{\texttt{bgjs-adv1.tex}}
+%    We make an auxiliary calculations when data are entered into the
+%    \cs{inputFor} command.\medskip
+%    \begin{macrocode}
+\documentclass{article}
+ % \usepackage{web}
+\usepackage[usealtadobe,setcorder]{eforms}
+\usepackage{bargraph-js}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+ % \previewOn\pmpvOn
+\makePDasXOn
+
+%    \end{macrocode}
+%     In this example, we calculate the percentage of the class that receives
+%     each grade. When data is entered, it is important to calculate the field
+%     \texttt{titalClass} first, this will force all calculate that depend on this
+%     field to be calculated. As a result, |\calcOrder{totalClass}| set the calculateion
+%     order. \cs{calcOrder} is an \pkg{eforms} command.
+%    \begin{macrocode}
+\calcOrder{totalClass}
+
+\begin{insDLJS}{lbl}{Labeling function}
+%%   fld="<bgenv-name>@<bg-name>.<bar-name>"
+%%   v=value of field
+function customLabelsForBars(fld,v){
+var pos=fld.indexOf(".");
+var bargraph=fld.substring(0,pos);
+var bar=fld.substring(pos+1);
+  switch(bargraph) {
+    case "math@class":
+      var f=this.getField("totalClass");
+      var tot=f.value;
+      var V=(tot!=0)?((v/tot)*100):(v*100);
+      V=util.printf("\%.1f",V);
+      switch(bar) {
+        case "A":
+          return V+"\% of the class received an 'A'";
+        case "B":
+          return V+"\% of the class received an 'B'";
+        case "C":
+          return V+"\% of the class received an 'C'";
+        case "D":
+          return V+"\% of the class received an 'D'";
+        case "F":
+          return V+"\% of the class received an 'F'";
+        default:
+          return "unknown result";
+      }
+    default:
+      return simpleBarLabels(fld,v);
+  }
+}
+\end{insDLJS}
+
+%% applies to all bars without a \TU key
+\barLabelsNoTU{customLabelsForBars}
+
+\parindent0pt
+\begin{document}
+
+Enter the number of class members that received the grades
+A, B, C, D, and~F.\medskip
+
+%    \end{macrocode}
+%    We define \cs{presetinputforcalc}, which is the calculate code
+%    for the \cs{inputFor} commands. Here, \texttt{p(1)}
+%    is \texttt{\ameta{bgenv-name}} and \texttt{p(2)} is
+%    \texttt{\ameta{bg-name}.\ameta{bar-name}}. We use these
+%    to form the name of the \texttt{pctFor} fields.
+%    \begin{macrocode}
+\begin{defineJS}[\catcode`\*=0\relax]{\presetinputforcalc}
+var f=this.getField("pctFor.*p(2)@*p(1)");
+var g=this.getField("totalClass");
+if (event.value!=0)
+  f.value=( g.value==0 )?1:(event.value/g.value);
+\end{defineJS}
+
+\def\pctThisGrade#1#2#3{\textField[\Ff{\FfReadOnly}\Q{2}
+  \AAkeystroke{EFPercent_Keystroke(1, 1);}
+  \AAformat{if (event.value!=0)EFPercent_Format(1, 1);\r
+  else event.value="";}
+%    \end{macrocode}
+%    The name of this field shall be
+% \begin{flushleft}\ttfamily
+% pctFor.\ameta{bg-name}.\ameta{bar-name}@\ameta{bgenv-name}
+% \end{flushleft}
+%    \begin{macrocode}
+]{pctFor.#2.#3@#1}{.6in}{11bp}\cgBdry[.5em]}
+%    \end{macrocode}
+% \cs{scaleFactorDef} is used to reset initial scale factor the
+% next environment. Here we set it to be the height of the
+% environment (in bp points) divided by~100, that way, data are
+% re-scaled as a proportion of the height of the bar graph. We
+% make this declaration inside the \cs{fbox} to make the definition
+% local.
+%    \begin{macrocode}
+\fbox{\scaleFactorDef{dataForEnv["math"].height/100}%
+\begin{bargraphenv}[width=2in,height=2in,o=vert]{math}
+\begin{bargraph}[nbars=5,gap=3]{class}
+\barfor{A}\barfor{B}\barfor{C}\barfor{D}\barfor{F}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {\linewidth-2\fboxsep-2\fboxrule-2in-10pt}\kern0pt\parskip3pt
+\def\presetinputfor#1#2{\AAcalculate{\presetinputforcalc}
+  \AAkeystroke{AFNumber_Keystroke(0, 0, 0, 0, "", true);}
+  \AAformat{AFNumber_Format(0, 0, 0, 0, "", true);}
+  \AAvalidate{AFRange_Validate(true, 0, false, 0);}
+}%
+\makebox[\widthof{A:}][l]{A:} \inputFor{math}{class}{A}{.5in}{11bp}
+  \pctThisGrade{math}{class}{A}\vcgBdry[3bp]
+\makebox[\widthof{A:}][l]{B:} \inputFor{math}{class}{B}{.5in}{11bp}
+  \pctThisGrade{math}{class}{B}\vcgBdry[3bp]
+\makebox[\widthof{A:}][l]{C:} \inputFor{math}{class}{C}{.5in}{11bp}
+  \pctThisGrade{math}{class}{C}\vcgBdry[3bp]
+\makebox[\widthof{A:}][l]{D:} \inputFor{math}{class}{D}{.5in}{11bp}
+  \pctThisGrade{math}{class}{D}\vcgBdry[3bp]
+\makebox[\widthof{A:}][l]{F:} \inputFor{math}{class}{F}{.5in}{11bp}
+  \pctThisGrade{math}{class}{F}\vcgBdry[3bp]
+\makebox[\widthof{A:}][l]{\phantom{A:}}
+\textField[\Ff{\FfReadOnly}
+  \AAcalculate{AFSimple_Calculate("SUM",new Array("math"));}
+]{totalClass}{.5in}{13bp}\vcgBdry[4bp]
+\pushButton[\TU{This button re-scales the bar graph so that the
+  tallest bar takes the entire height of the region.}
+  \CA{Optimize}\AAmouseup{optimizeScaling("math");}
+]{optimize3}{}{13bp}
+\end{minipage}\medskip
+
+Reset vertical bar graph:
+\pushButton[\CA{Reset}
+  \AAmouseup{resetBargraphs("math","pctFor","totalClass");}
+]{reset}{}{13bp}
+\end{document}
+%</adv1>
+%<*comma1>
+%    \end{macrocode}
+%    \subsection{\texttt{bgjs-comma1.tex}}
+%    This file illustrates populating a bar graph using comma-delimited data.
+%    \begin{macrocode}
+\documentclass{article}
+ % \usepackage{web}
+\usepackage{eforms}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\usepackage{bargraph-js}
+ % \previewOn\pmpvOn
+\makePDasXOn
+
+\parindent0pt
+\begin{document}
+
+This file demonstrates comma-delimited data, manually enter the data
+in the text field or by press on one of the buttons to give
+pre-packaged examples.\medskip
+
+\bgroup\setlength{\fboxrule}{1bp}\fbox
+{\begin{bargraphenv}[width=(14bp*20),height=2in,%
+  o=vert]{statdemo}%
+\begin{bargraph}[nbars=20,gap=0,bardimen=14]{histogram}
+\barfor{bar1}\barfor{bar2}\barfor{bar3}\barfor{bar4}\barfor{bar5}
+\barfor{bar6}\barfor{bar7}\barfor{bar8}\barfor{bar9}\barfor{bar10}
+\barfor{bar11}\barfor{bar12}\barfor{bar13}\barfor{bar14}
+\barfor{bar15}\barfor{bar16}\barfor{bar17}\barfor{bar18}
+\barfor{bar19}\barfor{bar20}
+\end{bargraph}%
+\end{bargraphenv}}\egroup\vcgBdry[6pt]
+
+\hglue1bp\textField[\TU{Enter up to twenty nonnegative numbers
+  separated by commas}
+  \AAvalidate{resetBargraphs("statdemo");\r
+  \populateCommaData("statdemo","histogram",event.value,%
+%    \end{macrocode}
+%    Require each entry in the array to be non-negative numbers.
+%    \begin{macrocode}
+    validateArrayNonNegNums)}
+  ]{commaed}{(\bardimen*\nbars+2\fboxsep+2bp)}{13bp}\vcgBdry[6pt]
+
+\hglue1bp\pushButton[\CA{Symmetrical}\AAmouseup{%
+var str="1,2,3,4,5,6,7,8,9,10,10,9,8,7,6,5,4,3,2,1";\r
+%    \end{macrocode}
+%    Here, we don't include \texttt{validateArrayNonNegNums()} because it is assumed
+%    the document author knows what he/she is doing.
+%    \begin{macrocode}
+\populateCommaData("statdemo","histogram",str);
+}]{symmetrical}{}{13bp}\cgBdry[.5em]
+\pushButton[\CA{Skew left}\AAmouseup{%
+var str="1,2,2,3,3,4,5,6,8,10,12,14,16,19,20,19,17,15,13,11";\r
+\populateCommaData("statdemo","histogram",str);}
+]{skewleft}{}{13bp}\cgBdry[.5em]
+\pushButton[\CA{Skew right}\AAmouseup{%
+var str="17,18,19,20,19,18,16,14,12,10,8,7,7,6,6,4,4,3,2,1";\r
+\populateCommaData("statdemo","histogram",str);}
+]{skewright}{}{13bp}\vcgBdry[6pt]
+
+\hglue1bp\pushButton[\TU{This button re-scales the bar graph so
+  that the longest bar takes the entire width of the region.}
+  \CA{Optimize}\AAmouseup{optimizeScaling("statdemo");}
+]{optimize1}{}{13bp}\cgBdry[.5em]
+\displaysfFor{statdemo}{.5in}{13bp}\olBdry
+\manualsfFor[\CA{Rescale}\TU{Enter a new scale factor in the
+  text field, then press this button}]{statdemo}{}{13bp}\vcgBdry[6bp]
+
+\hglue1bp\pushButton[\CA{Reset}
+  \AAmouseup{resetBargraphs("statdemo","commaed","rescale.statdemo")}
+]{reset}{}{13bp}\vcgBdry[6pt]
+\end{document}
+%</comma1>
+%<*comma2>
+%    \end{macrocode}
+%    \subsection{\texttt{bgjs-comma2.tex}}
+%    This file demonstrates multiple \env{bargraph} environments placed within a single
+%    \env{bargraphenv} environment. Comma-delimited data can populates the bar graphs.
+%    \begin{macrocode}
+\documentclass{article}
+ % \usepackage{web}
+\usepackage{eforms}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\usepackage{bargraph-js}
+ % \previewOn\pmpvOn
+\makePDasXOn
+
+\parindent0pt
+\begin{document}
+
+This file demonstrates comma-delimited data, manually enter the
+data in the text field or by press on one of the buttons to give
+pre-packaged examples. More than one \texttt{bargraph} environment
+can appear within a \texttt{bargraphenv}, as illustrated in the next
+two examples.\medskip
+
+\fbox{\begin{bargraphenv}[width=23bp*10,height=1.4in,o=vert]{math1}
+\presetsbarfor{class1}{A}{\BG{red}
+  \TU{Class1: @v@ students received an 'A'}}
+\presetsbarfor{class1}{B}{\BG{red}
+  \TU{Class1: @v@ students received an 'B'}}
+\presetsbarfor{class1}{C}{\BG{red}
+  \TU{Class1: @v@ students received an 'C'}}
+\presetsbarfor{class1}{D}{\BG{red}
+  \TU{Class1: @v@ students received an 'D'}}
+\presetsbarfor{class1}{F}{\BG{red}
+  \TU{Class1: @v@ students received an 'F'}}
+\presetsbarfor{class2}{A}{\BG{blue}
+  \TU{Class2: @v@ students received an 'A'}}
+\presetsbarfor{class2}{B}{\BG{blue}
+  \TU{Class2: @v@ students received an 'B'}}
+\presetsbarfor{class2}{C}{\BG{blue}
+  \TU{Class2: @v@ students received an 'C'}}
+\presetsbarfor{class2}{D}{\BG{blue}
+  \TU{Class2: @v@ students received an 'D'}}
+\presetsbarfor{class2}{F}{\BG{blue}
+  \TU{Class2: @v@ students received an 'F'}}
+\begin{bargraph}[nbars=5,gap=3]{class1}
+\barfor{A}\barfor{B}\barfor{C}\barfor{D}\barfor{F}
+\end{bargraph}
+\begin{bargraph}[nbars=5,gap=3]{class2}\cmd{\hs{\bargap}}
+\barfor{A}\barfor{B}\barfor{C}\barfor{D}\barfor{F}
+\end{bargraph}
+\end{bargraphenv}}\vcgBdry[6pt]
+
+\begin{minipage}[c]{222pt}
+class1:
+  \textField[\TU{Enter five natural numbers separated
+    by commas}
+    \AAvalidate{\populateCommaData("math1","class1",event.value,%
+      validateArrayNonNegNums)}
+  ]{txtclass3}{2in}{13bp}\cgBdry[.5em]
+  \pushButton[\CA{Class 1}\AAmouseup{%
+    var str="12,15,23,10,15";\r
+    this.getField("txtclass3").value=str;\r
+    \populateCommaData("math1","class1",str);
+}]{math1class1}{}{13bp}\vcgBdry[4bp]
+class2:
+  \textField[\TU{Enter five natural numbers separated by commas}
+    \AAvalidate{\populateCommaData("math1","class2",event.value,%
+      validateArrayNonNegNums)}
+  ]{txtclass4}{2in}{13bp}\cgBdry[.5em]
+  \pushButton[\CA{Class 2}\AAmouseup{%
+    var str="10,17,29,10,20";\r
+    this.getField("txtclass4").value=str;\r
+    \populateCommaData("math1","class2",str);
+  }]{math1class1}{}{13bp}
+\end{minipage}\cgBdry[.5em]
+\pushButton[\TU{This button re-scales the bar graph so that the
+  tallest bar takes the entire height of the region.}\CA{Optimize}
+  \AAmouseup{optimizeScaling("math1");}
+]{optimize3}{}{13bp}\cgBdry[.5em]
+\pushButton[\CA{Reset}
+  \AAmouseup{resetBargraphs("math1","txtclass3","txtclass4");}
+]{reset}{}{13bp}\vcgBdry[6pt]
+
+
+You can adjust the positions of the bar graph to have a more
+side-by-side comparison.\vcgBdry[4bp]
+
+\fbox{\begin{bargraphenv}[width=33bp*5,height=2in,%
+  o=vert]{math2}
+\presetsbarfor{class1}{A}{\BG{red}}
+\presetsbarfor{class1}{B}{\BG{red}}
+\presetsbarfor{class1}{C}{\BG{red}}
+\presetsbarfor{class1}{D}{\BG{red}}
+\presetsbarfor{class1}{F}{\BG{red}}
+\presetsbarfor{class2}{A}{\BG{blue}}
+\presetsbarfor{class2}{B}{\BG{blue}}
+\presetsbarfor{class2}{C}{\BG{blue}}
+\presetsbarfor{class2}{D}{\BG{blue}}
+\presetsbarfor{class2}{F}{\BG{blue}}
+\begin{bargraph}[nbars=5,gap=13]{class1}
+\barfor{A}\barfor{B}\barfor{C}\barfor{D}\barfor{F}
+\end{bargraph}%
+\begin{bargraph}[nbars=5,gap=13]{class2}\cmd{\hs{13bp}}
+\cmd{\color{red}\hs{-33bp*5+10bp}}
+\barfor{A}\barfor{B}\barfor{C}\barfor{D}\barfor{F}
+\end{bargraph}
+\end{bargraphenv}}\vcgBdry[6pt]
+
+\begin{defineJS}{\pbaction}
+var f=this.getField("txtclass5");
+for (var value="",i=0; i<5; i++)
+  value+=(""+(Math.round(Math.random()*200))+",");
+f.value=value.substring(0,value.length-1);
+for (var value="",i=0; i<5; i++)
+  value+=(""+(Math.round(Math.random()*200))+",");
+var g=this.getField("txtclass6");
+g.value=value.substring(0,value.length-1);
+\end{defineJS}
+
+\begin{minipage}[c]{222pt}
+class1:
+  \textField[\TU{Enter five natural numbers separated by commas}
+  \AAvalidate{\populateCommaData("math2","class1",event.value,%
+    validateArrayNonNegNums)}
+  ]{txtclass5}{2in}{13bp}\cgBdry[.5em]
+  \pushButton[\CA{Class 1}\AAmouseup{%
+    var str="12,15,23,10,15";\r
+    this.getField("txtclass5").value=str;\r
+    \populateCommaData("math2","class1",str);
+  }]{math1class1}{}{13bp}\vcgBdry[4bp]
+class2:
+  \textField[\TU{Enter five natural numbers separated by commas}
+  \AAvalidate{\populateCommaData("math2","class2",event.value,%
+    validateArrayNonNegNums)}
+  ]{txtclass6}{2in}{13bp}\cgBdry[.5em]
+  \pushButton[\CA{Class 2}\AAmouseup{%
+    var str="10,17,29,10,20";\r
+    this.getField("txtclass6").value=str;\r
+    \populateCommaData("math2","class2",v);
+  }]{math1class1}{}{13bp}
+\end{minipage}\cgBdry[.5em]
+\pushButton[\CA{Test}\TU{Press to automatically enter data into the
+  two fields above}\AAmouseup{\pbaction}]{tstdata}{}{13bp}\cgBdry[.5em]
+\pushButton[\TU{This button re-scales the bar graph so that the
+  tallest bar takes the entire height of the region.}\CA{Optimize}
+  \AAmouseup{optimizeScaling("math2");}]{optimize3}{}{13bp}\cgBdry[.5em]
+\pushButton[\CA{Reset}
+  \AAmouseup{resetBargraphs("math2","txtclass5","txtclass6");}
+]{reset}{}{13bp}
+\end{document}
+%</comma2>
+%<*pro1>
+%    \end{macrocode}
+%    \subsection{\texttt{bgjs-pro1.tex}}
+%    This file is similar to \texttt{bgjs-basic3.tex} but uses layers instead of
+%    PDF forms to insert and control the explicit labeling. It requires \pkg{aeb\_pro} and
+%    a \app{dvips}/\allowbreak\app{Adobe Distiller} workflow.
+%    \begin{macrocode}
+\documentclass{article}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Requires a dvips/Distiller workflow %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage[web,eforms={usealtadobe},uselayers]{aeb_pro}
+ % \hypersetup{pdfpagemode=UseNone} % web executes this
+\usepackage{bargraph-js}
+\usepackage{graphicx}
+
+ % \previewOn\pmpvOn
+\makePDasXOn
+
+\begin{insDLJS}{lbl}{Labeling function}
+%%   fld="<bgenv-name>@<bg-name>.<bar-name>"
+%%   v=value of field
+function customLabelsForBars(fld,v){
+var pos=fld.indexOf(".");
+var bargraph=fld.substring(0,pos);
+var bar=fld.substring(pos+1);
+  switch(bargraph) {
+    case "vehiclesH@hBar":
+      switch(bar) {
+        case "auto":
+          return "Automobiles: "+v;
+        case "truck":
+         return "Pickup trucks: "+v;
+        case "suv":
+          return "SUV types: "+v+", costing big \$\$s";
+        case "van":
+          return "Family vans: "+v
+            +", these cost some serious \u20AC\u20ACs";
+        default:
+          return simpleBarLabels(fld,v);
+      }
+// other cases can be included
+    default:
+      return simpleBarLabels(fld,v);
+  }
+}
+\end{insDLJS}
+%% applies to all bars with a \TU key
+%% \barLabelsTU{customBarLabels}
+%% applies to all other bars
+\barLabelsNoTU{customLabelsForBars}
+
+\parindent0pt
+\begin{document}
+
+In this example, we label the bar graph using typeset content which
+is placed in layers (OCGs). The layers are initially hidden, then
+made visible when data is entered into the input fields.
+\medskip
+
+%% These bars have not \TU key, so the are handled by the argument
+%% of \barLabalsNoTU{customLabelsForBars}.
+\fbox{\begin{bargraphenv}[width=.67\linewidth,height=2in,
+  o=horiz]{vehiclesH}
+\presetsbarfor{hBar}{auto}{\BG{red}}
+\presetsbarfor{hBar}{truck}{\BG{green}}
+\presetsbarfor{hBar}{suv}{\BG{yellow}}
+\presetsbarfor{hBar}{van}{\BG{magenta}}
+\begin{bargraph}[nbars=4,gap=3]{hBar}
+\barfor{auto}\cmd{\vs{-3bp}\xBld{hBar.auto}
+  {\small Automobiles (two or four door)}\eBld\vs{3bp}}
+\barfor{truck}\cmd{\vs{-3bp}\xBld{hBar.truck}
+  {\small Pickup trucks}\eBld\vs{3bp}}
+\barfor{suv}\cmd{\vs{-3bp}\xBld{hBar.suv}
+  {\small Sport utility vehicle (SUV)}\eBld\vs{3bp}}
+\barfor{van}\cmd{\vs{0bp}\xBld{hBar.van}
+  {\small Passenger van}\eBld}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {.33\linewidth-2\fboxsep-2\fboxrule-10pt}\kern0pt\parskip3pt
+\def\presetinputfor#1#2{%
+  \AAkeystroke{EFNumber_Keystroke(0, 0, 0, 0, "", true);}
+  \AAformat{try{EFNumber_Format(0, 0, 0, 0, "", true);\r
+  if(event.rc)toggleSetThisLayer("#2",(event.value!=0));}catch(e){}}
+  \AAvalidate{EFRange_Validate(true, 0, false, 0);}
+}
+\makebox[\widthof{Truck:}][l]{Auto:}
+  \inputFor{vehiclesH}{hBar}{auto}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Truck:}
+  \inputFor{vehiclesH}{hBar}{truck}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{SUV:}
+  \inputFor{vehiclesH}{hBar}{suv}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Van:}
+  \inputFor{vehiclesH}{hBar}{van}{.5in}{11bp}\vcgBdry[3bp]
+\pushButton[\TU{This button re-scales the bar graph so that the
+  longest bar takes the entire width of the region.}\CA{Optimize}
+  \AAmouseup{optimizeScaling("vehiclesH");}]{optimize1}{}{13bp}
+\end{minipage}\medskip
+
+Reset horizontal bar graph: \pushButton[\CA{Reset}
+  \AAmouseup{resetBargraphs("hBar","vehiclesH");}
+]{reset}{}{13bp}
+
+\bigskip
+
+%% These bars have a \TU key
+\fbox{\begin{bargraphenv}[width=2in,height=2in,%
+  o=vert]{vehiclesV}\def\WD{2in}
+\presetsbarfor{vBar}{auto}{\BG{red}
+  \TU{There were @v@ automobiles observed}}
+\presetsbarfor{vBar}{truck}{\BG{green}
+  \TU{There were @v@ pickups observed during time period}}
+\presetsbarfor{vBar}{suv}{\BG{yellow}
+  \TU{There were @v@ SUVs observed, costing big
+    \textdollar\textdollar s}}
+\presetsbarfor{vBar}{van}{\BG{magenta}
+  \TU{There were @v@ family vans filled with happy people;
+    reminds me of J\"{u}rgen's family}}
+\begin{bargraph}[nbars=4,gap=3]{vBar}
+\barfor{auto}
+\cmd{\hs{-3bp}\xBld{vBar.auto}\smash{\raisebox{1pt}
+  {\rotatebox[origin=lb]{90}
+  {\small Automobiles (two or four door)}}}\eBld\hs{3bp}}
+\barfor{truck}
+\cmd{\hs{-3bp}\xBld{vBar.truck}\smash{\raisebox{1pt}
+  {\rotatebox[origin=lb]{90}{\small Pickup trucks}}}\eBld\hs{3bp}}
+\barfor{suv}
+\cmd{\hs{-3bp}\xBld{vBar.suv}\smash{\raisebox{1pt}
+  {\rotatebox[origin=lb]{90}
+  {\small Sport utility vehicle (SUV)}}}\eBld\hs{3bp}}
+\barfor{van}
+\cmd{\hs{0bp}\xBld{vBar.van}\smash{\raisebox{1pt}
+  {\rotatebox[origin=lb]{90}{\small Passenger van}}}\eBld}
+\end{bargraph}
+\end{bargraphenv}}\hfill
+\begin{minipage}[b][2in][c]
+  {\linewidth-2\fboxsep-2\fboxrule-2in-10pt}\kern0pt\parskip3pt
+\def\presetinputfor#1#2{%
+%    \end{macrocode}
+%    The arguments for the \cs{presetinputfor} command are,
+%    \begin{description}
+%    \item[]\texttt{\#1=\ameta{bgenv-name}}
+%    \item[] \texttt{\#2=\ameta{bg-name}.\ameta{bar-name}}
+%    \end{description}
+%    \begin{macrocode}
+  \AAkeystroke{EFNumber_Keystroke(0, 0, 0, 0, "", true);}
+  \AAformat{try{EFNumber_Format(0, 0, 0, 0, "", true);\r
+%    \end{macrocode}
+%    I've deliberately named the layers to be \texttt{\ameta{bg-name}.\ameta{bar-name}},
+%    which is exactly the \texttt{\#2} argument of \cs{presetinputfor}. The
+%    \texttt{toggleSetThisLayer} is a JavaScript function built into the \pkg{aeb\_pro}
+%    package.
+%    \begin{macrocode}
+  if(event.rc)toggleSetThisLayer("#2",(event.value!=0));}catch(e){}}
+  \AAvalidate{EFRange_Validate(true, 0, false, 0);}
+}
+\makebox[\widthof{Truck:}][l]{Auto:}
+  \inputFor{vehiclesV}{vBar}{auto}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Truck:}
+  \inputFor{vehiclesV}{vBar}{truck}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{SUV:}
+  \inputFor{vehiclesV}{vBar}{suv}{.5in}{11bp}\vcgBdry[3bp]
+\makebox[\widthof{Truck:}][l]{Van:}
+  \inputFor{vehiclesV}{vBar}{van}{.5in}{11bp}\vcgBdry[4bp]
+\pushButton[\TU{This button re-scales the bar graph so that the
+tallest bar takes the entire height of the region.}\CA{Optimize}
+  \AAmouseup{optimizeScaling("vehiclesV");}
+]{optimize2}{}{13bp}
+\end{minipage}\medskip
+
+Reset vertical bar graph:
+  \pushButton[\CA{Reset}
+    \AAmouseup{resetBargraphs("vBar","vehiclesV");}
+]{reset}{}{13bp}\vcgBdry[6bp]
+Reset all bar graphs:
+  \pushButton[\CA{Reset}
+    \AAmouseup{resetBargraphs("hBar","vBar","vehiclesH","vehiclesV");}
+]{reset}{}{13bp}
+
+\end{document}
+%</pro1>
+%<*dyn1>
+%    \end{macrocode}
+%    \subsection{\texttt{bgjs-dyn1.tex}}
+%    This file gives some ideas how to create discrete probability distributions
+%    for discrete random variables that take on evenly spaced values. We present
+%    a table of values (both pmf and cdf) and the corresponding pmf and cdf bargraphs.
+%    \begin{macrocode}
+\documentclass{article}
+ % \usepackage{web}
+\usepackage[usealtadobe]{eforms}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\usepackage[dynamic]{bargraph-js}
+ % \previewOn\pmpvOn
+\makePDasXOn
+
+%    \end{macrocode}
+%    \leavevmode\DescribeMacro\displayTable
+%    creates a text field that will contain the tabled values of the
+%    discrete distribution. In this demo, we place the table in the left margin.
+%    \begin{macrocode}
+\def\displayTable{\textField[\autoCenter{n}\BC{}\BG{}
+  \Ff{\FfMultiline}]{displayTable}{\oddsidemargin}{6in}}
+%    \end{macrocode}
+%    Adjust the left margin and \cs{textwidth}
+%    \begin{macrocode}
+\def\addWdth{.6in}
+\addtolength{\oddsidemargin}{\addWdth}
+\addtolength{\marginparwidth}{0pt}
+\setlength{\textwidth}{\paperwidth-2in-\oddsidemargin}
+%    \end{macrocode}
+%    \leavevmode\IndexJS{displayTable} displays the entries in the
+%    \texttt{aDistr} array and places the string in the field
+%    named \texttt{fld}.
+%    \begin{macrocode}
+\begin{insDLJS}{dtable}{Display Table of Probabilities}
+function displayTable(fld,aDistr) {
+  var tableHead=util.printf("   \%s","k ")
+    +util.printf("     \%s     ","pmf")
+    +util.printf("     \%s     ","cdf")+"\r";
+  var str=tableHead;
+  for (var i=0; i<aDistr.length;i++) {
+    str +=(util.printf("\%4d",aDistr[i][0])
+      + util.printf("\%10.6f",aDistr[i][1])
+      + util.printf("\%10.6f",aDistr[i][2])
+      + "\r"
+    );
+  }
+  var f=this.getField(fld);
+  if (f!=null) f.value=str;
+}
+%    \end{macrocode}
+%    This function is not necessary, but simply demonstrates the feature of writing
+%    your own custom labeling function for dynamic bars. This example is modeled after
+%    the default function \texttt{\_labelDyBars}. The argument of this function are
+%    \texttt{pr} (the current value of the random variable); \texttt{v} (the probability
+%    associated with \texttt{pr}; and \texttt{bPmf} is \texttt{true} when this is for a \textsf{pmf}
+%    and \texttt{false} when this is for a \textsf{cdf}.
+%    \begin{macrocode}
+function customDyLabels(pr,v,bPmf) {
+  return bPmf?("P(Y="+pr+")="+v):("P(Y<="+pr+")="+v);
+}
+\end{insDLJS}
+
+\parindent0pt
+\begin{document}
+\begin{center}\bfseries
+   The bar graph for the probability mass function (pmf)
+\end{center}
+\noindent\makebox[0pt][r]{\smash
+  {\raisebox{-4in+2\fboxsep+2\fboxrule}{\displayTable}%
+    \hspace{\marginparsep}}}
+\fbox{\begin{bargraphenv}[width=\linewidth-2\fboxsep-2\fboxrule,%
+  height=2in,o=vert]{Pmf}
+\begin{bargraph}{pmfBar}\isdynamic\end{bargraph}
+\end{bargraphenv}}\vcgBdry[\medskipamount]
+\pushButton[\TU{This button re-scales the bar graph so that the
+  tallest bar takes the entire height of the region; shift-click
+  reverts bar graph to its original scaling.}\CA{Optimize}\AAmouseup{%
+  try{displayDyBargraph("Pmf",aPmfCdf,true,!event.shift)}
+    catch(e){};}
+]{optimize}{}{13bp}\cgBdry[1em]
+Under normal scaling, the height of this region is 1 unit, when the
+bar graph is optimized, the height is the height of the tallest bar.
+
+\medskip
+\begin{center}\bfseries
+   The bar graph for the cumulative distribution function (cdf)
+\end{center}
+\fbox{\begin{bargraphenv}[width=\linewidth-2\fboxsep-2\fboxrule,%
+  height=2in,o=vert]{Cdf}
+\begin{bargraph}{cdfBar}\isdynamic\end{bargraph}
+\end{bargraphenv}}\vcgBdry[\medskipamount]
+The height of the region above is 1~unit.
+
+\begin{flushleft}
+\textbf{Generate some probability distributions}\medskip
+
+\pushButton[\CA{Dist1}\AAmouseup{%
+%    \end{macrocode}
+%   Here we hard-wire the \texttt{aPmfCdf} matrix
+%    \begin{macrocode}
+  var aPmfCdf=new Array(
+    [1,.2,.2],
+    [2,.1,.3],
+    [3,.2,.5],
+    [4,.2,.7],
+    [5,.1,.8],
+    [6,.2,1]
+  );\r
+  displayTable("displayTable",aPmfCdf);\r
+%    \end{macrocode}
+%    In the next two \texttt{displayDyBargraph}, we use the custom
+%    dynamic labeling function \texttt{customDyLabels}.
+%    \begin{macrocode}
+  displayDyBargraph("Pmf",aPmfCdf,true,false,%
+{bc:color.blue,fc:color.red,lbl:customDyLabels});\r
+  displayDyBargraph("Cdf",aPmfCdf,false,false,%
+{bc:color.blue,fc:color.red,lbl:customDyLabels});
+}]{Distr1}{}{13bp}\cgBdry[.5em]
+\pushButton[\CA{Dist2}\AAmouseup{%
+%    \end{macrocode}
+%   In this example, we define the values of the distribution and their masses. The
+%   cdf is later computed and the \texttt{aPmfCdf} is calculated.
+%    \begin{macrocode}
+  var aValues=[-2,-1,0,1,2,3,4];\r
+  var apmfs=[2/20,3/20,6/20,1/20,2/20,6/20,2/20];\r
+  var acdfs=new Array();\r
+  var aPmfCdf=new Array();\r
+  acdfs[0]=apmfs[0];\r
+  aPmfCdf[0]=[aValues[0],apmfs[0],acdfs[0]];\r
+  var l=aValues.length-1;\r
+  for (var i=1; i<l; i++) {\r\t
+    acdfs[i]=apmfs[i]+acdfs[i-1];\r\t
+    aPmfCdf[i]=[aValues[i],apmfs[i],acdfs[i]]\r
+  }\r
+  displayTable("displayTable",aPmfCdf);\r
+  displayDyBargraph("Pmf",aPmfCdf,true,false,%
+{bc:color.blue,fc:color.red});\r
+  displayDyBargraph("Cdf",aPmfCdf,false,false,%
+{bc:color.blue,fc:color.red});
+}]{Distr2}{}{13bp}\cgBdry[.5em]
+\pushButton[\TU{Randomly generate a probability distribution}
+  \CA{Random}\AAmouseup{%
+%    \end{macrocode}
+%    We set the maximum values of the distribution through the variable. When
+%    \texttt{maxN} is too large, it take some time to make all calculations
+%    and display all the bar graphs. Experiment with the value of \texttt{maxN}.
+%    \texttt{maxN}.
+%    \begin{macrocode}
+  var maxN=40;\r
+  var aPmfCdf=new Array();\r
+  var n=Math.round(Math.random()*maxN);\r
+  var aValues=[],apmfs=[],acdfs=[];\r
+  var total=0;\r
+  for (var i=0; i<n; i++) {\r\t
+    aValues[i]=i;\r\t
+    apmfs[i]=Math.round(Math.random()*maxN);\r\t
+    total+=(apmfs[i]);\r
+  }\r
+  for (var i=0; i<n; i++) {\r\t
+    apmfs[i]=apmfs[i]/total;\r\t
+    acdfs[i]=apmfs[i]+((i==0)?0:acdfs[i-1]);\r\t
+    aPmfCdf[i]=[aValues[i],apmfs[i],acdfs[i]];\r
+  }\r
+  displayTable("displayTable",aPmfCdf);\r
+  displayDyBargraph("Pmf",aPmfCdf,true,false,
+{bc:color.blue,fc:color.red});\r
+  displayDyBargraph("Cdf",aPmfCdf,false,false,
+{bc:color.blue,fc:color.red});
+}]{Distr3}{}{13bp}\cgBdry[.5em]
+ \pushButton[\CA{Reset}
+    \TU{Press to clear the fields of this page, and shift-press to
+      clear all fields.}
+    \AAmouseup{%
+    this.calculate=true;\r
+    if (event.shift)\r\t
+      this.resetForm();\r
+    else {\r\t
+      this.removeField("Pmf@pmfBar");\r\t
+      this.removeField("Cdf@cdfBar");\r\t
+      this.resetForm("displayTable");\r
+    }
+}]{reset}{}{13bp}\cgBdry[2em]
+\pushButton[\CA{Toggle Border}\AAmouseup{%
+  var f=this.getField("Pmf@pmfBar");\r
+  if ( f!=null ) {\r\t
+    var a=f.getArray();\r\t\t
+    if (f.saveStrokeColor==undefined) f.saveStrokeColor=color.red;\r\t
+    if (!color.equal(a[0].strokeColor,color.transparent))\r\t\t
+      f.saveStrokeColor=a[0].strokeColor;\r\t
+    var g=getField("Cdf@cdfBar");\r\t
+    if (color.equal(a[0].strokeColor,color.transparent)) {\r\t\t
+      f.strokeColor=f.saveStrokeColor;\r\t\t
+      g.strokeColor=f.saveStrokeColor;\r\t
+    } else {\r\t\t
+      f.strokeColor=color.transparent;\r\t\t
+      g.strokeColor=color.transparent;\r\t
+    }\r
+  }
+}]{toggleBdry}{}{13bp}
+\end{flushleft}
+\end{document}
+%</dyn1>
+%    \end{macrocode}
+\endinput
-- 
cgit v1.2.3

