generic confirmationDialog for all files

This commit is contained in:
Azgaar 2021-05-16 18:51:34 +03:00
parent 5464e0a34b
commit 3359df0e02
25 changed files with 6727 additions and 5454 deletions

View file

@ -1,34 +1,39 @@
"use strict";
'use strict';
function overviewBurgs() {
if (customization) return;
closeDialogs("#burgsOverview, .stable");
if (!layerIsOn("toggleIcons")) toggleIcons();
if (!layerIsOn("toggleLabels")) toggleLabels();
closeDialogs('#burgsOverview, .stable');
if (!layerIsOn('toggleIcons')) toggleIcons();
if (!layerIsOn('toggleLabels')) toggleLabels();
const body = document.getElementById("burgsBody");
const body = document.getElementById('burgsBody');
updateFilter();
burgsOverviewAddLines();
$("#burgsOverview").dialog();
$('#burgsOverview').dialog();
if (modules.overviewBurgs) return;
modules.overviewBurgs = true;
$("#burgsOverview").dialog({
title: "Burgs Overview", resizable: false, width: fitContent(), close: exitAddBurgMode,
position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
$('#burgsOverview').dialog({
title: 'Burgs Overview',
resizable: false,
width: fitContent(),
close: exitAddBurgMode,
position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}
});
// add listeners
document.getElementById("burgsOverviewRefresh").addEventListener("click", refreshBurgsEditor);
document.getElementById("burgsChart").addEventListener("click", showBurgsChart);
document.getElementById("burgsFilterState").addEventListener("change", burgsOverviewAddLines);
document.getElementById("burgsFilterCulture").addEventListener("change", burgsOverviewAddLines);
document.getElementById("regenerateBurgNames").addEventListener("click", regenerateNames);
document.getElementById("addNewBurg").addEventListener("click", enterAddBurgMode);
document.getElementById("burgsExport").addEventListener("click", downloadBurgsData);
document.getElementById("burgNamesImport").addEventListener("click", renameBurgsInBulk);
document.getElementById("burgsListToLoad").addEventListener("change", function() {uploadFile(this, importBurgNames)});
document.getElementById("burgsRemoveAll").addEventListener("click", triggerAllBurgsRemove);
document.getElementById('burgsOverviewRefresh').addEventListener('click', refreshBurgsEditor);
document.getElementById('burgsChart').addEventListener('click', showBurgsChart);
document.getElementById('burgsFilterState').addEventListener('change', burgsOverviewAddLines);
document.getElementById('burgsFilterCulture').addEventListener('change', burgsOverviewAddLines);
document.getElementById('regenerateBurgNames').addEventListener('click', regenerateNames);
document.getElementById('addNewBurg').addEventListener('click', enterAddBurgMode);
document.getElementById('burgsExport').addEventListener('click', downloadBurgsData);
document.getElementById('burgNamesImport').addEventListener('click', renameBurgsInBulk);
document.getElementById('burgsListToLoad').addEventListener('change', function () {
uploadFile(this, importBurgNames);
});
document.getElementById('burgsRemoveAll').addEventListener('click', triggerAllBurgsRemove);
function refreshBurgsEditor() {
updateFilter();
@ -36,41 +41,42 @@ function overviewBurgs() {
}
function updateFilter() {
const stateFilter = document.getElementById("burgsFilterState");
const stateFilter = document.getElementById('burgsFilterState');
const selectedState = stateFilter.value || 1;
stateFilter.options.length = 0; // remove all options
stateFilter.options.add(new Option(`all`, -1, false, selectedState == -1));
stateFilter.options.add(new Option(pack.states[0].name, 0, false, !selectedState));
const statesSorted = pack.states.filter(s => s.i && !s.removed).sort((a, b) => (a.name > b.name) ? 1 : -1);
statesSorted.forEach(s => stateFilter.options.add(new Option(s.name, s.i, false, s.i == selectedState)));
const statesSorted = pack.states.filter((s) => s.i && !s.removed).sort((a, b) => (a.name > b.name ? 1 : -1));
statesSorted.forEach((s) => stateFilter.options.add(new Option(s.name, s.i, false, s.i == selectedState)));
const cultureFilter = document.getElementById("burgsFilterCulture");
const cultureFilter = document.getElementById('burgsFilterCulture');
const selectedCulture = cultureFilter.value || -1;
cultureFilter.options.length = 0; // remove all options
cultureFilter.options.add(new Option(`all`, -1, false, selectedCulture == -1));
cultureFilter.options.add(new Option(pack.cultures[0].name, 0, false, !selectedCulture));
const culturesSorted = pack.cultures.filter(c => c.i && !c.removed).sort((a, b) => (a.name > b.name) ? 1 : -1);
culturesSorted.forEach(c => cultureFilter.options.add(new Option(c.name, c.i, false, c.i == selectedCulture)));
const culturesSorted = pack.cultures.filter((c) => c.i && !c.removed).sort((a, b) => (a.name > b.name ? 1 : -1));
culturesSorted.forEach((c) => cultureFilter.options.add(new Option(c.name, c.i, false, c.i == selectedCulture)));
}
// add line for each burg
function burgsOverviewAddLines() {
const selectedState = +document.getElementById("burgsFilterState").value;
const selectedCulture = +document.getElementById("burgsFilterCulture").value;
let filtered = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
if (selectedState != -1) filtered = filtered.filter(b => b.state === selectedState); // filtered by state
if (selectedCulture != -1) filtered = filtered.filter(b => b.culture === selectedCulture); // filtered by culture
const selectedState = +document.getElementById('burgsFilterState').value;
const selectedCulture = +document.getElementById('burgsFilterCulture').value;
let filtered = pack.burgs.filter((b) => b.i && !b.removed); // all valid burgs
if (selectedState != -1) filtered = filtered.filter((b) => b.state === selectedState); // filtered by state
if (selectedCulture != -1) filtered = filtered.filter((b) => b.culture === selectedCulture); // filtered by culture
body.innerHTML = "";
let lines = "", totalPopulation = 0;
body.innerHTML = '';
let lines = '',
totalPopulation = 0;
for (const b of filtered) {
const population = b.population * populationRate.value * urbanization.value;
totalPopulation += population;
const type = b.capital && b.port ? "a-capital-port" : b.capital ? "c-capital" : b.port ? "p-port" : "z-burg";
const type = b.capital && b.port ? 'a-capital-port' : b.capital ? 'c-capital' : b.port ? 'p-port' : 'z-burg';
const state = pack.states[b.state].name;
const prov = pack.cells.province[b.cell];
const province = prov ? pack.provinces[prov].name : "";
const province = prov ? pack.provinces[prov].name : '';
const culture = pack.cultures[b.culture].name;
lines += `<div class="states" data-id=${b.i} data-name="${b.name}" data-state="${state}" data-province="${province}" data-culture="${culture}" data-population=${population} data-type="${type}">
@ -90,47 +96,47 @@ function overviewBurgs() {
<span data-tip="Remove burg" class="icon-trash-empty"></span>
</div>`;
}
body.insertAdjacentHTML("beforeend", lines);
body.insertAdjacentHTML('beforeend', lines);
// update footer
burgsFooterBurgs.innerHTML = filtered.length;
burgsFooterPopulation.innerHTML = filtered.length ? si(totalPopulation / filtered.length) : 0;
// add listeners
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseenter", ev => burgHighlightOn(ev)));
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => burgHighlightOff(ev)));
body.querySelectorAll("div > input.burgName").forEach(el => el.addEventListener("input", changeBurgName));
body.querySelectorAll("div > span.icon-dot-circled").forEach(el => el.addEventListener("click", zoomIntoBurg));
body.querySelectorAll("div > select.stateCulture").forEach(el => el.addEventListener("change", changeBurgCulture));
body.querySelectorAll("div > input.burgPopulation").forEach(el => el.addEventListener("change", changeBurgPopulation));
body.querySelectorAll("div > span.icon-star-empty").forEach(el => el.addEventListener("click", toggleCapitalStatus));
body.querySelectorAll("div > span.icon-anchor").forEach(el => el.addEventListener("click", togglePortStatus));
body.querySelectorAll("div > span.locks").forEach(el => el.addEventListener("click", toggleBurgLockStatus));
body.querySelectorAll("div > span.locks").forEach(el => el.addEventListener("mouseover", showBurgOLockTip));
body.querySelectorAll("div > span.icon-pencil").forEach(el => el.addEventListener("click", openBurgEditor));
body.querySelectorAll("div > span.icon-trash-empty").forEach(el => el.addEventListener("click", triggerBurgRemove));
body.querySelectorAll('div.states').forEach((el) => el.addEventListener('mouseenter', (ev) => burgHighlightOn(ev)));
body.querySelectorAll('div.states').forEach((el) => el.addEventListener('mouseleave', (ev) => burgHighlightOff(ev)));
body.querySelectorAll('div > input.burgName').forEach((el) => el.addEventListener('input', changeBurgName));
body.querySelectorAll('div > span.icon-dot-circled').forEach((el) => el.addEventListener('click', zoomIntoBurg));
body.querySelectorAll('div > select.stateCulture').forEach((el) => el.addEventListener('change', changeBurgCulture));
body.querySelectorAll('div > input.burgPopulation').forEach((el) => el.addEventListener('change', changeBurgPopulation));
body.querySelectorAll('div > span.icon-star-empty').forEach((el) => el.addEventListener('click', toggleCapitalStatus));
body.querySelectorAll('div > span.icon-anchor').forEach((el) => el.addEventListener('click', togglePortStatus));
body.querySelectorAll('div > span.locks').forEach((el) => el.addEventListener('click', toggleBurgLockStatus));
body.querySelectorAll('div > span.locks').forEach((el) => el.addEventListener('mouseover', showBurgOLockTip));
body.querySelectorAll('div > span.icon-pencil').forEach((el) => el.addEventListener('click', openBurgEditor));
body.querySelectorAll('div > span.icon-trash-empty').forEach((el) => el.addEventListener('click', triggerBurgRemove));
applySorting(burgsHeader);
}
function getCultureOptions(culture) {
let options = "";
pack.cultures.filter(c => !c.removed).forEach(c => options += `<option ${c.i === culture ? "selected" : ""} value="${c.i}">${c.name}</option>`);
let options = '';
pack.cultures.filter((c) => !c.removed).forEach((c) => (options += `<option ${c.i === culture ? 'selected' : ''} value="${c.i}">${c.name}</option>`));
return options;
}
function burgHighlightOn(event) {
if (!layerIsOn("toggleLabels")) toggleLabels();
if (!layerIsOn('toggleLabels')) toggleLabels();
const burg = +event.target.dataset.id;
burgLabels.select("[data-id='" + burg + "']").classed("drag", true);
burgLabels.select("[data-id='" + burg + "']").classed('drag', true);
}
function burgHighlightOff() {
burgLabels.selectAll("text.drag").classed("drag", false);
burgLabels.selectAll('text.drag').classed('drag', false);
}
function changeBurgName() {
if (this.value == "")tip("Please provide a name", false, "error");
if (this.value == '') tip('Please provide a name', false, 'error');
const burg = +this.parentNode.dataset.id;
pack.burgs[burg].name = this.value;
this.parentNode.dataset.name = this.value;
@ -141,7 +147,8 @@ function overviewBurgs() {
function zoomIntoBurg() {
const burg = +this.parentNode.dataset.id;
const label = document.querySelector("#burgLabels [data-id='" + burg + "']");
const x = +label.getAttribute("x"), y = +label.getAttribute("y");
const x = +label.getAttribute('x'),
y = +label.getAttribute('y');
zoomTo(x, y, 8, 2000);
}
@ -154,8 +161,8 @@ function overviewBurgs() {
function changeBurgPopulation() {
const burg = +this.parentNode.dataset.id;
if (this.value == "" || isNaN(+this.value)) {
tip("Please provide an integer number (like 10000, not 10K)", false, "error");
if (this.value == '' || isNaN(+this.value)) {
tip('Please provide an integer number (like 10000, not 10K)', false, 'error');
this.value = si(pack.burgs[burg].population * populationRate.value * urbanization.value);
return;
}
@ -164,7 +171,7 @@ function overviewBurgs() {
this.value = si(this.value);
const population = [];
body.querySelectorAll(":scope > div").forEach(el => population.push(+getInteger(el.dataset.population)));
body.querySelectorAll(':scope > div').forEach((el) => population.push(+getInteger(el.dataset.population)));
burgsFooterPopulation.innerHTML = si(d3.mean(population));
}
@ -177,15 +184,22 @@ function overviewBurgs() {
function togglePortStatus() {
const burg = +this.parentNode.parentNode.dataset.id;
togglePort(burg);
if (this.classList.contains("inactive")) this.classList.remove("inactive");
else this.classList.add("inactive");
if (this.classList.contains('inactive')) this.classList.remove('inactive');
else this.classList.add('inactive');
}
function toggleBurgLockStatus() {
const burg = +this.parentNode.dataset.id;
toggleBurgLock(burg);
if (this.classList.contains("icon-lock")) {this.classList.remove("icon-lock"); this.classList.add("icon-lock-open"); this.classList.add("inactive");}
else {this.classList.remove("icon-lock-open"); this.classList.add("icon-lock"); this.classList.remove("inactive");}
if (this.classList.contains('icon-lock')) {
this.classList.remove('icon-lock');
this.classList.add('icon-lock-open');
this.classList.add('inactive');
} else {
this.classList.remove('icon-lock-open');
this.classList.add('icon-lock');
this.classList.remove('inactive');
}
}
function showBurgOLockTip() {
@ -200,29 +214,27 @@ function overviewBurgs() {
function triggerBurgRemove() {
const burg = +this.parentNode.dataset.id;
if (pack.burgs[burg].capital) {tip("You cannot remove the capital. Please change the capital first", false, "error"); return;}
if (pack.burgs[burg].capital) {
tip('You cannot remove the capital. Please change the capital first', false, 'error');
return;
}
alertMessage.innerHTML = "Are you sure you want to remove the burg?";
$("#alert").dialog({resizable: false, title: "Remove burg",
buttons: {
Remove: function() {
$(this).dialog("close");
removeBurg(burg);
burgsOverviewAddLines();
},
Cancel: function() {$(this).dialog("close");}
}
});
const message = 'Are you sure you want to remove the burg? <br>This action cannot be reverted';
const onConfirm = () => {
removeBurg(burg);
burgsOverviewAddLines();
};
confirmationDialog({title: 'Remove burg', message, confirm: 'Remove', onConfirm});
}
function regenerateNames() {
body.querySelectorAll(":scope > div").forEach(function(el) {
body.querySelectorAll(':scope > div').forEach(function (el) {
const burg = +el.dataset.id;
//if (pack.burgs[burg].lock) return;
const culture = pack.burgs[burg].culture;
const name = Names.getCulture(culture);
if (!pack.burgs[burg].lock) {
el.querySelector(".burgName").value = name;
el.querySelector('.burgName').value = name;
pack.burgs[burg].name = el.dataset.name = name;
burgLabels.select("[data-id='" + burg + "']").text(name);
}
@ -230,18 +242,27 @@ function overviewBurgs() {
}
function enterAddBurgMode() {
if (this.classList.contains("pressed")) {exitAddBurgMode(); return;};
if (this.classList.contains('pressed')) {
exitAddBurgMode();
return;
}
customization = 3;
this.classList.add("pressed");
tip("Click on the map to create a new burg. Hold Shift to add multiple", true, "warn");
viewbox.style("cursor", "crosshair").on("click", addBurgOnClick);
this.classList.add('pressed');
tip('Click on the map to create a new burg. Hold Shift to add multiple', true, 'warn');
viewbox.style('cursor', 'crosshair').on('click', addBurgOnClick);
}
function addBurgOnClick() {
const point = d3.mouse(this);
const cell = findCell(point[0], point[1]);
if (pack.cells.h[cell] < 20) {tip("You cannot place state into the water. Please click on a land cell", false, "error"); return;}
if (pack.cells.burg[cell]) {tip("There is already a burg in this cell. Please select a free cell", false, "error"); return;}
if (pack.cells.h[cell] < 20) {
tip('You cannot place state into the water. Please click on a land cell', false, 'error');
return;
}
if (pack.cells.burg[cell]) {
tip('There is already a burg in this cell. Please select a free cell', false, 'error');
return;
}
addBurg(point); // add new burg
if (d3.event.shiftKey === false) {
@ -254,31 +275,37 @@ function overviewBurgs() {
customization = 0;
restoreDefaultEvents();
clearMainTip();
if (addBurgTool.classList.contains("pressed")) addBurgTool.classList.remove("pressed");
if (addNewBurg.classList.contains("pressed")) addNewBurg.classList.remove("pressed");
if (addBurgTool.classList.contains('pressed')) addBurgTool.classList.remove('pressed');
if (addNewBurg.classList.contains('pressed')) addNewBurg.classList.remove('pressed');
}
function showBurgsChart() {
// build hierarchy tree
const states = pack.states.map(s => {
const color = s.color ? s.color : "#ccc";
const states = pack.states.map((s) => {
const color = s.color ? s.color : '#ccc';
const name = s.fullName ? s.fullName : s.name;
return {id:s.i, state: s.i ? 0 : null, color, name}
});
const burgs = pack.burgs.filter(b => b.i && !b.removed).map(b => {
const id = b.i+states.length-1;
const population = b.population;
const capital = b.capital;
const province = pack.cells.province[b.cell];
const parent = province ? province + states.length-1 : b.state;
return {id, i:b.i, state:b.state, culture:b.culture, province, parent, name:b.name, population, capital, x:b.x, y:b.y}
return {id: s.i, state: s.i ? 0 : null, color, name};
});
const burgs = pack.burgs
.filter((b) => b.i && !b.removed)
.map((b) => {
const id = b.i + states.length - 1;
const population = b.population;
const capital = b.capital;
const province = pack.cells.province[b.cell];
const parent = province ? province + states.length - 1 : b.state;
return {id, i: b.i, state: b.state, culture: b.culture, province, parent, name: b.name, population, capital, x: b.x, y: b.y};
});
const data = states.concat(burgs);
const root = d3.stratify().parentId(d => d.state)(data)
.sum(d => d.population).sort((a, b) => b.value - a.value);
const root = d3
.stratify()
.parentId((d) => d.state)(data)
.sum((d) => d.population)
.sort((a, b) => b.value - a.value);
const width = 150 + 200 * uiSizeOutput.value, height = 150 + 200 * uiSizeOutput.value;
const width = 150 + 200 * uiSizeOutput.value,
height = 150 + 200 * uiSizeOutput.value;
const margin = {top: 0, right: -50, bottom: -10, left: -50};
const w = width - margin.left - margin.right;
const h = height - margin.top - margin.bottom;
@ -291,130 +318,155 @@ function overviewBurgs() {
<option value="parent">Group by province and state</option>
<option value="provinces">Group by province</option></select>`;
alertMessage.innerHTML += `<div id='burgsInfo' class='chartInfo'>&#8205;</div>`;
const svg = d3.select("#alertMessage").insert("svg", "#burgsInfo").attr("id", "burgsTree")
.attr("width", width).attr("height", height-10).attr("stroke-width", 2);
const graph = svg.append("g").attr("transform", `translate(-50, -10)`);
document.getElementById("burgsTreeType").addEventListener("change", updateChart);
const svg = d3
.select('#alertMessage')
.insert('svg', '#burgsInfo')
.attr('id', 'burgsTree')
.attr('width', width)
.attr('height', height - 10)
.attr('stroke-width', 2);
const graph = svg.append('g').attr('transform', `translate(-50, -10)`);
document.getElementById('burgsTreeType').addEventListener('change', updateChart);
treeLayout(root);
const node = graph.selectAll("circle").data(root.leaves())
.join("circle").attr("data-id", d => d.data.i)
.attr("r", d => d.r).attr("fill", d => d.parent.data.color)
.attr("cx", d => d.x).attr("cy", d => d.y)
.on("mouseenter", d => showInfo(event, d))
.on("mouseleave", d => hideInfo(event, d))
.on("click", d => zoomTo(d.data.x, d.data.y, 8, 2000));
const node = graph
.selectAll('circle')
.data(root.leaves())
.join('circle')
.attr('data-id', (d) => d.data.i)
.attr('r', (d) => d.r)
.attr('fill', (d) => d.parent.data.color)
.attr('cx', (d) => d.x)
.attr('cy', (d) => d.y)
.on('mouseenter', (d) => showInfo(event, d))
.on('mouseleave', (d) => hideInfo(event, d))
.on('click', (d) => zoomTo(d.data.x, d.data.y, 8, 2000));
function showInfo(ev, d) {
d3.select(ev.target).transition().duration(1500).attr("stroke", "#c13119");
d3.select(ev.target).transition().duration(1500).attr('stroke', '#c13119');
const name = d.data.name;
const parent = d.parent.data.name;
const population = si(d.value * populationRate.value * urbanization.value);
burgsInfo.innerHTML = `${name}. ${parent}. Population: ${population}`;
burgHighlightOn(ev);
tip("Click to zoom into view");
tip('Click to zoom into view');
}
function hideInfo(ev) {
burgHighlightOff(ev);
if (!document.getElementById("burgsInfo")) return;
burgsInfo.innerHTML = "&#8205;";
d3.select(ev.target).transition().attr("stroke", null);
tip("");
if (!document.getElementById('burgsInfo')) return;
burgsInfo.innerHTML = '&#8205;';
d3.select(ev.target).transition().attr('stroke', null);
tip('');
}
function updateChart() {
const getStatesData = () => pack.states.map(s => {
const color = s.color ? s.color : "#ccc";
const name = s.fullName ? s.fullName : s.name;
return {id:s.i, state: s.i ? 0 : null, color, name}
});
const getStatesData = () =>
pack.states.map((s) => {
const color = s.color ? s.color : '#ccc';
const name = s.fullName ? s.fullName : s.name;
return {id: s.i, state: s.i ? 0 : null, color, name};
});
const getCulturesData = () => pack.cultures.map(c => {
const color = c.color ? c.color : "#ccc";
return {id:c.i, culture: c.i ? 0 : null, color, name:c.name}
});
const getCulturesData = () =>
pack.cultures.map((c) => {
const color = c.color ? c.color : '#ccc';
return {id: c.i, culture: c.i ? 0 : null, color, name: c.name};
});
const getParentData = () => {
const states = pack.states.map(s => {
const color = s.color ? s.color : "#ccc";
const states = pack.states.map((s) => {
const color = s.color ? s.color : '#ccc';
const name = s.fullName ? s.fullName : s.name;
return {id:s.i, parent: s.i ? 0 : null, color, name}
});
const provinces = pack.provinces.filter(p => p.i && !p.removed).map(p => {
return {id:p.i + states.length-1, parent: p.state, color:p.color, name:p.fullName}
return {id: s.i, parent: s.i ? 0 : null, color, name};
});
const provinces = pack.provinces
.filter((p) => p.i && !p.removed)
.map((p) => {
return {id: p.i + states.length - 1, parent: p.state, color: p.color, name: p.fullName};
});
return states.concat(provinces);
}
};
const getProvincesData = () => pack.provinces.map(p => {
const color = p.color ? p.color : "#ccc";
const name = p.fullName ? p.fullName : p.name;
return {id:p.i ? p.i : 0, province: p.i ? 0 : null, color, name}
});
const getProvincesData = () =>
pack.provinces.map((p) => {
const color = p.color ? p.color : '#ccc';
const name = p.fullName ? p.fullName : p.name;
return {id: p.i ? p.i : 0, province: p.i ? 0 : null, color, name};
});
const value = d => {
if (this.value === "states") return d.state;
if (this.value === "cultures") return d.culture;
if (this.value === "parent") return d.parent;
if (this.value === "provinces") return d.province;
}
const value = (d) => {
if (this.value === 'states') return d.state;
if (this.value === 'cultures') return d.culture;
if (this.value === 'parent') return d.parent;
if (this.value === 'provinces') return d.province;
};
const base = this.value === "states" ? getStatesData()
: this.value === "cultures" ? getCulturesData()
: this.value === "parent" ? getParentData() : getProvincesData();
burgs.forEach(b => b.id = b.i+base.length-1);
const base = this.value === 'states' ? getStatesData() : this.value === 'cultures' ? getCulturesData() : this.value === 'parent' ? getParentData() : getProvincesData();
burgs.forEach((b) => (b.id = b.i + base.length - 1));
const data = base.concat(burgs);
const root = d3.stratify().parentId(d => value(d))(data)
.sum(d => d.population).sort((a, b) => b.value - a.value);
const root = d3
.stratify()
.parentId((d) => value(d))(data)
.sum((d) => d.population)
.sort((a, b) => b.value - a.value);
node.data(treeLayout(root).leaves()).transition().duration(2000)
.attr("data-id", d => d.data.i).attr("fill", d => d.parent.data.color)
.attr("cx", d => d.x).attr("cy", d => d.y).attr("r", d => d.r);
node
.data(treeLayout(root).leaves())
.transition()
.duration(2000)
.attr('data-id', (d) => d.data.i)
.attr('fill', (d) => d.parent.data.color)
.attr('cx', (d) => d.x)
.attr('cy', (d) => d.y)
.attr('r', (d) => d.r);
}
$("#alert").dialog({
title: "Burgs bubble chart", width: fitContent(),
position: {my: "left bottom", at: "left+10 bottom-10", of: "svg"}, buttons: {},
close: () => {alertMessage.innerHTML = "";}
$('#alert').dialog({
title: 'Burgs bubble chart',
width: fitContent(),
position: {my: 'left bottom', at: 'left+10 bottom-10', of: 'svg'},
buttons: {},
close: () => {
alertMessage.innerHTML = '';
}
});
}
function downloadBurgsData() {
let data = "Id,Burg,Province,State,Culture,Religion,Population,Longitude,Latitude,Elevation ("+heightUnit.value+"),Capital,Port,Citadel,Walls,Plaza,Temple,Shanty Town\n"; // headers
const valid = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
let data = 'Id,Burg,Province,State,Culture,Religion,Population,Longitude,Latitude,Elevation (' + heightUnit.value + '),Capital,Port,Citadel,Walls,Plaza,Temple,Shanty Town\n'; // headers
const valid = pack.burgs.filter((b) => b.i && !b.removed); // all valid burgs
valid.forEach(b => {
data += b.i + ",";
data += b.name + ",";
valid.forEach((b) => {
data += b.i + ',';
data += b.name + ',';
const province = pack.cells.province[b.cell];
data += province ? pack.provinces[province].fullName + "," : ",";
data += b.state ? pack.states[b.state].fullName +"," : pack.states[b.state].name + ",";
data += pack.cultures[b.culture].name + ",";
data += pack.religions[pack.cells.religion[b.cell]].name + ",";
data += rn(b.population * populationRate.value * urbanization.value) + ",";
data += province ? pack.provinces[province].fullName + ',' : ',';
data += b.state ? pack.states[b.state].fullName + ',' : pack.states[b.state].name + ',';
data += pack.cultures[b.culture].name + ',';
data += pack.religions[pack.cells.religion[b.cell]].name + ',';
data += rn(b.population * populationRate.value * urbanization.value) + ',';
// add geography data
data += mapCoordinates.lonW + (b.x / graphWidth) * mapCoordinates.lonT + ",";
data += mapCoordinates.latN - (b.y / graphHeight) * mapCoordinates.latT + ","; // this is inverted in QGIS otherwise
data += parseInt(getHeight(pack.cells.h[b.cell])) + ",";
data += mapCoordinates.lonW + (b.x / graphWidth) * mapCoordinates.lonT + ',';
data += mapCoordinates.latN - (b.y / graphHeight) * mapCoordinates.latT + ','; // this is inverted in QGIS otherwise
data += parseInt(getHeight(pack.cells.h[b.cell])) + ',';
// add status data
data += b.capital ? "capital," : ",";
data += b.port ? "port," : ",";
data += b.citadel ? "citadel," : ",";
data += b.walls ? "walls," : ",";
data += b.plaza ? "plaza," : ",";
data += b.temple ? "temple," : ",";
data += b.shanty ? "shanty town\n" : "\n";
data += b.capital ? 'capital,' : ',';
data += b.port ? 'port,' : ',';
data += b.citadel ? 'citadel,' : ',';
data += b.walls ? 'walls,' : ',';
data += b.plaza ? 'plaza,' : ',';
data += b.temple ? 'temple,' : ',';
data += b.shanty ? 'shanty town\n' : '\n';
});
const name = getFileName("Burgs") + ".csv";
const name = getFileName('Burgs') + '.csv';
downloadFile(data, name);
}
@ -423,49 +475,67 @@ function overviewBurgs() {
If you do not want to change the name, just leave it as is`;
alertMessage.innerHTML = message;
$("#alert").dialog({title: "Burgs bulk renaming", width:"22em",
position: {my: "center", at: "center", of: "svg"},
$('#alert').dialog({
title: 'Burgs bulk renaming',
width: '22em',
position: {my: 'center', at: 'center', of: 'svg'},
buttons: {
Download: function() {
const data = pack.burgs.filter(b => b.i && !b.removed).map(b => b.name).join("\r\n");
const name = getFileName("Burg names") + ".txt";
Download: function () {
const data = pack.burgs
.filter((b) => b.i && !b.removed)
.map((b) => b.name)
.join('\r\n');
const name = getFileName('Burg names') + '.txt';
downloadFile(data, name);
},
Upload: () => burgsListToLoad.click(),
Cancel: function() {$(this).dialog("close");}
Cancel: function () {
$(this).dialog('close');
}
}
});
}
function importBurgNames(dataLoaded) {
if (!dataLoaded) {tip("Cannot load the file, please check the format", false, "error"); return;}
const data = dataLoaded.split("\r\n");
if (!data.length) {tip("Cannot parse the list, please check the file format", false, "error"); return;}
if (!dataLoaded) {
tip('Cannot load the file, please check the format', false, 'error');
return;
}
const data = dataLoaded.split('\r\n');
if (!data.length) {
tip('Cannot parse the list, please check the file format', false, 'error');
return;
}
let change = [], message = `Burgs will be renamed as below. Please confirm`;
let change = [],
message = `Burgs will be renamed as below. Please confirm`;
message += `<table class="overflow-table"><tr><th>Id</th><th>Current name</th><th>New Name</th></tr>`;
const burgs = pack.burgs.filter(b => b.i && !b.removed);
for (let i=0; i < data.length && i <= burgs.length; i++) {
const burgs = pack.burgs.filter((b) => b.i && !b.removed);
for (let i = 0; i < data.length && i <= burgs.length; i++) {
const v = data[i];
if (!v || !burgs[i] || v == burgs[i].name) continue;
change.push({id:burgs[i].i, name: v});
change.push({id: burgs[i].i, name: v});
message += `<tr><td style="width:20%">${burgs[i].i}</td><td style="width:40%">${burgs[i].name}</td><td style="width:40%">${v}</td></tr>`;
}
message += `</tr></table>`;
if (!change.length) message = "No changes found in the file. Please change some names to get a result"
if (!change.length) message = 'No changes found in the file. Please change some names to get a result';
alertMessage.innerHTML = message;
$("#alert").dialog({title: "Burgs bulk renaming", width:"22em",
position: {my: "center", at: "center", of: "svg"},
$('#alert').dialog({
title: 'Burgs bulk renaming',
width: '22em',
position: {my: 'center', at: 'center', of: 'svg'},
buttons: {
Cancel: function() {$(this).dialog("close");},
Confirm: function() {
for (let i=0; i < change.length; i++) {
Cancel: function () {
$(this).dialog('close');
},
Confirm: function () {
for (let i = 0; i < change.length; i++) {
const id = change[i].id;
pack.burgs[id].name = change[i].name;
burgLabels.select("[data-id='" + id + "']").text(change[i].name);
}
$(this).dialog("close");
$(this).dialog('close');
burgsOverviewAddLines();
}
}
@ -473,21 +543,12 @@ function overviewBurgs() {
}
function triggerAllBurgsRemove() {
alertMessage.innerHTML = `Are you sure you want to remove all unlocked burgs except for capitals?
<br><i>To remove a capital you have to remove a state first</i>`;
$("#alert").dialog({resizable: false, title: "Remove all burgs",
buttons: {
Remove: function() {
$(this).dialog("close");
removeAllBurgs();
},
Cancel: function() {$(this).dialog("close");}
}
});
const message = 'Are you sure you want to remove all unlocked burgs except for capitals?<br><i>To remove a capital you have to remove the state first</i>';
confirmationDialog({title: 'Remove all burgs', message, confirm: 'Remove', onConfirm: removeAllBurgs});
}
function removeAllBurgs() {
pack.burgs.filter(b => b.i && !(b.capital || b.lock)).forEach(b => removeBurg(b.i));
pack.burgs.filter((b) => b.i && !(b.capital || b.lock)).forEach((b) => removeBurg(b.i));
burgsOverviewAddLines();
}
}