refactor ChartSeries

This commit is contained in:
GyulyVGC
2025-12-13 15:31:12 +01:00
parent 60a3e9af8e
commit f59964ac99
4 changed files with 125 additions and 143 deletions

View File

@@ -1,2 +1 @@
pub mod manage_chart_data;
pub mod types;

View File

@@ -1,100 +1,22 @@
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;
}
#[derive(Default, Clone)]
pub struct ChartSeries {
/// Series to be displayed DURING live/offline capture
pub spline: Spline<f32, f32>,
/// Used to draw overall data, after the offline capture is over (not used in live captures)
pub all_time: Vec<(f32, f32)>,
}
fn update_series(
series: &mut ChartSeries,
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 series.spline;
let spline = &mut self.spline;
let key = Key::new(point.0, point.1, Interpolation::Cosine);
if spline.len() >= 30 {
spline.remove(0);
@@ -103,7 +25,7 @@ fn update_series(
// if offline capture, update all time data
if !is_live_capture {
let all_time = &mut series.all_time;
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
@@ -116,36 +38,29 @@ fn update_series(
*spline = Spline::from_vec(keys);
}
}
}
}
/// Finds the minimum y value to be displayed in chart.
fn get_min(serie: &ChartSeries) -> f32 {
/// 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 &serie.spline {
for key in &self.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 {
/// 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 &serie.spline {
for key in &self.spline {
if key.value > max {
max = key.value;
}
}
max
}
#[derive(Default, Clone)]
pub struct ChartSeries {
/// Series to be displayed DURING live/offline capture
pub spline: Spline<f32, f32>,
/// Used to draw overall data, after the offline capture is over (not used in live captures)
pub all_time: Vec<(f32, f32)>,
}
}
fn reduce_all_time_data(all_time: &mut Vec<(f32, f32)>) {
@@ -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;

View File

@@ -1,2 +1,3 @@
pub mod chart_series;
pub mod donut_chart;
pub mod traffic_chart;

View File

@@ -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