diff options
author | Karl Berry <karl@freefriends.org> | 2024-03-08 23:16:17 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2024-03-08 23:16:17 +0000 |
commit | 7a013fab6544f4bf55266639cbaa0c965fbf6e6f (patch) | |
tree | d44e12c184a10fa425fed7016d04f8876d27fc45 /Master/texmf-dist/tex | |
parent | 09d578874592682e611910eec6ed9ed4c6e1b68b (diff) |
wheelchart (9mar24)
git-svn-id: svn://tug.org/texlive/trunk@70505 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r-- | Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty | 1944 |
1 files changed, 1189 insertions, 755 deletions
diff --git a/Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty b/Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty index af15d606540..e2c85439761 100644 --- a/Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty +++ b/Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty @@ -1,5 +1,5 @@ %% wheelchart.sty -%% Copyright 2023 Matthias Floré +%% Copyright 2022-2024 Matthias Floré % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c @@ -18,7 +18,7 @@ \NeedsTeXFormat{LaTeX2e} \RequirePackage{tikz} \usetikzlibrary{calc} -\ProvidesExplPackage{wheelchart}{2023/12/03}{2.0}{Draw wheelcharts with TikZ} +\ProvidesExplPackage{wheelchart}{2024/03/08}{3.0}{Diagrams with circular or other shapes using TikZ and LaTeX3} %%> \subsection{Variables} @@ -27,7 +27,6 @@ \bool_new:N \l__wheelchart_arc_bool \bool_new:N \l__wheelchart_contour_bool \bool_new:N \g__wheelchart_def_angle_radius_shift_bool -\bool_new:N \l__wheelchart_def_inner_contour_bool \bool_new:N \l__wheelchart_discrete_bool \bool_new:N \l__wheelchart_etoc_use_name_bool \bool_new:N \l__wheelchart_legend_only_bool @@ -46,33 +45,38 @@ \clist_new:N \g__wheelchart_slice_range_for_loop_clist \clist_new:N \l__wheelchart_slice_range_local_clist -\fp_const:Nn \c__wheelchart_arc_data_end_factor_center_fp { 0.5 } -\fp_const:Nn \c__wheelchart_arc_data_end_factor_left_fp { 1 } -\fp_const:Nn \c__wheelchart_arc_data_end_factor_right_fp { 0 } -\fp_const:Nn \c__wheelchart_arc_data_start_factor_center_fp { -0.5 } -\fp_const:Nn \c__wheelchart_arc_data_start_factor_left_fp { 0 } -\fp_const:Nn \c__wheelchart_arc_data_start_factor_right_fp { -1 } -\fp_new:N \l__wheelchart_abs_half_angle_minus_new_angle_fp \fp_new:N \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp \fp_new:N \l__wheelchart_anchor_xsep_fp \fp_new:N \l__wheelchart_anchor_ysep_fp \fp_new:N \g__wheelchart_angle_fp -\fp_new:N \l__wheelchart_angle_wheel_lines_fp +\fp_new:N \l__wheelchart_arc_around_line_fp \fp_new:N \l__wheelchart_arc_data_angle_pos_fp \fp_new:N \l__wheelchart_arc_data_angle_shift_fp +\fp_new:N \g__wheelchart_arc_data_aux_i_fp +\fp_new:N \g__wheelchart_arc_data_aux_ii_fp \fp_new:N \l__wheelchart_arc_data_dir_fp -\fp_new:N \g__wheelchart_arc_data_factor_fp +\fp_const:Nn \c__wheelchart_arc_data_end_factor_center_fp { 0.5 } +\fp_const:Nn \c__wheelchart_arc_data_end_factor_left_fp { 1 } +\fp_const:Nn \c__wheelchart_arc_data_end_factor_right_fp { 0 } +\fp_new:N \l__wheelchart_arc_data_line_sep_factor_fp \fp_new:N \l__wheelchart_arc_data_pos_fp +\fp_new:N \l__wheelchart_arc_data_radius_plot_false_fp \fp_new:N \l__wheelchart_arc_data_sep_fp \fp_new:N \g__wheelchart_arc_data_slice_length_fp +\fp_new:N \l__wheelchart_arc_data_start_angle_plot_false_fp +\fp_const:Nn \c__wheelchart_arc_data_start_factor_center_fp { -0.5 } +\fp_const:Nn \c__wheelchart_arc_data_start_factor_left_fp { 0 } +\fp_const:Nn \c__wheelchart_arc_data_start_factor_right_fp { -1 } +\fp_new:N \l__wheelchart_arc_data_text_pos_fp +\fp_new:N \l__wheelchart_arc_data_total_angle_plot_false_fp \fp_new:N \l__wheelchart_arc_pos_fp +\fp_new:N \l__wheelchart_arc_radius_fp \fp_new:N \l__wheelchart_arc_sep_fp +\fp_new:N \l__wheelchart_arc_start_angle_fp \fp_new:N \l__wheelchart_coord_determinant_fp +\fp_new:N \g__wheelchart_coord_x_fp +\fp_new:N \g__wheelchart_coord_y_fp \fp_new:N \l__wheelchart_counter_or_clockwise_fp -\fp_new:N \l__wheelchart_data_angle_pos_fp -\fp_new:N \l__wheelchart_data_angle_shift_fp -\fp_new:N \l__wheelchart_data_pos_fp -\fp_new:N \l__wheelchart_data_sep_fp \fp_new:N \g__wheelchart_def_angle_angle_fp \fp_new:N \l__wheelchart_discrete_end_length_fp \fp_new:N \l__wheelchart_discrete_factor_fp @@ -85,7 +89,6 @@ \fp_new:N \l__wheelchart_discrete_start_length_fp \fp_new:N \l__wheelchart_discrete_sublevel_end_length_fp \fp_new:N \l__wheelchart_discrete_sublevel_start_length_fp -\fp_new:N \l__wheelchart_explode_fp \fp_new:N \l__wheelchart_gap_fp \fp_new:N \l__wheelchart_gap_max_angle_fp \fp_new:N \l__wheelchart_gap_max_angle_def_fp @@ -96,14 +99,11 @@ \fp_new:N \l__wheelchart_inner_data_angle_shift_fp \fp_new:N \l__wheelchart_inner_data_pos_fp \fp_new:N \l__wheelchart_inner_data_sep_fp -\fp_new:c { l__wheelchart_inner~end_x_fp } -\fp_new:c { l__wheelchart_inner~end_y_fp } -\fp_new:N \l__wheelchart_inner_gap_fp -\fp_new:N \l__wheelchart_inner_plot_variable_fp +\fp_new:c { g__wheelchart_inner~end_x_fp } +\fp_new:c { g__wheelchart_inner~end_y_fp } \fp_new:N \l__wheelchart_inner_radius_fp -\fp_new:N \l__wheelchart_inner_radius_orig_fp -\fp_new:c { l__wheelchart_inner~start_x_fp } -\fp_new:c { l__wheelchart_inner~start_y_fp } +\fp_new:c { g__wheelchart_inner~start_x_fp } +\fp_new:c { g__wheelchart_inner~start_y_fp } \fp_new:N \l__wheelchart_lines_fp \fp_new:N \l__wheelchart_lines_angle_pos_fp \fp_new:N \l__wheelchart_lines_angle_shift_fp @@ -114,21 +114,14 @@ \fp_new:N \l__wheelchart_lines_pos_fp \fp_new:N \l__wheelchart_lines_sep_fp \fp_new:N \g__wheelchart_new_angle_fp -\fp_new:c { l__wheelchart_outer~end_x_fp } -\fp_new:c { l__wheelchart_outer~end_y_fp } -\fp_new:N \l__wheelchart_outer_gap_fp -\fp_new:N \l__wheelchart_outer_plot_variable_fp +\fp_new:c { g__wheelchart_outer~end_x_fp } +\fp_new:c { g__wheelchart_outer~end_y_fp } \fp_new:N \l__wheelchart_outer_radius_fp -\fp_new:c { l__wheelchart_outer~start_x_fp } -\fp_new:c { l__wheelchart_outer~start_y_fp } -\fp_new:N \l__wheelchart_plot_variable_fp -\fp_new:N \g__wheelchart_previous_x_coord_fp -\fp_new:N \g__wheelchart_previous_y_coord_fp +\fp_new:c { g__wheelchart_outer~start_x_fp } +\fp_new:c { g__wheelchart_outer~start_y_fp } +\fp_new:N \g__wheelchart_previous_coord_x_fp +\fp_new:N \g__wheelchart_previous_coord_y_fp \fp_new:N \l__wheelchart_samples_fp -\fp_new:N \l__wheelchart_slice_inner_end_angle_fp -\fp_new:N \l__wheelchart_slice_inner_start_angle_fp -\fp_new:N \l__wheelchart_slice_outer_end_angle_fp -\fp_new:N \l__wheelchart_slice_outer_start_angle_fp \fp_new:N \l__wheelchart_slices_angle_fp \fp_new:N \l__wheelchart_slices_angle_pos_fp \fp_new:N \l__wheelchart_slices_angle_shift_fp @@ -152,17 +145,11 @@ \fp_new:N \l__wheelchart_start_angle_fp \fp_new:N \l__wheelchart_total_angle_fp \fp_new:N \l__wheelchart_total_count_fp -\fp_new:N \l__wheelchart_value_fp -\fp_new:N \g__wheelchart_value_global_fp \fp_new:N \l__wheelchart_wheel_data_angle_pos_fp \fp_new:N \l__wheelchart_wheel_data_angle_shift_fp \fp_new:N \l__wheelchart_wheel_data_pos_fp \fp_new:N \l__wheelchart_wheel_data_sep_fp -\fp_new:N \g__wheelchart_x_coord_fp -\fp_new:N \g__wheelchart_y_coord_fp -\int_const:Nn \c__wheelchart_lines_ext_dir_left_int { -1 } -\int_const:Nn \c__wheelchart_lines_ext_dir_right_int { 1 } \int_new:N \g__wheelchart_discrete_count_int \int_new:N \l__wheelchart_discrete_levels_int \int_new:N \l__wheelchart_discrete_partitioning_first_index_int @@ -176,93 +163,104 @@ \int_new:N \l__wheelchart_legend_rows_int \int_new:N \l__wheelchart_lines_ext_bottom_dir_int \int_new:N \l__wheelchart_lines_ext_dir_int +\int_const:Nn \c__wheelchart_lines_ext_dir_left_int { -1 } +\int_const:Nn \c__wheelchart_lines_ext_dir_right_int { 1 } \int_new:N \l__wheelchart_lines_ext_top_dir_int -\int_new:N \l__wheelchart_slice_range_index_int +\int_new:N \l__wheelchart_max_list_items_int +\seq_new:N \l__wheelchart_arc_data_seq \seq_new:N \l__wheelchart_discrete_coefficients_first_seq \seq_new:N \l__wheelchart_discrete_coefficients_second_seq \seq_new:N \l__wheelchart_discrete_points_seq \seq_new:N \l__wheelchart_list_seq \seq_new:N \l__wheelchart_list_items_seq +\tl_new:N \WClegend +\tl_const:Nn \c__wheelchart_arc_around_text_aux_tl + { + sign ( \l__wheelchart_arc_data_dir_fp ) * + ( + \cs:w c__wheelchart_arc_data_start_factor_\l__wheelchart_arc_data_align_tl _fp\cs_end: + + \cs:w c__wheelchart_arc_data_end_factor_\l__wheelchart_arc_data_align_tl _fp\cs_end: + ) + } \tl_new:N \l__wheelchart_arc_data_align_tl \tl_new:N \l__wheelchart_data_anchor_tl \tl_new:N \l__wheelchart_etoc_level_tl \tl_new:N \l__wheelchart_etoc_name_tl \tl_new:N \l__wheelchart_expand_list_tl \tl_new:N \l__wheelchart_expand_list_items_tl -\tl_new:N \g__wheelchart_inner_contour_tl +\tl_new:N \l__wheelchart_inner_plot_variable_tl \tl_new:N \l__wheelchart_key_name_tl \tl_new:N \l__wheelchart_key_range_tl \tl_new:N \l__wheelchart_legend_row_tl \tl_new:N \g__wheelchart_name_tl -\tl_new:N \g__wheelchart_outer_contour_tl +\tl_new:N \l__wheelchart_outer_plot_variable_tl +\tl_new:N \l__wheelchart_plot_variable_tl +\tl_new:N \l__wheelchart_slice_range_index_tl \tl_new:N \l__wheelchart_slices_tl -\tl_new:N \l__wheelchart_slices_end_tl -\tl_set:Nn \l__wheelchart_slices_end_tl - { -- ( \fp_use:c { l__wheelchart_inner~end_x_fp } , \fp_use:c { l__wheelchart_inner~end_y_fp } ) } -\tl_new:N \l__wheelchart_slices_inner_tl -\tl_set:Nn \l__wheelchart_slices_inner_tl - { - \fp_compare:nNnT { \l__wheelchart_inner_radius_fp } > { 0 } - { - \fp_compare:nNnT { \l__wheelchart_inner_gap_fp } < { \l__wheelchart_abs_half_angle_minus_new_angle_fp } - { - arc - [ - start~angle = \fp_use:N \l__wheelchart_slice_inner_end_angle_fp , - end~angle = \fp_use:N \l__wheelchart_slice_inner_start_angle_fp , - radius = \fp_use:N \l__wheelchart_inner_radius_fp - ] - } - } - } -\tl_new:N \l__wheelchart_slices_outer_tl -\tl_set:Nn \l__wheelchart_slices_outer_tl - { - arc - [ - start~angle = \fp_use:N \l__wheelchart_slice_outer_start_angle_fp , - end~angle = \fp_use:N \l__wheelchart_slice_outer_end_angle_fp , - radius = \fp_use:N \l__wheelchart_outer_radius_fp - ] - } -\tl_new:N \l__wheelchart_slices_start_tl -\tl_set:Nn \l__wheelchart_slices_start_tl { -- cycle } +\tl_new:N \g__wheelchart_totalcount_tl \tl_new:N \l__wheelchart_type_tl \tl_set:Nn \l__wheelchart_type_tl { default } %%> \subsection{Functions} -\cs_generate_variant:Nn \seq_set_split:Nnn { Nen , Neo } +\cs_generate_variant:Nn \seq_set_split:Nnn { Nen , Neo , Nnf } \cs_generate_variant:Nn \tl_build_put_right:Nn { NV } -\cs_new:Npn \__wheelchart_arc_around_text:nnn #1#2#3 +\cs_new_protected:Npn \__wheelchart_arc_around_text_plot_false:nn #1#2 + { + \fp_set:Nn \l__wheelchart_arc_start_angle_fp + { + \__wheelchart_def_angle_plot_false:nnnnn + { \WCcount } + { \l__wheelchart_arc_data_angle_pos_fp } + { + ( 0.5 * \c__wheelchart_arc_around_text_aux_tl + #2 - 0.5 ) * \g__wheelchart_arc_data_aux_ii_fp + + \l__wheelchart_arc_data_angle_shift_fp + } + { \l__wheelchart_arc_pos_fp } + { \l__wheelchart_arc_sep_fp + \g__wheelchart_half_ex_over_one_cm_fp } + } + \path + [ draw , / wheelchart / arc_style , / wheelchart / arc_#1_half ] + ( \fp_use:N \l__wheelchart_arc_start_angle_fp \c_colon_str \fp_use:N \l__wheelchart_arc_radius_fp ) + arc + [ + start~angle = \fp_use:N \l__wheelchart_arc_start_angle_fp , + end~angle = + \__wheelchart_def_angle_plot_false:nnnnn + { \WCcount } + {#2} + { 0 } + { \l__wheelchart_arc_pos_fp } + { \l__wheelchart_arc_sep_fp + \g__wheelchart_half_ex_over_one_cm_fp } , + radius = \fp_use:N \l__wheelchart_arc_radius_fp + ] + ; + } + +\cs_new_protected:Npn \__wheelchart_arc_around_text_plot_true:nnn #1#2#3 { \__wheelchart_convex_comb_coord_plot:nnnnnnn { draw , / wheelchart / arc_style , / wheelchart / arc_#1_half } + { 1 } + { 0 } { + \l__wheelchart_plot_variable_tl * \fp_eval:n { - \l__wheelchart_arc_data_angle_pos_fp + 0.5 * \g__wheelchart_arc_data_factor_fp * - ( - sign ( \l__wheelchart_arc_data_dir_fp ) * - ( - \fp_use:c { c__wheelchart_arc_data_start_factor_\l__wheelchart_arc_data_align_tl _fp } - + \fp_use:c { c__wheelchart_arc_data_end_factor_\l__wheelchart_arc_data_align_tl _fp } - ) - + #2 - ) + \l__wheelchart_arc_data_angle_pos_fp + 0.5 * \g__wheelchart_arc_data_aux_ii_fp * + ( \c__wheelchart_arc_around_text_aux_tl + #2 ) } + + (#3) * ( 1 - \l__wheelchart_plot_variable_tl ) } - {#3} - { \l__wheelchart_plot_variable_fp } - { 0 } + { \l__wheelchart_plot_variable_tl * \l__wheelchart_arc_data_angle_shift_fp } { \l__wheelchart_arc_pos_fp } { \l__wheelchart_arc_sep_fp } } -\cs_new:Npn \__wheelchart_caption_and_title:nnnnn #1#2#3#4#5 +\cs_new_protected:Npn \__wheelchart_caption_and_title:nnnnn #1#2#3#4#5 { \__wheelchart_if_text:nn {#1} { @@ -284,12 +282,12 @@ { \fp_eval:n { - ( 1 - (#1) ) * \l__wheelchart_slice_inner_start_angle_fp - + (#1) * \l__wheelchart_slice_inner_end_angle_fp + ( 1 - (#1) ) * \cs:w g__wheelchart_slice_inner_start_angle_\WCcount _fp\cs_end: + + (#1) * \cs:w g__wheelchart_slice_inner_end_angle_\WCcount _fp\cs_end: + \l__wheelchart_counter_or_clockwise_fp * (#2) } } - { \fp_eval:n { \l__wheelchart_inner_radius_fp - (#4) } } + { \fp_eval:n { \cs:w g__wheelchart_inner_radius_\WCcount _fp\cs_end: - (#4) } } ) ! { \fp_eval:n {#3} } ! ( @@ -297,132 +295,196 @@ { \fp_eval:n { - ( 1 - (#1) ) * \l__wheelchart_slice_outer_start_angle_fp - + (#1) * \l__wheelchart_slice_outer_end_angle_fp + ( 1 - (#1) ) * \cs:w g__wheelchart_slice_outer_start_angle_\WCcount _fp\cs_end: + + (#1) * \cs:w g__wheelchart_slice_outer_end_angle_\WCcount _fp\cs_end: + \l__wheelchart_counter_or_clockwise_fp * (#2) } } - { \fp_eval:n { \l__wheelchart_outer_radius_fp + (#4) } } + { \fp_eval:n { \cs:w g__wheelchart_outer_radius_\WCcount _fp\cs_end: + (#4) } } ) $%note the () around the #i's to keep these contents together } -\cs_new:Npn \__wheelchart_convex_comb_coord:nnnn #1#2#3#4 - { \__wheelchart_convex_comb_coord_aux:o { \__wheelchart_convex_comb_coord_def:nnnn {#1} {#2} {#3} {#4} } } - -\cs_new:Npn \__wheelchart_convex_comb_coord_plot_aux:nnnn #1#2#3#4 +\cs_new_protected:Npn \__wheelchart_convex_comb_coord_plot_aux:nnnn #1#2#3#4 { \path [#1] plot [ domain = {#2} \c_colon_str {#3} , - samples = \fp_use:N \l__wheelchart_samples_fp , - variable = \l__wheelchart_plot_variable_fp + samples = \fp_use:c { g__wheelchart_samples_\WCcount _fp } , + variable = \l__wheelchart_plot_variable_tl ] ( {#4} ) ; } \cs_generate_variant:Nn \__wheelchart_convex_comb_coord_plot_aux:nnnn { nnno } -\cs_new:Npn \__wheelchart_convex_comb_coord_plot:nnnnnnn #1#2#3#4#5#6#7 +\cs_new_protected:Npn \__wheelchart_convex_comb_coord_plot:nnnnnnn #1#2#3#4#5#6#7 { \__wheelchart_convex_comb_coord_plot_aux:nnno {#1} {#2} {#3} { \__wheelchart_convex_comb_coord_def:nnnn {#4} {#5} {#6} { \g__wheelchart_half_ex_over_one_cm_fp + (#7) } } } -\cs_new:Npn \__wheelchart_def_angle:nnnN #1#2#3#4 +\cs_new_protected:Npn \__wheelchart_def_angle_aux: { - \path let - \p { l__wheelchart_def_angle_1 } = \__wheelchart_convex_comb_coord:nnnn {#1} {#2} { 0 } {#3} , - \p { l__wheelchart_def_angle_2 } = \__wheelchart_convex_comb_coord:nnnn {#1} {#2} { 1 } {#3} - in - [ - / utils / exec = - { - \bool_gset:Nn \g__wheelchart_def_angle_radius_shift_bool - { - \fp_compare_p:n - { - \y { l__wheelchart_def_angle_2 } - \y { l__wheelchart_def_angle_1 } == 0 - && - \x { l__wheelchart_def_angle_2 } - \x { l__wheelchart_def_angle_1 } == 0 - } - } - \bool_if:NF \g__wheelchart_def_angle_radius_shift_bool - { - \fp_gset:Nn \g__wheelchart_def_angle_angle_fp - { - atand - ( - \y { l__wheelchart_def_angle_2 } - \y { l__wheelchart_def_angle_1 } , - \x { l__wheelchart_def_angle_2 } - \x { l__wheelchart_def_angle_1 } - ) - }%here \pgf@xx and so on are not used - } - } - ] - ; - \bool_if:NT \g__wheelchart_def_angle_radius_shift_bool + \fp_gset:Nn \g__wheelchart_def_angle_angle_fp + { + atand + ( + ( + \pgf@xx * ( \y { l__wheelchart_def_angle_2 } - \y { l__wheelchart_def_angle_1 } ) + - \pgf@xy * ( \x { l__wheelchart_def_angle_2 } - \x { l__wheelchart_def_angle_1 } ) + ) + / \l__wheelchart_coord_determinant_fp , + ( + \pgf@yy * ( \x { l__wheelchart_def_angle_2 } - \x { l__wheelchart_def_angle_1 } ) + - \pgf@yx * ( \y { l__wheelchart_def_angle_2 } - \y { l__wheelchart_def_angle_1 } ) + ) + / \l__wheelchart_coord_determinant_fp + ) + }%\pgf@xx and so on are necessary if an option such as [x={(-0.5,0)},y={(0,0.5)}] is given to the tikzpicture + } + +\cs_new_protected:Npn \__wheelchart_def_angle:nnnn #1#2#3#4 + { + \bool_if:NTF \l__wheelchart_plot_bool { \path let - \p { l__wheelchart_def_angle_1 } = - \__wheelchart_convex_comb_coord:nnnn {#1} {#2} { 0 } { \fp_eval:n { (#3) + 1 / \l__wheelchart_samples_fp } } , - \p { l__wheelchart_def_angle_2 } = - \__wheelchart_convex_comb_coord:nnnn {#1} {#2} { 1 } { \fp_eval:n { (#3) + 1 / \l__wheelchart_samples_fp } } + \p { l__wheelchart_def_angle_1 } = \__wheelchart_point_plot_true:nnnnn { \WCcount } {#1} {#2} { 0 } {#4} , + \p { l__wheelchart_def_angle_2 } = \__wheelchart_point_plot_true:nnnnn { \WCcount } {#1} {#2} { 1 } {#4} in [ / utils / exec = { - \fp_gset:Nn \g__wheelchart_def_angle_angle_fp + \bool_gset:Nn \g__wheelchart_def_angle_radius_shift_bool { - atand - ( - \y { l__wheelchart_def_angle_2 } - \y { l__wheelchart_def_angle_1 } , - \x { l__wheelchart_def_angle_2 } - \x { l__wheelchart_def_angle_1 } - ) + \fp_compare_p:n + { + \y { l__wheelchart_def_angle_2 } - \y { l__wheelchart_def_angle_1 } == 0 + && + \x { l__wheelchart_def_angle_2 } - \x { l__wheelchart_def_angle_1 } == 0 + } } + \bool_if:NF \g__wheelchart_def_angle_radius_shift_bool + { \__wheelchart_def_angle_aux: } } ] - ;%here \pgf@xx and so on are not used + ; + \bool_if:NT \g__wheelchart_def_angle_radius_shift_bool + { + \path let + \p { l__wheelchart_def_angle_1 } = + \__wheelchart_point_plot_true:nnnnn { \WCcount } {#1} {#2} { 0 } + { \fp_eval:n { (#4) + 1 / \cs:w g__wheelchart_samples_\WCcount _fp\cs_end: } } , + \p { l__wheelchart_def_angle_2 } = + \__wheelchart_point_plot_true:nnnnn { \WCcount } {#1} {#2} { 1 } + { \fp_eval:n { (#4) + 1 / \cs:w g__wheelchart_samples_\WCcount _fp\cs_end: } } + in [ / utils / exec = { \__wheelchart_def_angle_aux: } ] + ; + } + \pgfmathparse { Mod ( \fp_use:N \g__wheelchart_def_angle_angle_fp , 360 ) } + } + { + \pgfmathparse { Mod ( \__wheelchart_def_angle_plot_false:nnnnn { \WCcount } {#1} {#2} {#3} {#4} , 360 ) } + } + } + +\cs_new:Npn \__wheelchart_def_angle_plot_false_aux_angle:nn #1#2 + { + ( 1 - (#2) ) * + ( + \cs:w g__wheelchart_slice_outer_start_angle_#1_fp\cs_end: + - \cs:w g__wheelchart_slice_inner_start_angle_#1_fp\cs_end: + ) + + (#2) * ( \cs:w g__wheelchart_slice_outer_end_angle_#1_fp\cs_end: - \cs:w g__wheelchart_slice_inner_end_angle_#1_fp\cs_end: ) + } + +\cs_new:Npn \__wheelchart_def_angle_plot_false:nnnnn #1#2#3#4#5 + { + \fp_eval:n + { + \fp_compare:nNnTF { \__wheelchart_def_angle_plot_false_aux_angle:nn {#1} {#2} } = { 0 } + { 0 } + { + asind + ( + ( + sqrt + ( + ( \cs:w g__wheelchart_outer_radius_#1_fp\cs_end: + \cs:w g__wheelchart_inner_radius_#1_fp\cs_end: ) ^ 2 + - \cs:w g__wheelchart_outer_radius_#1_fp\cs_end: * \cs:w g__wheelchart_inner_radius_#1_fp\cs_end: * + ( + 2 + 2 * cosd ( \__wheelchart_def_angle_plot_false_aux_angle:nn {#1} {#2} ) + + \cs:w g__wheelchart_outer_radius_#1_fp\cs_end: * \cs:w g__wheelchart_inner_radius_#1_fp\cs_end: + * + ( + ( + sind ( \__wheelchart_def_angle_plot_false_aux_angle:nn {#1} {#2} ) + / \__wheelchart_def_radius:nnn {#1} {#4} {#5} + ) + ^ 2 + ) + ) + ) + + \cs:w g__wheelchart_inner_radius_#1_fp\cs_end: * + ( + \cs:w g__wheelchart_inner_radius_#1_fp\cs_end: + - \cs:w g__wheelchart_outer_radius_#1_fp\cs_end: + * cosd ( \__wheelchart_def_angle_plot_false_aux_angle:nn {#1} {#2} ) + ) + / \__wheelchart_def_radius:nnn {#1} {#4} {#5} + ) + * \cs:w g__wheelchart_outer_radius_#1_fp\cs_end: * sind ( \__wheelchart_def_angle_plot_false_aux_angle:nn {#1} {#2} ) + / + ( + ( \cs:w g__wheelchart_outer_radius_#1_fp\cs_end: + \cs:w g__wheelchart_inner_radius_#1_fp\cs_end: ) ^ 2 + - 2 * \cs:w g__wheelchart_outer_radius_#1_fp\cs_end: * \cs:w g__wheelchart_inner_radius_#1_fp\cs_end: + * ( 1 + cosd ( \__wheelchart_def_angle_plot_false_aux_angle:nn {#1} {#2} ) ) + ) + ) + } + + ( 1 - (#2) ) * ( \cs:w g__wheelchart_slice_inner_start_angle_#1_fp\cs_end: ) + + (#2) * ( \cs:w g__wheelchart_slice_inner_end_angle_#1_fp\cs_end: ) + + \l__wheelchart_counter_or_clockwise_fp * (#3) } - \pgfmathsetmacro {#4} { Mod ( \fp_use:N \g__wheelchart_def_angle_angle_fp , 360 ) } } -\cs_new:Npn \__wheelchart_def_coord_aux:nn #1#2 +\cs_new_protected:Npn \__wheelchart_def_coord:nnnn #1#2#3#4 { - \path let \p { l__wheelchart_coord } = ( \use:c { __wheelchart_#1_plot:nn } {#2} { \fp_use:c { l__wheelchart_#1_radius_fp } } ) + \path let \p { l__wheelchart_coord } = + ( \cs:w __wheelchart_#2_plot:nn\cs_end: {#4} { \fp_use:c { g__wheelchart_#2_radius_\WCcount _fp } } ) in [ / utils / exec = { - \fp_gset:Nn \g__wheelchart_x_coord_fp + \fp_gset:cn { g__wheelchart_#1_x_fp } { ( \pgf@yy * \x { l__wheelchart_coord } - \pgf@yx * \y { l__wheelchart_coord } ) / \l__wheelchart_coord_determinant_fp } - \fp_gset:Nn \g__wheelchart_y_coord_fp + \fp_gset:cn { g__wheelchart_#1_y_fp } { ( \pgf@xx * \y { l__wheelchart_coord } - \pgf@xy * \x { l__wheelchart_coord } ) / \l__wheelchart_coord_determinant_fp } } ] + coordinate ( g__wheelchart_slice_\WCcount _#2~#3_coordinate ) at ( \p { l__wheelchart_coord } ) ; } -\cs_new:Npn \__wheelchart_def_coord:nn #1#2 +\cs_new_protected:Npn \__wheelchart_def_fp:nn #1#2 { - \__wheelchart_def_coord_aux:nn {#1} { \fp_use:c { l__wheelchart_slice_#1_#2_angle_fp } } - \fp_set_eq:cN { l__wheelchart_#1~#2_x_fp } \g__wheelchart_x_coord_fp - \fp_set_eq:cN { l__wheelchart_#1~#2_y_fp } \g__wheelchart_y_coord_fp + \pgfmathparse { \pgfkeysvalueof { / wheelchart / #2 } } + \fp_set:cn { l__wheelchart_#1_fp } { \pgfmathresult } } -\cs_new:Npn \__wheelchart_def_gap:NN #1#2 +\cs_new_protected:Npn \__wheelchart_def_gap:nn #1#2 { - \fp_set:Nn #1 + \fp_gset:cn { g__wheelchart_#1_gap_\WCcount _fp } { (#2) * sind ( min ( \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp , \l__wheelchart_gap_max_angle_def_fp ) ) < \l__wheelchart_gap_fp ? - min ( \l__wheelchart_abs_half_angle_minus_new_angle_fp , \l__wheelchart_gap_max_angle_def_fp ) + min ( \cs:w g__wheelchart_abs_half_angle_minus_new_angle_\WCcount _fp\cs_end: , \l__wheelchart_gap_max_angle_def_fp ) : asind ( min ( \l__wheelchart_gap_fp / ( (#2) + 1 - sign (#2) ) , 1 ) ) + \l__wheelchart_gap_polar_fp %note the min ( ... , 1 ) such that the asind is always defined @@ -430,70 +492,125 @@ } } -\cs_new:Npn \__wheelchart_def_macro:Nn #1#2 +\cs_new_protected:Npn \__wheelchart_def_inner_radius: { - \str_case:enF { \pgfkeysvalueof { / wheelchart / parse } } + \bool_if:NTF \l__wheelchart_pie_bool + { \fp_set:Nn \l__wheelchart_inner_radius_fp { 0 } } { - { pgfmath } - { - \pgfmathparse {#2} - \fp_set:Nn #1 { \pgfmathresult } - } - { l3fp } - { \fp_set:Nn #1 {#2} } + \pgfmathparse { \pgfkeysvalueof { / wheelchart / inner~radius } } + \fp_set:Nn \l__wheelchart_inner_radius_fp { \pgfmathresult + \l__wheelchart_gap_radius_fp } } - { \pgfkeys { / errors / unknown~choice~value /. expanded = { parse } { \pgfkeysvalueof { / wheelchart / parse } } } } } -\cs_new:Npn \__wheelchart_def_macros:n #1 +\cs_new_protected:Npn \__wheelchart_def_orientation: + {%determine the orientation, this is necessary even if no plot is used, for example if + %inner radius > outer radius then \g__wheelchart_slices_orientation_fp is different from + %\l__wheelchart_counter_or_clockwise_fp + \fp_set:Nn \l__wheelchart_slices_orientation_new_angle_fp + { + \g__wheelchart_angle_fp + + ( + \g__wheelchart_new_angle_fp == \g__wheelchart_angle_fp + ? + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp + : + \g__wheelchart_new_angle_fp - \g__wheelchart_angle_fp + ) + / \cs:w g__wheelchart_samples_1_fp\cs_end: + } + \path let + \p { l__wheelchart_slices_orientation_1 } = + ( + \__wheelchart_outer_plot:nn + { \fp_use:N \g__wheelchart_angle_fp } + { \fp_use:c { g__wheelchart_outer_radius_1_fp } } + ) , + \p { l__wheelchart_slices_orientation_2 } = + ( + \__wheelchart_outer_plot:nn + { \fp_use:N \l__wheelchart_slices_orientation_new_angle_fp } + { \fp_use:c { g__wheelchart_outer_radius_1_fp } } + ) , + \p { l__wheelchart_slices_orientation_3 } = + ( + \__wheelchart_inner_plot:nn + { \fp_use:N \l__wheelchart_slices_orientation_new_angle_fp } + { \fp_use:c { g__wheelchart_inner_radius_1_fp } } + ) , + \p { l__wheelchart_slices_orientation_4 } = + ( + \__wheelchart_inner_plot:nn + { \fp_use:N \g__wheelchart_angle_fp } + { \fp_use:c { g__wheelchart_inner_radius_1_fp } } + ) + in + [ + / utils / exec = + { + \fp_gset:Nn \g__wheelchart_slices_orientation_fp + { + sign + ( + 0.1 * \y { l__wheelchart_slices_orientation_1 } + * ( \x { l__wheelchart_slices_orientation_4 } - \x { l__wheelchart_slices_orientation_2 } ) + + 0.1 * \y { l__wheelchart_slices_orientation_2 } + * ( \x { l__wheelchart_slices_orientation_1 } - \x { l__wheelchart_slices_orientation_3 } ) + + 0.1 * \y { l__wheelchart_slices_orientation_3 } + * ( \x { l__wheelchart_slices_orientation_2 } - \x { l__wheelchart_slices_orientation_4 } ) + + 0.1 * \y { l__wheelchart_slices_orientation_4 } + * ( \x { l__wheelchart_slices_orientation_3 } - \x { l__wheelchart_slices_orientation_1 } ) + ) + * sign ( \l__wheelchart_coord_determinant_fp ) + } + } + ] + ;%the terms are multiplied with 0.1 to try to avoid an overflow + \fp_compare:nNnT { \g__wheelchart_slices_orientation_fp } = { 0 } + { \fp_gset_eq:NN \g__wheelchart_slices_orientation_fp \l__wheelchart_counter_or_clockwise_fp } + } + +\cs_new_protected:Npn \__wheelchart_def_outer_radius: + { + \pgfmathparse { \pgfkeysvalueof { / wheelchart / outer~radius } } + \fp_set:Nn \l__wheelchart_outer_radius_fp { \pgfmathresult - \l__wheelchart_gap_radius_fp } + } + +\cs_new:Npn \__wheelchart_def_radius:nnn #1#2#3 { - \str_case:enF { \pgfkeysvalueof { / wheelchart / parse } } + \fp_eval:n { - { pgfmath } - { - \clist_map_inline:nn {#1} - { - \pgfmathparse { \pgfkeysvalueof { / wheelchart / ##1 } } - \fp_set:cn { l__wheelchart_\str_map_function:nN {##1} \__wheelchart_space_to_underscore:n _fp } { \pgfmathresult } - } - } - { l3fp } - { - \clist_map_inline:nn {#1} - { - \fp_set:cn { l__wheelchart_\str_map_function:nN {##1} \__wheelchart_space_to_underscore:n _fp } - { \pgfkeysvalueof { / wheelchart / ##1 } } - } - } + ( 1 - (#2) ) * ( \cs:w g__wheelchart_inner_radius_#1_fp\cs_end: - (#3) ) + + (#2) * ( \cs:w g__wheelchart_outer_radius_#1_fp\cs_end: + (#3) ) } - { \pgfkeys { / errors / unknown~choice~value /. expanded = { parse } { \pgfkeysvalueof { / wheelchart / parse } } } } } -\cs_new:Npn \__wheelchart_def_slice_angle:nnnn #1#2#3#4 +\cs_new_protected:Npn \__wheelchart_def_slice_angle:nnnn #1#2#3#4 { + \fp_gzero_new:c { g__wheelchart_slice_#1_#2_angle_\WCcount _fp } \bool_if:NTF \l__wheelchart_plot_bool { - \fp_set:cn { l__wheelchart_slice_#1_#2_angle_fp } + \fp_gset:cn { g__wheelchart_slice_#1_#2_angle_\WCcount _fp } { - \fp_use:c { g__wheelchart_#3angle_fp } + + \cs:w g__wheelchart_#3angle_fp\cs_end: + ( \l__wheelchart_counter_or_clockwise_fp * - ( (#4) * \fp_use:c { l__wheelchart_#1_gap_fp } + \fp_use:c { l__wheelchart_slices_#1_#2_angle_shift_fp } ) + ( (#4) * \cs:w g__wheelchart_#1_gap_\WCcount _fp\cs_end: + \cs:w l__wheelchart_slices_#1_#2_angle_shift_fp\cs_end: ) ) } } { - \fp_set:cn { l__wheelchart_slice_#1_#2_angle_fp } + \fp_gset:cn { g__wheelchart_slice_#1_#2_angle_\WCcount _fp } { - \fp_use:c { g__wheelchart_#3angle_fp } + + \cs:w g__wheelchart_#3angle_fp\cs_end: + ( \l__wheelchart_counter_or_clockwise_fp * ( - (#4) * \fp_use:c { l__wheelchart_#1_gap_fp } + \fp_use:c { l__wheelchart_slices_#1_#2_angle_shift_fp } + (#4) * \cs:w g__wheelchart_#1_gap_\WCcount _fp\cs_end: + \cs:w l__wheelchart_slices_#1_#2_angle_shift_fp\cs_end: - asind ( - \l__wheelchart_inner_radius_fp * sind ( \fp_use:c { l__wheelchart_slices_#1_#2_angle_shift_fp } ) - / \l__wheelchart_outer_radius_fp + \cs:w g__wheelchart_inner_radius_\WCcount _fp\cs_end: + * sind ( \cs:w l__wheelchart_slices_#1_#2_angle_shift_fp\cs_end: ) + / \cs:w g__wheelchart_outer_radius_\WCcount _fp\cs_end: ) ) ) @@ -501,7 +618,7 @@ } } -\cs_new:Npn \__wheelchart_def_slice_keys:n #1 +\cs_new_protected:Npn \__wheelchart_def_slice_keys:n #1 { {%note the double {{...}} such that the contents is in a group %such that pgfkeys which are specific to the current slice are local for this slice @@ -514,11 +631,10 @@ } } -\cs_new:Npn \__wheelchart_def_WClegend: +\cs_new_protected:Npn \__wheelchart_def_WClegend: { \int_set:Nn \l__wheelchart_legend_columns_int { \fp_eval:n { ceil ( \WCtotalcount / ceil ( \WCtotalcount / ( \pgfkeysvalueof { / wheelchart / legend~columns } ) ) ) } } - \cs_set:Npn \WClegend {} \tl_build_begin:N \WClegend \int_compare:nNnTF { \l__wheelchart_legend_columns_int } = { 1 } { \int_step_inline:nnn { 2 } { \WCtotalcount } { \__wheelchart_legend_append:nn {##1} { \\ } } } @@ -569,14 +685,14 @@ { \clist_if_empty:NTF \l__wheelchart_header_clist { - \int_step_inline:nn { \seq_count:N \l__wheelchart_list_items_seq } + \int_step_inline:nn { \l__wheelchart_max_list_items_int } { \cs_set:cpn { WCvar\int_to_Alph:n {##1} } { \cs:w l__wheelchart_item_WCvar\int_to_Alph:n {##1}_\theg__wheelchart_WCcount_counter\cs_end: } } } { - \int_step_inline:nn { \seq_count:N \l__wheelchart_list_items_seq } + \int_step_inline:nn { \l__wheelchart_max_list_items_int } { \cs_set:cpn { \pgfkeysvalueof { / wheelchart / header~prefix } \clist_item:Nn \l__wheelchart_header_clist {##1} } { @@ -601,13 +717,13 @@ ( atand ( - \fp_use:c { l__wheelchart_#3_y_fp } - \fp_use:c { l__wheelchart_#4_y_fp } , - \fp_use:c { l__wheelchart_#3_x_fp } - \fp_use:c { l__wheelchart_#4_x_fp } + \cs:w g__wheelchart_#3_y_fp\cs_end: - \cs:w g__wheelchart_#4_y_fp\cs_end: , + \cs:w g__wheelchart_#3_x_fp\cs_end: - \cs:w g__wheelchart_#4_x_fp\cs_end: ) - atand ( - \fp_use:c { l__wheelchart_#1_y_fp } - \fp_use:c { l__wheelchart_#2_y_fp } , - \fp_use:c { l__wheelchart_#1_x_fp } - \fp_use:c { l__wheelchart_#2_x_fp } + \cs:w g__wheelchart_#1_y_fp\cs_end: - \cs:w g__wheelchart_#2_y_fp\cs_end: , + \cs:w g__wheelchart_#1_x_fp\cs_end: - \cs:w g__wheelchart_#2_x_fp\cs_end: ) ) } @@ -616,17 +732,12 @@ )%note the Mod 360 because for example cos(90/2)\neq cos(-270/2) } -\cs_new:Npn \__wheelchart_discrete_algorithm: +\cs_new_protected:Npn \__wheelchart_discrete_algorithm: { - \__wheelchart_def_macros:n { discrete~factor , gap~radius , samples } - \__wheelchart_def_macro:Nn \l__wheelchart_outer_radius_fp - { \pgfkeysvalueof { / wheelchart / outer~radius } - \fp_use:N \l__wheelchart_gap_radius_fp } - \bool_if:NTF \l__wheelchart_pie_bool - { \fp_set:Nn \l__wheelchart_inner_radius_fp { 0 } } - { - \__wheelchart_def_macro:Nn \l__wheelchart_inner_radius_fp - { \pgfkeysvalueof { / wheelchart / inner~radius } + \fp_use:N \l__wheelchart_gap_radius_fp } - } + \__wheelchart_def_fp:nn { discrete_factor } { discrete~factor } + \__wheelchart_def_fp:nn { gap_radius } { gap~radius } + \__wheelchart_def_outer_radius: + \__wheelchart_def_inner_radius: \int_compare:nNnT { \l__wheelchart_discrete_space_at_borders_int } = { -1 } { \pgfkeys @@ -639,6 +750,7 @@ \seq_clear:N \l__wheelchart_discrete_points_seq \bool_if:NTF \l__wheelchart_plot_bool { + \__wheelchart_def_fp:nn { samples } { samples } \fp_zero:N \l__wheelchart_discrete_outer_length_fp \__wheelchart_discrete_def_coord:nn { outer } { 0 } \int_step_inline:nn { \fp_use:N \l__wheelchart_samples_fp - 1 } @@ -648,8 +760,8 @@ { sqrt ( - ( \g__wheelchart_x_coord_fp - \g__wheelchart_previous_x_coord_fp ) ^ 2 - + ( \g__wheelchart_y_coord_fp - \g__wheelchart_previous_y_coord_fp ) ^ 2 + ( \g__wheelchart_coord_x_fp - \g__wheelchart_previous_coord_x_fp ) ^ 2 + + ( \g__wheelchart_coord_y_fp - \g__wheelchart_previous_coord_y_fp ) ^ 2 ) } } @@ -658,8 +770,8 @@ { sqrt ( - ( \g__wheelchart_x_coord_fp - \g__wheelchart_previous_x_coord_fp ) ^ 2 - + ( \g__wheelchart_y_coord_fp - \g__wheelchart_previous_y_coord_fp ) ^ 2 + ( \g__wheelchart_coord_x_fp - \g__wheelchart_previous_coord_x_fp ) ^ 2 + + ( \g__wheelchart_coord_y_fp - \g__wheelchart_previous_coord_y_fp ) ^ 2 ) } \fp_zero:N \l__wheelchart_discrete_inner_length_fp @@ -670,8 +782,8 @@ { sqrt ( - ( \g__wheelchart_x_coord_fp - \g__wheelchart_previous_x_coord_fp ) ^ 2 - + ( \g__wheelchart_y_coord_fp - \g__wheelchart_previous_y_coord_fp ) ^ 2 + ( \g__wheelchart_coord_x_fp - \g__wheelchart_previous_coord_x_fp ) ^ 2 + + ( \g__wheelchart_coord_y_fp - \g__wheelchart_previous_coord_y_fp ) ^ 2 ) } } @@ -680,8 +792,8 @@ { sqrt ( - ( \g__wheelchart_x_coord_fp - \g__wheelchart_previous_x_coord_fp ) ^ 2 - + ( \g__wheelchart_y_coord_fp - \g__wheelchart_previous_y_coord_fp ) ^ 2 + ( \g__wheelchart_coord_x_fp - \g__wheelchart_previous_coord_x_fp ) ^ 2 + + ( \g__wheelchart_coord_y_fp - \g__wheelchart_previous_coord_y_fp ) ^ 2 ) } } @@ -857,9 +969,9 @@ \__wheelchart_for_loop:n { \pgfkeysvalueof { / wheelchart / before~slices } - \int_step_inline:nn { \fp_eval:n { round ( \l__wheelchart_value_fp ) } }%note that \fp_eval:n { round ( ... ) } is necessary - %even when the value is an integer because if parse=pgfmath then .0 is added and then - %\int_step_inline:nn { \fp_use:N \l__wheelchart_value_fp } would give the messages + \int_step_inline:nn { \fp_eval:n { round ( \cs:w g__wheelchart_value_\WCcount _fp\cs_end: ) } } + %note that \fp_eval:n { round ( ... ) } is necessary even when the value is an integer because if parse=pgfmath + %then .0 is added and then \int_step_inline:nn { \cs:w g__wheelchart_value_\WCcount _fp\cs_end: } would give the messages %Missing character: There is no . in font nullfont! Missing character: There is no 0 in font nullfont! { \int_gincr:N \g__wheelchart_discrete_count_int @@ -870,57 +982,84 @@ %greater than the rounded value of \WCtotalnum. %For example if there are 2 values 1.6 and 1.7 then these numbers are 4 and 3 and then there is no 4-th item in the list. %However only positive integer values make practical sense for this diagram. - \pic [ / wheelchart / slices_style ] at - ( - $ + \bool_if:NTF \l__wheelchart_plot_bool + { + \coordinate ( g__wheelchart_slice_##1_####1_coordinate ) at ( - \__wheelchart_inner_plot:nn - { - \fp_eval:n + $ + ( + \__wheelchart_inner_plot:nn { - \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp * - ( - \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq - { \l__wheelchart_discrete_partitioning_first_index_int } - ) + \fp_eval:n + { + \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp * + ( + \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq + { \l__wheelchart_discrete_partitioning_first_index_int } + ) + } } - } - { \fp_use:N \l__wheelchart_inner_radius_fp } - ) - ! - { - \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq - { \l__wheelchart_discrete_partitioning_second_index_int } - } - ! - ( - \__wheelchart_outer_plot:nn - { - \fp_eval:n + { \fp_use:N \l__wheelchart_inner_radius_fp } + ) + ! + { + \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq + { \l__wheelchart_discrete_partitioning_second_index_int } + } + ! + ( + \__wheelchart_outer_plot:nn { - \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp * - ( - \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq - { \l__wheelchart_discrete_partitioning_first_index_int } - ) + \fp_eval:n + { + \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp * + ( + \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq + { \l__wheelchart_discrete_partitioning_first_index_int } + ) + } } + { \fp_use:N \l__wheelchart_outer_radius_fp } + ) + $ + ) ; + } + { + \coordinate ( g__wheelchart_slice_##1_####1_coordinate ) at + ( + \fp_eval:n + { + \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp * + ( + \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq + { \l__wheelchart_discrete_partitioning_first_index_int } + ) } - { \fp_use:N \l__wheelchart_outer_radius_fp } - ) - $ - ) + \c_colon_str + \fp_eval:n + { + \l__wheelchart_inner_radius_fp + + \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq + { \l__wheelchart_discrete_partitioning_second_index_int } + * ( \l__wheelchart_outer_radius_fp - \l__wheelchart_inner_radius_fp ) + } + ) ; + } + \pic [ / wheelchart / slices_style ] at ( g__wheelchart_slice_##1_####1_coordinate ) { code = { \pgfkeysvalueof { / wheelchart / discrete~pic } } } ; } \pgfkeysvalueof { / wheelchart / after~slices } } } -\cs_new:Npn \__wheelchart_discrete_def_coord:nn #1#2 +\cs_new_protected:Npn \__wheelchart_discrete_def_coord:nn #1#2 { - \fp_gset_eq:NN \g__wheelchart_previous_x_coord_fp \g__wheelchart_x_coord_fp - \fp_gset_eq:NN \g__wheelchart_previous_y_coord_fp \g__wheelchart_y_coord_fp - \__wheelchart_def_coord_aux:nn + \fp_gset_eq:NN \g__wheelchart_previous_coord_x_fp \g__wheelchart_coord_x_fp + \fp_gset_eq:NN \g__wheelchart_previous_coord_y_fp \g__wheelchart_coord_y_fp + \__wheelchart_def_coord:nnnn + { coord } {#1} + {} { \fp_eval:n { @@ -930,134 +1069,33 @@ } } -\cs_new:Npn \__wheelchart_for_loop:n #1 +\cs_new_protected:Npn \__wheelchart_for_loop:n #1 { - \fp_gset_eq:NN \g__wheelchart_angle_fp \l__wheelchart_start_angle_fp \__wheelchart_for_loop_initial:n { \__wheelchart_def_slice_keys:n { - \fp_set_eq:Nc \l__wheelchart_value_fp { l__wheelchart_value_\WCcount _fp } \cs_set_eq:Nc \WCpercentage { l__wheelchart_WCpercentage_\WCcount } \cs_set_eq:Nc \WCpercentagerounded { l__wheelchart_WCpercentagerounded_\WCcount } - \fp_gset:Nn \g__wheelchart_new_angle_fp - { - \WCcount == \WCtotalcount - ? - \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp - : - \g__wheelchart_angle_fp + - ( - \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_value_fp - * ( \l__wheelchart_total_angle_fp / \WCtotalnum ) - ) - } - \__wheelchart_def_macros:n - { - data~angle~pos , - gap , - gap~max~angle , - gap~polar , - gap~radius , - samples , - slices~inner~end~angle~shift , - slices~inner~start~angle~shift , - slices~outer~end~angle~shift , - slices~outer~start~angle~shift - } - \__wheelchart_def_macro:Nn \l__wheelchart_outer_radius_fp - { \pgfkeysvalueof { / wheelchart / outer~radius } - \fp_use:N \l__wheelchart_gap_radius_fp } - \bool_if:NTF \l__wheelchart_pie_bool - { \fp_set:Nn \l__wheelchart_inner_radius_fp { 0 } } - { - \__wheelchart_def_macro:Nn \l__wheelchart_inner_radius_fp - { \pgfkeysvalueof { / wheelchart / inner~radius } + \fp_use:N \l__wheelchart_gap_radius_fp } - } - \fp_set_eq:NN \l__wheelchart_inner_radius_orig_fp \l__wheelchart_inner_radius_fp - \fp_set:Nn \l__wheelchart_abs_half_angle_minus_new_angle_fp - { abs ( \g__wheelchart_angle_fp - \g__wheelchart_new_angle_fp ) / 2 } - \fp_set:Nn \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp - { \l__wheelchart_abs_half_angle_minus_new_angle_fp - \l__wheelchart_gap_polar_fp } - \bool_if:NTF \l__wheelchart_plot_bool - { - \fp_set_eq:NN \l__wheelchart_outer_gap_fp \l__wheelchart_gap_polar_fp - \fp_set_eq:NN \l__wheelchart_inner_gap_fp \l__wheelchart_gap_polar_fp - } - { - \fp_set:Nn \l__wheelchart_gap_max_angle_def_fp - { - \l__wheelchart_inner_radius_fp > 0 - ? - 90 - : - ( - sind ( \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp ) < 0.001 - ? - ( - 90 < \l__wheelchart_gap_max_angle_fp && \l__wheelchart_gap_max_angle_fp < 180 - ? - \l__wheelchart_gap_max_angle_fp - : - 90 - ) - : - ( - \l__wheelchart_gap_max_angle_fp < 90 || \l__wheelchart_gap_max_angle_fp > 180 - ? - 180 - : - \l__wheelchart_gap_max_angle_fp - ) - ) - } - \__wheelchart_def_gap:NN \l__wheelchart_outer_gap_fp \l__wheelchart_outer_radius_fp - \__wheelchart_def_gap:NN \l__wheelchart_inner_gap_fp \l__wheelchart_inner_radius_fp - \fp_compare:nNnT { \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp } > { 0.01 } - { - \fp_set:Nn \l__wheelchart_inner_radius_fp - { - max - ( - \l__wheelchart_gap_fp - / sind - ( - min - ( - \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp , - \l__wheelchart_gap_max_angle_def_fp - ) - ) - , - \l__wheelchart_inner_radius_fp - ) - } - } - } - \__wheelchart_def_slice_angle:nnnn { inner } { end } { new_ } { -1 } - \__wheelchart_def_slice_angle:nnnn { inner } { start } {} { 1 } - \__wheelchart_def_slice_angle:nnnn { outer } { end } { new_ } { -1 } - \__wheelchart_def_slice_angle:nnnn { outer } { start } {} { 1 } - \__wheelchart_def_angle:nnnN { 0.5 } { 0 } { 0 } \WCmidangle - \__wheelchart_def_macros:n { data~angle~shift , data~sep } - \__wheelchart_def_angle:nnnN - { \l__wheelchart_data_angle_pos_fp } - { \l__wheelchart_data_angle_shift_fp } - { \l__wheelchart_data_sep_fp } - \WCdataangle - \__wheelchart_def_macros:n { explode } + \cs_set:Npe \WCdataangle + { \fp_use:c { g__wheelchart_WCdataangle_\WCcount _fp } } + \cs_set:Npe \WCmidangle + { \fp_use:c { g__wheelchart_WCmidangle_\WCcount _fp } } \pgfkeysvalueof { / wheelchart / for~loop~start }%this must be placed after the definition of macros such as \WCpercentage %such that these macros can be used in the key for loop start \begin { scope } - [ shift = { ( \WCmidangle \c_colon_str \fp_use:N \l__wheelchart_explode_fp ) } , / wheelchart / slices_scope ] + [ + shift = { ( \WCmidangle \c_colon_str \fp_use:c { g__wheelchart_explode_\WCcount _fp } ) } , + / wheelchart / slices_scope + ] #1 \end { scope } - \fp_gset_eq:NN \g__wheelchart_angle_fp \g__wheelchart_new_angle_fp \pgfkeysvalueof { / wheelchart / for~loop~end } } } } -\cs_new:Npn \__wheelchart_for_loop_initial:n #1 +\cs_new_protected:Npn \__wheelchart_for_loop_initial:n #1 { \str_case:en { \l__wheelchart_type_tl } { @@ -1068,7 +1106,7 @@ \int_step_inline:nn { \WCtotalcount } { \cs_set:Npe \WCcount {##1} - \int_step_inline:nn { \seq_count:N \l__wheelchart_list_items_seq } + \int_step_inline:nn { \l__wheelchart_max_list_items_int } { \cs_set_eq:cc { WCvar\int_to_Alph:n {####1} } { l__wheelchart_item_WCvar\int_to_Alph:n {####1}_##1 } } #1 } @@ -1077,7 +1115,7 @@ \int_step_inline:nn { \WCtotalcount } { \cs_set:Npe \WCcount {##1} - \int_step_inline:nn { \seq_count:N \l__wheelchart_list_items_seq } + \int_step_inline:nn { \l__wheelchart_max_list_items_int } { \cs_set_eq:cc { \pgfkeysvalueof { / wheelchart / header~prefix } \clist_item:Nn \l__wheelchart_header_clist {####1} } @@ -1116,7 +1154,14 @@ } } -\cs_new:Npn \__wheelchart_if_text:nn #1#2 +\cs_new_protected:Npn \__wheelchart_gdef_count_fp:nn #1#2 + { + \fp_gzero_new:c { g__wheelchart_#1_\WCcount _fp } + \pgfmathparse { \pgfkeysvalueof { / wheelchart / #2 } } + \fp_gset:cn { g__wheelchart_#1_\WCcount _fp } { \pgfmathresult } + } + +\cs_new_protected:Npn \__wheelchart_if_text:nn #1#2 { %https://tex.stackexchange.com/questions/42280/expand-away-empty-macros-within-ifthenelse %https://tex.stackexchange.com/questions/44919/proper-way-to-detect-empty-blank-text @@ -1128,7 +1173,7 @@ { {#2} } } -\cs_new:Npn \__wheelchart_initial:n #1 +\cs_new_protected:Npn \__wheelchart_initial:n #1 { \str_case:en { \l__wheelchart_type_tl } { @@ -1137,17 +1182,20 @@ \tl_if_empty:nTF {#1} { \cs_set:Npn \WCtotalcount { 0 } } { - \use:c { seq_set_split:Ne\l__wheelchart_expand_list_tl } + \cs:w seq_set_split:Ne\l__wheelchart_expand_list_tl\cs_end: \l__wheelchart_list_seq { \pgfkeysvalueof { / wheelchart / separator~rows } } {#1} \cs_set:Npe \WCtotalcount { \seq_count:N \l__wheelchart_list_seq } + \int_zero:N \l__wheelchart_max_list_items_int \seq_map_indexed_inline:Nn \l__wheelchart_list_seq { - \use:c { seq_set_split:Ne\l__wheelchart_expand_list_items_tl } + \cs:w seq_set_split:Ne\l__wheelchart_expand_list_items_tl\cs_end: \l__wheelchart_list_items_seq { \pgfkeysvalueof { / wheelchart / separator~columns } } {##2} + \int_compare:nNnT { \seq_count:N \l__wheelchart_list_items_seq } > { \l__wheelchart_max_list_items_int } + { \int_set:Nn \l__wheelchart_max_list_items_int { \seq_count:N \l__wheelchart_list_items_seq } } %make sure that the namespace l__wheelchart_item_ below is unique \clist_if_empty:NTF \l__wheelchart_header_clist { @@ -1184,7 +1232,7 @@ { \cs_set:Npn \WCtotalcount { 0 } } } { - \@ifpackageloaded { etoc } {} + \IfPackageLoadedTF { etoc } {} { \PackageError { wheelchart } { The~package~etoc~must~be~loaded~to~use~the~key~etoc~level } {} } \etocsetlevel { part } { 0 } \etocsetlevel { chapter } { 0 } @@ -1197,7 +1245,7 @@ \etocsetnexttocdepth { -1 }%only for the next toc \etocsetstyle { \l__wheelchart_etoc_level_tl } {} {} { - \int_compare:nNnT { \int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } } > { 0 } + \int_compare:nNnT { \cs:w g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int\cs_end: } > { 0 } { \cs_gset:cpe { @@ -1256,7 +1304,7 @@ {} \int_gzero_new:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } \pgfkeysvalueof { / wheelchart / etoc~code } - \int_compare:nNnT { \int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } } > { 0 } + \int_compare:nNnT { \cs:w g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int\cs_end: } > { 0 } { \cs_gset:cpe { @@ -1282,27 +1330,41 @@ \__wheelchart_for_loop_initial:n { \__wheelchart_def_slice_keys:n - { - \__wheelchart_def_macros:n { value } - \fp_gset_eq:NN \g__wheelchart_value_global_fp \l__wheelchart_value_fp - } - \fp_zero_new:c { l__wheelchart_value_\WCcount _fp } - \fp_set_eq:cN { l__wheelchart_value_\WCcount _fp } \g__wheelchart_value_global_fp - \cs_set:Npe \WCtotalnum { \fp_eval:n { \WCtotalnum + \g__wheelchart_value_global_fp } } + { \__wheelchart_gdef_count_fp:nn { value } { value } } + \cs_set:Npe \WCtotalnum { \fp_eval:n { \WCtotalnum + \cs:w g__wheelchart_value_\WCcount _fp\cs_end: } } } \int_step_inline:nn { \WCtotalcount } { \cs_set:cpe { l__wheelchart_WCpercentage_##1 } - { \fp_eval:n { \fp_use:c { l__wheelchart_value_##1_fp } / ( \WCtotalnum / 100 ) } } + { \fp_eval:n { \cs:w g__wheelchart_value_##1_fp\cs_end: / ( \WCtotalnum / 100 ) } } \cs_set:cpe { l__wheelchart_WCpercentagerounded_##1 } { \fp_eval:n { round ( \cs:w l__wheelchart_WCpercentage_##1\cs_end: , \pgfkeysvalueof { / wheelchart / perc~precision } ) } } } } +\cs_new_protected:Npn \__wheelchart_inner_and_wheel_data:n #1 + { + \__wheelchart_if_text:nn { #1~data } + { + \__wheelchart_def_fp:nn { #1_data_angle_pos } { #1~data~angle~pos } + \__wheelchart_def_fp:nn { #1_data_angle_shift } { #1~data~angle~shift } + \__wheelchart_def_fp:nn { #1_data_pos } { #1~data~pos } + \__wheelchart_def_fp:nn { #1_data_sep } { #1~data~sep } + \node [ align = left , / wheelchart / #1_data_style ] at + \cs:w __wheelchart_point_plot_\bool_to_str:N \l__wheelchart_plot_bool :nnnnn\cs_end: + { \WCcount } + { \cs:w l__wheelchart_#1_data_angle_pos_fp\cs_end: } + { \cs:w l__wheelchart_#1_data_angle_shift_fp\cs_end: } + { \cs:w l__wheelchart_#1_data_pos_fp\cs_end: } + { \cs:w l__wheelchart_#1_data_sep_fp\cs_end: } + { \pgfkeysvalueof { / wheelchart / #1~data } } ; + } + } + \cs_new:Npn \__wheelchart_inner_plot:nn #1#2 { {#1} \c_colon_str {#2} } -\cs_new:Npn \__wheelchart_legend_append:nn #1#2 +\cs_new_protected:Npn \__wheelchart_legend_append:nn #1#2 { \tl_build_put_right:NV \WClegend \l__wheelchart_legend_row_tl%note the V specifier such that \WClegend can also be combined %with an S column of the package siunitx and such that \WClegend can be used in a tblr environment of the package tabularray @@ -1316,27 +1378,44 @@ \tl_build_put_right:Nn \WClegend {#2} } +\cs_new:Npn \__wheelchart_mod:n #1 + { + \int_eval:n + { + \int_mod:nn { (#1) - \int_compare:nNnTF {#1} > { 0 } { 1 } { 0 } } { \g__wheelchart_totalcount_tl } + + \int_compare:nNnTF {#1} > { 0 } { 1 } { \g__wheelchart_totalcount_tl } + } + } + \cs_new:Npn \__wheelchart_outer_plot:nn #1#2 { {#1} \c_colon_str {#2} } -\cs_new:Npn \__wheelchart_slices_arc:nnnnnn #1#2#3#4#5#6 +\cs_new:Npn \__wheelchart_point_plot_false:nnnnn #1#2#3#4#5 + { ( \__wheelchart_def_angle_plot_false:nnnnn {#1} {#2} {#3} {#4} {#5} \c_colon_str \__wheelchart_def_radius:nnn {#1} {#4} {#5} ) } + +\cs_new:Npn \__wheelchart_point_plot_true:nnnnn #1#2#3#4#5 + { \__wheelchart_convex_comb_coord_aux:o { \__wheelchart_convex_comb_coord_def:nnnn {#2} {#3} {#4} {#5} } } + +\cs_new_protected:Npn \__wheelchart_slices_arc:nnnnnn #1#2#3#4#5#6 { { [ / utils / exec = { - \__wheelchart_def_macro:Nn \l__wheelchart_slices_arc_A_fp {#1} + \pgfmathparse {#1} + \fp_set:Nn \l__wheelchart_slices_arc_A_fp { \pgfmathresult } #6 \fp_set:Nn \l__wheelchart_slices_arc_A_abs_fp { abs ( \l__wheelchart_slices_arc_A_fp ) } \fp_compare:nNnF { \l__wheelchart_slices_arc_A_abs_fp } < { 0.01 } { - \__wheelchart_def_macro:Nn \l__wheelchart_slices_arc_B_fp {#2} + \pgfmathparse {#2} + \fp_set:Nn \l__wheelchart_slices_arc_B_fp { \pgfmathresult } \fp_set:Nn \l__wheelchart_slices_arc_rotate_fp { atand ( - \fp_use:c { l__wheelchart_#3_y_fp } - \fp_use:c { l__wheelchart_#4_y_fp } , - \fp_use:c { l__wheelchart_#3_x_fp } - \fp_use:c { l__wheelchart_#4_x_fp } + \cs:w g__wheelchart_#3_y_fp\cs_end: - \cs:w g__wheelchart_#4_y_fp\cs_end: , + \cs:w g__wheelchart_#3_x_fp\cs_end: - \cs:w g__wheelchart_#4_x_fp\cs_end: ) } \fp_set:Nn \l__wheelchart_slices_arc_coord_fp @@ -1375,9 +1454,9 @@ -- ( $ - ( \fp_use:c { l__wheelchart_#3_x_fp } , \fp_use:c { l__wheelchart_#3_y_fp } ) + ( g__wheelchart_slice_\WCcount _#3_coordinate ) ! { \fp_eval:n { \l__wheelchart_slices_arc_coord_fp / 2 } } ! - ( \fp_use:c { l__wheelchart_#4_x_fp } , \fp_use:c { l__wheelchart_#4_y_fp } ) + ( g__wheelchart_slice_\WCcount _#4_coordinate ) $ ) } @@ -1407,8 +1486,8 @@ * abs ( ( 1 / \l__wheelchart_slices_arc_A_fp ) + \l__wheelchart_slices_arc_A_fp ) * sqrt ( - ( \fp_use:c { l__wheelchart_#3_x_fp } - \fp_use:c { l__wheelchart_#4_x_fp } ) ^ 2 - + ( \fp_use:c { l__wheelchart_#3_y_fp } - \fp_use:c { l__wheelchart_#4_y_fp } ) ^ 2 + ( \cs:w g__wheelchart_#3_x_fp\cs_end: - \cs:w g__wheelchart_#4_x_fp\cs_end: ) ^ 2 + + ( \cs:w g__wheelchart_#3_y_fp\cs_end: - \cs:w g__wheelchart_#4_y_fp\cs_end: ) ^ 2 ) } } @@ -1420,16 +1499,18 @@ } } -\cs_new:Npn \__wheelchart_slices_arrow:nnnnn #1#2#3#4#5 +\cs_new_protected:Npn \__wheelchart_slices_arrow:nnnnn #1#2#3#4#5 { { [ / utils / exec = { - \__wheelchart_def_macro:Nn \l__wheelchart_slices_arrow_A_fp {#1} + \pgfmathparse {#1} + \fp_set:Nn \l__wheelchart_slices_arrow_A_fp { \pgfmathresult } \fp_compare:nNnF { \l__wheelchart_slices_arrow_A_fp } = { 0 } { - \__wheelchart_def_macro:Nn \l__wheelchart_slices_arrow_B_fp {#2} + \pgfmathparse {#2} + \fp_set:Nn \l__wheelchart_slices_arrow_B_fp { \pgfmathresult } \fp_set:Nn \l__wheelchart_slices_arrow_coord_fp { \l__wheelchart_slices_arrow_A_fp < 0 && \l__wheelchart_slices_arrow_B_fp < 0 ? 0 : \l__wheelchart_slices_arrow_B_fp @@ -1447,9 +1528,9 @@ -- ( $ - ( \fp_use:c { l__wheelchart_#3_x_fp } , \fp_use:c { l__wheelchart_#3_y_fp } ) + ( g__wheelchart_slice_\WCcount _#3_coordinate ) ! { \fp_eval:n { \l__wheelchart_slices_arrow_coord_fp / 2 } } ! - ( \fp_use:c { l__wheelchart_#4_x_fp } , \fp_use:c { l__wheelchart_#4_y_fp } ) + ( g__wheelchart_slice_\WCcount _#4_coordinate ) $ ) } @@ -1458,11 +1539,11 @@ \fp_eval:n { ( - \fp_use:c { l__wheelchart_#3_x_fp } + \fp_use:c { l__wheelchart_#4_x_fp } + + \cs:w g__wheelchart_#3_x_fp\cs_end: + \cs:w g__wheelchart_#4_x_fp\cs_end: + ( \g__wheelchart_slices_orientation_fp * ( \l__wheelchart_slices_arrow_coord_fp - 1 ) * \l__wheelchart_slices_arrow_A_fp - * ( \fp_use:c { l__wheelchart_#3_y_fp } - \fp_use:c { l__wheelchart_#4_y_fp } ) + * ( \cs:w g__wheelchart_#3_y_fp\cs_end: - \cs:w g__wheelchart_#4_y_fp\cs_end: ) ) ) / 2 @@ -1471,11 +1552,11 @@ \fp_eval:n { ( - \fp_use:c { l__wheelchart_#3_y_fp } + \fp_use:c { l__wheelchart_#4_y_fp } + + \cs:w g__wheelchart_#3_y_fp\cs_end: + \cs:w g__wheelchart_#4_y_fp\cs_end: + ( \g__wheelchart_slices_orientation_fp * ( \l__wheelchart_slices_arrow_coord_fp - 1 ) * \l__wheelchart_slices_arrow_A_fp - * ( \fp_use:c { l__wheelchart_#4_x_fp } - \fp_use:c { l__wheelchart_#3_x_fp } ) + * ( \cs:w g__wheelchart_#4_x_fp\cs_end: - \cs:w g__wheelchart_#3_x_fp\cs_end: ) ) ) / 2 @@ -1486,9 +1567,9 @@ -- ( $ - ( \fp_use:c { l__wheelchart_#4_x_fp } , \fp_use:c { l__wheelchart_#4_y_fp } ) + ( g__wheelchart_slice_\WCcount _#4_coordinate ) ! { \fp_eval:n { \l__wheelchart_slices_arrow_coord_fp / 2 } } ! - ( \fp_use:c { l__wheelchart_#3_x_fp } , \fp_use:c { l__wheelchart_#3_y_fp } ) + ( g__wheelchart_slice_\WCcount _#3_coordinate ) $ ) } @@ -1508,8 +1589,16 @@ ] } -\cs_new:Npn \__wheelchart_space_to_underscore:n #1 - { \str_if_eq:nnTF {#1} { ~ } { _ } {#1} } +\cs_new:Npn \__wheelchart_wheel_lines_aux:nn #1#2 + { + \fp_eval:n + { + ( 1 - (#1) / max ( round ( \cs:w g__wheelchart_value_\WCcount _fp\cs_end: ) , 1 ) ) + * \cs:w g__wheelchart_slice_#2_start_angle_\WCcount _fp\cs_end: + + (#1) * \cs:w g__wheelchart_slice_#2_end_angle_\WCcount _fp\cs_end: + / max ( round ( \cs:w g__wheelchart_value_\WCcount _fp\cs_end: ) , 1 ) + } + } %%> \subsection{Pgfkeys} @@ -1526,6 +1615,7 @@ arc_style /. style = {#1} } , arc_style /. style = {} , + arc~around~line /. initial = 1 , arc~around~text /. default = true ,%this key is not set up with /.is choice or \bool_set:Nn %such that for example \WCvarA can be used as value for this key arc~around~text /. initial = false , @@ -1536,6 +1626,8 @@ arc~data~angle~pos /. initial = 0.5 , arc~data~angle~shift /. initial = 0 , arc~data~dir /. initial = 1 , + arc~data~expand /. initial = n , + arc~data~line~sep~factor /. initial = 1 , arc~data~pos /. initial = 1 , arc~data~sep /. initial = 1 ex / 1 cm , arc~data~style /. style = { arc_data_style /. style = {#1} } , @@ -1613,7 +1705,7 @@ \tl_set:Nn \l__wheelchart_etoc_level_tl {#1} } , etoc~name /. code = { \tl_set:Nn \l__wheelchart_etoc_name_tl {#1} } , - etoc~name = , + etoc~name = {} , etoc~use~name /. code = { \tl_set:Nn \l__wheelchart_etoc_name_tl {#1} @@ -1656,23 +1748,27 @@ inner~data~sep /. initial = 0.2 , inner~data~style /. style = { inner_data_style /. style = {#1} } , inner_data_style /. style = {} , - inner~plot /. code = + inner~plot /. style = { - \bool_set_true:N \l__wheelchart_plot_bool - \cs_set:Npn \__wheelchart_inner_plot:nn ##1##2 {#1} - \tl_set:Nn \l__wheelchart_slices_inner_tl + bool_set_true = \l__wheelchart_plot_bool , + / utils / exec = { \cs_set:Npn \__wheelchart_inner_plot:nn ##1##2 {#1} } , + slices~inner = { -- plot [ domain = - \fp_use:N \l__wheelchart_slice_inner_end_angle_fp + \fp_use:c { g__wheelchart_slice_inner_end_angle_\WCcount _fp } \c_colon_str - \fp_use:N \l__wheelchart_slice_inner_start_angle_fp , - samples = \fp_use:N \l__wheelchart_samples_fp , - variable = \l__wheelchart_inner_plot_variable_fp , + \fp_use:c { g__wheelchart_slice_inner_start_angle_\WCcount _fp } , + samples = \fp_use:c { g__wheelchart_samples_\WCcount _fp } , + variable = \l__wheelchart_inner_plot_variable_tl , / wheelchart / inner_plot_style ] - ( \__wheelchart_inner_plot:nn { \l__wheelchart_inner_plot_variable_fp } { \fp_use:N \l__wheelchart_inner_radius_fp } ) + ( + \__wheelchart_inner_plot:nn + { \l__wheelchart_inner_plot_variable_tl } + { \fp_use:c { g__wheelchart_inner_radius_\WCcount _fp } } + ) } } , inner~plot~style /. style = { inner_plot_style /. style = {#1} } , @@ -1710,16 +1806,22 @@ { \fp_eval:n { - \l__wheelchart_lines_ext_dir_int - * ( \l__wheelchart_outer_radius_fp + \l__wheelchart_lines_sep_fp + \l__wheelchart_lines_fp + \l__wheelchart_lines_ext_fp ) + \l__wheelchart_lines_ext_dir_int * + ( + \cs:w g__wheelchart_outer_radius_\WCcount _fp\cs_end: + \l__wheelchart_lines_sep_fp + + \l__wheelchart_lines_fp + \l__wheelchart_lines_ext_fp + ) } } , lines~ext~fixed~right /. initial = { \fp_eval:n { - \l__wheelchart_lines_ext_dir_int - * ( \l__wheelchart_outer_radius_fp + \l__wheelchart_lines_sep_fp + \l__wheelchart_lines_fp + \l__wheelchart_lines_ext_fp ) + \l__wheelchart_lines_ext_dir_int * + ( + \cs:w g__wheelchart_outer_radius_\WCcount _fp\cs_end: + \l__wheelchart_lines_sep_fp + + \l__wheelchart_lines_fp + \l__wheelchart_lines_ext_fp + ) } } , lines~ext~left~anchor /. initial = mid~east , @@ -1741,29 +1843,32 @@ middle_style /. style = {} , name /. code = { \tl_gset:Ne \g__wheelchart_name_tl {#1} } , name = wheelchart@name , - outer~plot /. code = + outer~plot /. style = { - \bool_set_true:N \l__wheelchart_plot_bool - \cs_set:Npn \__wheelchart_outer_plot:nn ##1##2 {#1} - \tl_set:Nn \l__wheelchart_slices_outer_tl + bool_set_true = \l__wheelchart_plot_bool , + / utils / exec = { \cs_set:Npn \__wheelchart_outer_plot:nn ##1##2 {#1} } , + slices~outer = { -- plot [ domain = - \fp_use:N \l__wheelchart_slice_outer_start_angle_fp + \fp_use:c { g__wheelchart_slice_outer_start_angle_\WCcount _fp } \c_colon_str - \fp_use:N \l__wheelchart_slice_outer_end_angle_fp , - samples = \fp_use:N \l__wheelchart_samples_fp , - variable = \l__wheelchart_outer_plot_variable_fp , + \fp_use:c { g__wheelchart_slice_outer_end_angle_\WCcount _fp } , + samples = \fp_use:c { g__wheelchart_samples_\WCcount _fp } , + variable = \l__wheelchart_outer_plot_variable_tl , / wheelchart / outer_plot_style ] - ( \__wheelchart_outer_plot:nn { \l__wheelchart_outer_plot_variable_fp } { \fp_use:N \l__wheelchart_outer_radius_fp } ) + ( + \__wheelchart_outer_plot:nn + { \l__wheelchart_outer_plot_variable_tl } + { \fp_use:c { g__wheelchart_outer_radius_\WCcount _fp } } + ) } } , outer~plot~style /. style = { outer_plot_style /. style = {#1} } , outer_plot_style /. style = {} , outer~radius /. initial = 3 , - parse /. initial = pgfmath , perc~precision /. initial = 0 , pie /. code = { \bool_set:Nn \l__wheelchart_pie_bool { \cs:w c_#1_bool\cs_end: } } , pie /. default = true , @@ -1870,42 +1975,74 @@ slices~arc~outer~start~end / true /. value~forbidden , slices~arc~outer~start~end /. initial = false , slices~arc~outer~start~end /. default = true , + slices~Arrow /. style = + { + slices~end = + { + -- ( \WCpoint { 1 } {#1} { 0.5 } { 0 } ) + -- ( \WCpoint { 1 } { 0 } { 0 } { 0 } ) + } , + slices~start = + { + -- ( \WCpoint { 0 } {#1} { 0.5 } { 0 } ) + -- cycle + } + } , slices~arrow /. style~2~args = { slices~start~arrow = { - (#1) } {#2} , slices~end~arrow = {#1} {#2} } , - slices~end~arc /. code~2~args = + slices~end /. initial = { -- ( g__wheelchart_slice_\WCcount _inner~end_coordinate ) } , + slices~end~arc /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_end_tl + slices~end = { \__wheelchart_slices_arc:nnnnnn {#1} {#2} { outer~end } { inner~end } - { -- ( \fp_use:c { l__wheelchart_inner~end_x_fp } , \fp_use:c { l__wheelchart_inner~end_y_fp } ) } + { -- ( g__wheelchart_slice_\WCcount _inner~end_coordinate ) } {} } } , - slices~end~arrow /. code~2~args = + slices~end~arrow /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_end_tl + slices~end = { \__wheelchart_slices_arrow:nnnnn {#1} {#2} { outer~end } { inner~end } - { -- ( \fp_use:c { l__wheelchart_inner~end_x_fp } , \fp_use:c { l__wheelchart_inner~end_y_fp } ) } + { -- ( g__wheelchart_slice_\WCcount _inner~end_coordinate ) } } } , - slices~end~to /. code~2~args = + slices~end~to /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_end_tl + slices~end = { \__wheelchart_slices_to:nn {#2} {#1} - ( \fp_use:c { l__wheelchart_inner~end_x_fp } , \fp_use:c { l__wheelchart_inner~end_y_fp } ) + ( g__wheelchart_slice_\WCcount _inner~end_coordinate ) + } + } , + slices~inner /. initial = + { + \fp_compare:nNnT { \cs:w g__wheelchart_inner_radius_\WCcount _fp\cs_end: } > { 0 } + { + \fp_compare:nNnT + { \cs:w g__wheelchart_inner_gap_\WCcount _fp\cs_end: } + < + { \cs:w g__wheelchart_abs_half_angle_minus_new_angle_\WCcount _fp\cs_end: } + { + arc + [ + start~angle = \fp_use:c { g__wheelchart_slice_inner_end_angle_\WCcount _fp } , + end~angle = \fp_use:c { g__wheelchart_slice_inner_start_angle_\WCcount _fp } , + radius = \fp_use:c { g__wheelchart_inner_radius_\WCcount _fp } + ] + } } } , slices~inner~angle~reduce /. style = @@ -1918,32 +2055,32 @@ slices~inner~end~angle~shift = {#1} , slices~inner~start~angle~shift = {#1} } , - slices~inner~arc /. code~2~args = + slices~inner~arc /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_inner_tl + slices~inner = { \__wheelchart_slices_arc:nnnnnn {#1} {#2} { inner~end } { inner~start } - { -- ( \fp_use:c { l__wheelchart_inner~start_x_fp } , \fp_use:c { l__wheelchart_inner~start_y_fp } ) } + { -- ( g__wheelchart_slice_\WCcount _inner~start_coordinate ) } {} } } , slices~inner~arc~tangent /. is~choice , slices~inner~arc~tangent / false /. code = {} , slices~inner~arc~tangent / false /. value~forbidden , - slices~inner~arc~tangent / true /. code = + slices~inner~arc~tangent / true /. style = { - \tl_set:Nn \l__wheelchart_slices_inner_tl + slices~inner = { \__wheelchart_slices_arc:nnnnnn { \__wheelchart_diff_atan:nnnn { outer~start } { inner~start } { outer~end } { inner~end } } { 0 } { inner~end } { inner~start } - { -- ( \fp_use:c { l__wheelchart_inner~start_x_fp } , \fp_use:c { l__wheelchart_inner~start_y_fp } ) } + { -- ( g__wheelchart_slice_\WCcount _inner~start_coordinate ) } { \fp_compare:nNnTF { \l__wheelchart_slices_arc_A_fp } > { 359.99 } { \fp_set:Nn \l__wheelchart_slices_arc_A_fp { 1 } } @@ -1954,28 +2091,37 @@ slices~inner~arc~tangent / true /. value~forbidden , slices~inner~arc~tangent /. initial = false , slices~inner~arc~tangent /. default = true , - slices~inner~arrow /. code~2~args = + slices~inner~arrow /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_inner_tl + slices~inner = { \__wheelchart_slices_arrow:nnnnn {#1} {#2} { inner~end } { inner~start } - { -- ( \fp_use:c { l__wheelchart_inner~start_x_fp } , \fp_use:c { l__wheelchart_inner~start_y_fp } ) } + { -- ( g__wheelchart_slice_\WCcount _inner~start_coordinate ) } } } , slices~inner~end~angle~shift /. initial = 0 , slices~inner~start~angle~shift /. initial = 0 , - slices~inner~to /. code~2~args = + slices~inner~to /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_inner_tl + slices~inner = { \__wheelchart_slices_to:nn {#2} {#1} - ( \fp_use:c { l__wheelchart_inner~start_x_fp } , \fp_use:c { l__wheelchart_inner~start_y_fp } ) + ( g__wheelchart_slice_\WCcount _inner~start_coordinate ) } } , + slices~outer /. initial = + { + arc + [ + start~angle = \fp_use:c { g__wheelchart_slice_outer_start_angle_\WCcount _fp } , + end~angle = \fp_use:c { g__wheelchart_slice_outer_end_angle_\WCcount _fp } , + radius = \fp_use:c { g__wheelchart_outer_radius_\WCcount _fp } + ] + } , slices~outer~angle~reduce /. style = { slices~outer~end~angle~shift = { - (#1) } , @@ -1986,32 +2132,32 @@ slices~outer~end~angle~shift = {#1} , slices~outer~start~angle~shift = {#1} } , - slices~outer~arc /. code~2~args = + slices~outer~arc /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_outer_tl + slices~outer = { \__wheelchart_slices_arc:nnnnnn {#1} {#2} { outer~start } { outer~end } - { -- ( \fp_use:c { l__wheelchart_outer~end_x_fp } , \fp_use:c { l__wheelchart_outer~end_y_fp } ) } + { -- ( g__wheelchart_slice_\WCcount _outer~end_coordinate ) } {} } } , slices~outer~arc~tangent /. is~choice , slices~outer~arc~tangent / false /. code = {} , slices~outer~arc~tangent / false /. value~forbidden , - slices~outer~arc~tangent / true /. code = + slices~outer~arc~tangent / true /. style = { - \tl_set:Nn \l__wheelchart_slices_outer_tl + slices~outer = { \__wheelchart_slices_arc:nnnnnn { \__wheelchart_diff_atan:nnnn { outer~start } { inner~start } { outer~end } { inner~end } } { 0 } { outer~start } { outer~end } - { -- ( \fp_use:c { l__wheelchart_outer~end_x_fp } , \fp_use:c { l__wheelchart_outer~end_y_fp } ) } + { -- ( g__wheelchart_slice_\WCcount _outer~end_coordinate ) } { \fp_compare:nNnTF { \l__wheelchart_slices_arc_A_fp } > { 359.99 } { \fp_set:Nn \l__wheelchart_slices_arc_A_fp { 1 } } @@ -2026,35 +2172,36 @@ slices~outer~arc~tangent / true /. value~forbidden , slices~outer~arc~tangent /. initial = false , slices~outer~arc~tangent /. default = true , - slices~outer~arrow /. code~2~args = + slices~outer~arrow /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_outer_tl + slices~outer = { \__wheelchart_slices_arrow:nnnnn {#1} {#2} { outer~start } { outer~end } - { -- ( \fp_use:c { l__wheelchart_outer~end_x_fp } , \fp_use:c { l__wheelchart_outer~end_y_fp } ) } + { -- ( g__wheelchart_slice_\WCcount _outer~end_coordinate ) } } } , slices~outer~end~angle~shift /. initial = 0 , slices~outer~start~angle~shift /. initial = 0 , - slices~outer~to /. code~2~args = + slices~outer~to /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_outer_tl + slices~outer = { \__wheelchart_slices_to:nn {#1} {#2} - ( \fp_use:c { l__wheelchart_outer~end_x_fp } , \fp_use:c { l__wheelchart_outer~end_y_fp } ) + ( g__wheelchart_slice_\WCcount _outer~end_coordinate ) } } , slices~pos /. initial = 0.5 , slices~scope /. style = { slices_scope /. style = {#1} } , slices_scope /. style = {} , slices~sep /. initial = 0 , - slices~start~arc /. code~2~args = + slices~start /. initial = { -- cycle } , + slices~start~arc /. style~2~args = { - \tl_set:Nn \l__wheelchart_slices_start_tl + slices~start = { \__wheelchart_slices_arc:nnnnnn {#1} @@ -2065,9 +2212,9 @@ {} } } , - slices~start~arrow/.code~2~args = + slices~start~arrow/.style~2~args = { - \tl_set:Nn \l__wheelchart_slices_start_tl + slices~start = { \__wheelchart_slices_arrow:nnnnn {#1} @@ -2077,7 +2224,7 @@ { -- cycle } } } , - slices~start~to /. code~2~args = { \tl_set:Nn \l__wheelchart_slices_start_tl { \__wheelchart_slices_to:nn {#1} {#2} cycle } } , + slices~start~to /. style~2~args = { slices~start = { \__wheelchart_slices_to:nn {#1} {#2} cycle } } , slices~style /. style = { slices_style /. style = {#1} } , slices_style /. style = {} , slices~style = { \WCvarB } , @@ -2094,7 +2241,7 @@ (#1) - \fp_eval:n { - \l__wheelchart_counter_or_clockwise_fp * \fp_use:c { l__wheelchart_value_1_fp } * 0.5 + \l__wheelchart_counter_or_clockwise_fp * \cs:w g__wheelchart_value_1_fp\cs_end: * 0.5 * ( \l__wheelchart_total_angle_fp / \WCtotalnum ) } } @@ -2112,7 +2259,8 @@ total~count /. code = { \tl_set:Nn \l__wheelchart_type_tl { totalcount } - \__wheelchart_def_macro:Nn \l__wheelchart_total_count_fp {#1} + \pgfmathparse {#1} + \fp_set:Nn \l__wheelchart_total_count_fp { \pgfmathresult } } , triangle~proportional~area /. style~2~args = { @@ -2134,7 +2282,7 @@ WC_list /. code~2~args = { \cs_set:cpn {#1} - { \use:e { \clist_item:nn {#2} { \int_mod:nn { \WCcount-1 } { \clist_count:n {#2} } + 1 } } } + { \use:e { \clist_item:nn {#2} { \int_mod:nn { \WCcount - 1 } { \clist_count:n {#2} } + 1 } } } %note the \use:e such that \WClist<name> also works when given as an argument to pgfmath %if the list contains a macro, for example %\begin{tikzpicture} @@ -2199,14 +2347,15 @@ } { \clist_gclear:N \g__wheelchart_slice_range_for_loop_clist - \foreach \l__wheelchart_slice_range_index_int [ parse = true ] in \l__wheelchart_key_range_tl + \foreach \l__wheelchart_slice_range_index_tl [ parse = true ] in \l__wheelchart_key_range_tl { \clist_gput_right:Ne \g__wheelchart_slice_range_for_loop_clist - { \fp_eval:n { \l__wheelchart_slice_range_index_int } } + { \fp_eval:n { \l__wheelchart_slice_range_index_tl } } } \clist_map_inline:Nn \g__wheelchart_slice_range_for_loop_clist { - \clist_put_right:Nn \l__wheelchart_slice_range_local_clist {##1} + \clist_if_in:NnF \l__wheelchart_slice_range_local_clist {##1} + { \clist_put_right:Nn \l__wheelchart_slice_range_local_clist {##1} } \clist_if_exist:cF { l__wheelchart_slice_##1_keys_clist } { \clist_new:c { l__wheelchart_slice_##1_keys_clist } } \str_if_eq:eeTF { \l__wheelchart_key_name_tl } { slice } @@ -2226,13 +2375,27 @@ } }%this gives an error message if a key of the form <unknown key for wheelchart>{<range>} is given +%%> \subsection{Additional commands} + +\NewExpandableDocumentCommand \WCangle { O { \WCcount } m m m m } + { \__wheelchart_def_angle_plot_false:nnnnn { \__wheelchart_mod:n {#1} } {#2} {#3} {#4} {#5} } + +\NewExpandableDocumentCommand \WCcoordinate { O { \WCcount } m } + { g__wheelchart_slice_\__wheelchart_mod:n {#1}_#2_coordinate } + +\NewExpandableDocumentCommand \WCpoint { O { \WCcount } m m m m } + { \WCangle [#1] {#2} {#3} {#4} {#5} \c_colon_str \WCradius [#1] {#4} {#5} } + +\NewExpandableDocumentCommand \WCradius { O { \WCcount } m m } + { \__wheelchart_def_radius:nnn { \__wheelchart_mod:n {#1} } {#2} {#3} } + %%> \subsection{The command \textbackslash wheelchart} -\NewDocumentCommand { \wheelchart } { O{} m } +\NewDocumentCommand \wheelchart { O {} m } { - {%note the double {{...}} such that the contents is in a group and such that & can be used in pgfmath in a tabular + {%note the double braces {{...}} such that the contents is in a group and such that & can be used in pgfmath in a tabular \pgfkeys { / wheelchart , #1 } - \@ifpackageloaded { siunitx } + \IfPackageLoadedTF { siunitx } { \cs_set:Npn \WCperc { \qty { \WCpercentagerounded } { \percent } } } { \cs_set:Npn \WCperc { \WCpercentagerounded \, \% } }%the definition of \WCperc is placed inside the command \wheelchart %such that \WCperc is not defined outside this command @@ -2245,63 +2408,175 @@ } { \fp_set:Nn \l__wheelchart_coord_determinant_fp { \pgf@yy * \pgf@xx - \pgf@yx * \pgf@xy } - \begin { scope } [ shift /. expanded = { \pgfkeysvalueof { / wheelchart / at } } ] - \begin { scope } [ local~bounding~box /. expanded = \g__wheelchart_name_tl ] - \__wheelchart_def_macros:n { total~angle } - \__wheelchart_initial:n {#2} - \__wheelchart_def_macros:n { start~angle } - \bool_if:NF \l__wheelchart_plot_bool + \__wheelchart_def_fp:nn { total_angle } { total~angle } + \__wheelchart_initial:n {#2} + \tl_gset:Ne \g__wheelchart_totalcount_tl { \WCtotalcount }%\WCtotalcount is local and \g__wheelchart_totalcount_tl is global + %because it is used in commands such as \WCangle thus must be available after the command \wheelchart + \__wheelchart_def_fp:nn { start_angle } { start~angle } + \fp_gset_eq:NN \g__wheelchart_angle_fp \l__wheelchart_start_angle_fp + \__wheelchart_for_loop_initial:n + { + \__wheelchart_def_slice_keys:n { - \bool_set_false:N \l__wheelchart_def_inner_contour_bool - \bool_if:NTF \l__wheelchart_contour_bool + \cs_set_eq:Nc \WCpercentage { l__wheelchart_WCpercentage_\WCcount } + \cs_set_eq:Nc \WCpercentagerounded { l__wheelchart_WCpercentagerounded_\WCcount } + \fp_compare:nNnTF { \WCcount } = { \WCtotalcount } { - \bool_set_true:N \l__wheelchart_def_inner_contour_bool - \tl_build_gbegin:N \g__wheelchart_outer_contour_tl - \__wheelchart_for_loop:n - { - \tl_build_gput_left:Ne \g__wheelchart_outer_contour_tl - { - ( \fp_use:N \g__wheelchart_new_angle_fp \c_colon_str \fp_use:N \l__wheelchart_outer_radius_fp ) - arc - [ - start~angle = \fp_use:N \g__wheelchart_new_angle_fp , - end~angle = \fp_use:N \g__wheelchart_angle_fp , - radius = \fp_use:N \l__wheelchart_outer_radius_fp - ] - -- - } - } - \tl_build_gend:N \g__wheelchart_outer_contour_tl + \fp_gset:Nn \g__wheelchart_new_angle_fp + { \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp } } { - \bool_if:NT \l__wheelchart_middle_fill_bool - { \bool_set_true:N \l__wheelchart_def_inner_contour_bool } + \fp_gset:Nn \g__wheelchart_new_angle_fp + { + \g__wheelchart_angle_fp + + ( + \l__wheelchart_counter_or_clockwise_fp * \cs:w g__wheelchart_value_\WCcount _fp\cs_end: + * ( \l__wheelchart_total_angle_fp / \WCtotalnum ) + ) + } } - \bool_if:NT \l__wheelchart_def_inner_contour_bool + \__wheelchart_gdef_count_fp:nn { data_angle_pos } { data~angle~pos } + \__wheelchart_def_fp:nn { gap } { gap } + \__wheelchart_def_fp:nn { gap_max_angle } { gap~max~angle } + \__wheelchart_def_fp:nn { gap_polar } { gap~polar } + \__wheelchart_def_fp:nn { gap_radius } { gap~radius } + \__wheelchart_gdef_count_fp:nn { samples } { samples } + \__wheelchart_def_fp:nn { slices_inner_start_angle_shift } { slices~inner~start~angle~shift } + \__wheelchart_def_fp:nn { slices_inner_end_angle_shift } { slices~inner~end~angle~shift } + \__wheelchart_def_fp:nn { slices_outer_end_angle_shift } { slices~outer~end~angle~shift } + \__wheelchart_def_fp:nn { slices_outer_start_angle_shift } { slices~outer~start~angle~shift } + \__wheelchart_def_outer_radius: + \__wheelchart_def_inner_radius: + \fp_gzero_new:c { g__wheelchart_inner_radius_\WCcount _fp } + \fp_gset_eq:cN { g__wheelchart_inner_radius_\WCcount _fp } \l__wheelchart_inner_radius_fp + \fp_gzero_new:c { g__wheelchart_outer_radius_\WCcount _fp } + \fp_gset_eq:cN { g__wheelchart_outer_radius_\WCcount _fp } \l__wheelchart_outer_radius_fp + \fp_gzero_new:c { g__wheelchart_abs_half_angle_minus_new_angle_\WCcount _fp } + \fp_gset:cn { g__wheelchart_abs_half_angle_minus_new_angle_\WCcount _fp } + { abs ( \g__wheelchart_angle_fp - \g__wheelchart_new_angle_fp ) / 2 } + \fp_set:Nn \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp + { \cs:w g__wheelchart_abs_half_angle_minus_new_angle_\WCcount _fp\cs_end: - \l__wheelchart_gap_polar_fp } + \fp_gzero_new:c { g__wheelchart_outer_gap_\WCcount _fp } + \fp_gzero_new:c { g__wheelchart_inner_gap_\WCcount _fp } + \bool_if:NTF \l__wheelchart_plot_bool { - \tl_build_gbegin:N \g__wheelchart_inner_contour_tl - \__wheelchart_for_loop:n - { - \tl_build_gput_right:Ne \g__wheelchart_inner_contour_tl - { - ( \fp_use:N \g__wheelchart_angle_fp \c_colon_str \fp_use:N \l__wheelchart_inner_radius_fp ) - arc - [ - start~angle = \fp_use:N \g__wheelchart_angle_fp , - end~angle = \fp_use:N \g__wheelchart_new_angle_fp , - radius = \fp_use:N \l__wheelchart_inner_radius_fp - ] - -- - } - } - \tl_build_gend:N \g__wheelchart_inner_contour_tl + \fp_gset_eq:cN { g__wheelchart_outer_gap_\WCcount _fp } \l__wheelchart_gap_polar_fp + \fp_gset_eq:cN { g__wheelchart_inner_gap_\WCcount _fp } \l__wheelchart_gap_polar_fp } - \bool_if:NT \l__wheelchart_middle_fill_bool { + \fp_set:Nn \l__wheelchart_gap_max_angle_def_fp + { + \cs:w g__wheelchart_inner_radius_\WCcount _fp\cs_end: > 0 + ? + 90 + : + ( + sind ( \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp ) < 0.001 + ? + ( + 90 < \l__wheelchart_gap_max_angle_fp && \l__wheelchart_gap_max_angle_fp < 180 + ? + \l__wheelchart_gap_max_angle_fp + : + 90 + ) + : + ( + \l__wheelchart_gap_max_angle_fp < 90 || \l__wheelchart_gap_max_angle_fp > 180 + ? + 180 + : + \l__wheelchart_gap_max_angle_fp + ) + ) + } + \__wheelchart_def_gap:nn { outer } { \cs:w g__wheelchart_outer_radius_\WCcount _fp\cs_end: } + \__wheelchart_def_gap:nn { inner } { \cs:w g__wheelchart_inner_radius_\WCcount _fp\cs_end: } + \fp_compare:nNnT { \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp } > { 0.01 } + { + \fp_gset:cn { g__wheelchart_inner_radius_\WCcount _fp } + { + max + ( + \l__wheelchart_gap_fp + / sind + ( + min + ( + \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp , + \l__wheelchart_gap_max_angle_def_fp + ) + ) + , + \cs:w g__wheelchart_inner_radius_\WCcount _fp\cs_end: + ) + } + } + } + \__wheelchart_def_slice_angle:nnnn { inner } { end } { new_ } { -1 } + \__wheelchart_def_slice_angle:nnnn { inner } { start } {} { 1 } + \__wheelchart_def_slice_angle:nnnn { outer } { end } { new_ } { -1 } + \__wheelchart_def_slice_angle:nnnn { outer } { start } {} { 1 } + \__wheelchart_def_angle:nnnn { 0.5 } { 0 } { 0.5 } { 0 } + \cs_set:Npe \WCmidangle { \pgfmathresult } + \__wheelchart_gdef_count_fp:nn { data_angle_shift } { data~angle~shift } + \__wheelchart_gdef_count_fp:nn { data_pos } { data~pos } + \__wheelchart_gdef_count_fp:nn { data_sep } { data~sep } + \__wheelchart_def_angle:nnnn + { \cs:w g__wheelchart_data_angle_pos_\WCcount _fp\cs_end: } + { \cs:w g__wheelchart_data_angle_shift_\WCcount _fp\cs_end: } + { \cs:w g__wheelchart_data_pos_\WCcount _fp\cs_end: } + { \cs:w g__wheelchart_data_sep_\WCcount _fp\cs_end: } + \cs_set:Npe \WCdataangle { \pgfmathresult } + \__wheelchart_gdef_count_fp:nn { explode } { explode } + \pgfkeysvalueof { / wheelchart / for~loop~start }%this must be placed after the definition of macros such as + %\WCpercentage such that these macros can be used in the key for loop start + \int_compare:nNnT { \WCcount } = { 1 } + { + \begin { scope } + [ + shift = { ( \WCmidangle \c_colon_str \fp_use:c { g__wheelchart_explode_\WCcount _fp } ) } , + / wheelchart / slices_scope + ] + \__wheelchart_def_orientation: + \end { scope } + } + \fp_gzero_new:c { g__wheelchart_WCdataangle_\WCcount _fp } + \fp_gset:cn { g__wheelchart_WCdataangle_\WCcount _fp } { \WCdataangle } + \fp_gzero_new:c { g__wheelchart_WCmidangle_\WCcount _fp } + \fp_gset:cn { g__wheelchart_WCmidangle_\WCcount _fp } { \WCmidangle } + \fp_gset_eq:NN \g__wheelchart_angle_fp \g__wheelchart_new_angle_fp + \pgfkeysvalueof { / wheelchart / for~loop~end } + } + } + \begin { scope } [ shift /. expanded = { \pgfkeysvalueof { / wheelchart / at } } ] + \begin { scope } [ local~bounding~box /. expanded = \g__wheelchart_name_tl ] + \bool_if:NT \l__wheelchart_middle_fill_bool + { + \bool_if:NF \l__wheelchart_plot_bool + { + \__wheelchart_def_inner_radius: \fill [ / wheelchart / middle_fill ] - \fp_compare:nNnF { \l__wheelchart_total_angle_fp } = { 360 } - { ( 0 , 0 ) -- } - \g__wheelchart_inner_contour_tl cycle ; + \fp_compare:nNnTF { \l__wheelchart_total_angle_fp } = { 360 } + { ( 0 , 0 ) circle [ radius = \fp_use:N \l__wheelchart_inner_radius_fp ] } + { + ( 0 , 0 ) + -- ( \fp_use:N \l__wheelchart_start_angle_fp \c_colon_str \fp_use:N \l__wheelchart_inner_radius_fp ) + arc + [ + start~angle = \fp_use:N \l__wheelchart_start_angle_fp , + end~angle = + \fp_eval:n + { + \l__wheelchart_start_angle_fp + + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp + } + , + radius = \fp_use:N \l__wheelchart_inner_radius_fp + ] + -- cycle + } + ; } } \bool_if:NTF \l__wheelchart_discrete_bool @@ -2309,116 +2584,53 @@ { \__wheelchart_for_loop:n { - \int_compare:nNnT { \WCcount } = { 1 } - { - %determine the orientation, this is necessary even if no plot is used, for example if - %inner radius > outer radius then \g__wheelchart_slices_orientation_fp is different from - %\l__wheelchart_counter_or_clockwise_fp - \fp_set:Nn \l__wheelchart_slices_orientation_new_angle_fp - { - \g__wheelchart_angle_fp + - ( - \g__wheelchart_new_angle_fp == \g__wheelchart_angle_fp - ? - \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp - : - \g__wheelchart_new_angle_fp - \g__wheelchart_angle_fp - ) - / \l__wheelchart_samples_fp - } - \path let - \p { l__wheelchart_slices_orientation_1 } = - ( - \__wheelchart_outer_plot:nn - { \fp_use:N \g__wheelchart_angle_fp } - { \fp_use:N \l__wheelchart_outer_radius_fp } - ) , - \p { l__wheelchart_slices_orientation_2 } = - ( - \__wheelchart_outer_plot:nn - { \fp_use:N \l__wheelchart_slices_orientation_new_angle_fp } - { \fp_use:N \l__wheelchart_outer_radius_fp } - ) , - \p { l__wheelchart_slices_orientation_3 } = - ( - \__wheelchart_inner_plot:nn - { \fp_use:N \l__wheelchart_slices_orientation_new_angle_fp } - { \fp_use:N \l__wheelchart_inner_radius_fp } - ) , - \p { l__wheelchart_slices_orientation_4 } = - ( - \__wheelchart_inner_plot:nn - { \fp_use:N \g__wheelchart_angle_fp } - { \fp_use:N \l__wheelchart_inner_radius_fp } - ) - in - [ - / utils / exec = - { - \fp_gset:Nn \g__wheelchart_slices_orientation_fp - { - sign - ( - 0.1 * \y { l__wheelchart_slices_orientation_1 } - * ( \x { l__wheelchart_slices_orientation_4 } - \x { l__wheelchart_slices_orientation_2 } ) - + 0.1 * \y { l__wheelchart_slices_orientation_2 } - * ( \x { l__wheelchart_slices_orientation_1 } - \x { l__wheelchart_slices_orientation_3 } ) - + 0.1 * \y { l__wheelchart_slices_orientation_3 } - * ( \x { l__wheelchart_slices_orientation_2 } - \x { l__wheelchart_slices_orientation_4 } ) - + 0.1 * \y { l__wheelchart_slices_orientation_4 } - * ( \x { l__wheelchart_slices_orientation_3 } - \x { l__wheelchart_slices_orientation_1 } ) - ) - * sign ( \l__wheelchart_coord_determinant_fp ) - } - } - ] - ;%the terms are multiplied with 0.1 to try to avoid an overflow - \fp_compare:nNnT { \g__wheelchart_slices_orientation_fp } = { 0 } - { \fp_gset_eq:NN \g__wheelchart_slices_orientation_fp \l__wheelchart_counter_or_clockwise_fp } - } \pgfkeysvalueof { / wheelchart / before~slices } \bool_if:NTF \l__wheelchart_slices_bool { - \__wheelchart_def_macros:n { slices~angle~pos , slices~angle~shift , slices~pos , slices~sep } - \__wheelchart_def_angle:nnnN + \__wheelchart_def_fp:nn { slices_angle_pos } { slices~angle~pos } + \__wheelchart_def_fp:nn { slices_angle_shift } { slices~angle~shift } + \__wheelchart_def_fp:nn { slices_pos } { slices~pos } + \__wheelchart_def_fp:nn { slices_sep } { slices~sep } + \__wheelchart_def_angle:nnnn { \l__wheelchart_slices_angle_pos_fp } { \l__wheelchart_slices_angle_shift_fp } + { \l__wheelchart_slices_pos_fp } { \l__wheelchart_slices_sep_fp } - \l__wheelchart_slices_angle_fp + \fp_set:Nn \l__wheelchart_slices_angle_fp { \pgfmathresult } \begin { scope } [ shift /. expanded = { - \__wheelchart_convex_comb_coord:nnnn + \cs:w __wheelchart_point_plot_\bool_to_str:N \l__wheelchart_plot_bool :nnnnn\cs_end: + { \WCcount } { \l__wheelchart_slices_angle_pos_fp } { \l__wheelchart_slices_angle_shift_fp } { \l__wheelchart_slices_pos_fp } { \l__wheelchart_slices_sep_fp } } , - rotate = \l__wheelchart_slices_angle_fp + rotate = \fp_use:N \l__wheelchart_slices_angle_fp ] \fill [ / wheelchart / slices_style ] \l__wheelchart_slices_tl \end { scope } } { - %Below we define x and y coordinates of the 4 points of the slice. %We do not use the let operation in the path \fill[/wheelchart/slices_style] ... because then %\n, \p, \x and \y can not be used as macro names inside the argument of a key which is applied %on this path such as the key slices inner arc. - %First it is necessary to define \g__wheelchart_x_coord_fp and \g__wheelchart_y_coord_fp globally. Then we - %define local macros taking these values with an expanded definition. These are defined locally such that - %these macros do not interfere with values of another wheelchart, for example if wheelcharts would be nested. - %We do not use a \coordinate definition because this would be global which is not suited as explained above. - \__wheelchart_def_coord:nn { inner } { end } - \__wheelchart_def_coord:nn { inner } { start } - \__wheelchart_def_coord:nn { outer } { end } - \__wheelchart_def_coord:nn { outer } { start } + \__wheelchart_def_coord:nnnn { inner~end } { inner } { end } + { \fp_use:c { g__wheelchart_slice_inner_end_angle_\WCcount _fp } } + \__wheelchart_def_coord:nnnn { inner~start } { inner } { start } + { \fp_use:c { g__wheelchart_slice_inner_start_angle_\WCcount _fp } } + \__wheelchart_def_coord:nnnn { outer~end } { outer } { end } + { \fp_use:c { g__wheelchart_slice_outer_end_angle_\WCcount _fp } } + \__wheelchart_def_coord:nnnn { outer~start } { outer } { start } + { \fp_use:c { g__wheelchart_slice_outer_start_angle_\WCcount _fp } } \fill [ / wheelchart / slices_style ] - ( \fp_use:c { l__wheelchart_outer~start_x_fp } , \fp_use:c { l__wheelchart_outer~start_y_fp } ) - \l__wheelchart_slices_outer_tl - \l__wheelchart_slices_end_tl - \l__wheelchart_slices_inner_tl - \l__wheelchart_slices_start_tl + ( g__wheelchart_slice_\WCcount _outer~start_coordinate ) + \pgfkeysvalueof { / wheelchart / slices~outer } + \pgfkeysvalueof { / wheelchart / slices~end } + \pgfkeysvalueof { / wheelchart / slices~inner } + \pgfkeysvalueof { / wheelchart / slices~start } ; } \pgfkeysvalueof { / wheelchart / after~slices } @@ -2429,53 +2641,110 @@ \bool_if:NT \l__wheelchart_wheel_lines_bool %this is placed inside \__wheelchart_for_loop:n such that wheel lines can be applied for specific slices { - \int_step_inline:nnn { 0 } { \fp_eval:n { round ( \l__wheelchart_value_fp ) } } + \int_step_inline:nnn { 0 } { \fp_eval:n { round ( \cs:w g__wheelchart_value_\WCcount _fp\cs_end: ) } } %note the \fp_eval:n { round ( ... ) } to avoid the messages Missing character: There is no ... in font nullfont! { - \fp_set:Nn \l__wheelchart_angle_wheel_lines_fp + \bool_if:NTF \l__wheelchart_plot_bool { - \g__wheelchart_angle_fp - + ( \l__wheelchart_counter_or_clockwise_fp * (####1) * ( \l__wheelchart_total_angle_fp / \WCtotalnum ) ) + \draw [ / wheelchart / wheel_lines ] + ( + \__wheelchart_inner_plot:nn + { \__wheelchart_wheel_lines_aux:nn {####1} { inner } } + { \fp_use:c { g__wheelchart_inner_radius_\WCcount _fp } } + ) + -- + ( + \__wheelchart_outer_plot:nn + { \__wheelchart_wheel_lines_aux:nn {####1} { outer } } + { \fp_use:c { g__wheelchart_outer_radius_\WCcount _fp } } + ) + ; + } + { + \draw [ / wheelchart / wheel_lines ] + ( + \__wheelchart_wheel_lines_aux:nn {####1} { inner } + \c_colon_str + \fp_use:c { g__wheelchart_inner_radius_\WCcount _fp } + ) + -- + ( + \__wheelchart_wheel_lines_aux:nn {####1} { outer } + \c_colon_str + \fp_use:c { g__wheelchart_outer_radius_\WCcount _fp } + ) + ; } - \draw [ / wheelchart / wheel_lines ] - ( - \__wheelchart_inner_plot:nn - { \fp_use:N \l__wheelchart_angle_wheel_lines_fp } - { \fp_use:N \l__wheelchart_inner_radius_fp } - ) - -- - ( - \__wheelchart_outer_plot:nn - { \fp_use:N \l__wheelchart_angle_wheel_lines_fp } - { \fp_use:N \l__wheelchart_outer_radius_fp } - ) - ; } } } - \bool_if:NF \l__wheelchart_plot_bool + \bool_if:NT \l__wheelchart_contour_bool { - \bool_if:NT \l__wheelchart_contour_bool + \bool_if:NF \l__wheelchart_plot_bool { + \__wheelchart_def_outer_radius: + \__wheelchart_def_inner_radius: \fp_compare:nNnTF { \l__wheelchart_total_angle_fp } = { 360 } { - \draw [ / wheelchart / contour_style ] \g__wheelchart_inner_contour_tl cycle ; - \draw [ / wheelchart / contour_style ] \g__wheelchart_outer_contour_tl cycle ; + \draw [ / wheelchart / contour_style ] + ( 0 , 0 ) circle [ radius = \fp_use:N \l__wheelchart_inner_radius_fp ] ; + \draw [ / wheelchart / contour_style ] + ( 0 , 0 ) circle [ radius = \fp_use:N \l__wheelchart_outer_radius_fp ] ; } { - \draw [ / wheelchart / contour_style ] \g__wheelchart_inner_contour_tl \g__wheelchart_outer_contour_tl cycle ; + \draw [ / wheelchart / contour_style ] + ( \fp_use:N \l__wheelchart_start_angle_fp \c_colon_str \fp_use:N \l__wheelchart_inner_radius_fp ) + arc + [ + start~angle = \fp_use:N \l__wheelchart_start_angle_fp , + end~angle = + \fp_eval:n + { + \l__wheelchart_start_angle_fp + + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp + } + , + radius = \fp_use:N \l__wheelchart_inner_radius_fp + ] + -- + ( + \fp_eval:n + { + \l__wheelchart_start_angle_fp + + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp + } + \c_colon_str + \fp_use:N \l__wheelchart_outer_radius_fp + ) + arc + [ + start~angle = + \fp_eval:n + { + \l__wheelchart_start_angle_fp + + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp + } + , + end~angle = \fp_use:N \l__wheelchart_start_angle_fp , + radius = \fp_use:N \l__wheelchart_outer_radius_fp + ] + -- cycle ; } } } \__wheelchart_for_loop:n { - \__wheelchart_def_macros:n - { data~pos , lines , lines~angle~pos , lines~angle~shift , lines~ext , lines~pos , lines~sep } + \__wheelchart_def_fp:nn { lines } { lines } + \__wheelchart_def_fp:nn { lines_angle_pos } { lines~angle~pos } + \__wheelchart_def_fp:nn { lines_angle_shift } { lines~angle~shift } + \__wheelchart_def_fp:nn { lines_ext } { lines~ext } + \__wheelchart_def_fp:nn { lines_pos } { lines~pos } + \__wheelchart_def_fp:nn { lines_sep } { lines~sep } \fp_compare:nNnF { \l__wheelchart_lines_ext_fp } = { 0 } { \bool_if:NF \l__wheelchart_lines_ext_dir_bool { - \__wheelchart_def_macros:n { lines~ext~dirsep } + \__wheelchart_def_fp:nn { lines_ext_dirsep } { lines~ext~dirsep } \int_set:Nn \l__wheelchart_lines_ext_dir_int { \fp_eval:n @@ -2508,18 +2777,21 @@ } } } - \__wheelchart_def_macros:n { lines~ext~fixed~left , lines~ext~fixed~right } + \__wheelchart_def_fp:nn { lines_ext_fixed_left } { lines~ext~fixed~left } + \__wheelchart_def_fp:nn { lines_ext_fixed_right } { lines~ext~fixed~right } } \fp_compare:nF { \l__wheelchart_lines_fp == 0 && \l__wheelchart_lines_ext_fp == 0 } { \draw [ / wheelchart / lines_style ] let \p { l__wheelchart_lines_1 } = - \__wheelchart_convex_comb_coord:nnnn - { \l__wheelchart_data_angle_pos_fp } - { \l__wheelchart_data_angle_shift_fp } - { \l__wheelchart_data_pos_fp } + \cs:w __wheelchart_point_plot_\bool_to_str:N \l__wheelchart_plot_bool :nnnnn\cs_end: + { \WCcount } + { \cs:w g__wheelchart_data_angle_pos_\WCcount _fp\cs_end: } + { \cs:w g__wheelchart_data_angle_shift_\WCcount _fp\cs_end: } + { \cs:w g__wheelchart_data_pos_\WCcount _fp\cs_end: } { \l__wheelchart_lines_sep_fp + \l__wheelchart_lines_fp } in - \__wheelchart_convex_comb_coord:nnnn + \cs:w __wheelchart_point_plot_\bool_to_str:N \l__wheelchart_plot_bool :nnnnn\cs_end: + { \WCcount } { \l__wheelchart_lines_angle_pos_fp } { \l__wheelchart_lines_angle_shift_fp } { \l__wheelchart_lines_pos_fp } @@ -2559,7 +2831,20 @@ } } coordinate - [ shift = { ( { \fp_eval:n { \l__wheelchart_lines_ext_dir_int * \l__wheelchart_data_sep_fp } } , 0 ) } ] + [ + shift = + { + ( + { + \fp_eval:n + { + \l__wheelchart_lines_ext_dir_int * \cs:w g__wheelchart_data_sep_\WCcount _fp\cs_end: + } + } , + 0 + ) + } + ] ( g__wheelchart_data_coordinate ) } ; @@ -2568,7 +2853,8 @@ { \fp_compare:nNnTF { \l__wheelchart_lines_ext_fp } = { 0 } { - \__wheelchart_def_macros:n { anchor~xsep , anchor~ysep } + \__wheelchart_def_fp:nn { anchor_xsep } { anchor~xsep } + \__wheelchart_def_fp:nn { anchor_ysep } { anchor~ysep } \pgfmathparse { ( \WCdataangle == 0 ? "west" \c_colon_str @@ -2590,12 +2876,13 @@ \coordinate [ at = - \__wheelchart_convex_comb_coord:nnnn - { \l__wheelchart_data_angle_pos_fp } - { \l__wheelchart_data_angle_shift_fp } - { \l__wheelchart_data_pos_fp } + \cs:w __wheelchart_point_plot_\bool_to_str:N \l__wheelchart_plot_bool :nnnnn\cs_end: + { \WCcount } + { \cs:w g__wheelchart_data_angle_pos_\WCcount _fp\cs_end: } + { \cs:w g__wheelchart_data_angle_shift_\WCcount _fp\cs_end: } + { \cs:w g__wheelchart_data_pos_\WCcount _fp\cs_end: } { - \l__wheelchart_data_sep_fp + + \cs:w g__wheelchart_data_sep_\WCcount _fp\cs_end: + ( \l__wheelchart_lines_fp == 0 ? @@ -2617,106 +2904,273 @@ { \pgfkeysvalueof { / wheelchart / data } } ;%a separate \node and not at the end of the \draw with lines_style %such that the key lines style is not passed to this \node } - \__wheelchart_def_macros:n { arc~data~angle~pos , arc~data~dir }%these are needed for arc data and arc + \__wheelchart_def_fp:nn { arc_around_line } { arc~around~line } + \__wheelchart_def_fp:nn { arc_data_angle_pos } { arc~data~angle~pos } + \__wheelchart_def_fp:nn { arc_data_angle_shift } { arc~data~angle~shift } + \__wheelchart_def_fp:nn { arc_data_dir } { arc~data~dir } + %these are needed for arc data and arc \pgfinterruptpicture% \fp_gset:Nn \g__wheelchart_half_ex_over_one_cm_fp { 0.5 ex / 1 cm }% \endpgfinterruptpicture% - \fp_gset:Nn \g__wheelchart_arc_data_factor_fp { 0 } + \fp_gset:Nn \g__wheelchart_arc_data_aux_ii_fp { 0 } \__wheelchart_if_text:nn { arc~data } { - \__wheelchart_def_macros:n { arc~data~angle~shift , arc~data~pos , arc~data~sep } - \hbox_set:Nn \l__wheelchart_arc_data_box - { \pgfinterruptpicture { \pgfkeysvalueof { / wheelchart / arc~data } } \endpgfinterruptpicture } - \fp_gset:Nn \g__wheelchart_arc_data_slice_length_fp { 1 }%this is necessary if the value is 0 - \__wheelchart_convex_comb_coord_plot:nnnnnnn + \cs_set:Npn \WCperc { \WCpercentagerounded { \, } { \% } }%such that \WCperc follows the arc if used in arc data + %this redefinition of \WCperc is local to the group of arc data + \__wheelchart_def_fp:nn { arc_data_pos } { arc~data~pos } + \__wheelchart_def_fp:nn { arc_data_sep } { arc~data~sep } + \__wheelchart_def_fp:nn { arc_data_line_sep_factor } { arc~data~line~sep~factor } + \cs:w seq_set_split:Nn\pgfkeysvalueof { / wheelchart / arc~data~expand }\cs_end: + \l__wheelchart_arc_data_seq + { \\ } + { \pgfkeysvalueof { / wheelchart / arc~data } } + \seq_map_indexed_inline:Nn \l__wheelchart_arc_data_seq { - overlay , - decorate , - decoration = + \fp_set:Nn \l__wheelchart_arc_data_text_pos_fp { - text~along~path , - text = { {} { \fp_gset:Nn \g__wheelchart_arc_data_slice_length_fp { \pgfdecoratedpathlength } } } , - raise = -0.5 ex , - text~align = \l__wheelchart_arc_data_align_tl , - / wheelchart / arc_data_style + \l__wheelchart_arc_data_pos_fp + 2 * \g__wheelchart_slices_orientation_fp + * ( 2 * ####1 - \seq_count:N \l__wheelchart_arc_data_seq - 1 ) * sign ( \l__wheelchart_arc_data_dir_fp ) + * \l__wheelchart_arc_data_line_sep_factor_fp * \g__wheelchart_half_ex_over_one_cm_fp + / + ( + \cs:w g__wheelchart_outer_radius_\WCcount _fp\cs_end: + - \cs:w g__wheelchart_inner_radius_\WCcount _fp\cs_end: + + 2 * \l__wheelchart_arc_data_sep_fp + ) + }%the sign is needed because \l__wheelchart_arc_data_dir_fp is not necessarily 1 or -1 + \hbox_set:Nn \l__wheelchart_arc_data_box + { \pgfinterruptpicture {####2} \endpgfinterruptpicture } + \fp_gset:Nn \g__wheelchart_arc_data_slice_length_fp { 1 }%this is necessary if the value is 0 + \bool_if:NTF \l__wheelchart_plot_bool + { + \__wheelchart_convex_comb_coord_plot:nnnnnnn + { + overlay , + decorate , + decoration = + { + text~along~path , + text = + { {} { \fp_gset:Nn \g__wheelchart_arc_data_slice_length_fp { \pgfdecoratedpathlength } } } , + raise = -0.5 ex , + text~align = \l__wheelchart_arc_data_align_tl , + / wheelchart / arc_data_style + } + }%get the length of the path + %note the option overlay such that this does not increase the bounding box + %note the {} at the start of text and the braces around \fp_gset:Nn ... + %such that the compilation does not stall + { 0 } + { 1 } + { \l__wheelchart_plot_variable_tl } + { 0 } + { \l__wheelchart_arc_data_text_pos_fp } + { \l__wheelchart_arc_data_sep_fp } + \__wheelchart_convex_comb_coord_plot:nnnnnnn + { + decorate , + decoration = + { + text~along~path , + text = + { + { { \fp_gset:Nn \g__wheelchart_arc_data_aux_i_fp { \the \pgfdecoratedcompleteddistance } } } + ####2 + { + { + \fp_gset:Nn \g__wheelchart_arc_data_aux_i_fp + { + ( \the \pgfdecoratedcompleteddistance - \g__wheelchart_arc_data_aux_i_fp ) + / \g__wheelchart_arc_data_slice_length_fp + } + } + } + } , + raise = -0.5 ex , + text~align = \l__wheelchart_arc_data_align_tl , + / wheelchart / arc_data_style + } + }%note the double braces around \fp_gset:Nn ... + %so that for example arc data=text {\qty{5}{\percent}} is allowed + %note that \def\mytext{}\path[decorate,decoration={text along path,text={\mytext}}] (0,0)--(1,1); + %gives the message Missing character: There is no ... in font nullfont!, then + %text={\pgfkeysvalueof { / wheelchart / arc~data }{}} can be used + %if the \fp_gset:Nn ... would not be present + { \fp_use:c { c__wheelchart_arc_data_start_factor_\l__wheelchart_arc_data_align_tl _fp } } + { \fp_use:c { c__wheelchart_arc_data_end_factor_\l__wheelchart_arc_data_align_tl _fp } } + { + \l__wheelchart_plot_variable_tl * \l__wheelchart_arc_data_dir_fp * 1.1 + * ( \dim_to_fp:n { \box_wd:N \l__wheelchart_arc_data_box } / \g__wheelchart_arc_data_slice_length_fp ) + + \l__wheelchart_arc_data_angle_pos_fp + } + { \l__wheelchart_arc_data_angle_shift_fp } + { \l__wheelchart_arc_data_text_pos_fp } + { \l__wheelchart_arc_data_sep_fp } } - }%get the length of the path - %note the option overlay such that this does not increase the bounding box - %note the {} at the start of text and the braces around \fp_gset:Nn ... such that the compilation does not stall - { 0 } - { 1 } - { \l__wheelchart_plot_variable_fp } - { 0 } - { \l__wheelchart_arc_data_pos_fp } - { \l__wheelchart_arc_data_sep_fp } - \__wheelchart_convex_comb_coord_plot:nnnnnnn - { - decorate , - decoration = { - text~along~path , - text = + \fp_set:Nn \l__wheelchart_arc_data_radius_plot_false_fp { - { { \fp_gset:Nn \g__wheelchart_arc_data_factor_fp { \the \pgfdecoratedcompleteddistance } } } - \pgfkeysvalueof { / wheelchart / arc~data } - { + \__wheelchart_def_radius:nnn + { \WCcount } + { \l__wheelchart_arc_data_text_pos_fp } + { \l__wheelchart_arc_data_sep_fp + \g__wheelchart_half_ex_over_one_cm_fp } + } + \fp_set:Nn \l__wheelchart_arc_data_total_angle_plot_false_fp + { + \box_wd:N \l__wheelchart_arc_data_box * 1.1 / + ( + sqrt ( abs ( \l__wheelchart_coord_determinant_fp ) )%this is necessary if an option such as + %[x={(-0.5,0)},y={(0,0.5)}] is given to the tikzpicture + * \l__wheelchart_arc_data_radius_plot_false_fp * deg + ) + } + \fp_set:Nn \l__wheelchart_arc_data_start_angle_plot_false_fp + { + \__wheelchart_def_angle_plot_false:nnnnn + { \WCcount } + { \l__wheelchart_arc_data_angle_pos_fp } + { \l__wheelchart_arc_data_angle_shift_fp } + { \l__wheelchart_arc_data_text_pos_fp } + { \l__wheelchart_arc_data_sep_fp + \g__wheelchart_half_ex_over_one_cm_fp } + + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_arc_data_dir_fp + * \cs:w c__wheelchart_arc_data_start_factor_\l__wheelchart_arc_data_align_tl _fp\cs_end: + * \l__wheelchart_arc_data_total_angle_plot_false_fp + } + \path + [ + decorate , + decoration = { - \fp_gset:Nn \g__wheelchart_arc_data_factor_fp + text~along~path , + text = { - ( \the \pgfdecoratedcompleteddistance - \g__wheelchart_arc_data_factor_fp ) - / \g__wheelchart_arc_data_slice_length_fp - } + { { \fp_gset:Nn \g__wheelchart_arc_data_aux_i_fp { \the \pgfdecoratedcompleteddistance } } } + ####2 + { + { + \fp_gset:Nn \g__wheelchart_arc_data_aux_i_fp + { + ( \the \pgfdecoratedcompleteddistance - \g__wheelchart_arc_data_aux_i_fp ) + / \l__wheelchart_arc_data_radius_plot_false_fp + } + } + } + } , + raise = -0.5 ex , + text~align = \l__wheelchart_arc_data_align_tl , + / wheelchart / arc_data_style } - } - } , - raise = -0.5 ex , - text~align = \l__wheelchart_arc_data_align_tl , - / wheelchart / arc_data_style + ] + ( + \fp_use:N \l__wheelchart_arc_data_start_angle_plot_false_fp + \c_colon_str + \fp_use:N \l__wheelchart_arc_data_radius_plot_false_fp + ) + arc + [ + start~angle = \fp_use:N \l__wheelchart_arc_data_start_angle_plot_false_fp , + end~angle = + \fp_eval:n + { + \l__wheelchart_arc_data_start_angle_plot_false_fp + + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_arc_data_dir_fp + * \l__wheelchart_arc_data_total_angle_plot_false_fp + } + , + radius = \fp_use:N \l__wheelchart_arc_data_radius_plot_false_fp + ] + ; } - }%note the double braces around \fp_gset:Nn ... so that for example arc data=text {\qty{5}{\percent}} is allowed - %note that \def\mytext{}\path[decorate,decoration={text along path,text={\mytext}}] (0,0)--(1,1); - %gives the message Missing character: There is no ... in font nullfont!, then - %text={\pgfkeysvalueof { / wheelchart / arc~data }{}} can be used if the \fp_gset:Nn ... would not be present - { \fp_use:c { c__wheelchart_arc_data_start_factor_\l__wheelchart_arc_data_align_tl _fp } } - { \fp_use:c { c__wheelchart_arc_data_end_factor_\l__wheelchart_arc_data_align_tl _fp } } - { - \l__wheelchart_plot_variable_fp * \l__wheelchart_arc_data_dir_fp * 1.1 - * ( \dim_to_fp:n { \box_wd:N \l__wheelchart_arc_data_box } / \g__wheelchart_arc_data_slice_length_fp ) - + \l__wheelchart_arc_data_angle_pos_fp - } - { \l__wheelchart_arc_data_angle_shift_fp } - { \l__wheelchart_arc_data_pos_fp } - { \l__wheelchart_arc_data_sep_fp } - \fp_compare:nNnT { \g__wheelchart_arc_data_factor_fp } < { 0 } - { - \PackageWarning { wheelchart } + \fp_compare:nNnF { \g__wheelchart_arc_data_aux_i_fp } > { 0 } { - The~arc~data~in~slice~\WCcount \c_space_tl did~(possibly)~not~fit.~ - Increase~the~absolute~value~of~arc~data~dir. - }%refer to \WCcount and not to \pgfkeysvalueof { / wheelchart / arc~data } - %because the latter is not necessarily unique + \PackageWarning { wheelchart } + { + The~arc~data~in~slice~\WCcount \c_space_tl did~(possibly)~not~fit.~ + Increase~the~absolute~value~of~arc~data~dir. + }%refer to \WCcount and not to \pgfkeysvalueof { / wheelchart / arc~data } + %because the latter is not necessarily unique + } + \int_compare:nNnT {####1} = { \fp_use:N \l__wheelchart_arc_around_line_fp } + { \fp_gset_eq:NN \g__wheelchart_arc_data_aux_ii_fp \g__wheelchart_arc_data_aux_i_fp } } } \bool_if:NT \l__wheelchart_arc_bool { - \__wheelchart_def_macros:n { arc~pos , arc~sep } + \__wheelchart_def_fp:nn { arc_pos } { arc~pos } + \__wheelchart_def_fp:nn { arc_sep } { arc~sep } \str_case:enF { \pgfkeysvalueof { / wheelchart / arc~around~text } } { { true } { - \__wheelchart_arc_around_text:nnn { first } { -1 } { 0 } - \__wheelchart_arc_around_text:nnn { second } { 1 } { 1 } + \bool_if:NTF \l__wheelchart_plot_bool + { + \__wheelchart_arc_around_text_plot_true:nnn { first } { -1 } { 0 } + \__wheelchart_arc_around_text_plot_true:nnn { second } { 1 } { 1 } + } + { + \fp_gset:Nn \g__wheelchart_arc_data_aux_ii_fp + { + \g__wheelchart_arc_data_aux_ii_fp + / ( sqrt ( abs ( \l__wheelchart_coord_determinant_fp ) ) * deg ) + } + \fp_set:Nn \l__wheelchart_arc_radius_fp + { + \__wheelchart_def_radius:nnn + { \WCcount } + { \l__wheelchart_arc_pos_fp } + { \l__wheelchart_arc_sep_fp + \g__wheelchart_half_ex_over_one_cm_fp } + } + \__wheelchart_arc_around_text_plot_false:nn { first } { 0 } + \__wheelchart_arc_around_text_plot_false:nn { second } { 1 } + } } { false } { - \__wheelchart_convex_comb_coord_plot:nnnnnnn - { draw , / wheelchart / arc_style } - { 0 } - { 1 } - { \l__wheelchart_plot_variable_fp } - { 0 } - { \l__wheelchart_arc_pos_fp } - { \l__wheelchart_arc_sep_fp } + \bool_if:NTF \l__wheelchart_plot_bool + { + \__wheelchart_convex_comb_coord_plot:nnnnnnn + { draw , / wheelchart / arc_style } + { 0 } + { 1 } + { \l__wheelchart_plot_variable_tl } + { 0 } + { \l__wheelchart_arc_pos_fp } + { \l__wheelchart_arc_sep_fp } + } + { + \fp_set:Nn \l__wheelchart_arc_radius_fp + { + \__wheelchart_def_radius:nnn + { \WCcount } + { \l__wheelchart_arc_pos_fp } + { \l__wheelchart_arc_sep_fp + \g__wheelchart_half_ex_over_one_cm_fp } + } + \fp_set:Nn \l__wheelchart_arc_start_angle_fp + { + \__wheelchart_def_angle_plot_false:nnnnn + { \WCcount } + { 0 } + { 0 } + { \l__wheelchart_arc_pos_fp } + { \l__wheelchart_arc_sep_fp + \g__wheelchart_half_ex_over_one_cm_fp } + } + \path + [ draw , / wheelchart / arc_style ] + ( \fp_use:N \l__wheelchart_arc_start_angle_fp \c_colon_str \fp_use:N \l__wheelchart_arc_radius_fp ) + arc + [ + start~angle = \fp_use:N \l__wheelchart_arc_start_angle_fp , + end~angle = + \__wheelchart_def_angle_plot_false:nnnnn + { \WCcount } + { 1 } + { 0 } + { \l__wheelchart_arc_pos_fp } + { \l__wheelchart_arc_sep_fp + \g__wheelchart_half_ex_over_one_cm_fp } , + radius = \fp_use:N \l__wheelchart_arc_radius_fp + ] + ; + } } } { @@ -2728,28 +3182,8 @@ } } } - \__wheelchart_if_text:nn { inner~data } - { - \__wheelchart_def_macros:n { inner~data~angle~pos , inner~data~angle~shift , inner~data~pos , inner~data~sep } - \node [ align = left , / wheelchart / inner_data_style ] at - \__wheelchart_convex_comb_coord:nnnn - { \l__wheelchart_inner_data_angle_pos_fp } - { \l__wheelchart_inner_data_angle_shift_fp } - { \l__wheelchart_inner_data_pos_fp } - { \l__wheelchart_inner_data_sep_fp } - { \pgfkeysvalueof { / wheelchart / inner~data } } ; - } - \__wheelchart_if_text:nn { wheel~data } - { - \__wheelchart_def_macros:n { wheel~data~angle~pos , wheel~data~angle~shift , wheel~data~pos , wheel~data~sep } - \node [ align = left , / wheelchart / wheel_data_style ] at - \__wheelchart_convex_comb_coord:nnnn - { \l__wheelchart_wheel_data_angle_pos_fp } - { \l__wheelchart_wheel_data_angle_shift_fp } - { \l__wheelchart_wheel_data_pos_fp } - { \l__wheelchart_wheel_data_sep_fp } - { \pgfkeysvalueof { / wheelchart / wheel~data } } ; - } + \__wheelchart_inner_and_wheel_data:n { inner } + \__wheelchart_inner_and_wheel_data:n { wheel } \pgfkeysvalueof { / wheelchart / legend~entry } } \bool_if:NT \l__wheelchart_legend_row_bool |