Print variable labels optionally

This commit is contained in:
Arne Keller 2021-03-19 19:23:17 +01:00
parent 8dff087377
commit b2eeecfae6
4 changed files with 129 additions and 5 deletions

View File

@ -44,7 +44,8 @@
<div><label>Generate: <select id="mode-select">
<option value="dmf">DMF</option>
<option value="kmf">KMF</option>
</select></label></div>
</select></label>
<label><input type="checkbox" id="labels">Print variable labels</label></div>
<button id="calculate">Run</button>
<div id="output-help"></div>
<div id="output-container"></div>

View File

@ -77,6 +77,7 @@ fn span(text: &str) -> HtmlElement {
pub fn run() {
let document = web!(document);
let print_labels = get_labels();
let mode = get_mode();
let var_count = get_var_number();
let vars = (0..var_count).map(|x| 2usize.pow(x as u32)).collect::<Vec<_>>();
@ -100,7 +101,7 @@ pub fn run() {
macro_rules! render_svg {
($sol:expr, $mask:expr) => {
let svg = svg::get_svg(if var_count < 5 { 64 } else { 80 }, &function, &vars, $mask);
let svg = svg::get_svg(if var_count < 5 { 64 } else { 80 }, print_labels, &function, &vars, $mask);
let svg_container = document.create_element("div").unwrap();
svg_container.set_class_name("solution");
svg_container.set_inner_html(&svg);
@ -175,6 +176,14 @@ fn get_var_number() -> usize {
get_var_number_el().value().parse().unwrap()
}
fn get_labels_el() -> HtmlInputElement {
web!(document).get_element_by_id("labels").unwrap().unchecked_into()
}
fn get_labels() -> bool {
get_labels_el().checked()
}
fn get_mode_el() -> HtmlSelectElement {
web!(document).get_element_by_id("mode-select").unwrap().unchecked_into()
}

View File

@ -45,5 +45,5 @@ fn main() {
.collect()
};
println!("{}", svg::get_svg(SIZE_FACTOR, &function, &vars, &block_masks));
println!("{}", svg::get_svg(SIZE_FACTOR, false, &function, &vars, &block_masks));
}

View File

@ -15,9 +15,12 @@ const COLORS: &'static [Color] = &[
rgb(128, 0, 128), // dark red
];
pub fn get_svg(size_factor: usize, function: &FunctionSpec, vars: &[Variable], block_masks: &[(usize, usize)]) -> String {
pub fn get_svg(size_factor: usize, print_labels: bool,
function: &FunctionSpec, vars: &[Variable], block_masks: &[(usize, usize)]) -> String {
let size2 = (size_factor / 2) as f32;
let size4 = size_factor / 4;
let size8 = size_factor / 8;
let size16 = (size_factor / 16) as f32;
let delta = size_factor as f32 / 32.0;
let mut svg = String::new();
@ -32,7 +35,118 @@ pub fn get_svg(size_factor: usize, function: &FunctionSpec, vars: &[Variable], b
}
}
svg += &BeginSvg { w: w * size_factor + 3, h: h * size_factor + 3 }.to_string();
let (start_x, start_y, w_add, h_add) = if print_labels {
let mut a = 0.0;
let mut b = 0.0;
let mut c = 0.0;
let mut d = 0.0;
for i in 0..vars.len() {
match i % 4 {
0 => {
b -= size2;
d += size2;
},
1 => {
a -= size2;
c += size2;
},
2 => {
d += size2;
},
3 => {
c += size2;
},
_ => unreachable!()
}
}
(a, b, c, d)
} else {
(0.0, 0.0, 0.0, 0.0)
};
let w_base = (w * size_factor + 3) as f32;
let h_base = (h * size_factor + 3) as f32;
svg += &BeginSvg {
w: w_base + w_add, h: h_base + h_add,
x: start_x, y: start_y
}.to_string();
if print_labels {
for i in 0..vars.len() {
let offset = (i / 4) as f32 * size2 + size16;
let initial_window = 2usize.pow(((i + 2) / 4) as u32);
let mut start = vec![false; initial_window];
start.extend(vec![true; initial_window]);
let desired_len = if i % 2 == 0 { w } else { h };
while start.len() < desired_len {
let j = start.len();
for k in 0..j {
start.push(start[j-k-1]);
}
}
let mut segments = vec![];
let mut j = 0;
while j < desired_len {
if let Some((idx, _)) = start[j..].iter().find_position(|x| **x) {
j += idx;
let j2 = start[j..].iter().find_position(|x| !**x).map(|x| x.0).unwrap_or(desired_len-j);
segments.push((j, j+j2-1));
j += j2;
} else {
break;
}
}
let var_name = print_var(vars[i]);
match i % 4 {
0 => {
for (x1, x2) in segments {
svg += &line_segment(x1 * size_factor, -offset, (x2 + 1) * size_factor, -offset)
.width(2.0)
.to_string();
svg += &text((x1 + x2 + 1) * size_factor / 2, -offset - size16, var_name)
.align(Align::Center)
.size(SIZE_FONT)
.to_string();
}
},
1 => {
for (y1, y2) in segments {
svg += &line_segment(-offset, y1 * size_factor, -offset, (y2 + 1) * size_factor)
.width(2.0)
.to_string();
svg += &text(-offset - size8 as f32, (y1 + y2 + 1) * size_factor / 2, var_name)
.align(Align::Center)
.size(SIZE_FONT)
.to_string();
}
},
2 => {
for (x1, x2) in segments {
svg += &line_segment(x1 * size_factor, h_base + offset, (x2 + 1) * size_factor, h_base + offset)
.width(2.0)
.to_string();
svg += &text((x1 + x2 + 1) * size_factor / 2, h_base + offset + size4 as f32, var_name)
.align(Align::Center)
.size(SIZE_FONT)
.to_string();
}
},
3 => {
for (y1, y2) in segments {
svg += &line_segment(w_base + offset, y1 * size_factor, w_base + offset, (y2 + 1) * size_factor)
.width(2.0)
.to_string();
svg += &text(w_base + offset + size8 as f32, (y1 + y2 + 1) * size_factor / 2, var_name)
.align(Align::Center)
.size(SIZE_FONT)
.to_string();
}
},
_ => unreachable!()
}
}
}
for (i, &(x, y)) in grid.iter().enumerate() {
svg += &rectangle(1 + x * size_factor, 1 + y * size_factor, size_factor, size_factor)
.fill(white())