Ver a proveniência

Refactored most report generation to functions

Is it less monolithic? Yes
Is it actually any better? Uhh

This is still doing some reasonably code-smelly things which could
probably be improved with a decent JavaScript templating engine, but:

- it's after 10PM on a SAturday night and I've been working on this all
  afternoon
- it works for now
- I don't want to go too far down the rabbit hole of super-polished code
  (hah!) before I check that the output format suits C

It is actually better in the sens that we present charts first (easier
to see at a glance) with their data below them.

Todo:
 - sort output of outcomesBalance for chart (already sorted for table)
 - hide/show toggles
 - make the doughnut chart more straightforward (swap legend order,
   rename labels)
tags/v0.1.3
bertieb há 3 anos
ascendente
cometimento
a08472a6b8
1 ficheiros alterados com 183 adições e 66 eliminações
  1. +183
    -66
      src/ts/frontend.ts

+ 183
- 66
src/ts/frontend.ts Ver ficheiro

@@ -43,69 +43,118 @@ function buildCharts(): string {
return output;
}

function getResults():void {
console.log("getting results");
$("#results").empty();
rollstats.doRolls();
$("#results").append(`<div class="card my-4">`);
let resultsCard = $("#results").find("div.card");
resultsCard.append(`<div class="card-body">`);
let resultsCardBody = $("#results").find("div.card-body");
resultsCardBody.append(`<h2 class="card-title">Asphodice Results</h2>`);
resultsCardBody.append(`<h3 class="card-subtitle my-1">Rerolls</h3>`);
resultsCardBody.append(`<div class="row my-3 mx-auto">
<div class="col alert alert-success"><strong>Rerolled:</strong> ${rollstats.rerollCounts.true} (${(rollstats.rerollCounts.true / rollstats.numRolls * 100).toFixed(2)} %)</div>
<div class="col alert alert-warning"><strong>Not rerolled:</strong> ${rollstats.rerollCounts.false} (${(rollstats.rerollCounts.false / rollstats.numRolls * 100).toFixed(2)} %)</div>
</div>`);
/**
* h2 wrapper
*/
function bigTitle(text:string): string {
return `<h2 class="card-title">${text}</h2>`;
}

resultsCardBody.append(`<h3 class="card-subtitle my-1">Outcome Balances</h3>`);
resultsCardBody.append(makeTableSkeleton("balanceTable", ["Balance", "Count", "Percentage"]));
resultsCardBody.append(makeTableSkeleton("outcomeTable", ["Outcome", "Count", "Percentage"]));
/**
* h3 wrapper
*/
function subTitle(text:string): string {
return `<h3 class="card-subtitle my-1">${text}</h3>`;
}

let bc = rollstats.balanceCounts;
let keys = Object.keys(bc);
keys.sort(function(a: string, b: string){return Number(a) - Number(b)});
for (var i = 0; i < keys.length; i++) {
let tb = $("#balanceTable").find("tbody");
tb.append(`<tr> <td>${keys[i]}</td>
<td>${rollstats.balanceCounts[keys[i]]}</td>
<td>${(rollstats.balanceCounts[keys[i]] / rollstats.numRolls * 100).toFixed(2)}</td>
</tr>`);
}
/**
* h4 wrapper
*/
function subsubTitle(text:string): string {
return `<h4 class="card-subtitle my-1">${text}</h4>`;
}

let oc = rollstats.outcomeCounts;
let okeys = Object.keys(oc);
for (var i = 0; i < okeys.length; i++) {
let tb = $("#outcomeTable").find("tbody");
let outcome: Outcomes = okeys[i] as Outcomes;
let outcomeCount = rollstats.outcomeCounts[outcome];
let outcomePercent = (outcomeCount / rollstats.numRolls * 100).toFixed(2);
tb.append(`<tr> <td>${outcome}</td>
<td>${outcomeCount}</td>
<td>${outcomePercent}</td>
</tr>`);
}
/**
* Report on rerolls
* ie:
* - make chart
* - make number boxes
*/

// Charts
resultsCardBody.append(`<h3 class="card-subtitle my-2">Charts</h3>`);
resultsCardBody.append(`<h4 class="card-subtitle my-1">Outcome Balances</h4>`);
resultsCardBody.append(`<canvas id="balanceChart"></canvas>`);
let balanceCanvas: any = $("#balanceChart");
let balanceChart = new Chart(balanceCanvas, {
type: "bar",
function rerollReport(rollstats: RollStats): string {
let output = subTitle("Rerolls");
// Preamble (ie it looks super confusing)
output += "<p>This is super confusing because the colours are swapped on the legend and the chart, then the data below swaps back.</p>";
// Chart
//resultsCardBody.append(`<h4 class="card-subtitle my-1">Rerolls</h4>`);
//resultsCardBody.append(`<canvas id="rerollsChart"></canvas>`);
output += `<canvas id="rerollsChart"></canvas>`

// Numbers

output += `<div class="row my-3 mx-auto">`;
output += `<div class="col alert alert-success">
<strong>Rerolled:</strong>
${rollstats.rerollCounts.true}
(${(rollstats.rerollCounts.true / rollstats.numRolls * 100).toFixed(2)} %)
</div>`;
output += `<div class="col alert alert-warning">
<strong>Not rerolled:</strong>
${rollstats.rerollCounts.false}
(${(rollstats.rerollCounts.false / rollstats.numRolls * 100).toFixed(2)} %)
</div>`
output += `</div>`
return output;
}

function outcomesReport(rollstats: RollStats): string {
let output = subTitle("Outcomes");
// Preamble

// Chart
output += `<canvas id="outcomesChart"></canvas>`;

// Table
output += makeTableSkeleton("outcomeTable", ["Outcome", "Count", "Percentage"]);
return output;
}

function outcomeBalancesReport(rollstats: RollStats): string {
let output = subTitle("Outcome Balancess");
// Preamble

// Chart
output += `<canvas id="balanceChart"></canvas>`;

// Table
output += makeTableSkeleton("balanceTable", ["Balance", "Count", "Percentage"]);
return output;
}

/**
* Do the charts after we've added them to the canvas
*
* The more javascripty way of doing this would be a callback or a custom event (TODO?)
*/
function generateCharts(rollstats: RollStats): void {

/*
* Rerolls
*/

let rerollsCanvas: any = $("#rerollsChart");
let rerollsChart = new Chart(rerollsCanvas, {
type: "doughnut",
data: {
labels: Object.keys(rollstats.balanceCounts),
labels: Object.keys(rollstats.rerollCounts),
datasets: [{
label: "Outcome Balance Counts",
data: Object.values(rollstats.balanceCounts),
label: "Reroll Counts",
data: Object.values(rollstats.rerollCounts),
backgroundColor: hexColours(Object.values(rollstats.balanceCounts).length),
}],
},
options: barChartOptions,
options: {
title: {
text: "Rerolls Chart",
display: false,
},
}
});

resultsCardBody.append(`<h4 class="card-subtitle my-1">Outcomes</h4>`);
resultsCardBody.append(`<canvas id="outcomesChart"></canvas>`);
/*
* Outcomes
*/

let outcomesCanvas: any = $("#outcomesChart");
let outcomesChart = new Chart(outcomesCanvas, {
type: "bar",
@@ -120,26 +169,94 @@ function getResults():void {
options: barChartOptions,
});

resultsCardBody.append(`<h4 class="card-subtitle my-1">Rerolls</h4>`);
resultsCardBody.append(`<canvas id="rerollsChart"></canvas>`);
let rerollsCanvas: any = $("#rerollsChart");
let rerollsChart = new Chart(rerollsCanvas, {
type: "doughnut",
/**
* Outcome Balances
*/

let balanceCanvas: any = $("#balanceChart");
let balanceChart = new Chart(balanceCanvas, {
type: "bar",
data: {
labels: Object.keys(rollstats.rerollCounts),
labels: Object.keys(rollstats.balanceCounts),
datasets: [{
label: "Reroll Counts",
data: Object.values(rollstats.rerollCounts),
label: "Outcome Balance Counts",
data: Object.values(rollstats.balanceCounts),
backgroundColor: hexColours(Object.values(rollstats.balanceCounts).length),
}],
},
options: {
title: {
text: "Rerolls Chart",
display: false,
},
}
options: barChartOptions,
});

}

/**
* Generate tables after we've inserted them into the DOM,
*
* Also should be callback/event-driven. (TODO?)
*/
function generateTables(rollstats: RollStats): void {
/*
* Outcomes
*/

let oc = rollstats.outcomeCounts;
let okeys = Object.keys(oc);
for (var i = 0; i < okeys.length; i++) {
let tb = $("#outcomeTable").find("tbody");
let outcome: Outcomes = okeys[i] as Outcomes;
let outcomeCount = rollstats.outcomeCounts[outcome];
let outcomePercent = (outcomeCount / rollstats.numRolls * 100).toFixed(2);
tb.append(`<tr> <td>${outcome}</td>
<td>${outcomeCount}</td>
<td>${outcomePercent}</td>
</tr>`);
}

/*
* Outcome Balance Counts
*/

let bc = rollstats.balanceCounts;
let keys = Object.keys(bc);
keys.sort(function(a: string, b: string){return Number(a) - Number(b)});
for (var i = 0; i < keys.length; i++) {
let tb = $("#balanceTable").find("tbody");
tb.append(`<tr> <td>${keys[i]}</td>
<td>${rollstats.balanceCounts[keys[i]]}</td>
<td>${(rollstats.balanceCounts[keys[i]] / rollstats.numRolls * 100).toFixed(2)}</td>
</tr>`);
}

}

function getResults():void {
console.log("getting results");
$("#results").empty();
rollstats.doRolls();
$("#results").append(`<div class="card my-4">`);
let resultsCard = $("#results").find("div.card");
resultsCard.append(`<div class="card-body">`);
let resultsCardBody = $("#results").find("div.card-body");

resultsCardBody.append(bigTitle("Asphodice Results"));
resultsCardBody.append(rerollReport(rollstats));
resultsCardBody.append(outcomesReport(rollstats));
resultsCardBody.append(outcomeBalancesReport(rollstats));

// Post-DOM-Construction generation
//
// For tables: we need this as the way that tables were implemented
// we .find() the <tbody>
//
// For charts: the Chart() generation function expects to passed an extant
// <canvas> element

// Tables
generateTables(rollstats);

// Charts
generateCharts(rollstats);

}




Carregando…
Cancelar
Guardar