% Copyright 2008 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Public License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.

\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex,v 1.31 2010/09/15 22:27:36 tantau Exp $

\usepgfmodule{datavisualization}
\usetikzlibrary{backgrounds}


\tikzset{/tikz/data visualization/.is family,
  /tikz/data visualization/.unknown/.code={
    \let\tikz@dv@key\pgfkeyscurrentname% 
    \pgfkeys{/tikz/\tikz@dv@key/.try={#1}}%
    \ifpgfkeyssuccess%
    \else%
      \pgfkeys{/errors/unknown key={/tikz/data visualization/\tikz@dv@key}{#1}}%
    \fi%
  },
  /tikz/data visualization/data/.unknown/.code={%
    % Redirect to /pgf/data
    \let\tikz@dv@key\pgfkeyscurrentname% 
    \pgfkeys{/pgf/data/\tikz@dv@key/.try={#1}}%
    \ifpgfkeyssuccess%
    \else%
      \pgfkeys{/errors/unknown key={/pgf/data/\tikz@dv@key}{#1}}%
    \fi%
  }
}

\def\tikzdatavisualizationset{\pgfqkeys{/tikz/data visualization}}




% The main \datavisualization command
%
% This command must, as always, be given inside a tikz picture. It
% will add a data visualization to the picture; use "shift" option and
% friends to place the data visualization somewhere other than at the
% origin.
%
% The \datavisualization is followed by a sequence of blocks and ended
% with a semicolon. Each block may be one of the following:
%
% "data" blocks.
%
%   Syntax: data [options]                  % options specify an external source
%   Syntax: data [options] { inline data }  
%
%   The optional arguments may either specify an
%   external data source or the data may follow inline.
%
%   The options are executed for the path /pgf/data. The style
%   /tikz/every data is executed for each data, which can be useful to
%   generally set, say, a certain data format.
%
% "info" blocks.
%
%   Syntax: info [options] {code}
%
%   A block starting with "info" may contain any code. It
%   will be executed after the visualization. In order to execute code
%   at some other time (like, say, before the visualization), use
%   options like "before visualization".
%
% Options blocks.
%
%   Syntax: [options]
%
%   The options will be executed immediately.
%
% Scope blocks.
%
%   Syntax: scope[options] { blocks }
%
%   The blocks are executed inside a scope for which the options are
%   set. This can be used to group data blocks.
%
% Examples:
%
% \datavisualization[schoolbook plot]
%   data [source=my_data_file.csv]
% ;
%
%  \datavisualization[schoolbook plot]
%    data [format=key value pairs]
%    {
%      x=0, y=0
%      x=1, y=1
%      x=2, y=4
%      x=3, y=9
%    };
%
%  \datavisualization[schoolbook plot]
%    data [format=function]
%    {
%      var x: interval [0:3];
%      func y = \value x*\value x;
%    }
%    [before visualization={
%      \fill [black!10] (visualization cs:x=0,y=0) -- (visualization cs:x=3,y=9);
%    }]
%    info[red]
%    {
%      \draw (visualization cs:x=0,y=0) -- (visualization cs:x=3,y=9);
%    };
%
%  \datavisualization[schoolbook plot]
%    data [/data point/label=first experiment,source=file_1]
%    data [/data point/label=second experiment,source=file_2]
%    data [/data point/label=third experiment,source=file_3]
%    data [/data point/label=prediction,format=function]
%      { var x: interval [0,1]; func y = rand(\value x); }
%    ;

\def\tikz@lib@datavisualization{
  \begingroup%
    % Ok, first, start a new data visualization
    \pgfoonew \tikz@main@dv=new data visualization()%
    % Next, create a scope for the dv
    \pgfset{local bounding box=data visualization bounding box}%
    % Clear the axis list
    \pgfkeyslet{/tikz/data visualization/axes list}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/axes actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/label actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/legend actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/grid actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/major grid actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/minor grid actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/subminor grid actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/ticks actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/major ticks actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/minor ticks actions}\pgfutil@empty%
    \pgfkeyslet{/tikz/data visualization/subminor ticks actions}\pgfutil@empty%
    \tikz@main@dv.before visualization(%
    )%
    \tikz@main@dv.after visualization(%
      \pgfkeysvalueof{/tikz/data visualization/grid actions}
      \pgfkeysvalueof{/tikz/data visualization/subminor grid actions}
      \pgfkeysvalueof{/tikz/data visualization/minor grid actions}
      \pgfkeysvalueof{/tikz/data visualization/major grid actions}
      \pgfkeysvalueof{/tikz/data visualization/ticks actions}
      \pgfkeysvalueof{/tikz/data visualization/subminor ticks actions}
      \pgfkeysvalueof{/tikz/data visualization/minor ticks actions}
      \pgfkeysvalueof{/tikz/data visualization/major ticks actions}
      \pgfkeysvalueof{/tikz/data visualization/axes actions}
      \pgfkeysvalueof{/tikz/data visualization/label actions}
      \pgfkeysvalueof{/tikz/data visualization/legend actions}
    )%
    %
    \pgfset{/pgf/data/continue code=\tikz@lib@dv@parse@loop}%
    % Now enter parse loop
    \tikz@lib@dv@parse@loop
}

\def\tikz@lib@dv@parse@loop{%  
  \pgfutil@ifnextchar d\tikz@lib@dv@handle@data{%
    \pgfutil@ifnextchar ;\tikz@lib@dv@parse@end{%
      \pgfutil@ifnextchar \par\tikz@lib@dv@handle@par{%
        \pgfutil@ifnextchar s\tikz@lib@dv@handle@beginscope{%
          \pgfutil@ifnextchar i\tikz@lib@dv@handle@info{%
            \pgfutil@ifnextchar [\tikz@lib@dv@handle@options{%
              \pgfutil@ifnextchar \egroup\tikz@lib@dv@handle@endscope{%
                \PackageError{tikz}{Semicolon expected}{}%
                \endgroup%
              }%
            }%
          }%
        }%
      }%
    }%
  }%
}
\def\tikz@lib@dv@parse@end{%
    % Go!
    \tikz@main@dv.survey()%
    \tikz@main@dv.visualize()%
  \endgroup%
}
\def\tikz@lib@dv@handle@par\par{\tikz@lib@dv@parse@loop}

\def\tikz@lib@dv@handle@options[#1]{%
  \tikzdatavisualizationset{#1}%
  \tikz@lib@dv@parse@loop%
}

\def\tikz@lib@dv@handle@beginscope scope{%
  \begingroup%
    \pgfutil@ifnextchar[\tikz@lib@dv@beg@opt{\tikz@lib@dv@beg@opt[]}%}
}
\def\tikz@lib@dv@beg@opt[#1]{%
  \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}%
  \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\begingroup\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}}})%
  \pgfutil@ifnextchar\bgroup{
    \afterassignment\tikz@lib@dv@parse@loop%
    \let\tikz@dummy=%get rid of \bgroup
  }{%
    \PackageError{pgf}{Opening brace expected}{}%
  }%
}
\def\tikz@lib@dv@handle@endscope{%
    \pgfkeysvalueof{/pgf/data visualization/obj}.add data(\endgroup)%
  \endgroup%
  \afterassignment\tikz@lib@dv@parse@loop%
  \let\tikz@dummy=%get rid of \egroup
}

\def\tikz@lib@dv@handle@data data{\pgfdata}

\def\tikz@lib@dv@handle@info info{
  \pgfutil@ifnextchar[{\tikz@lib@dv@handle@info@block@opt}{\tikz@lib@dv@handle@info@block@opt[]}}%}
\def\tikz@lib@dv@handle@info@block@opt[#1]#2{%
  \tikz@main@dv.after visualization({{\scope[#1]#2\endscope}})%
  \tikz@lib@dv@parse@loop
}


\pgfset{/pgf/every data/.style={/tikz/every data/.try,/tikz/data visualization/every data/.try}}


%
% Performing before/after stuff via keys
% 

\tikzdatavisualizationset{
  before survey/.code=\tikz@main@dv.before survey({{#1}}),
  after survey/.code=\tikz@main@dv.after survey({{#1}}),
  before visualization/.code=\tikz@main@dv.before visualization({{#1}}),
  after visualization/.code=\tikz@main@dv.after visualization({{#1}}),
  at start survey/.code=\tikz@main@dv.at start survey({{#1}}),
  at end survey/.code=\tikz@main@dv.at end survey({{#1}}),
  at start visualization/.code=\tikz@main@dv.at start visualization({{#1}}),
  at end visualization/.code=\tikz@main@dv.at end visualization({{#1}}),
}



%
% Object setup 
%

% The following key is used to create objects for the rendering
% pipeline. They cannot be created "directly" because when it is known
% that the objects needs to be created, in principle, many keys may
% not yet be known.
%
% The following options are used:
%
% store           = key that will store the object (handle)
% class           = class of the object
% arg1            = argument1 of the constructor
% ...
% arg8            = argument8 of the constructor
% when            = specifies when the object will be created. Defaults to
%                   "before survey", other possible values are "after survey" and
%                   "before/after visualization"
% before creation = code to be executed just before the object is
%                   created
% after creation  = code to be executed just after the object has been created
%
% The following styles may be useful:
%
% arg1 from key        = use the contents of the given key as arg1. Similar
%                        for other args          
% arg1 handle from key = the contents of the given key should contain
%                        an object. Then arg1 will be a handle to this
%                        object. Similar for other args          

\tikzdatavisualizationset{%
  new object/.code={%
    \def\tikz@dv@grabbed@when{before survey}%
    \let\tikz@dv@grabbed@store\pgfutil@empty
    \pgfkeys{/tikz/data visualization/new object/grab/.cd,#1}%
    \ifx\tikz@dv@grabbed@store\pgfutil@empty
    \else
      \pgfkeyslet{\tikz@dv@grabbed@store}\pgfutil@empty%
    \fi
    \edef\tikz@marshal{\noexpand\tikz@main@dv.\tikz@dv@grabbed@when(\noexpand\tikz@dv@newobject{\tikz@dv@grabbed@store}}%
    \tikz@marshal{#1})%
  },
  new object/grab/store/.store in=\tikz@dv@grabbed@store,
  new object/grab/when/.store in=\tikz@dv@grabbed@when,
  new object/grab/.unknown/.code={},%ignore
}

\def\tikz@dv@newobject#1#2{%
  \def\tikz@dv@new@obj@store{#1}%
  \ifx\tikz@dv@new@obj@store\pgfutil@empty%
    \let\tikz@dv@new@obj=\pgfutil@empty%
  \else%
    \pgfkeysgetvalue\tikz@dv@new@obj@store\tikz@dv@new@obj%
  \fi%
  \ifx\tikz@dv@new@obj\pgfutil@empty
    \let\tikz@dv@arg@a=\tikz@lib@notused%
    \let\tikz@dv@arg@b=\tikz@lib@notused%
    \let\tikz@dv@arg@c=\tikz@lib@notused%
    \let\tikz@dv@arg@d=\tikz@lib@notused%
    \let\tikz@dv@arg@e=\tikz@lib@notused%
    \let\tikz@dv@arg@f=\tikz@lib@notused%
    \let\tikz@dv@arg@g=\tikz@lib@notused%
    \let\tikz@dv@arg@h=\tikz@lib@notused%
    \let\tikz@dv@new@after=\relax%
    \pgfkeys{/tikz/data visualization/new object/parse/.cd,#2}
    \edef\pgf@marshal{\noexpand\pgfoonew\noexpand\tikzdvobj=new \tikz@dv@new@class(}%
    \tikz@dv@add@arg{}\tikz@dv@arg@a%
    \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@b%
    \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@c%
    \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@d%
    \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@e%
    \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@f%
    \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@g%
    \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@h%
    \expandafter\def\expandafter\pgf@marshal\expandafter{\pgf@marshal)}%
    \pgf@marshal%
    \tikzdvobj.default connects()%
    \ifx\tikz@dv@new@obj@store\pgfutil@empty%
    \else%
      \pgfkeyslet\tikz@dv@new@obj@store\tikzdvobj%
    \fi%
    \tikz@dv@new@after%
  \fi
}       
\def\tikz@lib@notused{\tikz@lib@notused}

\def\tikz@dv@add@arg#1#2{%
  \ifx#2\tikz@lib@notused%
  \else%
    \expandafter\expandafter\expandafter\def%
    \expandafter\expandafter\expandafter\pgf@marshal%
    \expandafter\expandafter\expandafter{\expandafter\pgf@marshal#1#2}%
  \fi%
}

\tikzdatavisualizationset{%
  new object/parse/.cd,
  store/.code=,% ignore
  when/.code=,% ignore
  class/.store in=\tikz@dv@new@class,
  before creation/.code=#1,
  after creation/.store in=\tikz@dv@new@after,
  arg1/.store in=\tikz@dv@arg@a,
  arg2/.store in=\tikz@dv@arg@b,
  arg3/.store in=\tikz@dv@arg@c,
  arg4/.store in=\tikz@dv@arg@d,
  arg5/.store in=\tikz@dv@arg@e,
  arg6/.store in=\tikz@dv@arg@f,
  arg7/.store in=\tikz@dv@arg@g,
  arg8/.store in=\tikz@dv@arg@h,
  arg1 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@a},
  arg2 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@b},
  arg3 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@c},
  arg4 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@d},
  arg5 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@e},
  arg6 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@f},
  arg7 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@g},
  arg8 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@h}
  arg1 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@a}{\tikz@dv@arg@a},
  arg2 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@b}{\tikz@dv@arg@b},
  arg3 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@c}{\tikz@dv@arg@c},
  arg4 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@d}{\tikz@dv@arg@d},
  arg5 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@e}{\tikz@dv@arg@e},
  arg6 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@f}{\tikz@dv@arg@f},
  arg7 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@g}{\tikz@dv@arg@g},
  arg8 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@h}{\tikz@dv@arg@h}
}

\def\tikz@dv@handle@from@key#1#2#3{%
  \pgfkeysvalueof{#1}.get handle(#2)%
  \def#3{#2}%
}




%
% Data visualization coordinate system
%
%
% This cs is used to refer to points in a datavisualization. The
% parameters are keys that are set in the /data point key
% directory. Then, a (virtual) data point is created and the
% calculated position is returned

\tikzdeclarecoordinatesystem{visualization}
{%
  \tikzset{/data point/.cd,#1}%
  \pgfpointdvlocaldatapoint%
}




%
%
% Axes
%
%



%
% Axis base
%

\tikzdatavisualizationset{%
  new axis/.style={
    new object={
      class=scaling mapper,
      store=/tikz/data visualization/#1/scaling mapper,
      before creation={
        \pgfkeysgetvalue{/tikz/data visualization/#1/scaling}\tikz@temp
        \ifx\tikz@temp\pgfutil@empty%
          \pgfkeysgetvalue{/tikz/data visualization/#1/scaling/default}\tikz@temp
        \fi
        \expandafter\tikz@dv@lib@parse@scaling\tikz@temp\pgf@stop%
        \pgfkeyslet{/tikz/data visualization/#1/scaling}\tikz@temp
      },
      arg1 from key=/tikz/data visualization/#1/attribute,
      arg2/.expanded=\pgfkeysvalueof{/tikz/data visualization/#1/attribute}/scaled,
      arg3 from key=/tikz/data visualization/#1/scaling,
      arg4 from key=/tikz/data visualization/#1/function
    },
    #1/attribute/.initial=#1,
    #1/function/.initial=,
    #1/scaling/.initial=,
    #1/scaling/default/.initial=0 at 0 and 1 at 1,
    #1/ticks at/.initial=,
    #1/default ticks at/.initial=,
    #1/major ticks/.initial=,
    #1/minor ticks/.initial=,
    #1/subminor ticks/.initial=,
    #1/grid at/.initial=,
    #1/default grid at/.initial=,
    #1/major grid/.initial=,
    #1/minor grid/.initial=,
    #1/subminor grid/.initial=,
    #1/label/.initial=,
    #1/padding min/.initial=,
    #1/padding max/.initial=,
    #1/.code={
      \let\tikz@temp\tikz@dv@axis%
      \def\tikz@dv@axis{/tikz/data visualization/#1}%
      \expandafter\tikz@do@axis@options\expandafter{\tikz@temp}{##1}%
    },
    #1/@compute at positions/.initial=\tikz@lib@dv@compute@at@linear,
    axes list/.append={\tikz@lib@dv@do@axis{#1}}
  },
  all axes/.code={
    \def\tikz@lib@dv@args{#1}%
    \pgfkeysvalueof{/tikz/data visualization/axes list}%
  },
  % General styling
  styling/.style=,
  style/.style={styling/.append style={#1}},
  @node styling/.initial=,
  node styling/.style={%
    /utils/exec={\pgfkeysgetvalue{/tikz/data visualization/@node styling}\tikz@temp\expandafter\tikzset\expandafter{\tikz@temp}}},
  node style/.style={/tikz/data visualization/@node styling/.append={,#1}},
  grid styling/.style=,
  grid style/.style={grid styling/.append style={#1}},
  % General extends (both axes, grid and ticks)
  low/.initial=0,
  high/.initial=0,
  padded/.style={low=padded min,high=padded max},
  tick length/.style={low={-#1},high={#1}},
  % General tick and grid keys:
  common/.initial=,
  major/.initial=,
  minor/.initial=,
  subminor/.initial=,
  @setup at setters/.style={
    common/.code=\tikz@lib@dv@add@{common}{##1},
    major/.code=\tikz@lib@dv@add@{major}{##1},
    minor/.code=\tikz@lib@dv@add@{minor}{##1},
    subminor/.code=\tikz@lib@dv@add@{subminor}{##1}
  },
  @setup at setters,
  % Tick keys
  direction axis/.initial=,
  value/.initial=,
  pos/.initial=,
  tick text at low/.is if=tikz@dv@min@tick@node,
  tick text at high/.is if=tikz@dv@max@tick@node,
  no tick text/.style={tick text at low=false,tick text at high=false},
  every major ticks/.style={style={line cap=round},tick length=2pt},
  every minor ticks/.style={style={help lines,thin,line cap=round},tick length=1.4pt},
  every subminor ticks/.style={style={help lines,line cap=round},tick length=0.8pt},
  clean ticks/.style={node style={fill=white}},
  % Default grid styles
  grid style={high=max,low=min},
  every major grid/.style={style={help lines,thin,black!25}},
  every minor grid/.style={style={help lines,black!25}},
  every subminor grid/.style={style={help lines,black!10}},
  at default ticks/.code={%
    \expandafter\pgfkeysalso\expandafter{\tikz@lib@dv@ticks@default@at}},
  at ticks/.code={%
    \expandafter\pgfkeysalso\expandafter{\tikz@lib@dv@ticks@default@at}%
    \expandafter\pgfkeysalso\expandafter{\tikz@lib@dv@ticks@at}},
}

\def\tikz@lib@dv@add@#1#2{\pgfkeysaddvalue{/tikz/data visualization/#1}{}{,#2}}

\def\tikz@dv@lib@parse@scaling#1 at#2and #3 at#4\pgf@stop{%
  \pgfmathsetmacro{\tikz@dv@lib@min@at}{#2}
  \pgfmathsetmacro{\tikz@dv@lib@max@at}{#4}
  \edef\tikz@temp{#1 at \tikz@dv@lib@min@at and #3 at \tikz@dv@lib@max@at}%
}


% Ticks at
\tikzdatavisualizationset{
  at/.code={\def\tikz@dv@at@list{#1}},
  also at/.code={\expandafter\def\expandafter\tikz@dv@at@list\expandafter{\tikz@dv@at@list,{#1}}},
  major at/.style={major={at={#1}}},
  minor at/.style={minor={at={#1}}},
  subminor at/.style={subminor={at={#1}}},
  major also at/.style={major={also at={#1}}},
  minor also at/.style={minor={also at={#1}}},
  subminor also at/.style={subminor={also at={#1}}},
  options at/.code={\expandafter\def\expandafter\tikz@dv@style@at@list\expandafter{\tikz@dv@style@at@list,{#1}}},
  no tick text at/.style={options at={#1 as [no tick text]}}
}


\def\tikz@lib@dv@do@axis#1{%
  \def\tikz@marshal{#1=}
  \expandafter\expandafter\expandafter\tikzdatavisualizationset%
  \expandafter\expandafter\expandafter{\expandafter\tikz@marshal\expandafter{\tikz@lib@dv@args}}
}

\def\tikz@do@axis@options#1#2{
  \pgfkeys{/tikz/data visualization/axis options/.cd,#2}
  \def\tikz@dv@axis{#1}
}
\let\tikz@dv@axis\pgfutil@empty

\tikzdatavisualizationset{
  every ticks/.style={
    node style={%
      font=\pgfutil@font@footnotesize,
      inner sep=1pt,
      outer sep=.1666em,
      rounded corners=1.5pt
    }
  },
  every visualizer label/.style={
    every ticks,
    node style={
      font=\pgfutil@font@small
    }
  },
  @color of visualizer labels/.style={text=black},
  every visualizer legend label/.style={
    node style={
      fill=none
    }
  },
  every axis label/.style={
    node style={%
      font=\pgfutil@font@small
    }
  }
}


\tikzset{
  /tikz/data visualization/axis options/.cd,
  %
  % Basic setters
  %
  attribute/.style={\tikz@dv@axis/attribute={#1}},
  function/.style={\tikz@dv@axis/function={#1}},
  scaling/.style={\tikz@dv@axis/scaling={#1}},
  padding min/.style={\tikz@dv@axis/padding min={#1}},
  padding max/.style={\tikz@dv@axis/padding max={#1}},
  padding/.style={padding min={-#1},padding max={#1}},
  label/.style={\tikz@dv@axis/label={#1}},
  %
  % Strategies
  %
  tick placement strategy/.style={\tikz@dv@axis/@compute at positions={#1}},
  linear steps/.style={tick placement strategy=\tikz@lib@dv@compute@at@linear},
  %
  % Attribute setter
  %
  goto/.code={\tikz@dv@goto{\tikz@dv@axis}{#1}},
  % 
  % Modification of the range 
  %
  include values/.style={%
    /tikz/data visualization/before survey/.expanded={%
      \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper%
      \noexpand\foreach \noexpand\tikz@lib@dv@temp in {#1} {%
        \noexpand\tikz@dv@axis@mapper.include in value(\noexpand\tikz@lib@dv@temp)%
      }%
    }%
  },
  %
  % Visualization setters
  %
  visualize axis/.code=\expandafter\tikz@lib@dv@av\expandafter{\tikz@dv@axis}{#1},
  %
  % Ticks settings
  %
  ticks/.style={\tikz@dv@axis/ticks at/.append={,#1}},
  visualize ticks/.code=\expandafter\tikz@lib@dv@tv\expandafter{\tikz@dv@axis}{#1},
  %
  % Grid settings
  %
  grid/.style={\tikz@dv@axis/grid at/.append={,#1}},
  grid/.default=at default ticks,
  visualize grid/.code=\expandafter\tikz@lib@dv@gv\expandafter{\tikz@dv@axis}{#1},
  % 
  % Visualizing axis labels
  % 
  visualize label/.code=\expandafter\tikz@lib@dv@lv\expandafter{\tikz@dv@axis}{#1},
}


% Layer options
\tikzdatavisualizationset{
  axis layer/.style=on background layer,
  ticks layer/.style=on background layer,
  ticks node layer/.style=,
  grid layer/.style=on background layer,
}


% Axis visualization
%
% #1 = name of the to-be-visualized axis name
% #2 = options for the visualization

\def\tikz@lib@dv@av#1#2{
  \tikzdatavisualizationset{
    axes actions/.append={\tikz@lib@dv@show@axis{#1}{#2}}
  }
}

\def\tikz@lib@dv@show@axis#1#2{%
  \scope[data visualization/axis layer,/tikz/data visualization/.cd,low=min,high=max,every axis/.try,#2]
    \pgfkeysgetvalue{#1/scaling mapper}\tikz@dv@axis@mapper
    % Ok, calculate direction vector:
    \tikzpointandanchordirection{\tikz@dv@axis@mapper.set in to(min)}{\tikz@dv@axis@mapper.set in to(max)}
    \xdef\tikz@dv@axis@dir{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
    \path[draw,/tikz/data visualization/styling]
    \pgfextra{
      {
        \tikz@dv@goto{#1}{\pgfkeysvalueof{/tikz/data visualization/low}}%
        \pgfpathdvmoveto%
      }
      {
        \tikz@dv@goto{#1}{\pgfkeysvalueof{/tikz/data visualization/high}}%
        \pgfpathdvlineto%
      }
    };
  \endscope
}

\def\tikz@dv@goto#1#2{%
  \edef\pgf@temp{#2}%
  \ifx\pgf@temp\tikz@lib@dv@padded@min@text%
    \pgfkeysvalueof{#1/scaling mapper}.set in to(min)%
    \pgfkeysvalueof{#1/scaling mapper}.get out()%
    \pgfkeysgetvalue{#1/padding min}\pgf@temp%
    \pgfmathparse{\pgf@temp}%
    \pgfkeyslet{/data point/\pgfdvout/offset}\pgfmathresult%
  \else%
    \ifx\pgf@temp\tikz@lib@dv@padded@max@text%
      \pgfkeysvalueof{#1/scaling mapper}.set in to(max)%
      \pgfkeysvalueof{#1/scaling mapper}.get out()%
      \pgfkeysgetvalue{#1/padding max}\pgf@temp%
      \pgfmathparse{\pgf@temp}%
      \pgfkeyslet{/data point/\pgfdvout/offset}\pgfmathresult%
    \else%
      \pgfkeysvalueof{#1/scaling mapper}.set in to(#2)%
    \fi%
  \fi%
}       

\def\tikz@lib@dv@padded@min@text{padded min}
\def\tikz@lib@dv@padded@max@text{padded max}

% Ticks visualization 
%
% #1 = name of axis on which ticks should be shown
% #2 = options for the visualization

\def\tikz@lib@dv@tv#1#2{
  \tikzdatavisualizationset{
    ticks actions/.append={\tikz@lib@dv@default@action{ticks}{#1}{#2}},
    major ticks actions/.append={\tikz@lib@dv@show@ticks{major}{#1}{#2}},
    minor ticks actions/.append={\tikz@lib@dv@show@ticks{minor}{#1}{#2}},
    subminor ticks actions/.append={\tikz@lib@dv@show@ticks{subminor}{#1}{#2}}
  }
}

\def\tikz@lib@dv@default@action#1#2#3{%
  \let\tikz@marshal\pgfutil@empty%
  {%
    \let\tikz@lib@dv@ticks@at\pgfutil@empty%
    \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@ticks@default@at%
    \pgfkeysgetvalue{#2/#1 at}\tikz@lib@dv@settings%
    \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper
    % Normal minor etc. have no effect.
    \tikzdatavisualizationset{major/.code=,minor/.code=,subminor/.code=,common/.code=}
    \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}%
    \tikzdatavisualizationset{@setup at setters}%
    \pgfkeysgetvalue{/tikz/data visualization/compute step}\tikz@temp@step%
    \ifx\tikz@temp@step\pgfutil@empty%
    % do nothing
    \else%
      \pgfkeysvalueof{#2/@compute at positions}%
      \xdef\tikz@marshal{
        major={\pgfkeysvalueof{/tikz/data visualization/major}},
        minor={\pgfkeysvalueof{/tikz/data visualization/minor}},
        subminor={\pgfkeysvalueof{/tikz/data visualization/subminor}}}
    \fi
  }%
  \pgfkeyslet{#2/default #1 at}\tikz@marshal
}

\def\tikz@lib@dv@show@ticks#1#2#3{%
  % First, check whether there is anything to do at all:
  \pgfkeysgetvalue{#2/default ticks at}\tikz@lib@dv@default@settings%
  \ifx\tikz@lib@dv@default@settings\pgfutil@empty%
    \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@settings%
  \else%
    \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@settings%
    \expandafter\expandafter\expandafter\def%
    \expandafter\expandafter\expandafter\tikz@lib@dv@settings%
    \expandafter\expandafter\expandafter{\expandafter\tikz@lib@dv@default@settings\expandafter,\tikz@lib@dv@settings}
  \fi%
  \ifx\tikz@lib@dv@settings\pgfutil@empty%
    % Great, nothing to do
  \else
    {%
      \let\tikz@dv@at@list\pgfutil@empty%
      \let\tikz@dv@style@at@list\pgfutil@empty%
      \scope[/tikz/data visualization/.cd,every ticks/.try,every #1 ticks/.try,#3]%
        % Setup options
        \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper
        \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}%
        \pgfkeysgetvalue{/tikz/data visualization/common}\tikz@temp
        \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp}
        \pgfkeysgetvalue{/tikz/data visualization/#1}\tikz@temp
        \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp}
        \pgfkeysgetvalue{/tikz/data visualization/\pgfkeysvalueof{/tikz/data visualization/direction axis}/scaling mapper}\pgf@dv@tick@dir@mapper
        % Ok, now it's time to draw the ticks!
        \foreach \tikz@dv@tick@pos in \tikz@dv@at@list 
        {
          \ifx\tikz@dv@tick@pos\pgfutil@empty
          \else
            \expandafter\tikz@lib@dv@parse\tikz@dv@tick@pos\pgf@stop%
            \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@tick@opt}%
            \tikz@lib@dv@mapper.set in to(\tikz@dv@tick@pos)%
            % First, compute position of tick:
            \pgf@process{\pgfpointdvlocaldatapoint}
            \xdef\pgf@dv@tick@origin{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
            % Ok, calculate direction vector:
            \tikzpointandanchordirection{\pgf@dv@tick@dir@mapper.set in to(min)}{\pgf@dv@tick@dir@mapper.set in to(max)}
            \xdef\pgf@dv@tick@dir{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
            % Now, show something:
            \tikz@lib@handle@at@style%
            \scope[/tikz/data visualization/styling]
              \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\pgfkeysvalueof{/tikz/data visualization/high}}{\pgf@dv@tick@dir}}}
              \xdef\tikz@dv@max@tick{\the\pgf@x,\the\pgf@y}
              \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\pgfkeysvalueof{/tikz/data visualization/low}}{\pgf@dv@tick@dir}}}
              \xdef\tikz@dv@min@tick{\the\pgf@x,\the\pgf@y}
              \scope[data visualization/ticks layer] \draw (\tikz@dv@min@tick) -- (\tikz@dv@max@tick); \endscope
              \iftikz@dv@min@tick@node \scope[data visualization/ticks node layer] \path (\tikz@dv@min@tick) \tikz@dv@handle@tick{\tikz@dv@min@anchor}; \endscope \fi
              \iftikz@dv@max@tick@node \scope[data visualization/ticks node layer] \path (\tikz@dv@max@tick) \tikz@dv@handle@tick{\tikz@dv@max@anchor}; \endscope\fi
            \endscope
          \fi      
        }
      \endscope
    }
  \fi
}

\def\tikz@lib@dv@parse#1\pgf@stop{%
  \pgfutil@in@{as}{#1}%
  \ifpgfutil@in@%
    \tikz@lib@dv@parse@as#1\pgf@stop% 
  \else%
    \tikz@lib@dv@parse@as#1as\tikz@lib@dv@typeset\pgf@stop%
  \fi%
}
\def\tikz@lib@dv@parse@as#1as{%
  \def\tikz@dv@tick@pos{#1}%
  \pgfutil@ifnextchar[{\tikz@lib@dv@parse@as@opt}{\tikz@lib@dv@parse@as@opt[]}%]
}
\def\tikz@lib@dv@parse@as@opt[#1]{%
  \def\tikz@lib@dv@tick@opt{#1}%
  \pgfutil@ifnextchar\pgf@stop{\tikz@lib@dv@parse@as@text\tikz@lib@dv@typeset}{\tikz@lib@dv@parse@as@text}
}
\def\tikz@lib@dv@parse@as@text#1\pgf@stop{%
  \def\tikz@lib@dv@tick@text{#1}%
}

\def\tikz@lib@dv@typeset{%
  \pgfdvmathenter{\tikz@lib@dv@typesetnum}{\tikz@dv@tick@pos}%
  \pgfdvmathexitbyscientificformat{\tikz@lib@dv@typesetnum}{\tikz@lib@dv@typesetnum}% hmm... not sure about this...
  \pgfkeysvalueof{/tikz/data visualization/tick prefix}%
  \pgfkeysvalueof{/tikz/data visualization/tick typesetter}{\tikz@lib@dv@typesetnum}%
  \pgfkeysvalueof{/tikz/data visualization/tick suffix}%
}

\newif\iftikz@dv@min@tick@node
\newif\iftikz@dv@max@tick@node

\def\tikz@dv@handle@tick#1{%
  \pgfextra{
    \ifx\tikz@lib@dv@tick@text\pgfutil@empty%
      \global\let\tikz@dv@tick@marshal=\pgfutil@empty% Skip!
    \else
      \def\tikz@dv@tick@marshal{node[anchor=#1,/tikz/data visualization/node styling]}%
      \expandafter\pgfutil@g@addto@macro\expandafter\tikz@dv@tick@marshal\expandafter{\expandafter{\tikz@lib@dv@tick@text}}
    \fi
  \expandafter}%
  \tikz@dv@tick@marshal
}       


\def\tikz@lib@handle@at@style{%
  \ifx\tikz@dv@style@at@list\pgfutil@empty% nothing to do
  \else%
    \let\tikz@dv@lib@this@at@style=\pgfutil@empty%
    \pgfdvmathenter{\tikz@temp}{\tikz@dv@tick@pos}%
    \pgfdvmathexitbyscientificformat{\tikz@dv@compare@to}{\tikz@temp}%
    \foreach \tikz@dv@at@style in \tikz@dv@style@at@list {%
      \ifx\tikz@dv@at@style\pgfutil@empty%
      \else%
        \expandafter\tikz@dv@lib@handle@one@at@style\tikz@dv@at@style\tikz@stop%
      \fi%
    }
    \ifx\tikz@dv@lib@this@at@style\pgfutil@empty%
    \else%
      \expandafter\tikzdatavisualizationset\expandafter{\tikz@dv@lib@this@at@style}%
    \fi%
  \fi%
}

\def\tikz@dv@lib@handle@one@at@style#1as#2[#3]#4\tikz@stop{%
  \pgfdvmathenter{\tikz@lib@dv@at@math@var}{#1}%
  \pgfdvmathexitbyscientificformat{\tikz@dv@temp}{\tikz@lib@dv@at@math@var}%
  \ifx\tikz@dv@temp\tikz@dv@compare@to%
    % Bingo!
    \expandafter\gdef\expandafter\tikz@dv@lib@this@at@style\expandafter{\tikz@dv@lib@this@at@style,#3}%
  \fi%
}


% Help function
\def\tikzpointandanchordirection#1#2{%
  % This function works like pgfpointdvdirection, but also computes
  % appriate "min" and "max" anchors.
  \pgf@process{\pgfpointdvdirection{#1}{#2}}
  {
    \pgf@ya=\pgf@y
    \pgf@y=-\pgf@x
    \pgf@x=\pgf@ya
    \tikz@auto@anchor
    \xdef\tikz@dv@max@anchor{\tikz@anchor}
    \tikz@auto@anchor@prime
    \xdef\tikz@dv@min@anchor{\tikz@anchor}
  }
}




% Grid visualization 
%
% #1 = name of axis on which grid lines should be shown
% #2 = options for the visualization

\def\tikz@lib@dv@gv#1#2{
  \tikzdatavisualizationset{
    grid actions/.append={\tikz@lib@dv@default@action{grid}{#1}{#2}},
    major grid actions/.append={\tikz@lib@dv@show@grid{major}{#1}{#2}},
    minor grid actions/.append={\tikz@lib@dv@show@grid{minor}{#1}{#2}},
    subminor grid actions/.append={\tikz@lib@dv@show@grid{subminor}{#1}{#2}},
  }
}

\def\tikz@lib@dv@show@grid#1#2#3{%
  % First, check whether there is anything to do at all:
  \pgfkeysgetvalue{#2/default grid at}\tikz@lib@dv@default@settings%
  \ifx\tikz@lib@dv@default@settings\pgfutil@empty%
    \pgfkeysgetvalue{#2/grid at}\tikz@lib@dv@settings%
  \else%
    \pgfkeysgetvalue{#2/grid at}\tikz@lib@dv@settings%
    \expandafter\expandafter\expandafter\def%
    \expandafter\expandafter\expandafter\tikz@lib@dv@settings%
    \expandafter\expandafter\expandafter{\expandafter\tikz@lib@dv@default@settings\expandafter,\tikz@lib@dv@settings}
  \fi%
  \ifx\tikz@lib@dv@settings\pgfutil@empty%
    % Great, nothing to do
  \else
    {%
      \let\tikz@dv@at@list\pgfutil@empty
      \let\tikz@dv@style@at@list\pgfutil@empty
      \scope[data visualization/grid layer,/tikz/data visualization/.cd,every #1 grid/.try,grid styling,grid styling/.style=,#3]
        % Setup options
        \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper
        \let\tikz@lib@dv@ticks@default@at\pgfutil@empty%
        \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@ticks@at%
        \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}%
        \pgfkeysgetvalue{/tikz/data visualization/common}\tikz@temp
        \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp}
        \pgfkeysgetvalue{/tikz/data visualization/#1}\tikz@temp
        \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp}
        \edef\tikz@lib@dv@dir@axis{/tikz/data visualization/\pgfkeysvalueof{/tikz/data visualization/direction axis}}%
        % Ok, now it's time to draw the grid!
        \foreach \tikz@dv@grid@pos in \tikz@dv@at@list 
        {
          \ifx\tikz@dv@grid@pos\pgfutil@empty
          \else
            \expandafter\tikz@lib@dv@parse\tikz@dv@grid@pos\pgf@stop%
            \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@tick@opt}%
            \tikzdatavisualizationset{grid styling}%
            \tikz@lib@dv@mapper.set in to(\tikz@dv@tick@pos)%
            \draw[/tikz/data visualization/styling]
              \pgfextra{
                % First, compute start of grid:
                \tikz@dv@goto{\tikz@lib@dv@dir@axis}{\pgfkeysvalueof{/tikz/data visualization/low}}%
                \pgfpathdvmoveto%
                \tikz@dv@goto{\tikz@lib@dv@dir@axis}{\pgfkeysvalueof{/tikz/data visualization/high}}%
                \pgfpathdvlineto%
              };
          \fi
        }
      \endscope
    }
  \fi
}









% 
% Label visualization 
%

\def\tikz@lib@dv@lv#1#2{
  \tikzdatavisualizationset{
    label actions/.append={\tikz@lib@dv@show@label{#1}{#2}}
  }
}

\def\tikz@lib@dv@show@label#1#2{%
  % First, check whether there is anything to do at all:
  \pgfkeysgetvalue{#1/label}\tikz@dv@lib@label%
  \ifx\tikz@dv@lib@label\pgfutil@empty%
    % Great, nothing to do
  \else
    \scope[/tikz/data visualization/.cd,every axis label/.try,#2]
      \pgfkeysgetvalue{/tikz/data visualization/value}\tikz@lib@dv@at%
      \pgfkeysgetvalue{/tikz/data visualization/pos}\tikz@lib@dv@pos%
      \pgfkeysgetvalue{#1/scaling mapper}\tikz@dv@mapper
      \ifx\tikz@lib@dv@pos\pgfutil@empty%
        \ifx\tikz@lib@dv@at\pgfutil@empty%
          % Well, hopefully the node options setup things correctly...
        \else%
          % Special treatment of "min" and "max"
          \ifx\tikz@lib@dv@at\pgf@min@text%
            \tikz@lib@dv@special@at{\tikz@dv@min@anchor}
          \else \ifx\tikz@lib@dv@at\tikz@lib@dv@padded@min@text%
            \tikz@lib@dv@special@at{\tikz@dv@min@anchor}
          \else \ifx\tikz@lib@dv@at\pgf@max@text%
            \tikz@lib@dv@special@at{\tikz@dv@max@anchor}
          \else \ifx\tikz@lib@dv@at\tikz@lib@dv@padded@max@text%
            \tikz@lib@dv@special@at{\tikz@dv@max@anchor}
          \fi\fi\fi\fi%
          \tikz@dv@goto{#1}{\tikz@lib@dv@at}%
          \pgftransformshift{\pgfpointdvlocaldatapoint}%           
        \fi%
      \else%
        \tikz@dv@mapper.set in to(min)%
        \pgftransformshift{\pgfpointscale{1-\tikz@lib@dv@pos}{\pgfpointdvlocaldatapoint}}
        \tikz@dv@mapper.set in to(max)%
        \pgftransformshift{\pgfpointscale{\tikz@lib@dv@pos}{\pgfpointdvlocaldatapoint}}
      \fi
      \expandafter\tikz@lib@dv@parse@node\tikz@dv@lib@label\pgf@stop
    \endscope
  \fi
}
\def\tikz@lib@dv@special@at#1{%
  % Ok, calculate direction vector:
  \tikzpointandanchordirection{\tikz@dv@mapper.set in to(min)}{\tikz@dv@mapper.set in to(max)}
  \tikzset{anchor=#1}
}

\def\tikz@lib@dv@parse@node{\pgfutil@ifnextchar[\tikz@lib@dv@parse@node@opt{\tikz@lib@dv@parse@node@opt[]}}%}
\def\tikz@lib@dv@parse@node@opt[#1]#2\pgf@stop{
  \node [/tikz/data visualization/node styling,#1] {#2};
}



%
% Tick placement strategies
%

\tikzdatavisualizationset{
  compute step/.initial=,
  step/.style={compute step=\def\tikz@lib@dv@step{#1}},
  minor steps between steps/.initial=,
  minor steps between steps/.default=9,
  phase/.initial=0,
  tick typesetter/.initial=\pgfmathprintnumber,
  tick prefix/.initial=,
  tick suffix/.initial=,
  tick unit/.style={tick suffix={#1}},% this is an alias
}

\def\tikz@lib@dv@compute@at@linear{%
  % Setup about:
  \let\tikz@lib@dv@compute@about=\tikz@lib@dv@about@linear%
  \let\tikz@lib@dv@step\relax%
  \pgfkeysvalueof{/tikz/data visualization/compute step}
  \ifx\tikz@lib@dv@step\relax%
  \else%
    % Gather interesting values
    \tikz@lib@dv@mapper.get in range interval()%
    \pgfdvinrangeinterval.get min and max()%
    \pgfkeysgetvalue{/tikz/data visualization/phase}\tikz@temp
    \pgfdvmathenter{\tikz@dv@lib@phase}{\tikz@temp}
    \pgfdvmathenter{\tikz@dv@lib@step}{\tikz@lib@dv@step}
    % Compute start:
    \pgfdvmathsub{\tikz@dv@lib@temp}{\pgfdvmin}{\tikz@dv@lib@phase}% temp = dvmin - phase
    \pgfdvmathdiv{\tikz@dv@lib@temp}{\tikz@dv@lib@temp}{\tikz@dv@lib@step}% temp = temp/step
    \pgfdvmathfloor{\tikz@dv@lib@temp}{\tikz@dv@lib@temp}% temp = floor(temp)
    \pgfdvmathmul{\tikz@lib@dv@current}{\tikz@dv@lib@temp}{\tikz@dv@lib@step}% current = temp*step ...
    \pgfdvmathadd{\tikz@lib@dv@current}{\tikz@lib@dv@current}{\tikz@dv@lib@phase}% + phase
    \let\tikz@lib@dv@ats\pgfutil@empty%
    \let\tikz@lib@dv@minor@ats\pgfutil@empty%
    \tikz@lib@dv@mapper.get function(\tikz@temp)%
    \ifx\tikz@temp\pgfutil@empty%
      \pgfdvmathenter{\tikz@one@hundreth}{0.001}%
      \pgfdvmathsub{\tikz@lib@temp}{\pgfdvmax}{\pgfdvmin}%
      \pgfdvmathmul{\tikz@lib@dv@epsilon}{\tikz@lib@temp}{\tikz@one@hundreth}% epsilon = (max - min)/1000
    \else
      \let\tikz@lib@dv@epsilon\pgfdvmathalwayszero
    \fi
    \pgfdvmathsub{\tikz@lib@dv@min@minus@epsilon}{\pgfdvmin}{\tikz@lib@dv@epsilon}%
    \pgfdvmathadd{\tikz@lib@dv@max@plus@epsilon}{\pgfdvmax}{\tikz@lib@dv@epsilon}%
    \pgfkeysgetvalue{/tikz/data visualization/minor steps between steps}\tikz@lib@dv@substeps%
    \ifx\tikz@lib@dv@substeps\pgfutil@empty
    \else
      \pgfmathsetmacro\tikz@temp{\tikz@lib@dv@substeps+1}%
      \pgfdvmathenter{\tikz@dv@lib@substeps}{\tikz@temp}%
      \pgfdvmathdiv{\tikz@lib@dv@substep}{\tikz@dv@lib@step}{\tikz@dv@lib@substeps}%
    \fi
    \loop%
      \ifx\tikz@lib@dv@substeps\pgfutil@empty%
      \else%
        \let\tikz@lib@dv@subcurrent=\tikz@lib@dv@current%
        \pgfmathsetcount{\c@pgf@counta}{\tikz@lib@dv@substeps}%
        \let\tikz@lib@dv@next=\tikz@lib@dv@subloop%
        \tikz@lib@dv@subloop
      \fi%
      \pgfdvmathifless{\tikz@lib@dv@current}{\tikz@lib@dv@min@minus@epsilon}{}{%
        \pgfdvmathexitbyserializing{\tikz@temp}{\tikz@lib@dv@current}%
        \edef\tikz@lib@dv@ats{\tikz@lib@dv@ats,\tikz@temp}%
      }
      \pgfdvmathadd{\tikz@lib@dv@current}{\tikz@lib@dv@current}{\tikz@dv@lib@step}%
      \pgfdvmathifless{\tikz@lib@dv@current}{\tikz@lib@dv@max@plus@epsilon}{\tikz@lib@dv@continuetrue}{\tikz@lib@dv@continuefalse}%
    \iftikz@lib@dv@continue%
    \repeat%    
    \tikzdatavisualizationset{major/.expanded={at={\tikz@lib@dv@ats}},minor/.expanded={at={\tikz@lib@dv@minor@ats}}}%
  \fi%
}
\newif\iftikz@lib@dv@continue

\def\tikz@lib@dv@subloop{
  \pgfdvmathadd{\tikz@lib@dv@subcurrent}{\tikz@lib@dv@subcurrent}{\tikz@lib@dv@substep}%
  \pgfdvmathifless{\tikz@lib@dv@subcurrent}{\pgfdvmin}{}{%
    \pgfdvmathifless{\tikz@lib@dv@subcurrent}{\pgfdvmax}{%
      \pgfdvmathexitbyserializing{\tikz@temp}{\tikz@lib@dv@subcurrent}%
      \edef\tikz@lib@dv@minor@ats{\tikz@lib@dv@minor@ats,\tikz@temp}
      }{}}
  \advance\c@pgf@counta by-1\relax%
  \ifnum\c@pgf@counta=0\relax%
    \let\tikz@lib@dv@next=\relax
  \fi
  \tikz@lib@dv@next
}



%
% Ticks about settings
% 

\tikzdatavisualizationset{
  about/.style={compute step=\tikz@lib@dv@compute@about{#1}},
  about strategy/.initial=,
  standard about strategy/.style={about strategy={1.5/1.0,2.3/2.0,4/2.5,7/5,11/10}},
  standard about strategy,
  euro about strategy/.style={about strategy={1.5/1.0,3/2.0,7/5,11/10}},
  half about strategy/.style={about strategy={2/1.0,7/5,11/10}},
  quarter about strategy/.style={about strategy={1.8/1.0,4/2.5,7/5,11/10}},
  int about strategy/.style={about strategy={1.5/1.0,2.5/2.0,3.5/3.0,4.5/4.0,7/5,11/10}},
  none/.style={compute step=},
  few/.style={about=3},
  some/.style={about=5},
  many/.style={about=10},
}

\def\tikz@lib@dv@about@linear#1{%
  \tikz@lib@dv@mapper.get in range interval()%
  \pgfdvinrangeinterval.get min and max()%
  \pgfdvmathsub{\tikz@lib@dv@diff}{\pgfdvmax}{\pgfdvmin}
  \pgfdvmathenter{\tikz@lib@dv@about@val}{#1}%
  \pgfdvmathdiv{\tikz@lib@dv@around}{\tikz@lib@dv@diff}{\tikz@lib@dv@about@val}%
  % Make mantisse sensible
  \pgfmathfloattomacro{\tikz@lib@dv@around}{\tikz@lib@dv@flags}{\tikz@lib@dv@mant}{\tikz@lib@dv@exp}
  \pgf@xc=\tikz@lib@dv@mant pt%
  \pgfkeysgetvalue{/tikz/data visualization/about strategy}\tikz@lib@dv@strat
  \foreach \tikz@lib@dv@threshold/\tikz@lib@replace in \tikz@lib@dv@strat
  {
    \ifdim\pgf@xc<\tikz@lib@dv@threshold pt%
      \global\pgf@xc=\tikz@lib@replace pt%
      \breakforeach
    \fi
  }
  \ifdim\pgf@xc<10pt%
    \pgfmathfloatcreate{\tikz@lib@dv@flags}{\pgf@sys@tonumber{\pgf@xc}}{\tikz@lib@dv@exp}
  \else
    \pgfmathsetmacro\tikz@lib@dv@exp{\tikz@lib@dv@exp+1}
    \divide\pgf@xc by 10\relax  
    \pgfmathfloatcreate{\tikz@lib@dv@flags}{\pgf@sys@tonumber{\pgf@xc}}{\tikz@lib@dv@exp}
  \fi
  \pgfmathfloattofixed{\pgfmathresult}
  \let\tikz@lib@dv@step=\pgfmathresult
}





%
% Logarithmic axes
%

\tikzset{
  /tikz/data visualization/axis options/.cd,
  exponential steps/.style={tick placement strategy=\tikz@lib@dv@compute@at@log},
  %
  % Basic setters
  %
  logarithmic/.style={
    \tikz@dv@axis/function=\pgfdvmathln{\pgfvalue}{\pgfvalue},
    \tikz@dv@axis/scaling/default=1 at 0 and 10 at 1,
    exponential steps
  }
}

\def\tikz@lib@dv@compute@at@log{%
  % Setup about:
  \let\tikz@lib@dv@compute@about=\tikz@lib@dv@about@log%
  \let\tikz@lib@dv@step\relax%
  \pgfkeysvalueof{/tikz/data visualization/compute step}
  \ifx\tikz@lib@dv@step\relax%
  \else%
    % Gather interesting values
    \tikz@lib@dv@mapper.get in range interval()%
    \pgfdvinrangeinterval.get min and max()%
    \pgfdvmathlog{\pgfdvminlog}{\pgfdvmin}%
    \pgfdvmathlog{\pgfdvmaxlog}{\pgfdvmax}%
    \pgfkeysgetvalue{/tikz/data visualization/phase}\tikz@temp
    \pgfdvmathenter{\tikz@dv@lib@phase}{\tikz@temp}
    \pgfdvmathenter{\tikz@dv@lib@step}{\tikz@lib@dv@step}
    % Compute start:
    \pgfdvmathsub{\tikz@dv@lib@temp}{\pgfdvminlog}{\tikz@dv@lib@phase}% temp = dvmin - phase
    \pgfdvmathdiv{\tikz@dv@lib@temp}{\tikz@dv@lib@temp}{\tikz@dv@lib@step}% temp = temp/step
    \pgfdvmathfloor{\tikz@dv@lib@temp}{\tikz@dv@lib@temp}% temp = floor(temp)
    \pgfdvmathmul{\tikz@lib@dv@current}{\tikz@dv@lib@temp}{\tikz@dv@lib@step}% current = temp*step ...
    \pgfdvmathadd{\tikz@lib@dv@current}{\tikz@lib@dv@current}{\tikz@dv@lib@phase}% + phase
    \let\tikz@lib@dv@ats\pgfutil@empty%
    \let\tikz@lib@dv@minor@ats\pgfutil@empty%
    \pgfdvmathenter{\tikz@one@hundreth}{0.001}%
    \pgfdvmathsub{\tikz@lib@temp}{\pgfdvmaxlog}{\pgfdvminlog}%
    \pgfdvmathmul{\tikz@lib@dv@epsilon}{\tikz@lib@temp}{\tikz@one@hundreth}% epsilon = (max - min)/100
    \pgfdvmathsub{\tikz@lib@dv@min@minus@epsilon}{\pgfdvminlog}{\tikz@lib@dv@epsilon}%
    \pgfdvmathadd{\tikz@lib@dv@max@plus@epsilon}{\pgfdvmaxlog}{\tikz@lib@dv@epsilon}%
    \pgfkeysgetvalue{/tikz/data visualization/minor steps between steps}\tikz@lib@dv@substeps%
    \ifx\tikz@lib@dv@substeps\pgfutil@empty
    \else
      \pgfmathsetmacro\tikz@temp{\tikz@lib@dv@substeps+1}%
      \pgfdvmathenter{\tikz@dv@lib@substeps}{\tikz@temp}%
    \fi
    \loop%
      \ifx\tikz@lib@dv@substeps\pgfutil@empty%
      \else%
        \let\tikz@lib@dv@subcurrent=\tikz@lib@dv@current%
        \pgfdvmathadd{\tikz@lib@dv@subcurrent@next}{\tikz@lib@dv@subcurrent}{\tikz@dv@lib@step}%
        \pgfdvmathpowten{\tikz@lib@dv@subcurrent}{\tikz@lib@dv@subcurrent}%
        \pgfdvmathpowten{\tikz@lib@dv@subcurrent@max}{\tikz@lib@dv@subcurrent@next}%
        \pgfdvmathsub{\tikz@lib@dv@subcurrent@diff}{\tikz@lib@dv@subcurrent@max}{\tikz@lib@dv@subcurrent}%
        \pgfdvmathdiv{\tikz@lib@dv@substep}{\tikz@lib@dv@subcurrent@diff}{\tikz@dv@lib@substeps}%
        \pgfmathsetcount{\c@pgf@counta}{\tikz@lib@dv@substeps}%
        \let\tikz@lib@dv@next=\tikz@lib@dv@subloop%
        \tikz@lib@dv@subloop
      \fi%
      \pgfdvmathifless{\tikz@lib@dv@current}{\tikz@lib@dv@min@minus@epsilon}{}{%
        \pgfdvmathpowten{\tikz@lib@dv@current@pow}{\tikz@lib@dv@current}%
        \pgfdvmathexitbyserializing{\tikz@temp}{\tikz@lib@dv@current@pow}%
        \edef\tikz@lib@dv@ats{\tikz@lib@dv@ats,\tikz@temp}%
      }
      \pgfdvmathadd{\tikz@lib@dv@current}{\tikz@lib@dv@current}{\tikz@dv@lib@step}%
      \pgfdvmathifless{\tikz@lib@dv@current}{\tikz@lib@dv@max@plus@epsilon}{\tikz@lib@dv@continuetrue}{\tikz@lib@dv@continuefalse}%
      \iftikz@lib@dv@continue%
    \repeat%    
    \tikzdatavisualizationset{major/.expanded={at={\tikz@lib@dv@ats}},minor/.expanded={at={\tikz@lib@dv@minor@ats}}}%
  \fi%
}
\newif\iftikz@lib@dv@continue


\def\tikz@lib@dv@about@log#1{%
  \tikz@lib@dv@mapper.get in range interval()%
  \pgfdvinrangeinterval.get min and max()%
  \pgfdvmathlog{\pgfdvmin}{\pgfdvmin}%
  \pgfdvmathlog{\pgfdvmax}{\pgfdvmax}%
  \pgfdvmathsub{\tikz@lib@dv@diff}{\pgfdvmax}{\pgfdvmin}
  \pgfdvmathenter{\tikz@lib@dv@about@val}{#1}%
  \pgfdvmathdiv{\tikz@lib@dv@around}{\tikz@lib@dv@diff}{\tikz@lib@dv@about@val}%
  % Make mantisse sensible
  \pgfmathfloattomacro{\tikz@lib@dv@around}{\tikz@lib@dv@flags}{\tikz@lib@dv@mant}{\tikz@lib@dv@exp}
  \ifdim\tikz@lib@dv@exp pt<0pt%
    \pgfmathfloatcreate{1}{1.0}{0}%
  \else
    \pgf@xc=\tikz@lib@dv@mant pt\relax%
    \ifdim\pgf@xc<2.5pt
      \pgfmathfloatcreate{1}{1.0}{\tikz@lib@dv@exp}
    \else\ifdim\pgf@xc<5.1pt
      \pgfmathfloatcreate{1}{3.0}{\tikz@lib@dv@exp}
    \else
      \pgfmathfloatcreate{1}{6.0}{\tikz@lib@dv@exp}
    \fi\fi
  \fi%
  \pgfmathfloattofixed{\pgfmathresult}
  \let\tikz@lib@dv@step=\pgfmathresult
}







%
% Cartesian axes
%

\tikzdatavisualizationset{%
  new Cartesian axis/.style={
    new axis={#1},
    new object={
      class=linear transformer,
      store=/tikz/data visualization/#1/linear transformer,
      arg1/.expanded=\pgfkeysvalueof{/tikz/data visualization/#1/attribute}/scaled,
      arg2 from key=/tikz/data visualization/#1/unit vector,
    },
    #1/scaling/default/.initial=0 at 0 and 1 at 1cm,
    #1/unit vector/.initial=,
  }
}

\tikzset{
  /tikz/data visualization/axis options/.cd,
  unit vector/.code=\tikz@scan@one@point\tikz@lib@dv@uv#1,
  length/.style={\tikz@dv@axis/scaling=min at 0 and max at #1},
  positive length/.style={\tikz@dv@axis/scaling=0 at 0 and max at #1},
  negative length/.style={\tikz@dv@axis/scaling=min at -#1 and 0 at 0},
  unit length/.code={\tikz@dv@parse@unit@length{#1}},
  power unit length/.style={\tikz@dv@axis/scaling=1 at 0 and 10 at #1}
}

\def\tikz@lib@dv@uv#1{%
  \pgfkeyssetvalue{\tikz@dv@axis/unit vector}{#1}
}

\def\tikz@dv@parse@unit@length#1{
  \pgfutil@in@{per}{#1}
  \ifpgfutil@in@%
    \tikz@dv@parse@unit@length@#1\pgf@stop%
  \else%
    \tikz@dv@parse@unit@length@#1per1units\pgf@stop%
  \fi%
}
\def\tikz@dv@parse@unit@length@#1per#2units{
  \pgfkeysalso{\tikz@dv@axis/scaling=0 at 0 and #2 at #1}
}


% 
% Common visualizer interface 
%

\tikzdatavisualizationset{
  new visualizer/.style 2 args={
    /pgf/data/#1/.style={/data point/visualizer=#1},
    #1/.code={
      \def\tikz@visualizer{#1}%
      \pgfkeys{/tikz/data visualization/visualizer options/.cd,##1}
    },
    /utils/exec={
      \advance\tikzdvvisualizercounter by 1\relax
      \edef\tikz@temp{/data point/visualizer/#1/.initial=\the\tikzdvvisualizercounter}
      \expandafter\tikzset\expandafter{\tikz@temp}
    },
    /data point/#1/execute at begin/.initial={
      \pgfkeyssetvalue{/data point/visualizer}{#1}
      \scope[
        /tikz/data visualization/every visualizer/.try,
        #2,
        /utils/exec=\pgf@signalstyle.emit(),
        /tikz/data visualization/visualizers/#1/styling/.try]
    },
    /data point/#1/execute at end/.initial={
        \path; % invokes every path implicitly
      \endscope
    },
    /tikz/data visualization/visualizers/#1/styling/.style=,
  },
  visualizer style sheet/.style={/data point/visualizer/.style sheet={#1}}
}

\def\tikz@do@visualizer#1#2{%
  \tikzdatavisualizationset{
    #2=#1
  }
}

\newcount\tikzdvvisualizercounter

\newif\iftikz@dv@visualizer@label@inline

\tikzset{
  @set plot handler/.code={\let\tikz@plot@handler=#1},
  no lines/.style={@set plot handler=\pgfplothandlerdiscard,/utils/exec=\tikzdatavisualizationset{default label in legend mark}},
  smooth line/.style={@set plot handler=\pgfplothandlercurveto,/utils/exec=\tikzdatavisualizationset{default label in legend path}},
  smooth cycle/.style={@set plot  handler=\pgfplothandlerclosedcurve,/utils/exec=\tikzdatavisualizationset{default label in legend closed path}},
  straight line/.style={@set plot handler=\pgfplothandlerlineto,/utils/exec=\tikzdatavisualizationset{default label in legend path}},
  straight cycle/.style={@set plot handler=\pgfplothandlerpolygon,/utils/exec=\tikzdatavisualizationset{default label in legend closed path}},
  polygon/.style={straight cycle=cycle},% alias
  gapped line/.style={@set plot handler=\pgfplothandlergaplineto,/utils/exec=\tikzdatavisualizationset{default label in legend path}},
  gapped cycle/.style={@set plot handler=\pgfplothandlergapcycle,/utils/exec=\tikzdatavisualizationset{gapped circular label in legend line}}
}



% 
% Label visualizer 
%

\tikzdatavisualizationset{
  new label visualizer/.style 2 args={
    new object={
      when=before visualization,
      class=label visualizer,
      before creation={
        \begingroup
        \def\tikz@visualizer{#1}%
        \pgfkeys{/tikz/data visualization/visualizer label options/.cd,
          /tikz/data visualization/every label visualizer/.try,
          #2}
        \pgfkeysgetvalue{/tikz/data visualization/visualizer label options/text}\tikz@dv@temp@lab
        \def\tikz@tempa{
          \scope[/tikz/data visualization/visualizer label options/.cd,
          /tikz/data visualization/every label visualizer/.try,
          #2]
          \path [
            /data point/visualizer=#1,/utils/exec=\pgf@signalstyle.emit(),
            /tikz/data visualization/.cd,every visualizer label]
          (label visualizer coordinate') --
          (label visualizer coordinate)
          node [
            auto,
            at end,
            /tikz/data visualization/node styling]
        }
        \expandafter\def\expandafter\tikz@tempb\expandafter{\expandafter{\tikz@dv@temp@lab};}%
        \expandafter\expandafter\expandafter\gdef%
        \expandafter\expandafter\expandafter\tikz@dv@label@code%
        \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\relax%
          \expandafter\expandafter\expandafter{\expandafter\tikz@tempa\tikz@tempb\endscope}}
        \global\let\tikz@dv@label@attribute=\tikz@dv@label@attribute
        \global\let\tikz@dv@label@threshold=\tikz@dv@label@threshold
        \endgroup
      },
      arg1/.expand once=\tikz@dv@label@attribute,
      arg2/.expand once=\tikz@dv@label@threshold,
      arg3/.expand once=\tikz@dv@label@code,
      arg4=\pgfdvvisualizerfilter{#1}
    },
    /utils/exec=\tikz@create@label@count{#1}
  },
  % Label style
  text colored/.style={node style={text=visualizer color}}
}

\def\tikz@create@label@count#1{
  \tikzdatavisualizationset{
    new object={
      when=after survey,
      store=/tikz/data visualization/visualizers/#1/count/obj,
      class=count,
      arg1=visualizers/#1/count,
      after creation={
        \tikzdvobj.set filter({%
          \pgfkeysgetvalue{/data point/visualizer}\pgf@tempa%
          \def\pgf@tempb{#1}%
          \ifx\pgf@tempa\pgf@tempb%
          \else
            \pgfdvfilterpassedfalse%
          \fi
        }) 
      }
    }
  }
}

\pgfkeys{
  /tikz/data visualization/visualizer label options/.cd,
  at/.code args={#1>=#2}{%
    \def\tikz@dv@label@attribute{#1}%
    \def\tikz@dv@label@threshold{#2}%
  },
  index/.code={%
    \edef\tikz@dv@label@attribute{visualizers/\tikz@visualizer/count}%
    \def\tikz@dv@label@threshold{#1}%
  },
  text/.initial=,
  text'/.style={text={#1},node style=swap},
  node style/.style={/tikz/data visualization/node style={#1}},
  text colored/.style=/tikz/data visualization/text colored,
}

\let\tikz@dv@label@attribute\pgfutil@empty
\let\tikz@dv@label@threshold\pgfutil@empty
\let\tikz@dv@label@code\pgfutil@empty




%
% Legend handling
%

\tikzdatavisualizationset{
  new legend/.code={
    \pgfkeysifdefined{/tikz/data visualization/#1/at}{}
    {\tikzdatavisualizationset{
    new object={
      class=legend,
      store=/tikz/data visualization/#1/obj,
      arg1 from key=/tikz/data visualization/#1/@columns or rows,
      arg2 from key=/tikz/data visualization/#1/@ideal,
      arg3 from key=/tikz/data visualization/#1/max entries,
      arg4 from key=/tikz/data visualization/#1/@strategy,
      after creation={
        \tikzdatavisualizationset{
          legend actions/.append={
            \pgfkeysgetvalue{/tikz/data visualization/#1/obj}\pgf@dv@legend%
            {
              \pgf@dv@legend.get arrangement(\pgf@dv@temp)%
              \pgfkeysgetvalue{/tikz/data visualization/#1/at}\pgf@dv@at%
              \pgfkeysgetvalue{/tikz/data visualization/#1/anchor}\pgf@dv@anchor%
              \let\pgfdvnextcell=\pgfmatrixnextcell%
              \let\pgfdvendrow=\pgfmatrixendrow%
              \def\pgf@marshal{
                \matrix[at/.expand once=\pgf@dv@at,matrix anchor/.expand
                once=\pgf@dv@anchor,/tikz/data visualization/#1/styling]
              }
              \expandafter\pgf@marshal\expandafter{\pgf@dv@temp};
            }
          }
        }
      }
    },
    #1/@columns or rows/.initial=columns,
    #1/@ideal/.initial=1,
    #1/max entries/.initial=100,
    #1/@strategy/.initial=down then right,
    #1/anchor/.initial=west,
    #1/at/.initial=(data visualization bounding box.east),
    #1/styling/.style={row sep=0pt,column sep=.8em},
    % 
    % 
    %
    #1/.code={
      \let\tikz@temp\tikz@dv@legend%
      \def\tikz@dv@legend{/tikz/data visualization/#1}%
      \expandafter\tikz@do@legend@options\expandafter{\tikz@temp}{##1}%
    },
    #1={every new legend}
  }}},
  legend/.style={new legend=legend,legend={#1}}
}

\def\tikz@do@legend@options#1#2{
  \pgfkeys{/tikz/data visualization/legend options/.cd,#2}
  \def\tikz@dv@legend{#1}
}
\let\tikz@dv@legend\pgfutil@empty


\tikzset{
  /tikz/data visualization/legend options/.cd,
  %
  % How to arrange the entries in the legend
  %
  ideal number of columns/.style={\tikz@dv@legend/@columns or rows=columns,\tikz@dv@legend/@ideal={#1}},
  ideal number of rows/.style={\tikz@dv@legend/@columns or rows=rows,\tikz@dv@legend/@ideal={#1}},
  columns/.style={ideal number of columns={#1}},% alias
  rows/.style={ideal number of rows={#1}},% alias
  max rows/.style={\tikz@dv@legend/@columns or rows=columns,\tikz@dv@legend/max entries={#1}},
  max columns/.style={\tikz@dv@legend/@columns or rows=rows,\tikz@dv@legend/max entries={#1}},
  down then right/.style={\tikz@dv@legend/@strategy=down then right},
  down then left/.style={\tikz@dv@legend/@strategy=down then left},
  up then right/.style={\tikz@dv@legend/@strategy=up then right},
  up then left/.style={\tikz@dv@legend/@strategy=up then left},
  right then down/.style={\tikz@dv@legend/@strategy=right then down},
  left then down/.style={\tikz@dv@legend/@strategy=left then down},
  right then up/.style={\tikz@dv@legend/@strategy=right then up},
  left then up/.style={\tikz@dv@legend/@strategy=left then up},
  % 
  % Where to put the legend 
  % 
  anchor/.style={\tikz@dv@legend/anchor={#1}},
  at/.style={\tikz@dv@legend/at={#1}},
  right/.style={
    columns=1,
    at={([xshift=.8em]data visualization bounding box.east)},
    anchor=west,
  },
  left/.style={
    columns=1,
    at={([xshift=-.8em]data visualization bounding box.west)},
    anchor=east,
  },
  below/.style={
    rows=1,
    at={([yshift=-.5em]data visualization bounding box.south)},
    anchor=north,
  },
  above/.style={
    rows=1,
    at={([yshift=.5em]data visualization bounding box.north)},
    anchor=south,
  },
  every new legend/.style={right,label style=text right},
  % 
  % Label text styling 
  % 
  label style/.style={
    style={/tikz/data visualization/legend entry options/every label
      in legend/.append style={#1}}
  },
  % 
  % Styling 
  %
  style/.style={\tikz@dv@legend/styling/.append style={#1}},
}


\tikzdatavisualizationset{
  new legend entry/.code={
    \begingroup
      \pgfkeys{/tikz/data visualization/legend entry options/.cd,#1}
      \pgfkeysgetvalue{/tikz/data visualization/legend entry options/legend}\tikz@dv@temp@legend
      \global\let\tikz@dv@temp@legend\tikz@dv@temp@legend  
    \endgroup
    \tikzdatavisualizationset{new legend/.expanded=\tikz@dv@temp@legend}%
    \expandafter\tikz@dv@add@legend@entry\expandafter{\tikz@dv@temp@legend}{#1}
  }
}

\def\tikz@dv@add@legend@entry#1#2{
  \tikz@main@dv.at start survey({{
      \pgfkeysgetvalue{/tikz/data visualization/#1/obj}\pgf@temp
      \pgf@temp.add entry(\tikz@dv@render@legend@entry{legend=#1,#2})
    }})
}

\def\tikz@dv@render@legend@entry#1{
  \pgfkeys{/tikz/data visualization/.cd,
    every visualizer label,
    every visualizer legend label
  }
  \pgfkeys{/tikz/data visualization/legend entry options/.cd,#1}
  \pgfkeysgetvalue{/tikz/data visualization/legend entry options/text}\tikz@dv@temp@lab    
  \pgfkeysgetvalue{/tikz/data visualization/@node styling}\tikz@dv@temp@style
  \pgfkeysgetvalue{/tikz/data visualization/legend entry options/setup}\tikz@dv@temp@setup
  \pgfkeysgetvalue{/tikz/data visualization/legend entry options/value visualizer}\tikz@dv@temp@visual
  \pgfkeysgetvalue{/tikz/data visualization/legend entry options/value visualizer styling}\tikz@dv@temp@visual@styling
  \scope[/utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@setup},
         /utils/exec=\pgf@signalstyle.emit()]
    \node[/tikz/data visualization/node styling,
          /utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@style}]
    {\tikz@dv@pre@height\tikz@dv@temp@lab\tikz@dv@post@height};
    \scope[/utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@visual@styling}]
      \tikz@dv@temp@visual
    \endscope
  \endscope
}

\def\tikz@dv@pre@height{\hbox{\vrule height .75em width0pt}}
\def\tikz@dv@post@height{\hbox{\vrule depth .25em width0pt}}



\pgfkeys{
  /tikz/data visualization/legend entry options/.cd,
  % 
  % General options
  % 
  text/.initial=,
  node style/.style={/tikz/data visualization/node style={#1}},
  legend/.initial=legend,
  setup/.initial=,
  value visualizer/.initial=,
  value visualizer styling/.initial=,
  value visualizer style/.style={value visualizer styling/.append={,#1}},
  value visualizer macro/.initial=,
  % 
  % Legend visualizers for plots
  % 
  text right/.style={
    node style={anchor=mid west,inner ysep=1pt,inner xsep=0pt,reset cm,xshift=.333em},
    value visualizer style={reset cm},
    value visualizer macro=\tikz@dv@legend@entry@as@example
  },
  text left/.style={
    node style={anchor=mid east,inner ysep=1pt,inner xsep=0pt,reset
      cm,xshift=-.333em,align=right},
    value visualizer style={reset cm,xscale=-1},
    value visualizer macro=\tikz@dv@legend@entry@as@example
  },
  text only/.style={
    node style={anchor=mid west,inner ysep=1pt,inner xsep=0pt,reset cm,text=visualizer color},
    value visualizer style={},
    value visualizer macro=\relax,
  },
  text colored/.style=/tikz/data visualization/text colored,
}


\pgfkeys{
  /tikz/data visualization/visualizer options/.cd,
  label in legend/.code={\expandafter\tikz@dv@new@label@in@legend@for@visualizer\expandafter{\tikz@visualizer}{#1}},
  label in data/.code=\tikzdatavisualizationset{new label visualizer/.expand once=\expandafter{\tikz@visualizer}{#1}},
  style/.style={/tikz/data visualization/visualizers/\tikz@visualizer/styling/.append style={#1}},
}

\def\tikz@dv@new@label@in@legend@for@visualizer#1#2{
  \tikzdatavisualizationset{
    new legend entry={
      every legend entry/.try,
      every label in legend/.try,
      /tikz/data visualization/every label/.try,
      #2,
      setup={/data point/visualizer=#1},
      /utils/exec=\pgfkeysgetvalue{/tikz/data visualization/legend entry options/value visualizer macro}\tikz@dv@visualizer@macro,
      value visualizer={
        \scope[/tikz/data visualization/visualizers/#1/styling/.try]
          \def\tikz@visualizer{#1}
            \tikz@dv@visualizer@macro
        \endscope
      }      
    }
  }
}

\def\tikz@dv@legend@entry@as@example{
  \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin}
  \tikz@plot@handler
  \pgfplotstreamstart
  \pgfkeysgetvalue{/tikz/data visualization/label in legend line coordinates}{\tikz@dv@temp}
  \foreach \coordinate in \tikz@dv@temp
  { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} }
  \pgfplotstreamend
  \pgfkeysvalueof{/data point/\tikz@visualizer/execute at end}
  \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin}
  \tikz@dv@plot@mark@maker
  \pgfplotstreamstart
  \pgfkeysgetvalue{/tikz/data visualization/label in legend mark coordinates}{\tikz@dv@temp}
  \foreach \coordinate in \tikz@dv@temp
  { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} }
  \pgfplotstreamend
  \pgfkeysvalueof{/data point/\tikz@visualizer/execute at end}
}


\tikzdatavisualizationset{
  label in legend line coordinates/.initial=,
  label in legend mark coordinates/.initial=,
  label in legend one mark/.style={
    label in legend line coordinates={},
    label in legend mark coordinates={(0,0)},
  },
  label in legend three marks/.style={
    label in legend line coordinates={},
    label in legend mark coordinates={(-3ex,-.3ex),(-1.5ex,.3ex),(0,0)},
  },
  straight label in legend line/.style={
    label in legend line coordinates={(-2em,0),(0,0)},
    label in legend mark coordinates={(-1.5em,0),(-.5em,0)},
  },
  zig zag label in legend line/.style={
    label in legend line coordinates={(-2em,0),(-1.5em,.3ex),(-.5em,-.3ex),(0,0)},
    label in legend mark coordinates={(-1.5em,.3ex),(-.5em,-.3ex)},
  },
  circular label in legend line/.style={
    label in legend line coordinates={%
      ([xshift=-1em]0:.9em and .35ex),%
      ([xshift=-1em]30:.9em and .35ex),%
      ([xshift=-1em]60:.9em and .35ex),%
      ([xshift=-1em]90:.9em and .35ex),%
      ([xshift=-1em]120:.9em and .35ex),%
      ([xshift=-1em]150:.9em and .35ex),%
      ([xshift=-1em]180:.9em and .35ex),%
      ([xshift=-1em]210:.9em and .35ex),%
      ([xshift=-1em]240:.9em and .35ex),
      ([xshift=-1em]270:.9em and .35ex),%
      ([xshift=-1em]300:.9em and .35ex),%
      ([xshift=-1em]330:.9em and .35ex)},
    label in legend mark coordinates={([xshift=-1em]120:.9em and .35ex),([xshift=-1em]-60:.9em and .35ex)},
  },  
  gapped circular label in legend line/.style={
    label in legend line coordinates={%
      ([xshift=-1em,yshift=.2ex]90:1.4ex and 0.9ex),%
      ([xshift=-1em,yshift=.2ex]162:1.4ex and 0.9ex),%
      ([xshift=-1em,yshift=.2ex]234:1.4ex and 0.9ex),%
      ([xshift=-1em,yshift=.2ex]306:1.4ex and 0.9ex),%
      ([xshift=-1em,yshift=.2ex]18:1.4ex and 0.9ex)},
    label in legend mark coordinates={
      ([xshift=-1em,yshift=.2ex]90:1.4ex and 0.9ex),%
      ([xshift=-1em,yshift=.2ex]162:1.4ex and 0.9ex),%
      ([xshift=-1em,yshift=.2ex]234:1.4ex and 0.9ex),%
      ([xshift=-1em,yshift=.2ex]306:1.4ex and 0.9ex),%
      ([xshift=-1em,yshift=.2ex]18:1.4ex and 0.9ex)}
  },  
  default label in legend path/.style={zig zag label in legend line},
  default label in legend closed path/.style={circular label in legend line},
  default label in legend mark/.style={label in legend one mark},
}


\def\tikz@dv@legend@entry@visualizer@visualizer{
}



%
% Basic visualizers
%

\tikzdatavisualizationset{
  visualize as line/.style={
    new object={
      when=after survey,
      store=/tikz/data visualization/visualizers/#1,
      class=plot handler visualizer,
      arg1=#1,
      arg2={\tikz@plot@handler,\tikz@dv@plot@mark@maker}
    },
    new visualizer={#1}{%
      every path/.style={draw},
      style={every mark/.append style={color=visualizer color}},
      straight line,
      semithick,
      color=visualizer color,
      mark=none,
      /tikz/data visualization/every visualize as line/.try,
    },
    /data point/visualizer=#1
  },
  visualize as line/.default=line,
  visualize as smooth line/.style={
    visualize as line={#1},
    #1={style=smooth line}
  },
  visualize as smooth line/.default=line,
  visualize as scatter/.style={
    visualize as line={#1},
    #1={style=no lines,
      /tikz/data visualization/every visualize as scatter/.try},
    visualizer style sheet=cross marks
  },
  visualize as scatter/.default=scatter
}

\def\tikz@dv@plot@mark@maker{
  \let\tikz@options=\pgfutil@empty%
  \let\tikz@transform=\pgfutil@empty%
  \tikzset{solid,shift only,every mark}%
  \tikz@options%
  \pgfplothandlermark{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}}
}




% The following needs to be fixed...
\tikzdatavisualizationset{
  new rectangles visualizer/.style={
    new object={
      store=/tikz/data visualization/visualizers/#1,
      class=rectangle visualizer,
      arg1 from key=/tikz/data visualization/#1/attribute 1,
      arg2 from key=/tikz/data visualization/#1/attribute 2,
      arg3=#1/use path
    },
    #1/attribute 1/.initial=x,
    #1/attribute 2/.initial=y,
    /data point/#1/use path/.initial=\pgfusepath{stroke},
    /data point/#1/style/.code=\pgfkeysalso{/data point/#1/use path={\path[every rectangles/.try,##1];}}
  },
  rectangle visualizer/.default=rectangles
}





%
% Style sheets
% 

% Style sheet handler

\pgfkeysdef{/handlers/.style sheet}{%
  \edef\pgf@marshal{
    \noexpand \pgfoonew \noexpand\tikz@dv@temp=new style attribute(\pgfkeyscurrentpath,#1)
    \noexpand \tikz@dv@temp.default connects()
  }
  \pgf@marshal
}

\tikzset{
  visualizer color/.code=\colorlet{visualizer color}{#1},
  visualizer color=black
}

% Default style sheets

\pgfdvdeclarestylesheet{vary thickness}
{
  default style/.style={line width={0.3pt+#1*0.2pt}}
}
  
\pgfdvdeclarestylesheet{vary dashing}
{
  default style/.style=solid,
  1/.style=solid,
  2/.style={dash pattern=on 5\pgflinewidth off 2\pgflinewidth},
  3/.style={dash pattern=on 1.5\pgflinewidth off 1.5\pgflinewidth},
  4/.style={dash pattern=on 5\pgflinewidth off 1.5\pgflinewidth on 1.5\pgflinewidth off 1.5\pgflinewidth},
  5/.style={dash pattern=on 10\pgflinewidth off 3\pgflinewidth},
  6/.style={dash pattern=on 10\pgflinewidth off 2\pgflinewidth on 2\pgflinewidth off 2\pgflinewidth},
  7/.style={dash pattern=on 8\pgflinewidth off 2\pgflinewidth on
    1.5\pgflinewidth off 1.5\pgflinewidth on 1.5\pgflinewidth off
    1.5\pgflinewidth on 1.5\pgflinewidth off 1.5\pgflinewidth}
}

\pgfdvdeclarestylesheet{vary thickness and dashing}
{
  default style/.style=thin,
  1/.style=thin,
  2/.style=thick,
  3/.style={
    dash pattern=on 5\pgflinewidth off 2\pgflinewidth,
    thin
  },
  4/.style={
    dash pattern=on 5\pgflinewidth off 2\pgflinewidth,
    thick,
  },
  5/.style={
    dash pattern=on 1.5\pgflinewidth off 1.5\pgflinewidth,
    thin
  },
  6/.style={
    dash pattern=on 1.5\pgflinewidth off 1.5\pgflinewidth,
    thick
  },
  7/.style={
    dash pattern=on 5\pgflinewidth off 1.5\pgflinewidth on
    1.5\pgflinewidth off 1.5\pgflinewidth,
    thin
  },
  8/.style={
    dash pattern=on 5\pgflinewidth off 1.5\pgflinewidth on
    1.5\pgflinewidth off 1.5\pgflinewidth,
    thick
  },
  9/.style={
    dash pattern=on 10\pgflinewidth off 3\pgflinewidth,
    thin
  },
  10/.style={
    dash pattern=on 10\pgflinewidth off 3\pgflinewidth,
    thick
  },
  11/.style={
    dash pattern=on 10\pgflinewidth off 2\pgflinewidth on
    2\pgflinewidth off 2\pgflinewidth,
    thin
  },
  12/.style={
    dash pattern=on 10\pgflinewidth off 2\pgflinewidth on
    2\pgflinewidth off 2\pgflinewidth,
    thick
  },
  13/.style={
    dash pattern=on 8\pgflinewidth off 2\pgflinewidth on
    1.5\pgflinewidth off 1.5\pgflinewidth on 1.5\pgflinewidth off
    1.5\pgflinewidth on 1.5\pgflinewidth off 1.5\pgflinewidth,
    thin
  },
  14/.style={
    dash pattern=on 8\pgflinewidth off 2\pgflinewidth on
    1.5\pgflinewidth off 1.5\pgflinewidth on 1.5\pgflinewidth off
    1.5\pgflinewidth on 1.5\pgflinewidth off 1.5\pgflinewidth,
    thick
  }  
}


\pgfdvdeclarestylesheet{strong colors}
{
  default style/.style={black},
  1/.style={visualizer color=black},
  2/.style={visualizer color=red!80!black},
  3/.style={visualizer color=blue!80!black},
  4/.style={visualizer color=green!60!black},
  5/.style={visualizer color=orange!80!black},
  6/.style={visualizer color=black!60}
}


\pgfdvdeclarestylesheet{cross marks}
{
  default style/.style={mark=x,every mark/.append style=thin,mark size=1.8pt},
  1/.style={mark=x,every mark/.append style=thin,mark size=1.8pt},
  2/.style={mark=+,every mark/.append style=thin,mark size=1.8pt},
  3/.style={mark=Mercedes star,every mark/.append style=thin,mark size=1.8pt},
  4/.style={mark=Mercedes star flipped,every mark/.append style=thin,mark size=1.8pt},
  5/.style={mark=star,every mark/.append style=thin,mark size=1.8pt},
  6/.style={mark=10-pointed star,every mark/.append style={line width=.3pt,mark size=1.6pt}}
}



% Declare a color series style sheet
% 
% #1 = name of the style sheet
% #2 = color model
% #3 = initial color
% #4 = step
% 
% Description:
% 
% This function declares a style sheet that changes colors according
% to the value of the attribute. No test is made that the attribute is
% a number.

\def\tikzdvdeclarestylesheetcolorseries#1#2#3#4{
  \definecolorseries{tikzdvcolorseries#1}{#2}{step}[#2]{#3}{#4}
  \resetcolorseries{tikzdvcolorseries#1}
  \pgfdvdeclarestylesheet{#1}
  {
    default style/.style={
      /utils/exec=\colorlet{tikz@dv@temp}[rgb]{tikzdvcolorseries#1!![##1]},
      visualizer color=tikz@dv@temp
    }
  }
}

\tikzdvdeclarestylesheetcolorseries{varying hue}{hsb}{.4,0.9,0.8}{.213,0,0}
\tikzdvdeclarestylesheetcolorseries{shades of blue}{hsb}{.65,1.4,1}{0,-.4,-.0}
\tikzdvdeclarestylesheetcolorseries{shades of red}{hsb}{0,1.4,1}{0,-.4,-.0}





%
% Basic Axes & Coordinate Systems
%


%
%
% Basic axis systems
%
%

\tikzdatavisualizationset{
  xy Cartesian/.style={
    new Cartesian axis=x axis,
    x axis={attribute=x,unit vector={(1pt,0cm)}},
    new Cartesian axis=y axis,
    y axis={attribute=y,unit vector={(0cm,1pt)}}
  },
  xy axes/.style={x axis={#1},y axis={#1}},
  uv Cartesian/.style={
    new Cartesian axis=u axis,
    u axis={attribute=u,unit vector={(1pt,0cm)}},
    new Cartesian axis=v axis,
    v axis={attribute=v,unit vector={(0cm,1pt)}}
  },
  uv axes/.style={u axis={#1},v axis={#1}},
}

\tikzdatavisualizationset{
  xyz Cartesian cabinet/.style={
    xy Cartesian,
    new Cartesian axis=z axis,
    z axis={attribute=z,unit vector={(-0.353553pt,-0.353553pt)}}
  },
  xyz axes/.style={x axis={#1},y axis={#1},z axis={#1}},
  uvw Cartesian cabinet/.style={
    uv Cartesian,
    new Cartesian axis=w axis,
    w axis={attribute=w,unit vector={(-0.353553pt,-0.353553pt)}}
  }
  uvw axes/.style={u axis={#1},v axis={#1},w axis={#1}},
}




% The school book axes
%
% This coordinate system can be used to create plots that look like
% plots in a typical school book: There are two axes called "x axis"
% and "y axis" that meet at the origin, there are arrows at the ends
% of the axes, pointing in the directions of the positive axes. No
% scaling is done by default, rather one unit equals one 1cm. This
% ensures that the even when multiple plots are created, the same
% scaling will be used each time.
% 
% To change the scaling, say "all axes={unit length=1mm}" for
% instance. 

\tikzdatavisualizationset{
  school book axes/.style={
    xy Cartesian,
    x axis={
      include values=0,
      visualize axis={y axis={goto=0},style=->,padded},
      visualize ticks={common={y axis={goto=0},direction axis=y axis},
        major={tick text at low,
          options at=0 as [{style={draw=none},no tick text}]
        }},
      visualize grid={common={direction axis=y axis,padded}},
      ticks={step=1},
      padding=0.75em,
      visualize label={visualize x axis label}
    },
    y axis={
      include values=0,
      visualize axis={x axis={goto=0},style=->,padded},
      visualize ticks={
        common={x axis={goto=0},direction axis=x axis},
        major={tick text at low,options at=0 as [{high=0,low=0,style={draw=none},node style={anchor=north east}}]}
      },
      visualize grid={common={direction axis=x axis,padded}},
      ticks={step=1},
      padding=0.75em,
      visualize label={visualize y axis label}
    },
    school book axes standard labels,
    every school book axes/.try
  }  
}


% Possible axis positionings:

\tikzdatavisualizationset{
  %
  % Place labels at the ends of the axes
  school book axes standard labels/.style={
    visualize x axis label/.style={
      value=padded max,
      y axis={goto=0}
    },
    visualize y axis label/.style={
      value=padded max,
      x axis={goto=0}
    }
  }
}


% The scientific axes
%
% The scientific axes is a 2d plot that has a predetermined width and
% height. The data is then scaled in such a way that it fits inside
% this given rectangle. 

\tikzdatavisualizationset{
  scientific axes/width/.initial=5cm,
  scientific axes/height/.initial=0.618*\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},% golden ratio...
  scientific axes/.style={
    xy Cartesian,
    every axis/.append style={style={draw=black!50}},
    every ticks/.append style={style={draw=black!50}},
    x axis={
      length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},
      ticks={some},
      visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}},
      visualize ticks={common={y axis={goto=padded max},direction axis=y axis,low=0pt}},
      visualize axis={y axis={goto=padded min},padded},
      visualize axis={y axis={goto=padded max},padded},
      visualize grid={common={direction axis=y axis,padded}},
      visualize label=visualize x axis label
    },
    y axis={
      length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height},
      ticks={some},
      visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}},
      visualize ticks={common={x axis={goto=padded max},direction axis=x axis,low=0pt}},
      visualize axis={x axis={goto=padded min},padded},
      visualize axis={x axis={goto=padded max},padded},
      visualize grid={common={direction axis=x axis,padded}},
      visualize label=visualize y axis label
    },
    scientific axes standard labels,
    every scientific axes/.try
  },
  scientific inner axes/.style={
    xy Cartesian,
    every axis/.append style={style={draw=black!50}},
    every ticks/.append style={style={draw=black!50}},
    x axis={
      length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},
      ticks={some},
      visualize ticks={common={y axis={goto=padded min},direction axis=y axis,low=0pt},major={tick text at low}},
      visualize ticks={common={y axis={goto=padded max},direction axis=y axis,high=0pt}},
      visualize axis={y axis={goto=padded min},padded},
      visualize axis={y axis={goto=padded max},padded},
      visualize grid={common={direction axis=y axis,padded}},
      visualize label=visualize x axis label
    },
    y axis={
      length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height},
      ticks={some},
      visualize ticks={common={x axis={goto=padded min},direction axis=x axis,low=0pt},major={tick text at low}},
      visualize ticks={common={x axis={goto=padded max},direction axis=x axis,high=0pt}},
      visualize axis={x axis={goto=padded min},padded},
      visualize axis={x axis={goto=padded max},padded},
      visualize grid={common={direction axis=x axis,padded}},
      visualize label=visualize y axis label
    },
    scientific axes standard labels,
    every scientific axes/.try
  },
  scientific clean axes/.style={
    xy Cartesian,
    x axis={
      length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},
      ticks={some},
      visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}},
      visualize axis={y axis={goto=padded min}},
      visualize grid={common={direction axis=y axis}},
      visualize label=visualize x axis label,
      grid={major={also at=min,also at=max}},
    },
    y axis={
      length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height},
      ticks={some},
      visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}},
      visualize axis={x axis={goto=padded min}},
      visualize grid={common={direction axis=x axis}},
      visualize label=visualize y axis label,
      grid={major={also at=min,also at=max}},
    },
    all axes={padding=.5em},
    scientific axes standard labels,
    every scientific axes/.try
  },
}



% Possible axis positionings:

\tikzdatavisualizationset{
  % 
  % Place axes labels below and left, where left label is rotated 
  %
  scientific axes standard labels/.style={
    visualize x axis label/.style={
      % Horizontal position is middle of axis:
      pos=0.5,
      y axis={goto=padded min},
      % Vertical position comes from bounding box:
      node style={
        at={(0,0 |- data visualization bounding box.south)},
        below
      }
    },
    visualize y axis label/.style={%
      % Vertical position is middle of axis:
      pos=0.5,
      x axis={goto=padded min},
      % Horizontal position comes from bounding box:
      node style={
        at={(0,0 -| data visualization bounding box.west)},
        rotate=90,
        above}
    }
  },
  % 
  % Place axes labels below and left, no rotation
  %
  scientific axes upright labels/.style={
    scientific axes standard labels,
    visualize y axis label/.style={%
      % Vertical position is middle of axis:
      pos=0.5,
      x axis={goto=padded min},
      % Horizontal position comes from bounding box:
      node style={
        at={(0,0 -| data visualization bounding box.west)},
        left
      }
    }    
  },
  % 
  % Place axes at the ends of the axes
  %
  scientific axes end labels/.style={
    visualize x axis label/.style={
      value=max,
      y axis={goto=padded min},
      % Vertical position comes from bounding box:
      node style={
        at={(0,0 -| data visualization bounding box.east)},
        right
      }
    },
    visualize y axis label/.style={
      value=max,
      x axis={goto=padded min},
      % Horizontal position comes from bounding box:
      node style={
        at={(0,0 |- data visualization bounding box.north)},
        above
      }
    }
  }
}



\endinput

