summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2014-02-27 00:01:50 +0000
committerKarl Berry <karl@freefriends.org>2014-02-27 00:01:50 +0000
commit90ae413a94da014dbf7a6a8ab584f7c668483a5a (patch)
tree4e0528a2b2fb2004988e7fc804ea2f1354f1f5d5 /Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex
parent800cc56380d1edfe567a6a66bef13e8950eb2b0c (diff)
pgf 3.0.0
git-svn-id: svn://tug.org/texlive/trunk@33057 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex')
-rw-r--r--Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex485
1 files changed, 334 insertions, 151 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex
index 1c78bb221e6..243f8ce225d 100644
--- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex
+++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex
@@ -7,7 +7,7 @@
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.
-\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduledatavisualization.code.tex,v 1.37 2010/08/24 21:28:58 tantau Exp $
+\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduledatavisualization.code.tex,v 1.47 2013/07/19 13:16:48 tantau Exp $
\usepgfmodule{oo,shapes}
\usepgflibrary{fpu}
@@ -156,6 +156,7 @@
\def\pgfdvpathlinetotoken{6}
\def\pgfdvdirectionfromtoken{7}
\def\pgfdvdirectiontotoken{8}
+ \def\pgfdvdirectionattoken{9}
% Method
%
@@ -169,7 +170,10 @@
% Add data that is to be visualized. The code #1 should call the
% \pgfdatapoint macro for each data point it creates.
\method add data(#1) {
- \pgfooappend{data}{#1}
+ \pgf@dv@stripped@add#1\pgf@stop
+ }
+ \def\pgf@dv@stripped@add#1\pgf@stop{%
+ \pgfooappend{data}{#1}%
}
@@ -480,20 +484,22 @@
-% Compute a normalized vector pointing from some point to another.
+% Compute a normalized vector at the current point pointing along a
+% line from #1 to #2.
%
% #1 = code for setting the attributes of the first point
% #2 = code for setting the attributes of the second point
%
-% Using #1 and #2 you specify two data points. These are then
-% localized on the canvas and a vector pointing from the first data
-% point to the second one is returned. However, for instance in polar
+% The current point should be a point on a line from #1 to
+% #2. Both points as well as the current point are
+% localized on the canvas and a vector pointing from the first point
+% to the second one is returned. However, for instance in polar
% coordinates the vector may actually "point along" the angle axis.
%
% Internally, this command first sets up the first data point and then
-% emits a "path" signal with the \pgfdvpathdirectionfromtoken set and
+% emits a "direction" signal with the \pgfdvpathdirectionfromtoken set and
% then sets up the second point and emits the corresponding
-% ...totoken.
+% ...totoken. Finally, the \pgfdvpathdirectionattoken is emitted.
%
\def\pgfpointdvdirection#1#2{%
@@ -504,16 +510,14 @@
}
{
#2
- \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{
- \edef\pgf@dv@dir@xa{\the\pgf@x}
- \edef\pgf@dv@dir@ya{\the\pgf@y}
+ \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{\xdef\pgf@dv@to{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}
+ }
+ {\pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectionattoken}{%
\pgf@process{
\pgfpointnormalised{%
- \pgfpointdiff{\pgf@dv@from}{\pgfqpoint{\pgf@dv@dir@xa}{\pgf@dv@dir@ya}}
+ \pgfpointdiff{\pgf@dv@from}{\pgf@dv@to}
}
- }
- }
- }
+ }}}
}
}
@@ -529,7 +533,7 @@
-% Run the rendering pipeline on a dataset.
+% Run the rendering pipeline on a dataset and/or save the dataset.
%
% #1 = options with path /pgf/data/
% #2 = optionally data given inline in curly braces.
@@ -541,14 +545,27 @@
% accumulate. Data can be in different formats, as specified by the
% "format" key, and you can define new formats.
%
-% The setting of the following keys is important:
+% The settings of the following keys are important:
+%
+% /pgf/data visualization/obj
+% contains a handle to the dv-object
+%
+% /pgf/data/format
+% stores the format (see below)
+%
+% /pgf/data/read from file
+% determines where the data is.
+%
+% /pgf/data/store in group
+% when nonempty, the data is stored here instead of being fed to the
+% rendering pipeline
%
-% /pgf/data visualization/obj contains a handle to the dv-object
-% /pgf/data/format stores the format (see below)
-% /pgf/data/source determines where the data is.
+% /pgf/data/use group
+% when nonempty, data that has previsouly been stored here using
+% |define group| is read from here and all other keys are ignored
%
-% If source is empty, the data is stored in the argument that
-% follows. Otherwise, the file whose name is stored in source is read.
+% If "read from file" is empty, the data is stored in the argument that
+% follows. Otherwise, the data is read from the specified source file.
% This data is stored in an internal variable, which is local to the
% current group.
%
@@ -594,51 +611,78 @@
% 2200, 2300, 2250, 2260
% }
%
-% \pgfdata[source=data,format=comma separated columns]
+% \pgfdata[read from file=data.csv,format=comma separated columns]
%
% \dv.survey()
% \dv.visualize()
-\def\pgfdata{\pgfutil@ifnextchar[{\pgf@dataset@data@opt}{\pgf@dataset@data@opt[]}}%}
-\def\pgf@dataset@data@opt[#1]{%
+\def\pgfdata{\pgfutil@ifnextchar[{\pgf@datagroup@data@opt}{\pgf@datagroup@data@opt[]}}%}
+\def\pgf@datagroup@data@opt[#1]{%
% Ok, add one data thing...
- \pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgf@do@data{#1})%
\begingroup%
\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}%
\pgfkeysgetvalue{/pgf/data/continue code}\pgf@dv@cont@code%
\global\let\pgf@dv@cont@code\pgf@dv@cont@code%
- \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format%
- \expandafter\let\expandafter\pgf@dv@format@catcodes\csname pgfdv@format@\pgf@dv@format @catcodes\endcsname%
- \ifx\pgf@dv@format@catcodes\relax
- \PackageError{pgf}{Unknown data format '\pgf@dv@format'}{}%
+ \pgfkeysgetvalue{/pgf/data/use group}\pgf@dv@use@group%
+ \ifx\pgf@dv@use@group\pgfutil@empty%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgf@do@data{#1})}%
+ \expandafter\pgf@datagroup@data@opt@cont%
\else%
- \pgfkeysgetvalue{/pgf/data/source}\pgf@dv@source%
- \ifx\pgf@dv@source\pgfutil@empty%
- \let\pgf@next\pgf@dataset@grab@inline%
+ \expandafter\ifx\csname pgf@dv@group@@\pgf@dv@use@group\endcsname\relax%
+ \pgferror{Undefined data group '\pgf@dv@use@group'}%
\else%
- \let\pgf@next\pgf@dataset@grab@external%
+ {%
+ \pgfkeys{/pgf/data/define group/.code=}% no redefinitions during use
+ \csname pgf@dv@group@@\pgf@dv@use@group\endcsname%
+ }%
\fi%
- \pgf@next%
+ \endgroup%
+ \expandafter\pgf@dv@cont@code%
+ \fi%
+}
+\def\pgf@datagroup@data@opt@cont{%
+ \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format%
+ \expandafter\let\expandafter\pgf@dv@format@catcodes\csname pgfdv@format@\pgf@dv@format @catcodes\endcsname%
+ \ifx\pgf@dv@format@catcodes\relax
+ \pgferror{Unknown data format '\pgf@dv@format'}%
+ \else%
+ \pgfkeysgetvalue{/pgf/data/read from file}\pgf@dv@source%
+ \ifx\pgf@dv@source\pgfutil@empty%
+ \let\pgf@next\pgf@datagroup@grab@inline%
+ \else%
+ \let\pgf@next\pgf@datagroup@grab@external%
+ \fi%
+ \pgf@next%
}
-\def\pgf@dataset@grab@inline{%
+
+\def\pgf@datagroup@grab@inline{%
\pgfutil@ifnextchar\bgroup{%
\begingroup%
\catcode`\^^M=\active%
\pgf@dv@format@catcodes%
- \pgf@dataset@grab@@inline}%
- {\PackageError{pgf}{Opening brace expected}{}}%
+ \pgf@datagroup@grab@@inline}%
+ {\pgferror{Opening brace expected}}%
}
-\def\pgf@dataset@grab@external{%
+\def\pgf@datagroup@grab@external{%
\fi%
\endgroup%
- \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@external}}})%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@external}}})}%
\pgf@dv@cont@code%
}
+\def\pgf@dv@do@adddata#1{%
+ \pgfkeysgetvalue{/pgf/data/store in group}\pgf@dv@temp%
+ \ifx\pgf@dv@temp\pgfutil@empty%
+ #1%
+ \else%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@dv@group@@\pgf@dv@temp\endcsname{#1}%
+ \fi%
+}
+
{\catcode`\^^M=\active%
- \gdef\pgf@dataset@grab@@inline#1{%
+ \gdef\pgf@datagroup@grab@@inline#1{%
\endgroup%
- \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@inline#1^^M\pgf@@eol}}})%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@inline#1^^M\pgf@@eol}}})}%
\fi%
\endgroup%
\pgf@dv@cont@code%
@@ -663,19 +707,19 @@
% Read external file
%
-\def\pgf@dataset@do@external{%
+\def\pgf@datagroup@do@external{%
\csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@catcodes\endcsname%
- \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/source} %
+ \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/read from file} %
\ifeof\r@pgf@reada\relax
- \PackageError{pgf}{Data source '\pgfkeysvalueof{/pgf/data/source}' not found}{}%
+ \pgferror{Data file '\pgfkeysvalueof{/pgf/data/read from file}' not found}%
\else
- \pgf@dataset@readline%
+ \pgf@datagroup@readline%
\fi
\immediate\closein\r@pgf@reada%
}
\def\pgf@partext{\par}%
-\def\pgf@dataset@readline{%
+\def\pgf@datagroup@readline{%
\immediate\read\r@pgf@reada to \pgf@temp%
\ifx\pgf@temp\pgf@partext%
\pgf@dv@format@emptyline%
@@ -686,7 +730,7 @@
\expandafter\pgf@dv@format@line\pgf@temp\pgfeol%
\fi%
\fi%
- \ifeof\r@pgf@reada\else\expandafter\pgf@dataset@readline\fi%
+ \ifeof\r@pgf@reada\else\expandafter\pgf@datagroup@readline\fi%
}
@@ -694,7 +738,7 @@
% Read inline data
%
-\def\pgf@dataset@do@inline{%
+\def\pgf@datagroup@do@inline{%
\pgf@dv@handle@line%
}
@@ -712,8 +756,12 @@
\pgfkeys{
/pgf/data/data visualization obj/.initial=\undefined,
/pgf/data/format/.initial=table,% the default format
- /pgf/data/source/.initial=,
- /pgf/data/continue code/.initial=
+ /pgf/data/read from file/.initial=,
+ /pgf/data/inline/.style={read from file=},
+ /pgf/data/continue code/.initial=,
+ /pgf/data/store in group/.initial=,
+ /pgf/data/new group/.code={\expandafter\global\expandafter\let\csname pgf@dv@group@@#1\endcsname\pgfutil@empty},
+ /pgf/data/use group/.initial=,
}
@@ -737,7 +785,7 @@
% a data set is visualized and the format is set to #1, this handler
% is used to parse the data.
%
-% In detail, the \dataset command will select a source. Before this
+% In detail, the \pgfdata command will select a source. Before this
% source is read, #2 will be executed to setup the
% catcodes. Additionally, each time the data is parsed, #3 will be
% called. Then, for each nonempty line of the source, the
@@ -791,12 +839,23 @@
%
% Example:
%
-% \data[format=key value pairs] {
+% \data[format=named] {
% x=5, y=6, hi=9
% x=7, y=6, lo=10
% }
-\pgfdeclaredataformat{key value pairs}{}{}{#1}{{\pgfkeys{/data point/.cd,#1}\pgfdatapoint}}{}{}
+\pgfdeclaredataformat{named}{}{}{#1}{\pgf@dv@parse@named#1,\pgf@stop}{}{}
+\def\pgf@dv@parse@named{%
+ \pgfutil@ifnextchar\pgf@stop{\pgfdatapoint\pgfutil@gobble}{\pgf@dv@parse@named@}
+}
+\def\pgf@dv@parse@named@#1=#2,#3\pgf@stop{%
+ \foreach \pgf@dv@temp in {#2} {%
+ \def\pgf@dv@tempb{/data point/#1=}%
+ \expandafter\expandafter\expandafter\pgfkeys%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@dv@tempb\pgf@dv@temp}%
+ \pgf@dv@parse@named#3\pgf@stop%
+ }
+}
@@ -892,7 +951,7 @@
\def\pgf@dv@parse@table{%
\pgfutil@ifnextchar"% Special, but ignored right now...
- {\PackageError{pgf}{csv with quotes not yet implemented}{}}
+ {\pgferror{csv with quotes not yet implemented}}
{\pgf@dv@till@separator}
}
\def\pgf@dv@table@handle#1{%
@@ -924,7 +983,7 @@
\def\pgf@dv@doparse@headline{%
\pgfutil@ifnextchar"% Special, but ignored right now...
- {\PackageError{pgf}{csv with quotes not yet implemented}{}}
+ {\pgferror{csv with quotes not yet implemented}}
{\pgf@dv@till@separator@head}
}
\def\pgf@dv@head@handle#1{%
@@ -1158,6 +1217,27 @@
\let#1=\pgfmathresult%
}
+% Multiply by small number
+%
+% #1 = macro that should store the result of applying the
+% corresponding operation to the following:
+% #2 = entered number
+% #3 = fixed point number like 2 or 0.5, but not 10000000000
+%
+% Description:
+%
+% Sets #1 to the result of applying an operation to #2 and #3
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{2000}
+% \pgfdvmathadd{\b}{\a}{0.2}
+% % \b now stores 400
+
+\def\pgfdvmathmulfixed#1#2#3{%
+ \pgfmathfloatmultiplyfixed{#2}{#3}%
+ \let#1=\pgfmathresult%
+}
@@ -1457,12 +1537,15 @@
\attribute out min;
% Start of the second range (the value of c).
+ \attribute out min;
+ % End of the second range (the value of d).
+
\attribute trans in min;
% Transformed value of the start of the first range (the value
% f(a)).
\attribute scale;
- % The scaling factor, that is, the value of (f(d)-f(c))/(b-a).
+ % The scaling factor, that is, the value of (f(b)-f(a))/(d-c).
% Constructor
@@ -1540,6 +1623,7 @@
\pgfdvmathenter{\pgf@out@interval@max}{#4}
% Let's start with the output, it's easier...
\pgfoolet{out min}{\pgf@out@interval@min}
+ \pgfoolet{out max}{\pgf@out@interval@max}
\pgfdvmathsub{\pgf@out@diff}{\pgf@out@interval@max}{\pgf@out@interval@min}
\let\pgfvalue=\pgf@in@interval@min
\pgfoovalueof{trans}
@@ -1568,8 +1652,10 @@
\pgfkeysgetvalue{/data point/\pgfoovalueof{in}}\pgf@dv@external@value%
\fi%
\ifx\pgf@dv@external@value\pgfutil@empty%
+ \pgf@dv@mapper@pos@check%
\else%
\ifx\pgf@dv@external@value\relax%
+ \pgf@dv@mapper@pos@check%
\else%
% % Clip?
\pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}%
@@ -1581,20 +1667,20 @@
% \fi%
\fi%
\fi%
- \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/min}\pgf@dv@external@value%
- \ifx\pgf@dv@external@value\relax\else%
- \ifx\pgf@dv@external@value\pgfutil@empty\else%
- \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}%
- \pgf@dv@mapper@trans{/min}
- \fi
- \fi
- \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/max}\pgf@dv@external@value%
- \ifx\pgf@dv@external@value\relax\else%
- \ifx\pgf@dv@external@value\pgfutil@empty\else%
- \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}%
- \pgf@dv@mapper@trans{/max}
- \fi
- \fi
+% \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/min}\pgf@dv@external@value%
+% \ifx\pgf@dv@external@value\relax\else%
+% \ifx\pgf@dv@external@value\pgfutil@empty\else%
+% \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}%
+% \pgf@dv@mapper@trans{/min}
+% \fi
+% \fi
+% \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/max}\pgf@dv@external@value%
+% \ifx\pgf@dv@external@value\relax\else%
+% \ifx\pgf@dv@external@value\pgfutil@empty\else%
+% \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}%
+% \pgf@dv@mapper@trans{/max}
+% \fi
+% \fi
\fi%
}
@@ -1616,6 +1702,22 @@
\pgfdvmathexitbyserializing{\pgf@temp}{\pgfvalue}%
\pgfkeyslet{/data point/\pgfoovalueof{out}#1}\pgf@temp%
}
+
+ \def\pgf@dv@mapper@pos@check{%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/out pos}\pgf@dv@pos@value%
+ \ifx\pgf@dv@pos@value\relax\else\if\pgf@dv@pos@value\pgfutil@empty\else%
+ \pgfmathsetmacro{\pgf@dv@pos@num}{\pgf@dv@pos@value}%
+ \pgfmathsetmacro{\pgf@dv@pos@num@prime}{1-\pgf@dv@pos@num}%
+ % Ok, compute transformed min position:
+ \pgfooget{out min}{\pgf@out@interval@min}
+ \pgfooget{out max}{\pgf@out@interval@max}
+ \pgfdvmathmulfixed{\pgf@out@interval@min}{\pgf@out@interval@min}{\pgf@dv@pos@num@prime}
+ \pgfdvmathmulfixed{\pgf@out@interval@max}{\pgf@out@interval@max}{\pgf@dv@pos@num}
+ \pgfdvmathadd{\pgf@out@val}{\pgf@out@interval@min}{\pgf@out@interval@max}%
+ \pgfdvmathexitbyserializing{\pgf@temp}{\pgf@out@val}%
+ \pgfkeyslet{/data point/\pgfoovalueof{out}}\pgf@temp%
+ \fi\fi%
+ }
}
@@ -1868,8 +1970,15 @@
% "seen" during the survey phase. Based on this value, the size of,
% say, an axis can be detemined later on.
%
- % In case the attribute has the sub-attributes "min" and "max", they
- % are also taken into account.
+ % You can also set the key "sub attributes" of the attribute. In
+ % this case, this key should contain -- as the name suggests -- a
+ % list of subkeys that should also be taken into account for the
+ % computation of the minimum and maximum value. Inside the "sub
+ % attributes" key, each subkey should be surrounded by a call of
+ % \pgfdvsub. For instance, if there are two sub attributes "/data
+ % point/velocity/min" and "/data point/velocity/max" for a key
+ % "/data point/velocity", then "/data point/velocity/sub attributes"
+ % should be set to "\pgfdvsub{/min}\pgfdvsub{/max}".
\attribute attribute;
% The to-be-surveyed attribute
@@ -1902,9 +2011,12 @@
% Adjust the interval as if during the survey this value were
% encountered
\method include attribute value(#1) {
- \def\pgf@dv@val{#1}
+ \pgf@dv@assign@val@stripped#1\pgf@stop%
\pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)
}
+ \def\pgf@dv@assign@val@stripped#1\pgf@stop{%
+ \def\pgf@dv@val{#1}
+ }
% Slot
%
@@ -1913,34 +2025,36 @@
% interval.
%
\method survey() {
- \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}\pgf@dv@val%
- \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)
- \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/min}\pgf@dv@val%
- \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)
- \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/max}\pgf@dv@val%
- \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)
+ \let\pgfdvsub\pgf@dv@range@surv@sub
+ \pgfdvsub{}%
+ \pgfkeysvalueof{/data point/\pgfoovalueof{attribute}/sub attributes}
}
- \def\pgf@dv@range@surv{%
+ \def\pgf@dv@range@surv@sub#1{
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}#1}\pgf@dv@val%
\ifx\pgf@dv@val\relax%
\else%
\edef\pgf@dv@val{\pgf@dv@val}%
\ifx\pgf@dv@val\pgfutil@empty%
\else%
- \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}%
- % Now, protocol value
- \ifx\pgfdvmin\pgfutil@empty%
- \let\pgfdvmin\pgf@dv@value%
- \else%
- \pgfdvmathifless{\pgf@dv@value}{\pgfdvmin}{\let\pgfdvmin\pgf@dv@value}{}%
- \fi%
- \ifx\pgfdvmax\pgfutil@empty%
- \let\pgfdvmax\pgf@dv@value%
- \else%
- \pgfdvmathifless{\pgfdvmax}{\pgf@dv@value}{\let\pgfdvmax\pgf@dv@value}{}%
- \fi%
+ \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)%
\fi%
- \fi
+ \fi%
+ }
+
+ \def\pgf@dv@range@surv{%
+ \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}%
+ % Now, protocol value
+ \ifx\pgfdvmin\pgfutil@empty%
+ \let\pgfdvmin\pgf@dv@value%
+ \else%
+ \pgfdvmathifless{\pgf@dv@value}{\pgfdvmin}{\let\pgfdvmin\pgf@dv@value}{}%
+ \fi%
+ \ifx\pgfdvmax\pgfutil@empty%
+ \let\pgfdvmax\pgf@dv@value%
+ \else%
+ \pgfdvmathifless{\pgfdvmax}{\pgf@dv@value}{\let\pgfdvmax\pgf@dv@value}{}%
+ \fi%
}
}
@@ -1976,6 +2090,10 @@
% filter should set \pgfdvfilterpassedfalse for to-be-filtered data
% point.
%
+ % You can specify "projection code" that changes the canvas x and
+ % canvas y positions. This projection code allows you to draw, say,
+ % projected points instead of the actual data point.
+ %
% The keys /data point/<name>/execute at begin and /data
% point/<name>/execute at end, where <name> is the name of
% the visualizer, should store code that is to be executed directly
@@ -1987,7 +2105,7 @@
% The to-be-used handlers
\attribute name;
- % Filter code
+ % The attribute
\attribute filter=\pgfdvnamedvisualizerfilter;
% Filter code
@@ -2000,7 +2118,15 @@
% cache. Every 100 steps this cache is moved to positions. The idea
% behind this is that it will avoid the quadratic time increase that
% is normally caused when a protocol is build in TeX.
-
+
+ \attribute projection code;
+ % This code is empty by default. However, you can set it for
+ % instance to the following
+ %
+ % \pgfkeyssetvalue{/data point/y=0}\pgfdvmapdatapointtocanvas
+ %
+ % in order to visualize the data point with its y-coordinate
+ % replaced by 0.
% Constructor
%
@@ -2025,6 +2151,11 @@
\pgfooset{filter}{#1}
}
+ % Setter
+ \method set projection code(#1) {
+ \pgfooset{projection code}{#1}
+ }
+
% Slot
\method protocol() {
\pgfdvfilterpassedtrue
@@ -2037,7 +2168,17 @@
\def\pgf@dv@line@cache@it{
% Cache it
\pgfooget{cache}\pgf@dv@cache
- \edef\pgf@dv@add{\noexpand\pgf@dv@ph{\pgfkeysvalueof{/data point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}}%
+ \pgfkeysgetvalue{/data point/outlier}\pgf@temp%
+ \ifx\pgf@temp\pgfutil@empty
+ {%
+ \pgfoovalueof{projection code}
+ \xdef\pgf@dv@add{\noexpand\pgf@dv@ph{\pgfkeysvalueof{/data
+ point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}}%
+ }
+ \else%
+ % An outlier!
+ \gdef\pgf@dv@add{\pgf@dv@outliner}%
+ \fi%
\expandafter\expandafter\expandafter\def%
\expandafter\expandafter\expandafter\pgf@dv@cache%
\expandafter\expandafter\expandafter{\expandafter\pgf@dv@cache\pgf@dv@add}%
@@ -2072,10 +2213,10 @@
\else
\pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin}
\tikz@dv@temp
- \pgfplotstreamstart
+ \pgfdvnewstreamtrue
\pgfoovalueof{positions}
\pgfoovalueof{cache}
- \pgfplotstreamend
+ \ifpgfdvnewstream\else\pgfplotstreamend\fi
\pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end}
\fi
}
@@ -2084,15 +2225,22 @@
\pgfoolet{cache}\pgfutil@empty
}
- \def\pgf@dv@ph#1#2{\pgfplotstreampoint{\pgfqpoint{#1}{#2}}}
+ \def\pgf@dv@ph#1#2{\ifpgfdvnewstream\pgfplotstreamstart\pgfdvnewstreamfalse\fi\pgfplotstreampoint{\pgfqpoint{#1}{#2}}}
+ \def\pgf@dv@outliner{\ifpgfdvnewstream\else\pgfplotstreamend\pgfdvnewstreamtrue\fi}
}
+\newif\ifpgfdvnewstream
\newcount\pgf@lib@dv@cache@count
+\pgfkeys{%
+ /data point/outlier/.initial=,
+ /data point/outlier/.default=true
+}
+
% A possible filter for unnamed visualizers
%
-% #1 = Text to be compared with key /data point/visualizer
+% #1 = Text to be compared with key /data point/set
%
% Description:
%
@@ -2103,10 +2251,10 @@
% point/visualizer.
%
% When objects allow you to set a filter, you can use this filter to
-% test against /data point/visualizer being equal to #1.
+% test against /data point/set being equal to #1.
\def\pgfdvvisualizerfilter#1{%
- \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer%
+ \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer%
\def\pgf@temp{#1}%
\ifx\pgf@temp\pgf@dv@visualizer%
\else
@@ -2122,10 +2270,10 @@
%
% This filter works like \pgfdvvisualizerfilter, only it assumes the
% the object defines a "name" attribute. In this case, the value of
-% /data point/visualizer is tested against this attribute.
+% /data point/set is tested against this attribute.
\def\pgfdvnamedvisualizerfilter{%
- \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer%
+ \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer%
\pgfooget{name}\pgf@temp%
\ifx\pgf@temp\pgf@dv@visualizer%
\else
@@ -2140,16 +2288,19 @@
% Class rectangle visualizer
%
% This visualizer visualizes a datapoint as a rectangle. It needs
- % two attributes a1 and a2, each of which must have min and max
- % subattributes. Then, it draws a rectangle between (a1/min,a2/min)
- % and (a1/max,a2/max).
-
- \attribute attribute 1;
- \attribute attribute 2;
- % The attributes
+ % a name, so that /data point/<name>/attribute 1 and /data
+ % point/<name>/attribute 2 store two attributes names a1 to a2. Then,
+ % provided the current value of /data point/set equals name, for
+ % each data point a rectangle between (a1/min,a2/min) and
+ % (a1/max,a2/max) is created.
+
- \attribute use path attribute;
- % The attribute that stores the to-be-taken action
+ \attribute name;
+ % The name
+
+ \attribute a1;
+ \attribute a2;
+ % The attributes, filled from /data point/<name>/attribute 1 and 2
% Constructor
@@ -2157,47 +2308,65 @@
% #1 = first attribute
% #2 = second attribute
%
- \method rectangle visualizer(#1,#2,#3) {
- \pgfooset{attribute 1}{#1}
- \pgfooset{attribute 2}{#2}
- \pgfooset{use path attribute}{#3}
+ \method rectangle visualizer(#1) {
+ \pgfooset{name}{#1}
}
% Method
\method default connects() {
\pgfoothis.get handle(\pgf@dv@me)
\pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,visualize,visualize datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
}
-
+
+ % Slot
+ \method phase(#1) {%
+ \ifx#1\pgfdvbeginsurvey%
+ \pgfooeset{a1}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 1}}
+ \pgfooeset{a2}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 2}}
+ \pgfkeyssetvalue{\pgfoovalueof{a1}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}}
+ \pgfkeyssetvalue{\pgfoovalueof{a2}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}}
+ \fi%
+ }
+
% Slot
\method visualize() {
{
- \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 1}/min}\pgf@dv@amin
- \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 1}/max}\pgf@dv@amax
- \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 2}/min}\pgf@dv@bmin
- \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 2}/max}\pgf@dv@bmax
+ \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer%
+ \pgfooget{name}\pgf@temp%
+ \ifx\pgf@temp\pgf@dv@visualizer%
+ \pgf@dv@rect@do
+ \fi
+ }
+ }
+
+ \def\pgf@dv@rect@do{
+ \pgfkeysgetvalue{\pgfoovalueof{a1}/min}\pgf@dv@amin
\ifx\pgf@dv@amin\relax\else\ifx\pgf@dv@amin\pgfutil@empty\else
- \ifx\pgf@dv@bmin\relax\else\ifx\pgf@dv@bmin\pgfutil@empty\else
+ \pgfkeysgetvalue{\pgfoovalueof{a1}/max}\pgf@dv@amax
\ifx\pgf@dv@amax\relax\else\ifx\pgf@dv@amax\pgfutil@empty\else
+ \pgfkeysgetvalue{\pgfoovalueof{a2}/min}\pgf@dv@bmin
+ \ifx\pgf@dv@bmin\relax\else\ifx\pgf@dv@bmin\pgfutil@empty\else
+ \pgfkeysgetvalue{\pgfoovalueof{a2}/max}\pgf@dv@bmax
\ifx\pgf@dv@bmax\relax\else\ifx\pgf@dv@bmax\pgfutil@empty\else
- \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amin}
- \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmin}
- \pgfpathdvmoveto
- \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmax}
- \pgfpathdvlineto
- \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amax}
- \pgfpathdvlineto
- \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmin}
- \pgfpathdvlineto
- \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amin}
- \pgfpathdvlineto
- \pgfpathclose
- \pgfkeysvalueof{/data point/\pgfoovalueof{use path attribute}}
+ \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin}
+ \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin}
+ \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin}
+ \pgfpathdvmoveto
+ \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmax}
+ \pgfpathdvlineto
+ \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amax}
+ \pgfpathdvlineto
+ \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin}
+ \pgfpathdvlineto
+ \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin}
+ \pgfpathdvlineto
+ \pgfpathclose
+ \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end}
\fi\fi
\fi\fi
\fi\fi
\fi\fi
- }
}
}
@@ -2253,10 +2422,7 @@
%
\method label visualizer(#1,#2,#3,#4) {
\pgfooset{attribute}{#1}
- \ifx#2\pgfutil@empty
- \else
- \pgfdvmathenter{\pgf@temp}{#2}
- \fi
+ \expandafter\pgfdvmathenter\expandafter{\expandafter\pgf@temp\expandafter}\expandafter{#2}
\pgfoolet{threshold}\pgf@temp
\pgfooset{code}{#3}
\pgfooset{filter}{#4}
@@ -2532,6 +2698,10 @@
}
% Method
+ \method default connects() {
+ }
+
+ % Method
\method add entry(#1) {
\pgfooappend{entries}{{#1}}
\c@pgf@counta=\pgfoovalueof{number of entries}\relax%
@@ -2795,6 +2965,12 @@
\method set max(#1) {
\pgfooset{max}{#1}
}
+ \method let min(#1) {
+ \pgfoolet{min}{#1}
+ }
+ \method let max(#1) {
+ \pgfoolet{max}{#1}
+ }
% Getter
%
@@ -2835,16 +3011,9 @@
% present or that have a certain property. By default, for every
% data point a counter is incremented and the value of this counter
% is stored in an attribute. You can also specify an increment for
- % the counter and some action that should be taken when the counter
- % reaches zero. You can also specify that certain data points should
+ % the counter. You can specify that certain data points should
% not have an effect on the counter.
- %
- % Counters can serve different purposes.
- %
- % 1. For plotting points in a table or sequence, the counter can be
- % used to provide the position along one axis.
- % 2. By using the counter as a repetitive count down one can for
- % instance have only every 10th data point be marked.
+
\attribute attribute;
% The attribute that will be set to the current value of the counter
@@ -2852,6 +3021,9 @@
\attribute val=0;
% The current value of the counter
+ \attribute max=0;
+ % The current value of the counter
+
\attribute step=1;
% The stepping by which the counter is incremented for each
% datapoint
@@ -2880,6 +3052,11 @@
\pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
}
+ % Getter
+ \method get max(#1) {
+ \pgfooget{max}{#1}
+ }
+
% Setter
\method set value(#1) {
\pgfooset{val}{#1}
@@ -2889,6 +3066,7 @@
% Setter
\method set start value(#1) {
\pgfooset{start val}{#1}
+ \pgfooset{max}{#1}
}
% Setter
@@ -2909,6 +3087,11 @@
\pgfmathparse{\pgfoovalueof{val}+\pgfoovalueof{step}}%
\pgfoolet{val}\pgfmathresult%
\pgfkeyslet{/data point/\pgfoovalueof{attribute}}\pgfmathresult%
+ \ifdim\pgfmathresult pt>\pgfoovalueof{max}pt\relax%
+ \pgfoolet{max}\pgfmathresult%
+ \fi%
+ \pgfooget{max}\pgfmathresult%
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/max}\pgfmathresult%
\fi%
}