diff --git a/src/chart/mod.rs b/src/chart/mod.rs index d1f30755..cd408564 100644 --- a/src/chart/mod.rs +++ b/src/chart/mod.rs @@ -1,2 +1 @@ -pub mod manage_chart_data; pub mod types; diff --git a/src/chart/manage_chart_data.rs b/src/chart/types/chart_series.rs similarity index 69% rename from src/chart/manage_chart_data.rs rename to src/chart/types/chart_series.rs index f194672e..72928a11 100644 --- a/src/chart/manage_chart_data.rs +++ b/src/chart/types/chart_series.rs @@ -1,145 +1,5 @@ -use crate::TrafficChart; -use crate::networking::types::data_representation::DataRepr; -use crate::networking::types::info_traffic::InfoTraffic; use splines::{Interpolation, Key, Spline}; -impl TrafficChart { - pub fn update_charts_data(&mut self, info_traffic_msg: &InfoTraffic, no_more_packets: bool) { - self.no_more_packets = no_more_packets; - - if self.ticks == 0 { - self.first_packet_timestamp = info_traffic_msg.last_packet_timestamp; - } - - #[allow(clippy::cast_precision_loss)] - let tot_seconds = self.ticks as f32; - self.ticks += 1; - - #[allow(clippy::cast_precision_loss)] - let out_bytes_entry = -(info_traffic_msg - .tot_data_info - .outgoing_data(DataRepr::Bytes) as f32); - #[allow(clippy::cast_precision_loss)] - let in_bytes_entry = info_traffic_msg - .tot_data_info - .incoming_data(DataRepr::Bytes) as f32; - #[allow(clippy::cast_precision_loss)] - let out_packets_entry = -(info_traffic_msg - .tot_data_info - .outgoing_data(DataRepr::Packets) as f32); - #[allow(clippy::cast_precision_loss)] - let in_packets_entry = info_traffic_msg - .tot_data_info - .incoming_data(DataRepr::Packets) as f32; - - let out_bytes_point = (tot_seconds, out_bytes_entry); - let in_bytes_point = (tot_seconds, in_bytes_entry); - let out_packets_point = (tot_seconds, out_packets_entry); - let in_packets_point = (tot_seconds, in_packets_entry); - - // update sent bytes traffic data - update_series( - &mut self.out_bytes, - out_bytes_point, - self.is_live_capture, - no_more_packets, - ); - self.min_bytes = get_min(&self.out_bytes); - - // update received bytes traffic data - update_series( - &mut self.in_bytes, - in_bytes_point, - self.is_live_capture, - no_more_packets, - ); - self.max_bytes = get_max(&self.in_bytes); - - // update sent packets traffic data - update_series( - &mut self.out_packets, - out_packets_point, - self.is_live_capture, - no_more_packets, - ); - self.min_packets = get_min(&self.out_packets); - - // update received packets traffic data - update_series( - &mut self.in_packets, - in_packets_point, - self.is_live_capture, - no_more_packets, - ); - self.max_packets = get_max(&self.in_packets); - } - - pub fn push_offline_gap_to_splines(&mut self, gap: u32) { - for i in 0..gap { - #[allow(clippy::cast_precision_loss)] - let point = ((self.ticks + i) as f32, 0.0); - update_series(&mut self.in_bytes, point, false, false); - update_series(&mut self.out_bytes, point, false, false); - update_series(&mut self.in_packets, point, false, false); - update_series(&mut self.out_packets, point, false, false); - } - self.ticks += gap; - } -} - -fn update_series( - series: &mut ChartSeries, - point: (f32, f32), - is_live_capture: bool, - no_more_packets: bool, -) { - // update spline - let spline = &mut series.spline; - let key = Key::new(point.0, point.1, Interpolation::Cosine); - if spline.len() >= 30 { - spline.remove(0); - } - spline.add(key); - - // if offline capture, update all time data - if !is_live_capture { - let all_time = &mut series.all_time; - all_time.push(point); - - // if we reached the end of the PCAP, reduce all time data into spline - if no_more_packets { - reduce_all_time_data(all_time); - let keys = all_time - .iter() - .map(|p| Key::new(p.0, p.1, Interpolation::Cosine)) - .collect(); - *spline = Spline::from_vec(keys); - } - } -} - -/// Finds the minimum y value to be displayed in chart. -fn get_min(serie: &ChartSeries) -> f32 { - let mut min = 0.0; - for key in &serie.spline { - if key.value < min { - min = key.value; - } - } - min -} - -/// Finds the maximum y value to be displayed in chart. -fn get_max(serie: &ChartSeries) -> f32 { - let mut max = 0.0; - for key in &serie.spline { - if key.value > max { - max = key.value; - } - } - max -} - #[derive(Default, Clone)] pub struct ChartSeries { /// Series to be displayed DURING live/offline capture @@ -148,6 +8,61 @@ pub struct ChartSeries { pub all_time: Vec<(f32, f32)>, } +impl ChartSeries { + pub(super) fn update_series( + &mut self, + point: (f32, f32), + is_live_capture: bool, + no_more_packets: bool, + ) { + // update spline + let spline = &mut self.spline; + let key = Key::new(point.0, point.1, Interpolation::Cosine); + if spline.len() >= 30 { + spline.remove(0); + } + spline.add(key); + + // if offline capture, update all time data + if !is_live_capture { + let all_time = &mut self.all_time; + all_time.push(point); + + // if we reached the end of the PCAP, reduce all time data into spline + if no_more_packets { + reduce_all_time_data(all_time); + let keys = all_time + .iter() + .map(|p| Key::new(p.0, p.1, Interpolation::Cosine)) + .collect(); + *spline = Spline::from_vec(keys); + } + } + } + + /// Finds the minimum y value to be displayed in chart. + pub(super) fn get_min(&self) -> f32 { + let mut min = 0.0; + for key in &self.spline { + if key.value < min { + min = key.value; + } + } + min + } + + /// Finds the maximum y value to be displayed in chart. + pub(super) fn get_max(&self) -> f32 { + let mut max = 0.0; + for key in &self.spline { + if key.value > max { + max = key.value; + } + } + max + } +} + fn reduce_all_time_data(all_time: &mut Vec<(f32, f32)>) { // bisect data until we have less than 150 points while all_time.len() > 150 { @@ -219,7 +134,7 @@ fn reduce_all_time_data(all_time: &mut Vec<(f32, f32)>) { mod tests { use splines::{Interpolation, Key, Spline}; - use crate::chart::manage_chart_data::{ChartSeries, get_max, get_min}; + use crate::chart::chart_series::{ChartSeries, get_max, get_min}; use crate::networking::types::data_info::DataInfo; use crate::networking::types::data_representation::DataRepr; use crate::utils::types::timestamp::Timestamp; diff --git a/src/chart/types/mod.rs b/src/chart/types/mod.rs index c84d0fef..547b19cd 100644 --- a/src/chart/types/mod.rs +++ b/src/chart/types/mod.rs @@ -1,2 +1,3 @@ +pub mod chart_series; pub mod donut_chart; pub mod traffic_chart; diff --git a/src/chart/types/traffic_chart.rs b/src/chart/types/traffic_chart.rs index 977cf3b2..658366ae 100644 --- a/src/chart/types/traffic_chart.rs +++ b/src/chart/types/traffic_chart.rs @@ -10,12 +10,13 @@ use plotters_iced::{Chart, ChartBuilder, ChartWidget, DrawingBackend}; use splines::{Interpolation, Key, Spline}; -use crate::chart::manage_chart_data::ChartSeries; +use crate::chart::types::chart_series::ChartSeries; use crate::gui::sniffer::FONT_FAMILY_NAME; use crate::gui::styles::style_constants::CHARTS_LINE_BORDER; use crate::gui::styles::types::palette::to_rgb_color; use crate::gui::types::message::Message; use crate::networking::types::data_representation::DataRepr; +use crate::networking::types::info_traffic::InfoTraffic; use crate::networking::types::traffic_direction::TrafficDirection; use crate::translations::translations::{incoming_translation, outgoing_translation}; use crate::utils::error_logger::{ErrorLogger, Location}; @@ -81,6 +82,72 @@ pub fn new(style: StyleType, language: Language, data_repr: DataRepr) -> Self { } } + pub fn update_charts_data(&mut self, info_traffic_msg: &InfoTraffic, no_more_packets: bool) { + self.no_more_packets = no_more_packets; + + if self.ticks == 0 { + self.first_packet_timestamp = info_traffic_msg.last_packet_timestamp; + } + + #[allow(clippy::cast_precision_loss)] + let tot_seconds = self.ticks as f32; + self.ticks += 1; + + #[allow(clippy::cast_precision_loss)] + let out_bytes_entry = -(info_traffic_msg + .tot_data_info + .outgoing_data(DataRepr::Bytes) as f32); + #[allow(clippy::cast_precision_loss)] + let in_bytes_entry = info_traffic_msg + .tot_data_info + .incoming_data(DataRepr::Bytes) as f32; + #[allow(clippy::cast_precision_loss)] + let out_packets_entry = -(info_traffic_msg + .tot_data_info + .outgoing_data(DataRepr::Packets) as f32); + #[allow(clippy::cast_precision_loss)] + let in_packets_entry = info_traffic_msg + .tot_data_info + .incoming_data(DataRepr::Packets) as f32; + + let out_bytes_point = (tot_seconds, out_bytes_entry); + let in_bytes_point = (tot_seconds, in_bytes_entry); + let out_packets_point = (tot_seconds, out_packets_entry); + let in_packets_point = (tot_seconds, in_packets_entry); + + // update sent bytes traffic data + self.out_bytes + .update_series(out_bytes_point, self.is_live_capture, no_more_packets); + self.out_bytes.get_min(); + + // update received bytes traffic data + self.in_bytes + .update_series(in_bytes_point, self.is_live_capture, no_more_packets); + self.in_bytes.get_max(); + + // update sent packets traffic data + self.out_packets + .update_series(out_packets_point, self.is_live_capture, no_more_packets); + self.out_packets.get_min(); + + // update received packets traffic data + self.in_packets + .update_series(in_packets_point, self.is_live_capture, no_more_packets); + self.in_packets.get_max(); + } + + pub fn push_offline_gap_to_splines(&mut self, gap: u32) { + for i in 0..gap { + #[allow(clippy::cast_precision_loss)] + let point = ((self.ticks + i) as f32, 0.0); + self.in_bytes.update_series(point, false, false); + self.out_bytes.update_series(point, false, false); + self.in_packets.update_series(point, false, false); + self.out_packets.update_series(point, false, false); + } + self.ticks += gap; + } + pub fn view(&self) -> Element<'_, Message, StyleType> { let x_labels = if self.is_live_capture || self.thumbnail { None