%--------------------------------------------
%
% Package pgfplots, library for dynamic content in PDF files
% (clickable plots)
%
% Copyright 2007/2008 by Christian Feuersänger.
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see .
%
%--------------------------------------------
\edef\pgfplotscatcodeDQ{\the\catcode`\"}%
\catcode`\"=12
% ATTENTION:
% The eforms package creates \begin{Form} and \end{Form} in \AtBeginDocument and \AtEndDocument!
\def\pgfplots@glob@TMPa{pgfsys-pdftex.def}
\ifx\pgfplots@glob@TMPa\pgfsysdriver
\RequirePackage[pdftex]{insdljs}
\RequirePackage[pdftex]{eforms}
\else
\def\pgfplots@glob@TMPa{pgfsys-dvipdfm.def}
\ifx\pgfplots@glob@TMPa\pgfsysdriver
\RequirePackage[dvipdfm]{insdljs}
\RequirePackage[dvipdfm]{eforms}
\else
\def\pgfplots@glob@TMPa{pgfsys-dvips.def}
\ifx\pgfplots@glob@TMPa\pgfsysdriver
\RequirePackage[dvips]{insdljs}
\RequirePackage[dvips]{eforms}
\else
\def\pgfplots@glob@TMPa{pgfsys-textures.def}
\ifx\pgfplots@glob@TMPa\pgfsysdriver
\RequirePackage[textures]{insdljs}
\RequirePackage[textures]{eforms}
\else
\RequirePackage{insdljs}
\RequirePackage{eforms}
\fi\fi\fi\fi
% Work-around for a bug in \begindljs of acrotex:
% if " is active, \begindljs will be wrong.
\def\begindljs
{%
\iwvo{\string\begingroup}
{\uccode`c=`\%\uppercase{\iwvo{\string\obeyspaces\string\obeylines\string\global\string\let\string^\string^M=\string\jsR c}}}
{\escapechar=-1 \lccode`C=`\%\lowercase{\iwvo{\string\\catcode`\string\\"=12C}}}
}
\def\pgfplots@clickable@no{0}
% This catcode-hackery is too much for me, I don't get '|' to work in
% conjunction with ltxdoc document style.
% So, I simply use \pgfplotsVERTBAR instead... *sigh*.
{
\catcode`\"=12
\gdef\pgfplotsDQ{"}%
\catcode`\|=12
\gdef\pgfplotsVERTBAR{|}%
\catcode`\#=12
\gdef\pgfplotsHASH{#}%
\catcode`\%=12 \gdef\pgfplotsPERCENT{%}}
% FIXME : write this stuff DIRECTLY into a pdf using \pdfobj! I don't
% need ANY TeX code inside of the methods. Maybe I can even use some
% sort of "include external .js file" command instead of /S /Javascript /JS
%
% FIXME : using '\jobname' here produces a bug in insdljs :-(
% The problem: insdljs creates a macro named 'dlsj\jobname' or
% something like that, but if fails to use '\csname' properly. So:
% only normal letters are allowed inside of the argument here.
\begin{insDLJS}[processAnnotatedPlot]{pgfplotsJS}{pgfplots Clickable Plot Code}
/*********************************************************************************
* function sprintf() - written by Kevin van Zonneveld as part of the php to javascript
* conversion project.
*
* More info at: http://kevin.vanzonneveld.net/techblog/article/phpjs_licensing/
*
* This is version: 1.33
* php.js is copyright 2008 Kevin van Zonneveld.
*
* Portions copyright Michael White (http://crestidg.com), _argos, Jonas
* Raoni Soares Silva (http://www.jsfromhell.com), Legaev Andrey, Ates Goral
* (http://magnetiq.com), Philip Peterson, Martijn Wieringa, Webtoolkit.info
* (http://www.webtoolkit.info/), Carlos R. L. Rodrigues
* (http://www.jsfromhell.com), Ash Searle (http://hexmen.com/blog/),
* Erkekjetter, GeekFG (http://geekfg.blogspot.com), Johnny Mast
* (http://www.phpvrouwen.nl), marrtins, Alfonso Jimenez
* (http://www.alfonsojimenez.com), Aman Gupta, Arpad Ray
* (mailto:arpad@php.net), Karol Kowalski, Mirek Slugen, Thunder.m, Tyler
* Akins (http://rumkin.com), d3x, mdsjack (http://www.mdsjack.bo.it), Alex,
* Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev),
* Allan Jensen (http://www.winternet.no), Andrea Giammarchi
* (http://webreflection.blogspot.com), Arno, Bayron Guevara, Ben Bryan,
* Benjamin Lupton, Brad Touesnard, Brett Zamir, Cagri Ekin, Cord, David,
* David James, DxGx, FGFEmperor, Felix Geisendoerfer
* (http://www.debuggable.com/felix), FremyCompany, Gabriel Paderni, Howard
* Yeend, J A R, Leslie Hoare, Lincoln Ramsay, Luke Godfrey, MeEtc
* (http://yass.meetcweb.com), Mick@el, Nathan, Nick Callen, Ozh, Pedro Tainha
* (http://www.pedrotainha.com), Peter-Paul Koch
* (http://www.quirksmode.org/js/beat.html), Philippe Baumann, Sakimori,
* Sanjoy Roy, Simon Willison (http://simonwillison.net), Steve Clay, Steve
* Hilder, Steven Levithan (http://blog.stevenlevithan.com), T0bsn, Thiago
* Mata (http://thiagomata.blog.com), Tim Wiel, XoraX (http://www.xorax.info),
* Yannoo, baris ozdil, booeyOH, djmix, dptr1988, duncan, echo is bad, gabriel
* paderni, ger, gorthaur, jakes, john (http://www.jd-tech.net), kenneth,
* loonquawl, penutbutterjelly, stensi
*
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
// ATTENTION: this method has been masked such that special characters of TeX and javascript
// don't produce problems.
function sprintf( ) {
// Return a formatted string
//
// + discuss at: http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_sprintf/
// + version: 804.1712
// + original by: Ash Searle (http://hexmen.com/blog/)
// + namespaced by: Michael White (http://crestidg.com)
// * example 1: sprintf("\pgfplotsPERCENT01.2f", 123.1);
// * returns 1: 123.10
var regex = /\pgfplotsPERCENT\pgfplotsPERCENT\pgfplotsVERTBAR\pgfplotsPERCENT(\d+\$)?([-+\pgfplotsHASH0 ]*)(\*\d+\$\pgfplotsVERTBAR\*\pgfplotsVERTBAR\d+)?(\.(\*\d+\$\pgfplotsVERTBAR\*\pgfplotsVERTBAR\d+))?([scboxXuidfegEG])/g;
var a = arguments, i = 0, format = a[i++];
// pad()
var pad = function(str, len, chr, leftJustify) {
var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
return leftJustify ? str + padding : padding + str;
};
// justify()
var justify = function(value, prefix, leftJustify, minWidth, zeroPad) {
var diff = minWidth - value.length;
if (diff > 0) {
if (leftJustify \pgfplotsVERTBAR\pgfplotsVERTBAR !zeroPad) {
value = pad(value, minWidth, ' ', leftJustify);
} else {
value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
}
}
return value;
};
// formatBaseX()
var formatBaseX = function(value, base, prefix, leftJustify, minWidth, precision, zeroPad) {
// Note: casts negative numbers to positive ones
var number = value >>> 0;
prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] \pgfplotsVERTBAR\pgfplotsVERTBAR '';
value = prefix + pad(number.toString(base), precision \pgfplotsVERTBAR\pgfplotsVERTBAR 0, '0', false);
return justify(value, prefix, leftJustify, minWidth, zeroPad);
};
// formatString()
var formatString = function(value, leftJustify, minWidth, precision, zeroPad) {
if (precision != null) {
value = value.slice(0, precision);
}
return justify(value, '', leftJustify, minWidth, zeroPad);
};
// finalFormat()
var doFormat = function(substring, valueIndex, flags, minWidth, _, precision, type) {
if (substring == '\pgfplotsPERCENT\pgfplotsPERCENT') return '\pgfplotsPERCENT';
// parse flags
var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false;
for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) {
case ' ': positivePrefix = ' '; break;
case '+': positivePrefix = '+'; break;
case '-': leftJustify = true; break;
case '0': zeroPad = true; break;
case '\pgfplotsHASH': prefixBaseX = true; break;
}
// parameters may be null, undefined, empty-string or real valued
// we want to ignore null, undefined and empty-string values
if (!minWidth) {
minWidth = 0;
} else if (minWidth == '*') {
minWidth = +a[i++];
} else if (minWidth.charAt(0) == '*') {
minWidth = +a[minWidth.slice(1, -1)];
} else {
minWidth = +minWidth;
}
// Note: undocumented perl feature:
if (minWidth < 0) {
minWidth = -minWidth;
leftJustify = true;
}
if (!isFinite(minWidth)) {
throw new Error('sprintf: (minimum-)width must be finite');
}
if (!precision) {
precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void(0);
} else if (precision == '*') {
precision = +a[i++];
} else if (precision.charAt(0) == '*') {
precision = +a[precision.slice(1, -1)];
} else {
precision = +precision;
}
// grab value using valueIndex if required?
var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];
switch (type) {
case 's': return formatString(String(value), leftJustify, minWidth, precision, zeroPad);
case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad);
case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase();
case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
case 'i':
case 'd': {
var number = parseInt(+value);
var prefix = number < 0 ? '-' : positivePrefix;
value = prefix + pad(String(Math.abs(number)), precision, '0', false);
return justify(value, prefix, leftJustify, minWidth, zeroPad);
}
case 'e':
case 'E':
case 'f':
case 'F':
case 'g':
case 'G':
{
var number = +value;
var prefix = number < 0 ? '-' : positivePrefix;
var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) \pgfplotsPERCENT 2];
value = prefix + Math.abs(number)[method](precision);
return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform]();
}
default: return substring;
}
};
return format.replace(regex, doFormat);
}
/*********************************************************************************/
var lastMouseX = -1;
var lastMouseY = -1;
var posOnMouseDownX = -1;
var posOnMouseDownY = -1;
// preallocation.
var tmpArray1 = new Array(2);
var tmpArray2 = new Array(2);
/**
* Takes an already existing TextField, changes its value to \c value and places it at (x,y).
* Additional \c displayOpts will be used to format it.
*/
function initTextField( x,y, textField, displayOpts, value )
{
textField.value = ""+value;
var R = textField.rect;
R[0] = x;
R[1] = y;
R[2] = R[0] + displayOpts.textSize/2*Math.max( 5,value.length );
R[3] = R[1] - 1.5*displayOpts.textSize;
textField.rect = R;
textField.textFont = displayOpts.textFont;
textField.textSize = displayOpts.textSize;
textField.fillColor = displayOpts.fillColor;//["RGB",1,1,.855];
textField.doNotSpellCheck = true;
textField.readonly = true;
if( displayOpts.printable )
textField.display = display.visible;
else
textField.display = display.noPrint;
}
/**
* Changes all required Field values of \c plotRegionField, inserts the proper
* value and displays it at the pdf positions (x,y) .
*
* @param plotRegionField a reference to a Field object.
* @param x the x coordinate where the annotation shall be placed and which is used to determine
* the annotation text.
* @param y the corresponding y coord.
* @param axisAnnotObj An object containing axis references.
* @param displayOpts An object for display flags.
* @param[out] retCoords will be filled with the point in axis coordinates.
*/
function placeAnnot( plotRegionField, x,y, textField, axisAnnotObj, displayOpts, retCoords )
{
// Get and modify bounding box. The mouse movement is only accurate up to one point
// (mouseX and mouseY are integers), so the bounding box should be an integer as well.
var R = plotRegionField.rect;
R[0] = Math.round(R[0]);
R[1] = Math.round(R[1]);
R[2] = Math.round(R[2]);
R[3] = Math.round(R[3]);
plotRegionField.rect= R;
var w = R[2] - R[0];
var h = R[1] - R[3];
// compute position 0 <= mx <= 1, 0<= my <= 1 relative to lower(!) left corner.
var mx = x - R[0];
var my = h - (R[1] - y);
var unitx = mx / w;
var unity = my / h;
var realx = axisAnnotObj.xmin + unitx * (axisAnnotObj.xmax - axisAnnotObj.xmin);
var realy = axisAnnotObj.ymin + unity * (axisAnnotObj.ymax - axisAnnotObj.ymin);
var transformedCoordx = realx;
var transformedCoordy = realy;
if( axisAnnotObj.xscale.length >= 3 && axisAnnotObj.xscale.substr(0,3) == "log" ) {
if( axisAnnotObj.xscale.length > 4 ) // log:
realx = realx * Math.log( axisAnnotObj.xscale.substr(4) );
else {
// pgfplots handles log plots base e INTERNALLY, but uses base 10 for display.
// convert to base 10:
transformedCoordx = realx / Math.log(10);
}
realx = Math.exp(realx);
}
if( axisAnnotObj.yscale.length >= 3 && axisAnnotObj.yscale.substr(0,3) == "log" ) {
if( axisAnnotObj.yscale.length > 4 ) // log:
realy = realy * Math.log( axisAnnotObj.yscale.substr(4) );
else {
// pgfplots handles log plots base e INTERNALLY, but uses base 10 for display.
// convert to base 10:
transformedCoordy = realy / Math.log(10);
}
realy = Math.exp(realy);
}
// console.println( "w = " + w + "; h = " + h );
// console.println( "mx = " + mx + "; my = " + my );
// console.println( "unitx = " + unitx + "; unity " + unity );
initTextField( x,y, textField, displayOpts,
//util.printf( "(\pgfplotsPERCENT.2f,\pgfplotsPERCENT.2f)", realx,realy )
sprintf( displayOpts.pointFormat, realx,realy) );
if( retCoords ) {
retCoords[0] = transformedCoordx;
retCoords[1] = transformedCoordy;
}
}
/**
* @param formName the name of the clickable button. It is expected to be as large as the underlying plot.
* @param axisAnnotObj an object with the fields
* - xmin, xmax
* - ymin, ymax
* - xscale, yscale
* @param displayOpts an object with the fields
* - pointFormat an sprintf format string to format the final point coordinates.
* The default is "(\pgfplotsPERCENT.2f,\pgfplotsPERCENT.2f)"
* - fillColor the fill color for the annotation. Options are
* transparent, gray, RGB or CMYK color. Default is
* ["RGB",1,1,.855]
* - textFont / textSize
*/
function processAnnotatedPlot(formName, axisAnnotObj, displayOpts, bMouseUp )
{
if( !bMouseUp ) {
posOnMouseDownX = mouseX;
posOnMouseDownY = mouseY;
return;
}
var result = this.getField( formName + "-result");
var result2 = this.getField( formName + "-result2");
var slope = this.getField( formName + "-slope" );
if( !result ) {
console.println( "WARNING: there is no TextField \"" + formName + "-result\" to display results for interactive element \"" + formName + "\"");
return;
}
result2.display = display.hidden;
slope.display = display.hidden;
// clicking twice onto the same point hides it:
if( result.display != display.hidden &&
Math.abs(lastMouseX - mouseX) < 5 &&
Math.abs(lastMouseY - mouseY) < 5 )
{
result.display = display.hidden;
return;
}
lastMouseX = mouseX;
lastMouseY = mouseY;
var a = this.getField(formName);
if( ! a ) {
console.println( "Warning: there is no form named \"" + formName + "\"" );
return;
}
if( Math.abs( lastMouseX - posOnMouseDownX ) > 6 \pgfplotsVERTBAR\pgfplotsVERTBAR
Math.abs( lastMouseY - posOnMouseDownY ) > 6 )
{
// dragging the mouse results in slope computation:
// placeAnnot shows the endpoint coords and returns the (transformed) coordinates into tmpArray1 and tmpArray2:
placeAnnot( a, posOnMouseDownX, posOnMouseDownY, result, axisAnnotObj, displayOpts, tmpArray1 );
placeAnnot( a, lastMouseX, lastMouseY, result2, axisAnnotObj, displayOpts, tmpArray2 );
var m = ( tmpArray2[1] - tmpArray1[1] ) / ( tmpArray2[0] - tmpArray1[0] );
var n = tmpArray1[1] - m * tmpArray1[0];
initTextField(
0.5 * ( lastMouseX + posOnMouseDownX ),
0.5 * ( lastMouseY + posOnMouseDownY ),
slope,
displayOpts,
sprintf( displayOpts.slopeFormat, m, n ) );
// FIXME! these document rights seem to forbid modifications to annotations, although they work for text fields!?
//var lineobj = this.getAnnot( a.page, formName + '-line' );
//console.println( 'lineobj = ' + lineobj );
//lineobj.points = [[lastMouseX,lastMouseY],[posOnMouseDownX,posOnMouseDownY]];
//lineobj.display = display.visible;
} else {
placeAnnot( a, lastMouseX, lastMouseY, result, axisAnnotObj, displayOpts, null );
}
}
\end{insDLJS}
%--------------------------------------------------
% function hideClickableTextfields() {
% for (var i = 0; i < this.numFields; i++) {
% var fieldName = this.getNthFieldName(i);
% console.println("checking Field " + fieldName + " ... ");
% if( fieldName.substr( 0, 13 ) == "clickableplot" && fieldName.indexOf( "-result", 12 ) >= 0 ) {
% console.println("hiding Field " + fieldName + " ... ");
% this.getField( fieldName ).display = display.hidden;
% }
% }
% }
% hideClickableTextfields();
%--------------------------------------------------
\newif\ifpgfplots@clickable
\newif\ifpgfplots@annot@printable
\pgfqkeys{/pgfplots}{
@backgroundpath@hook/.add code={\ifpgfplots@threedim\else\pgfplots@create@clickable@plotarea@hook\fi},
clickable/.is if=pgfplots@clickable,
clickable/.default=true,
clickable=true,
annot/js fillColor/.initial={["RGB",1,1,.855]},
annot/point format/.initial={(\%.1f,\%.1f)},
annot/slope format/.initial={\%.1f*x \%+.1f},
annot/printable/.is if=pgfplots@annot@printable,
annot/printable/.default=true,
% Available are:
% Times-Roman font.Times
% Times-Bold font.TimesB
% Times-Italic font.TimesI
% Times-BoldItalic font.TimesBI
% Helvetica font.Helv
% Helvetica-Bold font.HelvB
% Helvetica-Oblique font.HelvI
% Helvetica-BoldOblique font.HelvBI
% Courier font.Cour
% Courier-Bold font.CourB
% Courier-Oblique font.CourI
% Courier-BoldOblique font.CourBI
% Symbol font.Symbol
% ZapfDingbats font.ZapfD
annot/font/.initial={font.Times},
% annot/font={"CMR10"},
annot/textSize/.initial=11,
annot/width/.initial=,
annot/height/.initial=,
annot/jsname/.initial=,
annot/xmin/.initial=,
annot/xmax/.initial=,
annot/ymin/.initial=,
annot/ymax/.initial=,
annot/xscale/.initial=, % "log" or "linear" or "log:"
annot/yscale/.initial=,
every semilogy axis/.append style={/pgfplots/annot/point format={(\%.1f,\%.1e)}},
every semilogx axis/.append style={/pgfplots/annot/point format={(\%.1e,\%.1f)}},
every loglog axis/.append style={/pgfplots/annot/point format={(\%.1e,\%.1e)}},
}
% Creates an area which is clickable. A click produces a popup which
% contains information about the point under the cursor.
%
% The complete (!) context needs to be provided using key-value-pairs,
% either in '#1' or set before invocation of \pgfplotsclickablecreate.
%
% This command actually creates an AcroForm which employs javascript
% whenever it is clicked. A javascript Object is created which
% represents the context (axis limits and options). This javascript
% object is available at runtime.
%
% @remark This method is public and it is NOT restricted to pgfplots.
% The pgfplots hook simply initialises the required key-value-pairs in
% '#1'.
% @remark This method does not draw anything. It initialises only a
% clickable area and javascript code.
%
% The required key-value-pairs are documented in the pdf-manual or can
% be seen above.
%
% @attention Complete key-value validation is NOT performed here. It
% can happen that invalid options will produce javascript bugs when
% opened with Acrobat Reader. Use the javascript console to find them.
\def\pgfplotsclickablecreate[#1]{%
\def\pgfplots@loc@TMPa{#1}%
\ifx\pgfplots@loc@TMPa\pgfutil@empty
\else
\pgfqkeys{/pgfplots/annot}{#1}%
\fi
\pgfkeysgetvalue{/pgfplots/annot/jsname}\pgfplots@clickable@uniquename
\ifx\pgfplots@clickable@uniquename\pgfutil@empty
\edef\pgfplots@clickable@uniquename{clickableplot\pgfplots@clickable@no}%
\begingroup
\c@pgf@counta=\pgfplots@clickable@no\relax
\advance\c@pgf@counta by1
\xdef\pgfplots@clickable@no{\the\c@pgf@counta}%
\endgroup
\fi
\edef\pgfplots@clickable@expanded@args{% FIXME : is that a good idea to do!? Are user-args expandable?
{\pgfkeysvalueof{/pgfplots/annot/width}}%
{\pgfkeysvalueof{/pgfplots/annot/height}}%
{\pgfplots@clickable@uniquename}%
{{
xmin:\pgfkeysvalueof{/pgfplots/annot/xmin},
xmax:\pgfkeysvalueof{/pgfplots/annot/xmax},
ymin:\pgfkeysvalueof{/pgfplots/annot/ymin},
ymax:\pgfkeysvalueof{/pgfplots/annot/ymax},
xscale:"\pgfkeysvalueof{/pgfplots/annot/xscale}",
yscale:"\pgfkeysvalueof{/pgfplots/annot/yscale}"
}}%
{{
pointFormat: "\pgfkeysvalueof{/pgfplots/annot/point format}",
slopeFormat: "\pgfkeysvalueof{/pgfplots/annot/slope format}",
fillColor:\pgfkeysvalueof{/pgfplots/annot/js fillColor},
textFont:\pgfkeysvalueof{/pgfplots/annot/font},
textSize:\pgfkeysvalueof{/pgfplots/annot/textSize},
printable: \ifpgfplots@annot@printable true\else false\fi
}}%
}%
\expandafter\pgfplots@create@clickable@plotarea\pgfplots@clickable@expanded@args
}%
% This thing is invoked from within pgfplots. It prepares and invokes
% \pgfplotsclickablecreate.
%
\def\pgfplots@create@clickable@plotarea@hook{%
\ifpgfplots@clickable
\begingroup
\ifpgfplots@apply@datatrafo@x
\pgfplots@inverse@datascaletrafo@x\pgfplots@xmin
\pgfmathfloattosci\pgfmathresult
\let\pgfplots@clickable@xmin=\pgfmathresult
\pgfplots@inverse@datascaletrafo@x\pgfplots@xmax
\pgfmathfloattosci\pgfmathresult
\let\pgfplots@clickable@xmax=\pgfmathresult
\else
\let\pgfplots@clickable@xmin=\pgfplots@xmin
\let\pgfplots@clickable@xmax=\pgfplots@xmax
\fi
%
\ifpgfplots@apply@datatrafo@y
\pgfplots@inverse@datascaletrafo@y\pgfplots@ymin
\pgfmathfloattosci\pgfmathresult
\let\pgfplots@clickable@ymin=\pgfmathresult
\pgfplots@inverse@datascaletrafo@y\pgfplots@ymax
\pgfmathfloattosci\pgfmathresult
\let\pgfplots@clickable@ymax=\pgfmathresult
\else
\let\pgfplots@clickable@ymin=\pgfplots@ymin
\let\pgfplots@clickable@ymax=\pgfplots@ymax
\fi
\pgfplotspointbbdiagonal
\edef\pgfplots@clickable@wd{\the\pgf@x}%
\edef\pgfplots@clickable@ht{\the\pgf@y}%
%
% Convert to user interface of clickable lib:
\pgfkeyslet{/pgfplots/annot/width}\pgfplots@clickable@wd
\pgfkeyslet{/pgfplots/annot/height}\pgfplots@clickable@ht
\pgfkeyslet{/pgfplots/annot/xmin}\pgfplots@clickable@xmin
\pgfkeyslet{/pgfplots/annot/xmax}\pgfplots@clickable@xmax
\pgfkeyslet{/pgfplots/annot/ymin}\pgfplots@clickable@ymin
\pgfkeyslet{/pgfplots/annot/ymax}\pgfplots@clickable@ymax
\ifpgfplots@xislinear
\pgfkeyssetvalue{/pgfplots/annot/xscale}{linear}%
\else
\pgfkeyssetvalue{/pgfplots/annot/xscale}{log:\pgfkeysvalueof{/pgfplots/log basis x}}%
\fi
\ifpgfplots@yislinear
\pgfkeyssetvalue{/pgfplots/annot/yscale}{linear}%
\else
\pgfkeyssetvalue{/pgfplots/annot/yscale}{log:\pgfkeysvalueof{/pgfplots/log basis y}}%
\fi
\pgfinterruptboundingbox%
\pgftext[left,bottom,at=\lowerleftinnercorner]{\pgfplotsclickablecreate[]}%
\endpgfinterruptboundingbox%
\endgroup
\fi
}
% This is the low-level method which creates Acroforms and Javascript
% code.
% #1: width
% #2: height
% #3: name
% #4: the axisAnnotObj object (see javascript docs above)
% #5: the displayOpts object (see javascript docs above)
\def\pgfplots@create@clickable@plotarea#1#2#3#4#5{%
%\tracingmacros=2\tracingcommands=2
%\leavevmode
%--------------------------------------------------
% hyperref.sty implementation:
%--------------------------------------------------
% \PushButton[name=#3,borderwidth=0,bordersep=0,
% onclick={processAnnotatedPlot("#3", #4, #5);}]{\vbox to #2{\hsize=#1\vfill\hfill}}%
% \TextField[name=#3-result,hidden=true]{}%
%--------------------------------------------------
%
%--------------------------------------------------
% eforms.sty implementation:
% it allows more customization.
%--------------------------------------------------
%
% Hier kommen Annotation Directories zum Zuge!
% -> siehe Annotations in pdf reference
\def\pushButtonDefaults{
\W{0}% border width
\Border{0 0 0}%
}%
\def\textFieldDefaults{%
\W{1}% border width
\S{B}% border style ( one of SDBIU )
\F{2}% "display" bitflag. 2^1= hidden (see "Annotation Flags" in pdf reference)
%ATTENTION: \F 2 (hidden) produces INCOMPATIBILITIES with figure environment!?
% ---> ok, that has been fixed by recent versions of hyperref.
% (the pdf catalog may be incomplete in older hyperref pdftex drivers)
\Ff{1}% "Field characteristics" bitflag. 2^0 = "read-only"
}%
\pushButton[
%\A{/S/JavaScript/JS(processAnnotatedPlot("#3", #4, #5);)}%
\AA{
% /U = "mouse UP"
% /D = "mouse DOWN"
/U << /S/JavaScript/JS(processAnnotatedPlot("#3", #4, #5, 1);) >>
/D << /S/JavaScript/JS(processAnnotatedPlot("#3", #4, #5, 0);) >>
}%
]
{#3}
{#1}{#2}%
\textField{#3-result}{0pt}{0pt}%
\textField{#3-result2}{0pt}{0pt}%
\textField{#3-slope}{0pt}{0pt}%
% Unfortunately, line annotations can't be created/changed in acrobat
% javascript due to right problems :-(
%--------------------------------------------------
% \hbox to 0pt{\vsize=0pt \pdfannot{
% /Subtype /Line
% /Open /false
% /NM (#3-line)
% /C
% /CA
% /Subj ()
% /Contents ()
% /L [0 0 0 0]
% /LE [/None /OpenArrow] % PDF 1.4
% % /Ff 194
% }}%
%--------------------------------------------------
%
%
%\setLinkBbox[%
% \Border{}%
% \A{/S/JavaScript/JS(processme("#3");)}%
% \rawPDF{/C[1 0 0] /NM (#3)}%
% ]%
% {#1}{#2}{}%
}
\catcode`\"=\pgfplotscatcodeDQ
\endinput