mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
1.0.39
This commit is contained in:
parent
ed720300ff
commit
f5bc33b171
7 changed files with 110 additions and 5 deletions
|
|
@ -205,6 +205,7 @@ i.icon-lock {
|
||||||
}
|
}
|
||||||
|
|
||||||
#religionHierarchy text,
|
#religionHierarchy text,
|
||||||
|
#statesTree text,
|
||||||
#provincesTree text {
|
#provincesTree text {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
@ -212,6 +213,12 @@ i.icon-lock {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#statesTree circle {
|
||||||
|
filter: url(#dropShadow05);
|
||||||
|
stroke: #666666;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
#provincesTree .selected {
|
#provincesTree .selected {
|
||||||
stroke: #c13119;
|
stroke: #c13119;
|
||||||
stroke-width: 2;
|
stroke-width: 2;
|
||||||
|
|
|
||||||
|
|
@ -2503,6 +2503,7 @@
|
||||||
<button id="statesEditorRefresh" data-tip="Refresh the Editor" class="icon-cw"></button>
|
<button id="statesEditorRefresh" data-tip="Refresh the Editor" class="icon-cw"></button>
|
||||||
<button id="statesLegend" data-tip="Toggle Legend box" class="icon-list-bullet"></button>
|
<button id="statesLegend" data-tip="Toggle Legend box" class="icon-list-bullet"></button>
|
||||||
<button id="statesPercentage" data-tip="Toggle percentage / absolute values views" class="icon-percent"></button>
|
<button id="statesPercentage" data-tip="Toggle percentage / absolute values views" class="icon-percent"></button>
|
||||||
|
<button id="statesChart" data-tip="Show states bubble chart" class="icon-chart-area"></button>
|
||||||
|
|
||||||
<button id="statesRegenerate" data-tip="Show the regeneration menu and more data" class="icon-cog-alt"></button>
|
<button id="statesRegenerate" data-tip="Show the regeneration menu and more data" class="icon-cog-alt"></button>
|
||||||
<div id="statesRegenerateButtons" style="display: none">
|
<div id="statesRegenerateButtons" style="display: none">
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@
|
||||||
if (b.capital) b.population = rn(b.population * 1.3, 3); // increase capital population
|
if (b.capital) b.population = rn(b.population * 1.3, 3); // increase capital population
|
||||||
|
|
||||||
if (port) {
|
if (port) {
|
||||||
b.population *= b.population * 1.3; // increase port population
|
b.population = b.population * 1.3; // increase port population
|
||||||
const e = cells.v[i].filter(v => vertices.c[v].some(c => c === cells.haven[i])); // vertices of common edge
|
const e = cells.v[i].filter(v => vertices.c[v].some(c => c === cells.haven[i])); // vertices of common edge
|
||||||
b.x = rn((vertices.p[e[0]][0] + vertices.p[e[1]][0]) / 2, 2);
|
b.x = rn((vertices.p[e[0]][0] + vertices.p[e[1]][0]) / 2, 2);
|
||||||
b.y = rn((vertices.p[e[0]][1] + vertices.p[e[1]][1]) / 2, 2);
|
b.y = rn((vertices.p[e[0]][1] + vertices.p[e[1]][1]) / 2, 2);
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,7 @@ const saveReminder = function() {
|
||||||
"Safety is number one priority. Please save the map",
|
"Safety is number one priority. Please save the map",
|
||||||
"Don't forget to save your map on a regular basis!",
|
"Don't forget to save your map on a regular basis!",
|
||||||
"Just a gentle reminder for you to save the map",
|
"Just a gentle reminder for you to save the map",
|
||||||
"Please forget to save your progress (saving as .map is the best option)",
|
"Please don't forget to save your progress (saving as .map is the best option)",
|
||||||
"Don't want to be reminded about need to save? Press CTRL+Q"];
|
"Don't want to be reminded about need to save? Press CTRL+Q"];
|
||||||
|
|
||||||
saveReminder.reminder = setInterval(() => {
|
saveReminder.reminder = setInterval(() => {
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ function editProvinces() {
|
||||||
: d => d.rural + d.urban;
|
: d => d.rural + d.urban;
|
||||||
|
|
||||||
const newRoot = d3.stratify().parentId(d => d.state)(data).sum(value);
|
const newRoot = d3.stratify().parentId(d => d.state)(data).sum(value);
|
||||||
node.data(treeLayout(newRoot).leaves())
|
node.data(treeLayout(newRoot).leaves());
|
||||||
|
|
||||||
node.select("rect").transition().duration(1500)
|
node.select("rect").transition().duration(1500)
|
||||||
.attr("x", d => d.x0).attr("y", d => d.y0)
|
.attr("x", d => d.x0).attr("y", d => d.y0)
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ function editReligions() {
|
||||||
const urban = r.urban * populationRate.value * urbanization.value;
|
const urban = r.urban * populationRate.value * urbanization.value;
|
||||||
const population = rural + urban > 0 ? ". " + si(rn(rural + urban)) + " believers" : ". Extinct";
|
const population = rural + urban > 0 ? ". " + si(rn(rural + urban)) + " believers" : ". Extinct";
|
||||||
info.innerHTML = `${r.name}${type}${form}${population}`;
|
info.innerHTML = `${r.name}${type}${form}${population}`;
|
||||||
tip("Drag to change parent. Hold CTRL and click to change abbrebiation");
|
tip("Drag to change parent. Hold CTRL and click to change abbreviation");
|
||||||
}
|
}
|
||||||
|
|
||||||
const el = body.querySelector(`div[data-id='${religion}']`);
|
const el = body.querySelector(`div[data-id='${religion}']`);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ function editStates() {
|
||||||
document.getElementById("statesEditorRefresh").addEventListener("click", refreshStatesEditor);
|
document.getElementById("statesEditorRefresh").addEventListener("click", refreshStatesEditor);
|
||||||
document.getElementById("statesLegend").addEventListener("click", toggleLegend);
|
document.getElementById("statesLegend").addEventListener("click", toggleLegend);
|
||||||
document.getElementById("statesPercentage").addEventListener("click", togglePercentageMode);
|
document.getElementById("statesPercentage").addEventListener("click", togglePercentageMode);
|
||||||
|
document.getElementById("statesChart").addEventListener("click", showStatesChart);
|
||||||
document.getElementById("statesRegenerate").addEventListener("click", openRegenerationMenu);
|
document.getElementById("statesRegenerate").addEventListener("click", openRegenerationMenu);
|
||||||
document.getElementById("statesRegenerateBack").addEventListener("click", exitRegenerationMenu);
|
document.getElementById("statesRegenerateBack").addEventListener("click", exitRegenerationMenu);
|
||||||
document.getElementById("statesRecalculate").addEventListener("click", () => recalculateStates(true));
|
document.getElementById("statesRecalculate").addEventListener("click", () => recalculateStates(true));
|
||||||
|
|
@ -387,6 +388,102 @@ function editStates() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showStatesChart() {
|
||||||
|
// build hierarchy tree
|
||||||
|
const data = pack.states.filter(s => !s.removed);
|
||||||
|
const root = d3.stratify().id(d => d.i).parentId(d => d.i ? 0 : null)(data)
|
||||||
|
.sum(d => d.area).sort((a, b) => b.value - a.value);
|
||||||
|
|
||||||
|
const width = 150 + 200 * uiSizeOutput.value, height = 150 + 200 * uiSizeOutput.value;
|
||||||
|
const margin = {top: 0, right: -50, bottom: 0, left: -50};
|
||||||
|
const w = width - margin.left - margin.right;
|
||||||
|
const h = height - margin.top - margin.bottom;
|
||||||
|
const treeLayout = d3.pack().size([w, h]).padding(3);
|
||||||
|
|
||||||
|
// prepare svg
|
||||||
|
alertMessage.innerHTML = `<select id="statesTreeType" style="display:block; margin-left:13px; font-size:11px">
|
||||||
|
<option value="area" selected>Area</option>
|
||||||
|
<option value="population">Total population</option>
|
||||||
|
<option value="rural">Rural population</option>
|
||||||
|
<option value="urban">Urban population</option>
|
||||||
|
<option value="burgs">Burgs number</option>
|
||||||
|
</select>`;
|
||||||
|
alertMessage.innerHTML += `<div id='statesInfo' class='chartInfo'>‍</div>`;
|
||||||
|
const svg = d3.select("#alertMessage").insert("svg", "#statesInfo").attr("id", "statesTree")
|
||||||
|
.attr("width", width).attr("height", height).style("font-family", "Almendra SC")
|
||||||
|
.attr("text-anchor", "middle").attr("dominant-baseline", "central");
|
||||||
|
const graph = svg.append("g").attr("transform", `translate(-50, 0)`);
|
||||||
|
document.getElementById("statesTreeType").addEventListener("change", updateChart);
|
||||||
|
|
||||||
|
treeLayout(root);
|
||||||
|
|
||||||
|
const node = graph.selectAll("g").data(root.leaves()).enter()
|
||||||
|
.append("g").attr("transform", d => `translate(${d.x},${d.y})`)
|
||||||
|
.attr("data-id", d => d.data.id)
|
||||||
|
.on("mouseenter", d => showInfo(event, d))
|
||||||
|
.on("mouseleave", d => hideInfo(event, d));
|
||||||
|
|
||||||
|
node.append("circle").attr("fill", d => d.data.color).attr("r", d => d.r);
|
||||||
|
|
||||||
|
const exp = /(?=[A-Z][^A-Z])/g;
|
||||||
|
const lp = n => d3.max(n.split(exp).map(p => p.length)) + 1; // longest name part + 1
|
||||||
|
|
||||||
|
node.append("text")
|
||||||
|
.style("font-size", d => rn(d.r ** .97 * 4 / lp(d.data.name), 2) + "px")
|
||||||
|
.selectAll("tspan").data(d => d.data.name.split(exp))
|
||||||
|
.join("tspan").attr("x", 0).text(d => d)
|
||||||
|
.attr("dy", (d, i, n) => `${i ? 1 : (n.length-1) / -2}em`);
|
||||||
|
|
||||||
|
function showInfo(ev, d) {
|
||||||
|
d3.select(ev.target).select("circle").classed("selected", 1);
|
||||||
|
const state = d.data.fullName;
|
||||||
|
|
||||||
|
const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value;
|
||||||
|
const area = d.data.area * (distanceScaleInput.value ** 2) + unit;
|
||||||
|
const rural = rn(d.data.rural * populationRate.value);
|
||||||
|
const urban = rn(d.data.urban * populationRate.value * urbanization.value);
|
||||||
|
|
||||||
|
const option = statesTreeType.value;
|
||||||
|
const value = option === "area" ? "Area: " + area
|
||||||
|
: option === "rural" ? "Rural population: " + si(rural)
|
||||||
|
: option === "urban" ? "Urban population: " + si(urban)
|
||||||
|
: option === "burgs" ? "Burgs number: " + d.data.burgs
|
||||||
|
: "Population: " + si(rural + urban);
|
||||||
|
|
||||||
|
statesInfo.innerHTML = `${state}. ${value}`;
|
||||||
|
stateHighlightOn(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideInfo(ev) {
|
||||||
|
stateHighlightOff(ev);
|
||||||
|
if (!document.getElementById("statesInfo")) return;
|
||||||
|
statesInfo.innerHTML = "‍";
|
||||||
|
d3.select(ev.target).select("circle").classed("selected", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateChart() {
|
||||||
|
const value = this.value === "area" ? d => d.area
|
||||||
|
: this.value === "rural" ? d => d.rural
|
||||||
|
: this.value === "urban" ? d => d.urban
|
||||||
|
: this.value === "burgs" ? d => d.burgs
|
||||||
|
: d => d.rural + d.urban;
|
||||||
|
|
||||||
|
root.sum(value);
|
||||||
|
node.data(treeLayout(root).leaves());
|
||||||
|
|
||||||
|
node.transition().duration(1500).attr("transform", d => `translate(${d.x},${d.y})`)
|
||||||
|
node.select("circle").transition().duration(1500).attr("r", d => d.r);
|
||||||
|
node.select("text").transition().duration(1500)
|
||||||
|
.style("font-size", d => rn(d.r ** .97 * 4 / lp(d.data.name), 2) + "px");
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#alert").dialog({
|
||||||
|
title: "States bubble chart", width: fitContent(),
|
||||||
|
position: {my: "left bottom", at: "left+10 bottom-10", of: "svg"}, buttons: {},
|
||||||
|
close: () => {alertMessage.innerHTML = "";}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function openRegenerationMenu() {
|
function openRegenerationMenu() {
|
||||||
statesBottom.querySelectorAll(":scope > button").forEach(el => el.style.display = "none");
|
statesBottom.querySelectorAll(":scope > button").forEach(el => el.style.display = "none");
|
||||||
statesRegenerateButtons.style.display = "block";
|
statesRegenerateButtons.style.display = "block";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue