答案1
权重自动标准化。
(不知怎的,我把这个名字和“进度条”混淆了,请忽略这个错误)
\documentclass{article}
\usepackage{xcolor}
\usepackage{expl3}
\usepackage{tikz}
\usepackage{amsmath, amssymb}
\usepackage[inline]{enumitem}
\usetikzlibrary{positioning,shapes.misc}
\ExplSyntaxOn
\clist_new:N \g_pb_colors_clist
% these are the colors used by the progress bar
% number of items should not exceed the number of colors here
% the last color will always be used for the last item in the bar
\clist_gset:Nn \g_pb_colors_clist {
6495ed,
006400,
00008b,
b03060,
ff4500,
ffd700,
7fff00,
00ffff,
ff00ff,
ffdab9,
a0a0a0
}
% the dimensions of progress bar (in cm)
\fp_new:N \g_pb_width_fp
\fp_new:N \g_pb_height_fp
\fp_gset:Nn \g_pb_width_fp {5.0}
\fp_gset:Nn \g_pb_height_fp {0.5}
% radius of rounded corners (in cm)
\fp_new:N \g_pb_corner_radius_fp
\fp_gset:Nn \g_pb_corner_radius_fp {0.2}
% helper function to get names of colors
\cs_set:Npn \pb_color_name:n #1 {
pb-internal-color-\int_to_alph:n{#1}
}
\cs_set_eq:NN \color_define:nnn \definecolor
\cs_generate_variant:Nn \color_define:nnn {xnx}
% declare all colors
\int_step_inline:nn {\clist_count:N \g_pb_colors_clist} {
\tl_set:Nn \l_tmpa_tl {\clist_item:Nn \g_pb_colors_clist {#1}}
\color_define:xnx {\pb_color_name:n {#1}}{HTML}{\l_tmpa_tl}
}
% the last color
\tl_new:N \g_pb_last_color_tl
\tl_gset:Nx \g_pb_last_color_tl {\pb_color_name:n {\clist_count:N \g_pb_colors_clist}}
\cs_set:Npn \__pb_node_template:nnn #1#2#3 {
\node[pbnode,#1]~at~(#2~cm,#3~cm)~{};
}
\cs_set:Npn \__pb_draw_left:nn #1#2 {
\fill[#1]
(0~cm,0~cm) --
++(#2~cm,0~cm) --
++(0,-\fp_use:N \g_pb_height_fp~cm) {[rounded~corners=\fp_use:N \g_pb_corner_radius_fp~cm] --
++(-#2~cm,0~cm) --
cycle}
{};
}
\cs_set:Npn \__pb_draw_middle:nn #1#2 {
\fill[#1]
(0~cm,0~cm) --
++(#2~cm,0~cm) --
++(0,-\fp_use:N \g_pb_height_fp~cm) --
++(-#2~cm,0~cm) --
cycle
{};
}
\cs_set:Npn \__pb_draw_right:nn #1#2 {
\fill[#1]
(0~cm,0~cm) {[rounded~corners=\fp_use:N \g_pb_corner_radius_fp~cm] --
++(#2~cm,0~cm) --
++(0,-\fp_use:N \g_pb_height_fp~cm)} --
++(-#2~cm,0~cm) --
cycle
{};
}
\cs_set:Npn \__pb_draw_both:nn #1#2 {
\fill[#1, rounded~corners=\fp_use:N \g_pb_corner_radius_fp~cm]
(0~cm,0~cm) --
++(#2~cm,0~cm) --
++(0,-\fp_use:N \g_pb_height_fp~cm) --
++(-#2~cm,0~cm) --
cycle
{};
}
% helper function to get the correct color
\cs_set:Npn \pb__fetch_color:nN #1#2 {
\int_compare:nNnTF {#1} = {\clist_count:N #2} {
\g_pb_last_color_tl
} {
\pb_color_name:n {#1}
}
}
\clist_new:N \l_pb_tmpa_clist
\clist_new:N \l_pb_tmpb_clist
\clist_new:N \l_pb_tmpc_clist
\seq_new:N \l_pb_tmpa_seq
\fp_new:N \l_pb_tmpa_fp
\fp_new:N \l_pb_tmpb_fp
\fp_new:N \l_pb_tmpc_fp
\tl_new:N \l_pb_tmpa_tl
\tl_new:N \l_pb_tmpb_tl
\int_new:N \l_pb_tmpa_int
\int_new:N \l_pb_tmpb_int
\cs_set:Npn \pb_progress_bar:nn #1#2 {
\clist_set:Nn \l_pb_tmpa_clist {#1}
\clist_set:Nn \l_pb_tmpb_clist {#2}
\int_compare:nNnF {\clist_count:N \l_pb_tmpa_clist} =
{\clist_count:N \l_pb_tmpb_clist} {
\GenericError{}{progress~bar~error}
{}{number~of~items~does~not~match~the~number~of~weights}
}
\int_compare:nNnT {\clist_count:N \l_pb_tmpa_clist} >
{\clist_count:N \g_pb_colors_clist} {
\GenericError{}{progress~bar~error}
{}{number~of~progress~bar~items~exceeds~number~of~colors}
}
% compute total weights
\fp_set:Nn \l_pb_tmpa_fp {0.0}
\clist_map_inline:Nn \l_pb_tmpb_clist {
\fp_add:Nn \l_pb_tmpa_fp {##1}
}
\fp_set:Nn \l_pb_tmpc_fp {0.0}
% determine drawing range
\int_set:Nn \l_pb_tmpa_int {1}
\int_set:Nn \l_pb_tmpb_int {\clist_count:N \l_pb_tmpa_clist}
\clist_map_inline:Nn \l_pb_tmpb_clist {
\fp_compare:nNnT {##1} > {0} {
\clist_map_break:
}
\int_incr:N \l_pb_tmpa_int
}
\clist_set_eq:NN \l_pb_tmpc_clist \l_pb_tmpb_clist
\clist_reverse:N \l_pb_tmpc_clist
\clist_map_inline:Nn \l_pb_tmpc_clist {
\fp_compare:nNnT {##1} > {0} {
\clist_map_break:
}
\int_decr:N \l_pb_tmpb_int
}
% draw progress bar
\begin{tikzpicture}
\int_compare:nNnTF {\l_pb_tmpa_int} = {\l_pb_tmpb_int} {
\fp_set:Nn \l_pb_tmpb_fp {
\g_pb_width_fp
}
\tl_set:Nn \l_pb_tmpa_tl {
color=\pb__fetch_color:nN {\l_pb_tmpa_int} \l_pb_tmpa_clist,
}
\exp_args:NV \__pb_draw_both:nn \l_pb_tmpa_tl {\fp_use:N \l_pb_tmpb_fp}
} {
\int_step_inline:nnn {\l_pb_tmpa_int} {\l_pb_tmpb_int} {
% compute width
\fp_set:Nn \l_pb_tmpb_fp {
\clist_item:Nn \l_pb_tmpb_clist {##1} / \l_pb_tmpa_fp * \g_pb_width_fp
}
\tl_set:Nn \l_pb_tmpa_tl {
color=\pb__fetch_color:nN {##1} \l_pb_tmpa_clist,
xshift=\fp_use:N\l_pb_tmpc_fp~cm,
}
% call corresponding drawing command
\int_case:nnF {##1} {
{\l_pb_tmpa_int} {
\exp_args:NV \__pb_draw_left:nn \l_pb_tmpa_tl {\fp_use:N \l_pb_tmpb_fp}
}
{\l_pb_tmpb_int} {
\exp_args:NV \__pb_draw_right:nn \l_pb_tmpa_tl {\fp_use:N \l_pb_tmpb_fp}
}
} {
\exp_args:NV \__pb_draw_middle:nn \l_pb_tmpa_tl {\fp_use:N \l_pb_tmpb_fp}
}
% update offset
\fp_add:Nn \l_pb_tmpc_fp {\l_pb_tmpb_fp}
}
}
\end{tikzpicture}
% construct legend
\seq_clear:N \l_pb_tmpa_seq
\int_step_inline:nn {\clist_count:N \l_pb_tmpa_clist} {
\seq_put_right:Nx \l_pb_tmpa_seq {
\exp_not:N\item
[\exp_not:N\textcolor{\pb__fetch_color:nN {##1} \l_pb_tmpa_clist}{$\exp_not:N\blacksquare$}] {
\clist_item:Nn \l_pb_tmpa_clist {##1}
}
}
}
\par\begin{itemize*}
\seq_use:Nn \l_pb_tmpa_seq {}
\end{itemize*}
}
\newcommand{\progressbar}[2]{
\pb_progress_bar:nn {#1}{#2}
}
\ExplSyntaxOff
\begin{document}
\begin{minipage}{6cm}
\centering
\progressbar{E, A, Media, Apps, Photos, Other, B, C, D}{0, 0, 1,2,3,4, 0, 0, 0}
\end{minipage}
\begin{minipage}{6cm}
\centering
\progressbar{A,B,C,D,E}{0,0,1,0,0}
\end{minipage}
\begin{minipage}{6cm}
\centering
\progressbar{lorem,ipsum,dolor,sit,amet,consectetur,adipiscing,elit,sed,do,eiusmod}
{4, 5, 7, 1, 2, 5, 7, 9, 3, 6, 4}
\end{minipage}
\end{document}