]> granicus.if.org Git - sysstat/blobdiff - svg_stats.c
Merge branch 'scop-grep-E'
[sysstat] / svg_stats.c
index cd6ed488c599b9aa924c0588f621073ed9035be1..aea9bda0cd862e86a2c2ba037b343b13a991dda3 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * svg_stats.c: Funtions used by sadf to display statistics in SVG format.
- * (C) 2016 by Sebastien GODARD (sysstat <at> orange.fr)
+ * svg_stats.c: Functions used by sadf to display statistics in SVG format.
+ * (C) 2016-2021 by Sebastien GODARD (sysstat <at> orange.fr)
  *
  ***************************************************************************
  * This program is free software; you can redistribute it and/or modify it *
@@ -26,7 +26,6 @@
 #include <float.h>
 
 #include "sa.h"
-#include "sadf.h"
 #include "ioconf.h"
 #include "svg_stats.h"
 
 #define _(string) (string)
 #endif
 
-extern unsigned int flags;
-extern unsigned int dm_major;
-
-unsigned int svg_colors[] = {0x00cc00, 0xff00bf, 0x00ffff, 0xff0000,
-                            0xe85f00, 0x0000ff, 0x006020, 0x7030a0,
-                            0xffff00, 0x666635, 0xd60093, 0x00bfbf,
-                            0xcc3300, 0xbfbfbf, 0xffffbf, 0xff3300};
-#define SVG_COLORS_IDX_MASK    0x0f
+extern uint64_t flags;
+extern int palette;
+
+unsigned int svg_colors[SVG_COL_PALETTE_NR][SVG_COL_PALETTE_SIZE] =
+       {{0x00cc00, 0xff00bf, 0x00ffff, 0xff0000,       /* Default palette */
+         0xe85f00, 0x0000ff, 0x006020, 0x7030a0,
+         0xffff00, 0x666635, 0xd60093, 0x00bfbf,
+         0xcc3300, 0x50040f, 0xffffbf, 0x193d55,
+         0x000000, 0xffffff, 0x202020, 0xffff00,
+         0xffff00, 0x808080, 0xa52a2a, 0xff0000},
+
+        {0x000000, 0x1a1aff, 0x1affb2, 0xb21aff,       /* Custom color palette */
+         0x1ab2ff, 0xff1a1a, 0xffb31a, 0xb2ff1a,
+         0xefefef, 0x000000, 0x1a1aff, 0x1affb2,
+         0xb21aff, 0x1ab2ff, 0xff1a1a, 0xffb31a,
+         0xffffff, 0x000000, 0xbebebe, 0x000000,
+         0x000000, 0x000000, 0x000000, 0x000000},
+
+        {0x696969, 0xbebebe, 0x000000, 0xa9a9a9,       /* Black & white palette */
+         0x708090, 0xc0c0c0, 0x808080, 0xd3d3d3,
+         0x909090, 0x696969, 0xbebebe, 0x000000,
+         0x000000, 0xa9a9a9, 0xc0c0c0, 0x808080,
+         0xffffff, 0x000000, 0xbebebe, 0x000000,
+         0x000000, 0x000000, 0x000000, 0x000000}};
 
 /*
  ***************************************************************************
@@ -58,25 +73,25 @@ unsigned int svg_colors[] = {0x00cc00, 0xff00bf, 0x00ffff, 0xff0000,
  * followed by @u_nr unsigned int fields.
  *
  * IN:
- * @llu_nr     Number of unsigned long long fields composing the structure.
- * @lu_nr      Number of unsigned long fields composing the structure.
- * @u_nr       Number of unsigned int fields composing the structure.
+ * @types_nr   Number of fields whose type is "long long", "long" and "int"
+ *             composing the structure.
  * @cs         Pointer on current sample statistics structure.
  * @ps         Pointer on previous sample statistics structure (may be NULL).
- * @itv                Interval of time in jiffies.
- * @minv       Array containing min values already found for this activity.
- * @maxv       Array containing max values already found for this activity.
+ * @itv                Interval of time in 1/100th of a second.
+ * @spmin      Array containing min values already found for this activity.
+ * @spmax      Array containing max values already found for this activity.
+ * @g_fields   Index in spmin/spmax arrays where extrema values for each
+ *             activity metric will be saved. As a consequence spmin/spmax
+ *             arrays may contain values in a different order than that of
+ *             the fields in the statistics structure.
  *
  * OUT:
- * @minv       Array containg the possible new min values for current activity.
- * @maxv       Array containg the possible new max values for current activity.
- *
- * NB: @minv and @maxv arrays contain values in the same order as the fields
- * in the statistics structure.
+ * @spmin      Array containing the possible new min values for current activity.
+ * @spmax      Array containing the possible new max values for current activity.
  ***************************************************************************
  */
-void save_extrema(int llu_nr, int lu_nr, int u_nr, void *cs, void *ps,
-                 unsigned long long itv, double *spmin, double *spmax, int g_fields[])
+void save_extrema(unsigned int types_nr[], void *cs, void *ps, unsigned long long itv,
+                 double *spmin, double *spmax, int g_fields[])
 {
        unsigned long long *lluc, *llup;
        unsigned long *luc, *lup;
@@ -87,7 +102,7 @@ void save_extrema(int llu_nr, int lu_nr, int u_nr, void *cs, void *ps,
        /* Compare unsigned long long fields */
        lluc = (unsigned long long *) cs;
        llup = (unsigned long long *) ps;
-       for (i = 0; i < llu_nr; i++, m++) {
+       for (i = 0; i < types_nr[0]; i++, m++) {
                if (ps) {
                        val = *lluc < *llup ? 0.0 : S_VALUE(*llup, *lluc, itv);
                }
@@ -113,7 +128,7 @@ void save_extrema(int llu_nr, int lu_nr, int u_nr, void *cs, void *ps,
        /* Compare unsigned long fields */
        luc = (unsigned long *) lluc;
        lup = (unsigned long *) llup;
-       for (i = 0; i < lu_nr; i++, m++) {
+       for (i = 0; i < types_nr[1]; i++, m++) {
                if (ps) {
                        val = *luc < *lup ? 0.0 : S_VALUE(*lup, *luc, itv);
                }
@@ -135,7 +150,7 @@ void save_extrema(int llu_nr, int lu_nr, int u_nr, void *cs, void *ps,
        /* Compare unsigned int fields */
        uc = (unsigned int *) luc;
        up = (unsigned int *) lup;
-       for (i = 0; i < u_nr; i++, m++) {
+       for (i = 0; i < types_nr[2]; i++, m++) {
                if (ps) {
                        val = *uc < *up ? 0.0 : S_VALUE(*up, *uc, itv);
                }
@@ -159,13 +174,13 @@ void save_extrema(int llu_nr, int lu_nr, int u_nr, void *cs, void *ps,
  ***************************************************************************
  * Find the min and max values of all the graphs that will be drawn in the
  * same view. The graphs have their own min and max values in
- * minv[pos...pos+n-1] and maxv[pos...pos+n-1]. 
+ * spmin[pos...pos+n-1] and spmax[pos...pos+n-1]. 
  *
  * IN:
  * @pos                Position in array for the first graph extrema value.
  * @n          Number of graphs to scan.
- * @minv       Array containing min values for graphs.
- * @maxv       Array containing max values for graphs.
+ * @spmin      Array containing min values for graphs.
+ * @spmax      Array containing max values for graphs.
  *
  * OUT:
  * @gmin       Global min value found.
@@ -320,12 +335,13 @@ void save_svg_data(char *data, char **out, int *outsize)
  *             element in array of chars.
  ***************************************************************************
  */
-void lnappend(unsigned long timetag, double value, char **out, int *outsize, int restart)
+void lnappend(unsigned long long timetag, double value, char **out, int *outsize,
+             int restart)
 {
        char data[128];
 
        /* Prepare additional graph definition data */
-       snprintf(data, 128, " %c%lu,%.2f", restart ? 'M' : 'L', timetag, value);
+       snprintf(data, 128, " %c%llu,%.2f", restart ? 'M' : 'L', timetag, value);
        data[127] = '\0';
 
        save_svg_data(data, out, outsize);
@@ -352,13 +368,13 @@ void lnappend(unsigned long timetag, double value, char **out, int *outsize, int
  *             element in array of chars.
  ***************************************************************************
  */
-void lniappend(unsigned long timetag, unsigned long value, char **out, int *outsize,
-              int restart)
+void lniappend(unsigned long long timetag, unsigned long long value, char **out,
+              int *outsize, int restart)
 {
        char data[128];
 
        /* Prepare additional graph definition data */
-       snprintf(data, 128, " %c%lu,%lu", restart ? 'M' : 'L', timetag, value);
+       snprintf(data, 128, " %c%llu,%llu", restart ? 'M' : 'L', timetag, value);
        data[127] = '\0';
 
        save_svg_data(data, out, outsize);
@@ -386,18 +402,22 @@ void lniappend(unsigned long timetag, unsigned long value, char **out, int *outs
  *             element in array of chars.
  ***************************************************************************
  */
-void brappend(unsigned long timetag, double offset, double value, char **out, int *outsize,
-             unsigned long dt)
+void brappend(unsigned long long timetag, double offset, double value, char **out,
+             int *outsize, unsigned long long dt)
 {
        char data[128];
+       unsigned long long t = 0;
 
        /* Prepare additional graph definition data */
        if ((value == 0.0) || (dt == 0))
-               /* Dont draw a flat rectangle! */
+               /* Don't draw a flat rectangle! */
                return;
+       if (dt < timetag) {
+               t = timetag -dt;
+       }
 
-       snprintf(data, 128, "<rect x=\"%lu\" y=\"%.2f\" height=\"%.2f\" width=\"%lu\"/>",
-                timetag - dt, MINIMUM(offset, 100.0), MINIMUM(value, (100.0 - offset)), dt);
+       snprintf(data, 128, "<rect x=\"%llu\" y=\"%.2f\" height=\"%.2f\" width=\"%llu\"/>",
+                t, MINIMUM(offset, 100.0), MINIMUM(value, (100.0 - offset)), dt);
        data[127] = '\0';
 
        save_svg_data(data, out, outsize);
@@ -429,8 +449,8 @@ void brappend(unsigned long timetag, double offset, double value, char **out, in
  *             element in array of chars.
  ***************************************************************************
  */
-void cpuappend(unsigned long timetag, double *offset, double value, char **out, int *outsize,
-              unsigned long dt, double *spmin, double *spmax)
+void cpuappend(unsigned long long timetag, double *offset, double value, char **out,
+              int *outsize, unsigned long long dt, double *spmin, double *spmax)
 {
        /* Save min and max values */
        if (value < *spmin) {
@@ -472,10 +492,12 @@ void cpuappend(unsigned long timetag, double *offset, double value, char **out,
  * @spmax      Max value for this metric.
  ***************************************************************************
  */
-void recappend(unsigned long timetag, double p_value, double value, char **out, int *outsize,
-              int restart, unsigned long dt, double *spmin, double *spmax)
+void recappend(unsigned long long timetag, double p_value, double value, char **out,
+              int *outsize, int restart, unsigned long long dt,
+              double *spmin, double *spmax)
 {
-       char data[128], data1[128], data2[128];
+       char data[512], data1[128], data2[128];
+       unsigned long long t = 0;
 
        /* Save min and max values */
        if (value < *spmin) {
@@ -484,18 +506,21 @@ void recappend(unsigned long timetag, double p_value, double value, char **out,
        if (value > *spmax) {
                *spmax = value;
        }
+       if (dt < timetag) {
+               t = timetag -dt;
+       }
        /* Prepare additional graph definition data */
        if (restart) {
-               snprintf(data1, 128, " M%lu,%.2f", timetag - dt, p_value);
-               data1[127] = '\0';
+               snprintf(data1, sizeof(data1), " M%llu,%.2f", t, p_value);
+               data1[sizeof(data1) - 1] = '\0';
        }
        if (p_value != value) {
-               snprintf(data2, 128, " L%lu,%.2f", timetag, value);
-               data2[127] = '\0';
+               snprintf(data2, sizeof(data2), " L%llu,%.2f", timetag, value);
+               data2[sizeof(data2) - 1] = '\0';
        }
-       snprintf(data, 128, "%s L%lu,%.2f%s", restart ? data1 : "", timetag, p_value,
+       snprintf(data, sizeof(data), "%s L%llu,%.2f%s", restart ? data1 : "", timetag, p_value,
                 p_value != value ? data2 : "");
-       data[127] = '\0';
+       data[sizeof(data) - 1] = '\0';
 
        save_svg_data(data, out, outsize);
 }
@@ -580,12 +605,19 @@ void display_hgrid(double ypos, double yfactor, double lmax, int dp)
        int j = 0;
        char stmp[32];
 
+       /* Print marker in debug mode */
+       if (DISPLAY_DEBUG_MODE(flags)) {
+               printf("<!-- Hgrid -->\n");
+       }
+
        do {
                /* Display horizontal lines (except on X axis) */
                if (j > 0) {
                        printf("<polyline points=\"0,%.2f %d,%.2f\" style=\"vector-effect: non-scaling-stroke; "
-                              "stroke: #202020\" transform=\"scale(1,%f)\"/>\n",
-                              ypos * j, SVG_G_XSIZE, ypos * j, yfactor);
+                              "stroke: #%06x\" transform=\"scale(1,%f)\"/>\n",
+                              ypos * j, SVG_G_XSIZE, ypos * j,
+                              svg_colors[palette][SVG_COL_GRID_IDX],
+                              yfactor);
                }
 
                /*
@@ -594,12 +626,14 @@ void display_hgrid(double ypos, double yfactor, double lmax, int dp)
                 * to make sure they are properly aligned.
                 */
                sprintf(stmp, "%.2f", ypos * j);
-               printf("<text x=\"0\" y=\"%ld\" style=\"fill: white; stroke: none; font-size: 12px; "
+               printf("<text x=\"0\" y=\"%ld\" style=\"fill: #%06x; stroke: none; font-size: 12px; "
                       "text-anchor: end\">%.*f.</text>\n",
-                      (long) (atof(stmp) * yfactor), dp, ypos * j);
+                      (long) (atof(stmp) * yfactor),
+                      svg_colors[palette][SVG_COL_AXIS_IDX],
+                      dp, ypos * j);
                j++;
        }
-       while (ypos * j <= lmax);
+       while ((ypos * j <= lmax) && (j < MAX_HLINES_NR));
 }
 
 /*
@@ -609,7 +643,8 @@ void display_hgrid(double ypos, double yfactor, double lmax, int dp)
  * IN:
  * @xpos       Gap between two vertical lines.
  * @xfactor    Scaling factor on X axis.
- * @v_gridnr   Number of vertical lines to display.
+ * @v_gridnr   Default number of vertical lines to display. The actual
+ *             number may vary between this value and 2 times this value.
  * @svg_p      SVG specific parameters (see draw_activity_graphs() function).
  ***************************************************************************
  */
@@ -622,35 +657,57 @@ void display_vgrid(long int xpos, double xfactor, int v_gridnr, struct svg_parm
 
        stamp.ust_time = svg_p->ust_time_ref; /* Only ust_time field needs to be set. TRUE_TIME not allowed */
 
-       for (j = 0; (j <= v_gridnr) && (stamp.ust_time <= svg_p->ust_time_end); j++) {
+       /* Print marker in debug mode */
+       if (DISPLAY_DEBUG_MODE(flags)) {
+               printf("<!-- Vgrid -->\n");
+       }
+
+       /*
+        * What really matters to know when we should stop drawing vertical lines
+        * is the time end. v_gridnr is only informative and used to calculate
+        * the gap between two lines.
+        */
+       for (j = 0; (j <= (2 * v_gridnr)) && (stamp.ust_time <= svg_p->ust_time_end); j++) {
 
                /* Display vertical lines */
-               sa_get_record_timestamp_struct(flags, &stamp, &rectime, NULL);
+               if (sa_get_record_timestamp_struct(flags, &stamp, &rectime)) {
+#ifdef DEBUG
+                       fprintf(stderr, "%s: ust_time: %llu\n", __FUNCTION__, stamp.ust_time);
+#endif
+                       exit(1);
+               }
                set_record_timestamp_string(flags, &stamp, NULL, cur_time, TIMESTAMP_LEN, &rectime);
                printf("<polyline points=\"%ld,0 %ld,%d\" style=\"vector-effect: non-scaling-stroke; "
-                      "stroke: #202020\" transform=\"scale(%f,1)\"/>\n",
-                      xpos * j, xpos * j, -SVG_G_YSIZE, xfactor);
+                      "stroke: #%06x\" transform=\"scale(%f,1)\"/>\n",
+                      xpos * j, xpos * j, -SVG_G_YSIZE,
+                      svg_colors[palette][SVG_COL_GRID_IDX],
+                      xfactor);
                /*
                 * Display graduations.
                 * NB: We may have tm_min != 0 if we have more than 24H worth of data in one datafile.
                 * In this case, we should rather display the exact time instead of only the hour.
                 */
                if (DISPLAY_ONE_DAY(flags) && (rectime.tm_min == 0)) {
-                       printf("<text x=\"%ld\" y=\"15\" style=\"fill: white; stroke: none; font-size: 14px; "
-                              "text-anchor: start\">%2dH</text>\n",
-                              (long) (xpos * j * xfactor) - 8, rectime.tm_hour);
+                       printf("<text x=\"%ld\" y=\"15\" style=\"fill: #%06x; stroke: none; font-size: 14px; "
+                              "text-anchor: start\">%2d:00</text>\n",
+                              (long) (xpos * j * xfactor) - 15,
+                              svg_colors[palette][SVG_COL_AXIS_IDX],
+                              rectime.tm_hour);
                }
                else {
-                       printf("<text x=\"%ld\" y=\"10\" style=\"fill: white; stroke: none; font-size: 12px; "
+                       printf("<text x=\"%ld\" y=\"10\" style=\"fill: #%06x; stroke: none; font-size: 12px; "
                               "text-anchor: start\" transform=\"rotate(45,%ld,0)\">%s</text>\n",
-                              (long) (xpos * j * xfactor), (long) (xpos * j * xfactor), cur_time);
+                              (long) (xpos * j * xfactor),
+                              svg_colors[palette][SVG_COL_AXIS_IDX],
+                              (long) (xpos * j * xfactor), cur_time);
                }
                stamp.ust_time += xpos;
        }
 
        if (!PRINT_LOCAL_TIME(flags)) {
-               printf("<text x=\"-10\" y=\"30\" style=\"fill: yellow; stroke: none; font-size: 12px; "
-                      "text-anchor: end\">UTC</text>\n");
+               printf("<text x=\"-10\" y=\"30\" style=\"fill: #%06x; stroke: none; font-size: 12px; "
+                      "text-anchor: end\">UTC</text>\n",
+                      svg_colors[palette][SVG_COL_INFO_IDX]);
        }
 }
 
@@ -781,7 +838,7 @@ void skip_current_view(char **out, int *pos, int group)
  * Display all graphs for current activity.
  *
  * IN:
- * @g_nr       Number of sets of graphs (views) to display.
+ * @g_nr       Number of views to display.
  * @g_type     Type of graph (SVG_LINE_GRAPH, SVG_BAR_GRAPH) for each view.
  * @title      Titles for each set of graphs.
  * @g_title    Titles for each graph.
@@ -791,34 +848,52 @@ void skip_current_view(char **out, int *pos, int group)
  * @spmax      Array containing max values for graphs.
  * @out                Pointer on array of chars for each graph definition.
  * @outsize    Size of array of chars for each graph definition.
- * @svg_p      SVG specific parameters: Current graph number (.@graph_no),
+ * @svg_p      SVG specific parameters: Current views row number (.@graph_no),
  *             time for the first sample of stats (.@ust_time_first), and
  *             times used as start and end values on the X axis
  *             (.@ust_time_ref and .@ust_time_end).
  * @record_hdr Pointer on record header of current stats sample.
+ * @skip_void  Set to <> 0 if graphs with no data should be skipped.
+ *             This is typicallly used to not display CPU offline on the
+ *             whole period.
+ * @a          Current activity structure.
+ * @xid                Current activity extra id number.
+ *
+ * RETURNS:
+ * TRUE if at least one graph has been displayed.
  ***************************************************************************
  */
-void draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[], char *item_name,
-                         int group[], double *spmin, double *spmax, char **out, int *outsize,
-                         struct svg_parm *svg_p, struct record_header *record_hdr)
+int draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[], char *item_name,
+                        int group[], double *spmin, double *spmax, char **out, int *outsize,
+                        struct svg_parm *svg_p, struct record_header *record_hdr, int skip_void,
+                        struct activity *a, unsigned int xid)
 {
        char *out_p;
-       int i, j, dp, pos = 0, views_nr = 0;
-       int v_gridnr;
+       int i, j, dp, pos = 0, views_nr = 0, displayed = FALSE, palpos;
+       int v_gridnr, xv, yv;
        unsigned int asfactor[16];
        long int xpos;
        double lmax, xfactor, yfactor, ypos, gmin, gmax;
-       char val[32];
+       char val[32], cur_date[TIMESTAMP_LEN];
+       struct tm rectime;
 
-       /* Translate to proper position for current activity */
-       printf("<g id=\"g%d\" transform=\"translate(0,%d)\">\n",
-              svg_p->graph_no,
-              SVG_H_YSIZE + svg_p->graph_no * SVG_T_YSIZE);
+       /* Print activity name in debug mode */
+       if (DISPLAY_DEBUG_MODE(flags)) {
+               printf("<!-- Name: %s -->\n", a->name);
+       }
 
-       /* For each set of graphs which are part of current activity */
+       /* For each view which is part of current activity */
        for (i = 0; i < g_nr; i++) {
 
-               /* Get global min and max value for current set of graphs */
+               /* Print view number in debug mode */
+               if (DISPLAY_DEBUG_MODE(flags)) {
+                       printf("<!-- View %d -->\n", i + 1);
+               }
+
+               /* Used as index in color palette */
+               palpos = (palette == SVG_BW_COL_PALETTE ? 0 : pos);
+
+               /* Get global min and max value for current view */
                get_global_extrema(pos, group[i], spmin, spmax, &gmin, &gmax);
 
                /* Don't display empty views if requested */
@@ -826,25 +901,51 @@ void draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[]
                        skip_current_view(out, &pos, group[i]);
                        continue;
                }
+               /* Skip void graphs */
+               if (skip_void && ((*(spmin + pos) == DBL_MAX) || (*(spmax + pos) == -DBL_MIN)))
+                       continue;
+
+               if (!displayed) {
+                       /* Translate to proper position for current activity */
+                       printf("<g id=\"g%d-%d\" transform=\"translate(0,%d)\">\n",
+                              a->id, xid,
+                              SVG_H_YSIZE +
+                              SVG_C_YSIZE * (DISPLAY_TOC(flags) ? svg_p->nr_act_dispd : 0) +
+                              SVG_T_YSIZE * svg_p->graph_no);
+                       displayed = TRUE;
+               }
+
                /* Increment number of views actually displayed */
                views_nr++;
 
+               /* Compute top left position of view */
+               if (PACK_VIEWS(flags)) {
+                       xv = (views_nr - 1) * SVG_T_XSIZE;
+                       yv = 0;
+               }
+               else {
+                       xv = 0;
+                       yv = (views_nr - 1) * SVG_T_YSIZE;
+               }
+
                /* Graph background */
-               printf("<rect x=\"0\" y=\"%d\" height=\"%d\" width=\"%d\"/>\n",
-                      (views_nr - 1) * SVG_T_YSIZE,
-                      SVG_V_YSIZE, SVG_V_XSIZE);
+               printf("<rect x=\"%d\" y=\"%d\" height=\"%d\" width=\"%d\" fill=\"#%06x\"/>\n",
+                      xv, yv, SVG_V_YSIZE, SVG_V_XSIZE,
+                      svg_colors[palette][SVG_COL_BCKGRD_IDX]);
 
                /* Graph title */
-               printf("<text x=\"0\" y=\"%d\" style=\"fill: yellow; stroke: none\">%s",
-                      20 + (views_nr - 1) * SVG_T_YSIZE, title[i]);
+               printf("<text x=\"%d\" y=\"%d\" style=\"fill: #%06x; stroke: none\">%s",
+                      xv, 20 + yv,
+                      svg_colors[palette][SVG_COL_TITLE_IDX],
+                      title[i]);
                if (item_name) {
                        printf(" [%s]", item_name);
                }
                printf("\n");
-               printf("<tspan x=\"%d\" y=\"%d\" style=\"fill: yellow; stroke: none; font-size: 12px\">"
+               printf("<tspan x=\"%d\" y=\"%d\" style=\"fill: #%06x; stroke: none; font-size: 12px\">"
                       "(Min, Max values)</tspan>\n</text>\n",
-                      5 + SVG_M_XSIZE + SVG_G_XSIZE,
-                      25 + (views_nr - 1) * SVG_T_YSIZE);
+                      xv + 5 + SVG_M_XSIZE + SVG_G_XSIZE, yv + 25,
+                      svg_colors[palette][SVG_COL_INFO_IDX]);
 
                /*
                 * At least two samples are needed.
@@ -853,17 +954,20 @@ void draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[]
                if ((record_hdr->ust_time == svg_p->ust_time_first) ||
                    (*(spmin + pos) == DBL_MAX) || (*(spmax + pos) == -DBL_MIN)) {
                        /* No data found */
-                       printf("<text x=\"0\" y=\"%d\" style=\"fill: red; stroke: none\">No data</text>\n",
-                              SVG_M_YSIZE + (views_nr - 1) * SVG_T_YSIZE);
+                       printf("<text x=\"%d\" y=\"%d\" style=\"fill: #%06x; stroke: none\">No data</text>\n",
+                              xv, yv + SVG_M_YSIZE,
+                              svg_colors[palette][SVG_COL_ERROR_IDX]);
                        skip_current_view(out, &pos, group[i]);
                        continue;
                }
 
                /* X and Y axis */
-               printf("<polyline points=\"%d,%d %d,%d %d,%d\" stroke=\"white\" stroke-width=\"2\"/>\n",
-                      SVG_M_XSIZE, SVG_M_YSIZE + (views_nr - 1) * SVG_T_YSIZE,
-                      SVG_M_XSIZE, SVG_M_YSIZE + SVG_G_YSIZE + (views_nr - 1) * SVG_T_YSIZE,
-                      SVG_M_XSIZE + SVG_G_XSIZE, SVG_M_YSIZE + SVG_G_YSIZE + (views_nr - 1) * SVG_T_YSIZE);
+               printf("<polyline points=\"%d,%d %d,%d %d,%d\" style=\"fill: #%06x; stroke: #%06x; stroke-width: 2\"/>\n",
+                      xv + SVG_M_XSIZE, yv + SVG_M_YSIZE,
+                      xv + SVG_M_XSIZE, yv + SVG_M_YSIZE + SVG_G_YSIZE,
+                      xv + SVG_M_XSIZE + SVG_G_XSIZE, yv + SVG_M_YSIZE + SVG_G_YSIZE,
+                      svg_colors[palette][SVG_COL_BCKGRD_IDX],
+                      svg_colors[palette][SVG_COL_AXIS_IDX]);
 
                /* Autoscaling graphs if needed */
                gr_autoscaling(asfactor, 16, group[i], g_type[i], pos, gmax, spmax);
@@ -875,16 +979,36 @@ void draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[]
                        snprintf(val, 32, "x%u ", asfactor[j]);
                        printf("<text x=\"%d\" y=\"%d\" style=\"fill: #%06x; stroke: none; font-size: 12px\">"
                               "%s %s(%.*f, %.*f)</text>\n",
-                              5 + SVG_M_XSIZE + SVG_G_XSIZE, SVG_M_YSIZE + (views_nr - 1) * SVG_T_YSIZE + j * 15,
-                              svg_colors[(pos + j) & SVG_COLORS_IDX_MASK], g_title[pos + j] + dp,
+                              xv + 5 + SVG_M_XSIZE + SVG_G_XSIZE, yv + SVG_M_YSIZE + j * 15,
+                              svg_colors[palette][(palpos + j) & SVG_COLORS_IDX_MASK], g_title[pos + j] + dp,
                               asfactor[j] == 1 ? "" : val,
                               !dp * 2, *(spmin + pos + j) * asfactor[j],
                               !dp * 2, *(spmax + pos + j) * asfactor[j]);
                }
 
+               if (DISPLAY_INFO(flags)) {
+                       /* Display additional info (hostname, date) */
+                       printf("<text x=\"%d\" y=\"%d\" "
+                              "style=\"fill: #%06x; text-anchor: end; stroke: none; font-size: 14px\">"
+                              "%s\n",
+                              xv + SVG_V_XSIZE - 5, yv + SVG_M_YSIZE + SVG_G_YSIZE,
+                              svg_colors[palette][SVG_COL_INFO_IDX],
+                              svg_p->file_hdr->sa_nodename);
+
+                       /* Get report date */
+                       set_report_date(localtime_r((const time_t *) &(svg_p->file_hdr->sa_ust_time), &rectime),
+                                       cur_date, sizeof(cur_date));
+                       printf("<tspan x=\"%d\" y=\"%d\" "
+                              "style=\"fill: #%06x; text-anchor: end; stroke: none; font-size: 14px\">"
+                              "%s</tspan>\n</text>\n",
+                              xv + SVG_V_XSIZE - 5, yv + SVG_M_YSIZE + SVG_G_YSIZE + 14,
+                              svg_colors[palette][SVG_COL_INFO_IDX],
+                              cur_date);
+               }
+
                /* Translate to proper position for current graph within current activity */
                printf("<g transform=\"translate(%d,%d)\">\n",
-                      SVG_M_XSIZE, SVG_M_YSIZE + SVG_G_YSIZE + (views_nr - 1) * SVG_T_YSIZE);
+                      xv + SVG_M_XSIZE, yv + SVG_M_YSIZE + SVG_G_YSIZE);
 
                /* Grid */
                if (g_type[i] == SVG_LINE_GRAPH) {
@@ -929,24 +1053,29 @@ void draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[]
                /* Display vertical lines and graduations */
                display_vgrid(xpos, xfactor, v_gridnr, svg_p);
 
+               /* Print marker in debug mode */
+               if (DISPLAY_DEBUG_MODE(flags)) {
+                       printf("<!-- Graphs -->\n");
+               }
+
                /* Draw current graphs set */
                for (j = 0; j < group[i]; j++) {
                        out_p = *(out + pos + j);
                        if (g_type[i] == SVG_LINE_GRAPH) {
                                /* Line graphs */
-                               printf("<path id=\"g%dp%d\" d=\"%s\" "
+                               printf("<path d=\"%s\" "
                                       "style=\"vector-effect: non-scaling-stroke; "
                                       "stroke: #%06x; stroke-width: 1; fill-opacity: 0\" "
                                       "transform=\"scale(%f,%f)\"/>\n",
-                                      svg_p->graph_no, pos + j, out_p,
-                                      svg_colors[(pos + j) & SVG_COLORS_IDX_MASK],
+                                      out_p,
+                                      svg_colors[palette][(palpos + j) & SVG_COLORS_IDX_MASK],
                                       xfactor,
                                       yfactor * asfactor[j]);
                        }
                        else if (*out_p) {      /* Ignore flat bars */
                                /* Bar graphs */
                                printf("<g style=\"fill: #%06x; stroke: none\" transform=\"scale(%f,%f)\">\n",
-                                      svg_colors[(pos + j) & SVG_COLORS_IDX_MASK], xfactor, yfactor);
+                                      svg_colors[palette][(palpos + j) & SVG_COLORS_IDX_MASK], xfactor, yfactor);
                                printf("%s\n", out_p);
                                printf("</g>\n");
                        }
@@ -955,10 +1084,14 @@ void draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[]
                printf("</g>\n");
                pos += group[i];
        }
-       printf("</g>\n");
+       if (displayed) {
+               printf("</g>\n");
+
+               /* For next row of views */
+               (svg_p->graph_no) += PACK_VIEWS(flags) ? 1 : views_nr;
+       }
 
-       /* Next graph */
-       (svg_p->graph_no) += views_nr;
+       return displayed;
 }
 
 /*
@@ -973,83 +1106,94 @@ void draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[]
  *             flag indicating that a restart record has been previously
  *             found (.@restart), and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
+ *             Unused here.
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
+#define CPU_ARRAY_SZ   10
 __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
-                                   unsigned long long g_itv, struct record_header *record_hdr)
+                                   unsigned long long itv, struct record_header *record_hdr)
 {
        struct stats_cpu *scc, *scp;
+       unsigned long long deltot_jiffies = 1;
+       unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
        int group1[] = {5};
        int group2[] = {9};
        int g_type[] = {SVG_BAR_GRAPH};
-       char *title[] = {"CPU load"};
+       char *title[] = {"CPU utilization"};
        char *g_title1[] = {"%user", "%nice", "%system", "%iowait", "%steal", "%idle"};
        char *g_title2[] = {"%usr", "%nice", "%sys", "%iowait", "%steal", "%irq", "%soft", "%guest", "%gnice", "%idle"};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
-       char item_name[8];
+       char item_name[16];
        double offset, val;
-       int i, j, k, pos, cpu_offline;
+       int i, j, k, pos;
 
        if (action & F_BEGIN) {
                /*
                 * Allocate arrays that will contain the graphs data
                 * and the min/max values.
                 */
-               out = allocate_graph_lines(10 * a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(CPU_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
-               /* For each CPU */
-               for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
 
-                       scc = (struct stats_cpu *) ((char *) a->buf[curr]  + i * a->msize);
-                       scp = (struct stats_cpu *) ((char *) a->buf[!curr] + i * a->msize);
+               /* @nr[curr] cannot normally be greater than @nr_ini */
+               if (a->nr[curr] > a->nr_ini) {
+                       a->nr_ini = a->nr[curr];
+               }
+
+               /*
+                * Compute CPU "all" as sum of all individual CPU (on SMP machines)
+                * and look for offline CPU.
+                */
+               if (a->nr_ini > 1) {
+                       deltot_jiffies = get_global_cpu_statistics(a, !curr, curr,
+                                                                  flags, offline_cpu_bitmap);
+               }
+
+               /* For each CPU */
+               for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
 
                        /* Should current CPU (including CPU "all") be displayed? */
-                       if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
-                               /* No */
+                       if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) ||
+                           offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07)))
+                               /* Don't display CPU */
                                continue;
 
-                       pos = i * 10;
+                       scc = (struct stats_cpu *) ((char *) a->buf[curr]  + i * a->msize);
+                       scp = (struct stats_cpu *) ((char *) a->buf[!curr] + i * a->msize);
+
+                       pos = i * CPU_ARRAY_SZ;
                        offset = 0.0;
 
-                       if (i) {        /* Don't test CPU "all" here */
-                               /*
-                                * If the CPU is offline then it is omited from /proc/stat:
-                                * All the fields couldn't have been read and the sum of them is zero.
-                                * (Remember that guest/guest_nice times are already included in
-                                * user/nice modes.)
-                                */
-                               if ((scc->cpu_user    + scc->cpu_nice + scc->cpu_sys   +
-                                    scc->cpu_iowait  + scc->cpu_idle + scc->cpu_steal +
-                                    scc->cpu_hardirq + scc->cpu_softirq) == 0) {
+                       if (i == 0) {
+                               /* This is CPU "all" */
+                               if (a->nr_ini == 1) {
                                        /*
-                                        * Set current struct fields (which have been set to zero)
-                                        * to values from previous iteration. Hence their values won't
-                                        * jump from zero when the CPU comes back online.
+                                        * This is a UP machine. In this case
+                                        * interval has still not been calculated.
                                         */
-                                       *scc = *scp;
-
-                                       g_itv = 0;
-                                       cpu_offline = TRUE;
+                                       deltot_jiffies = get_per_cpu_interval(scc, scp);
                                }
-                               else {
-                                       /*
-                                        * Recalculate interval for current proc.
-                                        * If result is 0 then current CPU is a tickless one.
-                                        */
-                                       g_itv = get_per_cpu_interval(scc, scp);
-                                       cpu_offline = FALSE;
+                               if (!deltot_jiffies) {
+                                       /* CPU "all" cannot be tickless */
+                                       deltot_jiffies = 1;
                                }
+                       }
+                       else {
+                               /*
+                                * Recalculate interval for current proc.
+                                * If result is 0 then current CPU is a tickless one.
+                                */
+                               deltot_jiffies = get_per_cpu_interval(scc, scp);
 
-                               if (!g_itv) {   /* Current CPU is offline or tickless */
+                               if (!deltot_jiffies) {  /* Current CPU is tickless */
 
-                                       val = (cpu_offline ? 0.0        /* Offline CPU: %idle = 0% */
-                                                          : 100.0);    /* Tickless CPU: %idle = 100% */
+                                       val = 100.0;    /* Tickless CPU: %idle = 100% */
 
                                        if (DISPLAY_CPU_DEF(a->opt_flags)) {
                                                j  = 5; /* -u */
@@ -1080,7 +1224,7 @@ __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, st
                        if (DISPLAY_CPU_DEF(a->opt_flags)) {
                                /* %user */
                                cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                         &offset, ll_sp_value(scp->cpu_user, scc->cpu_user, g_itv),
+                                         &offset, ll_sp_value(scp->cpu_user, scc->cpu_user, deltot_jiffies),
                                          out + pos, outsize + pos, svg_p->dt,
                                          spmin + pos, spmax + pos);
                        }
@@ -1091,7 +1235,7 @@ __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, st
                                          (scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest) ?
                                           0.0 :
                                           ll_sp_value(scp->cpu_user - scp->cpu_guest,
-                                                      scc->cpu_user - scc->cpu_guest, g_itv),
+                                                      scc->cpu_user - scc->cpu_guest, deltot_jiffies),
                                          out + pos, outsize + pos, svg_p->dt,
                                          spmin + pos, spmax + pos);
                        }
@@ -1099,7 +1243,7 @@ __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, st
                        if (DISPLAY_CPU_DEF(a->opt_flags)) {
                                /* %nice */
                                cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                         &offset, ll_sp_value(scp->cpu_nice, scc->cpu_nice, g_itv),
+                                         &offset, ll_sp_value(scp->cpu_nice, scc->cpu_nice, deltot_jiffies),
                                          out + pos + 1, outsize + pos + 1, svg_p->dt,
                                          spmin + pos + 1, spmax + pos + 1);
                        }
@@ -1110,7 +1254,7 @@ __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, st
                                          (scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice) ?
                                           0.0 :
                                           ll_sp_value(scp->cpu_nice - scp->cpu_guest_nice,
-                                                      scc->cpu_nice - scc->cpu_guest_nice, g_itv),
+                                                      scc->cpu_nice - scc->cpu_guest_nice, deltot_jiffies),
                                          out + pos + 1, outsize + pos + 1, svg_p->dt,
                                          spmin + pos + 1, spmax + pos + 1);
                        }
@@ -1121,48 +1265,48 @@ __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, st
                                          &offset,
                                          ll_sp_value(scp->cpu_sys + scp->cpu_hardirq + scp->cpu_softirq,
                                                      scc->cpu_sys + scc->cpu_hardirq + scc->cpu_softirq,
-                                                     g_itv),
+                                                     deltot_jiffies),
                                          out + pos + 2, outsize + pos + 2, svg_p->dt,
                                          spmin + pos + 2, spmax + pos + 2);
                        }
                        else {
                                /* %sys */
                                cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                         &offset, ll_sp_value(scp->cpu_sys, scc->cpu_sys, g_itv),
+                                         &offset, ll_sp_value(scp->cpu_sys, scc->cpu_sys, deltot_jiffies),
                                          out + pos + 2, outsize + pos + 2, svg_p->dt,
                                          spmin + pos + 2, spmax + pos + 2);
                        }
 
                        /* %iowait */
                        cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                 &offset, ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, g_itv),
+                                 &offset, ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies),
                                  out + pos + 3, outsize + pos + 3, svg_p->dt,
                                  spmin + pos + 3, spmax + pos + 3);
                        /* %steal */
                        cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                 &offset, ll_sp_value(scp->cpu_steal, scc->cpu_steal, g_itv),
+                                 &offset, ll_sp_value(scp->cpu_steal, scc->cpu_steal, deltot_jiffies),
                                  out + pos + 4, outsize + pos + 4, svg_p->dt,
                                  spmin + pos + 4, spmax + pos + 4);
 
                        if (DISPLAY_CPU_ALL(a->opt_flags)) {
                                /* %irq */
                                cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                         &offset, ll_sp_value(scp->cpu_hardirq, scc->cpu_hardirq, g_itv),
+                                         &offset, ll_sp_value(scp->cpu_hardirq, scc->cpu_hardirq, deltot_jiffies),
                                          out + pos + 5, outsize + pos + 5, svg_p->dt,
                                          spmin + pos + 5, spmax + pos + 5);
                                /* %soft */
                                cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                         &offset, ll_sp_value(scp->cpu_softirq, scc->cpu_softirq, g_itv),
+                                         &offset, ll_sp_value(scp->cpu_softirq, scc->cpu_softirq, deltot_jiffies),
                                          out + pos + 6, outsize + pos + 6, svg_p->dt,
                                          spmin + pos + 6, spmax + pos + 6);
                                /* %guest */
                                cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                         &offset, ll_sp_value(scp->cpu_guest, scc->cpu_guest, g_itv),
+                                         &offset, ll_sp_value(scp->cpu_guest, scc->cpu_guest, deltot_jiffies),
                                          out + pos + 7, outsize + pos + 7, svg_p->dt,
                                          spmin + pos + 7, spmax + pos + 7);
                                /* %gnice */
                                cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                         &offset, ll_sp_value(scp->cpu_guest_nice, scc->cpu_guest_nice, g_itv),
+                                         &offset, ll_sp_value(scp->cpu_guest_nice, scc->cpu_guest_nice, deltot_jiffies),
                                          out + pos + 8, outsize + pos + 8, svg_p->dt,
                                          spmin + pos + 8, spmax + pos + 8);
 
@@ -1176,21 +1320,29 @@ __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, st
                        cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                  &offset,
                                  (scc->cpu_idle < scp->cpu_idle ? 0.0 :
-                                  ll_sp_value(scp->cpu_idle, scc->cpu_idle, g_itv)),
+                                  ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies)),
                                  out + pos + j, outsize + pos + j, svg_p->dt,
                                  spmin + pos + j, spmax + pos + j);
                }
        }
 
        if (action & F_END) {
-               for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+               int xid = 0, displayed;
+
+               if (DISPLAY_IDLE(flags)) {
+                       /* Include additional %idle field */
+                       group1[0]++;
+                       group2[0]++;
+               }
+
+               for (i = 0; (i < a->item_list_sz) && (i < a->bitmap->b_size + 1); i++) {
 
                        /* Should current CPU (including CPU "all") be displayed? */
                        if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
                                /* No */
                                continue;
 
-                       pos = i * 10;
+                       pos = i * CPU_ARRAY_SZ;
                        if (!i) {
                                /* This is CPU "all" */
                                strcpy(item_name, "all");
@@ -1200,16 +1352,19 @@ __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, st
                        }
 
                        if (DISPLAY_CPU_DEF(a->opt_flags)) {
-                               draw_activity_graphs(a->g_nr, g_type,
-                                                    title, g_title1, item_name, group1,
-                                                    spmin + pos, spmax + pos, out + pos, outsize + pos,
-                                                    svg_p, record_hdr);
+                               displayed = draw_activity_graphs(a->g_nr, g_type,
+                                                                title, g_title1, item_name, group1,
+                                                                spmin + pos, spmax + pos, out + pos, outsize + pos,
+                                                                svg_p, record_hdr, i, a, xid);
                        }
                        else {
-                               draw_activity_graphs(a->g_nr, g_type,
-                                                    title, g_title2, item_name, group2,
-                                                    spmin + pos, spmax + pos, out + pos, outsize + pos,
-                                                    svg_p, record_hdr);
+                               displayed = draw_activity_graphs(a->g_nr, g_type,
+                                                                title, g_title2, item_name, group2,
+                                                                spmin + pos, spmax + pos, out + pos, outsize + pos,
+                                                                svg_p, record_hdr, i, a, xid);
+                       }
+                       if (displayed) {
+                               xid++;
                        }
                }
 
@@ -1230,7 +1385,7 @@ __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, st
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -1260,7 +1415,7 @@ __print_funct_t svg_print_pcsw_stats(struct activity *a, int curr, int action, s
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(1, 1, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
                /* proc/s */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
@@ -1274,7 +1429,7 @@ __print_funct_t svg_print_pcsw_stats(struct activity *a, int curr, int action, s
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -1293,7 +1448,7 @@ __print_funct_t svg_print_pcsw_stats(struct activity *a, int curr, int action, s
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -1322,7 +1477,7 @@ __print_funct_t svg_print_swap_stats(struct activity *a, int curr, int action, s
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 2, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
                /* pswpin/s */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
@@ -1336,7 +1491,7 @@ __print_funct_t svg_print_swap_stats(struct activity *a, int curr, int action, s
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -1355,7 +1510,7 @@ __print_funct_t svg_print_swap_stats(struct activity *a, int curr, int action, s
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -1386,7 +1541,7 @@ __print_funct_t svg_print_paging_stats(struct activity *a, int curr, int action,
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 8, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
                /* pgpgin/s */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
@@ -1424,7 +1579,7 @@ __print_funct_t svg_print_paging_stats(struct activity *a, int curr, int action,
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -1443,7 +1598,7 @@ __print_funct_t svg_print_paging_stats(struct activity *a, int curr, int action,
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -1453,12 +1608,23 @@ __print_funct_t svg_print_io_stats(struct activity *a, int curr, int action, str
        struct stats_io
                *sic = (struct stats_io *) a->buf[curr],
                *sip = (struct stats_io *) a->buf[!curr];
-       int group[] = {3, 2};
+       int group[] = {4, 3};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
        char *title[] = {"I/O and transfer rate statistics (1)", "I/O and transfer rate statistics (2)"};
-       char *g_title[] = {"tps", "rtps", "wtps",
-                          "bread/s", "bwrtn/s"};
-       int g_fields[] = {0, 1, 2, 3, 4};
+       char *g_title[] = {"tps", "rtps", "wtps", "dtps",
+                          "bread/s", "bwrtn/s", "bdscd/s"};
+       /*
+        * tps:0, rtps:1, wtps:2, dtps:3, bread/s:4, bwrtn/s:5, bdscd/s:6
+        * g_fields[]:
+        *      dk_drive=0
+        *      dk_drive_rio:1
+        *      dk_drive_wio:2
+        *      dk_drive_rblk:4
+        *      dk_drive_wblk:5
+        *      dk_drive_dio:3
+        *      dk_drive_dblk:6
+        */
+       int g_fields[] = {0, 1, 2, 4, 5, 3, 6};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
@@ -1468,12 +1634,12 @@ __print_funct_t svg_print_io_stats(struct activity *a, int curr, int action, str
                 * Allocate arrays that will contain the graphs data
                 * and the min/max values.
                 */
-               out = allocate_graph_lines(5, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(7, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 5, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /*
@@ -1497,21 +1663,31 @@ __print_funct_t svg_print_io_stats(struct activity *a, int curr, int action, str
                         sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 :
                         S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv),
                         out + 2, outsize + 2, svg_p->restart);
+               /* dtps */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        sic->dk_drive_dio < sip->dk_drive_dio ? 0.0 :
+                        S_VALUE(sip->dk_drive_dio, sic->dk_drive_dio, itv),
+                        out + 3, outsize + 3, svg_p->restart);
                /* bread/s */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                         sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 :
                         S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv),
-                        out + 3, outsize + 3, svg_p->restart);
+                        out + 4, outsize + 4, svg_p->restart);
                /* bwrtn/s */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                         sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 :
                         S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv),
-                        out + 4, outsize + 4, svg_p->restart);
+                        out + 5, outsize + 5, svg_p->restart);
+               /* bdscd/s */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        sic->dk_drive_dblk < sip->dk_drive_dblk ? 0.0 :
+                        S_VALUE(sip->dk_drive_dblk, sic->dk_drive_dblk, itv),
+                        out + 6, outsize + 6, svg_p->restart);
        }
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -1530,7 +1706,7 @@ __print_funct_t svg_print_io_stats(struct activity *a, int curr, int action, str
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -1549,18 +1725,20 @@ __print_funct_t svg_print_memory_stats(struct activity *a, int curr, int action,
                          "Memory utilization (5)", "Memory utilization (6)"};
        char *title2[] = {"Swap utilization (1)", "Swap utilization (2)",
                          "Swap utilization (3)"};
-       char *g_title1[] = {"MBmemfree", "MBmemused", "MBavail", "%memused", "MBbuffers",
+       char *g_title1[] = {"MBmemfree", "MBavail", "MBmemused", "%memused", "MBbuffers",
                            "MBcached", "MBcommit", "%commit", "MBactive", "MBinact",
                            "MBdirty", "MBanonpg", "MBslab", "MBkstack", "MBpgtbl",
                            "MBvmused"};
        char *g_title2[] = {"MBswpfree", "MBswpused", "MBswpcad", "%swpused",
                            "%swpcad"};
-       int g_fields[] = {0, 4, 5, 21, 16, 22, 18, 6, 8, 9, 10, 11, 12, 13, 14, 15, 2};
+       int g_fields[] = {0, 4, 5, 21, 16, 22, 18, 6, 8, 9, 10, 11, 12, 13, 14, 15, 1};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
+       static int xid = 0;
        double tval;
        int i;
+       unsigned long long nousedmem;
 
        if (action & F_BEGIN) {
                /*
@@ -1572,10 +1750,14 @@ __print_funct_t svg_print_memory_stats(struct activity *a, int curr, int action,
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 17, 0, (void *) a->buf[curr], NULL,
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
                             itv, spmin, spmax, g_fields);
                /* Compute %memused min/max values */
-               tval = smc->tlmkb ? SP_VALUE(smc->frmkb, smc->tlmkb, smc->tlmkb) : 0.0;
+               nousedmem = smc->frmkb + smc->bufkb + smc->camkb + smc->slabkb;
+               if (nousedmem > smc->tlmkb) {
+                       nousedmem = smc->tlmkb;
+               }
+               tval = smc->tlmkb ? SP_VALUE(nousedmem, smc->tlmkb, smc->tlmkb) : 0.0;
                if (tval > *(spmax + 3)) {
                        *(spmax + 3) = tval;
                }
@@ -1610,12 +1792,12 @@ __print_funct_t svg_print_memory_stats(struct activity *a, int curr, int action,
                        *(spmin + 20) = tval;
                }
                /* Compute memused min/max values in MB */
-               tval = ((double) (smc->tlmkb - smc->frmkb)) / 1024;
-               if (tval > *(spmax + 1)) {
-                       *(spmax + 1) = tval;
+               tval = ((double) (smc->tlmkb - nousedmem)) / 1024;
+               if (tval > *(spmax + 2)) {
+                       *(spmax + 2) = tval;
                }
-               if (tval < *(spmin + 1)) {
-                       *(spmin + 1) = tval;
+               if (tval < *(spmin + 2)) {
+                       *(spmin + 2) = tval;
                }
                /* Compute swpused min/max values in MB */
                tval = ((double) (smc->tlskb - smc->frskb)) / 1024;
@@ -1632,12 +1814,12 @@ __print_funct_t svg_print_memory_stats(struct activity *a, int curr, int action,
                         out, outsize, svg_p->restart);
                /* MBmemused */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                        ((double) (smc->tlmkb - smc->frmkb)) / 1024,
-                        out + 1, outsize + 1, svg_p->restart);
+                        ((double) (smc->tlmkb - nousedmem)) / 1024,
+                        out + 2, outsize + 2, svg_p->restart);
                /* MBavail */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                         ((double) smc->availablekb) / 1024,
-                        out + 2, outsize + 2, svg_p->restart);
+                        out + 1, outsize + 1, svg_p->restart);
                /* MBbuffers */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                         ((double) smc->bufkb) / 1024,
@@ -1698,7 +1880,7 @@ __print_funct_t svg_print_memory_stats(struct activity *a, int curr, int action,
                brappend(record_hdr->ust_time - svg_p->ust_time_ref,
                         0.0,
                         smc->tlmkb ?
-                        SP_VALUE(smc->frmkb, smc->tlmkb, smc->tlmkb) : 0.0,
+                        SP_VALUE(nousedmem, smc->tlmkb, smc->tlmkb) : 0.0,
                         out + 3, outsize + 3, svg_p->dt);
                /* %commit */
                brappend(record_hdr->ust_time - svg_p->ust_time_ref,
@@ -1728,16 +1910,19 @@ __print_funct_t svg_print_memory_stats(struct activity *a, int curr, int action,
                        *(spmax + g_fields[i]) /= 1024;
                }
 
-               if (DISPLAY_MEM_AMT(a->opt_flags)) {
-                       draw_activity_graphs(DISPLAY_MEM_ALL(a->opt_flags) ? 6 : 5,
-                                            g_type1, title1, g_title1, NULL, group1,
-                                            spmin, spmax, out, outsize, svg_p, record_hdr);
+               if (DISPLAY_MEMORY(a->opt_flags)) {
+                       if (draw_activity_graphs(DISPLAY_MEM_ALL(a->opt_flags) ? 6 : 5,
+                                                g_type1, title1, g_title1, NULL, group1,
+                                                spmin, spmax, out, outsize, svg_p, record_hdr,
+                                                FALSE, a, xid)) {
+                               xid++;
+                       }
                }
 
                if (DISPLAY_SWAP(a->opt_flags)) {
                        draw_activity_graphs(3, g_type2, title2, g_title2, NULL, group2,
-                                            spmin + 15, spmax + 15, out + 15, outsize + 15,
-                                            svg_p, record_hdr);
+                                            spmin + 16, spmax + 16, out + 16, outsize + 16,
+                                            svg_p, record_hdr, FALSE, a, xid);
                }
 
                /* Free remaining structures */
@@ -1757,7 +1942,7 @@ __print_funct_t svg_print_memory_stats(struct activity *a, int curr, int action,
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -1768,7 +1953,7 @@ __print_funct_t svg_print_ktables_stats(struct activity *a, int curr, int action
                *skc = (struct stats_ktables *) a->buf[curr];
        int group[] = {3, 1};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"Kernel tables (1)", "Kernel tables (2)"};
+       char *title[] = {"Kernel tables statistics (1)", "Kernel tables statistics (2)"};
        char *g_title[] = {"~dentunusd", "~file-nr", "~inode-nr",
                           "~pty-nr"};
        int g_fields[] = {1, 2, 0, 3};
@@ -1786,29 +1971,29 @@ __print_funct_t svg_print_ktables_stats(struct activity *a, int curr, int action
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 0, 4, (void *) a->buf[curr], NULL,
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
                             itv, spmin, spmax, g_fields);
                /* dentunusd */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) skc->dentry_stat,
+                         (unsigned long long) skc->dentry_stat,
                          out, outsize, svg_p->restart);
                /* file-nr */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) skc->file_used,
+                         (unsigned long long) skc->file_used,
                          out + 1, outsize + 1, svg_p->restart);
                /* inode-nr */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) skc->inode_used,
+                         (unsigned long long) skc->inode_used,
                          out + 2, outsize + 2, svg_p->restart);
                /* pty-nr */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) skc->pty_nr,
+                         (unsigned long long) skc->pty_nr,
                          out + 3, outsize + 3, svg_p->restart);
        }
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -1827,7 +2012,7 @@ __print_funct_t svg_print_ktables_stats(struct activity *a, int curr, int action
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -1838,11 +2023,11 @@ __print_funct_t svg_print_queue_stats(struct activity *a, int curr, int action,
                *sqc = (struct stats_queue *) a->buf[curr];
        int group[] = {2, 1, 3};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"Queue length", "Task list", "Load average"};
+       char *title[] = {"Queue length", "Task list statistics", "Load average statistics"};
        char *g_title[] = {"~runq-sz", "~blocked",
                           "~plist-sz",
                           "ldavg-1", "ldavg-5", "ldavg-15"};
-       int g_fields[] = {0, 1, 3, 4, 5, 2};
+       int g_fields[] = {0, 1, 2, 3, 4, 5};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
@@ -1857,19 +2042,19 @@ __print_funct_t svg_print_queue_stats(struct activity *a, int curr, int action,
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 2, 4, (void *) a->buf[curr], NULL,
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
                             itv, spmin, spmax, g_fields);
                /* runq-sz */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) sqc->nr_running,
+                         (unsigned long long) sqc->nr_running,
                          out, outsize, svg_p->restart);
                /* blocked */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) sqc->procs_blocked,
+                         (unsigned long long) sqc->procs_blocked,
                          out + 1, outsize + 1, svg_p->restart);
                /* plist-sz */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) sqc->nr_threads,
+                         (unsigned long long) sqc->nr_threads,
                          out + 2, outsize + 2, svg_p->restart);
                /* ldavg-1 */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
@@ -1892,7 +2077,7 @@ __print_funct_t svg_print_queue_stats(struct activity *a, int curr, int action,
                *(spmin + 5) /= 100; *(spmax + 5) /= 100;
 
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -1911,32 +2096,34 @@ __print_funct_t svg_print_queue_stats(struct activity *a, int curr, int action,
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
+#define DISK_ARRAY_SZ  9
 __print_funct_t svg_print_disk_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
                                     unsigned long long itv, struct record_header *record_hdr)
 {
-       struct stats_disk *sdc, *sdp;
+       struct stats_disk *sdc, *sdp, sdpzero;
        struct ext_disk_stats xds;
-       int group[] = {1, 2, 2, 2, 1};
+       int group[] = {1, 3, 2, 1, 1};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
                        SVG_LINE_GRAPH, SVG_BAR_GRAPH};
-       char *title[] = {"Disk statistics (1)", "Disk statistics (2)",
-                        "Disk statistics (3)", "Disk statistics (4)",
-                        "Disk statistics (5)"};
+       char *title[] = {"Block devices statistics (1)", "Block devices statistics (2)",
+                        "Block devices statistics (3)", "Block devices statistics (4)",
+                        "Block devices statistics (5)"};
        char *g_title[] = {"tps",
-                          "rd_sec/s", "wr_sec/s",
-                          "avgrq-sz", "avgqu-sz",
-                          "await", "svctm",
+                          "rkB/s", "wkB/s", "dkB/s",
+                          "areq-sz", "aqu-sz",
+                          "await",
                           "%util"};
        int g_fields[] = {0, 1, 2};
+       unsigned int local_types_nr[] = {1, 0, 0};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
-       char *item_name, *persist_dev_name;
-       double aqusz;
+       char *dev_name, *item_name;
+       double rkB, wkB, dkB, aqusz;
        int i, j, k, pos, restart, *unregistered;
 
        if (action & F_BEGIN) {
@@ -1944,57 +2131,69 @@ __print_funct_t svg_print_disk_stats(struct activity *a, int curr, int action, s
                 * Allocate arrays (#0..7) that will contain the graphs data
                 * and the min/max values.
                 * Also allocate one additional array (#8) for each disk device:
-                * spmax + 8 will contain the device major number,
-                * spmin + 8 will contain the device minor number,
+                * out + 8 will contain the device name (WWN id, pretty name or devm-n),
                 * outsize + 8 will contain a positive value (TRUE) if the device
                 * has either still not been registered, or has been unregistered.
                 */
-               out = allocate_graph_lines(9 * a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(DISK_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
-               restart = svg_p->restart;
+               memset(&sdpzero, 0, STATS_DISK_SIZE);
                /*
                 * Mark previously registered devices as now
                 * possibly unregistered for all graphs.
                 */
-               for (k = 0; k < a->nr; k++) {
-                       unregistered = outsize + k * 9 + 8;
+               for (k = 0; k < a->item_list_sz; k++) {
+                       unregistered = outsize + k * DISK_ARRAY_SZ + 8;
                        if (*unregistered == FALSE) {
                                *unregistered = MAYBE;
                        }
                }
 
                /* For each device structure */
-               for (i = 0; i < a->nr; i++) {
+               for (i = 0; i < a->nr[curr]; i++) {
                        sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
-                       if (!(sdc->major + sdc->minor))
-                               /* Empty structure: Ignore it */
-                               continue;
+                       restart = svg_p->restart;
+
+                       /* Get device name  */
+                       dev_name = get_device_name(sdc->major, sdc->minor, sdc->wwn, sdc->part_nr,
+                                                  DISPLAY_PRETTY(flags), DISPLAY_PERSIST_NAME_S(flags),
+                                                  USE_STABLE_ID(flags), NULL);
+
+                       if (a->item_list != NULL) {
+                               /* A list of devices has been entered on the command line */
+                               if (!search_list_item(a->item_list, dev_name))
+                                       /* Device not found */
+                                       continue;
+                       }
 
                        /* Look for corresponding graph */
-                       for (k = 0; k < a->nr; k++) {
-                               if ((sdc->major == *(spmax + k * 9 + 8)) &&
-                                   (sdc->minor == *(spmin + k * 9 + 8)))
+                       for (k = 0; k < a->item_list_sz; k++) {
+                               item_name = *(out + k * DISK_ARRAY_SZ + 8);
+                               if (!strcmp(dev_name, item_name))
                                        /* Graph found! */
                                        break;
                        }
-                       if (k == a->nr) {
+                       if (k == a->item_list_sz) {
                                /* Graph not found: Look for first free entry */
-                               for (k = 0; k < a->nr; k++) {
-                                       if (*(spmax + k * 9 + 8) == -DBL_MAX)
+                               for (k = 0; k < a->item_list_sz; k++) {
+                                       item_name = *(out + k * DISK_ARRAY_SZ + 8);
+                                       if (!strcmp(item_name, ""))
                                                break;
                                }
-                               if (k == a->nr)
-                                       /* No free graph entry: Graph for this item won't be drawn */
+                               if (k == a->item_list_sz) {
+                                       /* No free graph entry: Ignore it (should never happen) */
+#ifdef DEBUG
+                                       fprintf(stderr, "%s: Name=%s major=%d minor=%d\n",
+                                               __FUNCTION__, dev_name, sdc->major, sdc->minor);
+#endif
                                        continue;
+                               }
                        }
-                       pos = k * 9;
+                       pos = k * DISK_ARRAY_SZ;
                        unregistered = outsize + pos + 8;
 
-                       j = check_disk_reg(a, curr, !curr, i);
-                       sdp = (struct stats_disk *) ((char *) a->buf[!curr] + j * a->msize);
-
                        /*
                         * If current device was marked as previously unregistered,
                         * then set restart variable to TRUE so that the graph will be
@@ -2005,41 +2204,68 @@ __print_funct_t svg_print_disk_stats(struct activity *a, int curr, int action, s
                        }
                        *unregistered = FALSE;
 
-                       if (*(spmax + pos + 8) == -DBL_MAX) {
-                               /* Save device major and minor numbers (if not already done) */
-                               *(spmax + pos + 8) = sdc->major;
-                               *(spmin + pos + 8) = sdc->minor;
+                       item_name = *(out + pos + 8);
+                       if (!item_name[0]) {
+                               /* Save device name (WWN id or pretty name) if not already done */
+                               strncpy(item_name, dev_name, CHUNKSIZE);
+                               item_name[CHUNKSIZE - 1] = '\0';
+                       }
+
+                       j = check_disk_reg(a, curr, !curr, i);
+                       if (j < 0) {
+                               /* This is a newly registered interface. Previous stats are zero */
+                               sdp = &sdpzero;
+                               restart = TRUE;
+                       }
+                       else {
+                               sdp = (struct stats_disk *) ((char *) a->buf[!curr] + j * a->msize);
                        }
 
                        /* Check for min/max values */
-                       save_extrema(1, 2, 0, (void *) sdc, (void *) sdp,
+                       save_extrema(local_types_nr, (void *) sdc, (void *) sdp,
                                     itv, spmin + pos, spmax + pos, g_fields);
 
-                       compute_ext_disk_stats(sdc, sdp, itv, &xds);
-                       if (xds.arqsz < *(spmin + pos + 3)) {
-                               *(spmin + pos + 3) = xds.arqsz;
+                       rkB = S_VALUE(sdp->rd_sect, sdc->rd_sect, itv) / 2;
+                       wkB = S_VALUE(sdp->wr_sect, sdc->wr_sect, itv) / 2;
+                       dkB = S_VALUE(sdp->dc_sect, sdc->dc_sect, itv) / 2;
+                       if (rkB < *(spmin + pos + 1)) {
+                               *(spmin + pos + 1) = rkB;
                        }
-                       if (xds.arqsz > *(spmax + pos + 3)) {
-                               *(spmax + pos + 3) = xds.arqsz;
+                       if (rkB > *(spmax + pos + 1)) {
+                               *(spmax + pos + 1) = rkB;
                        }
-                       aqusz = S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0;
-                       if (aqusz < *(spmin + pos + 4)) {
-                               *(spmin + pos + 4) = aqusz;
+                       if (wkB < *(spmin + pos + 2)) {
+                               *(spmin + pos + 2) = wkB;
+                       }
+                       if (wkB > *(spmax + pos + 2)) {
+                               *(spmax + pos + 2) = wkB;
+                       }
+                       if (dkB < *(spmin + pos + 3)) {
+                               *(spmin + pos + 3) = dkB;
+                       }
+                       if (dkB > *(spmax + pos + 3)) {
+                               *(spmax + pos + 3) = dkB;
                        }
-                       if (aqusz > *(spmax + pos + 4)) {
-                               *(spmax + pos + 4) = aqusz;
+
+                       compute_ext_disk_stats(sdc, sdp, itv, &xds);
+                       if ((xds.arqsz / 2) < *(spmin + pos + 4)) {
+                               *(spmin + pos + 4) = xds.arqsz / 2;
                        }
-                       if (xds.await < *(spmin + pos + 5)) {
-                               *(spmin + pos + 5) = xds.await;
+                       if ((xds.arqsz / 2) > *(spmax + pos + 4)) {
+                               *(spmax + pos + 4) = xds.arqsz / 2;
+                       }
+                       aqusz = S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0;
+                       if (aqusz < *(spmin + pos + 5)) {
+                               *(spmin + pos + 5) = aqusz;
                        }
-                       if (xds.await > *(spmax + pos + 5)) {
-                               *(spmax + pos + 5) = xds.await;
+                       if (aqusz > *(spmax + pos + 5)) {
+                               *(spmax + pos + 5) = aqusz;
                        }
-                       if (xds.svctm < *(spmin + pos + 6)) {
-                               *(spmin + pos + 6) = xds.svctm;
+                       if (xds.await < *(spmin + pos + 6)) {
+                               *(spmin + pos + 6) = xds.await;
                        }
-                       if (xds.svctm > *(spmax + pos + 6)) {
-                               *(spmax + pos + 6) = xds.svctm;
+                       if (xds.await > *(spmax + pos + 6)) {
+                               *(spmax + pos + 6) = xds.await;
                        }
                        if ((xds.util / 10.0) < *(spmin + pos + 7)) {
                                *(spmin + pos + 7) = xds.util / 10.0;
@@ -2052,29 +2278,29 @@ __print_funct_t svg_print_disk_stats(struct activity *a, int curr, int action, s
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 S_VALUE(sdp->nr_ios, sdc->nr_ios, itv),
                                 out + pos, outsize + pos, restart);
-                       /* rd_sec/s */
+                       /* rkB/s */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                S_VALUE(sdp->rd_sect, sdc->rd_sect, itv),
+                                S_VALUE(sdp->rd_sect, sdc->rd_sect, itv) / 2,
                                 out + pos + 1, outsize + pos + 1, restart);
-                       /* wr_sec/s */
+                       /* wkB/s */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                S_VALUE(sdp->wr_sect, sdc->wr_sect, itv),
+                                S_VALUE(sdp->wr_sect, sdc->wr_sect, itv) / 2,
                                 out + pos + 2, outsize + pos + 2, restart);
-                       /* avgrq-sz */
+                       /* dkB/s */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                xds.arqsz,
+                                S_VALUE(sdp->dc_sect, sdc->dc_sect, itv) / 2,
                                 out + pos + 3, outsize + pos + 3, restart);
-                       /* avgqu-sz */
+                       /* areq-sz */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                aqusz,
+                                xds.arqsz / 2,
                                 out + pos + 4, outsize + pos + 4, restart);
-                       /* await */
+                       /* aqu-sz */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                xds.await,
+                                aqusz,
                                 out + pos + 5, outsize + pos + 5, restart);
-                       /* svctm */
+                       /* await */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                xds.svctm,
+                                xds.await,
                                 out + pos + 6, outsize + pos + 6, restart);
                        /* %util */
                        brappend(record_hdr->ust_time - svg_p->ust_time_ref,
@@ -2083,8 +2309,8 @@ __print_funct_t svg_print_disk_stats(struct activity *a, int curr, int action, s
                }
 
                /* Mark devices not seen here as now unregistered */
-               for (k = 0; k < a->nr; k++) {
-                       unregistered = outsize + k * 9 + 8;
+               for (k = 0; k < a->item_list_sz; k++) {
+                       unregistered = outsize + k * DISK_ARRAY_SZ + 8;
                        if (*unregistered != FALSE) {
                                *unregistered = TRUE;
                        }
@@ -2092,38 +2318,21 @@ __print_funct_t svg_print_disk_stats(struct activity *a, int curr, int action, s
        }
 
        if (action & F_END) {
-               for (i = 0; i < a->nr; i++) {
+               int xid = 0;
+
+               for (i = 0; i < a->item_list_sz; i++) {
                        /* Check if there is something to display */
-                       pos = i * 9;
+                       pos = i * DISK_ARRAY_SZ;
                        if (!**(out + pos))
                                continue;
 
-                       item_name = NULL;
-                       persist_dev_name = NULL;
-
-                       if (DISPLAY_PERSIST_NAME_S(flags)) {
-                               persist_dev_name = get_persistent_name_from_pretty(get_devname(*(spmax + pos + 8),
-                                                                                              *(spmin + pos + 8),
-                                                                                              TRUE));
-                       }
-                       if (persist_dev_name) {
-                               item_name = persist_dev_name;
-                       }
-                       else {
-                               if ((USE_PRETTY_OPTION(flags)) && (*(spmax + pos + 8) == dm_major)) {
-                                       item_name = transform_devmapname(*(spmax + pos + 8), *(spmin + pos + 8));
-                               }
-
-                               if (!item_name) {
-                                       item_name = get_devname(*(spmax + pos + 8), *(spmin + pos + 8),
-                                                               USE_PRETTY_OPTION(flags));
-                               }
+                       item_name = *(out + pos + 8);
+                       if (draw_activity_graphs(a->g_nr, g_type,
+                                                title, g_title, item_name, group,
+                                                spmin + pos, spmax + pos, out + pos, outsize + pos,
+                                                svg_p, record_hdr, FALSE, a, xid)) {
+                               xid++;
                        }
-
-                       draw_activity_graphs(a->g_nr, g_type,
-                                            title, g_title, item_name, group,
-                                            spmin + pos, spmax + pos, out + pos, outsize + pos,
-                                            svg_p, record_hdr);
                }
 
                /* Free remaining structures */
@@ -2143,24 +2352,26 @@ __print_funct_t svg_print_disk_stats(struct activity *a, int curr, int action, s
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
+#define NET_DEV_ARRAY_SZ       9
 __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
                                        unsigned long long itv, struct record_header *record_hdr)
 {
-       struct stats_net_dev *sndc, *sndp;
+       struct stats_net_dev *sndc, *sndp, sndzero;
        int group[] = {2, 2, 3, 1};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
                        SVG_BAR_GRAPH};
-       char *title[] = {"Network statistics (1)", "Network statistics (2)",
-                        "Network statistics (3)", "Network statistics (4)"};
+       char *title[] = {"Network interfaces statistics (1)", "Network interfaces statistics (2)",
+                        "Network interfaces statistics (3)", "Network interfaces statistics (4)"};
        char *g_title[] = {"rxpck/s", "txpck/s",
                           "rxkB/s", "txkB/s",
                           "rxcmp/s", "txcmp/s", "rxmcst/s",
                           "%ifutil"};
        int g_fields[] = {0, 1, 2, 3, 4, 5, 6};
+       unsigned int local_types_nr[] = {7, 0, 0};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
@@ -2177,53 +2388,69 @@ __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action
                 * outsize + 8 will contain a positive value (TRUE) if the interface
                 * has either still not been registered, or has been unregistered.
                 */
-               out = allocate_graph_lines(9 * a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(NET_DEV_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
-               restart = svg_p->restart;
+               memset(&sndzero, 0, STATS_NET_DEV_SIZE);
                /*
                 * Mark previously registered interfaces as now
                 * possibly unregistered for all graphs.
                 */
-               for (k = 0; k < a->nr; k++) {
-                       unregistered = outsize + k * 9 + 8;
+               for (k = 0; k < a->item_list_sz; k++) {
+                       unregistered = outsize + k * NET_DEV_ARRAY_SZ + 8;
                        if (*unregistered == FALSE) {
                                *unregistered = MAYBE;
                        }
                }
 
                /* For each network interfaces structure */
-               for (i = 0; i < a->nr; i++) {
+               for (i = 0; i < a->nr[curr]; i++) {
                        sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize);
-                       if (!strcmp(sndc->interface, ""))
-                               /* Empty structure: Ignore it */
-                               continue;
+                       restart = svg_p->restart;
+
+                       if (a->item_list != NULL) {
+                               /* A list of devices has been entered on the command line */
+                               if (!search_list_item(a->item_list, sndc->interface))
+                                       /* Device not found */
+                                       continue;
+                       }
 
                        /* Look for corresponding graph */
-                       for (k = 0; k < a->nr; k++) {
-                               item_name = *(out + k * 9 + 8);
+                       for (k = 0; k < a->item_list_sz; k++) {
+                               item_name = *(out + k * NET_DEV_ARRAY_SZ + 8);
                                if (!strcmp(sndc->interface, item_name))
                                        /* Graph found! */
                                        break;
                        }
-                       if (k == a->nr) {
+                       if (k == a->item_list_sz) {
                                /* Graph not found: Look for first free entry */
-                               for (k = 0; k < a->nr; k++) {
-                                       item_name = *(out + k * 9 + 8);
+                               for (k = 0; k < a->item_list_sz; k++) {
+                                       item_name = *(out + k * NET_DEV_ARRAY_SZ + 8);
                                        if (!strcmp(item_name, ""))
                                                break;
                                }
-                               if (k == a->nr)
-                                       /* No free graph entry: Graph for this item won't be drawn */
+                               if (k == a->item_list_sz) {
+                                       /* No free graph entry: Ignore it (should never happen) */
+#ifdef DEBUG
+                                       fprintf(stderr, "%s: Name=%s\n",
+                                               __FUNCTION__, sndc->interface);
+#endif
                                        continue;
+                               }
                        }
-
-                       pos = k * 9;
+                       pos = k * NET_DEV_ARRAY_SZ;
                        unregistered = outsize + pos + 8;
 
                        j = check_net_dev_reg(a, curr, !curr, i);
-                       sndp = (struct stats_net_dev *) ((char *) a->buf[!curr] + j * a->msize);
+                       if (j < 0) {
+                               /* This is a newly registered interface. Previous stats are zero */
+                               sndp = &sndzero;
+                               restart = TRUE;
+                       }
+                       else {
+                               sndp = (struct stats_net_dev *) ((char *) a->buf[!curr] + j * a->msize);
+                       }
 
                        /*
                         * If current interface was marked as previously unregistered,
@@ -2235,6 +2462,7 @@ __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action
                        }
                        *unregistered = FALSE;
 
+                       item_name = *(out + pos + 8);
                        if (!item_name[0]) {
                                /* Save network interface name (if not already done) */
                                strncpy(item_name, sndc->interface, CHUNKSIZE);
@@ -2242,7 +2470,7 @@ __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action
                        }
 
                        /* Check for min/max values */
-                       save_extrema(7, 0, 0, (void *) sndc, (void *) sndp,
+                       save_extrema(local_types_nr, (void *) sndc, (void *) sndp,
                                     itv, spmin + pos, spmax + pos, g_fields);
 
                        rxkb = S_VALUE(sndp->rx_bytes, sndc->rx_bytes, itv);
@@ -2290,8 +2518,8 @@ __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action
                }
 
                /* Mark interfaces not seen here as now unregistered */
-               for (k = 0; k < a->nr; k++) {
-                       unregistered = outsize + k * 9 + 8;
+               for (k = 0; k < a->item_list_sz; k++) {
+                       unregistered = outsize + k * NET_DEV_ARRAY_SZ + 8;
                        if (*unregistered != FALSE) {
                                *unregistered = TRUE;
                        }
@@ -2299,13 +2527,15 @@ __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action
        }
 
        if (action & F_END) {
-               for (i = 0; i < a->nr; i++) {
+               int xid = 0;
+
+               for (i = 0; i < a->item_list_sz; i++) {
                        /*
                         * Check if there is something to display.
                         * Don't test sndc->interface because maybe the network
                         * interface has been registered later.
                         */
-                       pos = i * 9;
+                       pos = i * NET_DEV_ARRAY_SZ;
                        if (!**(out + pos))
                                continue;
 
@@ -2316,10 +2546,12 @@ __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action
                        *(spmax + pos + 3) /= 1024;
 
                        item_name = *(out + pos + 8);
-                       draw_activity_graphs(a->g_nr, g_type,
-                                            title, g_title, item_name, group,
-                                            spmin + pos, spmax + pos, out + pos, outsize + pos,
-                                            svg_p, record_hdr);
+                       if (draw_activity_graphs(a->g_nr, g_type,
+                                                title, g_title, item_name, group,
+                                                spmin + pos, spmax + pos, out + pos, outsize + pos,
+                                                svg_p, record_hdr, FALSE, a, xid)) {
+                               xid++;
+                       }
                }
 
                /* Free remaining structures */
@@ -2329,7 +2561,7 @@ __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action
 
 /*
  ***************************************************************************
- * Display network interface errors statistics in SVG.
+ * Display network interfaces errors statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -2339,19 +2571,20 @@ __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
+#define NET_EDEV_ARRAY_SZ      10
 __print_funct_t svg_print_net_edev_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
                                         unsigned long long itv, struct record_header *record_hdr)
 {
-       struct stats_net_edev *snedc, *snedp;
+       struct stats_net_edev *snedc, *snedp, snedzero;
        int group[] = {2, 2, 2, 3};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
                        SVG_LINE_GRAPH};
-       char *title[] = {"Network errors statistics (1)", "Network errors statistics (2)",
-                        "Network errors statistics (3)", "Network errors statistics (4)"};
+       char *title[] = {"Network interfaces errors statistics (1)", "Network interfaces errors statistics (2)",
+                        "Network interfaces errors statistics (3)", "Network interfaces errors statistics (4)"};
        char *g_title[] = {"rxerr/s", "txerr/s",
                            "rxdrop/s", "txdrop/s",
                            "rxfifo/s", "txfifo/s",
@@ -2372,53 +2605,70 @@ __print_funct_t svg_print_net_edev_stats(struct activity *a, int curr, int actio
                 * outsize + 9 will contain a positive value (TRUE) if the interface
                 * has either still not been registered, or has been unregistered.
                 */
-               out = allocate_graph_lines(10 * a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(NET_EDEV_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
-               restart = svg_p->restart;
+               memset(&snedzero, 0, STATS_NET_EDEV_SIZE);
                /*
                 * Mark previously registered interfaces as now
                 * possibly unregistered for all graphs.
                 */
-               for (k = 0; k < a->nr; k++) {
-                       unregistered = outsize + k * 10 + 9;
+               for (k = 0; k < a->item_list_sz; k++) {
+                       unregistered = outsize + k * NET_EDEV_ARRAY_SZ + 9;
                        if (*unregistered == FALSE) {
                                *unregistered = MAYBE;
                        }
                }
 
                /* For each network interfaces structure */
-               for (i = 0; i < a->nr; i++) {
+               for (i = 0; i < a->nr[curr]; i++) {
                        snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize);
-                       if (!strcmp(snedc->interface, ""))
-                               /* Empty structure: Ignore it */
-                               continue;
+                       restart = svg_p->restart;
+
+                       if (a->item_list != NULL) {
+                               /* A list of devices has been entered on the command line */
+                               if (!search_list_item(a->item_list, snedc->interface))
+                                       /* Device not found */
+                                       continue;
+                       }
 
                        /* Look for corresponding graph */
-                       for (k = 0; k < a->nr; k++) {
-                               item_name = *(out + k * 10 + 9);
+                       for (k = 0; k < a->item_list_sz; k++) {
+                               item_name = *(out + k * NET_EDEV_ARRAY_SZ + 9);
                                if (!strcmp(snedc->interface, item_name))
                                        /* Graph found! */
                                        break;
                        }
-                       if (k == a->nr) {
+                       if (k == a->item_list_sz) {
                                /* Graph not found: Look for first free entry */
-                               for (k = 0; k < a->nr; k++) {
-                                       item_name = *(out + k * 10 + 9);
+                               for (k = 0; k < a->item_list_sz; k++) {
+                                       item_name = *(out + k * NET_EDEV_ARRAY_SZ + 9);
                                        if (!strcmp(item_name, ""))
                                                break;
                                }
-                               if (k == a->nr)
-                                       /* No free graph entry: Graph for this item won't be drawn */
+                               if (k == a->item_list_sz) {
+                                       /* No free graph entry: Ignore it (should never happen) */
+#ifdef DEBUG
+                                       fprintf(stderr, "%s: Name=%s\n",
+                                               __FUNCTION__, snedc->interface);
+#endif
                                        continue;
+                               }
                        }
 
-                       pos = k * 10;
+                       pos = k * NET_EDEV_ARRAY_SZ;
                        unregistered = outsize + pos + 9;
 
                        j = check_net_edev_reg(a, curr, !curr, i);
-                       snedp = (struct stats_net_edev *) ((char *) a->buf[!curr] + j * a->msize);
+                       if (j < 0) {
+                               /* This is a newly registered interface. Previous stats are zero */
+                               snedp = &snedzero;
+                               restart = TRUE;
+                       }
+                       else {
+                               snedp = (struct stats_net_edev *) ((char *) a->buf[!curr] + j * a->msize);
+                       }
 
                        /*
                         * If current interface was marked as previously unregistered,
@@ -2430,6 +2680,7 @@ __print_funct_t svg_print_net_edev_stats(struct activity *a, int curr, int actio
                        }
                        *unregistered = FALSE;
 
+                       item_name = *(out + pos + 9);
                        if (!item_name[0]) {
                                /* Save network interface name (if not already done) */
                                strncpy(item_name, snedc->interface, CHUNKSIZE);
@@ -2437,7 +2688,7 @@ __print_funct_t svg_print_net_edev_stats(struct activity *a, int curr, int actio
                        }
 
                        /* Check for min/max values */
-                       save_extrema(9, 0, 0, (void *) snedc, (void *) snedp,
+                       save_extrema(a->gtypes_nr, (void *) snedc, (void *) snedp,
                                     itv, spmin + pos, spmax + pos, g_fields);
 
                        /* rxerr/s */
@@ -2479,8 +2730,8 @@ __print_funct_t svg_print_net_edev_stats(struct activity *a, int curr, int actio
                }
 
                /* Mark interfaces not seen here as now unregistered */
-               for (k = 0; k < a->nr; k++) {
-                       unregistered = outsize + k * 10 + 9;
+               for (k = 0; k < a->item_list_sz; k++) {
+                       unregistered = outsize + k * NET_EDEV_ARRAY_SZ + 9;
                        if (*unregistered != FALSE) {
                                *unregistered = TRUE;
                        }
@@ -2488,21 +2739,25 @@ __print_funct_t svg_print_net_edev_stats(struct activity *a, int curr, int actio
        }
 
        if (action & F_END) {
-               for (i = 0; i < a->nr; i++) {
+               int xid = 0;
+
+               for (i = 0; i < a->item_list_sz; i++) {
                        /*
                         * Check if there is something to display.
                         * Don't test snedc->interface because maybe the network
                         * interface has been registered later.
                         */
-                       pos = i * 10;
+                       pos = i * NET_EDEV_ARRAY_SZ;
                        if (!**(out + pos))
                                continue;
 
                        item_name = *(out + pos + 9);
-                       draw_activity_graphs(a->g_nr, g_type,
-                                            title, g_title, item_name, group,
-                                            spmin + pos, spmax + pos, out + pos, outsize + pos,
-                                            svg_p, record_hdr);
+                       if (draw_activity_graphs(a->g_nr, g_type,
+                                                title, g_title, item_name, group,
+                                                spmin + pos, spmax + pos, out + pos, outsize + pos,
+                                                svg_p, record_hdr, FALSE, a, xid)) {
+                               xid++;
+                       }
                }
 
                /* Free remaining structures */
@@ -2522,7 +2777,7 @@ __print_funct_t svg_print_net_edev_stats(struct activity *a, int curr, int actio
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -2554,7 +2809,7 @@ __print_funct_t svg_print_net_nfs_stats(struct activity *a, int curr, int action
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 0, 6, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* call/s */
@@ -2585,7 +2840,7 @@ __print_funct_t svg_print_net_nfs_stats(struct activity *a, int curr, int action
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -2604,7 +2859,7 @@ __print_funct_t svg_print_net_nfs_stats(struct activity *a, int curr, int action
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -2640,7 +2895,7 @@ __print_funct_t svg_print_net_nfsd_stats(struct activity *a, int curr, int actio
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 0, 11, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* scall/s */
@@ -2691,7 +2946,7 @@ __print_funct_t svg_print_net_nfsd_stats(struct activity *a, int curr, int actio
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -2700,7 +2955,7 @@ __print_funct_t svg_print_net_nfsd_stats(struct activity *a, int curr, int actio
 
 /*
  ***************************************************************************
- * Display network socket statistics in SVG.
+ * Display socket statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -2710,7 +2965,7 @@ __print_funct_t svg_print_net_nfsd_stats(struct activity *a, int curr, int actio
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -2721,7 +2976,7 @@ __print_funct_t svg_print_net_sock_stats(struct activity *a, int curr, int actio
                *snsc = (struct stats_net_sock *) a->buf[curr];
        int group[] = {1, 5};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"IPv4 network sockets (1)", "IPv4 network sockets (2)"};
+       char *title[] = {"IPv4 sockets statistics (1)", "IPv4 sockets statistics (2)"};
        char *g_title[] = {"~totsck",
                           "~tcpsck", "~udpsck", "~rawsck", "~ip-frag", "~tcp-tw"};
        int g_fields[] = {0, 1, 5, 2, 3, 4};
@@ -2739,37 +2994,37 @@ __print_funct_t svg_print_net_sock_stats(struct activity *a, int curr, int actio
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 0, 6, (void *) a->buf[curr], NULL,
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
                             itv, spmin, spmax, g_fields);
                /* totsck */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->sock_inuse,
+                         (unsigned long long) snsc->sock_inuse,
                          out, outsize, svg_p->restart);
                /* tcpsck */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->tcp_inuse,
+                         (unsigned long long) snsc->tcp_inuse,
                          out + 1, outsize + 1, svg_p->restart);
                /* udpsck */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->udp_inuse,
+                         (unsigned long long) snsc->udp_inuse,
                          out + 2, outsize + 2, svg_p->restart);
                /* rawsck */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->raw_inuse,
+                         (unsigned long long) snsc->raw_inuse,
                          out + 3, outsize + 3, svg_p->restart);
                /* ip-frag */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->frag_inuse,
+                         (unsigned long long) snsc->frag_inuse,
                          out + 4, outsize + 4, svg_p->restart);
                /* tcp-tw */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->tcp_tw,
+                         (unsigned long long) snsc->tcp_tw,
                          out + 5, outsize + 5, svg_p->restart);
        }
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -2778,7 +3033,7 @@ __print_funct_t svg_print_net_sock_stats(struct activity *a, int curr, int actio
 
 /*
  ***************************************************************************
- * Display IPv4 network statistics in SVG.
+ * Display IPv4 traffic statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -2788,7 +3043,7 @@ __print_funct_t svg_print_net_sock_stats(struct activity *a, int curr, int actio
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -2800,7 +3055,7 @@ __print_funct_t svg_print_net_ip_stats(struct activity *a, int curr, int action,
                *snip = (struct stats_net_ip *) a->buf[!curr];
        int group[] = {4, 2, 2};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"IPv4 network statistics (1)", "IPv4 network statistics (2)", "IPv4 network statistics (3)"};
+       char *title[] = {"IPv4 traffic statistics (1)", "IPv4 traffic statistics (2)", "IPv4 traffic statistics (3)"};
        char *g_title[] = {"irec/s", "fwddgm/s", "idel/s", "orq/s",
                           "asmrq/s", "asmok/s",
                           "fragok/s", "fragcrt/s"};
@@ -2819,7 +3074,7 @@ __print_funct_t svg_print_net_ip_stats(struct activity *a, int curr, int action,
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(8, 0, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* irec/s */
@@ -2858,7 +3113,7 @@ __print_funct_t svg_print_net_ip_stats(struct activity *a, int curr, int action,
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -2867,7 +3122,7 @@ __print_funct_t svg_print_net_ip_stats(struct activity *a, int curr, int action,
 
 /*
  ***************************************************************************
- * Display IPv4 network errors statistics in SVG.
+ * Display IPv4 traffic errors statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -2877,7 +3132,7 @@ __print_funct_t svg_print_net_ip_stats(struct activity *a, int curr, int action,
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -2889,8 +3144,8 @@ __print_funct_t svg_print_net_eip_stats(struct activity *a, int curr, int action
                *sneip = (struct stats_net_eip *) a->buf[!curr];
        int group[] = {3, 2, 3};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"IPv4 network errors statistics (1)", "IPv4 network errors statistics (2)",
-                        "IPv4 network errors statistics (3)"};
+       char *title[] = {"IPv4 traffic errors statistics (1)", "IPv4 traffic errors statistics (2)",
+                        "IPv4 traffic errors statistics (3)"};
        char *g_title[] = {"ihdrerr/s", "iadrerr/s", "iukwnpr/s",
                           "idisc/s", "odisc/s",
                           "onort/s", "asmf/s", "fragf/s"};
@@ -2909,7 +3164,7 @@ __print_funct_t svg_print_net_eip_stats(struct activity *a, int curr, int action
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(8, 0, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* ihdrerr/s */
@@ -2948,7 +3203,7 @@ __print_funct_t svg_print_net_eip_stats(struct activity *a, int curr, int action
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -2957,7 +3212,7 @@ __print_funct_t svg_print_net_eip_stats(struct activity *a, int curr, int action
 
 /*
  ***************************************************************************
- * Display ICMPv4 network statistics in SVG.
+ * Display ICMPv4 traffic statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -2967,7 +3222,7 @@ __print_funct_t svg_print_net_eip_stats(struct activity *a, int curr, int action
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -2980,8 +3235,8 @@ __print_funct_t svg_print_net_icmp_stats(struct activity *a, int curr, int actio
        int group[] = {2, 4, 4, 4};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
                        SVG_LINE_GRAPH};
-       char *title[] = {"ICMPv4 network statistics (1)", "ICMPv4 network statistics (2)",
-                        "ICMPv4 network statistics (3)", "ICMPv4 network statistics (4)"};
+       char *title[] = {"ICMPv4 traffic statistics (1)", "ICMPv4 traffic statistics (2)",
+                        "ICMPv4 traffic statistics (3)", "ICMPv4 traffic statistics (4)"};
        char *g_title[] = {"imsg/s", "omsg/s",
                           "iech/s", "iechr/s", "oech/s", "oechr/s",
                           "itm/s", "itmr/s", "otm/s", "otmr/s",
@@ -3001,7 +3256,7 @@ __print_funct_t svg_print_net_icmp_stats(struct activity *a, int curr, int actio
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 14, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* imsg/s */
@@ -3064,7 +3319,7 @@ __print_funct_t svg_print_net_icmp_stats(struct activity *a, int curr, int actio
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3073,7 +3328,7 @@ __print_funct_t svg_print_net_icmp_stats(struct activity *a, int curr, int actio
 
 /*
  ***************************************************************************
- * Display ICMPv4 network errors statistics in SVG.
+ * Display ICMPv4 traffic errors statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3083,7 +3338,7 @@ __print_funct_t svg_print_net_icmp_stats(struct activity *a, int curr, int actio
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3096,9 +3351,9 @@ __print_funct_t svg_print_net_eicmp_stats(struct activity *a, int curr, int acti
        int group[] = {2, 2, 2, 2, 2, 2};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
                        SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"ICMPv4 network errors statistics (1)", "ICMPv4 network errors statistics (2)",
-                        "ICMPv4 network errors statistics (3)", "ICMPv4 network errors statistics (4)",
-                        "ICMPv4 network errors statistics (5)", "ICMPv4 network errors statistics (6)"};
+       char *title[] = {"ICMPv4 traffic errors statistics (1)", "ICMPv4 traffic errors statistics (2)",
+                        "ICMPv4 traffic errors statistics (3)", "ICMPv4 traffic errors statistics (4)",
+                        "ICMPv4 traffic errors statistics (5)", "ICMPv4 traffic errors statistics (6)"};
        char *g_title[] = {"ierr/s", "oerr/s",
                           "idstunr/s", "odstunr/s",
                           "itmex/s", "otmex/s",
@@ -3120,7 +3375,7 @@ __print_funct_t svg_print_net_eicmp_stats(struct activity *a, int curr, int acti
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 12, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* ierr/s */
@@ -3175,7 +3430,7 @@ __print_funct_t svg_print_net_eicmp_stats(struct activity *a, int curr, int acti
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3184,7 +3439,7 @@ __print_funct_t svg_print_net_eicmp_stats(struct activity *a, int curr, int acti
 
 /*
  ***************************************************************************
- * Display TCPv4 network statistics in SVG.
+ * Display TCPv4 traffic statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3194,7 +3449,7 @@ __print_funct_t svg_print_net_eicmp_stats(struct activity *a, int curr, int acti
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3206,7 +3461,7 @@ __print_funct_t svg_print_net_tcp_stats(struct activity *a, int curr, int action
                *sntp = (struct stats_net_tcp *) a->buf[!curr];
        int group[] = {2, 2};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"TCPv4 network statistics (1)", "TCPv4 network statistics (2)"};
+       char *title[] = {"TCPv4 traffic statistics (1)", "TCPv4 traffic statistics (2)"};
        char *g_title[] = {"active/s", "passive/s",
                           "iseg/s", "oseg/s"};
        int g_fields[] = {0, 1, 2, 3};
@@ -3224,7 +3479,7 @@ __print_funct_t svg_print_net_tcp_stats(struct activity *a, int curr, int action
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 4, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* active/s */
@@ -3247,7 +3502,7 @@ __print_funct_t svg_print_net_tcp_stats(struct activity *a, int curr, int action
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3256,7 +3511,7 @@ __print_funct_t svg_print_net_tcp_stats(struct activity *a, int curr, int action
 
 /*
  ***************************************************************************
- * Display TCPv4 network errors statistics in SVG.
+ * Display TCPv4 traffic errors statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3266,7 +3521,7 @@ __print_funct_t svg_print_net_tcp_stats(struct activity *a, int curr, int action
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3278,7 +3533,7 @@ __print_funct_t svg_print_net_etcp_stats(struct activity *a, int curr, int actio
                *snetp = (struct stats_net_etcp *) a->buf[!curr];
        int group[] = {2, 3};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"TCPv4 network errors statistics (1)", "TCPv4 network errors statistics (2)"};
+       char *title[] = {"TCPv4 traffic errors statistics (1)", "TCPv4 traffic errors statistics (2)"};
        char *g_title[] = {"atmptf/s", "estres/s",
                           "retrans/s", "isegerr/s", "orsts/s"};
        int g_fields[] = {0, 1, 2, 3, 4};
@@ -3296,7 +3551,7 @@ __print_funct_t svg_print_net_etcp_stats(struct activity *a, int curr, int actio
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 5, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* atmptf/s */
@@ -3323,7 +3578,7 @@ __print_funct_t svg_print_net_etcp_stats(struct activity *a, int curr, int actio
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3332,7 +3587,7 @@ __print_funct_t svg_print_net_etcp_stats(struct activity *a, int curr, int actio
 
 /*
  ***************************************************************************
- * Display UDPv4 network statistics in SVG.
+ * Display UDPv4 traffic statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3342,7 +3597,7 @@ __print_funct_t svg_print_net_etcp_stats(struct activity *a, int curr, int actio
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3354,7 +3609,7 @@ __print_funct_t svg_print_net_udp_stats(struct activity *a, int curr, int action
                *snup = (struct stats_net_udp *) a->buf[!curr];
        int group[] = {2, 2};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"UDPv4 network statistics (1)", "UDPv4 network statistics (2)"};
+       char *title[] = {"UDPv4 traffic statistics (1)", "UDPv4 traffic statistics (2)"};
        char *g_title[] = {"idgm/s", "odgm/s",
                           "noport/s", "idgmerr/s"};
        int g_fields[] = {0, 1, 2, 3};
@@ -3372,7 +3627,7 @@ __print_funct_t svg_print_net_udp_stats(struct activity *a, int curr, int action
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 4, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* idgm/s */
@@ -3395,7 +3650,7 @@ __print_funct_t svg_print_net_udp_stats(struct activity *a, int curr, int action
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3404,7 +3659,7 @@ __print_funct_t svg_print_net_udp_stats(struct activity *a, int curr, int action
 
 /*
  ***************************************************************************
- * Display IPV6 network socket statistics in SVG.
+ * Display IPV6 socket statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3414,7 +3669,7 @@ __print_funct_t svg_print_net_udp_stats(struct activity *a, int curr, int action
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3425,7 +3680,7 @@ __print_funct_t svg_print_net_sock6_stats(struct activity *a, int curr, int acti
                *snsc = (struct stats_net_sock6 *) a->buf[curr];
        int group[] = {4};
        int g_type[] = {SVG_LINE_GRAPH};
-       char *title[] = {"IPv6 network sockets"};
+       char *title[] = {"IPv6 sockets statistics"};
        char *g_title[] = {"~tcp6sck", "~udp6sck", "~raw6sck", "~ip6-frag"};
        int g_fields[] = {0, 1, 2, 3};
        static double *spmin, *spmax;
@@ -3442,29 +3697,29 @@ __print_funct_t svg_print_net_sock6_stats(struct activity *a, int curr, int acti
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 0, 4, (void *) a->buf[curr], NULL,
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
                             itv, spmin, spmax, g_fields);
                /* tcp6sck */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->tcp6_inuse,
+                         (unsigned long long) snsc->tcp6_inuse,
                          out, outsize, svg_p->restart);
                /* udp6sck */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->udp6_inuse,
+                         (unsigned long long) snsc->udp6_inuse,
                          out + 1, outsize + 1, svg_p->restart);
                /* raw6sck */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->raw6_inuse,
+                         (unsigned long long) snsc->raw6_inuse,
                          out + 2, outsize + 2, svg_p->restart);
                /* ip6-frag */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) snsc->frag6_inuse,
+                         (unsigned long long) snsc->frag6_inuse,
                          out + 3, outsize + 3, svg_p->restart);
        }
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3473,7 +3728,7 @@ __print_funct_t svg_print_net_sock6_stats(struct activity *a, int curr, int acti
 
 /*
  ***************************************************************************
- * Display IPv6 network statistics in SVG.
+ * Display IPv6 traffic statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3483,7 +3738,7 @@ __print_funct_t svg_print_net_sock6_stats(struct activity *a, int curr, int acti
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3496,8 +3751,8 @@ __print_funct_t svg_print_net_ip6_stats(struct activity *a, int curr, int action
        int group[] = {4, 2, 2, 2};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
                        SVG_LINE_GRAPH};
-       char *title[] = {"IPv6 network statistics (1)", "IPv6 network statistics (2)",
-                        "IPv6 network statistics (3)", "IPv6 network statistics (4)"};
+       char *title[] = {"IPv6 traffic statistics (1)", "IPv6 traffic statistics (2)",
+                        "IPv6 traffic statistics (3)", "IPv6 traffic statistics (4)"};
        char *g_title[] = {"irec6/s", "fwddgm6/s", "idel6/s", "orq6/s",
                           "asmrq6/s", "asmok6/s",
                           "imcpck6/s", "omcpck6/s",
@@ -3517,7 +3772,7 @@ __print_funct_t svg_print_net_ip6_stats(struct activity *a, int curr, int action
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(10, 0, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* irec6/s */
@@ -3564,7 +3819,7 @@ __print_funct_t svg_print_net_ip6_stats(struct activity *a, int curr, int action
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3573,7 +3828,7 @@ __print_funct_t svg_print_net_ip6_stats(struct activity *a, int curr, int action
 
 /*
  ***************************************************************************
- * Display IPv6 network errors statistics in SVG.
+ * Display IPv6 traffic errors statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3583,7 +3838,7 @@ __print_funct_t svg_print_net_ip6_stats(struct activity *a, int curr, int action
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3596,9 +3851,9 @@ __print_funct_t svg_print_net_eip6_stats(struct activity *a, int curr, int actio
        int group[] = {4, 2, 2, 3};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
                        SVG_LINE_GRAPH};
-       char *title[] = {"IPv6 network errors statistics (1)", "IPv6 network errors statistics (2)",
-                        "IPv6 network errors statistics (3)", "IPv6 network errors statistics (4)",
-                        "IPv6 network errors statistics (5)"};
+       char *title[] = {"IPv6 traffic errors statistics (1)", "IPv6 traffic errors statistics (2)",
+                        "IPv6 traffic errors statistics (3)", "IPv6 traffic errors statistics (4)",
+                        "IPv6 traffic errors statistics (5)"};
        char *g_title[] = {"ihdrer6/s", "iadrer6/s", "iukwnp6/s", "i2big6/s",
                           "idisc6/s", "odisc6/s",
                           "inort6/s", "onort6/s",
@@ -3618,7 +3873,7 @@ __print_funct_t svg_print_net_eip6_stats(struct activity *a, int curr, int actio
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(11, 0, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* ihdrer6/s */
@@ -3669,7 +3924,7 @@ __print_funct_t svg_print_net_eip6_stats(struct activity *a, int curr, int actio
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3678,7 +3933,7 @@ __print_funct_t svg_print_net_eip6_stats(struct activity *a, int curr, int actio
 
 /*
  ***************************************************************************
- * Display ICMPv6 network statistics in SVG.
+ * Display ICMPv6 traffic statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3688,7 +3943,7 @@ __print_funct_t svg_print_net_eip6_stats(struct activity *a, int curr, int actio
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3701,9 +3956,9 @@ __print_funct_t svg_print_net_icmp6_stats(struct activity *a, int curr, int acti
        int group[] = {2, 3, 5, 3, 4};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
                        SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"ICMPv6 network statistics (1)", "ICMPv6 network statistics (2)",
-                        "ICMPv6 network statistics (3)", "ICMPv6 network statistics (4)",
-                        "ICMPv6 network statistics (5)"};
+       char *title[] = {"ICMPv6 traffic statistics (1)", "ICMPv6 traffic statistics (2)",
+                        "ICMPv6 traffic statistics (3)", "ICMPv6 traffic statistics (4)",
+                        "ICMPv6 traffic statistics (5)"};
        char *g_title[] = {"imsg6/s", "omsg6/s",
                           "iech6/s", "iechr6/s", "oechr6/s",
                           "igmbq6/s", "igmbr6/s", "ogmbr6/s", "igmbrd6/s", "ogmbrd6/s",
@@ -3724,7 +3979,7 @@ __print_funct_t svg_print_net_icmp6_stats(struct activity *a, int curr, int acti
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 17, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* imsg6/s */
@@ -3781,7 +4036,7 @@ __print_funct_t svg_print_net_icmp6_stats(struct activity *a, int curr, int acti
                         out + 12, outsize + 12, svg_p->restart);
                /* inbsol6/s */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                        S_VALUE(snip->InNeighborSolicits6,snic->InNeighborSolicits6, itv),
+                        S_VALUE(snip->InNeighborSolicits6, snic->InNeighborSolicits6, itv),
                         out + 13, outsize + 13, svg_p->restart);
                /* onbsol6/s */
                lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
@@ -3799,7 +4054,7 @@ __print_funct_t svg_print_net_icmp6_stats(struct activity *a, int curr, int acti
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3808,7 +4063,7 @@ __print_funct_t svg_print_net_icmp6_stats(struct activity *a, int curr, int acti
 
 /*
  ***************************************************************************
- * Display ICMPv6 network errors statistics in SVG.
+ * Display ICMPv6 traffic errors statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3818,7 +4073,7 @@ __print_funct_t svg_print_net_icmp6_stats(struct activity *a, int curr, int acti
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3831,9 +4086,9 @@ __print_funct_t svg_print_net_eicmp6_stats(struct activity *a, int curr, int act
        int group[] = {1, 2, 2, 2, 2, 2};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
                        SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"ICMPv6 network errors statistics (1)", "ICMPv6 network errors statistics (2)",
-                        "ICMPv6 network errors statistics (3)", "ICMPv6 network errors statistics (4)",
-                        "ICMPv6 network errors statistics (5)", "ICMPv6 network errors statistics (6)"};
+       char *title[] = {"ICMPv6 traffic errors statistics (1)", "ICMPv6 traffic errors statistics (2)",
+                        "ICMPv6 traffic errors statistics (3)", "ICMPv6 traffic errors statistics (4)",
+                        "ICMPv6 traffic errors statistics (5)", "ICMPv6 traffic errors statistics (6)"};
        char *g_title[] = {"ierr6/s",
                           "idtunr6/s", "odtunr6/s",
                           "itmex6/s", "otmex6/s",
@@ -3855,7 +4110,7 @@ __print_funct_t svg_print_net_eicmp6_stats(struct activity *a, int curr, int act
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 11, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* ierr6/s */
@@ -3906,7 +4161,7 @@ __print_funct_t svg_print_net_eicmp6_stats(struct activity *a, int curr, int act
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3915,7 +4170,7 @@ __print_funct_t svg_print_net_eicmp6_stats(struct activity *a, int curr, int act
 
 /*
  ***************************************************************************
- * Display UDPv6 network statistics in SVG.
+ * Display UDPv6 traffic statistics in SVG.
  *
  * IN:
  * @a          Activity structure with statistics.
@@ -3925,7 +4180,7 @@ __print_funct_t svg_print_net_eicmp6_stats(struct activity *a, int curr, int act
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -3937,7 +4192,7 @@ __print_funct_t svg_print_net_udp6_stats(struct activity *a, int curr, int actio
                *snup = (struct stats_net_udp6 *) a->buf[!curr];
        int group[] = {2, 2};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
-       char *title[] = {"UDPv6 network statistics (1)", "UDPv6 network statistics (2)"};
+       char *title[] = {"UDPv6 traffic statistics (1)", "UDPv6 traffic statistics (2)"};
        char *g_title[] = {"idgm6/s", "odgm6/s",
                           "noport6/s", "idgmer6/s"};
        int g_fields[] = {0, 1, 2, 3};
@@ -3955,7 +4210,7 @@ __print_funct_t svg_print_net_udp6_stats(struct activity *a, int curr, int actio
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 4, 0, (void *) a->buf[curr], (void *) a->buf[!curr],
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
                             itv, spmin, spmax, g_fields);
 
                /* idgm6/s */
@@ -3978,7 +4233,7 @@ __print_funct_t svg_print_net_udp6_stats(struct activity *a, int curr, int actio
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -3997,7 +4252,7 @@ __print_funct_t svg_print_net_udp6_stats(struct activity *a, int curr, int actio
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (unused here).
+ * @itv                Interval of time in 1/100th of a second (unused here).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -4007,12 +4262,12 @@ __print_funct_t svg_print_pwr_cpufreq_stats(struct activity *a, int curr, int ac
        struct stats_pwr_cpufreq *spc, *spp;
        int group[] = {1};
        int g_type[] = {SVG_LINE_GRAPH};
-       char *title[] = {"CPU frequency"};
+       char *title[] = {"CPU clock frequency"};
        char *g_title[] = {"MHz"};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
-       char item_name[8];
+       char item_name[16];
        int i;
 
        if (action & F_BEGIN) {
@@ -4020,21 +4275,26 @@ __print_funct_t svg_print_pwr_cpufreq_stats(struct activity *a, int curr, int ac
                 * Allocate arrays that will contain the graphs data
                 * and the min/max values.
                 */
-               out = allocate_graph_lines(a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
                /* For each CPU */
-               for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+               for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
 
                        spc = (struct stats_pwr_cpufreq *) ((char *) a->buf[curr]  + i * a->msize);
-                       spp = (struct stats_pwr_cpufreq *) ((char *) a->buf[!curr]  + i * a->msize);
+                       spp = (struct stats_pwr_cpufreq *) ((char *) a->buf[!curr] + i * a->msize);
 
                        /* Should current CPU (including CPU "all") be displayed? */
                        if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
                                /* No */
                                continue;
 
+                       /*
+                        * Note: Don't skip offline CPU here as it is needed
+                        * to make the graph go though 0.
+                        */
+
                        /* MHz */
                        recappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                  ((double) spp->cpufreq) / 100,
@@ -4045,7 +4305,9 @@ __print_funct_t svg_print_pwr_cpufreq_stats(struct activity *a, int curr, int ac
        }
 
        if (action & F_END) {
-               for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+               int xid = 0;
+
+               for (i = 0; (i < a->item_list_sz) && (i < a->bitmap->b_size + 1); i++) {
 
                        /* Should current CPU (including CPU "all") be displayed? */
                        if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
@@ -4057,13 +4319,23 @@ __print_funct_t svg_print_pwr_cpufreq_stats(struct activity *a, int curr, int ac
                                strcpy(item_name, "all");
                        }
                        else {
+                               /*
+                                * If the maximum frequency reached by the CPU is 0, then
+                                * the CPU has been offline on the whole period.
+                                * => Don't display it.
+                                */
+                               if (*(spmax + i) == 0)
+                                       continue;
+
                                sprintf(item_name, "%d", i - 1);
                        }
 
-                       draw_activity_graphs(a->g_nr, g_type,
-                                            title, g_title, item_name, group,
-                                            spmin + i, spmax + i, out + i, outsize + i,
-                                            svg_p, record_hdr);
+                       if (draw_activity_graphs(a->g_nr, g_type,
+                                                title, g_title, item_name, group,
+                                                spmin + i, spmax + i, out + i, outsize + i,
+                                                svg_p, record_hdr, i, a, xid)) {
+                               xid++;
+                       }
                }
 
                /* Free remaining structures */
@@ -4083,7 +4355,7 @@ __print_funct_t svg_print_pwr_cpufreq_stats(struct activity *a, int curr, int ac
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (unused here).
+ * @itv                Interval of time in 1/100th of a second (unused here).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -4093,12 +4365,12 @@ __print_funct_t svg_print_pwr_fan_stats(struct activity *a, int curr, int action
        struct stats_pwr_fan *spc, *spp;
        int group[] = {1};
        int g_type[] = {SVG_LINE_GRAPH};
-       char *title[] = {"Fan speed"};
+       char *title[] = {"Fans speed"};
        char *g_title[] = {"~rpm"};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
-       char item_name[MAX_SENSORS_DEV_LEN + 8];
+       char item_name[MAX_SENSORS_DEV_LEN + 16];
        int i;
 
        if (action & F_BEGIN) {
@@ -4106,15 +4378,15 @@ __print_funct_t svg_print_pwr_fan_stats(struct activity *a, int curr, int action
                 * Allocate arrays that will contain the graphs data
                 * and the min/max values.
                 */
-               out = allocate_graph_lines(a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
                /* For each fan */
-               for (i = 0; i < a->nr; i++) {
+               for (i = 0; i < a->nr[curr]; i++) {
 
                        spc = (struct stats_pwr_fan *) ((char *) a->buf[curr]  + i * a->msize);
-                       spp = (struct stats_pwr_fan *) ((char *) a->buf[!curr]  + i * a->msize);
+                       spp = (struct stats_pwr_fan *) ((char *) a->buf[!curr] + i * a->msize);
 
                        /* rpm */
                        recappend(record_hdr->ust_time - svg_p->ust_time_ref,
@@ -4126,17 +4398,21 @@ __print_funct_t svg_print_pwr_fan_stats(struct activity *a, int curr, int action
        }
 
        if (action & F_END) {
-               for (i = 0; i < a->nr; i++) {
+               int xid = 0;
 
-                       spc = (struct stats_pwr_fan *) ((char *) a->buf[curr]  + i * a->msize);
+               for (i = 0; i < a->item_list_sz; i++) {
 
-                       snprintf(item_name, MAX_SENSORS_DEV_LEN + 8, "%d: %s", i + 1, spc->device);
-                       item_name[MAX_SENSORS_DEV_LEN + 7] = '\0';
+                       spc = (struct stats_pwr_fan *) ((char *) a->buf[curr] + i * a->msize);
 
-                       draw_activity_graphs(a->g_nr, g_type,
-                                            title, g_title, item_name, group,
-                                            spmin + i, spmax + i, out + i, outsize + i,
-                                            svg_p, record_hdr);
+                       snprintf(item_name, sizeof(item_name), "%d: %s", i + 1, spc->device);
+                       item_name[sizeof(item_name) - 1] = '\0';
+
+                       if (draw_activity_graphs(a->g_nr, g_type,
+                                                title, g_title, item_name, group,
+                                                spmin + i, spmax + i, out + i, outsize + i,
+                                                svg_p, record_hdr, FALSE, a, xid)) {
+                               xid++;
+                       }
                }
 
                /* Free remaining structures */
@@ -4156,24 +4432,25 @@ __print_funct_t svg_print_pwr_fan_stats(struct activity *a, int curr, int action
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (unused here).
+ * @itv                Interval of time in 1/100th of a second (unused here).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
+#define TEMP_ARRAY_SZ  2
 __print_funct_t svg_print_pwr_temp_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
                                         unsigned long long itv, struct record_header *record_hdr)
 {
        struct stats_pwr_temp *spc;
        int group[] = {1, 1};
        int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH};
-       char *title[] = {"Device temperature (1)",
-                        "Device temperature (2)"};
+       char *title[] = {"Devices temperature (1)",
+                        "Devices temperature (2)"};
        char *g_title[] = {"~degC",
                           "%temp"};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
-       char item_name[MAX_SENSORS_DEV_LEN + 8];
+       char item_name[MAX_SENSORS_DEV_LEN + 16];
        int i;
        double tval;
 
@@ -4182,55 +4459,60 @@ __print_funct_t svg_print_pwr_temp_stats(struct activity *a, int curr, int actio
                 * Allocate arrays that will contain the graphs data
                 * and the min/max values.
                 */
-               out = allocate_graph_lines(2 * a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(TEMP_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
-               /* For each temperature  sensor */
-               for (i = 0; i < a->nr; i++) {
+               /* For each temperature sensor */
+               for (i = 0; i < a->nr[curr]; i++) {
 
-                       spc = (struct stats_pwr_temp *) ((char *) a->buf[curr]  + i * a->msize);
+                       spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize);
 
                        /* Look for min/max values */
-                       if (spc->temp < *(spmin + 2 * i)) {
-                               *(spmin + 2 * i) = spc->temp;
+                       if (spc->temp < *(spmin + TEMP_ARRAY_SZ * i)) {
+                               *(spmin + TEMP_ARRAY_SZ * i) = spc->temp;
                        }
-                       if (spc->temp > *(spmax + 2 * i)) {
-                               *(spmax + 2 * i) = spc->temp;
+                       if (spc->temp > *(spmax + TEMP_ARRAY_SZ * i)) {
+                               *(spmax + TEMP_ARRAY_SZ * i) = spc->temp;
                        }
                        tval = (spc->temp_max - spc->temp_min) ?
                               (spc->temp - spc->temp_min) / (spc->temp_max - spc->temp_min) * 100 :
                               0.0;
-                       if (tval < *(spmin + 2 * i + 1)) {
-                               *(spmin + 2 * i + 1) = tval;
+                       if (tval < *(spmin + TEMP_ARRAY_SZ * i + 1)) {
+                               *(spmin + TEMP_ARRAY_SZ * i + 1) = tval;
                        }
-                       if (tval > *(spmax + 2 * i + 1)) {
-                               *(spmax + 2 * i + 1) = tval;
+                       if (tval > *(spmax + TEMP_ARRAY_SZ * i + 1)) {
+                               *(spmax + TEMP_ARRAY_SZ * i + 1) = tval;
                        }
 
                        /* degC */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 (double) spc->temp,
-                                out + 2 * i, outsize + 2 * i, svg_p->restart);
+                                out + TEMP_ARRAY_SZ * i, outsize + TEMP_ARRAY_SZ * i, svg_p->restart);
                        /* %temp */
                        brappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 0.0, tval,
-                                out + 2 * i + 1, outsize + 2 * i + 1, svg_p->dt);
+                                out + TEMP_ARRAY_SZ * i + 1, outsize + TEMP_ARRAY_SZ * i + 1, svg_p->dt);
                }
        }
 
        if (action & F_END) {
-               for (i = 0; i < a->nr; i++) {
+               int xid = 0;
 
-                       spc = (struct stats_pwr_temp *) ((char *) a->buf[curr]  + i * a->msize);
+               for (i = 0; i < a->item_list_sz; i++) {
 
-                       snprintf(item_name, MAX_SENSORS_DEV_LEN + 8, "%d: %s", i + 1, spc->device);
-                       item_name[MAX_SENSORS_DEV_LEN + 7] = '\0';
+                       spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize);
 
-                       draw_activity_graphs(a->g_nr, g_type,
-                                            title, g_title, item_name, group,
-                                            spmin + 2 * i, spmax + 2 * i, out + 2 * i, outsize + 2 * i,
-                                            svg_p, record_hdr);
+                       snprintf(item_name, sizeof(item_name), "%d: %s", i + 1, spc->device);
+                       item_name[sizeof(item_name) - 1] = '\0';
+
+                       if (draw_activity_graphs(a->g_nr, g_type,
+                                                title, g_title, item_name, group,
+                                                spmin + TEMP_ARRAY_SZ * i, spmax + TEMP_ARRAY_SZ * i,
+                                                out + TEMP_ARRAY_SZ * i, outsize + TEMP_ARRAY_SZ * i,
+                                                svg_p, record_hdr, FALSE, a, xid)) {
+                               xid++;
+                       }
                }
 
                /* Free remaining structures */
@@ -4250,24 +4532,25 @@ __print_funct_t svg_print_pwr_temp_stats(struct activity *a, int curr, int actio
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
+#define IN_ARRAY_SZ    2
 __print_funct_t svg_print_pwr_in_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
                                       unsigned long long itv, struct record_header *record_hdr)
 {
        struct stats_pwr_in *spc;
        int group[] = {1, 1};
        int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH};
-       char *title[] = {"Voltage inputs (1)",
-                        "Voltage inputs (2)"};
+       char *title[] = {"Voltage inputs statistics (1)",
+                        "Voltage inputs statistics (2)"};
        char *g_title[] = {"inV",
                           "%in"};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
-       char item_name[MAX_SENSORS_DEV_LEN + 8];
+       char item_name[MAX_SENSORS_DEV_LEN + 16];
        int i;
        double tval;
 
@@ -4276,55 +4559,60 @@ __print_funct_t svg_print_pwr_in_stats(struct activity *a, int curr, int action,
                 * Allocate arrays that will contain the graphs data
                 * and the min/max values.
                 */
-               out = allocate_graph_lines(2 * a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(IN_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
-               /* For each temperature  sensor */
-               for (i = 0; i < a->nr; i++) {
+               /* For each voltage input sensor */
+               for (i = 0; i < a->nr[curr]; i++) {
 
-                       spc = (struct stats_pwr_in *) ((char *) a->buf[curr]  + i * a->msize);
+                       spc = (struct stats_pwr_in *) ((char *) a->buf[curr] + i * a->msize);
 
                        /* Look for min/max values */
-                       if (spc->in < *(spmin + 2 * i)) {
-                               *(spmin + 2 * i) = spc->in;
+                       if (spc->in < *(spmin + IN_ARRAY_SZ * i)) {
+                               *(spmin + IN_ARRAY_SZ * i) = spc->in;
                        }
-                       if (spc->in > *(spmax + 2 * i)) {
-                               *(spmax + 2 * i) = spc->in;
+                       if (spc->in > *(spmax + IN_ARRAY_SZ * i)) {
+                               *(spmax + IN_ARRAY_SZ * i) = spc->in;
                        }
                        tval = (spc->in_max - spc->in_min) ?
                               (spc->in - spc->in_min) / (spc->in_max - spc->in_min) * 100 :
                               0.0;
-                       if (tval < *(spmin + 2 * i + 1)) {
-                               *(spmin + 2 * i + 1) = tval;
+                       if (tval < *(spmin + IN_ARRAY_SZ * i + 1)) {
+                               *(spmin + IN_ARRAY_SZ * i + 1) = tval;
                        }
-                       if (tval > *(spmax + 2 * i + 1)) {
-                               *(spmax + 2 * i + 1) = tval;
+                       if (tval > *(spmax + IN_ARRAY_SZ * i + 1)) {
+                               *(spmax + IN_ARRAY_SZ * i + 1) = tval;
                        }
 
                        /* inV */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 (double) spc->in,
-                                out + 2 * i, outsize + 2 * i, svg_p->restart);
+                                out + IN_ARRAY_SZ * i, outsize + IN_ARRAY_SZ * i, svg_p->restart);
                        /* %in */
                        brappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 0.0, tval,
-                                out + 2 * i + 1, outsize + 2 * i + 1, svg_p->dt);
+                                out + IN_ARRAY_SZ * i + 1, outsize + IN_ARRAY_SZ * i + 1, svg_p->dt);
                }
        }
 
        if (action & F_END) {
-               for (i = 0; i < a->nr; i++) {
+               int xid = 0;
+
+               for (i = 0; i < a->item_list_sz; i++) {
 
                        spc = (struct stats_pwr_in *) ((char *) a->buf[curr]  + i * a->msize);
 
-                       snprintf(item_name, MAX_SENSORS_DEV_LEN + 8, "%d: %s", i + 1, spc->device);
-                       item_name[MAX_SENSORS_DEV_LEN + 7] = '\0';
+                       snprintf(item_name, sizeof(item_name), "%d: %s", i + 1, spc->device);
+                       item_name[sizeof(item_name) - 1] = '\0';
 
-                       draw_activity_graphs(a->g_nr, g_type,
-                                            title, g_title, item_name, group,
-                                            spmin + 2 * i, spmax + 2 * i, out + 2 * i, outsize + 2 * i,
-                                            svg_p, record_hdr);
+                       if (draw_activity_graphs(a->g_nr, g_type,
+                                                title, g_title, item_name, group,
+                                                spmin + IN_ARRAY_SZ * i, spmax + IN_ARRAY_SZ * i,
+                                                out + IN_ARRAY_SZ * i, outsize + IN_ARRAY_SZ * i,
+                                                svg_p, record_hdr, FALSE, a, xid)) {
+                               xid++;
+                       }
                }
 
                /* Free remaining structures */
@@ -4344,7 +4632,7 @@ __print_funct_t svg_print_pwr_in_stats(struct activity *a, int curr, int action,
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
@@ -4353,13 +4641,13 @@ __print_funct_t svg_print_huge_stats(struct activity *a, int curr, int action, s
 {
        struct stats_huge
                *smc = (struct stats_huge *) a->buf[curr];
-       int group[] = {2, 1};
+       int group[] = {4, 1};
        int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH};
        char *title[] = {"Huge pages utilization (1)",
                         "Huge pages utilization (2)"};
-       char *g_title[] = {"~kbhugfree", "~kbhugused",
+       char *g_title[] = {"~kbhugfree", "~kbhugused", "~kbhugrsvd", "~kbhugsurp",
                           "%hugused"};
-       int g_fields[] = {0};
+       int g_fields[] = {0, 5, 2, 3};
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
@@ -4369,13 +4657,15 @@ __print_funct_t svg_print_huge_stats(struct activity *a, int curr, int action, s
                /*
                 * Allocate arrays that will contain the graphs data
                 * and the min/max values.
+                * Allocate one additional array (#5) to save min/max
+                * values for tlhkb (unused).
                 */
-               out = allocate_graph_lines(3, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(6, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
                /* Check for min/max values */
-               save_extrema(0, 1, 0, (void *) a->buf[curr], NULL,
+               save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
                             itv, spmin, spmax, g_fields);
 
                if (smc->tlhkb - smc->frhkb < *(spmin + 1)) {
@@ -4385,31 +4675,39 @@ __print_funct_t svg_print_huge_stats(struct activity *a, int curr, int action, s
                        *(spmax + 1) = smc->tlhkb - smc->frhkb;
                }
                tval = smc->tlhkb ? SP_VALUE(smc->frhkb, smc->tlhkb, smc->tlhkb) : 0.0;
-               if (tval < *(spmin + 2)) {
-                       *(spmin + 2) = tval;
+               if (tval < *(spmin + 4)) {
+                       *(spmin + 4) = tval;
                }
-               if (tval > *(spmax + 2)) {
-                       *(spmax + 2) = tval;
+               if (tval > *(spmax + 4)) {
+                       *(spmax + 4) = tval;
                }
 
                /* kbhugfree */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) smc->frhkb,
+                         (unsigned long long) smc->frhkb,
                          out, outsize, svg_p->restart);
                /* hugused */
                lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                         (unsigned long) smc->tlhkb - smc->frhkb,
+                         (unsigned long long) smc->tlhkb - smc->frhkb,
                          out + 1, outsize + 1, svg_p->restart);
+               /* kbhugrsvd */
+               lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                         (unsigned long long) smc->rsvdhkb,
+                         out + 2, outsize + 2, svg_p->restart);
+               /* kbhugsurp */
+               lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                         (unsigned long long) smc->surphkb,
+                         out + 3, outsize + 3, svg_p->restart);
                /* %hugused */
                brappend(record_hdr->ust_time - svg_p->ust_time_ref,
                         0.0, tval,
-                        out + 2, outsize + 2, svg_p->dt);
+                        out + 4, outsize + 4, svg_p->dt);
        }
 
        if (action & F_END) {
                draw_activity_graphs(a->g_nr, g_type,
                                     title, g_title, NULL, group,
-                                    spmin, spmax, out, outsize, svg_p, record_hdr);
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
@@ -4428,10 +4726,11 @@ __print_funct_t svg_print_huge_stats(struct activity *a, int curr, int action, s
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (unused here).
+ * @itv                Interval of time in 1/100th of a second (unused here).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
+#define FS_ARRAY_SZ    8
 __print_funct_t svg_print_filesystem_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
                                           unsigned long long itv, struct record_header *record_hdr)
 {
@@ -4439,8 +4738,8 @@ __print_funct_t svg_print_filesystem_stats(struct activity *a, int curr, int act
        int group[] = {2, 2, 2, 1};
        int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH,
                        SVG_LINE_GRAPH, SVG_BAR_GRAPH};
-       char *title[] = {"Filesystem statistics (1)", "Filesystem statistics (2)",
-                        "Filesystem statistics (3)", "Filesystem statistics (4)"};
+       char *title[] = {"Filesystems statistics (1)", "Filesystems statistics (2)",
+                        "Filesystems statistics (3)", "Filesystems statistics (4)"};
        char *g_title[] = {"~MBfsfree", "~MBfsused",
                           "%ufsused", "%fsused",
                           "Ifree/1000", "Iused/1000",
@@ -4448,7 +4747,7 @@ __print_funct_t svg_print_filesystem_stats(struct activity *a, int curr, int act
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
-       char *item_name;
+       char *dev_name, *item_name;
        double tval;
        int i, k, pos, restart;
 
@@ -4456,55 +4755,63 @@ __print_funct_t svg_print_filesystem_stats(struct activity *a, int curr, int act
                /*
                 * Allocate arrays (#0..6) that will contain the graphs data
                 * and the min/max values.
-                * Also allocate two additional arrays (#7..8) for each filesystem:
-                 * out + 7 will contain the filesystem name,
-                * out + 8 will contain the mount point.
+                * Also allocate an additional arrays (#7) for each filesystem:
+                 * out + 7 will contain the persistent or standard fs name, or mount point.
                 */
-               out = allocate_graph_lines(9 * a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(FS_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
                /* For each filesystem structure */
-               for (i = 0; i < a->nr; i++) {
+               for (i = 0; i < a->nr[curr]; i++) {
                        sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
 
-                       if (!sfc->f_blocks)
-                               /* Size of filesystem is zero: We are at the end of the list */
-                               break;
+                       /* Get name to display (persistent or standard fs name, or mount point) */
+                       dev_name = get_fs_name_to_display(a, flags, sfc);
+
+                       if (a->item_list != NULL) {
+                               /* A list of devices has been entered on the command line */
+                               if (!search_list_item(a->item_list, dev_name))
+                                       /* Device not found */
+                                       continue;
+                       }
 
                        /* Look for corresponding graph */
-                       for (k = 0; k < a->nr; k++) {
-                               item_name = *(out + k * 9 + 7);
-                               if (!strcmp(sfc->fs_name, item_name))
+                       for (k = 0; k < a->item_list_sz; k++) {
+                               item_name = *(out + k * FS_ARRAY_SZ + 7);
+                               if (!strcmp(dev_name, item_name))
                                        /* Graph found! */
                                        break;
                        }
 
-                       if (k == a->nr) {
+                       if (k == a->item_list_sz) {
                                /* Graph not found: Look for first free entry */
-                               for (k = 0; k < a->nr; k++) {
-                                       item_name = *(out + k * 9 + 7);
+                               for (k = 0; k < a->item_list_sz; k++) {
+                                       item_name = *(out + k * FS_ARRAY_SZ + 7);
                                        if (!strcmp(item_name, ""))
                                                break;
                                }
-                               if (k == a->nr)
-                                       /* No free graph entry: Graph for this item won't be drawn */
+                               if (k == a->item_list_sz) {
+                                       /* No free graph entry: Ignore it (should never happen) */
+#ifdef DEBUG
+                                       fprintf(stderr, "%s: Name=%s\n",
+                                               __FUNCTION__, sfc->fs_name);
+#endif
                                        continue;
+                               }
                        }
 
-                       pos = k * 9;
+                       pos = k * FS_ARRAY_SZ;
 
+                       item_name = *(out + pos + 7);
                        if (!item_name[0]) {
                                /* Save filesystem name and mount point (if not already done) */
-                               strncpy(item_name, sfc->fs_name, CHUNKSIZE);
-                               item_name[CHUNKSIZE - 1] = '\0';
-                               item_name = *(out + pos + 8);
-                               strncpy(item_name, sfc->mountp, CHUNKSIZE);
+                               strncpy(item_name, dev_name, CHUNKSIZE);
                                item_name[CHUNKSIZE - 1] = '\0';
                        }
 
                        restart = TRUE;
-                       for (k = 0; k < a->nr; k++) {
+                       for (k = 0; k < a->nr[!curr]; k++) {
                                sfp = (struct stats_filesystem *) ((char *) a->buf[!curr] + k * a->msize);
                                if (!strcmp(sfc->fs_name, sfp->fs_name)) {
                                        /* Filesystem found in previous sample */
@@ -4612,15 +4919,16 @@ __print_funct_t svg_print_filesystem_stats(struct activity *a, int curr, int act
        }
 
        if (action & F_END) {
+               int xid = 0;
 
-               for (i = 0; i < a->nr; i++) {
+               for (i = 0; i < a->item_list_sz; i++) {
 
                        /* Check if there is something to display */
-                       pos = i * 9;
+                       pos = i * FS_ARRAY_SZ;
                        if (!**(out + pos))
                                continue;
 
-                       /* Conversion B -> MB and inodes/1000 */
+                       /* Conversion B -> MiB and inodes/1000 */
                        for (k = 0; k < 2; k++) {
                                *(spmin + pos + k) /= (1024 * 1024);
                                *(spmax + pos + k) /= (1024 * 1024);
@@ -4628,16 +4936,13 @@ __print_funct_t svg_print_filesystem_stats(struct activity *a, int curr, int act
                                *(spmax + pos + 4 + k) /= 1000;
                        }
 
-                       if (DISPLAY_MOUNT(a->opt_flags)) {
-                               item_name = *(out + pos + 8);
-                       }
-                       else {
-                               item_name = *(out + pos + 7);
-                       }
+                       item_name = *(out + pos + 7);
 
-                       draw_activity_graphs(a->g_nr, g_type, title, g_title, item_name, group,
-                                            spmin + pos, spmax + pos, out + pos, outsize + pos,
-                                            svg_p, record_hdr);
+                       if (draw_activity_graphs(a->g_nr, g_type, title, g_title, item_name, group,
+                                                spmin + pos, spmax + pos, out + pos, outsize + pos,
+                                                svg_p, record_hdr, FALSE, a, xid)) {
+                               xid++;
+                       }
                }
 
                /* Free remaining structures */
@@ -4657,14 +4962,15 @@ __print_funct_t svg_print_filesystem_stats(struct activity *a, int curr, int act
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
+#define FC_ARRAY_SZ    5
 __print_funct_t svg_print_fchost_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
                                       unsigned long long itv, struct record_header *record_hdr)
 {
-       struct stats_fchost *sfcc, *sfcp;
+       struct stats_fchost *sfcc, *sfcp, sfczero;
        int group[] = {2, 2};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
        char *title[] = {"Fibre Channel HBA statistics (1)", "Fibre Channel HBA statistics (2)"};
@@ -4675,65 +4981,149 @@ __print_funct_t svg_print_fchost_stats(struct activity *a, int curr, int action,
        static char **out;
        static int *outsize;
        char *item_name;
-       int i, pos;
+       int i, j, j0, k, found, pos, restart, *unregistered;
 
        if (action & F_BEGIN) {
                /*
                 * Allocate arrays (#0..3) that will contain the graphs data
                 * and the min/max values.
                 * Also allocate one additional array (#4) that will contain
-                * FC HBA name.
+                * FC HBA name (out + 4) and a positive value (TRUE) if the interface
+                * has either still not been registered, or has been unregistered
+                * (outsize + 4).
                 */
-               out = allocate_graph_lines(4 * a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(FC_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
+               memset(&sfczero, 0, sizeof(struct stats_fchost));
+               /*
+                * Mark previously registered interfaces as now
+                * possibly unregistered for all graphs.
+                */
+               for (k = 0; k < a->item_list_sz; k++) {
+                       unregistered = outsize + k * FC_ARRAY_SZ + 4;
+                       if (*unregistered == FALSE) {
+                               *unregistered = MAYBE;
+                       }
+               }
+
                /* For each FC HBA */
-               for (i = 0; i < a->nr; i++) {
+               for (i = 0; i < a->nr[curr]; i++) {
 
+                       found = FALSE;
                        sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
-                       if (!sfcc->fchost_name[0])
-                               /* We are at the end of the list */
-                               break;
-
-                       sfcp = (struct stats_fchost *) ((char *) a->buf[!curr] + i * a->msize);
-                       pos = i * 5;
+                       restart = svg_p->restart;
 
-                       item_name = *(out + pos + 4);
-                       if (!item_name[0]) {
-                               /* Save FC HBA name */
-                               strncpy(item_name, sfcc->fchost_name, CHUNKSIZE);
-                               item_name[CHUNKSIZE - 1] = '\0';
+                       /* Look for corresponding graph */
+                       for (k = 0; k < a->item_list_sz; k++) {
+                               item_name = *(out + k * FC_ARRAY_SZ + 4);
+                               if (!strcmp(sfcc->fchost_name, item_name))
+                                       /* Graph found! */
+                                       break;
+                       }
+                       if (k == a->item_list_sz) {
+                               /* Graph not found: Look for first free entry */
+                               for (k = 0; k < a->item_list_sz; k++) {
+                                       item_name = *(out + k * FC_ARRAY_SZ + 4);
+                                       if (!strcmp(item_name, ""))
+                                               break;
+                               }
+                               if (k == a->item_list_sz) {
+                                       /* No free graph entry: Ignore it (should never happen) */
+#ifdef DEBUG
+                                       fprintf(stderr, "%s: Name=%s\n",
+                                               __FUNCTION__, sfcc->fchost_name);
+#endif
+                                       continue;
+                               }
                        }
 
-                       /* Look for min/max values */
-                       save_extrema(0, 4, 0, (void *) sfcc, (void *) sfcp,
-                               itv, spmin + pos, spmax + pos, g_fields);
+                       pos = k * FC_ARRAY_SZ;
+                       unregistered = outsize + pos + 4;
 
-                       /* fch_rxf/s */
-                       lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                S_VALUE(sfcp->f_rxframes, sfcc->f_rxframes, itv),
-                                out + pos, outsize + pos, svg_p->restart);
-                       /* fch_txf/s */
-                       lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                S_VALUE(sfcp->f_txframes, sfcc->f_txframes, itv),
-                                out + pos + 1, outsize + pos + 1, svg_p->restart);
-                       /* fch_rxw/s */
-                       lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
-                                S_VALUE(sfcp->f_rxwords, sfcc->f_rxwords, itv),
-                                out + pos + 2, outsize + pos + 2, svg_p->restart);
-                       /* fch_txw/s */
+                       if (a->nr[!curr] > 0) {
+                               /* Look for corresponding structure in previous iteration */
+                               j = i;
+
+                               if (j >= a->nr[!curr]) {
+                                       j = a->nr[!curr] - 1;
+                               }
+
+                               j0 = j;
+
+                               do {
+                                       sfcp = (struct stats_fchost *) ((char *) a->buf[!curr] + j * a->msize);
+                                       if (!strcmp(sfcc->fchost_name, sfcp->fchost_name)) {
+                                               found = TRUE;
+                                               break;
+                                       }
+                                       if (++j >= a->nr[!curr]) {
+                                               j = 0;
+                                       }
+                               }
+                               while (j != j0);
+                       }
+
+                       if (!found) {
+                               /* This is a newly registered host */
+                               sfcp = &sfczero;
+                               restart = TRUE;
+                       }
+
+                       /*
+                        * If current interface was marked as previously unregistered,
+                        * then set restart variable to TRUE so that the graph will be
+                        * discontinuous, and mark it as now registered.
+                        */
+                       if (*unregistered == TRUE) {
+                               restart = TRUE;
+                       }
+                       *unregistered = FALSE;
+
+                       item_name = *(out + pos + 4);
+                       if (!item_name[0]) {
+                               /* Save FC HBA name */
+                               strncpy(item_name, sfcc->fchost_name, CHUNKSIZE);
+                               item_name[CHUNKSIZE - 1] = '\0';
+                       }
+
+                       /* Look for min/max values */
+                       save_extrema(a->gtypes_nr, (void *) sfcc, (void *) sfcp,
+                               itv, spmin + pos, spmax + pos, g_fields);
+
+                       /* fch_rxf/s */
+                       lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                                S_VALUE(sfcp->f_rxframes, sfcc->f_rxframes, itv),
+                                out + pos, outsize + pos, restart);
+                       /* fch_txf/s */
+                       lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                                S_VALUE(sfcp->f_txframes, sfcc->f_txframes, itv),
+                                out + pos + 1, outsize + pos + 1, restart);
+                       /* fch_rxw/s */
+                       lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                                S_VALUE(sfcp->f_rxwords, sfcc->f_rxwords, itv),
+                                out + pos + 2, outsize + pos + 2, restart);
+                       /* fch_txw/s */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 S_VALUE(sfcp->f_txwords, sfcc->f_txwords, itv),
-                                out + pos + 3, outsize + pos + 3, svg_p->restart);
+                                out + pos + 3, outsize + pos + 3, restart);
+               }
+
+               /* Mark interfaces not seen here as now unregistered */
+               for (k = 0; k < a->item_list_sz; k++) {
+                       unregistered = outsize + k * FC_ARRAY_SZ + 4;
+                       if (*unregistered != FALSE) {
+                               *unregistered = TRUE;
+                       }
                }
        }
 
        if (action & F_END) {
-               for (i = 0; i < a->nr; i++) {
+               for (i = 0; i < a->item_list_sz; i++) {
 
                        /* Check if there is something to display */
-                       pos = i * 5;
+                       pos = i * FC_ARRAY_SZ;
                        if (!**(out + pos))
                                continue;
 
@@ -4741,7 +5131,7 @@ __print_funct_t svg_print_fchost_stats(struct activity *a, int curr, int action,
                        draw_activity_graphs(a->g_nr, g_type,
                                             title, g_title, item_name, group,
                                             spmin + pos, spmax + pos, out + pos, outsize + pos,
-                                            svg_p, record_hdr);
+                                            svg_p, record_hdr, FALSE, a, i);
                }
 
                /* Free remaining structures */
@@ -4761,14 +5151,15 @@ __print_funct_t svg_print_fchost_stats(struct activity *a, int curr, int action,
  *             flag indicating that a restart record has been previously
  *             found (.@restart) and time used for the X axis origin
  *             (@ust_time_ref).
- * @itv                Interval of time in jiffies (only with F_MAIN action).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
  * @record_hdr Pointer on record header of current stats sample.
  ***************************************************************************
  */
+#define SOFT_ARRAY_SZ  5
 __print_funct_t svg_print_softnet_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
                                        unsigned long long itv, struct record_header *record_hdr)
 {
-       struct stats_softnet *ssnc, *ssnp;
+       struct stats_softnet *ssnc, *ssnp, ssnczero;
        int group[] = {2, 3};
        int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
        char *title[] = {"Software-based network processing statistics (1)",
@@ -4779,67 +5170,96 @@ __print_funct_t svg_print_softnet_stats(struct activity *a, int curr, int action
        static double *spmin, *spmax;
        static char **out;
        static int *outsize;
-       char item_name[8];
-       int i, pos;
+       char item_name[16];
+       unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
+       int i, pos, restart;
 
        if (action & F_BEGIN) {
                /*
                 * Allocate arrays that will contain the graphs data
                 * and the min/max values.
                 */
-               out = allocate_graph_lines(5 * a->nr, &outsize, &spmin, &spmax);
+               out = allocate_graph_lines(SOFT_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
        }
 
        if (action & F_MAIN) {
-               /* For each CPU */
-               for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+               memset(&ssnczero, 0, STATS_SOFTNET_SIZE);
 
-                       ssnc = (struct stats_softnet *) ((char *) a->buf[curr]  + i * a->msize);
-                       ssnp = (struct stats_softnet *) ((char *) a->buf[!curr] + i * a->msize);
+               /* @nr[curr] cannot normally be greater than @nr_ini */
+               if (a->nr[curr] > a->nr_ini) {
+                       a->nr_ini = a->nr[curr];
+               }
+
+               /* Compute statistics for CPU "all" */
+               get_global_soft_statistics(a, !curr, curr, flags, offline_cpu_bitmap);
+
+               /* For each CPU */
+               for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
+                       restart = svg_p->restart;
 
                        /* Should current CPU (including CPU "all") be displayed? */
                        if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
                                /* No */
                                continue;
 
-                       pos = i * 5;
+                       ssnc = (struct stats_softnet *) ((char *) a->buf[curr]  + i * a->msize);
+                       ssnp = (struct stats_softnet *) ((char *) a->buf[!curr] + i * a->msize);
+
+                       /* Is current CPU marked offline? */
+                       if (offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07))) {
+                               /*
+                                * Yes and it doesn't follow a RESTART record.
+                                * To add a discontinuity in graph, we simulate
+                                * a RESTART mark.
+                                */
+                               restart = TRUE;
+                               if (svg_p->restart) {
+                                       /*
+                                        * CPU is offline and it follows a real
+                                        * RESTART record. Ignore its current value
+                                        * (no previous sample).
+                                        */
+                                       ssnc = &ssnczero;
+                               }
+                       }
+                       pos = i * SOFT_ARRAY_SZ;
 
                        /* Check for min/max values */
-                       save_extrema(0, 0, 5, (void *) ssnc, (void *) ssnp,
+                       save_extrema(a->gtypes_nr, (void *) ssnc, (void *) ssnp,
                                     itv, spmin + pos, spmax + pos, g_fields);
 
                        /* total/s */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 S_VALUE(ssnp->processed, ssnc->processed, itv),
-                                out + pos, outsize + pos, svg_p->restart);
+                                out + pos, outsize + pos, restart);
                        /* dropd/s */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 S_VALUE(ssnp->dropped, ssnc->dropped, itv),
-                                out + pos + 1, outsize + pos + 1, svg_p->restart);
+                                out + pos + 1, outsize + pos + 1, restart);
                        /* squeezd/s */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 S_VALUE(ssnp->time_squeeze, ssnc->time_squeeze, itv),
-                                out + pos + 2, outsize + pos + 2, svg_p->restart);
+                                out + pos + 2, outsize + pos + 2, restart);
                        /* rx_rps/s */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 S_VALUE(ssnp->received_rps, ssnc->received_rps, itv),
-                                out + pos + 3, outsize + pos + 3, svg_p->restart);
+                                out + pos + 3, outsize + pos + 3, restart);
                        /* flw_lim/s */
                        lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
                                 S_VALUE(ssnp->flow_limit, ssnc->flow_limit, itv),
-                                out + pos + 4, outsize + pos + 4, svg_p->restart);
+                                out + pos + 4, outsize + pos + 4, restart);
                }
        }
 
        if (action & F_END) {
-               for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+               for (i = 0; (i < a->item_list_sz) && (i < a->bitmap->b_size + 1); i++) {
 
                        /* Should current CPU (including CPU "all") be displayed? */
                        if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
                                /* No */
                                continue;
 
-                       pos = i * 5;
+                       pos = i * SOFT_ARRAY_SZ;
 
                        if (!i) {
                                /* This is CPU "all" */
@@ -4852,10 +5272,415 @@ __print_funct_t svg_print_softnet_stats(struct activity *a, int curr, int action
                        draw_activity_graphs(a->g_nr, g_type,
                                             title, g_title, item_name, group,
                                             spmin + pos, spmax + pos, out + pos, outsize + pos,
-                                            svg_p, record_hdr);
+                                            svg_p, record_hdr, FALSE, a, i);
                }
 
                /* Free remaining structures */
                free_graphs(out, outsize, spmin, spmax);
        }
 }
+
+/*
+ ***************************************************************************
+ * Display pressure-stall CPU statistics in SVG.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ * @action     Action expected from current function.
+ * @svg_p      SVG specific parameters: Current graph number (.@graph_no),
+ *             flag indicating that a restart record has been previously
+ *             found (.@restart) and time used for the X axis origin
+ *             (@ust_time_ref).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
+ * @record_hdr Pointer on record header of current stats sample.
+ ***************************************************************************
+ */
+__print_funct_t svg_print_psicpu_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
+                                      unsigned long long itv, struct record_header *record_hdr)
+{
+       struct stats_psi_cpu
+               *psic = (struct stats_psi_cpu *) a->buf[curr],
+               *psip = (struct stats_psi_cpu *) a->buf[!curr];
+       int group[] = {3, 1};
+       int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH};
+       char *title[] = {"CPU pressure trends (some tasks)", "CPU stall time (some tasks)"};
+       char *g_title[] = {"%scpu-10", "%scpu-60", "%scpu-300",
+                          "%scpu"};
+       static double *spmin, *spmax;
+       static char **out;
+       static int *outsize;
+       double tval;
+
+       if (action & F_BEGIN) {
+               /*
+                * Allocate arrays that will contain the graphs data
+                * and the min/max values.
+                */
+               out = allocate_graph_lines(4, &outsize, &spmin, &spmax);
+       }
+
+       if (action & F_MAIN) {
+               /* Check for min/max values */
+               if (psic->some_acpu_10 > *spmax) {
+                       *spmax = psic->some_acpu_10;
+               }
+               if (psic->some_acpu_10 < *spmin) {
+                       *spmin = psic->some_acpu_10;
+               }
+               if (psic->some_acpu_60 > *(spmax + 1)) {
+                       *(spmax + 1) = psic->some_acpu_60;
+               }
+               if (psic->some_acpu_60 < *(spmin + 1)) {
+                       *(spmin + 1) = psic->some_acpu_60;
+               }
+               if (psic->some_acpu_300 > *(spmax + 2)) {
+                       *(spmax + 2) = psic->some_acpu_300;
+               }
+               if (psic->some_acpu_300 < *(spmin + 2)) {
+                       *(spmin + 2) = psic->some_acpu_300;
+               }
+               tval = ((double) psic->some_cpu_total - psip->some_cpu_total) / (100 * itv);
+               if (tval > *(spmax + 3)) {
+                       *(spmax + 3) = tval;
+               }
+               if (tval < *(spmin + 3)) {
+                       *(spmin + 3) = tval;
+               }
+
+               /* %scpu-10 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->some_acpu_10 / 100,
+                        out, outsize, svg_p->restart);
+               /* %scpu-60 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->some_acpu_60 / 100,
+                        out + 1, outsize + 1, svg_p->restart);
+               /* %scpu-300 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->some_acpu_300 / 100,
+                        out + 2, outsize + 2, svg_p->restart);
+               /* %scpu */
+               brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        0.0,
+                        ((double) psic->some_cpu_total - psip->some_cpu_total) / (100 * itv),
+                        out + 3, outsize + 3, svg_p->dt);
+       }
+
+       if (action & F_END) {
+               /* Fix min/max values for pressure ratios */
+               *spmin /= 100; *spmax /= 100;
+               *(spmin + 1) /= 100; *(spmax + 1) /= 100;
+               *(spmin + 2) /= 100; *(spmax + 2) /= 100;
+
+               draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
+
+               /* Free remaining structures */
+               free_graphs(out, outsize, spmin, spmax);
+       }
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall I/O statistics in SVG.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ * @action     Action expected from current function.
+ * @svg_p      SVG specific parameters: Current graph number (.@graph_no),
+ *             flag indicating that a restart record has been previously
+ *             found (.@restart) and time used for the X axis origin
+ *             (@ust_time_ref).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
+ * @record_hdr Pointer on record header of current stats sample.
+ ***************************************************************************
+ */
+__print_funct_t svg_print_psiio_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
+                                     unsigned long long itv, struct record_header *record_hdr)
+{
+       struct stats_psi_io
+               *psic = (struct stats_psi_io *) a->buf[curr],
+               *psip = (struct stats_psi_io *) a->buf[!curr];
+       int group[] = {3, 1, 3, 1};
+       int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH, SVG_LINE_GRAPH, SVG_BAR_GRAPH};
+       char *title[] = {"I/O pressure trends (some tasks)", "I/O stall time (some tasks)",
+                        "I/O pressure trends (full)", "I/O stall time (full)"};
+       char *g_title[] = {"%sio-10", "%sio-60", "%sio-300",
+                          "%sio",
+                          "%fio-10", "%fio-60", "%fio-300",
+                          "%fio"};
+       static double *spmin, *spmax;
+       static char **out;
+       static int *outsize;
+       double tval;
+
+       if (action & F_BEGIN) {
+               /*
+                * Allocate arrays that will contain the graphs data
+                * and the min/max values.
+                */
+               out = allocate_graph_lines(8, &outsize, &spmin, &spmax);
+       }
+
+       if (action & F_MAIN) {
+               /* Check for min/max values */
+               if (psic->some_aio_10 > *spmax) {
+                       *spmax = psic->some_aio_10;
+               }
+               if (psic->some_aio_10 < *spmin) {
+                       *spmin = psic->some_aio_10;
+               }
+               if (psic->some_aio_60 > *(spmax + 1)) {
+                       *(spmax + 1) = psic->some_aio_60;
+               }
+               if (psic->some_aio_60 < *(spmin + 1)) {
+                       *(spmin + 1) = psic->some_aio_60;
+               }
+               if (psic->some_aio_300 > *(spmax + 2)) {
+                       *(spmax + 2) = psic->some_aio_300;
+               }
+               if (psic->some_aio_300 < *(spmin + 2)) {
+                       *(spmin + 2) = psic->some_aio_300;
+               }
+               tval = ((double) psic->some_io_total - psip->some_io_total) / (100 * itv);
+               if (tval > *(spmax + 3)) {
+                       *(spmax + 3) = tval;
+               }
+               if (tval < *(spmin + 3)) {
+                       *(spmin + 3) = tval;
+               }
+
+               if (psic->full_aio_10 > *(spmax + 4)) {
+                       *(spmax + 4) = psic->full_aio_10;
+               }
+               if (psic->full_aio_10 < *(spmin + 4)) {
+                       *(spmin + 4) = psic->full_aio_10;
+               }
+               if (psic->full_aio_60 > *(spmax + 5)) {
+                       *(spmax + 5) = psic->full_aio_60;
+               }
+               if (psic->full_aio_60 < *(spmin + 5)) {
+                       *(spmin + 5) = psic->full_aio_60;
+               }
+               if (psic->full_aio_300 > *(spmax + 6)) {
+                       *(spmax + 6) = psic->full_aio_300;
+               }
+               if (psic->full_aio_300 < *(spmin + 6)) {
+                       *(spmin + 6) = psic->full_aio_300;
+               }
+               tval = ((double) psic->full_io_total - psip->full_io_total) / (100 * itv);
+               if (tval > *(spmax + 7)) {
+                       *(spmax + 7) = tval;
+               }
+               if (tval < *(spmin + 7)) {
+                       *(spmin + 7) = tval;
+               }
+
+               /* %sio-10 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->some_aio_10 / 100,
+                        out, outsize, svg_p->restart);
+               /* %sio-60 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->some_aio_60 / 100,
+                        out + 1, outsize + 1, svg_p->restart);
+               /* %sio-300 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->some_aio_300 / 100,
+                        out + 2, outsize + 2, svg_p->restart);
+               /* %sio */
+               brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        0.0,
+                        ((double) psic->some_io_total - psip->some_io_total) / (100 * itv),
+                        out + 3, outsize + 3, svg_p->dt);
+
+               /* %fio-10 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->full_aio_10 / 100,
+                        out + 4, outsize + 4, svg_p->restart);
+               /* %fio-60 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->full_aio_60 / 100,
+                        out + 5, outsize + 5, svg_p->restart);
+               /* %fio-300 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->full_aio_300 / 100,
+                        out + 6, outsize + 6, svg_p->restart);
+               /* %fio */
+               brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        0.0,
+                        ((double) psic->full_io_total - psip->full_io_total) / (100 * itv),
+                        out + 7, outsize + 7, svg_p->dt);
+       }
+
+       if (action & F_END) {
+               /* Fix min/max values for pressure ratios */
+               *spmin /= 100; *spmax /= 100;
+               *(spmin + 1) /= 100; *(spmax + 1) /= 100;
+               *(spmin + 2) /= 100; *(spmax + 2) /= 100;
+
+               *(spmin + 4) /= 100; *(spmax + 4) /= 100;
+               *(spmin + 5) /= 100; *(spmax + 5) /= 100;
+               *(spmin + 6) /= 100; *(spmax + 6) /= 100;
+
+               draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
+
+               /* Free remaining structures */
+               free_graphs(out, outsize, spmin, spmax);
+       }
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall memory statistics in SVG.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ * @action     Action expected from current function.
+ * @svg_p      SVG specific parameters: Current graph number (.@graph_no),
+ *             flag indicating that a restart record has been previously
+ *             found (.@restart) and time used for the X axis origin
+ *             (@ust_time_ref).
+ * @itv                Interval of time in 1/100th of a second (only with F_MAIN action).
+ * @record_hdr Pointer on record header of current stats sample.
+ ***************************************************************************
+ */
+__print_funct_t svg_print_psimem_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
+                                      unsigned long long itv, struct record_header *record_hdr)
+{
+       struct stats_psi_mem
+               *psic = (struct stats_psi_mem *) a->buf[curr],
+               *psip = (struct stats_psi_mem *) a->buf[!curr];
+       int group[] = {3, 1, 3, 1};
+       int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH, SVG_LINE_GRAPH, SVG_BAR_GRAPH};
+       char *title[] = {"Memory pressure trends (some tasks)", "Memory stall time (some tasks)",
+                        "Memory pressure trends (full)", "Memory stall time (full)"};
+       char *g_title[] = {"%smem-10", "%smem-60", "%smem-300",
+                          "%smem",
+                          "%fmem-10", "%fmem-60", "%fmem-300",
+                          "%fmem"};
+       static double *spmin, *spmax;
+       static char **out;
+       static int *outsize;
+       double tval;
+
+       if (action & F_BEGIN) {
+               /*
+                * Allocate arrays that will contain the graphs data
+                * and the min/max values.
+                */
+               out = allocate_graph_lines(8, &outsize, &spmin, &spmax);
+       }
+
+       if (action & F_MAIN) {
+               /* Check for min/max values */
+               if (psic->some_amem_10 > *spmax) {
+                       *spmax = psic->some_amem_10;
+               }
+               if (psic->some_amem_10 < *spmin) {
+                       *spmin = psic->some_amem_10;
+               }
+               if (psic->some_amem_60 > *(spmax + 1)) {
+                       *(spmax + 1) = psic->some_amem_60;
+               }
+               if (psic->some_amem_60 < *(spmin + 1)) {
+                       *(spmin + 1) = psic->some_amem_60;
+               }
+               if (psic->some_amem_300 > *(spmax + 2)) {
+                       *(spmax + 2) = psic->some_amem_300;
+               }
+               if (psic->some_amem_300 < *(spmin + 2)) {
+                       *(spmin + 2) = psic->some_amem_300;
+               }
+               tval = ((double) psic->some_mem_total - psip->some_mem_total) / (100 * itv);
+               if (tval > *(spmax + 3)) {
+                       *(spmax + 3) = tval;
+               }
+               if (tval < *(spmin + 3)) {
+                       *(spmin + 3) = tval;
+               }
+
+               if (psic->full_amem_10 > *(spmax + 4)) {
+                       *(spmax + 4) = psic->full_amem_10;
+               }
+               if (psic->full_amem_10 < *(spmin + 4)) {
+                       *(spmin + 4) = psic->full_amem_10;
+               }
+               if (psic->full_amem_60 > *(spmax + 5)) {
+                       *(spmax + 5) = psic->full_amem_60;
+               }
+               if (psic->full_amem_60 < *(spmin + 5)) {
+                       *(spmin + 5) = psic->full_amem_60;
+               }
+               if (psic->full_amem_300 > *(spmax + 6)) {
+                       *(spmax + 6) = psic->full_amem_300;
+               }
+               if (psic->full_amem_300 < *(spmin + 6)) {
+                       *(spmin + 6) = psic->full_amem_300;
+               }
+               tval = ((double) psic->full_mem_total - psip->full_mem_total) / (100 * itv);
+               if (tval > *(spmax + 7)) {
+                       *(spmax + 7) = tval;
+               }
+               if (tval < *(spmin + 7)) {
+                       *(spmin + 7) = tval;
+               }
+
+               /* %smem-10 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->some_amem_10 / 100,
+                        out, outsize, svg_p->restart);
+               /* %smem-60 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->some_amem_60 / 100,
+                        out + 1, outsize + 1, svg_p->restart);
+               /* %smem-300 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->some_amem_300 / 100,
+                        out + 2, outsize + 2, svg_p->restart);
+               /* %smem */
+               brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        0.0,
+                        ((double) psic->some_mem_total - psip->some_mem_total) / (100 * itv),
+                        out + 3, outsize + 3, svg_p->dt);
+
+               /* %fmem-10 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->full_amem_10 / 100,
+                        out + 4, outsize + 4, svg_p->restart);
+               /* %fmem-60 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->full_amem_60 / 100,
+                        out + 5, outsize + 5, svg_p->restart);
+               /* %fmem-300 */
+               lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        (double) psic->full_amem_300 / 100,
+                        out + 6, outsize + 6, svg_p->restart);
+               /* %fmem */
+               brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+                        0.0,
+                        ((double) psic->full_mem_total - psip->full_mem_total) / (100 * itv),
+                        out + 7, outsize + 7, svg_p->dt);
+       }
+
+       if (action & F_END) {
+               /* Fix min/max values for pressure ratios */
+               *spmin /= 100; *spmax /= 100;
+               *(spmin + 1) /= 100; *(spmax + 1) /= 100;
+               *(spmin + 2) /= 100; *(spmax + 2) /= 100;
+
+               *(spmin + 4) /= 100; *(spmax + 4) /= 100;
+               *(spmin + 5) /= 100; *(spmax + 5) /= 100;
+               *(spmin + 6) /= 100; *(spmax + 6) /= 100;
+
+               draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
+                                    spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
+
+               /* Free remaining structures */
+               free_graphs(out, outsize, spmin, spmax);
+       }
+}