import {findCell} from "/src/utils/graphUtils"; import {last} from "/src/utils/arrayUtils"; import {tip, clearMainTip} from "/src/scripts/tooltips"; import {rn} from "/src/utils/numberUtils"; export function overviewRegiments(state) { if (customization) return; closeDialogs(".stable"); if (!layerIsOn("toggleMilitary")) toggleMilitary(); const body = document.getElementById("regimentsBody"); updateFilter(state); addLines(); $("#regimentsOverview").dialog(); if (fmg.modules.overviewRegiments) return; fmg.modules.overviewRegiments = true; updateHeaders(); $("#regimentsOverview").dialog({ title: "Regiments Overview", resizable: false, width: "fit-content", position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"} }); // add listeners document.getElementById("regimentsOverviewRefresh").addEventListener("click", addLines); document.getElementById("regimentsPercentage").addEventListener("click", togglePercentageMode); document.getElementById("regimentsAddNew").addEventListener("click", toggleAdd); document.getElementById("regimentsExport").addEventListener("click", downloadRegimentsData); document.getElementById("regimentsFilter").addEventListener("change", addLines); // update military types in header and tooltips function updateHeaders() { const header = document.getElementById("regimentsHeader"); const units = options.military.length; header.style.gridTemplateColumns = `9em 13em repeat(${units}, 5.2em) 7em`; header.querySelectorAll(".removable").forEach(el => el.remove()); const insert = html => document.getElementById("regimentsTotal").insertAdjacentHTML("beforebegin", html); for (const u of options.military) { const label = capitalize(u.name.replace(/_/g, " ")); insert( `
${label} 
` ); } header.querySelectorAll(".removable").forEach(function (e) { e.addEventListener("click", function () { sortLines(this); }); }); } // add line for each state function addLines() { const state = +regimentsFilter.value; body.innerHTML = ""; let lines = ""; const regiments = []; for (const s of pack.states) { if (!s.i || s.removed || !s.military.length) continue; if (state !== -1 && s.i !== state) continue; // specific state is selected for (const r of s.military) { const sortData = options.military.map(u => `data-${u.name}=${r.u[u.name] || 0}`).join(" "); const lineData = options.military .map( u => `
${r.u[u.name] || 0}
` ) .join(" "); lines += /* html */ `
${r.icon} ${lineData}
${r.a}
`; regiments.push(r); } } lines += /* html */ `
Regiments: ${regiments.length}
${options.military .map(u => `
${si(d3.sum(regiments.map(r => r.u[u.name] || 0)))}
`) .join(" ")}
${si(d3.sum(regiments.map(r => r.a)))}
`; body.insertAdjacentHTML("beforeend", lines); if (body.dataset.type === "percentage") { body.dataset.type = "absolute"; togglePercentageMode(); } applySorting(regimentsHeader); // add listeners body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseenter", ev => regimentHighlightOn(ev))); body .querySelectorAll("div.states") .forEach(el => el.addEventListener("mouseleave", ev => regimentHighlightOff(ev))); } function updateFilter(state) { const filter = document.getElementById("regimentsFilter"); filter.options.length = 0; // remove all options filter.options.add(new Option(`all`, -1, false, state === -1)); const statesSorted = pack.states.filter(s => s.i && !s.removed).sort((a, b) => (a.name > b.name ? 1 : -1)); statesSorted.forEach(s => filter.options.add(new Option(s.name, s.i, false, s.i == state))); } function regimentHighlightOn(event) { const state = +event.target.dataset.s; const id = +event.target.dataset.id; if (customization || !state) return; armies.select(`g > g#regiment${state}-${id}`).transition().duration(2000).style("fill", "#ff0000"); } function regimentHighlightOff(event) { const state = +event.target.dataset.s; const id = +event.target.dataset.id; armies.select(`g > g#regiment${state}-${id}`).transition().duration(1000).style("fill", null); } function togglePercentageMode() { if (body.dataset.type === "absolute") { body.dataset.type = "percentage"; const lines = body.querySelectorAll(":scope > div:not(.totalLine)"); const array = Array.from(lines), cache = []; const total = function (type) { if (cache[type]) cache[type]; cache[type] = d3.sum(array.map(el => +el.dataset[type])); return cache[type]; }; lines.forEach(function (el) { el.querySelectorAll("div").forEach(function (div) { const type = div.dataset.type; if (type === "rate") return; div.textContent = total(type) ? rn((+el.dataset[type] / total(type)) * 100) + "%" : "0%"; }); }); } else { body.dataset.type = "absolute"; addLines(); } } function toggleAdd() { document.getElementById("regimentsAddNew").classList.toggle("pressed"); if (document.getElementById("regimentsAddNew").classList.contains("pressed")) { viewbox.style("cursor", "crosshair").on("click", addRegimentOnClick); tip("Click on map to create new regiment or fleet", true); if (regimentAdd.offsetParent) regimentAdd.classList.add("pressed"); } else { clearMainTip(); viewbox.on("click", clicked).style("cursor", "default"); addLines(); if (regimentAdd.offsetParent) regimentAdd.classList.remove("pressed"); } } function addRegimentOnClick() { const state = +regimentsFilter.value; if (state === -1) { tip("Please select state from the list", false, "error"); return; } const point = d3.mouse(this); const cell = findCell(point[0], point[1]); const x = pack.cells.p[cell][0], y = pack.cells.p[cell][1]; const military = pack.states[state].military; const i = military.length ? last(military).i + 1 : 0; const n = +(pack.cells.h[cell] < 20); // naval or land const reg = {a: 0, cell, i, n, u: {}, x, y, bx: x, by: y, state, icon: "🛡️"}; reg.name = Military.getName(reg, military); military.push(reg); Military.generateNote(reg, pack.states[state]); // add legend Military.drawRegiment(reg, state); toggleAdd(); } function downloadRegimentsData() { const units = options.military.map(u => u.name); let data = "State,Id,Name," + units.map(u => capitalize(u)).join(",") + ",Total\n"; // headers body.querySelectorAll(":scope > div:not(.totalLine)").forEach(function (el) { data += el.dataset.state + ","; data += el.dataset.id + ","; data += el.dataset.name + ","; data += units.map(u => el.dataset[u]).join(",") + ","; data += el.dataset.total + "\n"; }); const name = getFileName("Regiments") + ".csv"; downloadFile(data, name); } }