From f0a68c80d0b2e196ef4b9b6c24fae65d31aa5562 Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Sat, 16 Jun 2018 17:52:06 +0200 Subject: [PATCH] sadf: SVG: Add new option "showtoc" Add new option "showtoc" aimed at displaying, at the beginning of the SVG file, the list of activities for which there are graphs ("table of contents"). Each entry consists of a link pointing at the corresponding activity in the SVG file, enabling the user to quickly navigate through graphs. Signed-off-by: Sebastien GODARD --- sa.h | 12 +++++++++++- sadf.c | 27 +++++++++++++++++++++------ sadf_misc.c | 42 ++++++++++++++++++++++++++++++++++++++---- svg_stats.c | 4 +++- 4 files changed, 73 insertions(+), 12 deletions(-) diff --git a/sa.h b/sa.h index 3d8b487..5d68b62 100644 --- a/sa.h +++ b/sa.h @@ -109,6 +109,7 @@ #define S_F_SVG_SHOW_INFO 0x00800000 #define S_F_HUMAN_READ 0x01000000 #define S_F_ZERO_OMIT 0x02000000 +#define S_F_SVG_SHOW_TOC 0x04000000 #define WANT_SINCE_BOOT(m) (((m) & S_F_SINCE_BOOT) == S_F_SINCE_BOOT) #define WANT_SA_ROTAT(m) (((m) & S_F_SA_ROTAT) == S_F_SA_ROTAT) @@ -137,6 +138,7 @@ #define SET_CANVAS_HEIGHT(m) (((m) & S_F_SVG_HEIGHT) == S_F_SVG_HEIGHT) #define PACK_VIEWS(m) (((m) & S_F_SVG_PACKED) == S_F_SVG_PACKED) #define DISPLAY_HUMAN_READ(m) (((m) & S_F_HUMAN_READ) == S_F_HUMAN_READ) +#define DISPLAY_TOC(m) (((m) & S_F_SVG_SHOW_TOC) == S_F_SVG_SHOW_TOC) #define AO_F_NULL 0x00000000 @@ -221,6 +223,7 @@ #define K_DEBUG "debug" #define K_HEIGHT "height=" #define K_PACKED "packed" +#define K_SHOWTOC "showtoc" /* Groups of activities */ #define G_DEFAULT 0x00 @@ -309,6 +312,7 @@ struct svg_parm { unsigned long long ust_time_first; /* Time (in seconds since the epoch) for first sample */ int graph_no; /* Total number of views already displayed */ int restart; /* TRUE if we have just met a RESTART record */ + int nr_act_dispd; /* Number of activities that will be displayed */ __nr_t nr_max; /* Maximum number of items for this activity */ struct file_header *file_hdr; /* Pointer on file header structure */ }; @@ -317,6 +321,7 @@ struct svg_parm { struct svg_hdr_parm { int graph_nr; /* Number of rows of views to display or canvas height entered on the command line */ int views_per_row; /* Maximum number of views on a single row */ + int nr_act_dispd; /* Number of activities that will be displayed */ }; /* @@ -1007,6 +1012,9 @@ struct report_format { * ^ * 1 | General header * v + * ^ + * 9 | One line from table of contents (if any) + * v * ^ ^ ^ * | | 4 | Graph title * | | v @@ -1041,13 +1049,15 @@ struct report_format { /* #5 */ #define SVG_G_YSIZE 200 /* #1 */ -#define SVG_H_YSIZE 50 +#define SVG_H_YSIZE 60 /* #4 */ #define SVG_M_YSIZE 50 /* #2 */ #define SVG_T_YSIZE 310 /* #3 */ #define SVG_V_YSIZE 300 +/* #9 */ +#define SVG_C_YSIZE 20 /* Grid: Nr of horizontal lines */ #define SVG_H_GRIDNR 3 diff --git a/sadf.c b/sadf.c index 2bd4133..a650ddd 100644 --- a/sadf.c +++ b/sadf.c @@ -450,6 +450,8 @@ void seek_file_position(int ifd, int action) * OUT: * @views_per_row Maximum number of views that will be displayed on a * single row (useful only if "packed" option entered). + * @nr_act_dispd Number of activities that will be displayed. + * May be 0. * * RETURNS: * Number of rows containing views, taking into account only activities @@ -459,11 +461,13 @@ void seek_file_position(int ifd, int action) */ int get_svg_graph_nr(int ifd, char *file, struct file_magic *file_magic, struct file_activity *file_actlst, struct tm *rectime, - struct tm *loctime, int *views_per_row) + struct tm *loctime, int *views_per_row, int *nr_act_dispd) { int i, n, p, eosaf; int rtype, tot_g_nr = 0; + *nr_act_dispd = 0; + /* Save current file position */ seek_file_position(ifd, DO_SAVE); @@ -516,6 +520,8 @@ int get_svg_graph_nr(int ifd, char *file, struct file_magic *file_magic, if (!IS_SELECTED(act[p]->options) || !act[p]->g_nr) continue; + (*nr_act_dispd)++; + if (((act[p]->id == A_NET_DEV) || (act[p]->id == A_NET_EDEV)) && (dlst_iface_idx > 0) && (dlst_iface_idx < id_nr_max[p])) { id_nr_max[p] = dlst_iface_idx; @@ -839,6 +845,8 @@ void rw_curr_act_stats(int ifd, int *curr, long *cnt, int *eosaf, * @file Name of file being read. * @file_magic file_magic structure filled with file magic header data. * @g_nr Number of graphs already displayed (for all activities). + * @nr_act_dispd + * Total number of activities that will be displayed. * * OUT: * @cnt Number of lines of stats remaining to write. @@ -851,7 +859,8 @@ void rw_curr_act_stats(int ifd, int *curr, long *cnt, int *eosaf, void display_curr_act_graphs(int ifd, int *curr, long *cnt, int *eosaf, int p, int *reset, struct file_activity *file_actlst, struct tm *rectime, struct tm *loctime, - char *file, struct file_magic *file_magic, int *g_nr) + char *file, struct file_magic *file_magic, int *g_nr, + int nr_act_dispd) { struct svg_parm parm; int rtype; @@ -872,6 +881,7 @@ void display_curr_act_graphs(int ifd, int *curr, long *cnt, int *eosaf, parm.restart = TRUE; parm.file_hdr = &file_hdr; parm.nr_max = id_nr_max[p]; + parm.nr_act_dispd = nr_act_dispd; *cnt = count; reset_cd = 1; @@ -1245,7 +1255,7 @@ void logic3_display_loop(int ifd, struct file_activity *file_actlst, { struct svg_hdr_parm parm; int i, p; - int curr = 1, rtype, g_nr = 0, views_per_row = 1; + int curr = 1, rtype, g_nr = 0, views_per_row = 1, nr_act_dispd; int eosaf = TRUE, reset = TRUE; long cnt = 1; int graph_nr = 0; @@ -1258,7 +1268,8 @@ void logic3_display_loop(int ifd, struct file_activity *file_actlst, * Result may be 0. In this case, "No data" will be displayed instead of the graphs. */ graph_nr = get_svg_graph_nr(ifd, file, file_magic, - file_actlst, rectime, loctime, &views_per_row); + file_actlst, rectime, loctime, &views_per_row, + &nr_act_dispd); if (SET_CANVAS_HEIGHT(flags)) { /* @@ -1271,6 +1282,7 @@ void logic3_display_loop(int ifd, struct file_activity *file_actlst, parm.graph_nr = graph_nr; parm.views_per_row = PACK_VIEWS(flags) ? views_per_row : 1; + parm.nr_act_dispd = nr_act_dispd; /* Print SVG header */ if (*fmt[f_position]->f_header) { @@ -1316,7 +1328,7 @@ void logic3_display_loop(int ifd, struct file_activity *file_actlst, display_curr_act_graphs(ifd, &curr, &cnt, &eosaf, p, &reset, file_actlst, rectime, loctime, file, - file_magic, &g_nr); + file_magic, &g_nr, nr_act_dispd); } else { unsigned int optf, msk; @@ -1329,7 +1341,7 @@ void logic3_display_loop(int ifd, struct file_activity *file_actlst, display_curr_act_graphs(ifd, &curr, &cnt, &eosaf, p, &reset, file_actlst, rectime, loctime, file, - file_magic, &g_nr); + file_magic, &g_nr, nr_act_dispd); act[p]->opt_flags = optf; } } @@ -1517,6 +1529,9 @@ int main(int argc, char **argv) else if (!strcmp(t, K_PACKED)) { flags |= S_F_SVG_PACKED; } + else if (!strcmp(t, K_SHOWTOC)) { + flags |= S_F_SVG_SHOW_TOC; + } else { usage(argv[0]); } diff --git a/sadf_misc.c b/sadf_misc.c index 1d2d279..eb51266 100644 --- a/sadf_misc.c +++ b/sadf_misc.c @@ -34,6 +34,8 @@ extern unsigned int flags; extern char *seps[]; +extern unsigned int id_seq[]; + /* *************************************************************************** @@ -918,21 +920,35 @@ __printf_funct_t print_svg_header(void *parm, int action, char *dfile, struct file_activity *file_actlst) { struct svg_hdr_parm *hdr_parm = (struct svg_hdr_parm *) parm; - unsigned int height = 0; + unsigned int height = 0, ht = 0; + int i, p; if (action & F_BEGIN) { printf("\n"); printf("\n"); printf("\n"); } } if (action & F_MAIN) { - height = SET_CANVAS_HEIGHT(flags) ? hdr_parm->graph_nr - : SVG_H_YSIZE + SVG_T_YSIZE * (hdr_parm->graph_nr); + if (SET_CANVAS_HEIGHT(flags)) { + /* + * Option "-O height=..." used: @graph_nr is + * the SVG canvas height set on the command line. + */ + height = hdr_parm->graph_nr; + } + else { + height = SVG_H_YSIZE + + SVG_C_YSIZE * (DISPLAY_TOC(flags) ? hdr_parm->nr_act_dispd : 0) + + SVG_T_YSIZE * hdr_parm->graph_nr; + } if (height < 100) { /* Min canvas height is 100 (at least to display "No data") */ height = 100; @@ -947,6 +963,22 @@ __printf_funct_t print_svg_header(void *parm, int action, char *dfile, file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1, PLAIN_OUTPUT); printf("\n"); + if (DISPLAY_TOC(flags)) { + for (i = 0; i < NR_ACT; i++) { + if (!id_seq[i]) + continue; + + p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND); + if (!IS_SELECTED(act[p]->options) || !act[p]->g_nr) + continue; + + printf("\n", + act[p]->id, act[p]->name); + printf("%s\n", + SVG_H_YSIZE + ht, act[p]->desc); + ht += SVG_C_YSIZE; + } + } } if (action & F_END) { @@ -958,7 +990,9 @@ __printf_funct_t print_svg_header(void *parm, int action, char *dfile, } /* Give actual SVG height */ printf("\n", - SVG_H_YSIZE + SVG_T_YSIZE * (hdr_parm->graph_nr)); + SVG_H_YSIZE + + SVG_C_YSIZE * (DISPLAY_TOC(flags) ? hdr_parm->nr_act_dispd : 0) + + SVG_T_YSIZE * hdr_parm->graph_nr); } printf("\n"); } diff --git a/svg_stats.c b/svg_stats.c index 7fa2448..0974efc 100644 --- a/svg_stats.c +++ b/svg_stats.c @@ -878,7 +878,9 @@ void draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[] /* Translate to proper position for current activity */ printf("\n", id, xid, - SVG_H_YSIZE + svg_p->graph_no * SVG_T_YSIZE); + SVG_H_YSIZE + + SVG_C_YSIZE * (DISPLAY_TOC(flags) ? svg_p->nr_act_dispd : 0) + + SVG_T_YSIZE * svg_p->graph_no); /* For each view which is part of current activity */ for (i = 0; i < g_nr; i++) { -- 2.40.0