Skip to content

Commit

Permalink
refactor: reorganize the box component
Browse files Browse the repository at this point in the history
  • Loading branch information
YiNNx committed Sep 1, 2024
1 parent 55a853a commit ad7fb59
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 123 deletions.
109 changes: 38 additions & 71 deletions src/stats.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use chrono::{DateTime, Datelike, Duration, Local, NaiveDate, Timelike};
use colored::*;
use num_traits::cast::FromPrimitive;
use std::collections::HashMap;

use crate::{
parser::Command,
view::{View, Window, STR_MONTH, STR_WEEKDAY},
view::{Component, View, STR_WEEKDAY},
};

#[derive(Default)]
Expand Down Expand Up @@ -268,50 +267,25 @@ impl Statistic {
View::wait();
}

pub fn daytime_graph(list: &[usize]) -> String {
let mut res = String::new();

let max = list.iter().max().copied().unwrap_or_default();
for row in 0..=4 {
let mut s = String::new();
for hour in 0..list.len() {
let h = (6 + hour) % list.len();
s += if (max / 5) * (4 - row) < list[h] {
"▉ "
} else {
" "
}
}
res += &s.cyan().to_string();
res += " \n";
}
res += &format!("{}\n", "-".repeat(48));
res += "6 8 10 12 14 16 18 20 22 0 2 4 \n";
res
}

pub fn output_recent(&self) {
let mut window = Window::new(61, 6, View::display);
window.edge();
window.break_line();

window.content(&format!(
"{:<71}",
&format!(
"Today - {} commands / {} unique commands",
self.today_command_count.to_string().green().bold(),
self.map_command_daily.len().to_string().green().bold()
)
let mut component = Component::new(61, 6, View::display);
component.edge();
component.break_line();

component.content(&format!(
"Today - {} commands / {} unique commands",
self.today_command_count,
self.map_command_daily.len()
));
window.break_line();
component.break_line();

let today = Self::daytime_graph(&self.list_daytime_today);
window.content(&today);
window.break_line();
component.daytime_graph(&self.list_daytime_today);
component.break_line();

let mut fav_commands: Vec<_> = self.map_command_daily.iter().collect();
fav_commands.sort_by(|a, b| b.1.cmp(a.1));
let top_fav_commands: Vec<_> = fav_commands.iter().take(5).collect();

let max = top_fav_commands
.first()
.map(|(_, b)| **b)
Expand All @@ -322,50 +296,43 @@ impl Statistic {
.max()
.unwrap_or_default();
for (command, &count) in top_fav_commands {
window.content(&View::histogram_command(command, count, max, len_max))
component.command_rank(command, count, max, len_max);
}

window.break_line();
window.edge();
window.break_line();
window.padding(4);

window.content(&format!(
"{:<75}",
&format!(
"This year - {} commands / {} unique commands",
self.command_count.to_string().green().bold(),
self.map_command_annual.len().to_string().green().bold()
)
component.break_line();
component.edge();
component.padding(4);
component.break_line();

component.content(&format!(
"This year - {} commands / {} unique commands",
self.command_count,
self.map_command_annual.len()
));
window.break_line();
component.break_line();

window.content(&View::graph2(&self.list_day));
window.break_line();
component.graph2(&self.list_day);
component.break_line();

let month = Local::now().month0() as isize;
for m in (month - 1..=month).rev() {
if m < 0 {
continue;
}
window.content(&format!(
"○ {} - {} commands / {} unique commands",
STR_MONTH[m as usize].trim(),
let mut monthly_commands: Vec<_> =
self.map_command_monthly[m as usize].iter().collect();
monthly_commands.sort_by(|a, b| b.1.cmp(a.1));
let fav_commands: Vec<_> = monthly_commands.iter().take(4).cloned().collect();
component.monthly_stat(
m,
self.list_month[m as usize],
self.map_command_monthly[m as usize].len()
));
window.content("│");
let mut fav_command: Vec<_> = self.map_command_monthly[m as usize].iter().collect();
fav_command.sort_by(|a, b| b.1.cmp(a.1));
for (command, &count) in fav_command.iter().take(4) {
window.content(&format!("• {:<44}{:<5} ", command.green().bold(), count));
}
if m == month {
window.content("│");
}
self.map_command_monthly[m as usize].len(),
fav_commands,
m != month,
);
}

window.break_line();
window.edge();
component.break_line();
component.edge();
}
}
153 changes: 101 additions & 52 deletions src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,34 +186,6 @@ impl View {
res
}

pub fn graph2(graph_list: &[usize]) -> String {
let mut res = String::new();
for str_month in STR_MONTH {
res += str_month;
}
res += "\n";
for i in 0..=6 {
for j in 0..=52 {
let ordinal = i + j * 7;
if ordinal >= 365 {
res += " "
} else {
res += &format!(
"{}",
match graph_list[ordinal] {
0 => " ".normal(),
1..=30 => "●".cyan().dimmed(),
31..=50 => "●".cyan(),
_ => "●".bright_cyan().bold(),
}
)
}
}
res += "\n";
}
res
}

pub fn histogram<T: ToString>(index: T, count: usize, max: usize) {
Self::typewriter_for_line(&format!(
"{:<3} {}| {}",
Expand All @@ -223,26 +195,6 @@ impl View {
));
}

pub fn histogram_command<T: ToString>(
index: T,
count: usize,
max: usize,
len_max: usize,
) -> String {
format!(
"{:<len$} {:<len2$}",
index.to_string().green().bold(),
"▮"
.repeat((count as f64 * ((41 - len_max) as f64 / max as f64)) as usize)
.dimmed()
.to_string()
+ " "
+ &count.to_string(),
len = len_max,
len2 = 55 - len_max,
)
}

pub fn histogram_with_total<T: ToString>(index: T, count: usize, total: usize, max: usize) {
if count == 0 {
return;
Expand Down Expand Up @@ -277,16 +229,16 @@ impl View {
}
}

pub struct Window {
pub struct Component {
width: usize,
padding: usize,
display: fn(&str),
}

impl Window {
pub fn new(width: usize, padding: usize, fn_display: fn(&str)) -> Window {
impl Component {
pub fn new(width: usize, padding: usize, fn_display: fn(&str)) -> Component {
View::line_break();
Window {
Component {
width,
padding,
display: fn_display,
Expand Down Expand Up @@ -316,4 +268,101 @@ impl Window {
))
}
}

pub fn daytime_graph(&self, list: &[usize]) {
let mut output = String::new();
let max = list.iter().max().copied().unwrap_or_default();
for row in 0..=4 {
let mut line = String::new();
for hour in 0..list.len() {
let h = (6 + hour) % list.len();
line += if (max / 5) * (4 - row) < list[h] {
"▉ "
} else {
" "
}
}
output += &line.cyan().dimmed().to_string();
output += " \n";
}
output += &format!("{}\n", "-".repeat(48));
output += "6 8 10 12 14 16 18 20 22 0 2 4 \n";
self.content(&output)
}

pub fn command_rank<T: ToString>(
&self,
index: T,
current_count: usize,
max_count: usize,
command_padding: usize,
) {
let bar_max_len = self.width - 20;
self.content(&format!(
"{:<command_padding$} {:<right_len$}",
index.to_string().green().bold(),
"▮"
.repeat(
(current_count as f64
* ((bar_max_len - command_padding) as f64 / max_count as f64))
as usize
)
.dimmed()
.to_string()
+ " "
+ &current_count.to_string(),
right_len = self.width - 6 - command_padding,
))
}

pub fn graph2(&self, graph_list: &[usize]) {
let mut output = String::new();
for str_month in STR_MONTH {
output += str_month;
}
output += "\n";
for i in 0..=6 {
for j in 0..=52 {
let ordinal = i + j * 7;
if ordinal >= 365 {
output += " "
} else {
output += &format!(
"{}",
match graph_list[ordinal] {
0 => " ".normal(),
1..=20 => "●".cyan().dimmed(),
21..=50 => "●".cyan(),
_ => "●".bright_cyan(),
}
)
}
}
output += "\n";
}
self.content(&output)
}

pub fn monthly_stat(
&self,
month: isize,
command_count: usize,
unique_count: usize,
fav_commands: Vec<(&String, &usize)>,
end: bool,
) {
self.content(&format!(
"○ {} - {} commands / {} unique commands",
STR_MONTH[month as usize].trim(),
command_count,
unique_count
));
self.content("│");
for (command, &count) in fav_commands {
self.content(&format!("• {:<44}{:<6}", command.green().bold(), count));
}
if !end {
self.content("│");
}
}
}

0 comments on commit ad7fb59

Please sign in to comment.