소스 검색

shipbuilding: show mat consumption popover

raylu 5 일 전
부모
커밋
4a5422f0e5
2개의 변경된 파일28개의 추가작업 그리고 5개의 파일을 삭제
  1. 26 3
      ts/shipbuilding.ts
  2. 2 2
      www/shipbuilding.html

+ 26 - 3
ts/shipbuilding.ts

@@ -1,4 +1,5 @@
 import {cachedFetchJSON} from './cache';
+import {setupPopover} from './popover';
 
 const BUY = new Set([
 	// definitely buy
@@ -38,6 +39,7 @@ const shipbuilders = [
 
 const main = document.querySelector('main.shipbuilding')!;
 (async () => {
+	setupPopover();
 	main.innerHTML = 'loading...';
 	try {
 		await render();
@@ -268,6 +270,24 @@ function renderProduction(expertiseGroups: Record<string, string[]>, production:
 	const section = element('section');
 	section.append(element('h2', {textContent: 'production'}));
 
+	// mat → list of {outputMat, expertise, amount} that consume it as an input
+	const matConsumers: Record<string, {downstreamMat: string, expertise: string, amount: number}[]> = {};
+	for (const [expertise, productionBuildings] of Object.entries(expertiseGroups)) {
+		for (const building of productionBuildings) {
+			for (const [mat, totalAmount] of Object.entries(production[building])) {
+				const recipe = recipes[mat];
+				const outputPerRun = recipe.outputs.find((o) => o.material_ticker === mat)!.material_amount;
+				for (const input of recipe.inputs) {
+					const ticker = input.material_ticker;
+					if (!matConsumers[ticker])
+						matConsumers[ticker] = [];
+					const amount = input.material_amount * totalAmount / outputPerRun;
+					matConsumers[ticker].push({downstreamMat: mat, expertise, amount});
+				}
+			}
+		}
+	}
+
 	let totalConsumablesCost = 0;
 	for (const [expertise, productionBuildings] of Object.entries(expertiseGroups)) {
 		section.append(element('h3', {textContent: expertise.toLocaleLowerCase()}));
@@ -277,10 +297,13 @@ function renderProduction(expertiseGroups: Record<string, string[]>, production:
 			let buildingMins = 0;
 			for (const [index, [mat, amount]] of mats.entries()) {
 				const traded = prices[mat]?.AverageTraded30D ?? 0;
-				const span = element('span', {
-					textContent: `${formatAmount(amount)}x${mat}`,
-				});
+				const span = element('span', {textContent: `${formatAmount(amount)}x${mat}`});
 				span.style.color = traded > amount * 2 ? '#0cc' : '#c70';
+				const consumers = matConsumers[mat];
+				if (consumers)
+					span.dataset.tooltip = consumers
+						.map((c) => `${formatAmount(c.amount)}x${mat} → ${c.downstreamMat} (${c.expertise.toLocaleLowerCase()})`)
+						.join('\n');
 				buildingMats.append(span);
 				if (index < mats.length - 1)
 					buildingMats.append(document.createTextNode(' '));

+ 2 - 2
www/shipbuilding.html

@@ -10,8 +10,8 @@
 </head>
 <body>
 	<a href="/">← back</a>
-	<main class="shipbuilding">
-	</main>
+	<main class="shipbuilding"></main>
+	<div id="popover" popover="hint"></div>
 	<script src="shipbuilding.js"></script>
 </body>
 </html>