|
|
@@ -1,12 +1,21 @@
|
|
|
-(async function () {
|
|
|
+const profits: Promise<Profit[]> = (async function () {
|
|
|
const response = await fetch('roi.json');
|
|
|
- const profits: Profit[] = await response.json();
|
|
|
+ return await response.json();
|
|
|
+})();
|
|
|
+
|
|
|
+const lowVolume = document.querySelector('#low-volume') as HTMLInputElement;
|
|
|
|
|
|
+async function render() {
|
|
|
const formatDecimal = new Intl.NumberFormat(undefined,
|
|
|
{maximumFractionDigits: 2, maximumSignificantDigits: 6, roundingPriority: 'lessPrecision'}).format;
|
|
|
const formatWhole = new Intl.NumberFormat(undefined, {maximumFractionDigits: 0}).format;
|
|
|
const tbody = document.querySelector('tbody')!;
|
|
|
- for (const p of profits) {
|
|
|
+ tbody.innerHTML = '';
|
|
|
+ for (const p of await profits) {
|
|
|
+ const volumeRatio = p.output_per_day / p.average_traded_7d;
|
|
|
+ if (!lowVolume.checked && volumeRatio > 0.05) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
const tr = document.createElement('tr');
|
|
|
const profit_per_area = p.profit_per_day / p.area;
|
|
|
const break_even = p.profit_per_day > 0 ? p.capex / p.profit_per_day : Infinity;
|
|
|
@@ -20,14 +29,14 @@
|
|
|
<td style="color: ${color(p.logistics_per_area, 2, 0.2)}">${formatDecimal(p.logistics_per_area)}</td>
|
|
|
<td>
|
|
|
${formatWhole(p.output_per_day)}<br>
|
|
|
- <span style="color: ${color(p.output_per_day/p.average_traded_7d, 0.05, 0.002)}">${formatWhole(p.average_traded_7d)}</span>
|
|
|
+ <span style="color: ${color(volumeRatio, 0.05, 0.002)}">${formatWhole(p.average_traded_7d)}</span>
|
|
|
</td>
|
|
|
`;
|
|
|
const output = tr.querySelector('td')!;
|
|
|
output.title = p.recipe;
|
|
|
tbody.appendChild(tr);
|
|
|
}
|
|
|
-})();
|
|
|
+}
|
|
|
|
|
|
function color(n: number, low: number, high: number): string {
|
|
|
// scale n from low..high to 0..1 clamped
|
|
|
@@ -35,6 +44,9 @@ function color(n: number, low: number, high: number): string {
|
|
|
return `color-mix(in oklch, #0c8 ${scale * 100}%, #f70)`;
|
|
|
}
|
|
|
|
|
|
+lowVolume.addEventListener('change', render);
|
|
|
+render();
|
|
|
+
|
|
|
interface Profit {
|
|
|
output: string
|
|
|
recipe: string
|