mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
1.0.40
This commit is contained in:
parent
d5ec72b6b8
commit
dd1510e4ff
8 changed files with 265 additions and 61 deletions
|
|
@ -20,6 +20,7 @@ function editBurgs() {
|
|||
|
||||
// add listeners
|
||||
document.getElementById("burgsEditorRefresh").addEventListener("click", refreshBurgsEditor);
|
||||
document.getElementById("burgsChart").addEventListener("click", showBurgsChart);
|
||||
document.getElementById("burgsFilterState").addEventListener("change", burgsEditorAddLines);
|
||||
document.getElementById("burgsFilterCulture").addEventListener("change", burgsEditorAddLines);
|
||||
document.getElementById("regenerateBurgNames").addEventListener("click", regenerateNames);
|
||||
|
|
@ -250,6 +251,133 @@ function editBurgs() {
|
|||
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 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}
|
||||
});
|
||||
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 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;
|
||||
const treeLayout = d3.pack().size([w, h]).padding(3);
|
||||
|
||||
// prepare svg
|
||||
alertMessage.innerHTML = `<select id="burgsTreeType" style="display:block; margin-left:13px; font-size:11px">
|
||||
<option value="states" selected>Group by state</option>
|
||||
<option value="cultures">Group by culture</option>
|
||||
<option value="parent">Group by province and state</option>
|
||||
<option value="provinces">Group by province</option></select>`;
|
||||
alertMessage.innerHTML += `<div id='burgsInfo' class='chartInfo'>‍</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);
|
||||
|
||||
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));
|
||||
|
||||
function showInfo(ev, d) {
|
||||
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");
|
||||
}
|
||||
|
||||
function hideInfo(ev) {
|
||||
burgHighlightOff(ev);
|
||||
if (!document.getElementById("burgsInfo")) return;
|
||||
burgsInfo.innerHTML = "‍";
|
||||
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 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 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 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 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 data = base.concat(burgs);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$("#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\n"; // headers
|
||||
const valid = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
|
||||
|
|
@ -259,7 +387,7 @@ function editBurgs() {
|
|||
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 += 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) + ",";
|
||||
|
|
|
|||
|
|
@ -229,6 +229,42 @@ function applyOption(select, option) {
|
|||
select.value = option;
|
||||
}
|
||||
|
||||
// show info about the generator in a popup
|
||||
function showInfo() {
|
||||
const Discord = link("https://discordapp.com/invite/X7E84HU", "Discord");
|
||||
const Reddit = link("https://www.reddit.com/r/FantasyMapGenerator", "Reddit")
|
||||
const Patreon = link("https://www.patreon.com/azgaar", "Patreon");
|
||||
const Trello = link("https://trello.com/b/7x832DG4/fantasy-map-generator", "Trello");
|
||||
|
||||
const QuickStart = link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Quick-Start-Tutorial", "Quick start tutorial");
|
||||
const QAA = link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Q&A", "Q&A page");
|
||||
|
||||
alertMessage.innerHTML = `
|
||||
<b>Fantasy Map Generator</b> (FMG) is an open-source application, it means the code is published an anyone can use it.
|
||||
In case of FMG is also means that you own all created maps and can use them as you wish, you can even sell them.
|
||||
|
||||
<p>The development is supported by community, you can donate on ${Patreon}.
|
||||
You can also help creating overviews, tutorials and spreding the word about the Generator.</p>
|
||||
|
||||
<p>The best way to get help is to contact the community on ${Discord} and ${Reddit}.
|
||||
Before asking questions, please check out the ${QuickStart} and the ${QAA}.</p>
|
||||
|
||||
<p>You can track the development process on ${Trello}.</p>
|
||||
|
||||
Links:
|
||||
<ul style="columns:2">
|
||||
<li>${link("https://github.com/Azgaar/Fantasy-Map-Generator", "GitHub repository")}</li>
|
||||
<li>${link("https://github.com/Azgaar/Fantasy-Map-Generator/blob/master/LICENSE", "License")}</li>
|
||||
<li>${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog", "Changelog")}</li>
|
||||
<li>${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Hotkeys", "Hotkeys")}</li>
|
||||
</ul>`;
|
||||
|
||||
$("#alert").dialog({resizable: false, title: document.title, width: "28em",
|
||||
buttons: {OK: function() {$(this).dialog("close");}},
|
||||
position: {my: "center", at: "center", of: "svg"}
|
||||
});
|
||||
}
|
||||
|
||||
// prevent default browser behavior for FMG-used hotkeys
|
||||
document.addEventListener("keydown", event => {
|
||||
if ([112, 113, 117, 120, 9].includes(event.keyCode)) event.preventDefault(); // F1, F2, F6, F9, Tab
|
||||
|
|
@ -242,13 +278,14 @@ document.addEventListener("keyup", event => {
|
|||
event.stopPropagation();
|
||||
|
||||
const key = event.keyCode, ctrl = event.ctrlKey, shift = event.shiftKey, meta = event.metaKey;
|
||||
if (key === 27) {closeDialogs(); hideOptions();} // Escape to close all dialogs
|
||||
else if (key === 9) toggleOptions(event); // Tab to toggle options
|
||||
|
||||
if (key === 112) showInfo(); // "F1" to show info
|
||||
else if (key === 113) regeneratePrompt(); // "F2" for new map
|
||||
else if (key === 46) removeElementOnKey(); // "Delete" to remove the selected element
|
||||
else if (key === 113) regeneratePrompt(); // "F2" for a new map
|
||||
else if (key === 117) quickSave(); // "F6" for quick save
|
||||
else if (key === 120) quickLoad(); // "F9" for quick load
|
||||
else if (key === 9) toggleOptions(event); // Tab to toggle options
|
||||
else if (key === 27) {closeDialogs(); hideOptions();} // Escape to close all dialogs
|
||||
else if (key === 46) removeElementOnKey(); // "Delete" to remove the selected element
|
||||
|
||||
else if (ctrl && key === 80) saveAsImage("png"); // Ctrl + "P" to save as PNG
|
||||
else if (ctrl && key === 83) saveAsImage("svg"); // Ctrl + "S" to save as SVG
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ function editHeightmap() {
|
|||
<p>If you need to change the coastline and keep the data, you may try the <i>risk</i> edit option.
|
||||
The data will be restored as much as possible, but the coastline change can cause unexpected fluctuations and errors.</p>
|
||||
|
||||
<p>Check out <a href="https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Heightmap-customization" target="_blank">wiki</a> for guidance.</p>
|
||||
|
||||
<p>Check out ${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Heightmap-customization", "wiki")} for guidance.</p>
|
||||
|
||||
<p>Please <span class="pseudoLink" onclick=saveMap(); editHeightmap();>save the map</span> before edditing the heightmap!</p>`;
|
||||
|
||||
$("#alert").dialog({resizable: false, title: "Edit Heightmap", width: "28em",
|
||||
|
|
|
|||
|
|
@ -286,8 +286,10 @@ function editProvinces() {
|
|||
const states = pack.states.map(s => {
|
||||
return {id:s.i, state: s.i?0:null, color: s.i && s.color[0] === "#" ? d3.color(s.color).darker() : "#666"}
|
||||
});
|
||||
const provinces = pack.provinces.filter(p => p.i && !p.removed);
|
||||
provinces.forEach(p => p.id = p.i + states.length - 1);
|
||||
const provinces = pack.provinces.filter(p => p.i && !p.removed).map(p => {
|
||||
return {id:p.i+states.length-1, i:p.i, state:p.state, color:p.color,
|
||||
name:p.name, fullName:p.fullName, area:p.area, urban:p.urban, rural:p.rural}
|
||||
});
|
||||
const data = states.concat(provinces);
|
||||
const root = d3.stratify().parentId(d => d.state)(data).sum(d => d.area);
|
||||
|
||||
|
|
@ -371,9 +373,9 @@ function editProvinces() {
|
|||
: this.value === "rural" ? d => d.rural
|
||||
: this.value === "urban" ? d => d.urban
|
||||
: d => d.rural + d.urban;
|
||||
|
||||
const newRoot = d3.stratify().parentId(d => d.state)(data).sum(value);
|
||||
node.data(treeLayout(newRoot).leaves());
|
||||
|
||||
root.sum(value);
|
||||
node.data(treeLayout(root).leaves());
|
||||
|
||||
node.select("rect").transition().duration(1500)
|
||||
.attr("x", d => d.x0).attr("y", d => d.y0)
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ function editStates() {
|
|||
|
||||
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)
|
||||
.attr("data-id", d => d.data.i)
|
||||
.on("mouseenter", d => showInfo(event, d))
|
||||
.on("mouseleave", d => hideInfo(event, d));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue