"Fossies" - the Fresh Open Source Software Archive

Member "tcpflow-1.6.1/src/netviz/address_histogram_view.cpp" (19 Feb 2021, 6002 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 "address_histogram_view.cpp" see the Fossies "Dox" file reference documentation.

    1 /**
    2  * address_histogram_view.cpp: 
    3  * Show packets received vs addr
    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 <math.h>
   17 #include <iomanip>
   18 
   19 #include "address_histogram_view.h"
   20 
   21 using namespace std;
   22 
   23 address_histogram_view::address_histogram_view(const address_histogram &histogram_) :
   24     histogram(histogram_), bar_color(0.0, 0.0, 0.0), cdf_color(0.0, 0.0, 0.0)
   25 {
   26     subtitle = "";
   27     title_on_bottom = true;
   28     pad_left_factor = 0.1;
   29     pad_right_factor = 0.1;
   30     pad_top_factor = 0.5;
   31     x_label = "";
   32     y_label = "";
   33     y_tick_font_size = 6.0;
   34     right_tick_font_size = 6.0;
   35 }
   36 
   37 const double address_histogram_view::bar_space_factor = 1.2;
   38 const size_t address_histogram_view::compressed_ip6_str_max_len = 16;
   39 const double address_histogram_view::cdf_line_width = 0.5;
   40 const double address_histogram_view::data_width_factor = 0.85;
   41 
   42 void address_histogram_view::render(cairo_t *cr, const bounds_t &bounds)
   43 {
   44     y_tick_labels.push_back(plot_view::pretty_byte_total(0));
   45     if(histogram.size() > 0) {
   46         y_tick_labels.push_back(plot_view::pretty_byte_total(histogram.at(0).count, 0));
   47     }
   48 
   49     right_tick_labels.push_back("0%");
   50     right_tick_labels.push_back("100%");
   51 
   52     plot_view::render(cr, bounds);
   53 }
   54 
   55 void address_histogram_view::render_data(cairo_t *cr, const bounds_t &bounds)
   56 {
   57     if(histogram.size() < 1 || histogram.at(0).count == 0) {
   58         return;
   59     }
   60 
   61     double data_width = bounds.width * data_width_factor;
   62     double data_offset = 0;
   63     bounds_t data_bounds(bounds.x + data_offset, bounds.y,
   64             data_width, bounds.height);
   65 
   66     double offset_unit = data_bounds.width / histogram.size();
   67     double bar_width = offset_unit / bar_space_factor;
   68     double space_width = (offset_unit - bar_width) / 2.0;
   69     uint64_t greatest = histogram.at(0).count;
   70     unsigned int index = 0;
   71 
   72     double cdf_last_x = bounds.x, cdf_last_y = bounds.y + data_bounds.height;
   73     for(address_histogram::ipt_addrs::const_iterator it = histogram.begin();
   74             it != histogram.end(); it++) {
   75     double bar_height = (((double) it->count) / ((double) greatest)) * data_bounds.height;
   76 
   77         // bar
   78         double bar_x = data_bounds.x + (index * offset_unit + space_width);
   79         double bar_y = data_bounds.y + (data_bounds.height - bar_height);
   80         bounds_t bar_bounds(bar_x, bar_y, bar_width, bar_height);
   81 
   82         bucket_view view(*it, bar_color);
   83         view.render(cr, bar_bounds);
   84 
   85         // CDF
   86         double cdf_x = cdf_last_x + offset_unit;
   87         // account for left and right padding of bars
   88         if(index == 0) {
   89             cdf_x += data_offset;
   90         }
   91         if(index == histogram.size() - 1) {
   92             cdf_x = bounds.x + bounds.width;
   93         }
   94         double cdf_y = cdf_last_y - ((double) it->count / (double) histogram.ingest_count()) *
   95                 data_bounds.height;
   96 
   97         cairo_move_to(cr, cdf_last_x, cdf_last_y);
   98         // don't draw over the left-hand y axis
   99         if(index == 0) {
  100             cairo_move_to(cr, cdf_last_x, cdf_y);
  101         }
  102         else {
  103             cairo_line_to(cr, cdf_last_x, cdf_y);
  104         }
  105         cairo_line_to(cr, cdf_x, cdf_y);
  106 
  107         cairo_set_source_rgb(cr, cdf_color.r, cdf_color.g, cdf_color.b);
  108         cairo_set_line_width(cr, cdf_line_width);
  109         cairo_stroke(cr);
  110 
  111         cdf_last_x = cdf_x;
  112         cdf_last_y = cdf_y;
  113 
  114     index++;
  115     }
  116     index = 0;
  117     // labels must be done after the fact to avoid awkward interaction with the CDF
  118     for(address_histogram::ipt_addrs::const_iterator it = histogram.begin();
  119             it != histogram.end(); it++) {
  120     double bar_height = (((double) it->count) / ((double) greatest)) * data_bounds.height;
  121         double bar_x = data_bounds.x + (index * offset_unit + space_width);
  122         double bar_y = data_bounds.y + (data_bounds.height - bar_height);
  123         bounds_t bar_bounds(bar_x, bar_y, bar_width, bar_height);
  124         bucket_view view(*it, bar_color);
  125         view.render_label(cr, bar_bounds);
  126         index++;
  127     }
  128 }
  129 
  130 const address_histogram &address_histogram_view::get_data() const
  131 {
  132     return histogram;
  133 }
  134 
  135 string address_histogram_view::compressed_ip6_str(iptree::addr_elem address)
  136 {
  137     return ssprintf("%x:%x...%x", (address.addr[0] << 8) + address.addr[1],
  138             (address.addr[2] << 8) + address.addr[3],
  139             (address.addr[14] << 8) + address.addr[15]);
  140 }
  141 
  142 // bucket view
  143 
  144 const double address_histogram_view::bucket_view::label_font_size = 6.0;
  145 
  146 void address_histogram_view::bucket_view::render(cairo_t *cr, const bounds_t &bounds)
  147 {
  148     cairo_set_source_rgb(cr, color.r, color.g, color.b);
  149     cairo_rectangle(cr, bounds.x, bounds.y, bounds.width, bounds.height);
  150     cairo_fill(cr);
  151 }
  152 
  153 void address_histogram_view::bucket_view::render_label(cairo_t *cr, const bounds_t &bounds)
  154 {
  155     cairo_matrix_t unrotated_matrix;
  156     cairo_get_matrix(cr, &unrotated_matrix);
  157     cairo_rotate(cr, -M_PI / 4.0);
  158 
  159     string label = bucket.str();
  160     if(!bucket.is4() && label.length() > compressed_ip6_str_max_len) {
  161         label = compressed_ip6_str(bucket);
  162     }
  163 
  164     cairo_set_font_size(cr, label_font_size);
  165 
  166     cairo_text_extents_t label_extents;
  167     cairo_text_extents(cr, label.c_str(), &label_extents);
  168 
  169     double label_x = bounds.x + bounds.width / 2.0;
  170     double label_y = bounds.y - 2.0;
  171     cairo_device_to_user(cr, &label_x, &label_y);
  172 
  173     cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
  174     cairo_rectangle(cr, label_x, label_y, label_extents.width, -label_extents.height);
  175     cairo_fill(cr);
  176     cairo_rectangle(cr, label_x, label_y, label_extents.width, -label_extents.height);
  177     cairo_set_line_width(cr, 2.0);
  178     cairo_stroke(cr);
  179 
  180     cairo_move_to(cr, label_x, label_y);
  181 
  182     cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  183     cairo_show_text(cr, label.c_str());
  184 
  185     cairo_set_matrix(cr, &unrotated_matrix);
  186 }
  187 
  188 #endif