"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