raylu преди 4 седмици
родител
ревизия
a995682689
променени са 3 файла, в които са добавени 40 реда и са изтрити 2 реда
  1. 2 0
      roi.py
  2. 35 2
      ts/roi.ts
  3. 3 0
      www/roi.html

+ 2 - 0
roi.py

@@ -90,6 +90,7 @@ def calc_profit(recipe: Recipe, buildings: typing.Mapping[str, Building], hab_ar
 	) * runs_per_day / area
 	return Profit(outputs, recipe['recipe_name'],
 			expertise=building['expertise'],
+			building=building['building_ticker'],
 			profit_per_day=(profit_per_run * runs_per_day - worker_consumable_daily_cost),
 			area=area,
 			capex=capex,
@@ -176,6 +177,7 @@ class Profit:
 	outputs: typing.Collection[MatPrice]
 	recipe: str
 	expertise: str
+	building: str
 	profit_per_day: float
 	area: float
 	capex: float

+ 35 - 2
ts/roi.ts

@@ -8,8 +8,14 @@ async function getROI(cx: string) {
 	return {lastModified, profits};
 }
 
+const buildingsPromise = fetch('https://api.prunplanner.org/data/buildings/')
+		.then((r) => r.json()).then((buildings: Building[]) =>
+			buildings.filter((b) => b.building_type === 'PRODUCTION')
+					.sort((a, b) => a.building_ticker.localeCompare(b.building_ticker)));
+
 const lowVolume = document.querySelector('input#low-volume') as HTMLInputElement;
 
+const cxSelect = document.querySelector('select#cx') as HTMLSelectElement;
 const expertise = {
 	AGRICULTURE: 'agri',
 	CHEMISTRY: 'chem',
@@ -28,7 +34,7 @@ for (const key of Object.keys(expertise)) {
 	option.textContent = key.replace('_', ' ').toLowerCase();
 	expertiseSelect.appendChild(option);
 }
-const cxSelect = document.querySelector('select#cx') as HTMLSelectElement;
+const buildingSelect = document.querySelector('select#building') as HTMLSelectElement;
 
 const formatDecimal = new Intl.NumberFormat(undefined,
 		{maximumFractionDigits: 2, maximumSignificantDigits: 6, roundingPriority: 'lessPrecision'}).format;
@@ -38,6 +44,23 @@ async function render() {
 	const tbody = document.querySelector('tbody')!;
 	tbody.innerHTML = '';
 
+	let selectedBuilding = buildingSelect.value;
+	let buildingFound = false;
+	buildingSelect.innerHTML = '<option value="">(all)</option>';
+	for (const building of await buildingsPromise)
+		if (expertiseSelect.value === '' || expertiseSelect.value === building.expertise) {
+			const option = document.createElement('option');
+			option.value = building.building_ticker;
+			option.textContent = building.building_ticker;
+			if (building.building_ticker === selectedBuilding) {
+				buildingFound = true;
+				option.selected = true;
+			}
+			buildingSelect.appendChild(option);
+		}
+	if (!buildingFound)
+		selectedBuilding = '';
+
 	const cx = cxSelect.value;
 	if (!roiCache[cx])
 		roiCache[cx] = getROI(cx);
@@ -49,6 +72,8 @@ async function render() {
 			continue;
 		if (expertiseSelect.value !== '' && p.expertise !== expertiseSelect.value)
 			continue;
+		if (selectedBuilding !== '' && p.building !== selectedBuilding)
+			continue;
 		const tr = document.createElement('tr');
 		const profitPerArea = p.profit_per_day / p.area;
 		const breakEven = p.profit_per_day > 0 ? p.capex / p.profit_per_day : Infinity;
@@ -98,14 +123,16 @@ function formatMatPrices(matPrices: MatPrice[]): string {
 
 setupPopover();
 lowVolume.addEventListener('change', render);
-expertiseSelect.addEventListener('change', render);
 cxSelect.addEventListener('change', render);
+expertiseSelect.addEventListener('change', render);
+buildingSelect.addEventListener('change', render);
 render();
 
 interface Profit {
 	outputs: MatPrice[]
 	recipe: string
 	expertise: keyof typeof expertise
+	building: string
 	profit_per_day: number
 	area: number
 	capex: number
@@ -123,3 +150,9 @@ interface MatPrice {
 	amount: number
 	vwap_7d: number
 }
+
+interface Building {
+	building_type: 'INFRASTRUCTURE' | 'PLANETARY' | 'PRODUCTION';
+	building_ticker: string;
+	expertise: keyof typeof expertise;
+}

+ 3 - 0
www/roi.html

@@ -22,6 +22,9 @@
 			<label>expertise <select id="expertise">
 				<option value="">(all)</option>
 			</select></label>
+			<label>building <select id="building">
+				<option value="">(all)</option>
+			</select></label>
 		</form>
 		<table>
 			<thead>