%% The LaTeX package genealogytree - version 2.1.0 (2021/09/20) %% gtrlib.fanchart.code.tex: Fancharts %% %% ------------------------------------------------------------------------------------------- %% Copyright (c) 2013-2021 by Prof. Dr. Dr. Thomas F. Sturm %% ------------------------------------------------------------------------------------------- %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3 %% of this license or (at your option) any later version. %% The latest version of this license is in %% http://www.latex-project.org/lppl.txt %% and version 1.3 or later is part of all distributions of LaTeX %% version 2005/12/01 or later. %% %% This work has the LPPL maintenance status `author-maintained'. %% %% This work consists of all files listed in README %% \gtr@set@library@version{2.1.0} \ExplSyntaxOn \tl_new:N \l_getree_fanchart_minor_angle_tl \tl_new:N \l_getree_fanchart_major_angle_tl \tl_new:N \l_getree_fanchart_angle_a_tl \tl_new:N \l_getree_fanchart_angle_b_tl \tl_new:N \l_getree_fanchart_id_tl \tl_new:N \l_getree_fanchart_radius_a_tl \tl_new:N \l_getree_fanchart_radius_b_tl \tl_new:N \l_getree_fanchart_level_tl \tl_new:N \l_getree_fanchart_ratio_tl \tl_new:N \l_getree_fanchart_offset_a_tl \tl_new:N \l_getree_fanchart_offset_b_tl \tl_new:N \l_getree_fanchart_line_width_tl \bool_new:N \l__getree_fanchart_reset_bounds_bool \tl_new:N \l__getree_fanchart_recursive_action_tl \tl_new:N \l__getree_fanchart_tmpa_tl \tl_new:N \l__getree_fanchart_tmpb_tl \tl_new:N \l__getree_fanchart_landscape_level_tl \fp_new:N \l__getree_fanchart_angle_fp \fp_new:N \l__getree_fanchart_radius_fp \fp_new:N \l__getree_fanchart_inner_fp \fp_new:N \l__getree_fanchart_inner_off_fp \fp_new:N \l__getree_fanchart_outer_fp \fp_new:N \l__getree_fanchart_outer_off_fp \fp_new:N \l__getree_fanchart_boundary_width_fp \fp_new:N \l__getree_fanchart_boundary_scale_fp \fp_new:N \l__getree_fanchart_bounds_border_fp \fp_new:N \l__getree_fanchart_bounds_xmin_fp \fp_new:N \l__getree_fanchart_bounds_xmax_fp \fp_new:N \l__getree_fanchart_bounds_ymin_fp \fp_new:N \l__getree_fanchart_bounds_ymax_fp \tl_const:Nn \c_getree_fanchart_maximum_rings_tl {24} \fparray_new:Nn \g__getree_fanchart_radii_fparry {\c_getree_fanchart_maximum_rings_tl+1} \fparray_new:Nn \g__getree_fanchart_distances_fparry {\c_getree_fanchart_maximum_rings_tl} \fparray_new:Nn \g__getree_fanchart_inner_fparry {\c_getree_fanchart_maximum_rings_tl} \fparray_new:Nn \g__getree_fanchart_outer_fparry {\c_getree_fanchart_maximum_rings_tl} %%%%%%%%%%%%%%%%%%%%%%% %% Core %%%%%%%%%%%%%%%%%%%%%%% \cs_new:Npn \__getree_fanchart_segment_computation: { \fp_compare:nNnF {\l_getree_fanchart_major_angle_tl} > {\l_getree_fanchart_minor_angle_tl} { \tl_set_eq:NN \l_tmpa_tl \l_getree_fanchart_major_angle_tl \tl_set_eq:NN \l_getree_fanchart_major_angle_tl \l_getree_fanchart_minor_angle_tl \tl_set_eq:NN \l_getree_fanchart_minor_angle_tl \l_tmpa_tl } \fp_set:Nn \l__getree_fanchart_angle_fp { (\l_getree_fanchart_major_angle_tl-\l_getree_fanchart_minor_angle_tl)/2 } \fp_set:Nn \l__getree_fanchart_inner_fp { \fparray_item:Nn\g__getree_fanchart_radii_fparry{1} } \tl_set:Nn \l_tmpa_tl {\fp_to_dim:n{ sqrt(2)*\l__getree_fanchart_inner_fp }} \use:x { \exp_not:N\pgfkeys{/gtr/level~0/.append~code={\exp_not:N\pgfkeysalso{node~size=\l_tmpa_tl,level~size=\l_tmpa_tl}}} } \int_step_inline:nnn {1} { \c_getree_fanchart_maximum_rings_tl-1 } { \fp_set:Nn \l__getree_fanchart_outer_fp { \fparray_item:Nn\g__getree_fanchart_radii_fparry{##1+1} } \fp_set:Nn \l__getree_fanchart_inner_off_fp { \l__getree_fanchart_inner_fp + \fparray_item:Nn\g__getree_fanchart_inner_fparry{##1} } \fp_set:Nn \l__getree_fanchart_outer_off_fp { \l__getree_fanchart_outer_fp - \fparray_item:Nn\g__getree_fanchart_outer_fparry{##1} } \fp_set:Nn \l__getree_fanchart_angle_fp { \l__getree_fanchart_angle_fp/2 } \fp_set:Nn \l__getree_fanchart_radius_fp { \l__getree_fanchart_inner_off_fp/\l__getree_fanchart_outer_off_fp } \fp_set:Nn \l_tmpb_fp { sqrt(\l__getree_fanchart_radius_fp^2+8) } \fp_set:Nn \l_tmpa_fp { sqrt( 1 - ( ( \l__getree_fanchart_radius_fp+\l_tmpb_fp )/4 )^2 ) } \fp_compare:nNnTF { \l__getree_fanchart_angle_fp<90 ? \l__getree_fanchart_radius_fp*tand(\l__getree_fanchart_angle_fp)<\l_tmpa_fp : 0 } = {0} { \tl_set:Nx \l_tmpa_tl {\fp_to_dim:n{ 2*\l_tmpa_fp*\l__getree_fanchart_outer_off_fp }}% b \tl_set:Nx \l_tmpb_tl {\fp_to_dim:n{ (\l_tmpb_fp-3*\l__getree_fanchart_radius_fp)/4*\l__getree_fanchart_outer_off_fp }}% h \fparray_gset:Nnn \g__getree_fanchart_distances_fparry { ##1 }{ (\l_tmpb_fp+5*\l__getree_fanchart_radius_fp)/8*\l__getree_fanchart_outer_off_fp } } { \fp_set:Nn \l_tmpa_fp { sqrt( 1 - ( \l__getree_fanchart_radius_fp*tand(\l__getree_fanchart_angle_fp) )^2 ) } \fp_set:Nn \l_tmpb_fp { cosd( \l__getree_fanchart_angle_fp/2 ) } \fp_compare:nNnTF {\l_tmpa_fp} < {\l_tmpb_fp} { \tl_set:Nx \l_tmpa_tl {\fp_to_dim:n{ 2*\l__getree_fanchart_radius_fp*tand(\l__getree_fanchart_angle_fp)*\l__getree_fanchart_outer_off_fp }}% b \tl_set:Nx \l_tmpb_tl {\fp_to_dim:n{ (\l_tmpa_fp-\l__getree_fanchart_radius_fp)*\l__getree_fanchart_outer_off_fp }}% h \fparray_gset:Nnn \g__getree_fanchart_distances_fparry { ##1 }{ (\l_tmpa_fp+\l__getree_fanchart_radius_fp)/2*\l__getree_fanchart_outer_off_fp } } { \tl_set:Nx \l_tmpa_tl {\fp_to_dim:n{ 2*sind(\l__getree_fanchart_angle_fp/2)*\l__getree_fanchart_outer_off_fp }}% b \tl_set:Nx \l_tmpb_tl {\fp_to_dim:n{ 1/(2*\l_tmpb_fp)*\l__getree_fanchart_outer_off_fp }}% h \fparray_gset:Nnn \g__getree_fanchart_distances_fparry { ##1 }{ (2*\l_tmpb_fp-1/(2*\l_tmpb_fp))/2*\l__getree_fanchart_outer_off_fp } } } \int_compare:nNnTF {##1} < {\l__getree_fanchart_landscape_level_tl} { \use:x { \exp_not:N\pgfkeys{/gtr/level~##1/.append~code={\exp_not:N\pgfkeysalso{node~size=\l_tmpa_tl,level~size=\l_tmpb_tl}}} } } { \use:x { \exp_not:N\pgfkeys{/gtr/level~##1/.append~code={\exp_not:N\pgfkeysalso{node~size=\l_tmpb_tl,level~size=\l_tmpa_tl}}} } } \fp_set_eq:NN \l__getree_fanchart_inner_fp \l__getree_fanchart_outer_fp } } \prg_new_conditional:Npnn \getree_fanchart_if_complemented_node: { p, TF } { \str_if_eq:VnTF \gtrcomplemented {true} { \prg_return_true: } { \prg_return_false: } } % #1: person number % #2: level % #3: angle a % #4: angle b \cs_new:Npn \__getree_fanchart_draw_person:nnnn #1#2#3#4 { \cs_set_nopar:Npx \gtr@currentperson {#1} \cs_set_nopar:Npx \gtrDBsex {\use:c{gtr@per@\gtr@currentperson @flag@s}} \cs_set_nopar:Npx \gtrDBrelation {\use:c{gtr@per@\gtr@currentperson @flag@r}} \cs_set_nopar:Npx \gtrcomplemented {\use:c{gtr@per@\gtr@currentperson @flag@c}} \tl_set:Nx \l_getree_fanchart_level_tl { \int_eval:n{#2} } \tl_set:Nx \l_getree_fanchart_id_tl {\cs_if_exist_use:c {gtr@per@\gtr@currentperson @id}} \int_compare:nNnTF {\l_getree_fanchart_level_tl} > {0} { \tl_set:Nx \l_getree_fanchart_angle_a_tl { \fp_to_decimal:n{#3} } \tl_set:Nx \l_getree_fanchart_angle_b_tl { \fp_to_decimal:n{#4} } \tl_set:Nx \l_getree_fanchart_ratio_tl { \fp_to_decimal:n{ ((\l_getree_fanchart_angle_a_tl+\l_getree_fanchart_angle_b_tl)/2-\l_getree_fanchart_minor_angle_tl)/ (\l_getree_fanchart_major_angle_tl-\l_getree_fanchart_minor_angle_tl) } } \tl_set:Nx \l_getree_fanchart_radius_a_tl { \fp_to_dim:n{\fparray_item:Nn\g__getree_fanchart_radii_fparry{#2}} } \fp_set:Nn \l_tmpa_fp { \fparray_item:Nn\g__getree_fanchart_radii_fparry{#2+1} } \fp_compare:nNnT {\l_tmpa_fp} > {\l__getree_fanchart_bounds_xmax_fp} { \fp_set_eq:NN \l__getree_fanchart_bounds_xmax_fp \l_tmpa_fp } \tl_set:Nx \l_getree_fanchart_radius_b_tl { \fp_to_dim:n{\l_tmpa_fp} } \tl_set:Nx \l_getree_fanchart_offset_a_tl { \fp_to_dim:n{\fparray_item:Nn\g__getree_fanchart_inner_fparry{#2}} } \tl_set:Nx \l_getree_fanchart_offset_b_tl { \fp_to_dim:n{\fparray_item:Nn\g__getree_fanchart_outer_fparry{#2}} } \tl_set:Nx \l_getree_fanchart_line_width_tl { \fp_to_dim:n { min(\l__getree_fanchart_boundary_width_fp, \l_getree_fanchart_radius_a_tl*(\l_getree_fanchart_angle_b_tl-\l_getree_fanchart_angle_a_tl)*\l__getree_fanchart_boundary_scale_fp/2000) } } \__getree_fanchart_segment_definition: \__getree_fanchart_marker_definition: \__getree_fanchart_draw_segment: \fp_set:Nn \l__getree_fanchart_angle_fp {(\l_getree_fanchart_angle_a_tl+\l_getree_fanchart_angle_b_tl)/2} \fp_set:Nn \l__getree_fanchart_radius_fp { \fparray_item:Nn\g__getree_fanchart_distances_fparry{#2} } \int_compare:nNnTF {#2} < {\l__getree_fanchart_landscape_level_tl} { \__getree_fanchart_portrait_angle:nnn { \fp_compare:nNnTF {sind(\l__getree_fanchart_angle_fp)} < {0} { \fp_set:Nn \l_tmpa_fp { \l__getree_fanchart_angle_fp+90 } } { \fp_set:Nn \l_tmpa_fp { \l__getree_fanchart_angle_fp-90 } } } { \fp_set:Nn \l_tmpa_fp { \l__getree_fanchart_angle_fp-90 } } { \fp_set:Nn \l_tmpa_fp { \l__getree_fanchart_angle_fp+90 } } } { \__getree_fanchart_landscape_angle:nnn { \fp_compare:nNnTF {cosd(\l__getree_fanchart_angle_fp)} < {0} { \fp_set:Nn \l_tmpa_fp { \l__getree_fanchart_angle_fp-180 } } { \fp_set_eq:NN \l_tmpa_fp \l__getree_fanchart_angle_fp } } { \fp_set_eq:NN \l_tmpa_fp \l__getree_fanchart_angle_fp } { \fp_set:Nn \l_tmpa_fp { \l__getree_fanchart_angle_fp-180 } } } \node[rotate=\fp_to_decimal:N\l_tmpa_fp] at (\fp_to_decimal:N\l__getree_fanchart_angle_fp \c_colon_str \fp_to_dim:N\l__getree_fanchart_radius_fp) {\unhbox\use:c{gtr@per@#1@box}}; } { \tl_set:Nx \l_getree_fanchart_radius_b_tl { \fp_to_dim:n{\fparray_item:Nn\g__getree_fanchart_radii_fparry{1}} } \tl_set:Nn \l_getree_fanchart_line_width_tl {\fp_to_dim:N\l__getree_fanchart_boundary_width_fp} \__getree_fanchart_draw_root: \node at ( 0,0 ) {\unhbox\use:c{gtr@per@#1@box}}; } } % #1: family number % #2: level % #3: angle a % #4: angle b \cs_new:Npn \__getree_fanchart_draw_family:nnnn #1#2#3#4 { \gtr@set@currentfamily{#1} \letcs\gtr@node{gtr@fam@\gtr@currentfamily @g} \__getree_fanchart_draw_person:nnnn {\gtr@node}{#2}{#3}{#4} \def\dodo##1 { \cs_if_exist:cT {gtr@per@##1@box} { \cs_if_exist:cTF {gtr@per@##1@chiof} { \tl_put_right:Nx\l__getree_fanchart_recursive_action_tl { \exp_not:N\__getree_fanchart_draw_family:nnnn { \use:c{gtr@per@##1@chiof} }{ \int_eval:n{#2+1} }{ #3 }{ \l_tmpa_tl } } } { \tl_put_right:Nx\l__getree_fanchart_recursive_action_tl { \exp_not:N\__getree_fanchart_draw_person:nnnn { ##1 }{ #2+1 }{ #3 }{ \l_tmpa_tl } } } } } \def\do##1 { \cs_if_exist:cT {gtr@per@##1@box} { \cs_if_exist:cTF {gtr@per@##1@chiof} { \tl_put_right:Nx\l__getree_fanchart_recursive_action_tl { \exp_not:N\__getree_fanchart_draw_family:nnnn { \use:c{gtr@per@##1@chiof} }{ \int_eval:n{#2+1} }{ \l_tmpa_tl }{ #4 } } } { \tl_put_right:Nx\l__getree_fanchart_recursive_action_tl { \exp_not:N\__getree_fanchart_draw_person:nnnn { ##1 }{ #2+1 }{ \l_tmpa_tl }{ #4 } } } } \let\do\dodo }% \cs_if_exist:cT {gtr@fam@\gtr@currentfamily @par} { \tl_set:Nx \l_tmpa_tl { \fp_to_decimal:n { (#3+#4)/2 } } \tl_clear:N\l__getree_fanchart_recursive_action_tl \dolistcsloop{gtr@fam@\gtr@currentfamily @par} \tl_use:N\l__getree_fanchart_recursive_action_tl } } \cs_new:Npn \__getree_fanchart_bounds_fit:n #1 { \fp_set:Nn \l_tmpa_fp { \l__getree_fanchart_radius_fp*cosd(#1) } \fp_compare:nNnTF {\l_tmpa_fp} < {\l__getree_fanchart_bounds_xmin_fp} { \fp_set_eq:NN \l__getree_fanchart_bounds_xmin_fp \l_tmpa_fp } { \fp_compare:nNnT {\l_tmpa_fp} > {\l__getree_fanchart_bounds_xmax_fp} { \fp_set_eq:NN \l__getree_fanchart_bounds_xmax_fp \l_tmpa_fp } } \fp_set:Nn \l_tmpa_fp { \l__getree_fanchart_radius_fp*sind(#1) } \fp_compare:nNnTF {\l_tmpa_fp} < {\l__getree_fanchart_bounds_ymin_fp} { \fp_set_eq:NN \l__getree_fanchart_bounds_ymin_fp \l_tmpa_fp } { \fp_compare:nNnT {\l_tmpa_fp} > {\l__getree_fanchart_bounds_ymax_fp} { \fp_set_eq:NN \l__getree_fanchart_bounds_ymax_fp \l_tmpa_fp } } } \cs_new:Npn \__getree_fanchart_reset_bounds: { \fp_set_eq:NN \l__getree_fanchart_radius_fp \l__getree_fanchart_bounds_xmax_fp \fp_set:Nn \l__getree_fanchart_bounds_xmax_fp { \fparray_item:Nn\g__getree_fanchart_radii_fparry{1} } \fp_set_eq:NN \l__getree_fanchart_bounds_ymax_fp \l__getree_fanchart_bounds_xmax_fp \fp_set:Nn \l__getree_fanchart_bounds_xmin_fp { -\l__getree_fanchart_bounds_xmax_fp } \fp_set_eq:NN \l__getree_fanchart_bounds_ymin_fp \l__getree_fanchart_bounds_xmin_fp \__getree_fanchart_bounds_fit:n { \l_getree_fanchart_minor_angle_tl } \__getree_fanchart_bounds_fit:n { \l_getree_fanchart_major_angle_tl } \fp_set:Nn \l__getree_fanchart_angle_fp { floor(\l_getree_fanchart_minor_angle_tl/90)*90+90 } \fp_while_do:nNnn {\l__getree_fanchart_angle_fp} < {\l_getree_fanchart_major_angle_tl} { \__getree_fanchart_bounds_fit:n { \l__getree_fanchart_angle_fp } \fp_set:Nn \l__getree_fanchart_angle_fp { \l__getree_fanchart_angle_fp+90 } } \pgfresetboundingbox \path (\fp_to_dim:n{\l__getree_fanchart_bounds_xmin_fp-\l__getree_fanchart_bounds_border_fp}, \fp_to_dim:n{\l__getree_fanchart_bounds_ymin_fp-\l__getree_fanchart_bounds_border_fp}) rectangle (\fp_to_dim:n{\l__getree_fanchart_bounds_xmax_fp+\l__getree_fanchart_bounds_border_fp}, \fp_to_dim:n{\l__getree_fanchart_bounds_ymax_fp+\l__getree_fanchart_bounds_border_fp}); } \cs_new:Npn \__getree_fanchart:nn #1#2 { \group_begin: \cs_if_exist:NF \pgfpictureid { \gtr@error{\gtrfanchart\space~outside~tikzpicture~environment} {\gtrfanchart\space~can~only~be~used~inside~a~tikzpicture~environment.} } \def\gtr@proc@@parent@end { \cs_if_exist:cF {gtr@fam@\gtr@currentfamily @g} { \gtr@error{No~g-node~in~parent~family~(\gtr@currentfamily)}{Every~family~needs~a~g-node} } } \def\gtr@positioning{} \gtrset{ phantom/.style={phantom*={##1}, code={ \cs_if_exist:NT \gtr@currentperson { \use:x { \exp_not:N\gappto\exp_not:N\gtrkv@after@parser{\exp_not:N\csundef{gtr@per@\gtr@currentperson @box}} } } } }, } \gtr@reset@before@parser \gtr@parsegraph [ processing = database, ignore~parent~childs, box = { empty, size = minimal, boxsep = \tcbfitdim/10, middle = \tcbfitdim/5, halign = center, valign = center, before~upper={\parskip=0.1\tcbfitdim}, }, level/.prefix~code= { \int_compare:nNnT {##1} > {5} { \pgfkeysalso{node={list~separators={\par}{~}{}{}}} } }, #1, code={\__getree_fanchart_segment_computation:} ]{#2} \gtrkv@after@parser \fp_zero:N \l__getree_fanchart_bounds_xmax_fp \__getree_fanchart_draw_family:nnnn{\gtr@num@fam@first}{0}{\l_getree_fanchart_minor_angle_tl}{\l_getree_fanchart_major_angle_tl} \bool_if:NT \l__getree_fanchart_reset_bounds_bool { \__getree_fanchart_reset_bounds: } \group_end: } \NewDocumentCommand{\gtrfanchart}{ +O{} } { \__getree_fanchart:nn {#1} } \NewDocumentCommand{\gtrfanchartinput}{ +O{} m } { \__getree_fanchart:nn {#1}{input{#2}} } %%%%%%%%%%%%%%%%%%%%%%% %% Options %%%%%%%%%%%%%%%%%%%%%%% \cs_new:Npn \__getree_fanchart_paper_fit:nn #1#2 { \fp_set:Nn \l_tmpa_fp {#1} \fp_set:Nn \l_tmpb_fp {#2} \fp_compare:nTF { \l_tmpa_fp > \l_tmpb_fp } { \fp_compare:nTF { \l_tmpb_fp > \l_tmpa_fp/2 } { \fp_set:Nn \l_tmpa_fp { 180+2*asind( 2*\l_tmpb_fp/\l_tmpa_fp - 1 ) } \gtrset { fanchart~open~up = \l_tmpa_fp, fanchart~text~portrait = inwards } } { \gtrset { fanchart~open~up = 180, fanchart~text~portrait = inwards } } } { \fp_compare:nTF { \l_tmpa_fp > \l_tmpb_fp/2 } { \fp_set:Nn \l_tmpa_fp { 180+2*asind( 2*\l_tmpa_fp/\l_tmpb_fp -1 ) } \gtrset { fanchart~open~right = \l_tmpa_fp, fanchart~text~landscape = clockwise } } { \gtrset { fanchart~open~right = 180, fanchart~text~landscape = clockwise } } } } \gtrset{ fanchart~radii/.code={ \clist_set:Nn \l_tmpa_clist {#1} \fparray_gzero:N \g__getree_fanchart_radii_fparry \int_zero:N \l_tmpa_int \fp_zero:N \l_tmpb_fp \clist_map_inline:Nn \l_tmpa_clist { \int_incr:N \l_tmpa_int \fp_set:Nn \l_tmpa_fp { ##1 } \fp_add:Nn \l_tmpb_fp {\l_tmpa_fp} \fparray_gset:Nnn \g__getree_fanchart_radii_fparry { \l_tmpa_int }{ \l_tmpb_fp } } \int_step_inline:nnn { \l_tmpa_int+1 }{ \c_getree_fanchart_maximum_rings_tl } { \fp_add:Nn \l_tmpb_fp {\l_tmpa_fp} \fparray_gset:Nnn \g__getree_fanchart_radii_fparry { ##1 }{ \l_tmpb_fp } } }, fanchart~inner~offset/.code={ \clist_set:Nn \l_tmpa_clist {#1} \fparray_gzero:N \g__getree_fanchart_inner_fparry \int_zero:N \l_tmpa_int \fp_zero:N \l_tmpa_fp \clist_map_inline:Nn \l_tmpa_clist { \int_incr:N \l_tmpa_int \fp_set:Nn \l_tmpa_fp { ##1 } \fparray_gset:Nnn \g__getree_fanchart_inner_fparry { \l_tmpa_int }{ \l_tmpa_fp } } \int_step_inline:nnn { \l_tmpa_int+1 }{ \c_getree_fanchart_maximum_rings_tl } { \fp_add:Nn \l_tmpb_fp {\l_tmpa_fp} \fparray_gset:Nnn \g__getree_fanchart_inner_fparry { ##1 }{ \l_tmpa_fp } } }, fanchart~outer~offset/.code={ \clist_set:Nn \l_tmpa_clist {#1} \fparray_gzero:N \g__getree_fanchart_outer_fparry \int_zero:N \l_tmpa_int \fp_zero:N \l_tmpa_fp \clist_map_inline:Nn \l_tmpa_clist { \int_incr:N \l_tmpa_int \fp_set:Nn \l_tmpa_fp { ##1 } \fparray_gset:Nnn \g__getree_fanchart_outer_fparry { \l_tmpa_int }{ \l_tmpa_fp } } \int_step_inline:nnn { \l_tmpa_int+1 }{ \c_getree_fanchart_maximum_rings_tl } { \fp_add:Nn \l_tmpb_fp {\l_tmpa_fp} \fparray_gset:Nnn \g__getree_fanchart_outer_fparry { ##1 }{ \l_tmpa_fp } } }, fanchart~minor~angle/.code={\tl_set:Nx \l_getree_fanchart_minor_angle_tl { \fp_to_decimal:n {#1} }}, fanchart~major~angle/.code={\tl_set:Nx \l_getree_fanchart_major_angle_tl { \fp_to_decimal:n {#1} }}, fanchart~open~up/.code={ \tl_set:Nx \l_getree_fanchart_minor_angle_tl { \fp_to_decimal:n {90-(#1)/2}} \tl_set:Nx \l_getree_fanchart_major_angle_tl { \fp_to_decimal:n {90+(#1)/2}} }, fanchart~open~up/.default=220, fanchart~open~left/.code={ \tl_set:Nx \l_getree_fanchart_minor_angle_tl { \fp_to_decimal:n {180-(#1)/2}} \tl_set:Nx \l_getree_fanchart_major_angle_tl { \fp_to_decimal:n {180+(#1)/2}} }, fanchart~open~left/.default=160, fanchart~open~right/.code={ \tl_set:Nx \l_getree_fanchart_minor_angle_tl { \fp_to_decimal:n {-(#1)/2}} \tl_set:Nx \l_getree_fanchart_major_angle_tl { \fp_to_decimal:n {(#1)/2}} }, fanchart~open~right/.default=160, fanchart~open~down/.code={ \tl_set:Nx \l_getree_fanchart_minor_angle_tl { \fp_to_decimal:n {270-(#1)/2}} \tl_set:Nx \l_getree_fanchart_major_angle_tl { \fp_to_decimal:n {270+(#1)/2}} }, fanchart~open~down/.default=220, fanchart~open~full/.style={fanchart~open~right=360}, fanchart~open~for/.code~args={#1x#2}{\__getree_fanchart_paper_fit:nn{#1}{#2}}, fanchart~landscape~from~level/.code={\tl_set:Nn\l__getree_fanchart_landscape_level_tl{#1}}, fanchart~text~portrait/.is~choice, fanchart~text~portrait/.default=auto, fanchart~text~portrait/auto/.code = \cs_set_eq:NN \__getree_fanchart_portrait_angle:nnn \use_i:nnn, fanchart~text~portrait/inwards/.code = \cs_set_eq:NN \__getree_fanchart_portrait_angle:nnn \use_ii:nnn, fanchart~text~portrait/outwards/.code = \cs_set_eq:NN \__getree_fanchart_portrait_angle:nnn \use_iii:nnn, fanchart~text~landscape/.is~choice, fanchart~text~landscape/.default=auto, fanchart~text~landscape/auto/.code = \cs_set_eq:NN \__getree_fanchart_landscape_angle:nnn \use_i:nnn, fanchart~text~landscape/clockwise/.code = \cs_set_eq:NN \__getree_fanchart_landscape_angle:nnn \use_ii:nnn, fanchart~text~landscape/counterclockwise/.code = \cs_set_eq:NN \__getree_fanchart_landscape_angle:nnn \use_iii:nnn, fanchart~boundary~color/.code={\colorlet{gtrfanchartboundary}{#1}}, fanchart~boundary~width/.code={ \fp_set:Nn \l__getree_fanchart_boundary_width_fp {#1} \fp_set:Nn \l__getree_fanchart_boundary_scale_fp {min(5,\l__getree_fanchart_boundary_width_fp/0.4pt)} }, fanchart~male~style/.code={\tikzset{gtr@fanchart@male@style/.style={#1}}}, fanchart~female~style/.code={\tikzset{gtr@fanchart@female@style/.style={#1}}}, fanchart~neuter~style/.code={\tikzset{gtr@fanchart@neuter@style/.style={#1}}}, fanchart~ancestor~style/.code={\tikzset{gtr@fanchart@ancestor@style/.style={#1}}}, fanchart~descendant~style/.code={\tikzset{gtr@fanchart@descendant@style/.style={#1}}}, fanchart~sibling~style/.code={\tikzset{gtr@fanchart@sibling@style/.style={#1}}}, fanchart~unrelated~style/.code={\tikzset{gtr@fanchart@unrelated@style/.style={#1}}}, fanchart~reset~bounds/.is~choice, fanchart~reset~bounds/.default=true, fanchart~reset~bounds/true/.code={\bool_set_true:N \l__getree_fanchart_reset_bounds_bool}, fanchart~reset~bounds/false/.code={\bool_set_false:N \l__getree_fanchart_reset_bounds_bool}, fanchart~bounds~border/.code={\fp_set:Nn \l__getree_fanchart_bounds_border_fp {#1}}, } %%%%%%%%%%%%%%%%%%%%%%% %% Segment Drawing %%%%%%%%%%%%%%%%%%%%%%% \cs_new:Npn \getree_fanchart_set_marker_style:n #1 { \getree_fanchart_if_complemented_node:TF { \tikzset{gtr@fanchart@marker@style/.style={#1, gtr@fanchart/@mark@level@\l_getree_fanchart_level_tl/.try, gtr@fanchart@marker@complemented }} } { \tikzset{gtr@fanchart@marker@style/.style={#1, gtr@fanchart/@mark@level@\l_getree_fanchart_level_tl/.try, gtr@fanchart/@mark@id@\l_getree_fanchart_id_tl/.try }} } } \cs_new:Npn \getree_fanchart_set_segment_style:n #1 { \getree_fanchart_if_complemented_node:TF { \tikzset{gtr@fanchart@segment@style/.style={#1, gtr@fanchart/@seg@level@\l_getree_fanchart_level_tl/.try, gtr@fanchart@segment@complemented }} } { \tikzset{gtr@fanchart@segment@style/.style={#1, gtr@fanchart/@seg@level@\l_getree_fanchart_level_tl/.try, gtr@fanchart/@seg@id@\l_getree_fanchart_id_tl/.try }} } } \cs_new:Npn \getree_fanchart_set_color_wave:n #1 { \definecolor{#1}{rgb:wave}{\fp_to_decimal:n { 400 + (1-\l_getree_fanchart_ratio_tl)*360 } } } % customize by \def\rangetHsb \cs_new:Npn \getree_fanchart_set_color_colorwheel:n #1 { \definecolor{#1}{rgb:tHsb}{\fp_to_decimal:n{(1-\l_getree_fanchart_ratio_tl)*360},1,1} } \cs_new:Npn \getree_fanchart_draw_path:n #1 { \path[#1] ( \l_getree_fanchart_angle_a_tl \c_colon_str \l_getree_fanchart_radius_a_tl ) arc ( \l_getree_fanchart_angle_a_tl \c_colon_str \l_getree_fanchart_angle_b_tl \c_colon_str \l_getree_fanchart_radius_a_tl ) -- ( \l_getree_fanchart_angle_b_tl \c_colon_str \l_getree_fanchart_radius_b_tl ) arc ( \l_getree_fanchart_angle_b_tl \c_colon_str \l_getree_fanchart_angle_a_tl \c_colon_str \l_getree_fanchart_radius_b_tl ) -- cycle; } \cs_new:Npn \getree_fanchart_draw_path:nnn #1#2#3 { \tl_set:Nx \l__getree_fanchart_tmpa_tl { \fp_to_dim:n {#1} } \tl_set:Nx \l__getree_fanchart_tmpb_tl { \fp_to_dim:n {#2} } \path[#3] ( \l_getree_fanchart_angle_a_tl \c_colon_str \l__getree_fanchart_tmpa_tl ) arc ( \l_getree_fanchart_angle_a_tl \c_colon_str \l_getree_fanchart_angle_b_tl \c_colon_str \l__getree_fanchart_tmpa_tl ) -- ( \l_getree_fanchart_angle_b_tl \c_colon_str \l__getree_fanchart_tmpb_tl ) arc ( \l_getree_fanchart_angle_b_tl \c_colon_str \l_getree_fanchart_angle_a_tl \c_colon_str \l__getree_fanchart_tmpb_tl ) -- cycle; } \cs_new:Npn \getree_fanchart_draw_segment_standard: { \fp_compare:nNnTF { \l_getree_fanchart_offset_b_tl } = { 0 } { \fp_compare:nNnTF { \l_getree_fanchart_offset_a_tl } = { 0 } { \getree_fanchart_draw_path:n { draw=gtrfanchartboundary,line~width=\l_getree_fanchart_line_width_tl,gtr@fanchart@segment@style } } { \getree_fanchart_draw_path:nnn {\l_getree_fanchart_radius_a_tl+\l_getree_fanchart_offset_a_tl} {\l_getree_fanchart_radius_b_tl} { draw=gtrfanchartboundary,line~width=\l_getree_fanchart_line_width_tl,gtr@fanchart@segment@style } } } { \getree_fanchart_draw_path:nnn {\l_getree_fanchart_radius_a_tl+\l_getree_fanchart_offset_a_tl} {\l_getree_fanchart_radius_b_tl-\l_getree_fanchart_offset_b_tl} { gtr@fanchart@segment@style } \getree_fanchart_draw_path:nnn {\l_getree_fanchart_radius_b_tl-\l_getree_fanchart_offset_b_tl} {\l_getree_fanchart_radius_b_tl} { gtr@fanchart@marker@style } \getree_fanchart_draw_path:nnn {\l_getree_fanchart_radius_a_tl+\l_getree_fanchart_offset_a_tl} {\l_getree_fanchart_radius_b_tl} { draw=gtrfanchartboundary,line~width=\l_getree_fanchart_line_width_tl } } } \cs_new:Npn \getree_fanchart_draw_root_style:n #1 { \path[draw=gtrfanchartboundary,line~width=\l_getree_fanchart_line_width_tl,#1] ( 0,0 ) circle[radius=\l_getree_fanchart_radius_b_tl]; } \gtrset { fanchart-segment-code/.code= { \cs_set:Npn \__getree_fanchart_draw_segment: {#1} }, fanchart-root-code/.code= { \cs_set:Npn \__getree_fanchart_draw_root: {#1} }, fanchart-marker-definition/.code= { \cs_set:Npn \__getree_fanchart_marker_definition: {#1} }, fanchart-segment-definition/.code= { \cs_set:Npn \__getree_fanchart_segment_definition: {#1} }, } \tikzset { gtr~set~color~wave/.code={\getree_fanchart_set_color_wave:n{#1}}, gtr~set~color~colorwheel/.code={\getree_fanchart_set_color_colorwheel:n{#1}}, gtr~set~color~series/.code={\colorlet{#1}{fanchart!![\l_getree_fanchart_level_tl]}}, } \gtrset { fanchart-segment-code={\getree_fanchart_draw_segment_standard:}, % fanchart~root~style/.style={fanchart-root-code={\getree_fanchart_draw_root_style:n{#1}}}, fanchart~root~malefemale/.style={fanchart-root-code={\getree_fanchart_draw_root_style:n{gtr@fanchart@\gtrDBsex @style}}}, % fanchart~segment~style/.style={fanchart-segment-definition={\getree_fanchart_set_segment_style:n{#1}}}, fanchart~segment~malefemale/.style={fanchart~segment~style={gtr@fanchart@\gtrDBsex @style}}, fanchart~segment~relation/.style={fanchart~segment~style={gtr@fanchart@\gtrDBrelation @style}}, fanchart~segment~wave/.style={fanchart~segment~style={ gtr~set~color~wave=gtr@fanchart@segment, top~color=gtr@fanchart@segment!20,bottom~color=gtr@fanchart@segment!25 }}, fanchart~segment~colorwheel/.style={fanchart~segment~style={ gtr~set~color~colorwheel=gtr@fanchart@segment, top~color=gtr@fanchart@segment!20,bottom~color=gtr@fanchart@segment!25 }}, fanchart~segment~radial/.style={fanchart~segment~style={ gtr~set~color~series=gtr@fanchart@segment, top~color=gtr@fanchart@segment!20,bottom~color=gtr@fanchart@segment!25 }}, % fanchart~marker~style/.style={fanchart-marker-definition={\getree_fanchart_set_marker_style:n{#1}}}, fanchart~marker~malefemale/.style={fanchart~marker~style={gtr@fanchart@\gtrDBsex @style}}, fanchart~marker~relation/.style={fanchart~marker~style={gtr@fanchart@\gtrDBrelation @style}}, fanchart~marker~wave/.style={fanchart~marker~style={ gtr~set~color~wave=gtr@fanchart@marker, fill=gtr@fanchart@marker }}, fanchart~marker~colorwheel/.style={fanchart~marker~style={ gtr~set~color~colorwheel=gtr@fanchart@marker, fill=gtr@fanchart@marker }}, fanchart~marker~radial/.style={fanchart~marker~style={ gtr~set~color~series=gtr@fanchart@marker, fill=gtr@fanchart@marker }}, % fanchart~complemented~segment~style/.code={\tikzset{gtr@fanchart@segment@complemented/.style={#1}}}, fanchart~complemented~marker~style/.code={\tikzset{gtr@fanchart@marker@complemented/.style={#1}}}, % fanchart~segment~style~for~levels/.code~2~args={ \clist_set:Nn \l_tmpa_clist {#1} \clist_map_inline:Nn \l_tmpa_clist { \tikzset{gtr@fanchart/@seg@level@##1/.style={#2}} } }, fanchart~marker~style~for~levels/.code~2~args={ \clist_set:Nn \l_tmpa_clist {#1} \clist_map_inline:Nn \l_tmpa_clist { \tikzset{gtr@fanchart/@mark@level@##1/.style={#2}} } }, fanchart~segment~style~for~ids/.code~2~args={ \clist_set:Nn \l_tmpa_clist {#1} \clist_map_inline:Nn \l_tmpa_clist { \tikzset{gtr@fanchart/@seg@id@##1/.style={#2}} } }, fanchart~marker~style~for~ids/.code~2~args={ \clist_set:Nn \l_tmpa_clist {#1} \clist_map_inline:Nn \l_tmpa_clist { \tikzset{gtr@fanchart/@mark@id@##1/.style={#2}} } }, } \ExplSyntaxOff \gtrset{ fanchart angles/.style args={#1:#2}{fanchart minor angle=#1,fanchart major angle=#2}, } \definecolorseries{fanchart}{rgb:hsb}{grad}[rgb:hsb]{.575,1,1}{.987,-.234,0} \resetcolorseries[12]{fanchart} %%%%%%%%%%%%%%%%%%%%%%% %% Templates %%%%%%%%%%%%%%%%%%%%%%% \gtrset { fanchart template/.is choice, % fanchart template/spartan/.style= { fanchart inner offset={0mm}, fanchart outer offset={0mm}, fanchart boundary color=gray!50, fanchart root style={fill=white}, fanchart segment style={fill=white}, empty name text={}, }, fanchart template/malefemale sober/.style= { fanchart inner offset={1mm}, fanchart outer offset={0mm}, fanchart boundary color=gray!50, fanchart root malefemale, fanchart segment malefemale, empty name text={}, }, fanchart template/malefemale relation/.style= { fanchart inner offset={1mm}, fanchart outer offset={2mm}, fanchart boundary color=gray!50, fanchart root malefemale, fanchart segment malefemale, fanchart marker relation, empty name text={}, }, fanchart template/colorwheel sober/.style= { fanchart inner offset={0mm}, fanchart outer offset={2mm}, fanchart boundary color=gray, fanchart root style={fill=white}, fanchart segment style={fill=white}, fanchart marker colorwheel, empty name text={}, }, fanchart template/colorwheel serious/.style= { fanchart inner offset={0mm}, fanchart outer offset={2mm}, fanchart boundary color=gray!50, fanchart root style={inner color=white,outer color=gray!4!white}, fanchart segment style={top color=gray!1!white,bottom color=gray!4!white}, fanchart marker colorwheel, empty name text={}, }, fanchart template/colorwheel malefemale/.style= { fanchart inner offset={1mm}, fanchart outer offset={2mm}, fanchart boundary color=gray!50, fanchart root malefemale, fanchart segment malefemale, fanchart marker colorwheel, empty name text={}, }, fanchart template/colorwheel rich/.style= { fanchart inner offset={1mm}, fanchart outer offset={0mm}, fanchart boundary color=white, fanchart root style={inner color=white,outer color=gray!15!white}, fanchart segment colorwheel, empty name text={}, }, fanchart template/colorwheel opulent/.style= { fanchart inner offset={1mm}, fanchart outer offset={2mm}, fanchart boundary color=white, fanchart root style={inner color=white,outer color=gray!15!white}, fanchart segment colorwheel, fanchart marker colorwheel, empty name text={}, }, % fanchart template/wave sober/.style= { fanchart inner offset={0mm}, fanchart outer offset={2mm}, fanchart boundary color=gray, fanchart root style={fill=white}, fanchart segment style={fill=white}, fanchart marker wave, empty name text={}, }, fanchart template/wave serious/.style= { fanchart inner offset={0mm}, fanchart outer offset={2mm}, fanchart boundary color=gray!50, fanchart root style={inner color=white,outer color=gray!4!white}, fanchart segment style={top color=gray!1!white,bottom color=gray!4!white}, fanchart marker wave, empty name text={}, }, fanchart template/wave malefemale/.style= { fanchart inner offset={1mm}, fanchart outer offset={2mm}, fanchart boundary color=gray!50, fanchart root malefemale, fanchart segment malefemale, fanchart marker wave, empty name text={}, }, fanchart template/wave rich/.style= { fanchart inner offset={1mm}, fanchart outer offset={0mm}, fanchart boundary color=white, fanchart root style={inner color=white,outer color=gray!15!white}, fanchart segment wave, empty name text={}, }, fanchart template/wave opulent/.style= { fanchart inner offset={1mm}, fanchart outer offset={2mm}, fanchart boundary color=white, fanchart root style={inner color=white,outer color=gray!15!white}, fanchart segment wave, fanchart marker wave, empty name text={}, }, fanchart template/radial sober/.style= { fanchart inner offset={0mm}, fanchart outer offset={2mm}, fanchart boundary color=gray, fanchart root style={fill=white}, fanchart segment style={fill=white}, fanchart marker radial, empty name text={}, }, fanchart template/radial serious/.style= { fanchart inner offset={0mm}, fanchart outer offset={2mm}, fanchart boundary color=gray!50, fanchart root style={inner color=white,outer color=gray!4!white}, fanchart segment style={top color=gray!1!white,bottom color=gray!4!white}, fanchart marker radial, empty name text={}, }, fanchart template/radial malefemale/.style= { fanchart inner offset={1mm}, fanchart outer offset={2mm}, fanchart boundary color=gray!50, fanchart root malefemale, fanchart segment malefemale, fanchart marker radial, empty name text={}, }, fanchart template/radial rich/.style= { fanchart inner offset={1mm}, fanchart outer offset={0mm}, fanchart boundary color=white, fanchart root style={inner color=white,outer color=gray!15!white}, fanchart segment radial, empty name text={}, }, fanchart template/radial opulent/.style= { fanchart inner offset={1mm}, fanchart outer offset={2mm}, fanchart boundary color=white, fanchart root style={inner color=white,outer color=gray!15!white}, fanchart segment radial, fanchart marker radial, empty name text={}, }, } %%%%%%%%%%%%%%%%%%%%%%% %% Presets %%%%%%%%%%%%%%%%%%%%%%% \gtrset{ fanchart radii={2.5cm,3.5cm,3cm}, fanchart inner offset={0mm}, fanchart outer offset={0mm}, fanchart open up=220, fanchart landscape from level=5, fanchart text portrait=auto, fanchart text landscape=auto, fanchart boundary color=gray!50, fanchart boundary width=0.4pt, fanchart male style={top color=blue!1!white,bottom color=blue!6!white}, fanchart female style={top color=red!1!white,bottom color=red!6!white}, fanchart neuter style={top color=gray!1!white,bottom color=gray!6!white}, fanchart ancestor style={fill=red!50!gray!50}, fanchart descendant style={fill=red!50!gray!50}, fanchart sibling style={fill=blue!50!gray!50}, fanchart unrelated style={fill=gray!15}, fanchart segment malefemale, fanchart root malefemale, fanchart marker style={fill=gtrfanchartboundary!50!white}, fanchart complemented segment style=, fanchart complemented marker style=, fanchart reset bounds, fanchart bounds border=0.2pt, }