mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-24 13:01:24 +01:00
merge completed... now to fix all the bugs...
This commit is contained in:
commit
87c4d80fbc
3472 changed files with 466748 additions and 6517 deletions
|
|
@ -1,83 +1,83 @@
|
|||
"use strict";
|
||||
'use strict';
|
||||
|
||||
function editZones() {
|
||||
closeDialogs();
|
||||
if (!layerIsOn("toggleZones")) toggleZones();
|
||||
const body = document.getElementById("zonesBodySection");
|
||||
if (!layerIsOn('toggleZones')) toggleZones();
|
||||
const body = document.getElementById('zonesBodySection');
|
||||
zonesEditorAddLines();
|
||||
|
||||
if (modules.editZones) return;
|
||||
modules.editZones = true;
|
||||
|
||||
$("#zonesEditor").dialog({
|
||||
title: "Zones Editor",
|
||||
$('#zonesEditor').dialog({
|
||||
title: 'Zones Editor',
|
||||
resizable: false,
|
||||
width: fitContent(),
|
||||
close: () => exitZonesManualAssignment("close"),
|
||||
position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
|
||||
close: () => exitZonesManualAssignment('close'),
|
||||
position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}
|
||||
});
|
||||
|
||||
// add listeners
|
||||
document.getElementById("zonesEditorRefresh").addEventListener("click", zonesEditorAddLines);
|
||||
document.getElementById("zonesEditStyle").addEventListener("click", () => editStyle("zones"));
|
||||
document.getElementById("zonesLegend").addEventListener("click", toggleLegend);
|
||||
document.getElementById("zonesPercentage").addEventListener("click", togglePercentageMode);
|
||||
document.getElementById("zonesManually").addEventListener("click", enterZonesManualAssignent);
|
||||
document.getElementById("zonesManuallyApply").addEventListener("click", applyZonesManualAssignent);
|
||||
document.getElementById("zonesManuallyCancel").addEventListener("click", cancelZonesManualAssignent);
|
||||
document.getElementById("zonesAdd").addEventListener("click", addZonesLayer);
|
||||
document.getElementById("zonesExport").addEventListener("click", downloadZonesData);
|
||||
document.getElementById("zonesRemove").addEventListener("click", toggleEraseMode);
|
||||
document.getElementById('zonesEditorRefresh').addEventListener('click', zonesEditorAddLines);
|
||||
document.getElementById('zonesEditStyle').addEventListener('click', () => editStyle('zones'));
|
||||
document.getElementById('zonesLegend').addEventListener('click', toggleLegend);
|
||||
document.getElementById('zonesPercentage').addEventListener('click', togglePercentageMode);
|
||||
document.getElementById('zonesManually').addEventListener('click', enterZonesManualAssignent);
|
||||
document.getElementById('zonesManuallyApply').addEventListener('click', applyZonesManualAssignent);
|
||||
document.getElementById('zonesManuallyCancel').addEventListener('click', cancelZonesManualAssignent);
|
||||
document.getElementById('zonesAdd').addEventListener('click', addZonesLayer);
|
||||
document.getElementById('zonesExport').addEventListener('click', downloadZonesData);
|
||||
document.getElementById('zonesRemove').addEventListener('click', toggleEraseMode);
|
||||
|
||||
body.addEventListener("click", function (ev) {
|
||||
body.addEventListener('click', function (ev) {
|
||||
const el = ev.target,
|
||||
cl = el.classList,
|
||||
zone = el.parentNode.dataset.id;
|
||||
if (cl.contains("culturePopulation")) {
|
||||
if (cl.contains('culturePopulation')) {
|
||||
changePopulation(zone);
|
||||
return;
|
||||
}
|
||||
if (cl.contains("icon-trash-empty")) {
|
||||
if (cl.contains('icon-trash-empty')) {
|
||||
zoneRemove(zone);
|
||||
return;
|
||||
}
|
||||
if (cl.contains("icon-eye")) {
|
||||
if (cl.contains('icon-eye')) {
|
||||
toggleVisibility(el);
|
||||
return;
|
||||
}
|
||||
if (cl.contains("icon-pin")) {
|
||||
if (cl.contains('icon-pin')) {
|
||||
toggleFog(zone, cl);
|
||||
return;
|
||||
}
|
||||
if (cl.contains("fillRect")) {
|
||||
if (cl.contains('fillRect')) {
|
||||
changeFill(el);
|
||||
return;
|
||||
}
|
||||
if (customization) selectZone(el);
|
||||
});
|
||||
|
||||
body.addEventListener("input", function (ev) {
|
||||
body.addEventListener('input', function (ev) {
|
||||
const el = ev.target,
|
||||
zone = el.parentNode.dataset.id;
|
||||
if (el.classList.contains("religionName")) zones.select("#" + zone).attr("data-description", el.value);
|
||||
if (el.classList.contains('religionName')) zones.select('#' + zone).attr('data-description', el.value);
|
||||
});
|
||||
|
||||
// add line for each zone
|
||||
function zonesEditorAddLines() {
|
||||
const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value;
|
||||
let lines = "";
|
||||
const unit = areaUnit.value === 'square' ? ' ' + distanceUnitInput.value + '²' : ' ' + areaUnit.value;
|
||||
let lines = '';
|
||||
|
||||
zones.selectAll("g").each(function () {
|
||||
const c = this.dataset.cells ? this.dataset.cells.split(",").map(c => +c) : [];
|
||||
zones.selectAll('g').each(function () {
|
||||
const c = this.dataset.cells ? this.dataset.cells.split(',').map((c) => +c) : [];
|
||||
const description = this.dataset.description;
|
||||
const fill = this.getAttribute("fill");
|
||||
const area = d3.sum(c.map(i => pack.cells.area[i])) * distanceScaleInput.value ** 2;
|
||||
const rural = d3.sum(c.map(i => pack.cells.pop[i])) * populationRate;
|
||||
const urban = d3.sum(c.map(i => pack.cells.burg[i]).map(b => pack.burgs[b].population)) * populationRate * urbanization;
|
||||
const fill = this.getAttribute('fill');
|
||||
const area = d3.sum(c.map((i) => pack.cells.area[i])) * distanceScaleInput.value ** 2;
|
||||
const rural = d3.sum(c.map((i) => pack.cells.pop[i])) * populationRate;
|
||||
const urban = d3.sum(c.map((i) => pack.cells.burg[i]).map((b) => pack.burgs[b].population)) * populationRate * urbanization;
|
||||
const population = rural + urban;
|
||||
const populationTip = `Total population: ${si(population)}; Rural population: ${si(rural)}; Urban population: ${si(urban)}. Click to change`;
|
||||
const inactive = this.style.display === "none";
|
||||
const focused = defs.select("#fog #focus" + this.id).size();
|
||||
const inactive = this.style.display === 'none';
|
||||
const focused = defs.select('#fog #focus' + this.id).size();
|
||||
|
||||
lines += `<div class="states" data-id="${this.id}" data-fill="${fill}" data-description="${description}" data-cells=${c.length} data-area=${area} data-population=${population}>
|
||||
<svg data-tip="Zone fill style. Click to change" width=".9em" height=".9em" style="margin-bottom:-1px"><rect x="0" y="0" width="100%" height="100%" fill="${fill}" class="fillRect pointer"></svg>
|
||||
|
|
@ -89,8 +89,8 @@ function editZones() {
|
|||
<span data-tip="${populationTip}" class="icon-male hide"></span>
|
||||
<div data-tip="${populationTip}" class="culturePopulation hide">${si(population)}</div>
|
||||
<span data-tip="Drag to raise or lower the zone" class="icon-resize-vertical hide"></span>
|
||||
<span data-tip="Toggle zone focus" class="icon-pin ${focused ? "" : " inactive"} hide ${c.length ? "" : " placeholder"}"></span>
|
||||
<span data-tip="Toggle zone visibility" class="icon-eye ${inactive ? " inactive" : ""} hide ${c.length ? "" : " placeholder"}"></span>
|
||||
<span data-tip="Toggle zone focus" class="icon-pin ${focused ? '' : ' inactive'} hide ${c.length ? '' : ' placeholder'}"></span>
|
||||
<span data-tip="Toggle zone visibility" class="icon-eye ${inactive ? ' inactive' : ''} hide ${c.length ? '' : ' placeholder'}"></span>
|
||||
<span data-tip="Remove zone" class="icon-trash-empty hide"></span>
|
||||
</div>`;
|
||||
});
|
||||
|
|
@ -99,73 +99,73 @@ function editZones() {
|
|||
|
||||
// update footer
|
||||
const totalArea = (zonesFooterArea.dataset.area = graphWidth * graphHeight * distanceScaleInput.value ** 2);
|
||||
const totalPop = (d3.sum(pack.cells.pop) + d3.sum(pack.burgs.filter(b => !b.removed).map(b => b.population)) * urbanization) * populationRate;
|
||||
const totalPop = (d3.sum(pack.cells.pop) + d3.sum(pack.burgs.filter((b) => !b.removed).map((b) => b.population)) * urbanization) * populationRate;
|
||||
zonesFooterPopulation.dataset.population = totalPop;
|
||||
zonesFooterNumber.innerHTML = zones.selectAll("g").size();
|
||||
zonesFooterNumber.innerHTML = zones.selectAll('g').size();
|
||||
zonesFooterCells.innerHTML = pack.cells.i.length;
|
||||
zonesFooterArea.innerHTML = si(totalArea) + unit;
|
||||
zonesFooterPopulation.innerHTML = si(totalPop);
|
||||
|
||||
// add listeners
|
||||
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseenter", ev => zoneHighlightOn(ev)));
|
||||
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => zoneHighlightOff(ev)));
|
||||
body.querySelectorAll('div.states').forEach((el) => el.addEventListener('mouseenter', (ev) => zoneHighlightOn(ev)));
|
||||
body.querySelectorAll('div.states').forEach((el) => el.addEventListener('mouseleave', (ev) => zoneHighlightOff(ev)));
|
||||
|
||||
if (body.dataset.type === "percentage") {
|
||||
body.dataset.type = "absolute";
|
||||
if (body.dataset.type === 'percentage') {
|
||||
body.dataset.type = 'absolute';
|
||||
togglePercentageMode();
|
||||
}
|
||||
$("#zonesEditor").dialog({width: fitContent()});
|
||||
$('#zonesEditor').dialog({width: fitContent()});
|
||||
}
|
||||
|
||||
function zoneHighlightOn(event) {
|
||||
const zone = event.target.dataset.id;
|
||||
zones.select("#" + zone).style("outline", "1px solid red");
|
||||
zones.select('#' + zone).style('outline', '1px solid red');
|
||||
}
|
||||
|
||||
function zoneHighlightOff(event) {
|
||||
const zone = event.target.dataset.id;
|
||||
zones.select("#" + zone).style("outline", null);
|
||||
zones.select('#' + zone).style('outline', null);
|
||||
}
|
||||
|
||||
$(body).sortable({items: "div.states", handle: ".icon-resize-vertical", containment: "parent", axis: "y", update: movezone});
|
||||
$(body).sortable({items: 'div.states', handle: '.icon-resize-vertical', containment: 'parent', axis: 'y', update: movezone});
|
||||
function movezone(ev, ui) {
|
||||
const zone = $("#" + ui.item.attr("data-id"));
|
||||
const prev = $("#" + ui.item.prev().attr("data-id"));
|
||||
const zone = $('#' + ui.item.attr('data-id'));
|
||||
const prev = $('#' + ui.item.prev().attr('data-id'));
|
||||
if (prev) {
|
||||
zone.insertAfter(prev);
|
||||
return;
|
||||
}
|
||||
const next = $("#" + ui.item.next().attr("data-id"));
|
||||
const next = $('#' + ui.item.next().attr('data-id'));
|
||||
if (next) zone.insertBefore(next);
|
||||
}
|
||||
|
||||
function enterZonesManualAssignent() {
|
||||
if (!layerIsOn("toggleZones")) toggleZones();
|
||||
if (!layerIsOn('toggleZones')) toggleZones();
|
||||
customization = 10;
|
||||
document.querySelectorAll("#zonesBottom > button").forEach(el => (el.style.display = "none"));
|
||||
document.getElementById("zonesManuallyButtons").style.display = "inline-block";
|
||||
document.querySelectorAll('#zonesBottom > button').forEach((el) => (el.style.display = 'none'));
|
||||
document.getElementById('zonesManuallyButtons').style.display = 'inline-block';
|
||||
|
||||
zonesEditor.querySelectorAll(".hide").forEach(el => el.classList.add("hidden"));
|
||||
zonesFooter.style.display = "none";
|
||||
body.querySelectorAll("div > input, select, svg").forEach(e => (e.style.pointerEvents = "none"));
|
||||
$("#zonesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
||||
zonesEditor.querySelectorAll('.hide').forEach((el) => el.classList.add('hidden'));
|
||||
zonesFooter.style.display = 'none';
|
||||
body.querySelectorAll('div > input, select, svg').forEach((e) => (e.style.pointerEvents = 'none'));
|
||||
$('#zonesEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}});
|
||||
|
||||
tip("Click to select a zone, drag to paint a zone", true);
|
||||
viewbox.style("cursor", "crosshair").on("click", selectZoneOnMapClick).call(d3.drag().on("start", dragZoneBrush)).on("touchmove mousemove", moveZoneBrush);
|
||||
tip('Click to select a zone, drag to paint a zone', true);
|
||||
viewbox.style('cursor', 'crosshair').on('click', selectZoneOnMapClick).call(d3.drag().on('start', dragZoneBrush)).on('touchmove mousemove', moveZoneBrush);
|
||||
|
||||
body.querySelector("div").classList.add("selected");
|
||||
zones.selectAll("g").each(function () {
|
||||
this.setAttribute("data-init", this.getAttribute("data-cells"));
|
||||
body.querySelector('div').classList.add('selected');
|
||||
zones.selectAll('g').each(function () {
|
||||
this.setAttribute('data-init', this.getAttribute('data-cells'));
|
||||
});
|
||||
}
|
||||
|
||||
function selectZone(el) {
|
||||
body.querySelector("div.selected").classList.remove("selected");
|
||||
el.classList.add("selected");
|
||||
body.querySelector('div.selected').classList.remove('selected');
|
||||
el.classList.add('selected');
|
||||
}
|
||||
|
||||
function selectZoneOnMapClick() {
|
||||
if (d3.event.target.parentElement.parentElement.id !== "zones") return;
|
||||
if (d3.event.target.parentElement.parentElement.id !== 'zones') return;
|
||||
const zone = d3.event.target.parentElement.id;
|
||||
const el = body.querySelector("div[data-id='" + zone + "']");
|
||||
selectZone(el);
|
||||
|
|
@ -174,7 +174,7 @@ function editZones() {
|
|||
function dragZoneBrush() {
|
||||
const r = +zonesBrush.value;
|
||||
|
||||
d3.event.on("drag", () => {
|
||||
d3.event.on('drag', () => {
|
||||
if (!d3.event.dx && !d3.event.dy) return;
|
||||
const p = d3.mouse(this);
|
||||
moveCircle(p[0], p[1], r);
|
||||
|
|
@ -182,34 +182,34 @@ function editZones() {
|
|||
const selection = r > 5 ? findAll(p[0], p[1], r) : [findCell(p[0], p[1], r)];
|
||||
if (!selection) return;
|
||||
|
||||
const selected = body.querySelector("div.selected");
|
||||
const zone = zones.select("#" + selected.dataset.id);
|
||||
const base = zone.attr("id") + "_"; // id generic part
|
||||
const dataCells = zone.attr("data-cells");
|
||||
let cells = dataCells ? dataCells.split(",").map(i => +i) : [];
|
||||
const selected = body.querySelector('div.selected');
|
||||
const zone = zones.select('#' + selected.dataset.id);
|
||||
const base = zone.attr('id') + '_'; // id generic part
|
||||
const dataCells = zone.attr('data-cells');
|
||||
let cells = dataCells ? dataCells.split(',').map((i) => +i) : [];
|
||||
|
||||
const erase = document.getElementById("zonesRemove").classList.contains("pressed");
|
||||
const erase = document.getElementById('zonesRemove').classList.contains('pressed');
|
||||
if (erase) {
|
||||
// remove
|
||||
selection.forEach(i => {
|
||||
selection.forEach((i) => {
|
||||
const index = cells.indexOf(i);
|
||||
if (index === -1) return;
|
||||
zone.select("polygon#" + base + i).remove();
|
||||
zone.select('polygon#' + base + i).remove();
|
||||
cells.splice(index, 1);
|
||||
});
|
||||
} else {
|
||||
// add
|
||||
selection.forEach(i => {
|
||||
selection.forEach((i) => {
|
||||
if (cells.includes(i)) return;
|
||||
cells.push(i);
|
||||
zone
|
||||
.append("polygon")
|
||||
.attr("points", getPackPolygon(i))
|
||||
.attr("id", base + i);
|
||||
.append('polygon')
|
||||
.attr('points', getPackPolygon(i))
|
||||
.attr('id', base + i);
|
||||
});
|
||||
}
|
||||
|
||||
zone.attr("data-cells", cells);
|
||||
zone.attr('data-cells', cells);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -221,11 +221,11 @@ function editZones() {
|
|||
}
|
||||
|
||||
function applyZonesManualAssignent() {
|
||||
zones.selectAll("g").each(function () {
|
||||
zones.selectAll('g').each(function () {
|
||||
if (this.dataset.cells) return;
|
||||
// all zone cells are removed
|
||||
unfog("focusZone" + this.id);
|
||||
this.style.display = "block";
|
||||
unfog('focusZone' + this.id);
|
||||
this.style.display = 'block';
|
||||
});
|
||||
|
||||
zonesEditorAddLines();
|
||||
|
|
@ -234,20 +234,20 @@ function editZones() {
|
|||
|
||||
// restore initial zone cells
|
||||
function cancelZonesManualAssignent() {
|
||||
zones.selectAll("g").each(function () {
|
||||
zones.selectAll('g').each(function () {
|
||||
const zone = d3.select(this);
|
||||
const dataCells = zone.attr("data-init");
|
||||
const cells = dataCells ? dataCells.split(",").map(i => +i) : [];
|
||||
zone.attr("data-cells", cells);
|
||||
zone.selectAll("*").remove();
|
||||
const base = zone.attr("id") + "_"; // id generic part
|
||||
const dataCells = zone.attr('data-init');
|
||||
const cells = dataCells ? dataCells.split(',').map((i) => +i) : [];
|
||||
zone.attr('data-cells', cells);
|
||||
zone.selectAll('*').remove();
|
||||
const base = zone.attr('id') + '_'; // id generic part
|
||||
zone
|
||||
.selectAll("*")
|
||||
.selectAll('*')
|
||||
.data(cells)
|
||||
.enter()
|
||||
.append("polygon")
|
||||
.attr("points", d => getPackPolygon(d))
|
||||
.attr("id", d => base + d);
|
||||
.append('polygon')
|
||||
.attr('points', (d) => getPackPolygon(d))
|
||||
.attr('id', (d) => base + d);
|
||||
});
|
||||
|
||||
exitZonesManualAssignment();
|
||||
|
|
@ -256,97 +256,97 @@ function editZones() {
|
|||
function exitZonesManualAssignment(close) {
|
||||
customization = 0;
|
||||
removeCircle();
|
||||
document.querySelectorAll("#zonesBottom > button").forEach(el => (el.style.display = "inline-block"));
|
||||
document.getElementById("zonesManuallyButtons").style.display = "none";
|
||||
document.querySelectorAll('#zonesBottom > button').forEach((el) => (el.style.display = 'inline-block'));
|
||||
document.getElementById('zonesManuallyButtons').style.display = 'none';
|
||||
|
||||
zonesEditor.querySelectorAll(".hide:not(.show)").forEach(el => el.classList.remove("hidden"));
|
||||
zonesFooter.style.display = "block";
|
||||
body.querySelectorAll("div > input, select, svg").forEach(e => (e.style.pointerEvents = "all"));
|
||||
if (!close) $("#zonesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
||||
zonesEditor.querySelectorAll('.hide:not(.show)').forEach((el) => el.classList.remove('hidden'));
|
||||
zonesFooter.style.display = 'block';
|
||||
body.querySelectorAll('div > input, select, svg').forEach((e) => (e.style.pointerEvents = 'all'));
|
||||
if (!close) $('#zonesEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}});
|
||||
|
||||
restoreDefaultEvents();
|
||||
clearMainTip();
|
||||
zones.selectAll("g").each(function () {
|
||||
this.removeAttribute("data-init");
|
||||
zones.selectAll('g').each(function () {
|
||||
this.removeAttribute('data-init');
|
||||
});
|
||||
const selected = body.querySelector("div.selected");
|
||||
if (selected) selected.classList.remove("selected");
|
||||
const selected = body.querySelector('div.selected');
|
||||
if (selected) selected.classList.remove('selected');
|
||||
}
|
||||
|
||||
function changeFill(el) {
|
||||
const fill = el.getAttribute("fill");
|
||||
const fill = el.getAttribute('fill');
|
||||
const callback = function (fill) {
|
||||
el.setAttribute("fill", fill);
|
||||
document.getElementById(el.parentNode.parentNode.dataset.id).setAttribute("fill", fill);
|
||||
el.setAttribute('fill', fill);
|
||||
document.getElementById(el.parentNode.parentNode.dataset.id).setAttribute('fill', fill);
|
||||
};
|
||||
|
||||
openPicker(fill, callback);
|
||||
}
|
||||
|
||||
function toggleVisibility(el) {
|
||||
const zone = zones.select("#" + el.parentNode.dataset.id);
|
||||
const inactive = zone.style("display") === "none";
|
||||
inactive ? zone.style("display", "block") : zone.style("display", "none");
|
||||
el.classList.toggle("inactive");
|
||||
const zone = zones.select('#' + el.parentNode.dataset.id);
|
||||
const inactive = zone.style('display') === 'none';
|
||||
inactive ? zone.style('display', 'block') : zone.style('display', 'none');
|
||||
el.classList.toggle('inactive');
|
||||
}
|
||||
|
||||
function toggleFog(z, cl) {
|
||||
const dataCells = zones.select("#" + z).attr("data-cells");
|
||||
const dataCells = zones.select('#' + z).attr('data-cells');
|
||||
if (!dataCells) return;
|
||||
|
||||
const path =
|
||||
"M" +
|
||||
'M' +
|
||||
dataCells
|
||||
.split(",")
|
||||
.map(c => getPackPolygon(+c))
|
||||
.join("M") +
|
||||
"Z",
|
||||
id = "focusZone" + z;
|
||||
cl.contains("inactive") ? fog(id, path) : unfog(id);
|
||||
cl.toggle("inactive");
|
||||
.split(',')
|
||||
.map((c) => getPackPolygon(+c))
|
||||
.join('M') +
|
||||
'Z',
|
||||
id = 'focusZone' + z;
|
||||
cl.contains('inactive') ? fog(id, path) : unfog(id);
|
||||
cl.toggle('inactive');
|
||||
}
|
||||
|
||||
function toggleLegend() {
|
||||
if (legend.selectAll("*").size()) {
|
||||
if (legend.selectAll('*').size()) {
|
||||
clearLegend();
|
||||
return;
|
||||
} // hide legend
|
||||
const data = [];
|
||||
|
||||
zones.selectAll("g").each(function () {
|
||||
zones.selectAll('g').each(function () {
|
||||
const id = this.dataset.id;
|
||||
const description = this.dataset.description;
|
||||
const fill = this.getAttribute("fill");
|
||||
const fill = this.getAttribute('fill');
|
||||
data.push([id, fill, description]);
|
||||
});
|
||||
|
||||
drawLegend("Zones", data);
|
||||
drawLegend('Zones', data);
|
||||
}
|
||||
|
||||
function togglePercentageMode() {
|
||||
if (body.dataset.type === "absolute") {
|
||||
body.dataset.type = "percentage";
|
||||
if (body.dataset.type === 'absolute') {
|
||||
body.dataset.type = 'percentage';
|
||||
const totalCells = +zonesFooterCells.innerHTML;
|
||||
const totalArea = +zonesFooterArea.dataset.area;
|
||||
const totalPopulation = +zonesFooterPopulation.dataset.population;
|
||||
|
||||
body.querySelectorAll(":scope > div").forEach(function (el) {
|
||||
el.querySelector(".stateCells").innerHTML = rn((+el.dataset.cells / totalCells) * 100, 2) + "%";
|
||||
el.querySelector(".biomeArea").innerHTML = rn((+el.dataset.area / totalArea) * 100, 2) + "%";
|
||||
el.querySelector(".culturePopulation").innerHTML = rn((+el.dataset.population / totalPopulation) * 100, 2) + "%";
|
||||
body.querySelectorAll(':scope > div').forEach(function (el) {
|
||||
el.querySelector('.stateCells').innerHTML = rn((+el.dataset.cells / totalCells) * 100, 2) + '%';
|
||||
el.querySelector('.biomeArea').innerHTML = rn((+el.dataset.area / totalArea) * 100, 2) + '%';
|
||||
el.querySelector('.culturePopulation').innerHTML = rn((+el.dataset.population / totalPopulation) * 100, 2) + '%';
|
||||
});
|
||||
} else {
|
||||
body.dataset.type = "absolute";
|
||||
body.dataset.type = 'absolute';
|
||||
zonesEditorAddLines();
|
||||
}
|
||||
}
|
||||
|
||||
function addZonesLayer() {
|
||||
const id = getNextId("zone");
|
||||
const description = "Unknown zone";
|
||||
const fill = "url(#hatch" + (id.slice(4) % 14) + ")";
|
||||
zones.append("g").attr("id", id).attr("data-description", description).attr("data-cells", "").attr("fill", fill);
|
||||
const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value;
|
||||
const id = getNextId('zone');
|
||||
const description = 'Unknown zone';
|
||||
const fill = 'url(#hatch' + (id.slice(4) % 14) + ')';
|
||||
zones.append('g').attr('id', id).attr('data-description', description).attr('data-cells', '').attr('fill', fill);
|
||||
const unit = areaUnit.value === 'square' ? ' ' + distanceUnitInput.value + '²' : ' ' + areaUnit.value;
|
||||
|
||||
const line = `<div class="states" data-id="${id}" data-fill="${fill}" data-description="${description}" data-cells=0 data-area=0 data-population=0>
|
||||
<svg data-tip="Zone fill style. Click to change" width=".9em" height=".9em" style="margin-bottom:-1px"><rect x="0" y="0" width="100%" height="100%" fill="${fill}" class="fillRect pointer"></svg>
|
||||
|
|
@ -363,53 +363,53 @@ function editZones() {
|
|||
<span data-tip="Remove zone" class="icon-trash-empty hide"></span>
|
||||
</div>`;
|
||||
|
||||
body.insertAdjacentHTML("beforeend", line);
|
||||
zonesFooterNumber.innerHTML = zones.selectAll("g").size();
|
||||
body.insertAdjacentHTML('beforeend', line);
|
||||
zonesFooterNumber.innerHTML = zones.selectAll('g').size();
|
||||
}
|
||||
|
||||
function downloadZonesData() {
|
||||
const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value;
|
||||
let data = "Id,Fill,Description,Cells,Area " + unit + ",Population\n"; // headers
|
||||
const unit = areaUnit.value === 'square' ? distanceUnitInput.value + '2' : areaUnit.value;
|
||||
let data = 'Id,Fill,Description,Cells,Area ' + unit + ',Population\n'; // headers
|
||||
|
||||
body.querySelectorAll(":scope > div").forEach(function (el) {
|
||||
data += el.dataset.id + ",";
|
||||
data += el.dataset.fill + ",";
|
||||
data += el.dataset.description + ",";
|
||||
data += el.dataset.cells + ",";
|
||||
data += el.dataset.area + ",";
|
||||
data += el.dataset.population + "\n";
|
||||
body.querySelectorAll(':scope > div').forEach(function (el) {
|
||||
data += el.dataset.id + ',';
|
||||
data += el.dataset.fill + ',';
|
||||
data += el.dataset.description + ',';
|
||||
data += el.dataset.cells + ',';
|
||||
data += el.dataset.area + ',';
|
||||
data += el.dataset.population + '\n';
|
||||
});
|
||||
|
||||
const name = getFileName("Zones") + ".csv";
|
||||
const name = getFileName('Zones') + '.csv';
|
||||
downloadFile(data, name);
|
||||
}
|
||||
|
||||
function toggleEraseMode() {
|
||||
this.classList.toggle("pressed");
|
||||
this.classList.toggle('pressed');
|
||||
}
|
||||
|
||||
function changePopulation(zone) {
|
||||
const dataCells = zones.select("#" + zone).attr("data-cells");
|
||||
const dataCells = zones.select('#' + zone).attr('data-cells');
|
||||
const cells = dataCells
|
||||
? dataCells
|
||||
.split(",")
|
||||
.map(i => +i)
|
||||
.filter(i => pack.cells.h[i] >= 20)
|
||||
.split(',')
|
||||
.map((i) => +i)
|
||||
.filter((i) => pack.cells.h[i] >= 20)
|
||||
: [];
|
||||
if (!cells.length) {
|
||||
tip("Zone does not have any land cells, cannot change population", false, "error");
|
||||
tip('Zone does not have any land cells, cannot change population', false, 'error');
|
||||
return;
|
||||
}
|
||||
const burgs = pack.burgs.filter(b => !b.removed && cells.includes(b.cell));
|
||||
const burgs = pack.burgs.filter((b) => !b.removed && cells.includes(b.cell));
|
||||
|
||||
const rural = rn(d3.sum(cells.map(i => pack.cells.pop[i])) * populationRate);
|
||||
const urban = rn(d3.sum(cells.map(i => pack.cells.burg[i]).map(b => pack.burgs[b].population)) * populationRate * urbanization);
|
||||
const rural = rn(d3.sum(cells.map((i) => pack.cells.pop[i])) * populationRate);
|
||||
const urban = rn(d3.sum(cells.map((i) => pack.cells.burg[i]).map((b) => pack.burgs[b].population)) * populationRate * urbanization);
|
||||
const total = rural + urban;
|
||||
const l = n => Number(n).toLocaleString();
|
||||
const l = (n) => Number(n).toLocaleString();
|
||||
|
||||
alertMessage.innerHTML = `
|
||||
Rural: <input type="number" min=0 step=1 id="ruralPop" value=${rural} style="width:6em">
|
||||
Urban: <input type="number" min=0 step=1 id="urbanPop" value=${urban} style="width:6em" ${burgs.length ? "" : "disabled"}>
|
||||
Urban: <input type="number" min=0 step=1 id="urbanPop" value=${urban} style="width:6em" ${burgs.length ? '' : 'disabled'}>
|
||||
<p>Total population: ${l(total)} ⇒ <span id="totalPop">${l(total)}</span> (<span id="totalPopPerc">100</span>%)</p>`;
|
||||
|
||||
const update = function () {
|
||||
|
|
@ -422,41 +422,41 @@ function editZones() {
|
|||
ruralPop.oninput = () => update();
|
||||
urbanPop.oninput = () => update();
|
||||
|
||||
$("#alert").dialog({
|
||||
$('#alert').dialog({
|
||||
resizable: false,
|
||||
title: "Change zone population",
|
||||
width: "24em",
|
||||
title: 'Change zone population',
|
||||
width: '24em',
|
||||
buttons: {
|
||||
Apply: function () {
|
||||
applyPopulationChange();
|
||||
$(this).dialog("close");
|
||||
$(this).dialog('close');
|
||||
},
|
||||
Cancel: function () {
|
||||
$(this).dialog("close");
|
||||
$(this).dialog('close');
|
||||
}
|
||||
},
|
||||
position: {my: "center", at: "center", of: "svg"}
|
||||
position: {my: 'center', at: 'center', of: 'svg'}
|
||||
});
|
||||
|
||||
function applyPopulationChange() {
|
||||
const ruralChange = ruralPop.value / rural;
|
||||
if (isFinite(ruralChange) && ruralChange !== 1) {
|
||||
cells.forEach(i => (pack.cells.pop[i] *= ruralChange));
|
||||
cells.forEach((i) => (pack.cells.pop[i] *= ruralChange));
|
||||
}
|
||||
if (!isFinite(ruralChange) && +ruralPop.value > 0) {
|
||||
const points = ruralPop.value / populationRate;
|
||||
const pop = rn(points / cells.length);
|
||||
cells.forEach(i => (pack.cells.pop[i] = pop));
|
||||
cells.forEach((i) => (pack.cells.pop[i] = pop));
|
||||
}
|
||||
|
||||
const urbanChange = urbanPop.value / urban;
|
||||
if (isFinite(urbanChange) && urbanChange !== 1) {
|
||||
burgs.forEach(b => (b.population = rn(b.population * urbanChange, 4)));
|
||||
burgs.forEach((b) => (b.population = rn(b.population * urbanChange, 4)));
|
||||
}
|
||||
if (!isFinite(urbanChange) && +urbanPop.value > 0) {
|
||||
const points = urbanPop.value / populationRate / urbanization;
|
||||
const population = rn(points / burgs.length, 4);
|
||||
burgs.forEach(b => (b.population = population));
|
||||
burgs.forEach((b) => (b.population = population));
|
||||
}
|
||||
|
||||
zonesEditorAddLines();
|
||||
|
|
@ -464,8 +464,8 @@ function editZones() {
|
|||
}
|
||||
|
||||
function zoneRemove(zone) {
|
||||
zones.select("#" + zone).remove();
|
||||
unfog("focusZone" + zone);
|
||||
zones.select('#' + zone).remove();
|
||||
unfog('focusZone' + zone);
|
||||
zonesEditorAddLines();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue