From 4850e83cb035266f5a250711129fa9573c4ad9fa Mon Sep 17 00:00:00 2001 From: Ionizing Date: Sat, 10 Aug 2024 22:35:24 +0800 Subject: [PATCH] [commands] fix colors and graph height --- src/commands/band.rs | 10 ++++----- src/commands/common.rs | 46 ++++++++++++---------------------------- src/commands/dos.rs | 8 +++---- src/commands/tdm.rs | 5 +++-- src/commands/wav1d.rs | 6 +++--- src/commands/workfunc.rs | 6 +++--- 6 files changed, 32 insertions(+), 49 deletions(-) diff --git a/src/commands/band.rs b/src/commands/band.rs index 9372588..d11a190 100644 --- a/src/commands/band.rs +++ b/src/commands/band.rs @@ -61,7 +61,6 @@ use crate::{ commands::common::{ write_array_to_txt, RawSelection, - CustomColor, } }; @@ -75,7 +74,7 @@ struct Selection { ispins: Vec, iatoms: Vec, iorbits: Vec, - color: Option, + color: Option, } @@ -509,7 +508,7 @@ impl Band { assert_eq!(kpath.len(), nkpoints); // cropped_eigvals[ispin, ikpoint, iband] let rand_color = RawSelection::get_random_color(); - let color = selection.color.clone().unwrap_or(rand_color); + let color = selection.color.clone().unwrap_or(rand_color.into()); let marker = plotly::common::Marker::new().color(color); for ispin in 0 .. nspin { @@ -794,6 +793,7 @@ impl OptProcess for Band { .tick_text(klabels) .zero_line(true) ) + .height(960) .legend(plotly::layout::Legend::new().item_sizing(ItemSizing::Constant)); Self::plot_boundaries(&mut layout, &kxs); @@ -876,7 +876,7 @@ impl OptProcess for Band { // save data - info!("Writing Bandstructure to {:?}", &self.htmlout); + info!("Writing Bandstructure to {:?}", &htmlout); for is in 0 .. nspin { let spin_label = match (is_ncl, nspin, is) { @@ -897,7 +897,7 @@ impl OptProcess for Band { write_array_to_txt(&fname, data_ref, "kpath(in_2pi) band-levels(nkpoints_x_nbands)")?; } - fs::write(&self.htmlout, plot.to_html())?; + plot.write_html(&htmlout); if self.to_inline_html { info!("Printing inline html to stdout ..."); diff --git a/src/commands/common.rs b/src/commands/common.rs index fc45526..41b8fb5 100644 --- a/src/commands/common.rs +++ b/src/commands/common.rs @@ -2,10 +2,10 @@ use std::{ io::Write, fs, path::Path, - panic::catch_unwind, fmt::Write as _, }; +use regex::Regex; use serde::{ Serialize, Deserialize, @@ -16,13 +16,7 @@ use anyhow::{ Result, Context, }; -use plotly::common::{ - ColorScalePalette, - color::{ - Color, - ColorWrapper, - }, -}; +use plotly::common::ColorScalePalette; use ndarray::Array1; use crate::types::{ @@ -65,16 +59,6 @@ const NAMED_COLORS: &[&str] = &[ ]; -#[derive(Debug, Clone)] -pub struct CustomColor (ColorWrapper); - -impl Color for CustomColor { - fn to_color(&self) -> ColorWrapper { - self.0.clone() - } -} - - const PALETTES: &[&str] = &[ "blackbody", "bluered", "blues", "cividis", "earth", "electric", "greens", "greys", "hot", "jet", @@ -275,20 +259,18 @@ bail!("[DOS]: Invalid spin component selected: `{}`, available components are `u } // Parse the color to this curve. - pub fn parse_color(input: &str) -> Result { - if NAMED_COLORS.contains(&input.to_ascii_lowercase().as_ref()) { - Ok(CustomColor(ColorWrapper::S(input.to_owned()))) - } else { - let ret = catch_unwind(|| { - input.to_color() - }); + pub fn parse_color(input: &str) -> Result { + let re_rgb = Regex::new("^#(?:[0-9a-fA-F]{3}){1,2}$").unwrap().is_match(input); + let re_argb = Regex::new("^#(?:[0-9a-fA-F]{3,4}){1,2}$").unwrap().is_match(input); - if let Ok(c) = ret { - Ok(CustomColor(c)) - } else { - bail!("The input color is neither a named color nor a valid hex code. + let input_lowercase = input.to_lowercase(); + + if NAMED_COLORS.contains(&input_lowercase.as_ref()) || + re_rgb || re_argb { + Ok(input_lowercase) + } else { + bail!("The input color is neither a named color nor a valid hex code. See \"https://developer.mozilla.org/en-US/docs/Web/CSS/color_value for availed named colors.\""); - } } } @@ -301,12 +283,12 @@ See \"https://developer.mozilla.org/en-US/docs/Web/CSS/color_value for availed n } } - pub fn get_random_color() -> CustomColor { + pub fn get_random_color() -> &'static str { use rand::Rng; let mut rng = rand::thread_rng(); let id = rng.gen_range(0 .. NAMED_COLORS.len()); - Self::parse_color(NAMED_COLORS[id]).unwrap() + NAMED_COLORS[id] } } diff --git a/src/commands/dos.rs b/src/commands/dos.rs index 2f873b9..262c32e 100644 --- a/src/commands/dos.rs +++ b/src/commands/dos.rs @@ -33,7 +33,6 @@ use crate::{ commands::common::{ RawSelection, write_array_to_txt, - CustomColor, } }; @@ -47,7 +46,7 @@ struct Selection { ikpoints: Vec, iatoms: Vec, iorbits: Vec, - color: Option, + color: Option, factor: f64, } @@ -545,11 +544,12 @@ impl OptProcess for Dos { .zero_line(true) .range_slider(plotly::layout::RangeSlider::new().visible(true)) .range(xlim) - ); + ) + .height(960); plot.set_layout(layout); info!("Writing DOS plot to {:?}", htmlout); - fs::write(&htmlout, plot.to_html())?; + plot.write_html(&htmlout); info!("Writing raw DOS data to {:?}", txtout); let label = labels.join(" "); diff --git a/src/commands/tdm.rs b/src/commands/tdm.rs index ff40778..b3c3a32 100644 --- a/src/commands/tdm.rs +++ b/src/commands/tdm.rs @@ -331,13 +331,14 @@ I suggest you provide `gamma_half` argument to avoid confusion."); .x_axis(plotly::layout::Axis::new() .title(plotly::common::Title::with_text("Energy (eV)")) .fixed_range(false)) - .hover_mode(plotly::layout::HoverMode::X); + .hover_mode(plotly::layout::HoverMode::X) + .height(960); plot.set_layout(layout); // Write html info!("Writing plot to {:?}", &self.htmlout); - fs::write(&self.htmlout, plot.to_html())?; + plot.write_html(&self.htmlout); if self.to_inline_html { info!("Printing inline HTML to stdout ..."); diff --git a/src/commands/wav1d.rs b/src/commands/wav1d.rs index 3d01f59..5c90511 100644 --- a/src/commands/wav1d.rs +++ b/src/commands/wav1d.rs @@ -1,5 +1,4 @@ use std::path::PathBuf; -use std::fs; use clap::Args; use log::{ @@ -228,12 +227,13 @@ I suggest you provide `gamma_half` argument to avoid confusion."); .title(plotly::common::Title::with_text("E-Ef (eV)")) .zero_line(true)) .x_axis(plotly::layout::Axis::new() - .title(plotly::common::Title::with_text("Distance (Å)"))); + .title(plotly::common::Title::with_text("Distance (Å)"))) + .height(960); plot.set_layout(layout); plot.use_local_plotly(); info!("Writing to {:?}", self.htmlout); - fs::write(&self.htmlout, plot.to_html())?; + plot.write_html(&self.htmlout); let comment = dat.iter() .map(|(_, l, _)| l.clone()) diff --git a/src/commands/workfunc.rs b/src/commands/workfunc.rs index 3b6ba4a..e9ef12f 100644 --- a/src/commands/workfunc.rs +++ b/src/commands/workfunc.rs @@ -1,4 +1,3 @@ -use std::fs; use std::path::PathBuf; use clap::Args; use rayon; @@ -127,11 +126,12 @@ impl OptProcess for Workfunc { .zero_line(true)) .x_axis(plotly::layout::Axis::new() .title(plotly::common::Title::with_text("Distance (A)")) - .zero_line(true)); + .zero_line(true)) + .height(960); plot.set_layout(layout); info!("Writing to {:?}", self.htmlout); - fs::write(&self.htmlout, plot.to_html())?; + plot.write_html(&self.htmlout); if self.show { plot.show();