Qt: Don't plot zero values in I/O scatter plots
authorGerald Combs <gerald@wireshark.org>
Sat, 4 Jan 2020 20:36:12 +0000 (12:36 -0800)
committerAnders Broman <a.broman58@gmail.com>
Tue, 7 Jan 2020 12:42:48 +0000 (12:42 +0000)
We don't currently distinguish between missing and zero values in I/O
graphs. This can be problematic in scatter plots since the plot points
tend to show up as chartjunk which overwhelms the X axis. In plain,
non-calculated plots assume that zero values mean "missing" and omit
those points.

Describe this in the User's Guide, but comment the text out for now
pending a full update to the I/O Graph section.

Switch to title case in our default graphs. Make the TCP Errors graph
red by default.

Change-Id: I92dcbf05f58ae0b7b7734fa8dfc342424bbea114
Reviewed-on: https://code.wireshark.org/review/35645
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
docbook/wsug_src/WSUG_chapter_statistics.adoc
ui/qt/io_graph_dialog.cpp
ui/qt/io_graph_dialog.h

index 863dadc2a69b6e5a68eca1750783616ca5ed52d7..f36ffd100b2e866e698d6b34af9e7e2e2a8d4d9c 100644 (file)
@@ -417,6 +417,17 @@ The btn:[Copy] button will copy values from selected graphs to the clipboard in
 Click in the graph to select the first package in the selected interval.
 ====
 
+// Applies to the Qt verson:
+// .Missing Values Are Zero
+
+// Wireshark's I/O Graph window doesn’t distinguish between missing and zero values.
+// For _plain_ scatter plots, it is assumed that zero values indicate missing data, and those values are ommitted.
+// Zero values are shown in line graphs, bar charts, and _calculated_ scatter plots.
+// Scatter plots are considered calculated if they have a calculated Y axis field or if a moving average is set.
+
+// If you need to display zero values in a scatter plot, you can do so by making the Y Axis a calculated field.
+// For example, the calculated equivalent of “Packets” is a “COUNT FRAMES” Y Axis with a Y Field set to “frame”.
+
 [[ChStatSRT]]
 
 === Service Response Time
index f423d44d578016eb8c579bfe2480de4e6c256646..b0940c99669f27f828a4049121c297ba2118bb7c 100644 (file)
@@ -57,6 +57,9 @@
 // - Use scroll bars?
 // - Scroll during live captures
 // - Set ticks per pixel (e.g. pressing "2" sets 2 tpp).
+// - Explicitly handle missing values, e.g. via NAN.
+// - Add a "show missing" or "show zero" option to the UAT?
+//   It would add yet another graph configuration column.
 
 const qreal graph_line_width_ = 1.0;
 
@@ -458,7 +461,7 @@ void IOGraphDialog::copyFromProfile(QString filename)
     }
 }
 
-void IOGraphDialog::addGraph(bool checked, QString name, QString dfilter, int color_idx, IOGraph::PlotStyles style, io_graph_item_unit_t value_units, QString yfield, int moving_average)
+void IOGraphDialog::addGraph(bool checked, QString name, QString dfilter, QRgb color_idx, IOGraph::PlotStyles style, io_graph_item_unit_t value_units, QString yfield, int moving_average)
 {
     // should not fail, but you never know.
     if (!uat_model_->insertRows(uat_model_->rowCount(), 1)) {
@@ -476,7 +479,7 @@ void IOGraphDialog::addGraph(bool checked, QString name, QString dfilter, int co
     uat_model_->setData(uat_model_->index(currentRow, colStyle), val_to_str_const(style, graph_style_vs, "None"));
     uat_model_->setData(uat_model_->index(currentRow, colYAxis), val_to_str_const(value_units, y_axis_vs, "Packets"));
     uat_model_->setData(uat_model_->index(currentRow, colYField), yfield);
-    uat_model_->setData(uat_model_->index(currentRow, colSMAPeriod), val_to_str_const(moving_average, moving_avg_vs, "None"));
+    uat_model_->setData(uat_model_->index(currentRow, colSMAPeriod), val_to_str_const((guint32) moving_average, moving_avg_vs, "None"));
 
     // due to an EditTrigger, this will also start editing.
     ui->graphUat->setCurrentIndex(new_index);
@@ -532,11 +535,11 @@ void IOGraphDialog::addDefaultGraph(bool enabled, int idx)
 {
     switch (idx % 2) {
     case 0:
-        addGraph(enabled, tr("All packets"), QString(), ColorUtils::graphColor(idx),
+        addGraph(enabled, tr("All Packets"), QString(), ColorUtils::graphColor(idx),
                  IOGraph::psLine, IOG_ITEM_UNIT_PACKETS, QString(), DEFAULT_MOVING_AVERAGE);
         break;
     default:
-        addGraph(enabled, tr("TCP errors"), "tcp.analysis.flags", ColorUtils::graphColor(idx),
+        addGraph(enabled, tr("TCP Errors"), "tcp.analysis.flags", ColorUtils::graphColor(4), // 4 = red
                  IOGraph::psBar, IOG_ITEM_UNIT_PACKETS, QString(), DEFAULT_MOVING_AVERAGE);
         break;
     }
@@ -1884,7 +1887,7 @@ void IOGraph::recalcGraphData(capture_file *cap_file, bool enable_scaling)
     unsigned int mavg_in_average_count = 0, mavg_left = 0, mavg_right = 0;
     unsigned int mavg_to_remove = 0, mavg_to_add = 0;
     double mavg_cumulated = 0;
-    QCPAxis *x_axis = NULL;
+    QCPAxis *x_axis = nullptr;
 
     if (graph_) {
         graph_->data()->clear();
@@ -1927,8 +1930,17 @@ void IOGraph::recalcGraphData(capture_file *cap_file, bool enable_scaling)
             ts += start_time_;
         }
         double val = getItemValue(i, cap_file);
+        // Should we show this value? Yes, if
+        // - It's for a line or bar graph
+        // - It's a scatter plot with a calculated value.
+        bool show_value = val != 0.0 || (graph_ && graph_->scatterStyle().shape() == QCPScatterStyle::ssNone);
+
+        if (val_units_ >= IOG_ITEM_UNIT_CALC_SUM) {
+            show_value = true;
+        }
 
         if (moving_avg_period_ > 0) {
+            show_value = true;
             if (i != 0) {
                 mavg_left++;
                 if (mavg_left > moving_avg_period_ / 2) {
@@ -1950,7 +1962,7 @@ void IOGraph::recalcGraphData(capture_file *cap_file, bool enable_scaling)
             }
         }
 
-        if (graph_) {
+        if (graph_ && show_value) {
             graph_->addData(ts, val);
         }
         if (bars_) {
index cb1a2dbca42f922214a90d6f31c92c74a5d28fbf..b29c17845c8275a6d91330e7571bbf955331620c 100644 (file)
@@ -135,7 +135,7 @@ public:
 
     enum UatColumns { colEnabled = 0, colName, colDFilter, colColor, colStyle, colYAxis, colYField, colSMAPeriod, colMaxNum};
 
-    void addGraph(bool checked, QString name, QString dfilter, int color_idx, IOGraph::PlotStyles style,
+    void addGraph(bool checked, QString name, QString dfilter, QRgb color_idx, IOGraph::PlotStyles style,
                   io_graph_item_unit_t value_units, QString yfield, int moving_average);
     void addGraph(bool copy_from_current = false);
     void addDefaultGraph(bool enabled, int idx = 0);