summaryrefslogtreecommitdiff
path: root/texmf-dist/doc
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-10-01 11:31:05 +0900
committerNorbert Preining <norbert@preining.info>2019-10-01 11:31:05 +0900
commit7550a40711358021c4e6028deb4aa9d11fc503e4 (patch)
tree8998204f93b3e6d64919a4be9a07b3e411def2b2 /texmf-dist/doc
parent56cafb279fe43023ee711349757a0e9187c99923 (diff)
add bargraph-js
Diffstat (limited to 'texmf-dist/doc')
-rw-r--r--texmf-dist/doc/latex/bargraph-js/README.md27
-rw-r--r--texmf-dist/doc/latex/bargraph-js/bargraphjs-man.pdfbin0 -> 263600 bytes
-rw-r--r--texmf-dist/doc/latex/bargraph-js/bargraphjs-man.tex1189
-rw-r--r--texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.dtx1451
-rw-r--r--texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.ins66
-rw-r--r--texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.pdfbin0 -> 265306 bytes
-rw-r--r--texmf-dist/doc/latex/bargraph-js/examples/binomial-dist/binomial-tbl-gh.tex401
7 files changed, 3134 insertions, 0 deletions
diff --git a/texmf-dist/doc/latex/bargraph-js/README.md b/texmf-dist/doc/latex/bargraph-js/README.md
new file mode 100644
index 00000000..5cb1b59f
--- /dev/null
+++ b/texmf-dist/doc/latex/bargraph-js/README.md
@@ -0,0 +1,27 @@
+The bargraph-js Package
+Author: D. P. Story
+Dated: 2019-04-07
+
+The package uses Acrobat forms and Acrobat JavaScript API to create and
+manipulate interactive bar graphs. This means the user can enter data in a
+couple formats, to populate the bar graphs. The package can also be used to
+create and display discrete probability distributions, for both the pmf and
+cdf of a distribution.
+
+Any bar graph created by the bargraph-js package requires Adobe Reader DC (or
+Acrobat) for full functionality.
+
+PDF Creators: Any of the usual PDF creator can be used; however, to repeat,
+an Adobe PDF reader is required for full functionality.
+
+Enjoy!
+
+Now, I must get back to my retirement.
+
+
+D. P. Story
+www.acrotex.net
+dpstory@uakron.edu
+dpstory@acrotex.net
+
+
diff --git a/texmf-dist/doc/latex/bargraph-js/bargraphjs-man.pdf b/texmf-dist/doc/latex/bargraph-js/bargraphjs-man.pdf
new file mode 100644
index 00000000..9070a144
--- /dev/null
+++ b/texmf-dist/doc/latex/bargraph-js/bargraphjs-man.pdf
Binary files differ
diff --git a/texmf-dist/doc/latex/bargraph-js/bargraphjs-man.tex b/texmf-dist/doc/latex/bargraph-js/bargraphjs-man.tex
new file mode 100644
index 00000000..2dd5e673
--- /dev/null
+++ b/texmf-dist/doc/latex/bargraph-js/bargraphjs-man.tex
@@ -0,0 +1,1189 @@
+\documentclass{article}
+\usepackage[fleqn]{amsmath}
+\usepackage[
+ web={centertitlepage,designv,forcolorpaper,tight*,latextoc,extended},
+ eforms={usealtadobe,setcorder},aebxmp
+]{aeb_pro}
+\usepackage[dynamic]{bargraph-js}
+%\usepackage[ImplMulti]{dljslib}
+\usepackage{graphicx,array,fancyvrb}
+\usepackage{aeb_mlink}
+%\usepackage{myriadpro}
+%\usepackage{calibri}
+\usepackage[altbullet]{lucidbry}
+
+\hfuzz2pt
+\makePDasXOn
+ %\previewOn\pmpvOn
+
+\def\hardspace{{\fontfamily{cmtt}\selectfont\symbol{32}}}
+\let\uif\textsf
+
+\advance\marginparwidth12pt
+
+\usepackage{acroman}
+\usepackage[active]{srcltx}
+
+\edef\amtIndent{\the\parindent}
+
+\addtolength{\marginparwidth}{2pt}
+
+\urlstyle{tt}
+
+\def\STRUT{\rule{0pt}{14pt}}
+
+\makeatletter
+\newcount\hesheCnt \hesheCnt=-1
+\def\heshe{\@ifstar{\heshei}{\global\advance\hesheCnt1\relax\heshei}}
+\def\heshei{\ifodd\hesheCnt she\else he\fi}
+\def\HeShe{\@ifstar{\HeShei}{\global\advance\hesheCnt1\relax\HeShei}}
+\def\HeShei{\ifodd\hesheCnt She\else He\fi}
+\def\hisher{\@ifstar{\hisheri}{\global\advance\hesheCnt1\relax\hisheri}}
+\def\hisheri{\ifodd\hesheCnt her\else his\fi}
+\def\himher{\@ifstar{\himheri}{\global\advance\hesheCnt1\relax\himheri}}
+\def\himheri{\ifodd\hesheCnt her\else him\fi}
+\makeatother
+
+\DeclareDocInfo
+{
+ university={\AcroTeX.Net},
+ title={The \textsf{bargraph-js} Package},
+ author={D. P. Story},
+ email={dpstory@acrotex.net},
+ subject=Documentation for the bargraph-js package,
+ talksite={\url{www.acrotex.net}},
+ version={0.7,2019/04/07},
+ Keywords={LaTeX, form fields, bargraphs using JavaScript, AcroTeX},
+ copyrightStatus=True,
+ copyrightNotice={Copyright (C) \the\year, D. P. Story},
+ copyrightInfoURL={http://www.acrotex.net}
+}
+
+\universityLayout{fontsize=Large}
+\titleLayout{fontsize=LARGE}
+\authorLayout{fontsize=Large}
+\tocLayout{fontsize=Large,color=aeb}
+\sectionLayout{indent=-62.5pt,fontsize=large,color=aeb}
+\subsectionLayout{indent=-31.25pt,color=aeb}
+\subsubsectionLayout{indent=0pt,color=aeb}
+\subsubDefaultDing{\texorpdfstring{$\bullet$}{\textrm\textbullet}}
+
+\begin{insDLJS*}{lbl}
+\begin{newsegment}{Labeling function}
+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{newsegment}
+\begin{newsegment}{Validate input data}
+function validateArrayNonNegNums(aValue){
+ var bOk=true;
+ for (var i=0; i<aValue.length; i++) {
+ var x=1*aValue[i];
+ if(isNaN(x)) {bOk=false; break;}
+ else if (x<0) {bOk=false; break;}
+ }
+ return bOk
+}
+\end{newsegment}
+\begin{newsegment}{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{newsegment}
+\end{insDLJS*}
+\barLabelsTU{customBarLabels} % applies to all bars with a \TU key
+%\barLabelsNoTU{customLabelsForBars} % applies to all other bars
+
+
+\chngDocObjectTo{\newDO}{doc}
+\begin{docassembly}
+var titleOfManual="The bargrah-js Package";
+var manualfilename="Manual_BG_Print_bgraph-js.pdf";
+var manualtemplate="Manual_BG_Brown.pdf"; // Blue, Green, Brown
+var _pathToBlank="C:/Users/Public/Documents/ManualBGs/"+manualtemplate;
+var doc;
+var buildIt=false;
+if ( buildIt ) {
+ console.println("Creating new " + manualfilename + " file.");
+ doc = \appopenDoc({cPath: _pathToBlank, bHidden: true});
+ var _path=this.path;
+ var pos=_path.lastIndexOf("/");
+ _path=_path.substring(0,pos)+"/"+manualfilename;
+ \docSaveAs\newDO ({ cPath: _path });
+ doc.closeDoc();
+ doc = \appopenDoc({cPath: manualfilename, oDoc:this, bHidden: true});
+ f=doc.getField("ManualTitle");
+ f.value=titleOfManual;
+ doc.flattenPages();
+ \docSaveAs\newDO({ cPath: manualfilename });
+ doc.closeDoc();
+} else {
+ console.println("Using the current "+manualfilename+" file.");
+}
+var _path=this.path;
+var pos=_path.lastIndexOf("/");
+_path=_path.substring(0,pos)+"/"+manualfilename;
+\addWatermarkFromFile({
+ bOnTop:false,
+ bOnPrint:false,
+ cDIPath:_path
+});
+\executeSave();
+\end{docassembly}
+
+
+\begin{document}
+
+\maketitle
+
+\selectColors{linkColor=black}
+\tableofcontents
+\selectColors{linkColor=webgreen}
+
+
+\section{Introduction}\label{intro}
+
+This package can create bar graphs that represent categorical or quantitative
+data; special techniques can be use to create bargraph representations of a
+discrete probability distribution.
+
+Bar graphs created by this package are \emph{dynamic}; that is, the user
+can enter data and the bar graph changes to reflect this new data. This magic
+is performed using \app{Acrobat} forms and \app{Acrobat} JavaScript. The
+individual ``bars'' of a bar graph are form fields, JavaScript is used to
+change their bounding rectangles.
+
+The document requires, for the dynamic bar graph features to work, the user to
+be viewing the document in \app{AR} (or the \app{Acrobat} application
+(\app{AA}), of course). JavaScript even within \app{AR} is not fully
+supported on all devices, as a result, \app{AR} or \app{AA} on a desktop or
+laptop is required.
+
+Before we start describing this package, we present a simple example. Enter nonnegative numbers
+in the text fields to the right.\vcgBdry[6bp]
+
+\fbox{\begin{bargraphenv}[width=(23bp*4),height=2in,o=vert]{vehiclesV}
+\presetsbarfor{vBar}{auto}{\BG{red}}
+\presetsbarfor{vBar}{truck}{\BG{green}}
+\presetsbarfor{vBar}{suv}{\BG{yellow}}
+\presetsbarfor{vBar}{van}{\BG{magenta}}
+\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-(23bp*4)-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}
+ \A{\JS{optimizeScaling("vehiclesV");}
+}]{optimize2}{}{13bp}
+\end{minipage}\vcgBdry[6bp]
+
+Reset vertical bar graph:\marginpar{\small\itshape
+\raisebox{2in+6bp}{\parbox[t]{\marginparwidth}{\raggedleft
+ This example appears in \texttt{examples/\allowbreak bgjs-basic1.tex}}}}
+ \pushButton[\CA{Reset}\A{\JS{resetBargraphs("vehiclesV");}}
+]{reset}{}{13bp}\vcgBdry[6bp]
+
+\textbf{Motivation.} The motivation for the package comes from the request of
+an {Acro\negthinspace\TeX} user. He wanted a bar graph that summarizes the
+results of a questionnaire. Each of some eighty question is classified into
+one of eight categories. A bar graph is then generated based on the
+responses.
+
+\section{Requirements and options of the package}
+
+The \pkg{bargraph-js} package uses the \pkg{eforms} package
+dated 2019/03/16 or later. Use the package in the usual way,
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()]
+\documentclass{article}
+\usepackage{bargraph-js}
+\end{Verbatim}
+There are no package options. If you want to use options for the \pkg{eforms} package, load
+it earlier than \pkg{bargraph-js}:
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()]
+\documentclass{article}
+\usepackage[usealtadobe,setcorder]{eforms}
+\usepackage{bargraph-js}
+\end{Verbatim}
+
+\part{Bar graph with a fixed number of bars}
+
+In this part of the manual, the construction of bar graphs is discussed with a known number
+of bars.
+
+\section{The bar graph environments}
+
+The package defines two environments, these are \env{bargraphenv} and
+\env{bargraph}; the latter environment is placed within the former one.
+\bVerb\takeMeasure{\string\begin\darg{bargraphenv}[\ameta{bgenv-options}]\darg{\ameta{bgenv-name}}}%
+\def\1{\hskip\amtIndent\relax}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\begin{bargraphenv}[!ameta(bgenv-options)]{!ameta(bgenv-name)}
+!1!meta(\presetsbarfor)!sffamily!textsl( commands, optional)
+!1\begin{bargraph}[!ameta(bg-options)]{!ameta(bg-name)}
+!1!1\barfor{!ameta(bar-name!SUB1)}...\barfor{!ameta(bar-name!SUB(n))}
+!1\end{bargraph}
+!1!sffamily!textsl(additional bargraph environments, optional)
+\end{bargraphenv}
+\end{dCmd}
+\eVerb The \ameta{bgenv-name} argument must be unique throughout the
+document, the other names (\ameta{bg-name} and \ameta{bar-name}) may be
+reused in other \env{bargraphenv} environments. Within a \env{bargraphenv}
+environment, however, the \ameta{bg-name} must be unique, that is, not repeated. The
+\cs{presetsbarfor} commands are a way of changing the appearances of the
+individual bars. Within the \env{bargraph} environment, only \cs{barfor}\marginpar{\small\itshape\raggedleft Only \cs{barfor}
+and \cs{cmd} are permitted} or
+\cs{cmd} commands are recognized (the latter is not shown). The \cs{barfor}
+command gives a name to the bar so it can be referenced and manipulated. More
+than one \env{bargraph} environment within a \env{bargraphenv}
+environment is supported.
+
+Before describing the individual components, we present the verbatim listing of
+the example given above.\def\1{\hskip\amtIndent\relax}
+\begin{Verbatim}[fontsize=\small,commandchars={!~@}]
+\fbox{%
+!1\begin{bargraphenv}[width=(23bp*4),height=2in,o=vert]{vehiclesV}
+!1!1\presetsbarfor{vBar}{auto}{\BG{red}}
+!1!1\presetsbarfor{vBar}{truck}{\BG{green}}
+!1!1\presetsbarfor{vBar}{suv}{\BG{yellow}}
+!1!1\presetsbarfor{vBar}{van}{\BG{magenta}}
+!1!1\begin{bargraph}[nbars=4,gap=3]{vBar}
+!1!1!1\barfor{auto}\barfor{truck}\barfor{suv}\barfor{van}
+!1!1\end{bargraph}
+!1\end{bargraphenv}
+}
+\end{Verbatim}
+The key-values of \env{bargraphenv} set the dimensions of the `display
+window' (here, we use \cs{fbox} to enclose it). The option \texttt{o=vert}
+states these bar graphs will be vertically oriented. The next four lines are
+\cs{presetsbarfor} commands that pass appearances on to the bars themselves;
+this accounts for the coloring of the individual bars demonstrated in the
+interactive example above. The optional key-values for the \env{bargraph}
+environment are \texttt{nbars=4} (the number of bars in this bar graph,
+required); and \texttt{gap=3} (distance between bars in big points)
+
+%; and \texttt{order=fl} (the order this bars are placed in the display
+%window, here `first-to-last).
+
+\paragraph*{Description of \protect\env{bargraphenv} arguments.} \env{bargraphenv} is
+a \env{minipage} environment, in which the bars are drawn and
+displayed. The following are the key-values recognized within the optional
+argument of \env{bargraphenv}.
+\begin{aebDescript}
+ \item[\texttt{width=\ameta{length}}] The width of the environment.
+ \item[\texttt{height=\ameta{length}}] The height of the environment.
+ \item[\texttt{o=\ameta{\upshape{horiz|vert}}}] Declares the orientation of
+ the bar graph contained within the environment: \texttt{o=horiz}
+ specifies the bar graphs are to be horizontal; \texttt{o=vert} sets the
+ bar graphs to be vertical. The default is vertical.
+ \item[\texttt{origin=\ameta{\upshape{0|.5}}}] The position of
+ the horizontal axis (when \texttt{o=vert}) or the vertical
+ axis (when \texttt{o=horiz}). A value of \texttt{origin=0}
+ is the default.
+ \item[\texttt{showaxis\ameta{\upshape{true|false}}}] If
+ \texttt{showaxis=true} (or just \texttt{showaxis}, the horizontal rule
+ (if \texttt{o=vert}) or a vertical rule (if \texttt{o=horiz}) is drawn.
+ The default is no axis is drawn.
+
+\end{aebDescript}
+
+\paragraph*{Description of \protect\env{bargraph} arguments.} The \env{bargraph} environment
+is placed within the \env{bargraphenv} environment; it has a name
+(\ameta{bg-name}) and must contain, within its body, only the \cs{barfor} and
+\cs{cmd} commands. The optional arguments (\ameta{bg-options}) are used to
+describe the bars that is contained in the environment.
+
+\begin{aebDescript}
+ \item[\texttt{nbars=\ameta{num}}] (Required) The number of bars to appear in this
+ \env{bargraph} environment. The value \ameta{num} must be a positive
+ integer. There is no enforcement of this restriction; just disaster.
+ The value specified by
+ \texttt{nbars}\marginpar{\small\raggedleft\slshape\cs{nbars}} is saved in the
+ command \cs{nbars}; \cs{nbars} is globally defined and is overwritten
+ then when the next \env{bargraph} environment is expanded. The default
+ for \texttt{nbars} is zero (0); consequently, this is a required key.
+ \item[\texttt{gap=\ameta{num}}] (Optional) The amount space between bars; \ameta{num}
+ is a number of reasonable size; the number is dimensionless, but is
+ interpreted as a big point. No enforcement, its your document. The gap
+ can be access through the command \cs{bargap}\marginpar{\small\raggedleft\slshape\cs{bargap}};
+ if \texttt{gap=3}, then \cs{bargap} expands to \texttt{3bp}. The definition of \cs{bargap}
+ is global, it is overwritten when the next \env{bargraph} environment is expanded. The default
+ is \texttt{gap=0}.
+ \item[\texttt{bardimen=\ameta{num}}] (Optional) A dimensionless positive number
+ interpreted as the width (in the case of \texttt{o=vert}) and height
+ (when \texttt{o=horiz}) in big points. The default is 20. The value of the
+ \texttt{bardimen} key is saved in the \cs{bardimen}\marginpar{\small\raggedleft\slshape\cs{bardimen}}
+ command as \texttt{\ameta{num}bp}; this is global definition and is overwritten when
+ the next \env{bargraph} environment is expanded.
+% \item[\texttt{order=\ameta{\upshape{fl|lf}}}] The order the bars are
+% placed in the \env{bargraphenv} environment; \texttt{o=fl} is the
+% default, they are built in the same order they are listed; for
+% \texttt{o=lf}, the bars are built in reverse order to what they are
+% listed. This option may not really be needed, if you want them displayed in
+% reverse order, just list them in the order you wish and recompile.
+\end{aebDescript}
+In the example given earlier, the \env{bargraph} environment was,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small]
+\begin{bargraph}[nbars=4,gap=3]{vBar}
+\barfor{auto}\barfor{truck}\barfor{suv}\barfor{van}
+\end{bargraph}
+\end{Verbatim}
+We declare this environment to have a name of \texttt{vBar}
+(\ameta{bg-name}). It contains four bars, each with a gap of 3 (3bp). The
+environment contains four \cs{barfor} commands named \texttt{auto},
+\texttt{truck}, \texttt{suv}, and \texttt{van} (these are the
+\ameta{bar-name}s).
+
+
+\paragraph*{Description of \texorpdfstring{\protect\cs{presetsbarfor}}{\textbackslash{presetsbarfor}}.}
+The \cs{barfor} command creates a (rectangular) push button used to represent
+a single `bar' in a bar graph. The \cs{presetsbarfor} commands are the chosen
+way to pass (form field) options to the push buttons created by \cs{barfor}.
+\bVerb\takeMeasure{\string\presetsbarfor\darg{\ameta{bg-name}}\darg{\ameta{bar-name}}\darg{\ameta{KV-pairs}}}%
+\def\1{\hskip\amtIndent\relax}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\presetsbarfor{!ameta(bg-name)}{!ameta(bar-name)}{!ameta(KV-pairs)}
+\end{dCmd}
+\eVerb To uniquely identify which form field these key-value pairs
+(\ameta{KV-pairs}) apply, we supply the name of the \env{bargraph}
+environment (\ameta{bg-name}) the bar is located in, and the name of the
+particular bar (\ameta{bar-name}). The \ameta{KV-pairs} argument consists of
+any key-value pairs supported by the \pkg{eforms} package for form fields.
+\bVerb\def\1{\hskip\amtIndent\relax}
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars={!()}]
+\presetsbarfor{vBar}{auto}{\BG{red}}
+\presetsbarfor{vBar}{truck}{\BG{green}}
+\presetsbarfor{vBar}{suv}{\BG{yellow}}
+\presetsbarfor{vBar}{van}{\BG{magenta}}
+\begin{bargraph}[nbars=4,gap=3]{vBar}
+!1\barfor{auto}\barfor{truck}\barfor{suv}\barfor{van}
+\end{bargraph}
+\end{bargraphenv}}
+\end{Verbatim}
+\eVerb
+These commands reference the bars within the \texttt{vBar} \env{bargraph}
+environment. For example, for the bar named \texttt{auto}, we assign a background
+(or fill) color of red, and so on.
+
+\paragraph*{The \texorpdfstring{\protect\cs{barfor} and \protect\cs{cmd}}{\textbackslash{barfor} and \textbackslash{cmd}} commands.}
+The body of \env{bargraph} consists solely of \cs{barfor} and \cs{cmd}
+commands (\cs{cmd} is a local command, defined for the \env{bargraph}
+environment). The syntax for these are \cs{barfor\darg{\ameta{bar-name}}} and
+\cs{cmd\darg{\ameta{markup}}}, where \ameta{markup} refers to any {\LaTeX}
+markup. The author created \cs{cmd} to add typeset labeling to the bar graph,
+but there are other applications. Illustrations of \cs{cmd} are found in
+\hyperref[multiBars]{Section~\ref{multiBars}} on drawing multiple bar graphs
+and \hyperref[labelBars]{Section~\ref*{labelBars}} on labeling.
+
+
+\section{Inputting data for a bar graph}
+
+Now, given you have set up a \env{bargraphenv} environment with its various
+innards, how do you input data so the bar graph responds? There are several schemes.
+
+\subsection{Individual input via \texorpdfstring{\protect\cs{inputFor}}{\textbackslash{inputFor}}}
+
+The method illustrated in the example on page~\pageref{intro} is for the user to input individual data
+using the package provided command \cs{inputFor}.
+\bVerb\takeMeasure{\small\string
+\inputFor[\ameta{KV-pairs}]\darg{\ameta{bgenv-name}}\darg{\ameta{bg-name}}\darg{\ameta{bar-name}}\darg{\ameta{width}}\darg{\ameta{height}}}%
+\def\1{\hskip\amtIndent\relax}%
+\begin{dCmd}[commandchars=!(),fontsize=\small]{\bxSize}
+\renewcommand\presetinputfor[2]{!ameta(eforms-actions)}
+\inputFor[!ameta(KV-pairs)]{!ameta(bgenv-name)}{!ameta(bg-name)}{!ameta(bar-name)}{!ameta(width)}{!ameta(height)}
+\end{dCmd}
+\eVerb The command \cs{inputFor} doesn't have to reside within a
+\env{bargraphenv} environment, so a full path is needed to characterize which
+of the bars this text field references. Use \ameta{KV-pairs} to change the
+appearance of the field. One such example from page~\pageref{intro} is,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars={!()}]
+\inputFor{vehiclesV}{vBar}{auto}{.5in}{13bp}
+\end{Verbatim}
+You need one \cs{inputFor} command for each of the bars in the targeted \env{bargraphenv} environment.
+%This is the simplest scenario.
+
+Use \cs{presetinputfor} to set any actions you require of your \cs{inputFor}
+commands; any re-definition of \cs{presetinputfor} should occur prior to the
+targeted \cs{inputFor} commands. The package initial definition is,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars={!~@}]
+\newcommand{\presetinputfor}[2]{%
+ \AAkeystroke{AFNumber_Keystroke(0, 0, 0, 0, "", true);}
+ \AAformat{AFNumber_Format(0, 0, 0, 0, "", true);}
+ \AAvalidate{AFRange_Validate(true, 0, false, 0);}%!textsf~ remove to allow all numbers@
+}
+\end{Verbatim}
+This requires the entries in the \cs{inputFor} commands to be nonnegative
+numbers. The two arguments of \cs{presetinputfor} are normally not used, but
+for the record \texttt{\#1} is \ameta{bgenv-name} and \texttt{\#2} is
+\texttt{\ameta{bg-name}.\ameta{bar-name}}.
+
+\subsection{Providing comma-delimited data}
+
+Another way to enter data is through a comma-delimited list of numbers.
+
+\medskip\noindent\bgroup\setlength{\fboxrule}{1bp}\fbox
+{\begin{bargraphenv}[width=(14bp*20),height=2in,o=vert]{statdemo}%(\linewidth-2\fboxsep-2\fboxrule)
+\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]
+
+\noindent\hglue1bp\marginpar{\small\itshape
+\raisebox{2in+6bp}{\parbox[t]{\marginparwidth}{\raggedleft
+ This example appears in \texttt{examples/\allowbreak bgjs-comma1.tex}}}}
+\textField[\TU{Enter up to twenty nonnegative numbers separated by commas}
+ \AAvalidate{resetBargraphs("statdemo");\r
+ \populateCommaData("statdemo","histogram",event.value,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
+\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}\A{\JS{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} \texttt{\%}\textsf{ Can perform simple arithmetic operations in text field}
+ \vcgBdry[6bp]
+
+\hglue1bp\pushButton[\CA{Reset}\AAmouseup{resetBargraphs("statdemo","commaed","rescale.statdemo")}]{reset}{}{13bp}\vcgBdry[6pt]
+
+Enter comma-delimited nonnegative numbers into the text field above, or press
+any of the three buttons \uif{Symmetrical}, \uif{Skew left}, or
+\uif{Skew right} to populate the bar graph with comma-delimited data. Press
+the \uif{Optimize} button to automatically re-scale the graph; manually
+re-scale the graph by entering a scale factor in the text field, then press
+the \uif{Rescale} button. Clear all fields by pressing the \uif{Reset}
+button. These buttons are discussed in detail in a later section.
+
+\section{Multiple bar graphs within an \texorpdfstring{\protect\env{bargraphenv}}{bargraphenv} environment}\label{multiBars}
+
+More than one \env{bargraph} environment can appear within a \env{bargraphenv}, as illustrated in the next two examples.\medskip
+
+\noindent
+\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]
+
+\noindent\marginpar{\small\itshape
+\raisebox{1.4in+6pt}{\parbox[t]{\marginparwidth}{\raggedleft
+ This example appears in \texttt{examples/\allowbreak bgjs-comma2.tex}}}}%
+\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
+ \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
+ \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}\A{\JS{optimizeScaling("math1");}}]{optimize3}{}{13bp}\cgBdry[.5em]
+\pushButton[\CA{Reset}\A{\JS{resetBargraphs("math1","txtclass3","txtclass4");}}]{reset}{}{13bp}\vcgBdry[6pt]
+A partial verbatim listing is presented below:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars={!~@}]
+\fbox{\begin{bargraphenv}[width=23bp*10,height=1.4in,o=vert]{math1}
+...
+\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}!textbf~\cmd{\hs{\bargap}}@
+\barfor{A}\barfor{B}\barfor{C}\barfor{D}\barfor{F}
+\end{bargraph}
+\end{bargraphenv}}
+...
+class1: \textField[\TU{Enter five natural numbers separated by commas}
+ \AAvalidate{%
+ var str=event.value;\r
+ \populateCommaData("math1","class1",str,validateArrayNonNegNums)}
+ ]{txtclass3}{2in}{13bp}\cgBdry[.5em]
+ \pushButton[\CA{Class 1}\AAmouseup{%
+ var str="12,15,23,10,15";\r
+ \populateCommaData("math1","class1",str);
+ }]{math1class1}{}{13bp}
+\end{Verbatim}
+To populate a bar graph with comma-delimited data, use the \cs{populateCommData} command, a {\LaTeX} helper
+command for an underlying JavaScript function. Its arguments are
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars={!~@}]
+\populateCommaData("!ameta~bgenv-name@","!ameta~bg-name@",!ameta~str@[,!ameta~validate@])
+\end{Verbatim}
+Where, \ameta{str} is a comma-delimited string of numbers; the optional \ameta{validate} argument
+is a name of a validation function. In the example above, the package defined
+\texttt{validateArrayNonNegNums} is used.
+
+One\marginpar{\small\raggedleft\textbf{Important}} more comment on the
+listing above: Observe the markup in bold font; the gap is not applied to the
+last bar for a \env{bargraph} environment, so to get same gap as we move from
+the \texttt{class1} bar graph to the \texttt{class2} bar graph, we insert
+\verb~\cmd{\hs{\bargap}}~ the desired gap. Read the comments following the next example
+for more detailed explanation of the (local) commands \cs{cmd} and \cs{hs}.\medskip
+
+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} %+13bp+10bp +13bp
+\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}\cmd{\hs{-13bp}}
+\end{bargraph}
+\end{bargraphenv}}\vcgBdry[6pt]
+
+%\hs{-33bp*5} \hs{-23bp*5}\kern5bp}
+
+\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}
+
+\noindent\marginpar{\small\itshape
+\raisebox{2in+6pt}{\parbox[t]{\marginparwidth}{\raggedleft
+ This example appears in \texttt{examples/\allowbreak bgjs-comma2.tex}}}}%
+\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
+ \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
+ \populateCommaData("math2","class2",str);
+}]{math1class1}{}{13bp}
+\end{minipage}\cgBdry[.5em]
+\pushButton[\CA{Test}\TU{Press to automatically enter data into the two fields above}\A{\JS{\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}\A{\JS{optimizeScaling("math2");}}]{optimize3}{}{13bp}\cgBdry[.5em]
+\pushButton[\CA{Reset}\A{\JS{resetBargraphs("math2","txtclass5","txtclass6");}}]{reset}{}{13bp}\vcgBdry[6pt]
+
+A partial listing is given next:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars={!~@}]
+\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}
+!textbf~\cmd{\hs{-33bp*5+10bp}}@
+\barfor{A}\barfor{B}\barfor{C}\barfor{D}\barfor{F}
+\end{bargraph}
+\end{bargraphenv}
+\end{Verbatim}
+This listing introduces two new commands, shown in bold font:
+\cs{cmd}\marginpar{\small\raggedleft\slshape\cs{cmd}} is a generic command for placing
+{\LaTeX} content into the bar graph; \cs{hs} (and \cs{vs}) are short-hand
+commands for entering a horizontal skip
+(\cs{hs}\marginpar{\small\raggedleft\slshape\cs{hs}}) or a vertical skip
+(\cs{vs}\marginpar{\small\raggedleft\slshape\cs{vs}}) into the page. These two should be
+used only within the \cs{cmd} command argument. In the above listing, we shift
+the contents of the second \env{bargraph} environment to the left to appear as shifted
+over 10bp from the first \env{bargraph}.\medskip
+
+The markup shown in bold font horizontally shifts the second bar graph
+\texttt{33bp*5} to the left ($\texttt{33bp}=\cs{bardimen}+\cs{bargap}$) and
+$5 = \cs{nbars} $. Since $\cs{bardimen}=\texttt{20bp}$ (the default value),
+we shift \texttt{10bp} ($\cs{bardimen}/2$) to the right to get the two first
+bars offset by half their width.
+
+\section{Labeling the bars}\label{labelBars}
+
+Now we come to the difficult topic of labeling (or captioning) the bars.
+Because of the dynamic nature of these bar graphs, there can be no scaling on
+the axis; however, if you rollover any of the bars, you will see labeling
+that provides some information. Throughout this document, so far, the
+``default'' labeling is applied, as exhibited by the red bar graph below;
+there is a richer scheme that is possible when the bars have a \cs{TU} (tool
+tip) markup. When you provide an appropriately coded tool tip you can build a
+much more meaningful labeling of the bars, as illustrated by the blue bar
+graph below.
+
+\noindent
+\fbox{\begin{bargraphenv}[width=23bp*10,height=1.4in,o=vert]{math3}
+\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}\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)}]{txtclass7}{2in}{13bp}\cgBdry[.5em]
+ \pushButton[\CA{Class 1}\AAmouseup{%
+ var str="12,15,23,10,15";\r
+ \populateCommaData("math3","class1",str);
+}]{math1class1}{}{13bp}\vcgBdry[4bp]
+class2: \textField[\TU{Enter five natural numbers separated by commas}
+ \AAvalidate{\populateCommaData("math1","class2",event.value,validateArrayNonNegNums)}]{txtclass8}{2in}{13bp}\cgBdry[.5em]
+ \pushButton[\CA{Class 2}\AAmouseup{%
+ var str="10,17,29,10,20";\r
+ \populateCommaData("math3","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}\A{\JS{optimizeScaling("math3");}}]{optimize3}{}{13bp}\cgBdry[.5em]
+\pushButton[\CA{Reset}\A{\JS{resetBargraphs("math3","txtclass7","txtclass8");}}]{reset}{}{13bp}\vcgBdry[6pt]
+A partial verbatim listing is presented below:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars={!()}]
+\fbox{\begin{bargraphenv}[width=23bp*10,height=1.4in,%
+ o=vert]{math3}
+\presetsbarfor{class1}{A}{\BG{red}} %!textsf( The !cs(TU) key is not provided)
+...
+\presetsbarfor{class2}{A}{\BG{blue}
+ !textbf(\TU{Class2: @v@ students received an 'A'})} %!textsf( The !cs(TU) key is provided)
+...
+\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}}
+\end{Verbatim}
+Shown in bold font above is the \cs{TU} key for the first bar of
+\texttt{class2}. The value of the \cs{TU} key contains the string
+`\texttt{@v@}'; this three-character string is replaced by the actual value
+of the bar. Concepts and methods are outlined in the next section.
+
+\subsection{Methods for labeling bars}
+
+Fundamentally, there are two methods for labeling bars: (1) using the tooltip
+feature of {\PDF} forms; and (2) non-tooltip methods. Within each of these
+two methods, several techniques have been developed, which are explained in
+the next two sections.
+
+\subsubsection{Tooltip techniques}
+
+There are two commands, \cs{barLabelsTUs} and \cs{barLabelsNoTU}, to declare
+how the {\PDF} tooltips are formed. They handle the cases of \cs{TU} key is
+provided and the \cs{TU} key is not provided. We look at each of these in
+turn.
+
+\paragraph*{The \cs{TU} key is provided.} The \cs{barLabelsTU} takes either a
+JavaScript function name or a JavaScript string argument.
+\bVerb\takeMeasure{\string\barLabelsTU\darg{\ameta{JS-function}\string|\ameta{JS-string}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\barLabelsTU{!ameta(JS-function)|!ameta(JS-string)}
+\end{dCmd}
+\eVerb \cs{barLabelsTU} \emph{applies to all bars with a \cs{TU} key}. The
+\cs{barLabelsTU} \emph{can be used within the body of the document} to change the
+method of assigning labels to bars. The tooltip can comprise of the variables
+\texttt{@env@}, \texttt{@barname@}, \texttt{@bar@}, and \texttt{@v@} to
+compose the string; these variables are replaces with their respective values
+\ameta{bgenv-name}, \ameta{bg-name}, \ameta{bar-name} and \ameta{value} when
+the bar is populated with \ameta{value}.
+
+\paragraph*{Description of argument types}
+\subparagraph*{\ameta{JS-function}} Such a JavaScript function takes two
+arguments \texttt{fld} and \texttt{v}; the latter is the current value of the
+bar, the former is the field name of the bar. Such a function should return a
+string that will be displayed as the tooltip of the bar. The default is
+\texttt{customBarLabels},
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+\barLabelsTU{customBarLabels} % !textsf(applies to all bars with a !cs(TU) key)
+\end{Verbatim}
+which is part of the \pkg{bargraph-js} package. Note that this declaration
+is equivalent to \verb|\barLabelsTU{}| and \verb|\barLabelsTU{""}|.
+
+\subparagraph*{\ameta{JS-string}} When a string is provided, \emph{the
+\cs{TU} key is ignored}. Instead a formatted string is used.
+Use the variables \texttt{@env@}, \texttt{@barname@}, \texttt{@bar@}, and
+\texttt{@v@} to compose the string, as seen below.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small]
+ \barLabelsTU{"Within the \\"@env@\\" environment, within the
+ \\"@barname@\\" environment, the bar \\"@bar@\\"
+ has a value of @v@"}
+\end{Verbatim}
+When the empty string (\verb|\barLabelsTU{""}|) or the empty argument
+(\verb|\barLabelsTU{}|) is passed, the result is to default to
+\texttt{customBarLabels}.
+
+\paragraph*{No \cs{TU} key is provided.}
+For the case that a bar does not have a \cs{TU} key (no tooltip specified),
+the argument of \cs{barLabelsNoTU}, which is JavaScript function or a
+JavaScript string, provides tooltips for the bar.
+\bVerb\takeMeasure{\string\barLabelsNoTU\darg{\ameta{JS-function}\string|\ameta{JS-string}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\barLabelsNoTU{!ameta(JS-function)|!ameta(JS-string)}
+\end{dCmd}
+\eVerb \cs{barLabelsNoTU} is specified in the preamble\marginpar{\small\itshape
+ \raisebox{2\baselineskip}{\parbox{\marginparwidth}{\raggedleft Declare
+ \cs{barLabelsNoTU} in preamble}}} and cannot be changed in the body of the
+ document. This labeling system applies to all bars with no \cs{TU} key.
+\paragraph*{Description of argument types}
+\subparagraph*{\ameta{JS-function}} When the argument is a JavaScript
+ function, the referenced function must be written. In the sample file
+ \texttt{bgjs-basic1.tex}, the JavaScript function \texttt{customLabelsForBars(fld,v)} is defined;
+ use this function as a template for writing your own custom handlers.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+\barLabelsNoTU{customLabelsForBars} %!textsf( applies to all bars without a !cs(TU) key)
+\end{Verbatim}
+
+\subparagraph*{\ameta{JS-string}} When the argument is a JavaScript string,
+ use the variables \texttt{o.env}, \texttt{o.barname}, \texttt{o.bar}, and
+ \texttt{o.value} to compose the string. The default is,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small]
+\barLabelsNoTU{o.barname+": "+o.bar+", Value: "+o.value}
+\end{Verbatim}
+This is equivalent to \verb|\barLabelsNoTU{}|. Refer to the demo file
+\texttt{bgjs-basic1.tex} for more information.
+
+\subsubsection{Non-tooltip techniques}
+
+In addition to using the {\PDF} form feature of tool tips, the bars can be visually labeled by
+\begin{itemize}
+ \item using typeset text between the bars, refer to \texttt{examples/bgjs-basic2.tex};
+ \item using form fields between the bars, refer to \texttt{examples/bgjs-basic3.tex}, also illustrated below;
+ \item using layers (OCG) between the bars, refer to \texttt{examples/bgjs-pro1.tex}, this example
+ requires a \app{dvips}/\allowbreak\app{Distiller} workflow.
+\end{itemize}\par\vcgBdry
+
+\textbf{Class instructions.} Go to a road of your choice and count the number
+of vehicles of each type during rush hour (for one hour), fill out the form
+below and turn it in for credit.\footnote{It is strongly recommended you read the documentation
+\texttt{bgjs-examples.pdf} on \texttt{bgjs-basic3.tex} as this example uses the
+command \cs{labelFld} not formally documented in this manual.}\marginpar{\small\itshape
+\raisebox{-6bp-\baselineskip}{\parbox[t]{\marginparwidth}{\raggedleft
+ This example appears in \texttt{examples/\allowbreak bgjs-basic3.tex}}}}\vcgBdry[6bp]
+
+\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
+\def\presetinputfor#1#2{%\Ff{\FfReadOnly}
+ \AAkeystroke{EFNumber_Keystroke(0, 0, 0, 0, "", true);}
+ \AAformat{try{EFNumber_Format(0, 0, 0, 0, "", true);\r
+ if(event.rc)toggleFldVisibility("#2@vehiclesH",%
+(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}
+\A{\JS{optimizeScaling("vehiclesH");}}]{optimize1}{}{13bp}
+\end{minipage}\vcgBdry[6bp]
+
+Reset horizontal bar graph: \pushButton[\CA{Reset}
+ \A{\JS{resetBargraphs("hBar","vehiclesH");\r
+}}]{reset}{}{13bp}\vcgBdry[6bp]
+
+One advantage of using forms over the other two methods is that the labeling can be dynamically
+revised using JavaScript; for example, by inserting the value of a bar (perhaps as a percentage).
+
+\part{Bar graph with an unspecified number of bars}
+
+This package also supports the \env{bargraph} environment that contain no
+\cs{barfor} or \cs{cmd} tokens. These kinds of bar graphs are primarily
+designed to support the creation of probability mass functions (pmf) and
+cumulative distribution functions (cdf).
+
+The creation\marginpar{\small\itshape\raggedleft\opt{dynamic} option} of bar graph with an unspecified number of bars require the
+\opt{dynamic} option:
+\begin{Verbatim}[xleftmargin=\amtIndent]
+\usepackage[dynamic]{bargraph-js}
+\end{Verbatim}
+This brings in a JavaScript function \texttt{displayDyBargraph()}.
+
+When used to describe the bar graphs of a discrete probability distribution,
+it is assumed the weights are evenly distributed and contiguous on the number
+line.\footnote{This restriction of contiguous can be bypassed with a little
+trickery.}
+
+
+\section{Dynamic bar graphs}
+
+As in \textbf{Part I}, the package defines two environments,
+\env{bargraphenv} and \env{bargraph}; the latter environment is placed within
+the former one.
+%\bVerb\takeMeasure{\string\begin\darg{bargraphenv}[\ameta{bgenv-options}]\darg{\ameta{bgenv-name}}}%
+\bVerb\def\1{\hskip\amtIndent\relax}\takeMeasure{\1\string\begin\darg{bargraph}\darg{\ameta{bg-name}}%
+\textbf{\string\isdynamic}\string\end\darg{bargraph}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\begin{bargraphenv}[!ameta(bgenv-options)]{!ameta(bgenv-name)}
+!1\begin{bargraph}{!ameta(bg-name)}!textbf(\isdynamic)\end{bargraph}
+\end{bargraphenv}
+\end{dCmd}
+\eVerb The first thing to note is that the \env{bargraph} environment has no
+options; the options \opt{nbars}, \opt{gap}, and \opt{bardimen} are
+automatically assigned. Multiple \env{bargraph} environments are not
+supported within a \env{bargraphenv} environment. As a signal to the package
+that the current \env{bargraph} environment is one that is dynamic, place the
+\cs{isdynamic} command within the \env{bargraph} content, and nothing else.
+
+Multiple \env{bargraph} environments are not supported within the same
+\env{bargrapenv}, but you can have two \env{bargraphenv} environments, one to hold
+the \uif{pmf} and another to hold the \uif{cdf} bar graphs.
+
+The function that does all the work is \texttt{displayDyBargraph}, it has
+four required arguments and one optional one.
+\bVerb\takeMeasure{displayDyBargraph(\ameta{bgenv-name},%
+\ameta{aPr},\ameta{bPmf},\ameta{bOptimize}[,\ameta{object}])}%
+\begin{dCmd}[commandchars={!~@}]{\bxSize}
+displayDyBargraph(!ameta~bgenv-name@,!ameta~aPr@,!ameta~bPmf@,!ameta~bOptimize@[,!ameta~object@])
+\end{dCmd}
+\eVerb
+The arguments are described next.
+\begin{description}
+ \item[\ameta{bgenv-name}] is the name of the target environmet, a JavaScript
+ string that is enclosed in double (or single) quotes
+ (\texttt{"\ameta{bgenv-name}"}).
+ \item[\ameta{aPr}] is an array of probability mass information; each entry
+ in this array has the form \texttt{[k,pmfPr,cdfPr]}, where \texttt{k}
+ is a value of the distribution, \texttt{pmfPr} is the probability mass
+ at that value; and \texttt{cdfPr} is the cumulative mass up to and
+ including the value \texttt{k}.
+ \item[\ameta{bPmf}] is true if we are to draw bar graph for a probability
+ mass function (\uif{pmf}), and false if we are to draw bar graph for a cumulative
+ distribution function (\uif{cdf}).
+ \item[\ameta{bOptimize}] is true if we optimize the graph (applies to \uif{pmf}
+ only), otherwise, we use the current scale factor.
+ \item[\ameta{object}] is a JavaScript object having the following properties:
+ \begin{description}
+ \item[\texttt{bc:\ameta{color}}] is the border color for each of the bars,
+ \ameta{color} is a JavaScript color: \texttt{["RBG",1,0,1]} or \texttt{color.red}.
+ The default is \texttt{color.red}.
+ \item[\texttt{fc:\ameta{color}}] is the fill color for each of the bars,
+ \ameta{color} is a JavaScript color: \texttt{["RBG",1,0,1]} or \texttt{color.blue}.
+ The default is \texttt{color.blue}.
+ \item[\texttt{lbl:\ameta{JS-func}}] is a JavaScript function that provides the tool tips
+ for each of the bars. When this property is not present, the built-in JavaScript
+ function \texttt{\_labelDyBars(pr,v,bPmf)} is used.
+
+ A custom labeling function can be written and specified as the value of
+ the \texttt{lbl} property. The arguments for a labeling function are
+ \texttt{pr} (the current value of the random variable); \texttt{v} (the
+ probability associated with \texttt{pr}, \texttt{v} is a \uif{pmf} or
+ \uif{cdf} value depending on the switch \texttt{bPmf}); and \texttt{bPmf}
+ is \texttt{true} when this is for a \textsf{pmf} and \texttt{false} when
+ this is for a \textsf{cdf}.
+ \end{description}
+\end{description}
+
+\def\displayTable{\textField[\autoCenter{n}\BC{}\BG{}\textSize{6}
+ \Ff{\FfMultiline}]{displayTable}{1in}{2in+6pt+3\baselineskip}}
+
+\begin{center}\bfseries
+ The bar graph for the probability mass function (pmf)
+\end{center}
+\noindent\makebox[0pt][r]{\smash
+ {\raisebox{2\fboxsep+2\fboxrule-6pt-3\baselineskip}{\displayTable}%
+ \hspace{\marginparsep}}}
+\fbox{\begin{bargraphenv}[width=\linewidth-3\fboxsep-3\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.
+\begin{flushleft}
+\pushButton[\TU{Randomly generate a probability distribution}
+ \CA{Random}\AAmouseup{%
+ var maxN=40;\r
+ var aPmfCdf=new Array();\r
+ var n=0;
+ while (n==0)\r\t
+ 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,true);\r
+}]{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}
+Notice\marginpar{\small\itshape
+\parbox[t]{\marginparwidth}{\raggedleft
+ This example appears in \texttt{examples/\allowbreak bgjs-dyn1.tex}}} that the widths of the bars
+ are automatically adjusted to allow all the bars to be displayed in the bar graph window. The minimum
+ width is \opt{bardimen}, which is set to 20(bp). In this example, maximum weight is randomly chosen less
+ than or equal to 40. In this demo we do not display the \uif{cdf}. Populating a table, as seen in the margin,
+ is optional. Each row is one entry in the \ameta{aPr} array. In the sample file \texttt{bgjs-dyn1.tex}, several
+ techniques are used to create the \ameta{aPr} array.
+
+\part{Postscript}
+
+We finish this documentation with additional miscellaneous commands, comments
+on demonstration files, and notes on my retirement.
+
+\section{Miscellaneous commands}
+
+\subsection{The bar graph data structure}
+
+The \pkg{bargraph-js} package associates with each \env{bargraphenv}
+environment a hidden text field named \texttt{internalData.\ameta{bgenv-name}}.
+This field uses the JavaScript object \texttt{dataForEnv} to store information
+about the environment. The data stored is,
+\begin{Verbatim}[commandchars=!()]
+if (typeof dataForEnv=="undefined")
+ var dataForEnv=new Object;
+dataForEnv["!ameta(bgenv-name)"]=new Object;
+dataForEnv["!ameta(bgenv-name)"].width=!ameta(width); //!textsf( width in big points)
+dataForEnv["!ameta(bgenv-name)"].height=!ameta(heigh); //!textsf( height in big points)
+dataForEnv["!ameta(bgenv-name)"].horiz=!ameta(!upshape(true)|(false));
+dataForEnv["!ameta(bgenv-name)"].sf=!ameta(scale-factor);
+dataForEnv["!ameta(bgenv-name)"].bgs=[!ameta(list-of-bg-names)];
+dataForEnv["!ameta(bgenv-name)"].origin=!ameta(!upshape0|.5);
+\end{Verbatim}
+
+\subsection{Setting the scale} The initial scale of a \env{bargraphenv} environment is set
+by the command
+\bVerb\takeMeasure{\string\scaleFactorDef\darg{\ameta{pos-num}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\scaleFactorDef{!ameta(pos-num)}
+\end{dCmd}
+\eVerb When placed in the preamble, \cs{scaleFactorDef} sets the default
+scale factor; the \pkg{bargraph-js} declares \cs{scaleFactorDef\darg{2}}.
+When a bar graph is reset (cleared), the value \ameta{pos-num} is used to
+reset the scale value
+
+When executed in
+the body, the initial scale factor of all \env{bargraphenv} environments that
+follow are affected, unless the declaration occurs in a group. For example,
+\cs{scaleFactorDef\darg{3}} sets initial scale factor to 3; a more
+provocative example is found in sample file \texttt{bgjs-adv1.tex} where we
+declare,
+\begin{Verbatim}[xleftmargin=\amtIndent]
+\fbox{\scaleFactorDef{dataForEnv["math"].height/100}%
+\begin{bargraphenv}[width=2in,height=2in,o=vert]{math}
+...
+\end{bargraphenv}}
+\end{Verbatim}
+Here we set the scale factor 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 declaration local.
+
+\subsection{Optimizing a bar graph}
+
+To optimize all the bar graphs within a \env{bargraphenv} environment, use the built-in
+JavaScript function \texttt{optimizeScaling("\ameta{bgenv-name}")}. Below is a ``generic
+example'' for optimizing an environment.
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars={!~@}]
+\pushButton[\TU{!ameta~tool tip text@}\CA{Optimize}
+ \AAmouseup{optimizeScaling("!ameta~bgenv-name@");}]{optimize}{}{13bp}
+\end{Verbatim}
+The \texttt{optimizeScaling()} function is used in numerous examples of this package.
+
+\subsection{Manually scaling a bar graph}
+
+The user can be allowed to manually re-scale the bar graph. For this purpose,
+\pkg{bargraph-js} defines two commands \cs{displaysfFor} and \cs{manualsfFor},
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars={!()}]
+\displaysfFor[!ameta(eforms-opts)]{!ameta(bgenv-name)}{.5in}{13bp}
+\manualsfFor[!ameta(eforms-opts)]{!ameta(bgenv-name)}{}{13bp}
+\end{Verbatim}
+where, \ameta{bgenv-name} is the name of the \env{bargraphenv} environment
+that these controls are to re-scale. This pair of commands appear in the
+sample files \texttt{bgjs-basic4.tex} and \texttt{bgjs-comma1.tex}.
+
+Within the text field generated by \cs{displaysfFor}, simple arithmetic
+operations can be made; eg, if current scale factor is \texttt{3.3} (the
+optimized scale value, perhaps) then entering \texttt{3.3\,/\,2} and pressing
+the re-scale button, re-scales the bar graphs to half their height or width,
+depenting on whether \texttt{o=vert} or \texttt{o=horiz}.
+
+
+\subsection{Resetting a bar graph}
+
+Reset one or more bar graphs, as well as other fields using the JavaScript function
+\texttt{resetBargraphs(\ameta{various})}
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars={!~@}]
+\pushButton[\CA{Reset}!ameta~other-options@
+!quad\AAmouseup{resetBargraphs(!ameta~various@);}
+]{reset}{}{13bp}
+\end{Verbatim}
+The \ameta{various} argument consists of a list of field names and
+\env{bargraphenv} names to be reset. The name of the \env{bargraphenv}
+environment on page~\pageref{intro} is \texttt{vehiclesV}. The code for
+the \uif{Reset} button in that example is,
+\begin{Verbatim}[xleftmargin=\amtIndent]
+\pushButton[\CA{Reset}\A{\JS{resetBargraphs("vehiclesV");}}
+]{reset}{}{13bp}\end{Verbatim}
+Notice, the argument of \texttt{resetBargraphs} is \texttt{"vehiclesV"}, this will
+clear not only all bar graphs in the \env{bargraphenv} environment, but also the
+input fields (created by \cs{inputFor}); in the latter case, this is because the
+root name of the \cs{inputFor} fields is \texttt{"vehiclesV"}.
+
+The function \texttt{resetBargraphs} is used extensively in the sample file
+of this distribution.
+
+\section{Demonstration files}
+
+This distribution comes with numerous sample files. The files are packed
+into the DTX file \texttt{bgjs-examples.dtx} (and can be unpacked by latexing
+\texttt{bgjs-examples.ins}, if not done already). Read the documentation file
+\texttt{bgjs-examples.pdf} for detailed descriptions of each sample file.
+
+\section{My retirement}
+
+Now, I simply must get back to it. \dps
+
+\end{document}
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
diff --git a/texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.ins b/texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.ins
new file mode 100644
index 00000000..2925dcff
--- /dev/null
+++ b/texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.ins
@@ -0,0 +1,66 @@
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this package when run through
+%% LaTeX or TeX.
+%%
+%% Copyright 2016 D. P. Story
+%% -------------------------------------------
+%%
+%% It may be distributed under the conditions of the LaTeX Project Public
+%% License, either version 1.2 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.2 or later is part of all distributions of LaTeX
+%% version 1999/12/01 or later.
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\filedate{2019/01/17}
+\def\batchfile{bgjs-examples.ins}
+
+\input docstrip
+\ifx\generate\undefined
+ \Msg{**********************************************}
+ \Msg{*}
+ \Msg{* This installation requires docstrip}
+ \Msg{* version 2.4 or later.}
+ \Msg{*}
+ \Msg{* An older version of docstrip has been input}
+ \Msg{*}
+ \Msg{**********************************************}
+ \errhelp{Move or rename old docstrip.tex and get a newer one.}
+ \errmessage{Old docstrip in input path}
+ \batchmode
+ \csname @@end\endcsname\end
+\fi
+
+\keepsilent
+\askforoverwritefalse
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\preamble
+\endpreamble
+
+\generate
+{%
+ \file{bgjs-basic1.tex}{\from{bgjs-examples.dtx}{copyright,basic1}}
+ \file{bgjs-basic2.tex}{\from{bgjs-examples.dtx}{copyright,basic2}}
+ \file{bgjs-basic3.tex}{\from{bgjs-examples.dtx}{copyright,basic3}}
+ \file{bgjs-basic4.tex}{\from{bgjs-examples.dtx}{copyright,basic4}}
+ \file{bgjs-adv1.tex}{\from{bgjs-examples.dtx}{copyright,adv1}}
+ \file{bgjs-comma1.tex}{\from{bgjs-examples.dtx}{copyright,comma1}}
+ \file{bgjs-comma2.tex}{\from{bgjs-examples.dtx}{copyright,comma2}}
+ \file{bgjs-pro1.tex}{\from{bgjs-examples.dtx}{copyright,pro1}}
+ \file{bgjs-dyn1.tex}{\from{bgjs-examples.dtx}{copyright,dyn1}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files }
+\Msg{*}
+\Msg{* \space *.sty, *.cfg and *.def into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
diff --git a/texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.pdf b/texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.pdf
new file mode 100644
index 00000000..43f14e93
--- /dev/null
+++ b/texmf-dist/doc/latex/bargraph-js/examples/bgjs-examples.pdf
Binary files differ
diff --git a/texmf-dist/doc/latex/bargraph-js/examples/binomial-dist/binomial-tbl-gh.tex b/texmf-dist/doc/latex/bargraph-js/examples/binomial-dist/binomial-tbl-gh.tex
new file mode 100644
index 00000000..8325eb55
--- /dev/null
+++ b/texmf-dist/doc/latex/bargraph-js/examples/binomial-dist/binomial-tbl-gh.tex
@@ -0,0 +1,401 @@
+%xpmfBar.bgnoname@Pmf
+\documentclass{article}
+\usepackage[fleqn]{amsmath}
+\usepackage[designiv,forcolorpaper,tight]{web}
+\usepackage{grayhints}
+\usepackage[dynamic]{bargraph-js}
+
+ % \previewOn\pmcaOn
+
+
+\parindent0pt
+
+\def\maxN{72}
+\begin{insDLJS*}{binomialDistr}
+\begin{newsegment}{The Binomial Distribution}
+var to=app.setTimeOut('this.layout="TwoColumnLeft"',5);
+var maxN=\maxN;
+var pmfBinKNP=[0,0,0];
+var cdfBinKNP=[0,0,0];
+var aBinCoeff=new Array();
+aBinCoeff[1]=[1];
+var aPmfCdf=new Array();
+aBinCoeff[2]=[1,2,1];
+for (var i=3; i<= maxN; i++) {
+ aBinCoeff[i]=new Array();
+ aBinCoeff[i][0]=1;
+ for (var j=1; j < i; j++)
+ aBinCoeff[i][j]=aBinCoeff[i-1][j-1]+aBinCoeff[i-1][j];
+ aBinCoeff[i][i]=1;
+}
+function BinPMF(k,n,p){
+ if (n==0) return null;
+ var q = 1 - p, r=n-k;
+ return aBinCoeff[n][k]*Math.pow(p,k)*Math.pow(q,r);
+}
+function BinCDF(k,n,p){
+ var cdf=0;
+ for (var i=0; i <= Math.floor(k); i++ )
+ cdf += (BinPMF(i,n,p));
+ return cdf;
+}
+function updateNPValues(suffix,ext,event) {
+ /* suffix="pmf"|"cdf",ext="n"|"p" */
+ var index=(ext=="n")?1:2;
+ if (suffix=="pmf")
+ pmfBinKNP[index]=event.value;
+ else
+ cdfBinKNP[index]=event.value;
+}
+function pmfValidate(suffix,event) {
+ var n = this.getField(suffix+"n");
+ var p = this.getField(suffix+"p");
+ if (n.value=="") {
+ app.alert("First, enter a value for \"n\" between 1 and "+maxN+", inclusive");
+ event.rc=false;
+ return;
+ } else {
+ if (suffix=="pmf")
+ pmfBinKNP[1]=n.value;
+ else
+ cdfBinKNP[1]=n.value;
+ if (p.value=="") {
+ app.alert("First, enter a decimal number for \"p\" between 0 and 1, inclusive");
+ event.rc=false;
+ return;
+ } else
+ if (suffix=="pmf")
+ pmfBinKNP[2]=p.value;
+ else
+ cdfBinKNP[2]=p.value;
+ }
+ var k = 1*event.value;
+ if ( (suffix=="pmf")&&(k < 0) ) {
+ event.rc=false;
+ app.alert("\"k\" must be a nonnegative integer");
+ return;
+ }
+ if ( (suffix=="pmf")&&(k > n.value) ) {
+ event.rc=false;
+ app.alert("\"k\" must be a nonnegative integer no larger than "+ n.value);
+ return;
+ }
+ if ( (suffix=="pmf")&&(!Number.isInteger(k)) ) {
+ event.rc=false;
+ app.alert("\"k\" must be a nonnegative integer");
+ return;
+ }
+ if (suffix=="pmf")
+ pmfBinKNP[0]=k;
+ else
+ cdfBinKNP[0]=k;
+}
+function ValidateBinParams(fld) {
+ var k=this.getField(fld+"k");
+ var n=this.getField(fld+"n");
+ var p=this.getField(fld+"p");
+ var bOK=( (k.valueAsString!="") && (n.valueAsString!="") && (p.valueAsString!="") );
+ return bOK;
+}
+function pmfCalculate(fld) { % dps
+ var bOk=ValidateBinParams(fld);
+ if (!bOk) app.alert("Some of the parameters have no value, please fix.");
+ if (bOk) {
+ if ( pmfBinKNP[0] > pmfBinKNP[1] ) {
+ app.alert("The \"k\" parameter is larger than the \"n\" parmater, fix it");
+ } else {
+ var f = this.getField(fld);
+ var Pr=BinPMF(pmfBinKNP[0],pmfBinKNP[1],pmfBinKNP[2]);
+ if (Pr!=null) f.value=util.printf("\%.6f",Pr);
+ }
+ }
+}
+function cdfCalculate(fld) {
+ var bOk=ValidateBinParams(fld);
+ if (!bOk) app.alert("Some of the parameters have no value, please fix.");
+ if (bOk) {
+ var f = this.getField(fld);
+ if ( cdfBinKNP[0]> cdfBinKNP[1]) {
+ f.value=util.printf("\%.6f",1);
+ } else {
+ if (cdfBinKNP[0] < 0 ) {
+ f.value=util.printf("\%.6f",0);
+ } else {
+ var Pr=BinCDF(cdfBinKNP[0],cdfBinKNP[1],cdfBinKNP[2]);
+ f.value=util.printf("\%.6f",Pr);
+ }
+ }
+ }
+}
+function tableCalc(tableN,tableP,cFld,cTableN,cTableP) {
+ var f1=this.getField(cFld+".1");
+ var f2=this.getField(cFld+".2");
+ var f3=this.getField(cFld+".3");
+ var N=this.getField(cTableN);
+ var P=this.getField(cTableP);
+ aPmfCdf=new Array(); // initialize array (declared above)
+ if ( N.valueAsString=="" || P.valueAsString=="") {
+ f1.value="At least one of the parameters, \"n\" or \"p\", does not have a value, please correct this."
+ return;
+ }
+ var pmfPr=0; cdfPr=0, rowStr="",tableStr1="",tableStr2="",tableStr3="";
+ var tableHead=util.printf(" \%s ","k")
+ +util.printf(" \%s ","pmf")
+ +util.printf(" \%s","cdf")+"\r";
+ if ( tableN > 24 ) var col1=24;
+ else var col1=tableN;
+ for (var k=0; k<=Math.min(24,tableN); k++) {
+ pmfPr=BinPMF(k,tableN,tableP);
+ cdfPr=BinCDF(k,tableN,tableP);
+ rowStr=((k<10)?util.printf("\%4d",k):util.printf("\%3d",k))
+ +util.printf("\%10.6f", pmfPr)
+ +util.printf("\%10.6f", cdfPr)
+ +"\r";
+ tableStr1+=rowStr;
+ aPmfCdf.push([k,pmfPr,cdfPr]);
+ }
+ if ( tableN <= 24 ) f1.value=tableHead+tableStr1;
+ else {
+ for (var k=25; k<=Math.min(48,tableN); k++) {
+ pmfPr=BinPMF(k,tableN,tableP);
+ cdfPr=BinCDF(k,tableN,tableP);
+ rowStr=((k<10)?util.printf("\%4d",k):util.printf("\%3d",k))
+ +util.printf("\%10.6f", pmfPr)
+ +util.printf("\%10.6f", cdfPr)
+ +"\r";
+ tableStr2+=rowStr;
+ aPmfCdf.push([k,pmfPr,cdfPr]);
+ }
+ if ( tableN <= 48 ) {
+ f1.value=tableHead+tableStr1;
+ f2.value=tableHead+tableStr2;
+ } else {
+ for (var k=49; k<=tableN; k++) {
+ pmfPr=BinPMF(k,tableN,tableP);
+ cdfPr=BinCDF(k,tableN,tableP);
+ rowStr=((k<10)?util.printf("\%4d",k):util.printf("\%3d",k))
+ +util.printf("\%10.6f", pmfPr)
+ +util.printf("\%10.6f", cdfPr)
+ +"\r";
+ tableStr3+=rowStr;
+ aPmfCdf.push([k,pmfPr,cdfPr]);
+ }
+ f1.value=tableHead+tableStr1;
+ f2.value=tableHead+tableStr2;
+ f3.value=tableHead+tableStr3;
+ }
+ }
+}
+\end{newsegment}
+\end{insDLJS*}
+%
+% Special formatting macros
+%
+\def\binPresets{\autoCenter{y}\Q{1}\S{U}\BC{gray}\textColor{0.75 g}\textSize{6}}
+\def\ValidateInt{%
+ if ( !Number.isInteger(1*event.value) ) {\r\t
+ event.rc=false;\r\t
+ app.alert("\\"n\\" must be an integer");\r
+ }%
+}
+%
+% Begin PMF macros
+%
+\def\pmfk{\textField[\presets{\binPresets}
+ \TU{Enter the number of successes "k". Must be less than "n", the second parameter}
+ \AA{\AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\FmtToGray{k}}
+ \AAValidate{pmfValidate("pmf",event);}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+}]{pmfk}{10bp}{8bp}}
+\def\pmfn{\textField[\presets{\binPresets}
+ \TU{Enter "n", the number of trials, must be no greater than \maxN}
+ \AA{\AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\FmtToGray{n}}
+ \AAValidate{EFRange_Validate(true,1,true,\maxN);\r % dps
+ if (event.rc) updateNPValues("pmf","n",event);}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+}]{pmfn}{10bp}{8bp}}
+\def\pmfp{\textField[\presets{\binPresets}
+ \TU{Enter "p", the probability of success, a decimal number between
+ 0 and 1 inclusive}\AA{%
+ \AAKeystroke{AFNumber_Keystroke(3,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(3,1,0,0,"",true);\FmtToGray{p}}
+ \AAValidate{EFRange_Validate(true,0,true,1);\r % dps
+ if (event.rc) updateNPValues("pmf","p",event);}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+}]{pmfp}{18bp}{8bp}}
+\def\pmf{\textField[\textSize{6}\S{U}\BC{gray}]{pmf}{1in}{8bp}}
+\def\calcPMF#1{\pushButton[\textSize{6}\CA{Calc}\A{\JS{%
+ pmfCalculate("#1");}}
+]{calcPMF}{}{8bp}}
+%
+% Begin CDF macros
+%
+\def\cdfk{\textField[\presets{\binPresets}
+ \TU{Enter any number for "k"}
+ \AA{\AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\FmtToGray{k}}
+ \AAValidate{pmfValidate("cdf",event);}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+}]{cdfk}{10bp}{8bp}}
+\def\cdfn{\textField[\presets{\binPresets}
+ \TU{Enter "n", the number of trials, must be no greater than \maxN}
+ \AA{\AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\FmtToGray{n}}
+ \AAValidate{EFRange_Validate(true,1,true,\maxN);\r\ValidateInt\r
+ if (event.rc) updateNPValues("cdf","n",event);} % dps
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+}]{cdfn}{10bp}{8bp}}
+\def\cdfp{\textField[\presets{\binPresets}
+ \TU{Enter "p", the probability of success, a decimal number between
+ 0 and 1 inclusive}\AA{%
+ \AAKeystroke{AFNumber_Keystroke(3,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(3,1,0,0,"",true);\FmtToGray{p}}
+ \AAValidate{EFRange_Validate(true,0,true,1);\r % dps
+ if (event.rc) updateNPValues("cdf","p",event);}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+}]{cdfp}{18bp}{8bp}}
+\def\cdf{\textField[\textSize{6}\S{U}\BC{gray}]{cdf}{1in}{8bp}}
+\def\calcCDF#1{\pushButton[\textSize{6}\CA{Calc}\A{\JS{%
+ cdfCalculate("#1");}}
+]{calcCDF}{}{8bp}}
+
+
+
+\begin{document}
+
+%\previewOff
+
+\section*{Tables of Binomial Probabilities}
+
+\def\binTablePresets{\autoCenter{y}\Q{1}\S{U}}
+
+\(
+ n=\textField[\presets{\binTablePresets}\textColor{0.75 g}\BC{gray}
+ \TU{Enter "n", the number of trials, must be no greater than \maxN}
+ \AA{\AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\FmtToGray{n}}
+ \AAValidate{AFRange_Validate(true,1,true,\maxN);\r\ValidateInt }
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ }]{tableN}{16bp}{11bp}\cgBdry\quad
+ p=\textField[\presets{\binTablePresets}\textColor{0.75 g}\BC{gray}
+ \TU{Enter "p", the probability of success, a decimal number between 0 and 1 inclusive}
+ \AA{\AAKeystroke{AFNumber_Keystroke(3,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(3,1,0,0,"",true);\FmtToGray{p}}
+ \AAValidate{AFRange_Validate(true,0,true,1);}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ }]{tableP}{25bp}{11bp}\cgBdry\,
+\pushButton[\CA{Calc}\AAmouseup{%
+ var tableN=this.getField("tableN").value;\r
+ var tableP=this.getField("tableP").value;\r
+ tableCalc(tableN,tableP,"TableOfBinPrs","tableN","tableP");\r
+ displayDyBargraph("Pmf",aPmfCdf,true,false,{bc:color.red,fc:color.blue});\r
+ displayDyBargraph("Cdf",aPmfCdf,false,false,{bc:color.red,fc:color.blue});
+ }]{tableCalc}{}{11bp}\olBdry
+\pushButton[\CA{Reset}
+ \TU{Press to clear the fields of this page, and shift-press to clear all fields.}
+ \A{\JS{%
+ this.calculate=true;\r
+ if (event.shift)\r\t
+ this.resetForm();\r
+ else\r\t
+ this.resetForm(["TableOfBinPrs","tableN","tableP"]);\r
+ this.removeField("pmfBar");\r
+ this.removeField("cdfBar");
+}}]{reset}{}{11bp}
+\)
+ \vcgBdry[12pt]
+In the table, $\operatorname{\textsf{pmf}}=f(k;n,p)=\operatorname{Pr}(X=k)$,
+$\operatorname{\textsf{cdf}}=F(k;n,p)=\operatorname{Pr}(X\le k)$.
+ \vcgBdry[12pt]{\setlength{\fboxsep}{0pt}\fbox{%
+ \textField[\BC{}\Ff{\FfMultiline}]{TableOfBinPrs.1}{105bp}{11bp*26}\olBdry
+ \textField[\BC{}\Ff{\FfMultiline}]{TableOfBinPrs.2}{105bp}{11bp*26}\olBdry
+ \textField[\BC{}\Ff{\FfMultiline}]{TableOfBinPrs.3}{105bp}{11bp*26}}\bigskip
+
+\newpage
+
+%\setlength{\fboxsep}{3pt}
+
+%\previewOn
+\begin{center}\bfseries
+ The bar graph for the probability mass function (pmf)
+\end{center}
+\fbox{\begin{bargraphenv}[width=\linewidth,height=2in,o=vert]{Pmf} %[width=.67\linewidth,height=2in,o=vert]{kaf}
+\begin{bargraph}{pmfBar}\isdynamic %\relax
+\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}\A{\JS{%
+displayDyBargraph("Pmf",aPmfCdf,true,!event.shift);}}]{optimize}{}{11bp}\quad{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.}
+
+\bigskip
+\begin{center}\bfseries
+ The bar graph for the cumulative distribution function (cdf)
+\end{center}
+\fbox{\begin{bargraphenv}[width=\linewidth,height=2in,o=vert]{Cdf}
+\begin{bargraph}{cdfBar}\isdynamic %\relax
+\end{bargraph}
+\end{bargraphenv}}\vcgBdry[\medskipamount] The height of the region above is 1~unit.\vcgBdry[\bigskipamount]
+\(
+ n=\textField[\presets{\binTablePresets}\textColor{0.75 g}\BC{gray}
+ \TU{Enter "n", the number of trials, must be no greater than \maxN}
+ \AA{\AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\FmtToGray{n}}
+ \AAValidate{AFRange_Validate(true,1,true,\maxN);\r\ValidateInt }
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ }]{tableN}{16bp}{11bp}\cgBdry\quad
+ p=\textField[\presets{\binTablePresets}\textColor{0.75 g}\BC{gray}
+ \TU{Enter "p", the probability of success, a decimal number between 0 and 1 inclusive}
+ \AA{\AAKeystroke{AFNumber_Keystroke(3,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(3,1,0,0,"",true);\FmtToGray{p}}
+ \AAValidate{AFRange_Validate(true,0,true,1);}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ }]{tableP}{25bp}{11bp}\cgBdry\,
+\pushButton[\CA{Calc}\AAmouseup{%
+ var tableN=this.getField("tableN").value;\r
+ var tableP=this.getField("tableP").value;\r
+ tableCalc(tableN,tableP,"TableOfBinPrs","tableN","tableP");\r
+ displayDyBargraph("Pmf",aPmfCdf,true,false,{bc:color.blue,fc:color.red});\r
+ displayDyBargraph("Cdf",aPmfCdf,false,false,{bc:color.blue,fc:color.red});
+ }]{tableCalc}{}{11bp}\olBdry
+\pushButton[\CA{Reset}
+ \TU{Press to clear the fields of this page, and shift-press to clear all fields.}
+ \A{\JS{%
+ this.calculate=true;\r
+ if (event.shift)\r\t
+ this.resetForm();\r
+ else\r\t
+ this.resetForm(["TableOfBinPrs","tableN","tableP"]);\r
+ this.removeField("Pmf@pmfBar");\r
+ this.removeField("Cdf@cdfBar");
+}}]{reset}{}{11bp}\cgBdry[2em]
+\pushButton[\CA{Toggle Border}\A{\JS{%
+ 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}{}{11bp}
+\)
+
+\end{document}