"Fossies" - the Fresh Open Source Software Archive

Member "tcpflow-1.6.1/src/netviz/port_histogram_view.cpp" (19 Feb 2021, 6615 Bytes) of package /linux/misc/tcpflow-1.6.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "port_histogram_view.cpp" see the Fossies "Dox" file reference documentation.

    1 /**
    2  * port_histogram_view.cpp: 
    3  * Show packets received vs port
    4  *
    5  * This source file is public domain, as it is not based on the original tcpflow.
    6  *
    7  * Author: Michael Shick <mike@shick.in>
    8  *
    9  */
   10 
   11 #include "config.h"
   12 
   13 #ifdef HAVE_LIBCAIRO
   14 #include "tcpflow.h"
   15 
   16 #include "port_histogram_view.h"
   17 
   18 #include <math.h>
   19 
   20 using namespace std;
   21 
   22 port_histogram_view::port_histogram_view(port_histogram &histogram_,
   23         const map<in_port_t, rgb_t> &color_map_, const rgb_t &default_color_,
   24         const rgb_t &cdf_color_) :
   25     histogram(histogram_), color_map(color_map_), default_color(default_color_),
   26     cdf_color(cdf_color_)
   27 {
   28     subtitle = "";
   29     title_on_bottom = true;
   30     pad_left_factor = 0.1;
   31     pad_right_factor = 0.1;
   32     x_label = "";
   33     y_label = "";
   34     y_tick_font_size = 6.0;
   35     right_tick_font_size = 6.0;
   36 }
   37 
   38 const double port_histogram_view::bar_space_factor = 1.2;
   39 const double port_histogram_view::bar_chip_size_factor = 0.04;
   40 const double port_histogram_view::cdf_line_width = 0.5;
   41 const double port_histogram_view::data_width_factor = 0.95;
   42 
   43 void port_histogram_view::render(cairo_t *cr, const plot_view::bounds_t &bounds)
   44 {
   45     y_tick_labels.push_back(plot_view::pretty_byte_total(0));
   46     if(histogram.size() > 0) {
   47         y_tick_labels.push_back(plot_view::pretty_byte_total(histogram.at(0).count, 0));
   48     }
   49 
   50     right_tick_labels.push_back("0%");
   51     right_tick_labels.push_back("100%");
   52 
   53     plot_view::render(cr, bounds);
   54 }
   55 
   56 void port_histogram_view::render_data(cairo_t *cr, const plot_view::bounds_t &bounds)
   57 {
   58     if(histogram.size() < 1 || histogram.at(0).count == 0) {
   59         return;
   60     }
   61 
   62     double data_width = bounds.width * data_width_factor;
   63     double data_offset = 0;
   64     bounds_t data_bounds(bounds.x + data_offset, bounds.y,
   65             data_width, bounds.height);
   66 
   67     double visibility_chip_height = data_bounds.height * bar_chip_size_factor;
   68     double offset_unit = data_bounds.width / histogram.size();
   69     double bar_width = offset_unit / bar_space_factor;
   70     double space_width = (offset_unit - bar_width) / 2.0;
   71     uint64_t greatest = histogram.at(0).count;
   72     unsigned int index = 0;
   73 
   74     double cdf_last_x = bounds.x, cdf_last_y = bounds.y + data_bounds.height;
   75     for(vector<port_histogram::port_count>::const_iterator it = histogram.begin();
   76             it != histogram.end(); it++) {
   77     double bar_height = (((double) it->count) / ((double) greatest)) * data_bounds.height;
   78 
   79         // bar
   80         double bar_x = data_bounds.x + (index * offset_unit + space_width);
   81         double bar_y = data_bounds.y + (data_bounds.height - bar_height);
   82         bounds_t bar_bounds(bar_x, bar_y, bar_width, bar_height);
   83 
   84         rgb_t bar_color = default_color;
   85         map<in_port_t, rgb_t>::const_iterator color = color_map.find(it->port);
   86         if(color != color_map.end()) {
   87             bar_color = color->second;
   88         }
   89 
   90         bucket_view view(*it, bar_color);
   91 
   92         if(bar_height < visibility_chip_height && bar_color != default_color) {
   93             view.chip_height = visibility_chip_height;
   94             view.chip_offset = visibility_chip_height * 0.6;
   95         }
   96 
   97         view.render(cr, bar_bounds);
   98 
   99         // CDF
  100         double cdf_x = cdf_last_x + offset_unit;
  101         // account for left and right padding of bars
  102         if(index == 0) {
  103             cdf_x += data_offset;
  104         }
  105         if(index == histogram.size() - 1) {
  106             cdf_x = bounds.x + bounds.width;
  107         }
  108         double cdf_y = cdf_last_y - ((double) it->count / (double) histogram.ingest_count()) *
  109                 data_bounds.height;
  110 
  111         cairo_move_to(cr, cdf_last_x, cdf_last_y);
  112         // don't draw over the left-hand y axis
  113         if(index == 0) {
  114             cairo_move_to(cr, cdf_last_x, cdf_y);
  115         }
  116         else {
  117             cairo_line_to(cr, cdf_last_x, cdf_y);
  118         }
  119         cairo_line_to(cr, cdf_x, cdf_y);
  120 
  121         cairo_set_source_rgb(cr, cdf_color.r, cdf_color.g, cdf_color.b);
  122         cairo_set_line_width(cr, cdf_line_width);
  123         cairo_stroke(cr);
  124 
  125         cdf_last_x = cdf_x;
  126         cdf_last_y = cdf_y;
  127 
  128     index++;
  129     }
  130     index = 0;
  131     // labels must be done after the fact to avoid awkward interaction with the CDF
  132     for(vector<port_histogram::port_count>::const_iterator it = histogram.begin();
  133             it != histogram.end(); it++) {
  134     double bar_height = (((double) it->count) / ((double) greatest)) * data_bounds.height;
  135 
  136         double bar_x = data_bounds.x + (index * offset_unit + space_width);
  137         double bar_y = data_bounds.y + (data_bounds.height - bar_height);
  138         bounds_t bar_bounds(bar_x, bar_y, bar_width, bar_height);
  139 
  140         // bar label
  141         bucket_view view(*it, default_color);
  142         view.render_label(cr, bar_bounds);
  143 
  144     index++;
  145     }
  146 }
  147 
  148 port_histogram &port_histogram_view::get_data()
  149 {
  150     return histogram;
  151 }
  152 
  153 // bucket view
  154 
  155 const double port_histogram_view::bucket_view::label_font_size = 6.0;
  156 const double port_histogram_view::bucket_view::chip_width_factor = 0.4;
  157 
  158 void port_histogram_view::bucket_view::render(cairo_t *cr, const bounds_t &bounds)
  159 {
  160     cairo_set_source_rgb(cr, color.r, color.g, color.b);
  161     cairo_rectangle(cr, bounds.x, bounds.y, bounds.width, bounds.height);
  162     cairo_fill(cr);
  163     if(chip_height > 0.0) {
  164         double chip_x = bounds.x + (bounds.width * ((1.0 - chip_width_factor) / 2.0));
  165         double chip_y = bounds.y + bounds.height + chip_offset;
  166         double chip_width = bounds.width * chip_width_factor;
  167 
  168         cairo_rectangle(cr, chip_x, chip_y, chip_width, chip_height);
  169         cairo_fill(cr);
  170     }
  171 }
  172 
  173 void port_histogram_view::bucket_view::render_label(cairo_t *cr, const bounds_t &bounds)
  174 {
  175     cairo_matrix_t unrotated_matrix;
  176     cairo_get_matrix(cr, &unrotated_matrix);
  177     cairo_rotate(cr, -M_PI / 4.0);
  178 
  179     cairo_set_font_size(cr, label_font_size);
  180     string label = ssprintf("%d", bucket.port);
  181 
  182     cairo_text_extents_t label_extents;
  183     cairo_text_extents(cr, label.c_str(), &label_extents);
  184 
  185     double label_x = bounds.x + bounds.width / 2.0;
  186     double label_y = bounds.y - 2.0;
  187     cairo_device_to_user(cr, &label_x, &label_y);
  188 
  189     cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
  190     cairo_rectangle(cr, label_x, label_y, label_extents.width, -label_extents.height);
  191     cairo_fill(cr);
  192     cairo_rectangle(cr, label_x, label_y, label_extents.width, -label_extents.height);
  193     cairo_set_line_width(cr, 2.0);
  194     cairo_stroke(cr);
  195 
  196     cairo_move_to(cr, label_x, label_y);
  197     cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  198     cairo_show_text(cr, label.c_str());
  199 
  200     cairo_set_matrix(cr, &unrotated_matrix);
  201 }
  202 #endif