(async function () {
const response = await fetch('roi.json');
const profits: Profit[] = await response.json();
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) {
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;
tr.innerHTML = `
${p.output} |
${p.expertise} |
${formatDecimal(profit_per_area)} |
${formatDecimal(break_even)}d |
${formatWhole(p.capex)} |
${formatWhole(p.cost_per_day)} |
${formatDecimal(p.logistics_per_area)} |
${formatWhole(p.output_per_day)}
${formatWhole(p.average_traded_7d)}
|
`;
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
const scale = Math.min(Math.max((n - low) / (high - low), 0), 1);
return `color-mix(in oklch, #0c8 ${scale * 100}%, #f70)`;
}
interface Profit {
output: string
recipe: string
expertise: string
profit_per_day: number
area: number
capex: number
cost_per_day: number
logistics_per_area: number
output_per_day: number
average_traded_7d: number
}