mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 01:41:22 +01:00
feat: zones editor - option to edit land only
This commit is contained in:
parent
d1c09935a9
commit
dd3599506f
3 changed files with 122 additions and 75 deletions
68
index.html
68
index.html
|
|
@ -4912,34 +4912,44 @@
|
||||||
|
|
||||||
<button id="zonesManually" data-tip="Re-assign zones" class="icon-brush"></button>
|
<button id="zonesManually" data-tip="Re-assign zones" class="icon-brush"></button>
|
||||||
<div id="zonesManuallyButtons" style="display: none">
|
<div id="zonesManuallyButtons" style="display: none">
|
||||||
<label data-tip="Change brush size" data-shortcut="+ (increase), – (decrease)" class="italic"
|
<div>
|
||||||
>Brush:
|
<label data-tip="Change brush size" data-shortcut="+ (increase), – (decrease)" class="italic"
|
||||||
<input
|
>Brush:
|
||||||
id="zonesBrush"
|
<input
|
||||||
oninput="tip('Brush size: '+this.value); zonesBrushNumber.value = this.value"
|
id="zonesBrush"
|
||||||
type="range"
|
oninput="tip('Brush size: '+this.value); zonesBrushNumber.value = this.value"
|
||||||
min="5"
|
type="range"
|
||||||
max="50"
|
min="5"
|
||||||
value="7"
|
max="50"
|
||||||
style="width: 9em"
|
value="7"
|
||||||
/>
|
style="width: 9em"
|
||||||
<input
|
/>
|
||||||
id="zonesBrushNumber"
|
<input
|
||||||
oninput="tip('Brush size: '+this.value); zonesBrush.value = this.value"
|
id="zonesBrushNumber"
|
||||||
type="number"
|
oninput="tip('Brush size: '+this.value); zonesBrush.value = this.value"
|
||||||
min="5"
|
type="number"
|
||||||
max="50"
|
min="5"
|
||||||
value="7"
|
max="50"
|
||||||
/> </label
|
value="7"
|
||||||
><br />
|
/>
|
||||||
<button id="zonesManuallyApply" data-tip="Apply assignment" class="icon-check"></button>
|
</label>
|
||||||
<button id="zonesManuallyCancel" data-tip="Cancel assignment" class="icon-cancel"></button>
|
</div>
|
||||||
<button
|
|
||||||
id="zonesRemove"
|
<div>
|
||||||
data-tip="Click to toggle the removal mode on brush dragging"
|
<input id="zonesBrushLandOnly" class="checkbox" type="checkbox" checked />
|
||||||
data-shortcut="Ctrl"
|
<label for="zonesBrushLandOnly" class="checkbox-label"><i>Change land only</i></label>
|
||||||
class="icon-eraser"
|
</div>
|
||||||
></button>
|
|
||||||
|
<div style="margin-top: 0.3em">
|
||||||
|
<button id="zonesManuallyApply" data-tip="Apply assignment" class="icon-check"></button>
|
||||||
|
<button id="zonesManuallyCancel" data-tip="Cancel assignment" class="icon-cancel"></button>
|
||||||
|
<button
|
||||||
|
id="zonesRemove"
|
||||||
|
data-tip="Click to toggle the removal mode on brush dragging"
|
||||||
|
data-shortcut="Ctrl"
|
||||||
|
class="icon-eraser"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="zonesAdd" data-tip="Add new zone layer" class="icon-plus"></button>
|
<button id="zonesAdd" data-tip="Add new zone layer" class="icon-plus"></button>
|
||||||
|
|
@ -8088,7 +8098,7 @@
|
||||||
<script defer src="modules/ui/units-editor.js?v=1.96.00"></script>
|
<script defer src="modules/ui/units-editor.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/notes-editor.js?v=1.97.09"></script>
|
<script defer src="modules/ui/notes-editor.js?v=1.97.09"></script>
|
||||||
<script defer src="modules/ui/diplomacy-editor.js?v=1.88.04"></script>
|
<script defer src="modules/ui/diplomacy-editor.js?v=1.88.04"></script>
|
||||||
<script defer src="modules/ui/zones-editor.js"></script>
|
<script defer src="modules/ui/zones-editor.js?v=1.97.13"></script>
|
||||||
<script defer src="modules/ui/burgs-overview.js?v=1.97.00"></script>
|
<script defer src="modules/ui/burgs-overview.js?v=1.97.00"></script>
|
||||||
<script defer src="modules/ui/rivers-overview.js"></script>
|
<script defer src="modules/ui/rivers-overview.js"></script>
|
||||||
<script defer src="modules/ui/military-overview.js?v=1.96.07"></script>
|
<script defer src="modules/ui/military-overview.js?v=1.96.07"></script>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
function editZones() {
|
function editZones() {
|
||||||
closeDialogs();
|
closeDialogs();
|
||||||
if (!layerIsOn("toggleZones")) toggleZones();
|
if (!layerIsOn("toggleZones")) toggleZones();
|
||||||
const body = document.getElementById("zonesBodySection");
|
const body = byId("zonesBodySection");
|
||||||
|
|
||||||
updateFilters();
|
updateFilters();
|
||||||
zonesEditorAddLines();
|
zonesEditorAddLines();
|
||||||
|
|
@ -20,20 +20,20 @@ function editZones() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
document.getElementById("zonesFilterType").addEventListener("click", updateFilters);
|
byId("zonesFilterType").on("click", updateFilters);
|
||||||
document.getElementById("zonesFilterType").addEventListener("change", filterZonesByType);
|
byId("zonesFilterType").on("change", filterZonesByType);
|
||||||
document.getElementById("zonesEditorRefresh").addEventListener("click", zonesEditorAddLines);
|
byId("zonesEditorRefresh").on("click", zonesEditorAddLines);
|
||||||
document.getElementById("zonesEditStyle").addEventListener("click", () => editStyle("zones"));
|
byId("zonesEditStyle").on("click", () => editStyle("zones"));
|
||||||
document.getElementById("zonesLegend").addEventListener("click", toggleLegend);
|
byId("zonesLegend").on("click", toggleLegend);
|
||||||
document.getElementById("zonesPercentage").addEventListener("click", togglePercentageMode);
|
byId("zonesPercentage").on("click", togglePercentageMode);
|
||||||
document.getElementById("zonesManually").addEventListener("click", enterZonesManualAssignent);
|
byId("zonesManually").on("click", enterZonesManualAssignent);
|
||||||
document.getElementById("zonesManuallyApply").addEventListener("click", applyZonesManualAssignent);
|
byId("zonesManuallyApply").on("click", applyZonesManualAssignent);
|
||||||
document.getElementById("zonesManuallyCancel").addEventListener("click", cancelZonesManualAssignent);
|
byId("zonesManuallyCancel").on("click", cancelZonesManualAssignent);
|
||||||
document.getElementById("zonesAdd").addEventListener("click", addZonesLayer);
|
byId("zonesAdd").on("click", addZonesLayer);
|
||||||
document.getElementById("zonesExport").addEventListener("click", downloadZonesData);
|
byId("zonesExport").on("click", downloadZonesData);
|
||||||
document.getElementById("zonesRemove").addEventListener("click", toggleEraseMode);
|
byId("zonesRemove").on("click", toggleEraseMode);
|
||||||
|
|
||||||
body.addEventListener("click", function (ev) {
|
body.on("click", function (ev) {
|
||||||
const el = ev.target,
|
const el = ev.target,
|
||||||
cl = el.classList,
|
cl = el.classList,
|
||||||
zone = el.parentNode.dataset.id;
|
zone = el.parentNode.dataset.id;
|
||||||
|
|
@ -45,7 +45,7 @@ function editZones() {
|
||||||
if (customization) selectZone(el);
|
if (customization) selectZone(el);
|
||||||
});
|
});
|
||||||
|
|
||||||
body.addEventListener("input", function (ev) {
|
body.on("input", function (ev) {
|
||||||
const el = ev.target;
|
const el = ev.target;
|
||||||
const zone = zones.select("#" + el.parentNode.dataset.id);
|
const zone = zones.select("#" + el.parentNode.dataset.id);
|
||||||
|
|
||||||
|
|
@ -58,10 +58,11 @@ function editZones() {
|
||||||
const zones = Array.from(document.querySelectorAll("#zones > g"));
|
const zones = Array.from(document.querySelectorAll("#zones > g"));
|
||||||
const types = unique(zones.map(zone => zone.dataset.type));
|
const types = unique(zones.map(zone => zone.dataset.type));
|
||||||
|
|
||||||
const filterSelect = document.getElementById("zonesFilterType");
|
const filterSelect = byId("zonesFilterType");
|
||||||
const typeToFilterBy = types.includes(zonesFilterType.value) ? zonesFilterType.value : "all";
|
const typeToFilterBy = types.includes(zonesFilterType.value) ? zonesFilterType.value : "all";
|
||||||
|
|
||||||
filterSelect.innerHTML = "<option value='all'>all</option>" + types.map(type => `<option value="${type}">${type}</option>`).join("");
|
filterSelect.innerHTML =
|
||||||
|
"<option value='all'>all</option>" + types.map(type => `<option value="${type}">${type}</option>`).join("");
|
||||||
filterSelect.value = typeToFilterBy;
|
filterSelect.value = typeToFilterBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +70,7 @@ function editZones() {
|
||||||
function zonesEditorAddLines() {
|
function zonesEditorAddLines() {
|
||||||
const unit = " " + getAreaUnit();
|
const unit = " " + getAreaUnit();
|
||||||
|
|
||||||
const typeToFilterBy = document.getElementById("zonesFilterType").value;
|
const typeToFilterBy = byId("zonesFilterType").value;
|
||||||
const zones = Array.from(document.querySelectorAll("#zones > g"));
|
const zones = Array.from(document.querySelectorAll("#zones > g"));
|
||||||
const filteredZones = typeToFilterBy === "all" ? zones : zones.filter(zone => zone.dataset.type === typeToFilterBy);
|
const filteredZones = typeToFilterBy === "all" ? zones : zones.filter(zone => zone.dataset.type === typeToFilterBy);
|
||||||
|
|
||||||
|
|
@ -80,9 +81,12 @@ function editZones() {
|
||||||
const fill = zoneEl.getAttribute("fill");
|
const fill = zoneEl.getAttribute("fill");
|
||||||
const area = getArea(d3.sum(c.map(i => pack.cells.area[i])));
|
const area = getArea(d3.sum(c.map(i => pack.cells.area[i])));
|
||||||
const rural = d3.sum(c.map(i => pack.cells.pop[i])) * populationRate;
|
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 urban =
|
||||||
|
d3.sum(c.map(i => pack.cells.burg[i]).map(b => pack.burgs[b].population)) * populationRate * urbanization;
|
||||||
const population = rural + urban;
|
const population = rural + urban;
|
||||||
const populationTip = `Total population: ${si(population)}; Rural population: ${si(rural)}; Urban population: ${si(urban)}. Click to change`;
|
const populationTip = `Total population: ${si(population)}; Rural population: ${si(
|
||||||
|
rural
|
||||||
|
)}; Urban population: ${si(urban)}. Click to change`;
|
||||||
const inactive = zoneEl.style.display === "none";
|
const inactive = zoneEl.style.display === "none";
|
||||||
const focused = defs.select("#fog #focus" + zoneEl.id).size();
|
const focused = defs.select("#fog #focus" + zoneEl.id).size();
|
||||||
|
|
||||||
|
|
@ -98,8 +102,12 @@ function editZones() {
|
||||||
<span data-tip="${populationTip}" class="icon-male hide"></span>
|
<span data-tip="${populationTip}" class="icon-male hide"></span>
|
||||||
<div data-tip="${populationTip}" class="culturePopulation hide">${si(population)}</div>
|
<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="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 focus" class="icon-pin ${focused ? "" : " inactive"} hide ${
|
||||||
<span data-tip="Toggle zone visibility" class="icon-eye ${inactive ? " inactive" : ""} hide ${c.length ? "" : " placeholder"}"></span>
|
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>
|
<span data-tip="Remove zone" class="icon-trash-empty hide"></span>
|
||||||
</div>`;
|
</div>`;
|
||||||
});
|
});
|
||||||
|
|
@ -109,7 +117,9 @@ function editZones() {
|
||||||
// update footer
|
// update footer
|
||||||
const totalArea = getArea(graphWidth * graphHeight);
|
const totalArea = getArea(graphWidth * graphHeight);
|
||||||
zonesFooterArea.dataset.area = totalArea;
|
zonesFooterArea.dataset.area = totalArea;
|
||||||
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;
|
zonesFooterPopulation.dataset.population = totalPop;
|
||||||
zonesFooterNumber.innerHTML = /* html */ `${filteredZones.length} of ${zones.length}`;
|
zonesFooterNumber.innerHTML = /* html */ `${filteredZones.length} of ${zones.length}`;
|
||||||
zonesFooterCells.innerHTML = pack.cells.i.length;
|
zonesFooterCells.innerHTML = pack.cells.i.length;
|
||||||
|
|
@ -117,8 +127,8 @@ function editZones() {
|
||||||
zonesFooterPopulation.innerHTML = si(totalPop);
|
zonesFooterPopulation.innerHTML = si(totalPop);
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseenter", ev => zoneHighlightOn(ev)));
|
body.querySelectorAll("div.states").forEach(el => el.on("mouseenter", ev => zoneHighlightOn(ev)));
|
||||||
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => zoneHighlightOff(ev)));
|
body.querySelectorAll("div.states").forEach(el => el.on("mouseleave", ev => zoneHighlightOff(ev)));
|
||||||
|
|
||||||
if (body.dataset.type === "percentage") {
|
if (body.dataset.type === "percentage") {
|
||||||
body.dataset.type = "absolute";
|
body.dataset.type = "absolute";
|
||||||
|
|
@ -150,7 +160,13 @@ function editZones() {
|
||||||
zonesEditorAddLines();
|
zonesEditorAddLines();
|
||||||
}
|
}
|
||||||
|
|
||||||
$(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) {
|
function movezone(ev, ui) {
|
||||||
const zone = $("#" + ui.item.attr("data-id"));
|
const zone = $("#" + ui.item.attr("data-id"));
|
||||||
const prev = $("#" + ui.item.prev().attr("data-id"));
|
const prev = $("#" + ui.item.prev().attr("data-id"));
|
||||||
|
|
@ -166,7 +182,7 @@ function editZones() {
|
||||||
if (!layerIsOn("toggleZones")) toggleZones();
|
if (!layerIsOn("toggleZones")) toggleZones();
|
||||||
customization = 10;
|
customization = 10;
|
||||||
document.querySelectorAll("#zonesBottom > *").forEach(el => (el.style.display = "none"));
|
document.querySelectorAll("#zonesBottom > *").forEach(el => (el.style.display = "none"));
|
||||||
document.getElementById("zonesManuallyButtons").style.display = "inline-block";
|
byId("zonesManuallyButtons").style.display = "inline-block";
|
||||||
|
|
||||||
zonesEditor.querySelectorAll(".hide").forEach(el => el.classList.add("hidden"));
|
zonesEditor.querySelectorAll(".hide").forEach(el => el.classList.add("hidden"));
|
||||||
zonesFooter.style.display = "none";
|
zonesFooter.style.display = "none";
|
||||||
|
|
@ -174,7 +190,11 @@ function editZones() {
|
||||||
$("#zonesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
$("#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);
|
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);
|
viewbox
|
||||||
|
.style("cursor", "crosshair")
|
||||||
|
.on("click", selectZoneOnMapClick)
|
||||||
|
.call(d3.drag().on("start", dragZoneBrush))
|
||||||
|
.on("touchmove mousemove", moveZoneBrush);
|
||||||
|
|
||||||
body.querySelector("div").classList.add("selected");
|
body.querySelector("div").classList.add("selected");
|
||||||
zones.selectAll("g").each(function () {
|
zones.selectAll("g").each(function () {
|
||||||
|
|
@ -195,24 +215,27 @@ function editZones() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function dragZoneBrush() {
|
function dragZoneBrush() {
|
||||||
const r = +zonesBrush.value;
|
const radius = +byId("zonesBrush").value;
|
||||||
|
const eraseMode = byId("zonesRemove").classList.contains("pressed");
|
||||||
|
const landOnly = byId("zonesBrushLandOnly").checked;
|
||||||
|
|
||||||
|
const selected = body.querySelector("div.selected");
|
||||||
|
const zone = zones.select("#" + selected.dataset.id);
|
||||||
|
const base = zone.attr("id") + "_"; // id generic part
|
||||||
|
|
||||||
d3.event.on("drag", () => {
|
d3.event.on("drag", () => {
|
||||||
if (!d3.event.dx && !d3.event.dy) return;
|
if (!d3.event.dx && !d3.event.dy) return;
|
||||||
const p = d3.mouse(this);
|
const [x, y] = d3.mouse(this);
|
||||||
moveCircle(p[0], p[1], r);
|
moveCircle(x, y, radius);
|
||||||
|
|
||||||
const selection = r > 5 ? findAll(p[0], p[1], r) : [findCell(p[0], p[1], r)];
|
let selection = radius > 5 ? findAll(x, y, radius) : [findCell(x, y, radius)];
|
||||||
|
if (landOnly) selection = selection.filter(i => pack.cells.h[i] >= 20);
|
||||||
if (!selection) return;
|
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");
|
const dataCells = zone.attr("data-cells");
|
||||||
let cells = dataCells ? dataCells.split(",").map(i => +i) : [];
|
let cells = dataCells ? dataCells.split(",").map(i => +i) : [];
|
||||||
|
|
||||||
const erase = document.getElementById("zonesRemove").classList.contains("pressed");
|
if (eraseMode) {
|
||||||
if (erase) {
|
|
||||||
// remove
|
// remove
|
||||||
selection.forEach(i => {
|
selection.forEach(i => {
|
||||||
const index = cells.indexOf(i);
|
const index = cells.indexOf(i);
|
||||||
|
|
@ -280,12 +303,13 @@ function editZones() {
|
||||||
customization = 0;
|
customization = 0;
|
||||||
removeCircle();
|
removeCircle();
|
||||||
document.querySelectorAll("#zonesBottom > *").forEach(el => (el.style.display = "inline-block"));
|
document.querySelectorAll("#zonesBottom > *").forEach(el => (el.style.display = "inline-block"));
|
||||||
document.getElementById("zonesManuallyButtons").style.display = "none";
|
byId("zonesManuallyButtons").style.display = "none";
|
||||||
|
|
||||||
zonesEditor.querySelectorAll(".hide:not(.show)").forEach(el => el.classList.remove("hidden"));
|
zonesEditor.querySelectorAll(".hide:not(.show)").forEach(el => el.classList.remove("hidden"));
|
||||||
zonesFooter.style.display = "block";
|
zonesFooter.style.display = "block";
|
||||||
body.querySelectorAll("div > input, select, svg").forEach(e => (e.style.pointerEvents = "all"));
|
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"}});
|
if (!close)
|
||||||
|
$("#zonesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
||||||
|
|
||||||
restoreDefaultEvents();
|
restoreDefaultEvents();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
|
|
@ -300,7 +324,7 @@ function editZones() {
|
||||||
const fill = el.getAttribute("fill");
|
const fill = el.getAttribute("fill");
|
||||||
const callback = newFill => {
|
const callback = newFill => {
|
||||||
el.fill = newFill;
|
el.fill = newFill;
|
||||||
document.getElementById(el.parentNode.dataset.id).setAttribute("fill", newFill);
|
byId(el.parentNode.dataset.id).setAttribute("fill", newFill);
|
||||||
};
|
};
|
||||||
|
|
||||||
openPicker(fill, callback);
|
openPicker(fill, callback);
|
||||||
|
|
@ -356,7 +380,8 @@ function editZones() {
|
||||||
body.querySelectorAll(":scope > div").forEach(function (el) {
|
body.querySelectorAll(":scope > div").forEach(function (el) {
|
||||||
el.querySelector(".stateCells").innerHTML = rn((+el.dataset.cells / totalCells) * 100, 2) + "%";
|
el.querySelector(".stateCells").innerHTML = rn((+el.dataset.cells / totalCells) * 100, 2) + "%";
|
||||||
el.querySelector(".biomeArea").innerHTML = rn((+el.dataset.area / totalArea) * 100, 2) + "%";
|
el.querySelector(".biomeArea").innerHTML = rn((+el.dataset.area / totalArea) * 100, 2) + "%";
|
||||||
el.querySelector(".culturePopulation").innerHTML = rn((+el.dataset.population / totalPopulation) * 100, 2) + "%";
|
el.querySelector(".culturePopulation").innerHTML =
|
||||||
|
rn((+el.dataset.population / totalPopulation) * 100, 2) + "%";
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
body.dataset.type = "absolute";
|
body.dataset.type = "absolute";
|
||||||
|
|
@ -369,7 +394,13 @@ function editZones() {
|
||||||
const description = "Unknown zone";
|
const description = "Unknown zone";
|
||||||
const type = "Unknown";
|
const type = "Unknown";
|
||||||
const fill = "url(#hatch" + (id.slice(4) % 42) + ")";
|
const fill = "url(#hatch" + (id.slice(4) % 42) + ")";
|
||||||
zones.append("g").attr("id", id).attr("data-description", description).attr("data-type", type).attr("data-cells", "").attr("fill", fill);
|
zones
|
||||||
|
.append("g")
|
||||||
|
.attr("id", id)
|
||||||
|
.attr("data-description", description)
|
||||||
|
.attr("data-type", type)
|
||||||
|
.attr("data-cells", "")
|
||||||
|
.attr("fill", fill);
|
||||||
|
|
||||||
zonesEditorAddLines();
|
zonesEditorAddLines();
|
||||||
}
|
}
|
||||||
|
|
@ -411,13 +442,19 @@ function editZones() {
|
||||||
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 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 urban = rn(
|
||||||
|
d3.sum(cells.map(i => pack.cells.burg[i]).map(b => pack.burgs[b].population)) * populationRate * urbanization
|
||||||
|
);
|
||||||
const total = rural + urban;
|
const total = rural + urban;
|
||||||
const l = n => Number(n).toLocaleString();
|
const l = n => Number(n).toLocaleString();
|
||||||
|
|
||||||
alertMessage.innerHTML = /* html */ `Rural: <input type="number" min="0" step="1" id="ruralPop" value=${rural} style="width:6em" /> Urban:
|
alertMessage.innerHTML = /* html */ `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"} />
|
<input type="number" min="0" step="1" id="urbanPop" value=${urban} style="width:6em" ${
|
||||||
<p>Total population: ${l(total)} ⇒ <span id="totalPop">${l(total)}</span> (<span id="totalPopPerc">100</span>%)</p>`;
|
burgs.length ? "" : "disabled"
|
||||||
|
} />
|
||||||
|
<p>Total population: ${l(total)} ⇒ <span id="totalPop">${l(
|
||||||
|
total
|
||||||
|
)}</span> (<span id="totalPopPerc">100</span>%)</p>`;
|
||||||
|
|
||||||
const update = function () {
|
const update = function () {
|
||||||
const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber;
|
const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// version and caching control
|
// version and caching control
|
||||||
const version = "1.97.12"; // generator version, update each time
|
const version = "1.97.13"; // generator version, update each time
|
||||||
|
|
||||||
{
|
{
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue