Basic tabular output in HTML
This commit is contained in:
parent
97a776ff79
commit
37622eb78d
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -202,6 +202,15 @@ version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@ -290,6 +299,7 @@ dependencies = [
|
||||
"csv",
|
||||
"flate2",
|
||||
"git-version",
|
||||
"js-sys",
|
||||
"num-bigint",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
|
@ -15,6 +15,7 @@ wasm-bindgen = "0.2.74"
|
||||
# Only for WebAssembly - include here for syntax highlighting
|
||||
#[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
console_error_panic_hook = "0.1.6"
|
||||
js-sys = "0.3.51"
|
||||
num-bigint = "0.4.0"
|
||||
num-rational = "0.4.0"
|
||||
paste = "1.0.5"
|
||||
|
@ -25,13 +25,16 @@ function clickAdvancedOptions() {
|
||||
}
|
||||
}
|
||||
|
||||
console.log = function(v) {
|
||||
document.getElementById('resultLogs1').append(v);
|
||||
document.getElementById('resultLogs1').append("\n");
|
||||
};
|
||||
|
||||
var wasm = wasm_bindgen;
|
||||
|
||||
var tblResult = document.getElementById('result');
|
||||
|
||||
function updateResultTable(result) {
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
tblResult.rows[i].insertAdjacentHTML('beforeend', result[i]);
|
||||
}
|
||||
}
|
||||
|
||||
async function clickCount() {
|
||||
if (document.getElementById('bltFile').files.length === 0) {
|
||||
return;
|
||||
@ -46,10 +49,12 @@ async function clickCount() {
|
||||
|
||||
// Init election
|
||||
let election = wasm.election_from_blt_Rational(electionData);
|
||||
let state = wasm.CountStateRational.new(election);
|
||||
|
||||
// Init results table
|
||||
tblResult.innerHTML = wasm.init_results_table_Rational(election);
|
||||
|
||||
// Init STV options
|
||||
let stv_opts = wasm.STVOptions.new(
|
||||
let opts = wasm.STVOptions.new(
|
||||
document.getElementById('chkRoundTVs').checked ? parseInt(document.getElementById('txtRoundTVs').value) : null,
|
||||
document.getElementById('chkRoundWeights').checked ? parseInt(document.getElementById('txtRoundWeights').value) : null,
|
||||
document.getElementById('chkRoundVotes').checked ? parseInt(document.getElementById('txtRoundVotes').value) : null,
|
||||
@ -64,14 +69,15 @@ async function clickCount() {
|
||||
);
|
||||
|
||||
// Step election
|
||||
wasm.count_init_Rational(state, stv_opts);
|
||||
wasm.make_and_print_result_Rational(1, state);
|
||||
let state = wasm.CountStateRational.new(election);
|
||||
wasm.count_init_Rational(state, opts);
|
||||
updateResultTable(wasm.update_results_table_Rational(1, state, opts));
|
||||
|
||||
for (let stage_num = 2;; stage_num++) {
|
||||
let is_done = wasm.count_one_stage_Rational(state, stv_opts);
|
||||
if (is_done) {
|
||||
for (let stageNum = 2;; stageNum++) {
|
||||
let isDone = wasm.count_one_stage_Rational(state, opts);
|
||||
if (isDone) {
|
||||
break;
|
||||
}
|
||||
wasm.make_and_print_result_Rational(stage_num, state);
|
||||
updateResultTable(wasm.update_results_table_Rational(stageNum, state, opts));
|
||||
}
|
||||
}
|
||||
|
@ -83,9 +83,6 @@ td.count sup {
|
||||
tr.stage-no td, tr.stage-kind td, tr.stage-comment td {
|
||||
text-align: center;
|
||||
}
|
||||
tr.stage-no td:not(:first-child) {
|
||||
border-top: 1px solid #76858c;
|
||||
}
|
||||
tr.stage-kind td:not(:first-child) {
|
||||
font-size: 0.75em;
|
||||
min-width: 5rem;
|
||||
@ -109,10 +106,10 @@ tr.info td {
|
||||
color-adjust: exact;
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
td.bt {
|
||||
tr.stage-no td:not(:first-child), tr.transfers td {
|
||||
border-top: 1px solid #76858c;
|
||||
}
|
||||
td.bb {
|
||||
tr.info:last-child td {
|
||||
border-bottom: 1px solid #76858c;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ use crate::stv;
|
||||
|
||||
extern crate console_error_panic_hook;
|
||||
|
||||
use js_sys::Array;
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
// Logging
|
||||
@ -70,6 +71,18 @@ macro_rules! impl_type {
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn [<init_results_table_$type>](election: &[<Election$type>]) -> String {
|
||||
return init_results_table(&election.0);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn [<update_results_table_$type>](stage_num: usize, state: &[<CountState$type>], opts: &stv::STVOptions) -> Array {
|
||||
return update_results_table(stage_num, &state.0, opts);
|
||||
}
|
||||
|
||||
/*#[wasm_bindgen]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn [<make_and_print_result_$type>](stage_num: usize, state: &[<CountState$type>]) {
|
||||
let result = StageResult {
|
||||
kind: state.0.kind,
|
||||
@ -78,7 +91,7 @@ macro_rules! impl_type {
|
||||
state: CountStateOrRef::from(&state.0),
|
||||
};
|
||||
print_stage(stage_num, &result);
|
||||
}
|
||||
}*/
|
||||
|
||||
// Wrapper structs
|
||||
// Required as we cannot specify &'static in wasm-bindgen: issue #1187
|
||||
@ -114,7 +127,47 @@ impl_type!(NativeFloat64);
|
||||
|
||||
// Reporting
|
||||
|
||||
fn print_candidates<'a, N: 'a + Number, I: Iterator<Item=(&'a Candidate, &'a CountCard<'a, N>)>>(candidates: I) {
|
||||
fn init_results_table<N: Number>(election: &Election<N>) -> String {
|
||||
let mut result = String::from(r#"<tr class="stage-no"><td></td></tr><tr class="stage-kind"><td></td></tr><tr class="stage-comment"><td></td></tr>"#);
|
||||
for candidate in election.candidates.iter() {
|
||||
result.push_str(&format!(r#"<tr class="candidate transfers"><td rowspan="2">{}</td></tr><tr class="candidate votes"></tr>"#, candidate.name));
|
||||
}
|
||||
result.push_str(r#"<tr class="info transfers"><td rowspan="2">Exhausted</td></tr><tr class="info votes"></tr><tr class="info transfers"><td rowspan="2">Loss by fraction</td></tr><tr class="info votes"></tr><tr class="info transfers"><td>Total</td></tr><tr class="info transfers"><td>Quota</td></tr>"#);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn update_results_table<N: Number>(stage_num: usize, state: &CountState<N>, opts: &stv::STVOptions) -> Array {
|
||||
let result = Array::new();
|
||||
result.push(&format!(r#"<td>{}</td>"#, stage_num).into());
|
||||
result.push(&format!(r#"<td>{}</td>"#, state.kind.unwrap_or("")).into());
|
||||
result.push(&format!(r#"<td>{}</td>"#, state.title).into());
|
||||
for candidate in state.election.candidates.iter() {
|
||||
let count_card = state.candidates.get(candidate).unwrap();
|
||||
if count_card.state == stv::CandidateState::ELECTED {
|
||||
result.push(&format!(r#"<td class="elected">{:.dps$}</td>"#, count_card.transfers, dps=opts.pp_decimals).into());
|
||||
result.push(&format!(r#"<td class="elected">{:.dps$}</td>"#, count_card.votes, dps=opts.pp_decimals).into());
|
||||
} else {
|
||||
result.push(&format!(r#"<td>{:.dps$}</td>"#, count_card.transfers, dps=opts.pp_decimals).into());
|
||||
result.push(&format!(r#"<td>{:.dps$}</td>"#, count_card.votes, dps=opts.pp_decimals).into());
|
||||
}
|
||||
}
|
||||
result.push(&format!(r#"<td>{:.dps$}</td>"#, state.exhausted.transfers, dps=opts.pp_decimals).into());
|
||||
result.push(&format!(r#"<td>{:.dps$}</td>"#, state.exhausted.votes, dps=opts.pp_decimals).into());
|
||||
result.push(&format!(r#"<td>{:.dps$}</td>"#, state.loss_fraction.transfers, dps=opts.pp_decimals).into());
|
||||
result.push(&format!(r#"<td>{:.dps$}</td>"#, state.loss_fraction.votes, dps=opts.pp_decimals).into());
|
||||
|
||||
// Calculate total votes
|
||||
let mut total_vote = state.candidates.values().fold(N::zero(), |acc, cc| { acc + &cc.votes });
|
||||
total_vote += &state.exhausted.votes;
|
||||
total_vote += &state.loss_fraction.votes;
|
||||
result.push(&format!(r#"<td>{:.dps$}</td>"#, total_vote, dps=opts.pp_decimals).into());
|
||||
|
||||
result.push(&format!(r#"<td>{:.dps$}</td>"#, state.quota, dps=opts.pp_decimals).into());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*fn print_candidates<'a, N: 'a + Number, I: Iterator<Item=(&'a Candidate, &'a CountCard<'a, N>)>>(candidates: I) {
|
||||
for (candidate, count_card) in candidates {
|
||||
if count_card.state == CandidateState::ELECTED {
|
||||
cprintln!("- {}: {:.dps$} ({:.dps$}) - ELECTED {}", candidate.name, count_card.votes, count_card.transfers, count_card.order_elected, dps=2);
|
||||
@ -153,4 +206,4 @@ fn print_stage<N: Number>(stage_num: usize, result: &StageResult<N>) {
|
||||
cprintln!("Quota: {:.dps$}", state.quota, dps=2);
|
||||
|
||||
cprintln!("");
|
||||
}
|
||||
}*/
|
||||
|
Loading…
Reference in New Issue
Block a user