+ const focused = defs.select('#fog #focusProvince' + p.i).size();
+ COArenderer.trigger('provinceCOA' + p.i, p.coa);
+ lines += `
`;
}
@@ -142,54 +161,66 @@ function editProvinces() {
provincesFooterArea.dataset.area = totalArea;
provincesFooterPopulation.dataset.population = totalPopulation;
- body.querySelectorAll("div.states").forEach(el => {
- el.addEventListener("click", selectProvinceOnLineClick);
- el.addEventListener("mouseenter", ev => provinceHighlightOn(ev));
- el.addEventListener("mouseleave", ev => provinceHighlightOff(ev));
+ body.querySelectorAll('div.states').forEach((el) => {
+ el.addEventListener('click', selectProvinceOnLineClick);
+ el.addEventListener('mouseenter', (ev) => provinceHighlightOn(ev));
+ el.addEventListener('mouseleave', (ev) => provinceHighlightOff(ev));
});
- if (body.dataset.type === "percentage") {body.dataset.type = "absolute"; togglePercentageMode();}
+ if (body.dataset.type === 'percentage') {
+ body.dataset.type = 'absolute';
+ togglePercentageMode();
+ }
applySorting(provincesHeader);
- $("#provincesEditor").dialog({width: fitContent()});
+ $('#provincesEditor').dialog({width: fitContent()});
}
function getCapitalOptions(burgs, capital) {
- let options = "";
- burgs.forEach(b => options += `
`));
return options;
}
function provinceHighlightOn(event) {
const province = +event.target.dataset.id;
const el = body.querySelector(`div[data-id='${province}']`);
- if (el) el.classList.add("active");
+ if (el) el.classList.add('active');
- if (!layerIsOn("toggleProvinces")) return;
+ if (!layerIsOn('toggleProvinces')) return;
if (customization) return;
const animate = d3.transition().duration(2000).ease(d3.easeSinIn);
- provs.select("#province"+province).raise().transition(animate).attr("stroke-width", 2.5).attr("stroke", "#d0240f");
+ provs
+ .select('#province' + province)
+ .raise()
+ .transition(animate)
+ .attr('stroke-width', 2.5)
+ .attr('stroke', '#d0240f');
}
function provinceHighlightOff(event) {
const province = +event.target.dataset.id;
const el = body.querySelector(`div[data-id='${province}']`);
- if (el) el.classList.remove("active");
+ if (el) el.classList.remove('active');
- if (!layerIsOn("toggleProvinces")) return;
- provs.select("#province"+province).transition().attr("stroke-width", null).attr("stroke", null);
+ if (!layerIsOn('toggleProvinces')) return;
+ provs
+ .select('#province' + province)
+ .transition()
+ .attr('stroke-width', null)
+ .attr('stroke', null);
}
function changeFill(el) {
- const currentFill = el.getAttribute("fill");
+ const currentFill = el.getAttribute('fill');
const p = +el.parentNode.parentNode.dataset.id;
- const callback = function(fill) {
- el.setAttribute("fill", fill);
+ const callback = function (fill) {
+ el.setAttribute('fill', fill);
pack.provinces[p].color = fill;
- const g = provs.select("#provincesBody");
- g.select("#province"+p).attr("fill", fill);
- g.select("#province-gap"+p).attr("stroke", fill);
- }
+ const g = provs.select('#provincesBody');
+ g.select('#province' + p).attr('fill', fill);
+ g.select('#province-gap' + p).attr('stroke', fill);
+ };
openPicker(currentFill, callback);
}
@@ -197,26 +228,24 @@ function editProvinces() {
function capitalZoomIn(p) {
const capital = pack.provinces[p].burg;
const l = burgLabels.select("[data-id='" + capital + "']");
- const x = +l.attr("x"), y = +l.attr("y");
+ const x = +l.attr('x'),
+ y = +l.attr('y');
zoomTo(x, y, 8, 2000);
}
- function triggerIndependencePromps(p) {
- alertMessage.innerHTML = "Are you sure you want to declare province independence?
It will turn province into a new state";
- $("#alert").dialog({resizable: false, title: "Declare independence",
- buttons: {
- Declare: function() {
- declareProvinceIndependence(p);
- $(this).dialog("close");
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ function triggerIndependence(p) {
+ const message = 'Are you sure you want to declare province independence?
It will turn province into a new state';
+ confirmationDialog({title: 'Declare independence', message, confirm: 'Declare', onConfirm: () => declareProvinceIndependence(p)});
}
function declareProvinceIndependence(p) {
- const states = pack.states, provinces = pack.provinces, cells = pack.cells;
- if (provinces[p].burgs.some(b => pack.burgs[b].capital)) {tip("Cannot declare independence of a province having capital burg. Please change capital first", false, "error"); return;}
+ const states = pack.states,
+ provinces = pack.provinces,
+ cells = pack.cells;
+ if (provinces[p].burgs.some((b) => pack.burgs[b].capital)) {
+ tip('Cannot declare independence of a province having capital burg. Please change capital first', false, 'error');
+ return;
+ }
const oldState = pack.provinces[p].state;
const newState = pack.states.length;
@@ -225,10 +254,10 @@ function editProvinces() {
const burg = provinces[p].burg;
if (!burg) return;
pack.burgs[burg].capital = 1;
- moveBurgToGroup(burg, "cities");
+ moveBurgToGroup(burg, 'cities');
// move all burgs to a new state
- provinces[p].burgs.forEach(b => pack.burgs[b].state = newState);
+ provinces[p].burgs.forEach((b) => (pack.burgs[b].state = newState));
// difine new state attributes
const center = pack.burgs[burg].cell;
@@ -237,51 +266,56 @@ function editProvinces() {
const color = getRandomColor();
const coa = provinces[p].coa;
- const coaEl = document.getElementById("provinceCOA"+p);
- if (coaEl) coaEl.id = "stateCOA"+newState;
+ const coaEl = document.getElementById('provinceCOA' + p);
+ if (coaEl) coaEl.id = 'stateCOA' + newState;
emblems.select(`#provinceEmblems > use[data-i='${p}']`).remove();
// update cells
- cells.i.filter(i => cells.province[i] === p).forEach(i => {
- cells.province[i] = 0;
- cells.state[i] = newState;
- });
+ cells.i
+ .filter((i) => cells.province[i] === p)
+ .forEach((i) => {
+ cells.province[i] = 0;
+ cells.state[i] = newState;
+ });
// update diplomacy and reverse relations
- const diplomacy = states.map(s => {
- if (!s.i || s.removed) return "x";
+ const diplomacy = states.map((s) => {
+ if (!s.i || s.removed) return 'x';
let relations = states[oldState].diplomacy[s.i]; // relations between Nth state and old overlord
- if (s.i === oldState) relations = "Enemy"; // new state is Enemy to its old overlord
- else if (relations === "Ally") relations = "Suspicion";
- else if (relations === "Friendly") relations = "Suspicion";
- else if (relations === "Suspicion") relations = "Neutral";
- else if (relations === "Enemy") relations = "Friendly";
- else if (relations === "Rival") relations = "Friendly";
- else if (relations === "Vassal") relations = "Suspicion";
- else if (relations === "Suzerain") relations = "Enemy";
+ if (s.i === oldState) relations = 'Enemy';
+ // new state is Enemy to its old overlord
+ else if (relations === 'Ally') relations = 'Suspicion';
+ else if (relations === 'Friendly') relations = 'Suspicion';
+ else if (relations === 'Suspicion') relations = 'Neutral';
+ else if (relations === 'Enemy') relations = 'Friendly';
+ else if (relations === 'Rival') relations = 'Friendly';
+ else if (relations === 'Vassal') relations = 'Suspicion';
+ else if (relations === 'Suzerain') relations = 'Enemy';
s.diplomacy.push(relations);
return relations;
});
- diplomacy.push("x");
+ diplomacy.push('x');
states[0].diplomacy.push([`Independance declaration`, `${name} declared its independance from ${states[oldState].name}`]);
// create new state
- states.push({i:newState, name, diplomacy, provinces:[], color, expansionism:.5, capital:burg, type:"Generic", center, culture, military:[], alert:1, coa});
+ states.push({i: newState, name, diplomacy, provinces: [], color, expansionism: 0.5, capital: burg, type: 'Generic', center, culture, military: [], alert: 1, coa});
BurgsAndStates.collectStatistics();
BurgsAndStates.defineStateForms([newState]);
- if (layerIsOn("toggleProvinces")) toggleProvinces();
- if (!layerIsOn("toggleStates")) toggleStates(); else drawStates();
- if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
+ if (layerIsOn('toggleProvinces')) toggleProvinces();
+ if (!layerIsOn('toggleStates')) toggleStates();
+ else drawStates();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ else drawBorders();
BurgsAndStates.drawStateLabels([newState, oldState]);
// remove old province
- unfog("focusProvince"+p);
+ unfog('focusProvince' + p);
if (states[oldState].provinces.includes(p)) states[oldState].provinces.splice(states[oldState].provinces.indexOf(p), 1);
- provinces[p] = {i:p, removed: true};
+ provinces[p] = {i: p, removed: true};
// draw emblem
- COArenderer.add("state", newState, coa, pack.states[newState].pole[0], pack.states[newState].pole[1]);
+ COArenderer.add('state', newState, coa, pack.states[newState].pole[0], pack.states[newState].pole[1]);
closeDialogs();
editStates();
@@ -289,54 +323,66 @@ function editProvinces() {
function changePopulation(province) {
const p = pack.provinces[province];
- const cells = pack.cells.i.filter(i => pack.cells.province[i] === province);
- if (!cells.length) {tip("Province does not have any cells, cannot change population", false, "error"); return;}
+ const cells = pack.cells.i.filter((i) => pack.cells.province[i] === province);
+ if (!cells.length) {
+ tip('Province does not have any cells, cannot change population', false, 'error');
+ return;
+ }
const rural = rn(p.rural * populationRate.value);
const urban = rn(p.urban * populationRate.value * urbanization.value);
const total = rural + urban;
- const l = n => Number(n).toLocaleString();
+ const l = (n) => Number(n).toLocaleString();
alertMessage.innerHTML = `
Rural:
`;
- const update = function() {
+ const update = function () {
const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber;
if (isNaN(totalNew)) return;
totalPop.innerHTML = l(totalNew);
- totalPopPerc.innerHTML = rn(totalNew / total * 100);
- }
+ totalPopPerc.innerHTML = rn((totalNew / total) * 100);
+ };
ruralPop.oninput = () => update();
urbanPop.oninput = () => update();
- $("#alert").dialog({
- resizable: false, title: "Change province population", width: "24em", buttons: {
- Apply: function() {applyPopulationChange(); $(this).dialog("close");},
- Cancel: function() {$(this).dialog("close");}
- }, position: {my: "center", at: "center", of: "svg"}
+ $('#alert').dialog({
+ resizable: false,
+ title: 'Change province population',
+ width: '24em',
+ buttons: {
+ Apply: function () {
+ applyPopulationChange();
+ $(this).dialog('close');
+ },
+ Cancel: function () {
+ $(this).dialog('close');
+ }
+ },
+ 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.value;
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) {
- p.burgs.forEach(b => pack.burgs[b].population = rn(pack.burgs[b].population * urbanChange, 4));
+ p.burgs.forEach((b) => (pack.burgs[b].population = rn(pack.burgs[b].population * urbanChange, 4)));
}
if (!isFinite(urbanChange) && +urbanPop.value > 0) {
const points = urbanPop.value / populationRate.value / urbanization.value;
const population = rn(points / burgs.length, 4);
- p.burgs.forEach(b => pack.burgs[b].population = population);
+ p.burgs.forEach((b) => (pack.burgs[b].population = population));
}
refreshProvincesEditor();
@@ -344,103 +390,109 @@ function editProvinces() {
}
function toggleFog(p, cl) {
- const path = provs.select("#province"+p).attr("d"), id = "focusProvince"+p;
- cl.contains("inactive") ? fog(id, path) : unfog(id);
- cl.toggle("inactive");
+ const path = provs.select('#province' + p).attr('d'),
+ id = 'focusProvince' + p;
+ cl.contains('inactive') ? fog(id, path) : unfog(id);
+ cl.toggle('inactive');
}
function removeProvince(p) {
- alertMessage.innerHTML = `Are you sure you want to remove the province?
This action cannot be reverted`;
- $("#alert").dialog({resizable: false, title: "Remove province",
- buttons: {
- Remove: function() {
- pack.cells.province.forEach((province, i) => {
- if(province === p) pack.cells.province[i] = 0;
- });
- const s = pack.provinces[p].state, state = pack.states[s];
- if (state.provinces.includes(p)) state.provinces.splice(state.provinces.indexOf(p), 1);
+ const message = 'Are you sure you want to remove the province?
This action cannot be reverted';
+ const onConfirm = () => {
+ pack.cells.province.forEach((province, i) => {
+ if (province === p) pack.cells.province[i] = 0;
+ });
+ const s = pack.provinces[p].state;
+ const state = pack.states[s];
+ if (state.provinces.includes(p)) state.provinces.splice(state.provinces.indexOf(p), 1);
- unfog("focusProvince"+p);
+ unfog('focusProvince' + p);
- const coaId = "provinceCOA" + p;
- if (document.getElementById(coaId)) document.getElementById(coaId).remove();
- emblems.select(`#provinceEmblems > use[data-i='${p}']`).remove();
+ const coaId = 'provinceCOA' + p;
+ if (document.getElementById(coaId)) document.getElementById(coaId).remove();
+ emblems.select(`#provinceEmblems > use[data-i='${p}']`).remove();
- pack.provinces[p] = {i: p, removed: true};
+ pack.provinces[p] = {i: p, removed: true};
- const g = provs.select("#provincesBody");
- g.select("#province"+p).remove();
- g.select("#province-gap"+p).remove();
- if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
- refreshProvincesEditor();
- $(this).dialog("close");
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ const g = provs.select('#provincesBody');
+ g.select('#province' + p).remove();
+ g.select('#province-gap' + p).remove();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ else drawBorders();
+ refreshProvincesEditor();
+ };
+ confirmationDialog({title: 'Remove province', message, confirm: 'Remove', onConfirm});
}
function editProvinceName(province) {
const p = pack.provinces[province];
- document.getElementById("provinceNameEditor").dataset.province = province;
- document.getElementById("provinceNameEditorShort").value = p.name;
- applyOption(provinceNameEditorSelectForm, p.formName)
- document.getElementById("provinceNameEditorFull").value = p.fullName;
+ document.getElementById('provinceNameEditor').dataset.province = province;
+ document.getElementById('provinceNameEditorShort').value = p.name;
+ applyOption(provinceNameEditorSelectForm, p.formName);
+ document.getElementById('provinceNameEditorFull').value = p.fullName;
- $("#provinceNameEditor").dialog({
- resizable: false, title: "Change province name", buttons: {
- Apply: function() {applyNameChange(p); $(this).dialog("close");},
- Cancel: function() {$(this).dialog("close");}
- }, position: {my: "center", at: "center", of: "svg"}
+ $('#provinceNameEditor').dialog({
+ resizable: false,
+ title: 'Change province name',
+ buttons: {
+ Apply: function () {
+ applyNameChange(p);
+ $(this).dialog('close');
+ },
+ Cancel: function () {
+ $(this).dialog('close');
+ }
+ },
+ position: {my: 'center', at: 'center', of: 'svg'}
});
if (modules.editProvinceName) return;
modules.editProvinceName = true;
// add listeners
- document.getElementById("provinceNameEditorShortCulture").addEventListener("click", regenerateShortNameCuture);
- document.getElementById("provinceNameEditorShortRandom").addEventListener("click", regenerateShortNameRandom);
- document.getElementById("provinceNameEditorAddForm").addEventListener("click", addCustomForm);
- document.getElementById("provinceNameEditorFullRegenerate").addEventListener("click", regenerateFullName);
+ document.getElementById('provinceNameEditorShortCulture').addEventListener('click', regenerateShortNameCuture);
+ document.getElementById('provinceNameEditorShortRandom').addEventListener('click', regenerateShortNameRandom);
+ document.getElementById('provinceNameEditorAddForm').addEventListener('click', addCustomForm);
+ document.getElementById('provinceNameEditorFullRegenerate').addEventListener('click', regenerateFullName);
function regenerateShortNameCuture() {
const province = +provinceNameEditor.dataset.province;
const culture = pack.cells.culture[pack.provinces[province].center];
const name = Names.getState(Names.getCultureShort(culture), culture);
- document.getElementById("provinceNameEditorShort").value = name;
+ document.getElementById('provinceNameEditorShort').value = name;
}
function regenerateShortNameRandom() {
- const base = rand(nameBases.length-1);
+ const base = rand(nameBases.length - 1);
const name = Names.getState(Names.getBase(base), undefined, base);
- document.getElementById("provinceNameEditorShort").value = name;
+ document.getElementById('provinceNameEditorShort').value = name;
}
function addCustomForm() {
const value = provinceNameEditorCustomForm.value;
- const displayed = provinceNameEditorCustomForm.style.display === "inline-block";
- provinceNameEditorCustomForm.style.display = displayed ? "none" : "inline-block";
- provinceNameEditorSelectForm.style.display = displayed ? "inline-block" : "none";
+ const displayed = provinceNameEditorCustomForm.style.display === 'inline-block';
+ provinceNameEditorCustomForm.style.display = displayed ? 'none' : 'inline-block';
+ provinceNameEditorSelectForm.style.display = displayed ? 'inline-block' : 'none';
if (displayed) applyOption(provinceNameEditorSelectForm, value);
}
function regenerateFullName() {
- const short = document.getElementById("provinceNameEditorShort").value;
- const form = document.getElementById("provinceNameEditorSelectForm").value;
- document.getElementById("provinceNameEditorFull").value = getFullName();
+ const short = document.getElementById('provinceNameEditorShort').value;
+ const form = document.getElementById('provinceNameEditorSelectForm').value;
+ document.getElementById('provinceNameEditorFull').value = getFullName();
function getFullName() {
if (!form) return short;
- if (!short && form) return "The " + form;
- return short + " " + form;
+ if (!short && form) return 'The ' + form;
+ return short + ' ' + form;
}
}
function applyNameChange(p) {
- p.name = document.getElementById("provinceNameEditorShort").value;
- p.formName = document.getElementById("provinceNameEditorSelectForm").value;
- p.fullName = document.getElementById("provinceNameEditorFull").value;
- provs.select("#provinceLabel"+p.i).text(p.name);
+ p.name = document.getElementById('provinceNameEditorShort').value;
+ p.formName = document.getElementById('provinceNameEditorSelectForm').value;
+ p.fullName = document.getElementById('provinceNameEditorFull').value;
+ provs.select('#provinceLabel' + p.i).text(p.name);
refreshProvincesEditor();
}
}
@@ -452,33 +504,38 @@ function editProvinces() {
}
function togglePercentageMode() {
- if (body.dataset.type === "absolute") {
- body.dataset.type = "percentage";
+ if (body.dataset.type === 'absolute') {
+ body.dataset.type = 'percentage';
const totalArea = +provincesFooterArea.dataset.area;
const totalPopulation = +provincesFooterPopulation.dataset.population;
- body.querySelectorAll(":scope > div").forEach(function(el) {
- el.querySelector(".biomeArea").innerHTML = rn(+el.dataset.area / totalArea * 100) + "%";
- el.querySelector(".culturePopulation").innerHTML = rn(+el.dataset.population / totalPopulation * 100) + "%";
+ body.querySelectorAll(':scope > div').forEach(function (el) {
+ el.querySelector('.biomeArea').innerHTML = rn((+el.dataset.area / totalArea) * 100) + '%';
+ el.querySelector('.culturePopulation').innerHTML = rn((+el.dataset.population / totalPopulation) * 100) + '%';
});
} else {
- body.dataset.type = "absolute";
+ body.dataset.type = 'absolute';
provincesEditorAddLines();
}
}
function showChart() {
// build hierarchy tree
- const getColor = (s) => !s.i || s.removed || s.color[0] !== "#" ? "#666" : d3.color(s.color).darker();
- const states = pack.states.map(s => ({id: s.i, state: s.i ? 0 : null, color: getColor(s)}));
- 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 getColor = (s) => (!s.i || s.removed || s.color[0] !== '#' ? '#666' : d3.color(s.color).darker());
+ const states = pack.states.map((s) => ({id: s.i, state: s.i ? 0 : null, color: getColor(s)}));
+ 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);
+ const root = d3
+ .stratify()
+ .parentId((d) => d.state)(data)
+ .sum((d) => d.area);
- const width = 300 + 300 * uiSizeOutput.value, height = 90 + 90 * uiSizeOutput.value;
+ const width = 300 + 300 * uiSizeOutput.value,
+ height = 90 + 90 * uiSizeOutput.value;
const margin = {top: 10, right: 10, bottom: 0, left: 10};
const w = width - margin.left - margin.right;
const h = height - margin.top - margin.bottom;
@@ -492,32 +549,39 @@ function editProvinces() {
`;
- const svg = d3.select("#alertMessage").insert("svg", "#provinceInfo").attr("id", "provincesTree")
- .attr("width", width).attr("height", height).attr("font-size", "10px");
- const graph = svg.append("g").attr("transform", `translate(10, 0)`);
- document.getElementById("provincesTreeType").addEventListener("change", updateChart);
+ const svg = d3.select('#alertMessage').insert('svg', '#provinceInfo').attr('id', 'provincesTree').attr('width', width).attr('height', height).attr('font-size', '10px');
+ const graph = svg.append('g').attr('transform', `translate(10, 0)`);
+ document.getElementById('provincesTreeType').addEventListener('change', updateChart);
treeLayout(root);
- const node = graph.selectAll("g").data(root.leaves()).enter()
- .append("g").attr("data-id", d => d.data.i)
- .on("mouseenter", d => showInfo(event, d))
- .on("mouseleave", d => hideInfo(event, d));
+ const node = graph
+ .selectAll('g')
+ .data(root.leaves())
+ .enter()
+ .append('g')
+ .attr('data-id', (d) => d.data.i)
+ .on('mouseenter', (d) => showInfo(event, d))
+ .on('mouseleave', (d) => hideInfo(event, d));
function showInfo(ev, d) {
- d3.select(ev.target).select("rect").classed("selected", 1);
+ d3.select(ev.target).select('rect').classed('selected', 1);
const name = d.data.fullName;
const state = pack.states[d.data.state].fullName;
- const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value;
- const area = d.data.area * (distanceScaleInput.value ** 2) + unit;
+ 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 value = provincesTreeType.value === "area" ? "Area: " + area
- : provincesTreeType.value === "rural" ? "Rural population: " + si(rural)
- : provincesTreeType.value === "urban" ? "Urban population: " + si(urban)
- : "Population: " + si(rural + urban);
+ const value =
+ provincesTreeType.value === 'area'
+ ? 'Area: ' + area
+ : provincesTreeType.value === 'rural'
+ ? 'Rural population: ' + si(rural)
+ : provincesTreeType.value === 'urban'
+ ? 'Urban population: ' + si(urban)
+ : 'Population: ' + si(rural + urban);
provinceInfo.innerHTML = `${name}. ${state}. ${value}`;
provinceHighlightOn(ev);
@@ -525,106 +589,123 @@ function editProvinces() {
function hideInfo(ev) {
provinceHighlightOff(ev);
- if (!document.getElementById("provinceInfo")) return;
- provinceInfo.innerHTML = "";
- d3.select(ev.target).select("rect").classed("selected", 0);
+ if (!document.getElementById('provinceInfo')) return;
+ provinceInfo.innerHTML = '';
+ d3.select(ev.target).select('rect').classed('selected', 0);
}
- node.append("rect").attr("stroke", d => d.parent.data.color)
- .attr("stroke-width", 1).attr("fill", d => d.data.color)
- .attr("x", d => d.x0).attr("y", d => d.y0)
- .attr("width", d => d.x1 - d.x0).attr("height", d => d.y1 - d.y0);
+ node
+ .append('rect')
+ .attr('stroke', (d) => d.parent.data.color)
+ .attr('stroke-width', 1)
+ .attr('fill', (d) => d.data.color)
+ .attr('x', (d) => d.x0)
+ .attr('y', (d) => d.y0)
+ .attr('width', (d) => d.x1 - d.x0)
+ .attr('height', (d) => d.y1 - d.y0);
- node.append("text").attr("dx", ".2em").attr("dy", "1em")
- .attr("x", d => d.x0).attr("y", d => d.y0);
+ node
+ .append('text')
+ .attr('dx', '.2em')
+ .attr('dy', '1em')
+ .attr('x', (d) => d.x0)
+ .attr('y', (d) => d.y0);
function hideNonfittingLabels() {
- node.select("text").each(function(d) {
+ node.select('text').each(function (d) {
this.innerHTML = d.data.name;
let b = this.getBBox();
- if (b.y + b.height > d.y1 + 1) this.innerHTML = "";
+ if (b.y + b.height > d.y1 + 1) this.innerHTML = '';
- for(let i=0; i < 15 && b.width > 0 && b.x + b.width > d.x1; i++) {
- if (this.innerHTML.length < 3) {this.innerHTML = ""; break;}
- this.innerHTML = this.innerHTML.slice(0, -2) + "…";
+ for (let i = 0; i < 15 && b.width > 0 && b.x + b.width > d.x1; i++) {
+ if (this.innerHTML.length < 3) {
+ this.innerHTML = '';
+ break;
+ }
+ this.innerHTML = this.innerHTML.slice(0, -2) + '…';
b = this.getBBox();
}
- })
-
+ });
}
function updateChart() {
- const value = this.value === "area" ? d => d.area
- : this.value === "rural" ? d => d.rural
- : this.value === "urban" ? d => d.urban
- : d => d.rural + d.urban;
+ const value = this.value === 'area' ? (d) => d.area : this.value === 'rural' ? (d) => d.rural : this.value === 'urban' ? (d) => d.urban : (d) => d.rural + d.urban;
root.sum(value);
node.data(treeLayout(root).leaves());
- node.select("rect").transition().duration(1500)
- .attr("x", d => d.x0).attr("y", d => d.y0)
- .attr("width", d => d.x1 - d.x0).attr("height", d => d.y1 - d.y0);
+ node
+ .select('rect')
+ .transition()
+ .duration(1500)
+ .attr('x', (d) => d.x0)
+ .attr('y', (d) => d.y0)
+ .attr('width', (d) => d.x1 - d.x0)
+ .attr('height', (d) => d.y1 - d.y0);
- node.select("text").transition().duration(1500)
- .attr("x", d => d.x0).attr("y", d => d.y0);
+ node
+ .select('text')
+ .transition()
+ .duration(1500)
+ .attr('x', (d) => d.x0)
+ .attr('y', (d) => d.y0);
setTimeout(hideNonfittingLabels, 2000);
}
- $("#alert").dialog({
- title: "Provinces chart", width: fitContent(),
- position: {my: "left bottom", at: "left+10 bottom-10", of: "svg"}, buttons: {},
- close: () => {alertMessage.innerHTML = "";}
+ $('#alert').dialog({
+ title: 'Provinces chart',
+ width: fitContent(),
+ position: {my: 'left bottom', at: 'left+10 bottom-10', of: 'svg'},
+ buttons: {},
+ close: () => {
+ alertMessage.innerHTML = '';
+ }
});
hideNonfittingLabels();
}
function toggleLabels() {
- const hidden = provs.select("#provinceLabels").style("display") === "none";
- provs.select("#provinceLabels").style("display", `${hidden ? "block" : "none"}`);
- provs.attr("data-labels", +hidden);
- provs.selectAll("text").call(d3.drag().on("drag", dragLabel)).classed("draggable", true);
+ const hidden = provs.select('#provinceLabels').style('display') === 'none';
+ provs.select('#provinceLabels').style('display', `${hidden ? 'block' : 'none'}`);
+ provs.attr('data-labels', +hidden);
+ provs.selectAll('text').call(d3.drag().on('drag', dragLabel)).classed('draggable', true);
}
function enterProvincesManualAssignent() {
- if (!layerIsOn("toggleProvinces")) toggleProvinces();
- if (!layerIsOn("toggleBorders")) toggleBorders();
+ if (!layerIsOn('toggleProvinces')) toggleProvinces();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
// make province and state borders more visible
- provinceBorders.select("path").attr("stroke", "#000").attr("stroke-width", .5);
- stateBorders.select("path").attr("stroke", "#000").attr("stroke-width", 1.2);
+ provinceBorders.select('path').attr('stroke', '#000').attr('stroke-width', 0.5);
+ stateBorders.select('path').attr('stroke', '#000').attr('stroke-width', 1.2);
customization = 11;
- provs.select("g#provincesBody").append("g").attr("id", "temp");
- provs.select("g#provincesBody").append("g").attr("id", "centers")
- .attr("fill", "none").attr("stroke", "#ff0000").attr("stroke-width", 1);
+ provs.select('g#provincesBody').append('g').attr('id', 'temp');
+ provs.select('g#provincesBody').append('g').attr('id', 'centers').attr('fill', 'none').attr('stroke', '#ff0000').attr('stroke-width', 1);
- document.querySelectorAll("#provincesBottom > *").forEach(el => el.style.display = "none");
- document.getElementById("provincesManuallyButtons").style.display = "inline-block";
+ document.querySelectorAll('#provincesBottom > *').forEach((el) => (el.style.display = 'none'));
+ document.getElementById('provincesManuallyButtons').style.display = 'inline-block';
- provincesEditor.querySelectorAll(".hide").forEach(el => el.classList.add("hidden"));
- provincesHeader.querySelector("div[data-sortby='state']").style.left = "7.7em";
- provincesFooter.style.display = "none";
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "none");
- $("#provincesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
+ provincesEditor.querySelectorAll('.hide').forEach((el) => el.classList.add('hidden'));
+ provincesHeader.querySelector("div[data-sortby='state']").style.left = '7.7em';
+ provincesFooter.style.display = 'none';
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'none'));
+ $('#provincesEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}});
- tip("Click on a province to select, drag the circle to change province", true);
- viewbox.style("cursor", "crosshair")
- .on("click", selectProvinceOnMapClick)
- .call(d3.drag().on("start", dragBrush))
- .on("touchmove mousemove", moveBrush);
+ tip('Click on a province to select, drag the circle to change province', true);
+ viewbox.style('cursor', 'crosshair').on('click', selectProvinceOnMapClick).call(d3.drag().on('start', dragBrush)).on('touchmove mousemove', moveBrush);
- body.querySelector("div").classList.add("selected");
- selectProvince(+body.querySelector("div").dataset.id);
+ body.querySelector('div').classList.add('selected');
+ selectProvince(+body.querySelector('div').dataset.id);
}
function selectProvinceOnLineClick() {
if (customization !== 11) return;
- if (this.parentNode.id !== "provincesBodySection") return;
- body.querySelector("div.selected").classList.remove("selected");
- this.classList.add("selected");
+ if (this.parentNode.id !== 'provincesBodySection') return;
+ body.querySelector('div.selected').classList.remove('selected');
+ this.classList.add('selected');
selectProvince(+this.dataset.id);
}
@@ -633,27 +714,30 @@ function editProvinces() {
const i = findCell(point[0], point[1]);
if (pack.cells.h[i] < 20 || !pack.cells.state[i]) return;
- const assigned = provs.select("g#temp").select("polygon[data-cell='"+i+"']");
- const province = assigned.size() ? +assigned.attr("data-province") : pack.cells.province[i];
+ const assigned = provs.select('g#temp').select("polygon[data-cell='" + i + "']");
+ const province = assigned.size() ? +assigned.attr('data-province') : pack.cells.province[i];
- const editorLine = body.querySelector("div[data-id='"+province+"']");
- if (!editorLine) {tip("You cannot select a province if it is not in the Editor list", false, "error"); return;}
+ const editorLine = body.querySelector("div[data-id='" + province + "']");
+ if (!editorLine) {
+ tip('You cannot select a province if it is not in the Editor list', false, 'error');
+ return;
+ }
- body.querySelector("div.selected").classList.remove("selected");
- editorLine.classList.add("selected");
+ body.querySelector('div.selected').classList.remove('selected');
+ editorLine.classList.add('selected');
selectProvince(province);
}
function selectProvince(p) {
- debug.selectAll("path.selected").remove();
- const path = provs.select("#province"+p).attr("d");
- debug.append("path").attr("class", "selected").attr("d", path);
+ debug.selectAll('path.selected').remove();
+ const path = provs.select('#province' + p).attr('d');
+ debug.append('path').attr('class', 'selected').attr('d', path);
}
function dragBrush() {
const r = +provincesManuallyBrush.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);
@@ -666,33 +750,32 @@ function editProvinces() {
// change province within selection
function changeForSelection(selection) {
- const temp = provs.select("#temp"), centers = provs.select("#centers");
- const selected = body.querySelector("div.selected");
+ const temp = provs.select('#temp'),
+ centers = provs.select('#centers');
+ const selected = body.querySelector('div.selected');
const provinceNew = +selected.dataset.id;
const state = pack.provinces[provinceNew].state;
- const fill = pack.provinces[provinceNew].color || "#ffffff";
+ const fill = pack.provinces[provinceNew].color || '#ffffff';
- selection.forEach(i => {
+ selection.forEach((i) => {
if (!pack.cells.state[i] || pack.cells.state[i] !== state) return;
- const exists = temp.select("polygon[data-cell='"+i+"']");
- const provinceOld = exists.size() ? +exists.attr("data-province") : pack.cells.province[i];
+ const exists = temp.select("polygon[data-cell='" + i + "']");
+ const provinceOld = exists.size() ? +exists.attr('data-province') : pack.cells.province[i];
if (provinceNew === provinceOld) return;
if (i === pack.provinces[provinceOld].center) {
- const center = centers.select("polygon[data-center='"+i+"']");
- if (!center.size()) centers.append("polygon").attr("data-center", i).attr("points", getPackPolygon(i));
- tip("Province center cannot be assigned to a different region. Please remove the province first", false, "error");
+ const center = centers.select("polygon[data-center='" + i + "']");
+ if (!center.size()) centers.append('polygon').attr('data-center', i).attr('points', getPackPolygon(i));
+ tip('Province center cannot be assigned to a different region. Please remove the province first', false, 'error');
return;
}
// change of append new element
if (exists.size()) {
if (pack.cells.province[i] === provinceNew) exists.remove();
- else exists.attr("data-province", provinceNew).attr("fill", fill);
+ else exists.attr('data-province', provinceNew).attr('fill', fill);
} else {
- temp.append("polygon").attr("points", getPackPolygon(i))
- .attr("data-cell", i).attr("data-province", provinceNew)
- .attr("fill", fill).attr("stroke", "#555");
+ temp.append('polygon').attr('points', getPackPolygon(i)).attr('data-cell', i).attr('data-province', provinceNew).attr('fill', fill).attr('stroke', '#555');
}
});
}
@@ -705,61 +788,79 @@ function editProvinces() {
}
function applyProvincesManualAssignent() {
- provs.select("#temp").selectAll("polygon").each(function() {
- const i = +this.dataset.cell;
- pack.cells.province[i] = +this.dataset.province;;
- });
+ provs
+ .select('#temp')
+ .selectAll('polygon')
+ .each(function () {
+ const i = +this.dataset.cell;
+ pack.cells.province[i] = +this.dataset.province;
+ });
- if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
- if (!layerIsOn("toggleProvinces")) toggleProvinces(); else drawProvinces();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ else drawBorders();
+ if (!layerIsOn('toggleProvinces')) toggleProvinces();
+ else drawProvinces();
exitProvincesManualAssignment();
refreshProvincesEditor();
}
function exitProvincesManualAssignment(close) {
customization = 0;
- provs.select("#temp").remove();
- provs.select("#centers").remove();
+ provs.select('#temp').remove();
+ provs.select('#centers').remove();
removeCircle();
// restore borders style
- provinceBorders.select("path").attr("stroke", null).attr("stroke-width", null);
- stateBorders.select("path").attr("stroke", null).attr("stroke-width", null);
- debug.selectAll("path.selected").remove();
+ provinceBorders.select('path').attr('stroke', null).attr('stroke-width', null);
+ stateBorders.select('path').attr('stroke', null).attr('stroke-width', null);
+ debug.selectAll('path.selected').remove();
- document.querySelectorAll("#provincesBottom > *").forEach(el => el.style.display = "inline-block");
- document.getElementById("provincesManuallyButtons").style.display = "none";
+ document.querySelectorAll('#provincesBottom > *').forEach((el) => (el.style.display = 'inline-block'));
+ document.getElementById('provincesManuallyButtons').style.display = 'none';
- provincesEditor.querySelectorAll(".hide:not(.show)").forEach(el => el.classList.remove("hidden"));
- provincesHeader.querySelector("div[data-sortby='state']").style.left = "22em";
- provincesFooter.style.display = "block";
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "all");
- if(!close) $("#provincesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
+ provincesEditor.querySelectorAll('.hide:not(.show)').forEach((el) => el.classList.remove('hidden'));
+ provincesHeader.querySelector("div[data-sortby='state']").style.left = '22em';
+ provincesFooter.style.display = 'block';
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'all'));
+ if (!close) $('#provincesEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}});
restoreDefaultEvents();
clearMainTip();
- 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 enterAddProvinceMode() {
- if (this.classList.contains("pressed")) {exitAddProvinceMode(); return;};
+ if (this.classList.contains('pressed')) {
+ exitAddProvinceMode();
+ return;
+ }
customization = 12;
- this.classList.add("pressed");
- tip("Click on the map to place a new province center", true);
- viewbox.style("cursor", "crosshair").on("click", addProvince);
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "none");
+ this.classList.add('pressed');
+ tip('Click on the map to place a new province center', true);
+ viewbox.style('cursor', 'crosshair').on('click', addProvince);
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'none'));
}
function addProvince() {
- const cells = pack.cells, provinces = pack.provinces;
+ const cells = pack.cells,
+ provinces = pack.provinces;
const point = d3.mouse(this);
const center = findCell(point[0], point[1]);
- if (cells.h[center] < 20) {tip("You cannot place province into the water. Please click on a land cell", false, "error"); return;}
+ if (cells.h[center] < 20) {
+ tip('You cannot place province into the water. Please click on a land cell', false, 'error');
+ return;
+ }
const oldProvince = cells.province[center];
- if (oldProvince && provinces[oldProvince].center === center) {tip("The cell is already a center of a different province. Select other cell", false, "error"); return;}
+ if (oldProvince && provinces[oldProvince].center === center) {
+ tip('The cell is already a center of a different province. Select other cell', false, 'error');
+ return;
+ }
const state = cells.state[center];
- if (!state) {tip("You cannot create a province in neutral lands. Please assign this land to a state first", false, "error"); return;}
+ if (!state) {
+ tip('You cannot create a province in neutral lands. Please assign this land to a state first', false, 'error');
+ return;
+ }
if (d3.event.shiftKey === false) exitAddProvinceMode();
@@ -768,32 +869,35 @@ function editProvinces() {
const burg = cells.burg[center];
const c = cells.culture[center];
const name = burg ? pack.burgs[burg].name : Names.getState(Names.getCultureShort(c), c);
- const formName = oldProvince ? provinces[oldProvince].formName : "Province";
- const fullName = name + " " + formName;
- const stateColor = pack.states[state].color, rndColor = getRandomColor();
- const color = stateColor[0] === "#" ? d3.color(d3.interpolate(stateColor, rndColor)(.2)).hex() : rndColor;
+ const formName = oldProvince ? provinces[oldProvince].formName : 'Province';
+ const fullName = name + ' ' + formName;
+ const stateColor = pack.states[state].color,
+ rndColor = getRandomColor();
+ const color = stateColor[0] === '#' ? d3.color(d3.interpolate(stateColor, rndColor)(0.2)).hex() : rndColor;
// generate emblem
- const kinship = burg ? .8 : .4;
+ const kinship = burg ? 0.8 : 0.4;
const parent = burg ? pack.burgs[burg].coa : pack.states[state].coa;
const type = BurgsAndStates.getType(center, parent.port);
- const coa = COA.generate(parent, kinship, P(.1), type);
+ const coa = COA.generate(parent, kinship, P(0.1), type);
coa.shield = COA.getShield(c, state);
- COArenderer.add("province", province, coa, point[0], point[1]);
+ COArenderer.add('province', province, coa, point[0], point[1]);
- provinces.push({i:province, state, center, burg, name, formName, fullName, color, coa});
+ provinces.push({i: province, state, center, burg, name, formName, fullName, color, coa});
cells.province[center] = province;
- cells.c[center].forEach(c => {
+ cells.c[center].forEach((c) => {
if (cells.h[c] < 20 || cells.state[c] !== state) return;
- if (provinces.find(p => !p.removed && p.center === c)) return;
+ if (provinces.find((p) => !p.removed && p.center === c)) return;
cells.province[c] = province;
});
- if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
- if (!layerIsOn("toggleProvinces")) toggleProvinces(); else drawProvinces();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ else drawBorders();
+ if (!layerIsOn('toggleProvinces')) toggleProvinces();
+ else drawProvinces();
collectStatistics();
- document.getElementById("provincesFilterState").value = state;
+ document.getElementById('provincesFilterState').value = state;
provincesEditorAddLines();
}
@@ -801,89 +905,84 @@ function editProvinces() {
customization = 0;
restoreDefaultEvents();
clearMainTip();
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "all");
- if (provincesAdd.classList.contains("pressed")) provincesAdd.classList.remove("pressed");
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'all'));
+ if (provincesAdd.classList.contains('pressed')) provincesAdd.classList.remove('pressed');
}
function recolorProvinces() {
- const state = +document.getElementById("provincesFilterState").value;
+ const state = +document.getElementById('provincesFilterState').value;
- pack.provinces.forEach(p => {
+ pack.provinces.forEach((p) => {
if (!p || p.removed) return;
if (state !== -1 && p.state !== state) return;
const stateColor = pack.states[p.state].color;
const rndColor = getRandomColor();
- p.color = stateColor[0] === "#" ? d3.color(d3.interpolate(stateColor, rndColor)(.2)).hex() : rndColor;
+ p.color = stateColor[0] === '#' ? d3.color(d3.interpolate(stateColor, rndColor)(0.2)).hex() : rndColor;
});
- if (!layerIsOn("toggleProvinces")) toggleProvinces(); else drawProvinces();
+ if (!layerIsOn('toggleProvinces')) toggleProvinces();
+ else drawProvinces();
}
function downloadProvincesData() {
- const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value;
- let data = "Id,Province,Form,State,Color,Capital,Area "+unit+",Total Population,Rural Population,Urban Population\n"; // headers
+ const unit = areaUnit.value === 'square' ? distanceUnitInput.value + '2' : areaUnit.value;
+ let data = 'Id,Province,Form,State,Color,Capital,Area ' + unit + ',Total Population,Rural Population,Urban Population\n'; // headers
- body.querySelectorAll(":scope > div").forEach(function(el) {
- let key = parseInt(el.dataset.id)
- data += el.dataset.id + ",";
- data += el.dataset.name + ",";
- data += el.dataset.form + ",";
- data += el.dataset.state + ",";
- data += el.dataset.color + ",";
- data += el.dataset.capital + ",";
- data += el.dataset.area + ",";
- data += el.dataset.population + ",";
- data += `${Math.round(pack.provinces[key].rural*populationRate.value)},`
- data += `${Math.round(pack.provinces[key].urban*populationRate.value * urbanization.value)}\n`
+ body.querySelectorAll(':scope > div').forEach(function (el) {
+ let key = parseInt(el.dataset.id);
+ data += el.dataset.id + ',';
+ data += el.dataset.name + ',';
+ data += el.dataset.form + ',';
+ data += el.dataset.state + ',';
+ data += el.dataset.color + ',';
+ data += el.dataset.capital + ',';
+ data += el.dataset.area + ',';
+ data += el.dataset.population + ',';
+ data += `${Math.round(pack.provinces[key].rural * populationRate.value)},`;
+ data += `${Math.round(pack.provinces[key].urban * populationRate.value * urbanization.value)}\n`;
});
- const name = getFileName("Provinces") + ".csv";
+ const name = getFileName('Provinces') + '.csv';
downloadFile(data, name);
}
function removeAllProvinces() {
- alertMessage.innerHTML = `Are you sure you want to remove all provinces?
This action cannot be reverted`;
- $("#alert").dialog({resizable: false, title: "Remove all provinces",
- buttons: {
- Remove: function() {
- $(this).dialog("close");
+ const message = `Are you sure you want to remove all provinces?
This action cannot be reverted`;
+ const onConfirm = () => {
+ // remove emblems
+ document.querySelectorAll("[id^='provinceCOA']").forEach((el) => el.remove());
+ emblems.select('#provinceEmblems').selectAll('*').remove();
- // remove emblems
- document.querySelectorAll("[id^='provinceCOA']").forEach(el => el.remove());
- emblems.select("#provinceEmblems").selectAll("*").remove();
+ // remove data
+ pack.provinces = [0];
+ pack.cells.province = new Uint16Array(pack.cells.i.length);
+ pack.states.forEach((s) => (s.provinces = []));
- // remove data
- pack.provinces = [0];
- pack.cells.province = new Uint16Array(pack.cells.i.length);
- pack.states.forEach(s => s.provinces = []);
+ unfog();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ else drawBorders();
+ provs.select('#provincesBody').remove();
+ turnButtonOff('toggleProvinces');
- unfog();
- if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
- provs.select("#provincesBody").remove();
- turnButtonOff("toggleProvinces");
-
- provincesEditorAddLines();
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ provincesEditorAddLines();
+ };
+ confirmationDialog({title: 'Remove all provinces', message, confirm: 'Remove', onConfirm});
}
function dragLabel() {
- const tr = parseTransform(this.getAttribute("transform"));
- const x = +tr[0] - d3.event.x, y = +tr[1] - d3.event.y;
+ const tr = parseTransform(this.getAttribute('transform'));
+ const x = +tr[0] - d3.event.x,
+ y = +tr[1] - d3.event.y;
- d3.event.on("drag", function() {
- const transform = `translate(${(x + d3.event.x)},${(y + d3.event.y)})`;
- this.setAttribute("transform", transform);
+ d3.event.on('drag', function () {
+ const transform = `translate(${x + d3.event.x},${y + d3.event.y})`;
+ this.setAttribute('transform', transform);
});
}
function closeProvincesEditor() {
- provs.selectAll("text").call(d3.drag().on("drag", null)).attr("class", null);
- if (customization === 11) exitProvincesManualAssignment("close");
+ provs.selectAll('text').call(d3.drag().on('drag', null)).attr('class', null);
+ if (customization === 11) exitProvincesManualAssignment('close');
if (customization === 12) exitAddProvinceMode();
}
-
}
-
diff --git a/modules/ui/regiment-editor.js b/modules/ui/regiment-editor.js
index 881ce3bf..342ceed9 100644
--- a/modules/ui/regiment-editor.js
+++ b/modules/ui/regiment-editor.js
@@ -1,85 +1,95 @@
-"use strict";
+'use strict';
function editRegiment(selector) {
if (customization) return;
- closeDialogs(".stable");
- if (!layerIsOn("toggleMilitary")) toggleMilitary();
+ closeDialogs('.stable');
+ if (!layerIsOn('toggleMilitary')) toggleMilitary();
- armies.selectAll(":scope > g").classed("draggable", true);
- armies.selectAll(":scope > g > g").call(d3.drag().on("drag", dragRegiment));
+ armies.selectAll(':scope > g').classed('draggable', true);
+ armies.selectAll(':scope > g > g').call(d3.drag().on('drag', dragRegiment));
elSelected = selector ? document.querySelector(selector) : d3.event.target.parentElement; // select g element
if (!pack.states[elSelected.dataset.state]) return;
if (!regiment()) return;
updateRegimentData(regiment());
drawBase();
- $("#regimentEditor").dialog({
- title: "Edit Regiment", resizable: false, close: closeEditor,
- position: {my: "left top", at: "left+10 top+10", of: "#map"}
+ $('#regimentEditor').dialog({
+ title: 'Edit Regiment',
+ resizable: false,
+ close: closeEditor,
+ position: {my: 'left top', at: 'left+10 top+10', of: '#map'}
});
if (modules.editRegiment) return;
modules.editRegiment = true;
// add listeners
- document.getElementById("regimentNameRestore").addEventListener("click", restoreName);
- document.getElementById("regimentType").addEventListener("click", changeType);
- document.getElementById("regimentName").addEventListener("change", changeName);
- document.getElementById("regimentEmblem").addEventListener("input", changeEmblem);
- document.getElementById("regimentEmblemSelect").addEventListener("click", selectEmblem);
- document.getElementById("regimentAttack").addEventListener("click", toggleAttack);
- document.getElementById("regimentRegenerateLegend").addEventListener("click", regenerateLegend);
- document.getElementById("regimentLegend").addEventListener("click", editLegend);
- document.getElementById("regimentSplit").addEventListener("click", splitRegiment);
- document.getElementById("regimentAdd").addEventListener("click", toggleAdd);
- document.getElementById("regimentAttach").addEventListener("click", toggleAttach);
- document.getElementById("regimentRemove").addEventListener("click", removeRegiment);
+ document.getElementById('regimentNameRestore').addEventListener('click', restoreName);
+ document.getElementById('regimentType').addEventListener('click', changeType);
+ document.getElementById('regimentName').addEventListener('change', changeName);
+ document.getElementById('regimentEmblem').addEventListener('input', changeEmblem);
+ document.getElementById('regimentEmblemSelect').addEventListener('click', selectEmblem);
+ document.getElementById('regimentAttack').addEventListener('click', toggleAttack);
+ document.getElementById('regimentRegenerateLegend').addEventListener('click', regenerateLegend);
+ document.getElementById('regimentLegend').addEventListener('click', editLegend);
+ document.getElementById('regimentSplit').addEventListener('click', splitRegiment);
+ document.getElementById('regimentAdd').addEventListener('click', toggleAdd);
+ document.getElementById('regimentAttach').addEventListener('click', toggleAttach);
+ document.getElementById('regimentRemove').addEventListener('click', removeRegiment);
// get regiment data element
function regiment() {
- return pack.states[elSelected.dataset.state].military.find(r => r.i == elSelected.dataset.id);
+ return pack.states[elSelected.dataset.state].military.find((r) => r.i == elSelected.dataset.id);
}
function updateRegimentData(regiment) {
- document.getElementById("regimentType").className = regiment.n ? "icon-anchor" :"icon-users";
- document.getElementById("regimentName").value = regiment.name;
- document.getElementById("regimentEmblem").value = regiment.icon;
- const composition = document.getElementById("regimentComposition");
+ document.getElementById('regimentType').className = regiment.n ? 'icon-anchor' : 'icon-users';
+ document.getElementById('regimentName').value = regiment.name;
+ document.getElementById('regimentEmblem').value = regiment.icon;
+ const composition = document.getElementById('regimentComposition');
- composition.innerHTML = options.military.map(u => {
- return `
`;
+ })
+ .join('');
- composition.querySelectorAll("input").forEach(el => el.addEventListener("change", changeUnit));
+ composition.querySelectorAll('input').forEach((el) => el.addEventListener('change', changeUnit));
}
function drawBase() {
const reg = regiment();
const clr = pack.states[elSelected.dataset.state].color;
- const base = viewbox.insert("g", "g#armies").attr("id", "regimentBase").attr("stroke-width", .3).attr("stroke", "#000").attr("cursor", "move");
- base.on("mouseenter", () => {tip("Regiment base. Drag to re-base the regiment", true);}).on("mouseleave", () => {tip('', true);});
+ const base = viewbox.insert('g', 'g#armies').attr('id', 'regimentBase').attr('stroke-width', 0.3).attr('stroke', '#000').attr('cursor', 'move');
+ base
+ .on('mouseenter', () => {
+ tip('Regiment base. Drag to re-base the regiment', true);
+ })
+ .on('mouseleave', () => {
+ tip('', true);
+ });
- base.append("line").attr("x1", reg.bx).attr("y1", reg.by).attr("x2", reg.x).attr("y2", reg.y).attr("class", "dragLine");
- base.append("circle").attr("cx", reg.bx).attr("cy", reg.by).attr("r", 2).attr("fill", clr).call(d3.drag().on("drag", dragBase));
+ base.append('line').attr('x1', reg.bx).attr('y1', reg.by).attr('x2', reg.x).attr('y2', reg.y).attr('class', 'dragLine');
+ base.append('circle').attr('cx', reg.bx).attr('cy', reg.by).attr('r', 2).attr('fill', clr).call(d3.drag().on('drag', dragBase));
}
function changeType() {
const reg = regiment();
reg.n = +!reg.n;
- document.getElementById("regimentType").className = reg.n ? "icon-anchor" :"icon-users";
+ document.getElementById('regimentType').className = reg.n ? 'icon-anchor' : 'icon-users';
- const size = +armies.attr("box-size");
- const baseRect = elSelected.querySelectorAll("rect")[0];
- const iconRect = elSelected.querySelectorAll("rect")[1];
- const icon = elSelected.querySelector(".regimentIcon");
- const x = reg.n ? reg.x-size*2 : reg.x-size*3;
- baseRect.setAttribute("x", x);
- baseRect.setAttribute("width", reg.n ? size*4 : size*6);
- iconRect.setAttribute("x", x - size*2);
- icon.setAttribute("x", x - size);
- elSelected.querySelector("text").innerHTML = Military.getTotal(reg);
+ const size = +armies.attr('box-size');
+ const baseRect = elSelected.querySelectorAll('rect')[0];
+ const iconRect = elSelected.querySelectorAll('rect')[1];
+ const icon = elSelected.querySelector('.regimentIcon');
+ const x = reg.n ? reg.x - size * 2 : reg.x - size * 3;
+ baseRect.setAttribute('x', x);
+ baseRect.setAttribute('width', reg.n ? size * 4 : size * 6);
+ iconRect.setAttribute('x', x - size * 2);
+ icon.setAttribute('x', x - size);
+ elSelected.querySelector('text').innerHTML = Military.getTotal(reg);
}
function changeName() {
@@ -87,49 +97,64 @@ function editRegiment(selector) {
}
function restoreName() {
- const reg = regiment(), regs = pack.states[elSelected.dataset.state].military;
+ const reg = regiment(),
+ regs = pack.states[elSelected.dataset.state].military;
const name = Military.getName(reg, regs);
- elSelected.dataset.name = reg.name = document.getElementById("regimentName").value = name;
+ elSelected.dataset.name = reg.name = document.getElementById('regimentName').value = name;
}
function selectEmblem() {
- selectIcon(regimentEmblem.value, v => {regimentEmblem.value = v; changeEmblem()});
+ selectIcon(regimentEmblem.value, (v) => {
+ regimentEmblem.value = v;
+ changeEmblem();
+ });
}
function changeEmblem() {
- const emblem = document.getElementById("regimentEmblem").value;
- regiment().icon = elSelected.querySelector(".regimentIcon").innerHTML = emblem;
+ const emblem = document.getElementById('regimentEmblem').value;
+ regiment().icon = elSelected.querySelector('.regimentIcon').innerHTML = emblem;
}
function changeUnit() {
const u = this.dataset.u;
const reg = regiment();
- reg.u[u] = (+this.value)||0;
+ reg.u[u] = +this.value || 0;
reg.a = d3.sum(Object.values(reg.u));
- elSelected.querySelector("text").innerHTML = Military.getTotal(reg);
+ elSelected.querySelector('text').innerHTML = Military.getTotal(reg);
if (militaryOverviewRefresh.offsetParent) militaryOverviewRefresh.click();
if (regimentsOverviewRefresh.offsetParent) regimentsOverviewRefresh.click();
}
function splitRegiment() {
- const reg = regiment(), u1 = reg.u;
- const state = +elSelected.dataset.state, military = pack.states[state].military;
- const i = last(military).i + 1, u2 = Object.assign({}, u1); // u clone
+ const reg = regiment(),
+ u1 = reg.u;
+ const state = +elSelected.dataset.state,
+ military = pack.states[state].military;
+ const i = last(military).i + 1,
+ u2 = Object.assign({}, u1); // u clone
- Object.keys(u2).forEach(u => u2[u] = Math.floor(u2[u]/2)); // halved new reg
+ Object.keys(u2).forEach((u) => (u2[u] = Math.floor(u2[u] / 2))); // halved new reg
const a = d3.sum(Object.values(u2)); // new reg total
- if (!a) {tip("Not enough forces to split", false, "error"); return}; // nothing to add
+ if (!a) {
+ tip('Not enough forces to split', false, 'error');
+ return;
+ } // nothing to add
// update old regiment
- Object.keys(u1).forEach(u => u1[u] = Math.ceil(u1[u]/2)); // halved old reg
+ Object.keys(u1).forEach((u) => (u1[u] = Math.ceil(u1[u] / 2))); // halved old reg
reg.a = d3.sum(Object.values(u1)); // old reg total
- regimentComposition.querySelectorAll("input").forEach(el => el.value = reg.u[el.dataset.u]||0);
- elSelected.querySelector("text").innerHTML = Military.getTotal(reg);
+ regimentComposition.querySelectorAll('input').forEach((el) => (el.value = reg.u[el.dataset.u] || 0));
+ elSelected.querySelector('text').innerHTML = Military.getTotal(reg);
// create new regiment
- const shift = +armies.attr("box-size") * 2;
- const y = function(x, y) {do {y+=shift} while (military.find(r => r.x === x && r.y === y)); return y;}
- const newReg = {a, cell:reg.cell, i, n:reg.n, u:u2, x:reg.x, y:y(reg.x, reg.y), bx:reg.bx, by:reg.by, state, icon: reg.icon};
+ const shift = +armies.attr('box-size') * 2;
+ const y = function (x, y) {
+ do {
+ y += shift;
+ } while (military.find((r) => r.x === x && r.y === y));
+ return y;
+ };
+ const newReg = {a, cell: reg.cell, i, n: reg.n, u: u2, x: reg.x, y: y(reg.x, reg.y), bx: reg.bx, by: reg.by, state, icon: reg.icon};
newReg.name = Military.getName(newReg, military);
military.push(newReg);
Military.generateNote(newReg, pack.states[state]); // add legend
@@ -139,24 +164,26 @@ function editRegiment(selector) {
}
function toggleAdd() {
- document.getElementById("regimentAdd").classList.toggle("pressed");
- if (document.getElementById("regimentAdd").classList.contains("pressed")) {
- viewbox.style("cursor", "crosshair").on("click", addRegimentOnClick);
- tip("Click on map to create new regiment or fleet", true);
+ document.getElementById('regimentAdd').classList.toggle('pressed');
+ if (document.getElementById('regimentAdd').classList.contains('pressed')) {
+ viewbox.style('cursor', 'crosshair').on('click', addRegimentOnClick);
+ tip('Click on map to create new regiment or fleet', true);
} else {
clearMainTip();
- viewbox.on("click", clicked).style("cursor", "default");
+ viewbox.on('click', clicked).style('cursor', 'default');
}
}
function addRegimentOnClick() {
const point = d3.mouse(this);
const cell = findCell(point[0], point[1]);
- const x = pack.cells.p[cell][0], y = pack.cells.p[cell][1];
- const state = +elSelected.dataset.state, military = pack.states[state].military;
+ const x = pack.cells.p[cell][0],
+ y = pack.cells.p[cell][1];
+ const state = +elSelected.dataset.state,
+ military = pack.states[state].military;
const i = military.length ? last(military).i + 1 : 0;
const n = +(pack.cells.h[cell] < 20); // naval or land
- const reg = {a:0, cell, i, n, u:{}, x, y, bx:x, by:y, state, icon:"🛡️"};
+ const reg = {a: 0, cell, i, n, u: {}, x, y, bx: x, by: y, state, icon: '🛡️'};
reg.name = Military.getName(reg, military);
military.push(reg);
Military.generateNote(reg, pack.states[state]); // add legend
@@ -166,92 +193,124 @@ function editRegiment(selector) {
}
function toggleAttack() {
- document.getElementById("regimentAttack").classList.toggle("pressed");
- if (document.getElementById("regimentAttack").classList.contains("pressed")) {
- viewbox.style("cursor", "crosshair").on("click", attackRegimentOnClick);
- tip("Click on another regiment to initiate battle", true);
- armies.selectAll(":scope > g").classed("draggable", false);
+ document.getElementById('regimentAttack').classList.toggle('pressed');
+ if (document.getElementById('regimentAttack').classList.contains('pressed')) {
+ viewbox.style('cursor', 'crosshair').on('click', attackRegimentOnClick);
+ tip('Click on another regiment to initiate battle', true);
+ armies.selectAll(':scope > g').classed('draggable', false);
} else {
clearMainTip();
- armies.selectAll(":scope > g").classed("draggable", true);
- viewbox.on("click", clicked).style("cursor", "default");
+ armies.selectAll(':scope > g').classed('draggable', true);
+ viewbox.on('click', clicked).style('cursor', 'default');
}
}
function attackRegimentOnClick() {
- const target = d3.event.target, regSelected = target.parentElement, army = regSelected.parentElement;
- const oldState = +elSelected.dataset.state, newState = +regSelected.dataset.state;
+ const target = d3.event.target,
+ regSelected = target.parentElement,
+ army = regSelected.parentElement;
+ const oldState = +elSelected.dataset.state,
+ newState = +regSelected.dataset.state;
- if (army.parentElement.id !== "armies") {tip("Please click on a regiment to attack", false, "error"); return;}
- if (regSelected === elSelected) {tip("Regiment cannot attack itself", false, "error"); return;}
- if (oldState === newState) {tip("Cannot attack fraternal regiment", false, "error"); return;}
+ if (army.parentElement.id !== 'armies') {
+ tip('Please click on a regiment to attack', false, 'error');
+ return;
+ }
+ if (regSelected === elSelected) {
+ tip('Regiment cannot attack itself', false, 'error');
+ return;
+ }
+ if (oldState === newState) {
+ tip('Cannot attack fraternal regiment', false, 'error');
+ return;
+ }
const attacker = regiment();
- const defender = pack.states[regSelected.dataset.state].military.find(r => r.i == regSelected.dataset.id);
- if (!attacker.a || !defender.a) {tip("Regiment has no troops to battle", false, "error"); return;}
+ const defender = pack.states[regSelected.dataset.state].military.find((r) => r.i == regSelected.dataset.id);
+ if (!attacker.a || !defender.a) {
+ tip('Regiment has no troops to battle', false, 'error');
+ return;
+ }
// save initial position to temp attribute
- attacker.px = attacker.x, attacker.py = attacker.y;
- defender.px = defender.x, defender.py = defender.y;
+ (attacker.px = attacker.x), (attacker.py = attacker.y);
+ (defender.px = defender.x), (defender.py = defender.y);
// move attacker to defender
- Military.moveRegiment(attacker, defender.x, defender.y-8);
+ Military.moveRegiment(attacker, defender.x, defender.y - 8);
// draw battle icon
- const attack = d3.transition().delay(300).duration(700).ease(d3.easeSinInOut).on("end", () => new Battle(attacker, defender));
- svg.append("text").attr("x", window.innerWidth/2).attr("y", window.innerHeight/2)
- .text("⚔️").attr("font-size", 0).attr("opacity", 1)
- .style("dominant-baseline", "central").style("text-anchor", "middle")
- .transition(attack).attr("font-size", 1000).attr("opacity", .2).remove();
+ const attack = d3
+ .transition()
+ .delay(300)
+ .duration(700)
+ .ease(d3.easeSinInOut)
+ .on('end', () => new Battle(attacker, defender));
+ svg
+ .append('text')
+ .attr('x', window.innerWidth / 2)
+ .attr('y', window.innerHeight / 2)
+ .text('⚔️')
+ .attr('font-size', 0)
+ .attr('opacity', 1)
+ .style('dominant-baseline', 'central')
+ .style('text-anchor', 'middle')
+ .transition(attack)
+ .attr('font-size', 1000)
+ .attr('opacity', 0.2)
+ .remove();
clearMainTip();
- $("#regimentEditor").dialog("close");
+ $('#regimentEditor').dialog('close');
}
function toggleAttach() {
- document.getElementById("regimentAttach").classList.toggle("pressed");
- if (document.getElementById("regimentAttach").classList.contains("pressed")) {
- viewbox.style("cursor", "crosshair").on("click", attachRegimentOnClick);
- tip("Click on another regiment to unite both regiments. The current regiment will be removed", true);
- armies.selectAll(":scope > g").classed("draggable", false);
+ document.getElementById('regimentAttach').classList.toggle('pressed');
+ if (document.getElementById('regimentAttach').classList.contains('pressed')) {
+ viewbox.style('cursor', 'crosshair').on('click', attachRegimentOnClick);
+ tip('Click on another regiment to unite both regiments. The current regiment will be removed', true);
+ armies.selectAll(':scope > g').classed('draggable', false);
} else {
clearMainTip();
- armies.selectAll(":scope > g").classed("draggable", true);
- viewbox.on("click", clicked).style("cursor", "default");
+ armies.selectAll(':scope > g').classed('draggable', true);
+ viewbox.on('click', clicked).style('cursor', 'default');
}
}
function attachRegimentOnClick() {
- const target = d3.event.target, regSelected = target.parentElement, army = regSelected.parentElement;
- const oldState = +elSelected.dataset.state, newState = +regSelected.dataset.state;
+ const target = d3.event.target,
+ regSelected = target.parentElement,
+ army = regSelected.parentElement;
+ const oldState = +elSelected.dataset.state,
+ newState = +regSelected.dataset.state;
- if (army.parentElement.id !== "armies") {tip("Please click on a regiment", false, "error"); return;}
- if (regSelected === elSelected) {tip("Cannot attach regiment to itself. Please click on another regiment", false, "error"); return;}
+ if (army.parentElement.id !== 'armies') return tip('Please click on a regiment', false, 'error');
+ if (regSelected === elSelected) return tip('Cannot attach regiment to itself. Please click on another regiment', false, 'error');
const reg = regiment(); // reg to be attached
- const sel = pack.states[newState].military.find(r => r.i == regSelected.dataset.id); // reg to attach to
+ const sel = pack.states[newState].military.find((r) => r.i == regSelected.dataset.id); // reg to attach to
for (const unit of options.military) {
const u = unit.name;
- if (reg.u[u]) sel.u[u] ? sel.u[u] += reg.u[u] : sel.u[u] = reg.u[u];
+ if (reg.u[u]) sel.u[u] ? (sel.u[u] += reg.u[u]) : (sel.u[u] = reg.u[u]);
}
sel.a = d3.sum(Object.values(sel.u)); // reg total
- regSelected.querySelector("text").innerHTML = Military.getTotal(sel); // update selected reg total text
+ regSelected.querySelector('text').innerHTML = Military.getTotal(sel); // update selected reg total text
// remove attached regiment
const military = pack.states[oldState].military;
military.splice(military.indexOf(reg), 1);
- const index = notes.findIndex(n => n.id === elSelected.id);
+ const index = notes.findIndex((n) => n.id === elSelected.id);
if (index != -1) notes.splice(index, 1);
elSelected.remove();
if (regimentsOverviewRefresh.offsetParent) regimentsOverviewRefresh.click();
- $("#regimentEditor").dialog("close");
- editRegiment("#"+regSelected.id);
+ $('#regimentEditor').dialog('close');
+ editRegiment('#' + regSelected.id);
}
function regenerateLegend() {
- const index = notes.findIndex(n => n.id === elSelected.id);
+ const index = notes.findIndex((n) => n.id === elSelected.id);
if (index != -1) notes.splice(index, 1);
const s = pack.states[elSelected.dataset.state];
@@ -263,85 +322,83 @@ function editRegiment(selector) {
}
function removeRegiment() {
- alertMessage.innerHTML = "Are you sure you want to remove the regiment?";
- $("#alert").dialog({resizable: false, title: "Remove regiment",
- buttons: {
- Remove: function() {
- $(this).dialog("close");
- const military = pack.states[elSelected.dataset.state].military;
- const regIndex = military.indexOf(regiment());
- if (regIndex === -1) return;
- military.splice(regIndex, 1);
+ const message = 'Are you sure you want to remove the regiment?
This action cannot be reverted';
+ const onConfirm = () => {
+ const military = pack.states[elSelected.dataset.state].military;
+ const regIndex = military.indexOf(regiment());
+ if (regIndex === -1) return;
+ military.splice(regIndex, 1);
- const index = notes.findIndex(n => n.id === elSelected.id);
- if (index != -1) notes.splice(index, 1);
- elSelected.remove();
+ const index = notes.findIndex((n) => n.id === elSelected.id);
+ if (index != -1) notes.splice(index, 1);
+ elSelected.remove();
- if (militaryOverviewRefresh.offsetParent) militaryOverviewRefresh.click();
- if (regimentsOverviewRefresh.offsetParent) regimentsOverviewRefresh.click();
- $("#regimentEditor").dialog("close");
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ if (militaryOverviewRefresh.offsetParent) militaryOverviewRefresh.click();
+ if (regimentsOverviewRefresh.offsetParent) regimentsOverviewRefresh.click();
+ $('#regimentEditor').dialog('close');
+ };
+ confirmationDialog({title: 'Remove regiment', message, confirm: 'Remove', onConfirm});
}
function dragRegiment() {
d3.select(this).raise();
d3.select(this.parentNode).raise();
- const reg = pack.states[this.dataset.state].military.find(r => r.i == this.dataset.id);
- const size = +armies.attr("box-size");
+ const reg = pack.states[this.dataset.state].military.find((r) => r.i == this.dataset.id);
+ const size = +armies.attr('box-size');
const w = reg.n ? size * 4 : size * 6;
const h = size * 2;
- const x1 = x => rn(x - w / 2, 2);
- const y1 = y => rn(y - size, 2);
+ const x1 = (x) => rn(x - w / 2, 2);
+ const y1 = (y) => rn(y - size, 2);
- const baseRect = this.querySelector("rect");
- const text = this.querySelector("text");
- const iconRect = this.querySelectorAll("rect")[1];
- const icon = this.querySelector(".regimentIcon");
+ const baseRect = this.querySelector('rect');
+ const text = this.querySelector('text');
+ const iconRect = this.querySelectorAll('rect')[1];
+ const icon = this.querySelector('.regimentIcon');
const self = elSelected === this;
- const baseLine = viewbox.select("g#regimentBase > line");
+ const baseLine = viewbox.select('g#regimentBase > line');
- d3.event.on("drag", function() {
- const x = reg.x = d3.event.x, y = reg.y = d3.event.y;
+ d3.event.on('drag', function () {
+ const x = (reg.x = d3.event.x),
+ y = (reg.y = d3.event.y);
- baseRect.setAttribute("x", x1(x));
- baseRect.setAttribute("y", y1(y));
- text.setAttribute("x", x);
- text.setAttribute("y", y);
- iconRect.setAttribute("x", x1(x)-h);
- iconRect.setAttribute("y", y1(y));
- icon.setAttribute("x", x1(x)-size);
- icon.setAttribute("y", y);
- if (self) baseLine.attr("x2", x).attr("y2", y);
+ baseRect.setAttribute('x', x1(x));
+ baseRect.setAttribute('y', y1(y));
+ text.setAttribute('x', x);
+ text.setAttribute('y', y);
+ iconRect.setAttribute('x', x1(x) - h);
+ iconRect.setAttribute('y', y1(y));
+ icon.setAttribute('x', x1(x) - size);
+ icon.setAttribute('y', y);
+ if (self) baseLine.attr('x2', x).attr('y2', y);
});
}
function dragBase() {
- const baseLine = viewbox.select("g#regimentBase > line");
+ const baseLine = viewbox.select('g#regimentBase > line');
const reg = regiment();
- d3.event.on("drag", function() {
- this.setAttribute("cx", d3.event.x);
- this.setAttribute("cy", d3.event.y);
- baseLine.attr("x1", d3.event.x).attr("y1", d3.event.y);
+ d3.event.on('drag', function () {
+ this.setAttribute('cx', d3.event.x);
+ this.setAttribute('cy', d3.event.y);
+ baseLine.attr('x1', d3.event.x).attr('y1', d3.event.y);
});
- d3.event.on("end", function() {reg.bx = d3.event.x; reg.by = d3.event.y;});
+ d3.event.on('end', function () {
+ reg.bx = d3.event.x;
+ reg.by = d3.event.y;
+ });
}
function closeEditor() {
- armies.selectAll(":scope > g").classed("draggable", false);
- armies.selectAll("g>g").call(d3.drag().on("drag", null));
- viewbox.selectAll("g#regimentBase").remove();
- document.getElementById("regimentAdd").classList.remove("pressed");
- document.getElementById("regimentAttack").classList.remove("pressed");
- document.getElementById("regimentAttach").classList.remove("pressed");
+ armies.selectAll(':scope > g').classed('draggable', false);
+ armies.selectAll('g>g').call(d3.drag().on('drag', null));
+ viewbox.selectAll('g#regimentBase').remove();
+ document.getElementById('regimentAdd').classList.remove('pressed');
+ document.getElementById('regimentAttack').classList.remove('pressed');
+ document.getElementById('regimentAttach').classList.remove('pressed');
restoreDefaultEvents();
elSelected = null;
}
-
-}
\ No newline at end of file
+}
diff --git a/modules/ui/relief-editor.js b/modules/ui/relief-editor.js
index 7cd2d1d2..594ea710 100644
--- a/modules/ui/relief-editor.js
+++ b/modules/ui/relief-editor.js
@@ -1,19 +1,21 @@
-"use strict";
+'use strict';
function editReliefIcon() {
if (customization) return;
- closeDialogs(".stable");
- if (!layerIsOn("toggleRelief")) toggleRelief();
+ closeDialogs('.stable');
+ if (!layerIsOn('toggleRelief')) toggleRelief();
- terrain.selectAll("use").call(d3.drag().on("drag", dragReliefIcon)).classed("draggable", true);
+ terrain.selectAll('use').call(d3.drag().on('drag', dragReliefIcon)).classed('draggable', true);
elSelected = d3.select(d3.event.target);
restoreEditMode();
updateReliefIconSelected();
updateReliefSizeInput();
- $("#reliefEditor").dialog({
- title: "Edit Relief Icons", resizable: false, width: "27em",
- position: {my: "left top", at: "left+10 top+10", of: "#map"},
+ $('#reliefEditor').dialog({
+ title: 'Edit Relief Icons',
+ resizable: false,
+ width: '27em',
+ position: {my: 'left top', at: 'left+10 top+10', of: '#map'},
close: closeReliefEditor
});
@@ -21,62 +23,63 @@ function editReliefIcon() {
modules.editReliefIcon = true;
// add listeners
- document.getElementById("reliefIndividual").addEventListener("click", enterIndividualMode);
- document.getElementById("reliefBulkAdd").addEventListener("click", enterBulkAddMode);
- document.getElementById("reliefBulkRemove").addEventListener("click", enterBulkRemoveMode);
+ document.getElementById('reliefIndividual').addEventListener('click', enterIndividualMode);
+ document.getElementById('reliefBulkAdd').addEventListener('click', enterBulkAddMode);
+ document.getElementById('reliefBulkRemove').addEventListener('click', enterBulkRemoveMode);
- document.getElementById("reliefSize").addEventListener("input", changeIconSize);
- document.getElementById("reliefSizeNumber").addEventListener("input", changeIconSize);
- document.getElementById("reliefEditorSet").addEventListener("change", changeIconsSet);
- reliefIconsDiv.querySelectorAll("svg").forEach(el => el.addEventListener("click", changeIcon));
+ document.getElementById('reliefSize').addEventListener('input', changeIconSize);
+ document.getElementById('reliefSizeNumber').addEventListener('input', changeIconSize);
+ document.getElementById('reliefEditorSet').addEventListener('change', changeIconsSet);
+ reliefIconsDiv.querySelectorAll('svg').forEach((el) => el.addEventListener('click', changeIcon));
- document.getElementById("reliefEditStyle").addEventListener("click", () => editStyle("terrain"));
- document.getElementById("reliefCopy").addEventListener("click", copyIcon);
- document.getElementById("reliefMoveFront").addEventListener("click", () => elSelected.raise());
- document.getElementById("reliefMoveBack").addEventListener("click", () => elSelected.lower());
- document.getElementById("reliefRemove").addEventListener("click", removeIcon);
+ document.getElementById('reliefEditStyle').addEventListener('click', () => editStyle('terrain'));
+ document.getElementById('reliefCopy').addEventListener('click', copyIcon);
+ document.getElementById('reliefMoveFront').addEventListener('click', () => elSelected.raise());
+ document.getElementById('reliefMoveBack').addEventListener('click', () => elSelected.lower());
+ document.getElementById('reliefRemove').addEventListener('click', removeIcon);
function dragReliefIcon() {
- const dx = +this.getAttribute("x") - d3.event.x;
- const dy = +this.getAttribute("y") - d3.event.y;
+ const dx = +this.getAttribute('x') - d3.event.x;
+ const dy = +this.getAttribute('y') - d3.event.y;
- d3.event.on("drag", function() {
- const x = d3.event.x, y = d3.event.y;
- this.setAttribute("x", dx+x);
- this.setAttribute("y", dy+y);
+ d3.event.on('drag', function () {
+ const x = d3.event.x,
+ y = d3.event.y;
+ this.setAttribute('x', dx + x);
+ this.setAttribute('y', dy + y);
});
}
function restoreEditMode() {
- if (!reliefTools.querySelector("button.pressed")) enterIndividualMode(); else
- if (reliefBulkAdd.classList.contains("pressed")) enterBulkAddMode(); else
- if (reliefBulkRemove.classList.contains("pressed")) enterBulkRemoveMode();
+ if (!reliefTools.querySelector('button.pressed')) enterIndividualMode();
+ else if (reliefBulkAdd.classList.contains('pressed')) enterBulkAddMode();
+ else if (reliefBulkRemove.classList.contains('pressed')) enterBulkRemoveMode();
}
function updateReliefIconSelected() {
- const type = elSelected.attr("href") || elSelected.attr("data-type");
- const button = reliefIconsDiv.querySelector("svg[data-type='"+type+"']");
+ const type = elSelected.attr('href') || elSelected.attr('data-type');
+ const button = reliefIconsDiv.querySelector("svg[data-type='" + type + "']");
- reliefIconsDiv.querySelectorAll("svg.pressed").forEach(b => b.classList.remove("pressed"));
- button.classList.add("pressed");
- reliefIconsDiv.querySelectorAll("div").forEach(b => b.style.display = "none");
- button.parentNode.style.display = "block";
+ reliefIconsDiv.querySelectorAll('svg.pressed').forEach((b) => b.classList.remove('pressed'));
+ button.classList.add('pressed');
+ reliefIconsDiv.querySelectorAll('div').forEach((b) => (b.style.display = 'none'));
+ button.parentNode.style.display = 'block';
reliefEditorSet.value = button.parentNode.dataset.type;
}
function updateReliefSizeInput() {
- const size = +elSelected.attr("width");
+ const size = +elSelected.attr('width');
reliefSize.value = reliefSizeNumber.value = rn(size);
}
function enterIndividualMode() {
- reliefTools.querySelectorAll("button.pressed").forEach(b => b.classList.remove("pressed"));
- reliefIndividual.classList.add("pressed");
+ reliefTools.querySelectorAll('button.pressed').forEach((b) => b.classList.remove('pressed'));
+ reliefIndividual.classList.add('pressed');
- reliefSizeDiv.style.display = "block";
- reliefRadiusDiv.style.display = "none";
- reliefSpacingDiv.style.display = "none";
- reliefIconsSeletionAny.style.display = "none";
+ reliefSizeDiv.style.display = 'block';
+ reliefRadiusDiv.style.display = 'none';
+ reliefSpacingDiv.style.display = 'none';
+ reliefIconsSeletionAny.style.display = 'none';
updateReliefSizeInput();
restoreDefaultEvents();
@@ -84,22 +87,23 @@ function editReliefIcon() {
}
function enterBulkAddMode() {
- reliefTools.querySelectorAll("button.pressed").forEach(b => b.classList.remove("pressed"));
- reliefBulkAdd.classList.add("pressed");
+ reliefTools.querySelectorAll('button.pressed').forEach((b) => b.classList.remove('pressed'));
+ reliefBulkAdd.classList.add('pressed');
- reliefSizeDiv.style.display = "block";
- reliefRadiusDiv.style.display = "block";
- reliefSpacingDiv.style.display = "block";
- reliefIconsSeletionAny.style.display = "none";
+ reliefSizeDiv.style.display = 'block';
+ reliefRadiusDiv.style.display = 'block';
+ reliefSpacingDiv.style.display = 'block';
+ reliefIconsSeletionAny.style.display = 'none';
- const pressedType = reliefIconsDiv.querySelector("svg.pressed");
- if (pressedType.id === "reliefIconsSeletionAny") { // in "any" is pressed, select first type
- reliefIconsSeletionAny.classList.remove("pressed");
- reliefIconsDiv.querySelector("svg").classList.add("pressed");
+ const pressedType = reliefIconsDiv.querySelector('svg.pressed');
+ if (pressedType.id === 'reliefIconsSeletionAny') {
+ // in "any" is pressed, select first type
+ reliefIconsSeletionAny.classList.remove('pressed');
+ reliefIconsDiv.querySelector('svg').classList.add('pressed');
}
- viewbox.style("cursor", "crosshair").call(d3.drag().on("start", dragToAdd)).on("touchmove mousemove", moveBrush);
- tip("Drag to place relief icons within radius", true);
+ viewbox.style('cursor', 'crosshair').call(d3.drag().on('start', dragToAdd)).on('touchmove mousemove', moveBrush);
+ tip('Drag to place relief icons within radius', true);
}
function moveBrush() {
@@ -110,8 +114,11 @@ function editReliefIcon() {
}
function dragToAdd() {
- const pressed = reliefIconsDiv.querySelector("svg.pressed");
- if (!pressed) {tip("Please select an icon", false, error); return;}
+ const pressed = reliefIconsDiv.querySelector('svg.pressed');
+ if (!pressed) {
+ tip('Please select an icon', false, error);
+ return;
+ }
const type = pressed.dataset.type;
const r = +reliefRadiusNumber.value;
@@ -121,19 +128,19 @@ function editReliefIcon() {
// build a quadtree
const tree = d3.quadtree();
const positions = [];
- terrain.selectAll("use").each(function() {
- const x = +this.getAttribute("x") + this.getAttribute("width") / 2;
- const y = +this.getAttribute("y") + this.getAttribute("height") / 2;
+ terrain.selectAll('use').each(function () {
+ const x = +this.getAttribute('x') + this.getAttribute('width') / 2;
+ const y = +this.getAttribute('y') + this.getAttribute('height') / 2;
tree.add([x, y, x]);
const box = this.getBBox();
positions.push(box.y + box.height);
});
- d3.event.on("drag", function() {
+ d3.event.on('drag', function () {
const p = d3.mouse(this);
moveCircle(p[0], p[1], r);
- d3.range(Math.ceil(r/10)).forEach(function() {
+ d3.range(Math.ceil(r / 10)).forEach(function () {
const a = Math.PI * 2 * Math.random();
const rad = r * Math.random();
const cx = p[0] + rad * Math.cos(a);
@@ -142,83 +149,93 @@ function editReliefIcon() {
if (tree.find(cx, cy, spacing)) return; // too close to existing icon
if (pack.cells.h[findCell(cx, cy)] < 20) return; // on water cell
- const h = rn(size / 2 * (Math.random() * .4 + .8), 2);
- const x = rn(cx-h, 2);
- const y = rn(cy-h, 2);
+ const h = rn((size / 2) * (Math.random() * 0.4 + 0.8), 2);
+ const x = rn(cx - h, 2);
+ const y = rn(cy - h, 2);
const z = y + h * 2;
- const s = rn(h*2, 2);
+ const s = rn(h * 2, 2);
let nth = 1;
- while (positions[nth] && z > positions[nth]) {nth++;}
+ while (positions[nth] && z > positions[nth]) {
+ nth++;
+ }
tree.add([cx, cy]);
positions.push(z);
- terrain.insert("use", ":nth-child("+nth+")").attr("href", type)
- .attr("x", x).attr("y", y).attr("width", s).attr("height", s);
+ terrain
+ .insert('use', ':nth-child(' + nth + ')')
+ .attr('href', type)
+ .attr('x', x)
+ .attr('y', y)
+ .attr('width', s)
+ .attr('height', s);
});
-
});
}
function enterBulkRemoveMode() {
- reliefTools.querySelectorAll("button.pressed").forEach(b => b.classList.remove("pressed"));
- reliefBulkRemove.classList.add("pressed");
+ reliefTools.querySelectorAll('button.pressed').forEach((b) => b.classList.remove('pressed'));
+ reliefBulkRemove.classList.add('pressed');
- reliefSizeDiv.style.display = "none";
- reliefRadiusDiv.style.display = "block";
- reliefSpacingDiv.style.display = "none";
- reliefIconsSeletionAny.style.display = "inline-block";
+ reliefSizeDiv.style.display = 'none';
+ reliefRadiusDiv.style.display = 'block';
+ reliefSpacingDiv.style.display = 'none';
+ reliefIconsSeletionAny.style.display = 'inline-block';
- viewbox.style("cursor", "crosshair").call(d3.drag().on("start", dragToRemove)).on("touchmove mousemove", moveBrush);;
- tip("Drag to remove relief icons in radius", true);
+ viewbox.style('cursor', 'crosshair').call(d3.drag().on('start', dragToRemove)).on('touchmove mousemove', moveBrush);
+ tip('Drag to remove relief icons in radius', true);
}
function dragToRemove() {
- const pressed = reliefIconsDiv.querySelector("svg.pressed");
- if (!pressed) {tip("Please select an icon", false, error); return;}
+ const pressed = reliefIconsDiv.querySelector('svg.pressed');
+ if (!pressed) {
+ tip('Please select an icon', false, error);
+ return;
+ }
const r = +reliefRadiusNumber.value;
const type = pressed.dataset.type;
- const icons = type ? terrain.selectAll("use[href='"+type+"']") : terrain.selectAll("use");
+ const icons = type ? terrain.selectAll("use[href='" + type + "']") : terrain.selectAll('use');
const tree = d3.quadtree();
- icons.each(function() {
- const x = +this.getAttribute("x") + this.getAttribute("width") / 2;
- const y = +this.getAttribute("y") + this.getAttribute("height") / 2;
+ icons.each(function () {
+ const x = +this.getAttribute('x') + this.getAttribute('width') / 2;
+ const y = +this.getAttribute('y') + this.getAttribute('height') / 2;
tree.add([x, y, this]);
});
- d3.event.on("drag", function() {
+ d3.event.on('drag', function () {
const p = d3.mouse(this);
moveCircle(p[0], p[1], r);
- tree.findAll(p[0], p[1], r).forEach(f => f[2].remove());
+ tree.findAll(p[0], p[1], r).forEach((f) => f[2].remove());
});
}
function changeIconSize() {
const size = +reliefSizeNumber.value;
- if (!reliefIndividual.classList.contains("pressed")) return;
+ if (!reliefIndividual.classList.contains('pressed')) return;
- const shift = (size - +elSelected.attr("width")) / 2;
- elSelected.attr("width", size).attr("height", size);
- const x = +elSelected.attr("x"), y = +elSelected.attr("y");
- elSelected.attr("x", x-shift).attr("y", y-shift);
+ const shift = (size - +elSelected.attr('width')) / 2;
+ elSelected.attr('width', size).attr('height', size);
+ const x = +elSelected.attr('x'),
+ y = +elSelected.attr('y');
+ elSelected.attr('x', x - shift).attr('y', y - shift);
}
function changeIconsSet() {
const set = reliefEditorSet.value;
- reliefIconsDiv.querySelectorAll("div").forEach(b => b.style.display = "none");
- reliefIconsDiv.querySelector("div[data-type='" + set + "']").style.display = "block";
+ reliefIconsDiv.querySelectorAll('div').forEach((b) => (b.style.display = 'none'));
+ reliefIconsDiv.querySelector("div[data-type='" + set + "']").style.display = 'block';
}
function changeIcon() {
- if (this.classList.contains("pressed")) return;
+ if (this.classList.contains('pressed')) return;
- reliefIconsDiv.querySelectorAll("svg.pressed").forEach(b => b.classList.remove("pressed"))
- this.classList.add("pressed");
+ reliefIconsDiv.querySelectorAll('svg.pressed').forEach((b) => b.classList.remove('pressed'));
+ this.classList.add('pressed');
- if (reliefIndividual.classList.contains("pressed")) {
+ if (reliefIndividual.classList.contains('pressed')) {
const type = this.dataset.type;
- elSelected.attr("href", type);
+ elSelected.attr('href', type);
}
}
@@ -226,35 +243,31 @@ function editReliefIcon() {
const parent = elSelected.node().parentNode;
const copy = elSelected.node().cloneNode(true);
- let x = +elSelected.attr("x") - 3, y = +elSelected.attr("y") - 3;
- while (parent.querySelector("[x='"+x+"']","[x='"+y+"']")) {
- x -= 3; y -= 3;
+ let x = +elSelected.attr('x') - 3,
+ y = +elSelected.attr('y') - 3;
+ while (parent.querySelector("[x='" + x + "']", "[x='" + y + "']")) {
+ x -= 3;
+ y -= 3;
}
- copy.setAttribute("x", x);
- copy.setAttribute("y", y);
+ copy.setAttribute('x', x);
+ copy.setAttribute('y', y);
parent.insertBefore(copy, null);
}
function removeIcon() {
- alertMessage.innerHTML = `Are you sure you want to remove the icon?`;
- $("#alert").dialog({resizable: false, title: "Remove relief icon",
- buttons: {
- Remove: function() {
- $(this).dialog("close");
- elSelected.remove();
- $("#reliefEditor").dialog("close");
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ const message = 'Are you sure you want to remove the relief icon?
This action cannot be reverted';
+ const onConfirm = () => {
+ elSelected.remove();
+ $('#reliefEditor').dialog('close');
+ };
+ confirmationDialog({title: 'Remove relief icon', message, confirm: 'Remove', onConfirm});
}
function closeReliefEditor() {
- terrain.selectAll("use").call(d3.drag().on("drag", null)).classed("draggable", false);
+ terrain.selectAll('use').call(d3.drag().on('drag', null)).classed('draggable', false);
removeCircle();
unselect();
clearMainTip();
}
-
}
diff --git a/modules/ui/religions-editor.js b/modules/ui/religions-editor.js
index 8161f15e..981d4d17 100644
--- a/modules/ui/religions-editor.js
+++ b/modules/ui/religions-editor.js
@@ -1,14 +1,14 @@
-"use strict";
+'use strict';
function editReligions() {
if (customization) return;
- closeDialogs("#religionsEditor, .stable");
- if (!layerIsOn("toggleReligions")) toggleReligions();
- if (layerIsOn("toggleCultures")) toggleCultures();
- if (layerIsOn("toggleStates")) toggleStates();
- if (layerIsOn("toggleBiomes")) toggleBiomes();
- if (layerIsOn("toggleProvinces")) toggleProvinces();
+ closeDialogs('#religionsEditor, .stable');
+ if (!layerIsOn('toggleReligions')) toggleReligions();
+ if (layerIsOn('toggleCultures')) toggleCultures();
+ if (layerIsOn('toggleStates')) toggleStates();
+ if (layerIsOn('toggleBiomes')) toggleBiomes();
+ if (layerIsOn('toggleProvinces')) toggleProvinces();
- const body = document.getElementById("religionsBody");
+ const body = document.getElementById('religionsBody');
const animate = d3.transition().duration(1500).ease(d3.easeSinIn);
refreshReligionsEditor();
drawReligionCenters();
@@ -16,23 +16,26 @@ function editReligions() {
if (modules.editReligions) return;
modules.editReligions = true;
- $("#religionsEditor").dialog({
- title: "Religions Editor", resizable: false, width: fitContent(), close: closeReligionsEditor,
- position: {my: "right top", at: "right-10 top+10", of: "svg"}
+ $('#religionsEditor').dialog({
+ title: 'Religions Editor',
+ resizable: false,
+ width: fitContent(),
+ close: closeReligionsEditor,
+ position: {my: 'right top', at: 'right-10 top+10', of: 'svg'}
});
// add listeners
- document.getElementById("religionsEditorRefresh").addEventListener("click", refreshReligionsEditor);
- document.getElementById("religionsEditStyle").addEventListener("click", () => editStyle("relig"));
- document.getElementById("religionsLegend").addEventListener("click", toggleLegend);
- document.getElementById("religionsPercentage").addEventListener("click", togglePercentageMode);
- document.getElementById("religionsHeirarchy").addEventListener("click", showHierarchy);
- document.getElementById("religionsExtinct").addEventListener("click", toggleExtinct);
- document.getElementById("religionsManually").addEventListener("click", enterReligionsManualAssignent);
- document.getElementById("religionsManuallyApply").addEventListener("click", applyReligionsManualAssignent);
- document.getElementById("religionsManuallyCancel").addEventListener("click", () => exitReligionsManualAssignment());
- document.getElementById("religionsAdd").addEventListener("click", enterAddReligionMode);
- document.getElementById("religionsExport").addEventListener("click", downloadReligionsData);
+ document.getElementById('religionsEditorRefresh').addEventListener('click', refreshReligionsEditor);
+ document.getElementById('religionsEditStyle').addEventListener('click', () => editStyle('relig'));
+ document.getElementById('religionsLegend').addEventListener('click', toggleLegend);
+ document.getElementById('religionsPercentage').addEventListener('click', togglePercentageMode);
+ document.getElementById('religionsHeirarchy').addEventListener('click', showHierarchy);
+ document.getElementById('religionsExtinct').addEventListener('click', toggleExtinct);
+ document.getElementById('religionsManually').addEventListener('click', enterReligionsManualAssignent);
+ document.getElementById('religionsManuallyApply').addEventListener('click', applyReligionsManualAssignent);
+ document.getElementById('religionsManuallyCancel').addEventListener('click', () => exitReligionsManualAssignment());
+ document.getElementById('religionsAdd').addEventListener('click', enterAddReligionMode);
+ document.getElementById('religionsExport').addEventListener('click', downloadReligionsData);
function refreshReligionsEditor() {
religionsCollectStatistics();
@@ -40,8 +43,9 @@ function editReligions() {
}
function religionsCollectStatistics() {
- const cells = pack.cells, religions = pack.religions;
- religions.forEach(r => r.cells = r.area = r.rural = r.urban = 0);
+ const cells = pack.cells,
+ religions = pack.religions;
+ religions.forEach((r) => (r.cells = r.area = r.rural = r.urban = 0));
for (const i of cells.i) {
if (cells.h[i] < 20) continue;
@@ -55,30 +59,34 @@ function editReligions() {
// add line for each religion
function religionsEditorAddLines() {
- const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value;
- let lines = "", totalArea = 0, totalPopulation = 0;
+ const unit = areaUnit.value === 'square' ? ' ' + distanceUnitInput.value + '²' : ' ' + areaUnit.value;
+ let lines = '',
+ totalArea = 0,
+ totalPopulation = 0;
for (const r of pack.religions) {
if (r.removed) continue;
- const area = r.area * (distanceScaleInput.value ** 2);
+ const area = r.area * distanceScaleInput.value ** 2;
const rural = r.rural * populationRate.value;
const urban = r.urban * populationRate.value * urbanization.value;
const population = rn(rural + urban);
- if (r.i && !r.cells && body.dataset.extinct !== "show") continue; // hide extinct religions
+ if (r.i && !r.cells && body.dataset.extinct !== 'show') continue; // hide extinct religions
const populationTip = `Believers: ${si(population)}; Rural areas: ${si(rural)}; Urban areas: ${si(urban)}. Click to change`;
totalArea += area;
totalPopulation += population;
if (r.i) {
lines += `
-
+ data-population=${population} data-type=${r.type} data-form=${r.form} data-deity="${r.deity ? r.deity : ''}" data-expansionism=${r.expansionism}>
+
${getTypeOptions(r.type)}
-
+
${si(area) + unit}
@@ -104,94 +112,119 @@ function editReligions() {
body.innerHTML = lines;
// update footer
- const valid = pack.religions.filter(r => r.i && !r.removed);
- religionsOrganized.innerHTML = valid.filter(r => r.type === "Organized").length;
- religionsHeresies.innerHTML = valid.filter(r => r.type === "Heresy").length;
- religionsCults.innerHTML = valid.filter(r => r.type === "Cult").length;
- religionsFolk.innerHTML = valid.filter(r => r.type === "Folk").length;
+ const valid = pack.religions.filter((r) => r.i && !r.removed);
+ religionsOrganized.innerHTML = valid.filter((r) => r.type === 'Organized').length;
+ religionsHeresies.innerHTML = valid.filter((r) => r.type === 'Heresy').length;
+ religionsCults.innerHTML = valid.filter((r) => r.type === 'Cult').length;
+ religionsFolk.innerHTML = valid.filter((r) => r.type === 'Folk').length;
religionsFooterArea.innerHTML = si(totalArea) + unit;
religionsFooterPopulation.innerHTML = si(totalPopulation);
religionsFooterArea.dataset.area = totalArea;
religionsFooterPopulation.dataset.population = totalPopulation;
// add listeners
- body.querySelectorAll("div.religions").forEach(el => el.addEventListener("mouseenter", ev => religionHighlightOn(ev)));
- body.querySelectorAll("div.religions").forEach(el => el.addEventListener("mouseleave", ev => religionHighlightOff(ev)));
- body.querySelectorAll("div.states").forEach(el => el.addEventListener("click", selectReligionOnLineClick));
- body.querySelectorAll("rect.fillRect").forEach(el => el.addEventListener("click", religionChangeColor));
- body.querySelectorAll("div > input.religionName").forEach(el => el.addEventListener("input", religionChangeName));
- body.querySelectorAll("div > select.religionType").forEach(el => el.addEventListener("change", religionChangeType));
- body.querySelectorAll("div > input.religionForm").forEach(el => el.addEventListener("input", religionChangeForm));
- body.querySelectorAll("div > input.religionDeity").forEach(el => el.addEventListener("input", religionChangeDeity));
- body.querySelectorAll("div > span.icon-arrows-cw").forEach(el => el.addEventListener("click", regenerateDeity));
- body.querySelectorAll("div > div.culturePopulation").forEach(el => el.addEventListener("click", changePopulation));
- body.querySelectorAll("div > span.icon-trash-empty").forEach(el => el.addEventListener("click", religionRemove));
+ body.querySelectorAll('div.religions').forEach((el) => el.addEventListener('mouseenter', (ev) => religionHighlightOn(ev)));
+ body.querySelectorAll('div.religions').forEach((el) => el.addEventListener('mouseleave', (ev) => religionHighlightOff(ev)));
+ body.querySelectorAll('div.states').forEach((el) => el.addEventListener('click', selectReligionOnLineClick));
+ body.querySelectorAll('rect.fillRect').forEach((el) => el.addEventListener('click', religionChangeColor));
+ body.querySelectorAll('div > input.religionName').forEach((el) => el.addEventListener('input', religionChangeName));
+ body.querySelectorAll('div > select.religionType').forEach((el) => el.addEventListener('change', religionChangeType));
+ body.querySelectorAll('div > input.religionForm').forEach((el) => el.addEventListener('input', religionChangeForm));
+ body.querySelectorAll('div > input.religionDeity').forEach((el) => el.addEventListener('input', religionChangeDeity));
+ body.querySelectorAll('div > span.icon-arrows-cw').forEach((el) => el.addEventListener('click', regenerateDeity));
+ body.querySelectorAll('div > div.culturePopulation').forEach((el) => el.addEventListener('click', changePopulation));
+ body.querySelectorAll('div > span.icon-trash-empty').forEach((el) => el.addEventListener('click', religionRemove));
- if (body.dataset.type === "percentage") {body.dataset.type = "absolute"; togglePercentageMode();}
+ if (body.dataset.type === 'percentage') {
+ body.dataset.type = 'absolute';
+ togglePercentageMode();
+ }
applySorting(religionsHeader);
- $("#religionsEditor").dialog({width: fitContent()});
+ $('#religionsEditor').dialog({width: fitContent()});
}
function getTypeOptions(type) {
- let options = "";
- const types = ["Folk", "Organized", "Cult", "Heresy"];
- types.forEach(t => options += `
${t} `);
+ let options = '';
+ const types = ['Folk', 'Organized', 'Cult', 'Heresy'];
+ types.forEach((t) => (options += `
${t} `));
return options;
}
function religionHighlightOn(event) {
const religion = +event.target.dataset.id;
- const info = document.getElementById("religionInfo");
+ const info = document.getElementById('religionInfo');
if (info) {
- d3.select("#hierarchy").select("g[data-id='"+religion+"'] > path").classed("selected", 1);
+ d3.select('#hierarchy')
+ .select("g[data-id='" + religion + "'] > path")
+ .classed('selected', 1);
const r = pack.religions[religion];
- const type = r.name.includes(r.type) ? ""
- : r.type === "Folk" || r.type === "Organized"
- ? ". " + r.type + " religion" : ". " + r.type;
- const form = r.form === r.type || r.name.includes(r.form) ? "" : ". " + r.form;
+ const type = r.name.includes(r.type) ? '' : r.type === 'Folk' || r.type === 'Organized' ? '. ' + r.type + ' religion' : '. ' + r.type;
+ const form = r.form === r.type || r.name.includes(r.form) ? '' : '. ' + r.form;
const rural = r.rural * populationRate.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}`;
- tip("Drag to change parent, drag to itself to move to the top level. Hold CTRL and click to change abbreviation");
+ tip('Drag to change parent, drag to itself to move to the top level. Hold CTRL and click to change abbreviation');
}
const el = body.querySelector(`div[data-id='${religion}']`);
- if (el) el.classList.add("active");
+ if (el) el.classList.add('active');
- if (!layerIsOn("toggleReligions")) return;
+ if (!layerIsOn('toggleReligions')) return;
if (customization) return;
- relig.select("#religion"+religion).raise().transition(animate).attr("stroke-width", 2.5).attr("stroke", "#c13119");
- debug.select("#religionsCenter"+religion).raise().transition(animate).attr("r", 8).attr("stroke-width", 2).attr("stroke", "#c13119");
+ relig
+ .select('#religion' + religion)
+ .raise()
+ .transition(animate)
+ .attr('stroke-width', 2.5)
+ .attr('stroke', '#c13119');
+ debug
+ .select('#religionsCenter' + religion)
+ .raise()
+ .transition(animate)
+ .attr('r', 8)
+ .attr('stroke-width', 2)
+ .attr('stroke', '#c13119');
}
function religionHighlightOff(event) {
const religion = +event.target.dataset.id;
- const info = document.getElementById("religionInfo");
+ const info = document.getElementById('religionInfo');
if (info) {
- d3.select("#hierarchy").select("g[data-id='"+religion+"'] > path").classed("selected", 0);
- info.innerHTML = "";
- tip("");
+ d3.select('#hierarchy')
+ .select("g[data-id='" + religion + "'] > path")
+ .classed('selected', 0);
+ info.innerHTML = '';
+ tip('');
}
- const el = body.querySelector(`div[data-id='${religion}']`)
- if (el) el.classList.remove("active");
+ const el = body.querySelector(`div[data-id='${religion}']`);
+ if (el) el.classList.remove('active');
- relig.select("#religion"+religion).transition().attr("stroke-width", null).attr("stroke", null);
- debug.select("#religionsCenter"+religion).transition().attr("r", 4).attr("stroke-width", 1.2).attr("stroke", null);
+ relig
+ .select('#religion' + religion)
+ .transition()
+ .attr('stroke-width', null)
+ .attr('stroke', null);
+ debug
+ .select('#religionsCenter' + religion)
+ .transition()
+ .attr('r', 4)
+ .attr('stroke-width', 1.2)
+ .attr('stroke', null);
}
function religionChangeColor() {
const el = this;
- const currentFill = el.getAttribute("fill");
+ const currentFill = el.getAttribute('fill');
const religion = +el.parentNode.parentNode.dataset.id;
- const callback = function(fill) {
- el.setAttribute("fill", fill);
+ const callback = function (fill) {
+ el.setAttribute('fill', fill);
pack.religions[religion].color = fill;
- relig.select("#religion"+religion).attr("fill", fill);
- debug.select("#religionsCenter"+religion).attr("fill", fill);
- }
+ relig.select('#religion' + religion).attr('fill', fill);
+ debug.select('#religionsCenter' + religion).attr('fill', fill);
+ };
openPicker(currentFill, callback);
}
@@ -200,7 +233,10 @@ function editReligions() {
const religion = +this.parentNode.dataset.id;
this.parentNode.dataset.name = this.value;
pack.religions[religion].name = this.value;
- pack.religions[religion].code = abbreviate(this.value, pack.religions.map(c => c.code));
+ pack.religions[religion].code = abbreviate(
+ this.value,
+ pack.religions.map((c) => c.code)
+ );
}
function religionChangeType() {
@@ -233,113 +269,131 @@ function editReligions() {
function changePopulation() {
const religion = +this.parentNode.dataset.id;
const r = pack.religions[religion];
- if (!r.cells) {tip("Religion does not have any cells, cannot change population", false, "error"); return;}
+ if (!r.cells) {
+ tip('Religion does not have any cells, cannot change population', false, 'error');
+ return;
+ }
const rural = rn(r.rural * populationRate.value);
const urban = rn(r.urban * populationRate.value * urbanization.value);
const total = rural + urban;
- const l = n => Number(n).toLocaleString();
- const burgs = pack.burgs.filter(b => !b.removed && pack.cells.religion[b.cell] === religion);
+ const l = (n) => Number(n).toLocaleString();
+ const burgs = pack.burgs.filter((b) => !b.removed && pack.cells.religion[b.cell] === religion);
alertMessage.innerHTML = `
Please note all population of religion territory is considered
believers of this religion. It means believers number change will directly change population
Rural:
- Urban:
+ Urban:
Total believers: ${l(total)} ⇒ ${l(total)} (100 %)
`;
- const update = function() {
+ const update = function () {
const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber;
if (isNaN(totalNew)) return;
totalPop.innerHTML = l(totalNew);
- totalPopPerc.innerHTML = rn(totalNew / total * 100);
- }
+ totalPopPerc.innerHTML = rn((totalNew / total) * 100);
+ };
ruralPop.oninput = () => update();
urbanPop.oninput = () => update();
- $("#alert").dialog({
- resizable: false, title: "Change believers number", width: "24em", buttons: {
- Apply: function() {applyPopulationChange(); $(this).dialog("close");},
- Cancel: function() {$(this).dialog("close");}
- }, position: {my: "center", at: "center", of: "svg"}
+ $('#alert').dialog({
+ resizable: false,
+ title: 'Change believers number',
+ width: '24em',
+ buttons: {
+ Apply: function () {
+ applyPopulationChange();
+ $(this).dialog('close');
+ },
+ Cancel: function () {
+ $(this).dialog('close');
+ }
+ },
+ position: {my: 'center', at: 'center', of: 'svg'}
});
function applyPopulationChange() {
const ruralChange = ruralPop.value / rural;
if (isFinite(ruralChange) && ruralChange !== 1) {
- const cells = pack.cells.i.filter(i => pack.cells.religion[i] === religion);
- cells.forEach(i => pack.cells.pop[i] *= ruralChange);
+ const cells = pack.cells.i.filter((i) => pack.cells.religion[i] === religion);
+ cells.forEach((i) => (pack.cells.pop[i] *= ruralChange));
}
if (!isFinite(ruralChange) && +ruralPop.value > 0) {
const points = ruralPop.value / populationRate.value;
- const cells = pack.cells.i.filter(i => pack.cells.religion[i] === religion);
+ const cells = pack.cells.i.filter((i) => pack.cells.religion[i] === religion);
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.value / urbanization.value;
const population = rn(points / burgs.length, 4);
- burgs.forEach(b => b.population = population);
+ burgs.forEach((b) => (b.population = population));
}
refreshReligionsEditor();
}
-
}
function religionRemove() {
if (customization) return;
const religion = +this.parentNode.dataset.id;
- alertMessage.innerHTML = "Are you sure you want to remove the religion?
This action cannot be reverted";
- $("#alert").dialog({resizable: false, title: "Remove religion",
- buttons: {
- Remove: function() {
- relig.select("#religion"+religion).remove();
- relig.select("#religion-gap"+religion).remove();
- debug.select("#religionsCenter"+religion).remove();
+ const message = 'Are you sure you want to remove the religion?
This action cannot be reverted';
+ const onConfirm = () => {
+ relig.select('#religion' + religion).remove();
+ relig.select('#religion-gap' + religion).remove();
+ debug.select('#religionsCenter' + religion).remove();
- pack.cells.religion.forEach((r, i) => {if(r === religion) pack.cells.religion[i] = 0;});
- pack.religions[religion].removed = true;
- const origin = pack.religions[religion].origin;
- pack.religions.forEach(r => {if(r.origin === religion) r.origin = origin;});
-
- refreshReligionsEditor();
- $(this).dialog("close");
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ pack.cells.religion.forEach((r, i) => {
+ if (r === religion) pack.cells.religion[i] = 0;
+ });
+ pack.religions[religion].removed = true;
+ const origin = pack.religions[religion].origin;
+ pack.religions.forEach((r) => {
+ if (r.origin === religion) r.origin = origin;
+ });
+
+ refreshReligionsEditor();
+ };
+ confirmationDialog({title: 'Remove religion', message, confirm: 'Remove', onConfirm});
}
function drawReligionCenters() {
- debug.select("#religionCenters").remove();
- const religionCenters = debug.append("g").attr("id", "religionCenters")
- .attr("stroke-width", 1.2).attr("stroke", "#444444").style("cursor", "move");
+ debug.select('#religionCenters').remove();
+ const religionCenters = debug.append('g').attr('id', 'religionCenters').attr('stroke-width', 1.2).attr('stroke', '#444444').style('cursor', 'move');
- const data = pack.religions.filter(r => r.i && r.center && r.cells && !r.removed);
- religionCenters.selectAll("circle").data(data).enter().append("circle")
- .attr("id", d => "religionsCenter"+d.i).attr("data-id", d => d.i)
- .attr("r", 4).attr("fill", d => d.color)
- .attr("cx", d => pack.cells.p[d.center][0]).attr("cy", d => pack.cells.p[d.center][1])
- .on("mouseenter", d => {
- tip(d.name+ ". Drag to move the religion center", true);
+ const data = pack.religions.filter((r) => r.i && r.center && r.cells && !r.removed);
+ religionCenters
+ .selectAll('circle')
+ .data(data)
+ .enter()
+ .append('circle')
+ .attr('id', (d) => 'religionsCenter' + d.i)
+ .attr('data-id', (d) => d.i)
+ .attr('r', 4)
+ .attr('fill', (d) => d.color)
+ .attr('cx', (d) => pack.cells.p[d.center][0])
+ .attr('cy', (d) => pack.cells.p[d.center][1])
+ .on('mouseenter', (d) => {
+ tip(d.name + '. Drag to move the religion center', true);
religionHighlightOn(event);
- }).on("mouseleave", d => {
+ })
+ .on('mouseleave', (d) => {
tip('', true);
religionHighlightOff(event);
- }).call(d3.drag().on("start", religionCenterDrag));
+ })
+ .call(d3.drag().on('start', religionCenterDrag));
}
function religionCenterDrag() {
const el = d3.select(this);
const r = +this.dataset.id;
- d3.event.on("drag", () => {
- el.attr("cx", d3.event.x).attr("cy", d3.event.y);
+ d3.event.on('drag', () => {
+ el.attr('cx', d3.event.x).attr('cy', d3.event.y);
const cell = findCell(d3.event.x, d3.event.y);
if (pack.cells.h[cell] < 20) return; // ignore dragging on water
pack.religions[r].center = cell;
@@ -347,23 +401,29 @@ function editReligions() {
}
function toggleLegend() {
- if (legend.selectAll("*").size()) {clearLegend(); return;}; // hide legend
- const data = pack.religions.filter(r => r.i && !r.removed && r.area).sort((a, b) => b.area - a.area).map(r => [r.i, r.color, r.name]);
- drawLegend("Religions", data);
+ if (legend.selectAll('*').size()) {
+ clearLegend();
+ return;
+ } // hide legend
+ const data = pack.religions
+ .filter((r) => r.i && !r.removed && r.area)
+ .sort((a, b) => b.area - a.area)
+ .map((r) => [r.i, r.color, r.name]);
+ drawLegend('Religions', data);
}
function togglePercentageMode() {
- if (body.dataset.type === "absolute") {
- body.dataset.type = "percentage";
+ if (body.dataset.type === 'absolute') {
+ body.dataset.type = 'percentage';
const totalArea = +religionsFooterArea.dataset.area;
const totalPopulation = +religionsFooterPopulation.dataset.population;
- body.querySelectorAll(":scope > div").forEach(function(el) {
- el.querySelector(".biomeArea").innerHTML = rn(+el.dataset.area / totalArea * 100) + "%";
- el.querySelector(".culturePopulation").innerHTML = rn(+el.dataset.population / totalPopulation * 100) + "%";
+ body.querySelectorAll(':scope > div').forEach(function (el) {
+ el.querySelector('.biomeArea').innerHTML = rn((+el.dataset.area / totalArea) * 100) + '%';
+ el.querySelector('.culturePopulation').innerHTML = rn((+el.dataset.population / totalPopulation) * 100) + '%';
});
} else {
- body.dataset.type = "absolute";
+ body.dataset.type = 'absolute';
religionsEditorAddLines();
}
}
@@ -371,12 +431,19 @@ function editReligions() {
function showHierarchy() {
// build hierarchy tree
pack.religions[0].origin = null;
- const religions = pack.religions.filter(r => !r.removed);
- if (religions.length < 3) {tip("Not enough religions to show hierarchy", false, "error"); return;}
- const root = d3.stratify().id(d => d.i).parentId(d => d.origin)(religions);
+ const religions = pack.religions.filter((r) => !r.removed);
+ if (religions.length < 3) {
+ tip('Not enough religions to show hierarchy', false, 'error');
+ return;
+ }
+ const root = d3
+ .stratify()
+ .id((d) => d.i)
+ .parentId((d) => d.origin)(religions);
const treeWidth = root.leaves().length;
const treeHeight = root.height;
- const width = treeWidth * 40, height = treeHeight * 60;
+ const width = treeWidth * 40,
+ height = treeHeight * 60;
const margin = {top: 10, right: 10, bottom: -5, left: 10};
const w = width - margin.left - margin.right;
@@ -385,110 +452,151 @@ function editReligions() {
// prepare svg
alertMessage.innerHTML = "
";
- const svg = d3.select("#alertMessage").insert("svg", "#religionInfo").attr("id", "hierarchy")
- .attr("width", width).attr("height", height).style("text-anchor", "middle");
- const graph = svg.append("g").attr("transform", `translate(10, -45)`);
- const links = graph.append("g").attr("fill", "none").attr("stroke", "#aaaaaa");
- const nodes = graph.append("g");
+ const svg = d3.select('#alertMessage').insert('svg', '#religionInfo').attr('id', 'hierarchy').attr('width', width).attr('height', height).style('text-anchor', 'middle');
+ const graph = svg.append('g').attr('transform', `translate(10, -45)`);
+ const links = graph.append('g').attr('fill', 'none').attr('stroke', '#aaaaaa');
+ const nodes = graph.append('g');
renderTree();
function renderTree() {
treeLayout(root);
- links.selectAll('path').data(root.links()).enter()
- .append('path').attr("d", d => {return "M" + d.source.x + "," + d.source.y
- + "C" + d.source.x + "," + (d.source.y * 3 + d.target.y) / 4
- + " " + d.target.x + "," + (d.source.y * 2 + d.target.y) / 3
- + " " + d.target.x + "," + d.target.y;});
+ links
+ .selectAll('path')
+ .data(root.links())
+ .enter()
+ .append('path')
+ .attr('d', (d) => {
+ return (
+ 'M' +
+ d.source.x +
+ ',' +
+ d.source.y +
+ 'C' +
+ d.source.x +
+ ',' +
+ (d.source.y * 3 + d.target.y) / 4 +
+ ' ' +
+ d.target.x +
+ ',' +
+ (d.source.y * 2 + d.target.y) / 3 +
+ ' ' +
+ d.target.x +
+ ',' +
+ d.target.y
+ );
+ });
- const node = nodes.selectAll('g').data(root.descendants()).enter()
- .append('g').attr("data-id", d => d.data.i).attr("stroke", "#333333")
- .attr("transform", d => `translate(${d.x}, ${d.y})`)
- .on("mouseenter", () => religionHighlightOn(event))
- .on("mouseleave", () => religionHighlightOff(event))
- .call(d3.drag().on("start", d => dragToReorigin(d)));
+ const node = nodes
+ .selectAll('g')
+ .data(root.descendants())
+ .enter()
+ .append('g')
+ .attr('data-id', (d) => d.data.i)
+ .attr('stroke', '#333333')
+ .attr('transform', (d) => `translate(${d.x}, ${d.y})`)
+ .on('mouseenter', () => religionHighlightOn(event))
+ .on('mouseleave', () => religionHighlightOff(event))
+ .call(d3.drag().on('start', (d) => dragToReorigin(d)));
- node.append("path").attr("d", d => {
- if (d.data.type === "Folk") return "M11.3,0A11.3,11.3,0,1,1,-11.3,0A11.3,11.3,0,1,1,11.3,0"; else // circle
- if (d.data.type === "Heresy") return "M0,-14L14,0L0,14L-14,0Z"; else // diamond
- if (d.data.type === "Cult") return "M-6.5,-11.26l13,0l6.5,11.26l-6.5,11.26l-13,0l-6.5,-11.26Z"; else // hex
- if (!d.data.i) return "M5,0A5,5,0,1,1,-5,0A5,5,0,1,1,5,0"; else // small circle
- return "M-11,-11h22v22h-22Z"; // square
- }).attr("fill", d => d.data.i ? d.data.color : "#ffffff")
- .attr("stroke-dasharray", d => d.data.cells ? "null" : "1");
+ node
+ .append('path')
+ .attr('d', (d) => {
+ if (d.data.type === 'Folk') return 'M11.3,0A11.3,11.3,0,1,1,-11.3,0A11.3,11.3,0,1,1,11.3,0';
+ // circle
+ else if (d.data.type === 'Heresy') return 'M0,-14L14,0L0,14L-14,0Z';
+ // diamond
+ else if (d.data.type === 'Cult') return 'M-6.5,-11.26l13,0l6.5,11.26l-6.5,11.26l-13,0l-6.5,-11.26Z';
+ // hex
+ else if (!d.data.i) return 'M5,0A5,5,0,1,1,-5,0A5,5,0,1,1,5,0';
+ // small circle
+ else return 'M-11,-11h22v22h-22Z'; // square
+ })
+ .attr('fill', (d) => (d.data.i ? d.data.color : '#ffffff'))
+ .attr('stroke-dasharray', (d) => (d.data.cells ? 'null' : '1'));
- node.append("text").attr("dy", ".35em").text(d => d.data.i ? d.data.code : '');
+ node
+ .append('text')
+ .attr('dy', '.35em')
+ .text((d) => (d.data.i ? d.data.code : ''));
}
- $("#alert").dialog({
- title: "Religions tree", width: fitContent(), resizable: false,
- position: {my: "left center", at: "left+10 center", of: "svg"}, buttons: {},
- close: () => {alertMessage.innerHTML = "";}
+ $('#alert').dialog({
+ title: 'Religions tree',
+ width: fitContent(),
+ resizable: false,
+ position: {my: 'left center', at: 'left+10 center', of: 'svg'},
+ buttons: {},
+ close: () => {
+ alertMessage.innerHTML = '';
+ }
});
function dragToReorigin(d) {
- if (isCtrlClick(d3.event.sourceEvent)) {changeCode(d); return;}
+ if (isCtrlClick(d3.event.sourceEvent)) {
+ changeCode(d);
+ return;
+ }
- const originLine = graph.append("path")
- .attr("class", "dragLine").attr("d", `M${d.x},${d.y}L${d.x},${d.y}`);
+ const originLine = graph.append('path').attr('class', 'dragLine').attr('d', `M${d.x},${d.y}L${d.x},${d.y}`);
- d3.event.on("drag", () => {
- originLine.attr("d", `M${d.x},${d.y}L${d3.event.x},${d3.event.y}`)
+ d3.event.on('drag', () => {
+ originLine.attr('d', `M${d.x},${d.y}L${d3.event.x},${d3.event.y}`);
});
- d3.event.on("end", () => {
+ d3.event.on('end', () => {
originLine.remove();
- const selected = graph.select("path.selected");
+ const selected = graph.select('path.selected');
if (!selected.size()) return;
const religion = d.data.i;
const oldOrigin = d.data.origin;
let newOrigin = selected.datum().data.i;
if (newOrigin == oldOrigin) return; // already a child of the selected node
if (newOrigin == religion) newOrigin = 0; // move to top
- if (newOrigin && d.descendants().some(node => node.id == newOrigin)) return; // cannot be a child of its own child
+ if (newOrigin && d.descendants().some((node) => node.id == newOrigin)) return; // cannot be a child of its own child
pack.religions[religion].origin = d.data.origin = newOrigin; // change data
- showHierarchy() // update hierarchy
+ showHierarchy(); // update hierarchy
});
}
function changeCode(d) {
- prompt(`Please provide an abbreviation for ${d.data.name}`, {default:d.data.code}, v => {
+ prompt(`Please provide an abbreviation for ${d.data.name}`, {default: d.data.code}, (v) => {
pack.religions[d.data.i].code = v;
- nodes.select("g[data-id='"+d.data.i+"']").select("text").text(v);
+ nodes
+ .select("g[data-id='" + d.data.i + "']")
+ .select('text')
+ .text(v);
});
}
}
function toggleExtinct() {
- body.dataset.extinct = body.dataset.extinct !== "show" ? "show" : "hide";
+ body.dataset.extinct = body.dataset.extinct !== 'show' ? 'show' : 'hide';
religionsEditorAddLines();
}
function enterReligionsManualAssignent() {
- if (!layerIsOn("toggleReligions")) toggleReligions();
+ if (!layerIsOn('toggleReligions')) toggleReligions();
customization = 7;
- relig.append("g").attr("id", "temp");
- document.querySelectorAll("#religionsBottom > button").forEach(el => el.style.display = "none");
- document.getElementById("religionsManuallyButtons").style.display = "inline-block";
- debug.select("#religionCenters").style("display", "none");
+ relig.append('g').attr('id', 'temp');
+ document.querySelectorAll('#religionsBottom > button').forEach((el) => (el.style.display = 'none'));
+ document.getElementById('religionsManuallyButtons').style.display = 'inline-block';
+ debug.select('#religionCenters').style('display', 'none');
- religionsEditor.querySelectorAll(".hide").forEach(el => el.classList.add("hidden"));
- religionsFooter.style.display = "none";
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "none");
- $("#religionsEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
+ religionsEditor.querySelectorAll('.hide').forEach((el) => el.classList.add('hidden'));
+ religionsFooter.style.display = 'none';
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'none'));
+ $('#religionsEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg'}});
- tip("Click on religion to select, drag the circle to change religion", true);
- viewbox.style("cursor", "crosshair")
- .on("click", selectReligionOnMapClick)
- .call(d3.drag().on("start", dragReligionBrush))
- .on("touchmove mousemove", moveReligionBrush);
+ tip('Click on religion to select, drag the circle to change religion', true);
+ viewbox.style('cursor', 'crosshair').on('click', selectReligionOnMapClick).call(d3.drag().on('start', dragReligionBrush)).on('touchmove mousemove', moveReligionBrush);
- body.querySelector("div").classList.add("selected");
+ body.querySelector('div').classList.add('selected');
}
function selectReligionOnLineClick(i) {
if (customization !== 7) return;
- body.querySelector("div.selected").classList.remove("selected");
- this.classList.add("selected");
+ body.querySelector('div.selected').classList.remove('selected');
+ this.classList.add('selected');
}
function selectReligionOnMapClick() {
@@ -496,21 +604,21 @@ function editReligions() {
const i = findCell(point[0], point[1]);
if (pack.cells.h[i] < 20) return;
- const assigned = relig.select("#temp").select("polygon[data-cell='"+i+"']");
- const religion = assigned.size() ? +assigned.attr("data-religion") : pack.cells.religion[i];
+ const assigned = relig.select('#temp').select("polygon[data-cell='" + i + "']");
+ const religion = assigned.size() ? +assigned.attr('data-religion') : pack.cells.religion[i];
- body.querySelector("div.selected").classList.remove("selected");
- body.querySelector("div[data-id='"+religion+"']").classList.add("selected");
+ body.querySelector('div.selected').classList.remove('selected');
+ body.querySelector("div[data-id='" + religion + "']").classList.add('selected');
}
-
+
function dragReligionBrush() {
const r = +religionsManuallyBrushNumber.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);
-
+
const found = r > 5 ? findAll(p[0], p[1], r) : [findCell(p[0], p[1], r)];
const selection = found.filter(isLand);
if (selection) changeReligionForSelection(selection);
@@ -519,19 +627,19 @@ function editReligions() {
// change religion within selection
function changeReligionForSelection(selection) {
- const temp = relig.select("#temp");
- const selected = body.querySelector("div.selected");
+ const temp = relig.select('#temp');
+ const selected = body.querySelector('div.selected');
const r = +selected.dataset.id; // religionNew
- const color = pack.religions[r].color || "#ffffff";
+ const color = pack.religions[r].color || '#ffffff';
- selection.forEach(function(i) {
- const exists = temp.select("polygon[data-cell='"+i+"']");
- const religionOld = exists.size() ? +exists.attr("data-religion") : pack.cells.religion[i];
+ selection.forEach(function (i) {
+ const exists = temp.select("polygon[data-cell='" + i + "']");
+ const religionOld = exists.size() ? +exists.attr('data-religion') : pack.cells.religion[i];
if (r === religionOld) return;
// change of append new element
- if (exists.size()) exists.attr("data-religion", r).attr("fill", color);
- else temp.append("polygon").attr("data-cell", i).attr("data-religion", r).attr("points", getPackPolygon(i)).attr("fill", color);
+ if (exists.size()) exists.attr('data-religion', r).attr('fill', color);
+ else temp.append('polygon').attr('data-cell', i).attr('data-religion', r).attr('points', getPackPolygon(i)).attr('fill', color);
});
}
@@ -543,8 +651,8 @@ function editReligions() {
}
function applyReligionsManualAssignent() {
- const changed = relig.select("#temp").selectAll("polygon");
- changed.each(function() {
+ const changed = relig.select('#temp').selectAll('polygon');
+ changed.each(function () {
const i = +this.dataset.cell;
const r = +this.dataset.religion;
pack.cells.religion[i] = r;
@@ -557,49 +665,58 @@ function editReligions() {
}
exitReligionsManualAssignment();
}
-
+
function exitReligionsManualAssignment(close) {
customization = 0;
- relig.select("#temp").remove();
+ relig.select('#temp').remove();
removeCircle();
- document.querySelectorAll("#religionsBottom > button").forEach(el => el.style.display = "inline-block");
- document.getElementById("religionsManuallyButtons").style.display = "none";
+ document.querySelectorAll('#religionsBottom > button').forEach((el) => (el.style.display = 'inline-block'));
+ document.getElementById('religionsManuallyButtons').style.display = 'none';
- religionsEditor.querySelectorAll(".hide").forEach(el => el.classList.remove("hidden"));
- religionsFooter.style.display = "block";
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "all");
- if(!close) $("#religionsEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
+ religionsEditor.querySelectorAll('.hide').forEach((el) => el.classList.remove('hidden'));
+ religionsFooter.style.display = 'block';
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'all'));
+ if (!close) $('#religionsEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg'}});
- debug.select("#religionCenters").style("display", null);
+ debug.select('#religionCenters').style('display', null);
restoreDefaultEvents();
clearMainTip();
- 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 enterAddReligionMode() {
- if (this.classList.contains("pressed")) {exitAddReligionMode(); return;};
+ if (this.classList.contains('pressed')) {
+ exitAddReligionMode();
+ return;
+ }
customization = 8;
- this.classList.add("pressed");
- tip("Click on the map to add a new religion", true);
- viewbox.style("cursor", "crosshair").on("click", addReligion);
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "none");
+ this.classList.add('pressed');
+ tip('Click on the map to add a new religion', true);
+ viewbox.style('cursor', 'crosshair').on('click', addReligion);
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'none'));
}
function exitAddReligionMode() {
customization = 0;
restoreDefaultEvents();
clearMainTip();
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "all");
- if (religionsAdd.classList.contains("pressed")) religionsAdd.classList.remove("pressed");
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'all'));
+ if (religionsAdd.classList.contains('pressed')) religionsAdd.classList.remove('pressed');
}
function addReligion() {
const point = d3.mouse(this);
const center = findCell(point[0], point[1]);
- if (pack.cells.h[center] < 20) {tip("You cannot place religion center into the water. Please click on a land cell", false, "error"); return;}
- const occupied = pack.religions.some(r => !r.removed && r.center === center);
- if (occupied) {tip("This cell is already a religion center. Please select a different cell", false, "error"); return;}
+ if (pack.cells.h[center] < 20) {
+ tip('You cannot place religion center into the water. Please click on a land cell', false, 'error');
+ return;
+ }
+ const occupied = pack.religions.some((r) => !r.removed && r.center === center);
+ if (occupied) {
+ tip('This cell is already a religion center. Please select a different cell', false, 'error');
+ return;
+ }
if (d3.event.shiftKey === false) exitAddReligionMode();
Religions.add(center);
@@ -610,28 +727,27 @@ function editReligions() {
}
function downloadReligionsData() {
- const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value;
- let data = "Id,Religion,Color,Type,Form,Deity,Area "+unit+",Believers\n"; // headers
+ const unit = areaUnit.value === 'square' ? distanceUnitInput.value + '2' : areaUnit.value;
+ let data = 'Id,Religion,Color,Type,Form,Deity,Area ' + unit + ',Believers\n'; // headers
- body.querySelectorAll(":scope > div").forEach(function(el) {
- data += el.dataset.id + ",";
- data += el.dataset.name + ",";
- data += el.dataset.color + ",";
- data += el.dataset.type + ",";
- data += el.dataset.form + ",";
- data += el.dataset.deity.replace(",", " -") + ",";
- data += el.dataset.area + ",";
- data += el.dataset.population + "\n";
+ body.querySelectorAll(':scope > div').forEach(function (el) {
+ data += el.dataset.id + ',';
+ data += el.dataset.name + ',';
+ data += el.dataset.color + ',';
+ data += el.dataset.type + ',';
+ data += el.dataset.form + ',';
+ data += el.dataset.deity.replace(',', ' -') + ',';
+ data += el.dataset.area + ',';
+ data += el.dataset.population + '\n';
});
- const name = getFileName("Religions") + ".csv";
+ const name = getFileName('Religions') + '.csv';
downloadFile(data, name);
}
-
+
function closeReligionsEditor() {
- debug.select("#religionCenters").remove();
- exitReligionsManualAssignment("close");
+ debug.select('#religionCenters').remove();
+ exitReligionsManualAssignment('close');
exitAddReligionMode();
}
-
-}
\ No newline at end of file
+}
diff --git a/modules/ui/resources-editor.js b/modules/ui/resources-editor.js
index 36b8ea8c..3048856a 100644
--- a/modules/ui/resources-editor.js
+++ b/modules/ui/resources-editor.js
@@ -321,8 +321,7 @@ function editResources() {
function regenerateCurrentResources() {
const message = 'Are you sure you want to regenerate resources?
This action cannot be reverted';
- const onConfirm = () => regenerateResources();
- confirmationDialog({title: 'Regenerate resources', message, confirm: 'Regenerate', onConfirm});
+ confirmationDialog({title: 'Regenerate resources', message, confirm: 'Regenerate', onConfirm: regenerateResources});
}
function resourcesRestoreDefaults() {
diff --git a/modules/ui/rivers-editor.js b/modules/ui/rivers-editor.js
index bc8181ee..5eb1de5d 100644
--- a/modules/ui/rivers-editor.js
+++ b/modules/ui/rivers-editor.js
@@ -1,20 +1,21 @@
-"use strict";
+'use strict';
function editRiver(id) {
if (customization) return;
- if (elSelected && d3.event && d3.event.target.id === elSelected.attr("id")) return;
- closeDialogs(".stable");
- if (!layerIsOn("toggleRivers")) toggleRivers();
+ if (elSelected && d3.event && d3.event.target.id === elSelected.attr('id')) return;
+ closeDialogs('.stable');
+ if (!layerIsOn('toggleRivers')) toggleRivers();
const node = id ? document.getElementById(id) : d3.event.target;
- elSelected = d3.select(node).on("click", addInterimControlPoint);
- viewbox.on("touchmove mousemove", showEditorTips);
- debug.append("g").attr("id", "controlPoints").attr("transform", elSelected.attr("transform"));
+ elSelected = d3.select(node).on('click', addInterimControlPoint);
+ viewbox.on('touchmove mousemove', showEditorTips);
+ debug.append('g').attr('id', 'controlPoints').attr('transform', elSelected.attr('transform'));
updateRiverData();
drawControlPoints(node);
- $("#riverEditor").dialog({
- title: "Edit River", resizable: false,
- position: {my: "center top+80", at: "top", of: node, collision: "fit"},
+ $('#riverEditor').dialog({
+ title: 'Edit River',
+ resizable: false,
+ position: {my: 'center top+80', at: 'top', of: node, collision: 'fit'},
close: closeRiverEditor
});
@@ -22,64 +23,64 @@ function editRiver(id) {
modules.editRiver = true;
// add listeners
- document.getElementById("riverName").addEventListener("input", changeName);
- document.getElementById("riverType").addEventListener("input", changeType);
- document.getElementById("riverNameCulture").addEventListener("click", generateNameCulture);
- document.getElementById("riverNameRandom").addEventListener("click", generateNameRandom);
- document.getElementById("riverMainstem").addEventListener("change", changeParent);
+ document.getElementById('riverName').addEventListener('input', changeName);
+ document.getElementById('riverType').addEventListener('input', changeType);
+ document.getElementById('riverNameCulture').addEventListener('click', generateNameCulture);
+ document.getElementById('riverNameRandom').addEventListener('click', generateNameRandom);
+ document.getElementById('riverMainstem').addEventListener('change', changeParent);
- document.getElementById("riverSourceWidth").addEventListener("input", changeSourceWidth);
- document.getElementById("riverWidthFactor").addEventListener("input", changeWidthFactor);
+ document.getElementById('riverSourceWidth').addEventListener('input', changeSourceWidth);
+ document.getElementById('riverWidthFactor').addEventListener('input', changeWidthFactor);
- document.getElementById("riverNew").addEventListener("click", toggleRiverCreationMode);
- document.getElementById("riverEditStyle").addEventListener("click", () => editStyle("rivers"));
- document.getElementById("riverElevationProfile").addEventListener("click", showElevationProfile);
- document.getElementById("riverLegend").addEventListener("click", editRiverLegend);
- document.getElementById("riverRemove").addEventListener("click", removeRiver);
+ document.getElementById('riverNew').addEventListener('click', toggleRiverCreationMode);
+ document.getElementById('riverEditStyle').addEventListener('click', () => editStyle('rivers'));
+ document.getElementById('riverElevationProfile').addEventListener('click', showElevationProfile);
+ document.getElementById('riverLegend').addEventListener('click', editRiverLegend);
+ document.getElementById('riverRemove').addEventListener('click', removeRiver);
function showEditorTips() {
showMainTip();
- if (d3.event.target.parentNode.id === elSelected.attr("id")) tip("Drag to move, click to add a control point"); else
- if (d3.event.target.parentNode.id === "controlPoints") tip("Drag to move, click to delete the control point");
+ if (d3.event.target.parentNode.id === elSelected.attr('id')) tip('Drag to move, click to add a control point');
+ else if (d3.event.target.parentNode.id === 'controlPoints') tip('Drag to move, click to delete the control point');
}
function getRiver() {
- const riverId = +elSelected.attr("id").slice(5);
- const river = pack.rivers.find(r => r.i === riverId);
+ const riverId = +elSelected.attr('id').slice(5);
+ const river = pack.rivers.find((r) => r.i === riverId);
return river;
}
function updateRiverData() {
const r = getRiver();
- document.getElementById("riverName").value = r.name;
- document.getElementById("riverType").value = r.type;
+ document.getElementById('riverName').value = r.name;
+ document.getElementById('riverType').value = r.type;
- const parentSelect = document.getElementById("riverMainstem");
+ const parentSelect = document.getElementById('riverMainstem');
parentSelect.options.length = 0;
const parent = r.parent || r.i;
- const sortedRivers = pack.rivers.slice().sort((a, b) => a.name > b.name ? 1 : -1);
- sortedRivers.forEach(river => {
+ const sortedRivers = pack.rivers.slice().sort((a, b) => (a.name > b.name ? 1 : -1));
+ sortedRivers.forEach((river) => {
const opt = new Option(river.name, river.i, false, river.i === parent);
parentSelect.options.add(opt);
});
- document.getElementById("riverBasin").value = pack.rivers.find(river => river.i === r.basin).name;
+ document.getElementById('riverBasin').value = pack.rivers.find((river) => river.i === r.basin).name;
- document.getElementById("riverDischarge").value = r.discharge + " m³/s";
+ document.getElementById('riverDischarge').value = r.discharge + ' m³/s';
r.length = elSelected.node().getTotalLength() / 2;
- const length = rn(r.length * distanceScaleInput.value) + " " + distanceUnitInput.value;
- document.getElementById("riverLength").value = length;
- const width = rn(r.width * distanceScaleInput.value, 3) + " " + distanceUnitInput.value;
- document.getElementById("riverWidth").value = width;
+ const length = rn(r.length * distanceScaleInput.value) + ' ' + distanceUnitInput.value;
+ document.getElementById('riverLength').value = length;
+ const width = rn(r.width * distanceScaleInput.value, 3) + ' ' + distanceUnitInput.value;
+ document.getElementById('riverWidth').value = width;
- document.getElementById("riverSourceWidth").value = r.sourceWidth;
- document.getElementById("riverWidthFactor").value = r.widthFactor;
+ document.getElementById('riverSourceWidth').value = r.sourceWidth;
+ document.getElementById('riverWidthFactor').value = r.widthFactor;
}
function drawControlPoints(node) {
const length = getRiver().length;
const segments = Math.ceil(length / 4);
- const increment = rn(length / segments * 1e5);
+ const increment = rn((length / segments) * 1e5);
for (let i = increment * segments, c = i; i >= 0; i -= increment, c += increment) {
const p1 = node.getPointAtLength(i / 1e5);
const p2 = node.getPointAtLength(c / 1e5);
@@ -88,37 +89,39 @@ function editRiver(id) {
}
function addControlPoint(point, before = null) {
- debug.select("#controlPoints").insert("circle", before)
- .attr("cx", point[0]).attr("cy", point[1]).attr("r", .6)
- .call(d3.drag().on("drag", dragControlPoint))
- .on("click", clickControlPoint);
+ debug.select('#controlPoints').insert('circle', before).attr('cx', point[0]).attr('cy', point[1]).attr('r', 0.6).call(d3.drag().on('drag', dragControlPoint)).on('click', clickControlPoint);
}
function dragControlPoint() {
- this.setAttribute("cx", d3.event.x);
- this.setAttribute("cy", d3.event.y);
+ this.setAttribute('cx', d3.event.x);
+ this.setAttribute('cy', d3.event.y);
redrawRiver();
}
function redrawRiver() {
const points = [];
- debug.select("#controlPoints").selectAll("circle").each(function() {
- points.push([+this.getAttribute("cx"), +this.getAttribute("cy")]);
- });
+ debug
+ .select('#controlPoints')
+ .selectAll('circle')
+ .each(function () {
+ points.push([+this.getAttribute('cx'), +this.getAttribute('cy')]);
+ });
if (points.length < 2) return;
if (points.length === 2) {
- const p0 = points[0], p1 = points[1];
+ const p0 = points[0],
+ p1 = points[1];
const angle = Math.atan2(p1[1] - p0[1], p1[0] - p0[0]);
- const sin = Math.sin(angle), cos = Math.cos(angle);
- elSelected.attr("d", `M${p0[0]},${p0[1]} L${p1[0]},${p1[1]} l${-sin/2},${cos/2} Z`);
+ const sin = Math.sin(angle),
+ cos = Math.cos(angle);
+ elSelected.attr('d', `M${p0[0]},${p0[1]} L${p1[0]},${p1[1]} l${-sin / 2},${cos / 2} Z`);
return;
}
- const widthFactor = +document.getElementById("riverWidthFactor").value;
- const sourceWidth = +document.getElementById("riverSourceWidth").value;
+ const widthFactor = +document.getElementById('riverWidthFactor').value;
+ const sourceWidth = +document.getElementById('riverSourceWidth').value;
const [path, length, offset] = Rivers.getPath(points, widthFactor, sourceWidth);
- elSelected.attr("d", path);
+ elSelected.attr('d', path);
const r = getRiver();
if (r) {
@@ -137,10 +140,10 @@ function editRiver(id) {
function addInterimControlPoint() {
const point = d3.mouse(this);
- const controls = document.getElementById("controlPoints").querySelectorAll("circle");
- const points = Array.from(controls).map(circle => [+circle.getAttribute("cx"), +circle.getAttribute("cy")]);
+ const controls = document.getElementById('controlPoints').querySelectorAll('circle');
+ const points = Array.from(controls).map((circle) => [+circle.getAttribute('cx'), +circle.getAttribute('cy')]);
const index = getSegmentId(points, point, 2);
- addControlPoint(point, ":nth-child(" + (index+1) + ")");
+ addControlPoint(point, ':nth-child(' + (index + 1) + ')');
redrawRiver();
}
@@ -160,14 +163,14 @@ function editRiver(id) {
function generateNameRandom() {
const r = getRiver();
- if (r) r.name = riverName.value = Names.getBase(rand(nameBases.length-1));
+ if (r) r.name = riverName.value = Names.getBase(rand(nameBases.length - 1));
}
function changeParent() {
const r = getRiver();
r.parent = +this.value;
- r.basin = pack.rivers.find(river => river.i === r.parent).basin;
- document.getElementById("riverBasin").value = pack.rivers.find(river => river.i === r.basin).name;
+ r.basin = pack.rivers.find((river) => river.i === r.parent).basin;
+ document.getElementById('riverBasin').value = pack.rivers.find((river) => river.i === r.basin).name;
}
function changeSourceWidth() {
@@ -186,26 +189,26 @@ function editRiver(id) {
}
function editRiverLegend() {
- const id = elSelected.attr("id");
+ const id = elSelected.attr('id');
const river = getRiver();
- editNotes(id, river.name + " " + river.type);
+ editNotes(id, river.name + ' ' + river.type);
}
function toggleRiverCreationMode() {
- if (document.getElementById("riverNew").classList.contains("pressed")) exitRiverCreationMode();
+ if (document.getElementById('riverNew').classList.contains('pressed')) exitRiverCreationMode();
else {
- document.getElementById("riverNew").classList.add("pressed");
- tip("Click on map to add control points", true, "warn");
- viewbox.on("click", addPointOnClick).style("cursor", "crosshair");
- elSelected.on("click", null);
+ document.getElementById('riverNew').classList.add('pressed');
+ tip('Click on map to add control points', true, 'warn');
+ viewbox.on('click', addPointOnClick).style('cursor', 'crosshair');
+ elSelected.on('click', null);
}
}
function addPointOnClick() {
- if (!elSelected.attr("data-new")) {
- debug.select("#controlPoints").selectAll("circle").remove();
- const id = getNextId("river");
- elSelected = d3.select(elSelected.node().parentNode).append("path").attr("id", id).attr("data-new", 1);
+ if (!elSelected.attr('data-new')) {
+ debug.select('#controlPoints').selectAll('circle').remove();
+ const id = getNextId('river');
+ elSelected = d3.select(elSelected.node().parentNode).append('path').attr('id', id).attr('data-new', 1);
}
// add control point
@@ -215,20 +218,22 @@ function editRiver(id) {
}
function exitRiverCreationMode() {
- riverNew.classList.remove("pressed");
+ riverNew.classList.remove('pressed');
clearMainTip();
- viewbox.on("click", clicked).style("cursor", "default");
- elSelected.on("click", addInterimControlPoint);
+ viewbox.on('click', clicked).style('cursor', 'default');
+ elSelected.on('click', addInterimControlPoint);
- if (!elSelected.attr("data-new")) return; // no need to create a new river
- elSelected.attr("data-new", null);
+ if (!elSelected.attr('data-new')) return; // no need to create a new river
+ elSelected.attr('data-new', null);
// add a river
- const r = +elSelected.attr("id").slice(5);
- const node = elSelected.node(), length = node.getTotalLength() / 2;
+ const r = +elSelected.attr('id').slice(5);
+ const node = elSelected.node(),
+ length = node.getTotalLength() / 2;
const cells = [];
- const segments = Math.ceil(length / 4), increment = rn(length / segments * 1e5);
+ const segments = Math.ceil(length / 4),
+ increment = rn((length / segments) * 1e5);
for (let i = increment * segments, c = i; i >= 0; i -= increment, c += increment) {
const p = node.getPointAtLength(i / 1e5);
const cell = findCell(p.x, p.y);
@@ -236,38 +241,34 @@ function editRiver(id) {
cells.push(cell);
}
- const source = cells[0], mouth = last(cells);
+ const source = cells[0],
+ mouth = last(cells);
const name = Rivers.getName(mouth);
- const smallLength = pack.rivers.map(r => r.length||0).sort((a,b) => a-b)[Math.ceil(pack.rivers.length * .15)];
- const type = length < smallLength ? rw({"Creek":9, "River":3, "Brook":3, "Stream":1}) : "River";
+ const smallLength = pack.rivers.map((r) => r.length || 0).sort((a, b) => a - b)[Math.ceil(pack.rivers.length * 0.15)];
+ const type = length < smallLength ? rw({Creek: 9, River: 3, Brook: 3, Stream: 1}) : 'River';
const discharge = rn(cells.length * 20 * Math.random());
- const widthFactor = +document.getElementById("riverWidthFactor").value;
- const sourceWidth = +document.getElementById("riverSourceWidth").value;
+ const widthFactor = +document.getElementById('riverWidthFactor').value;
+ const sourceWidth = +document.getElementById('riverSourceWidth').value;
- pack.rivers.push({i:r, source, mouth, discharge, length, width: sourceWidth, widthFactor, sourceWidth, parent:0, name, type, basin:r});
+ pack.rivers.push({i: r, source, mouth, discharge, length, width: sourceWidth, widthFactor, sourceWidth, parent: 0, name, type, basin: r});
}
function removeRiver() {
- alertMessage.innerHTML = "Are you sure you want to remove the river? All tributaries will be auto-removed";
- $("#alert").dialog({resizable: false, width: "22em", title: "Remove river",
- buttons: {
- Remove: function() {
- $(this).dialog("close");
- const river = +elSelected.attr("id").slice(5);
- Rivers.remove(river);
- elSelected.remove(); // keep if river if missed in pack.rivers
- $("#riverEditor").dialog("close");
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ const message = 'Are you sure you want to remove the river?
All tributaries will be auto-removed';
+ const onConfirm = () => {
+ const river = +elSelected.attr('id').slice(5);
+ Rivers.remove(river);
+ elSelected.remove(); // if river if missed in pack.rivers
+ $('#riverEditor').dialog('close');
+ };
+ confirmationDialog({title: 'Remove river', message, confirm: 'Remove', onConfirm});
}
function closeRiverEditor() {
exitRiverCreationMode();
- elSelected.on("click", null);
- debug.select("#controlPoints").remove();
+ elSelected.on('click', null);
+ debug.select('#controlPoints').remove();
unselect();
}
}
diff --git a/modules/ui/rivers-overview.js b/modules/ui/rivers-overview.js
index f96e9857..3ad9d13b 100644
--- a/modules/ui/rivers-overview.js
+++ b/modules/ui/rivers-overview.js
@@ -1,39 +1,41 @@
-"use strict";
+'use strict';
function overviewRivers() {
if (customization) return;
- closeDialogs("#riversOverview, .stable");
- if (!layerIsOn("toggleRivers")) toggleRivers();
+ closeDialogs('#riversOverview, .stable');
+ if (!layerIsOn('toggleRivers')) toggleRivers();
- const body = document.getElementById("riversBody");
+ const body = document.getElementById('riversBody');
riversOverviewAddLines();
- $("#riversOverview").dialog();
+ $('#riversOverview').dialog();
if (modules.overviewRivers) return;
modules.overviewRivers = true;
- $("#riversOverview").dialog({
- title: "Rivers Overview", resizable: false, width: fitContent(),
- position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
+ $('#riversOverview').dialog({
+ title: 'Rivers Overview',
+ resizable: false,
+ width: fitContent(),
+ position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}
});
// add listeners
- document.getElementById("riversOverviewRefresh").addEventListener("click", riversOverviewAddLines);
- document.getElementById("addNewRiver").addEventListener("click", toggleAddRiver);
- document.getElementById("riversBasinHighlight").addEventListener("click", toggleBasinsHightlight);
- document.getElementById("riversExport").addEventListener("click", downloadRiversData);
- document.getElementById("riversRemoveAll").addEventListener("click", triggerAllRiversRemove);
+ document.getElementById('riversOverviewRefresh').addEventListener('click', riversOverviewAddLines);
+ document.getElementById('addNewRiver').addEventListener('click', toggleAddRiver);
+ document.getElementById('riversBasinHighlight').addEventListener('click', toggleBasinsHightlight);
+ document.getElementById('riversExport').addEventListener('click', downloadRiversData);
+ document.getElementById('riversRemoveAll').addEventListener('click', triggerAllRiversRemove);
// add line for each river
function riversOverviewAddLines() {
- body.innerHTML = "";
- let lines = "";
+ body.innerHTML = '';
+ let lines = '';
const unit = distanceUnitInput.value;
for (const r of pack.rivers) {
- const discharge = r.discharge + " m³/s";
- const length = rn(r.length * distanceScaleInput.value) + " " + unit;
- const width = rn(r.width * distanceScaleInput.value, 3) + " " + unit;
- const basin = pack.rivers.find(river => river.i === r.basin)?.name;
+ const discharge = r.discharge + ' m³/s';
+ const length = rn(r.length * distanceScaleInput.value) + ' ' + unit;
+ const width = rn(r.width * distanceScaleInput.value, 3) + ' ' + unit;
+ const basin = pack.rivers.find((river) => river.i === r.basin)?.name;
lines += `
@@ -47,115 +49,107 @@ function overviewRivers() {
`;
}
- body.insertAdjacentHTML("beforeend", lines);
+ body.insertAdjacentHTML('beforeend', lines);
// update footer
riversFooterNumber.innerHTML = pack.rivers.length;
- const averageDischarge = rn(d3.mean(pack.rivers.map(r => r.discharge)));
- riversFooterDischarge.innerHTML = averageDischarge + " m³/s";
- const averageLength = rn(d3.mean(pack.rivers.map(r => r.length)) );
- riversFooterLength.innerHTML = (averageLength * distanceScaleInput.value) + " " + unit;
- const averageWidth = rn(d3.mean(pack.rivers.map(r => r.width)), 3);
- riversFooterWidth.innerHTML = rn(averageWidth * distanceScaleInput.value, 3) + " " + unit;
+ const averageDischarge = rn(d3.mean(pack.rivers.map((r) => r.discharge)));
+ riversFooterDischarge.innerHTML = averageDischarge + ' m³/s';
+ const averageLength = rn(d3.mean(pack.rivers.map((r) => r.length)));
+ riversFooterLength.innerHTML = averageLength * distanceScaleInput.value + ' ' + unit;
+ const averageWidth = rn(d3.mean(pack.rivers.map((r) => r.width)), 3);
+ riversFooterWidth.innerHTML = rn(averageWidth * distanceScaleInput.value, 3) + ' ' + unit;
// add listeners
- body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseenter", ev => riverHighlightOn(ev)));
- body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => riverHighlightOff(ev)));
- body.querySelectorAll("div > span.icon-dot-circled").forEach(el => el.addEventListener("click", zoomToRiver));
- body.querySelectorAll("div > span.icon-pencil").forEach(el => el.addEventListener("click", openRiverEditor));
- body.querySelectorAll("div > span.icon-trash-empty").forEach(el => el.addEventListener("click", triggerRiverRemove));
+ body.querySelectorAll('div.states').forEach((el) => el.addEventListener('mouseenter', (ev) => riverHighlightOn(ev)));
+ body.querySelectorAll('div.states').forEach((el) => el.addEventListener('mouseleave', (ev) => riverHighlightOff(ev)));
+ body.querySelectorAll('div > span.icon-dot-circled').forEach((el) => el.addEventListener('click', zoomToRiver));
+ body.querySelectorAll('div > span.icon-pencil').forEach((el) => el.addEventListener('click', openRiverEditor));
+ body.querySelectorAll('div > span.icon-trash-empty').forEach((el) => el.addEventListener('click', triggerRiverRemove));
applySorting(riversHeader);
}
function riverHighlightOn(event) {
- if (!layerIsOn("toggleRivers")) toggleRivers();
+ if (!layerIsOn('toggleRivers')) toggleRivers();
const r = +event.target.dataset.id;
- rivers.select("#river"+r).attr("stroke", "red").attr("stroke-width", 1);
+ rivers
+ .select('#river' + r)
+ .attr('stroke', 'red')
+ .attr('stroke-width', 1);
}
function riverHighlightOff(e) {
const r = +e.target.dataset.id;
- rivers.select("#river"+r).attr("stroke", null).attr("stroke-width", null);
+ rivers
+ .select('#river' + r)
+ .attr('stroke', null)
+ .attr('stroke-width', null);
}
function zoomToRiver() {
const r = +this.parentNode.dataset.id;
- const river = rivers.select("#river"+r).node();
+ const river = rivers.select('#river' + r).node();
highlightElement(river);
}
function toggleBasinsHightlight() {
- if (rivers.attr("data-basin") === "hightlighted") {
- rivers.selectAll("*").attr("fill", null);
- rivers.attr("data-basin", null);
+ if (rivers.attr('data-basin') === 'hightlighted') {
+ rivers.selectAll('*').attr('fill', null);
+ rivers.attr('data-basin', null);
} else {
- rivers.attr("data-basin", "hightlighted");
- const basins = [...new Set(pack.rivers.map(r => r.basin))];
- const colors = ["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"];
+ rivers.attr('data-basin', 'hightlighted');
+ const basins = [...new Set(pack.rivers.map((r) => r.basin))];
+ const colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'];
basins.forEach((b, i) => {
const color = colors[i % colors.length];
- pack.rivers.filter(r => r.basin === b).forEach(r => {
- rivers.select("#river"+r.i).attr("fill", color);
- });
+ pack.rivers
+ .filter((r) => r.basin === b)
+ .forEach((r) => {
+ rivers.select('#river' + r.i).attr('fill', color);
+ });
});
}
}
function downloadRiversData() {
- let data = "Id,River,Type,Discharge,Length,Width,Basin\n"; // headers
+ let data = 'Id,River,Type,Discharge,Length,Width,Basin\n'; // headers
- body.querySelectorAll(":scope > div").forEach(function(el) {
+ body.querySelectorAll(':scope > div').forEach(function (el) {
const d = el.dataset;
- const discharge = d.discharge + " m³/s"
- const length = rn(d.length * distanceScaleInput.value) + " " + distanceUnitInput.value;
- const width = rn(d.width * distanceScaleInput.value, 3) + " " + distanceUnitInput.value;
- data += [d.id, d.name, d.type, discharge, length, width, d.basin].join(",") + "\n";
+ const discharge = d.discharge + ' m³/s';
+ const length = rn(d.length * distanceScaleInput.value) + ' ' + distanceUnitInput.value;
+ const width = rn(d.width * distanceScaleInput.value, 3) + ' ' + distanceUnitInput.value;
+ data += [d.id, d.name, d.type, discharge, length, width, d.basin].join(',') + '\n';
});
- const name = getFileName("Rivers") + ".csv";
+ const name = getFileName('Rivers') + '.csv';
downloadFile(data, name);
}
function openRiverEditor() {
- editRiver("river"+this.parentNode.dataset.id);
+ editRiver('river' + this.parentNode.dataset.id);
}
function triggerRiverRemove() {
const river = +this.parentNode.dataset.id;
- alertMessage.innerHTML = `Are you sure you want to remove the river?
- All tributaries will be auto-removed`;
- $("#alert").dialog({resizable: false, width: "22em", title: "Remove river",
- buttons: {
- Remove: function() {
- Rivers.remove(river);
- riversOverviewAddLines();
- $(this).dialog("close");
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ const message = 'Are you sure you want to remove the river?
All tributaries will be auto-removed';
+ const onConfirm = () => {
+ Rivers.remove(river);
+ riversOverviewAddLines();
+ };
+ confirmationDialog({title: 'Remove river', message, confirm: 'Remove', onConfirm});
}
function triggerAllRiversRemove() {
- alertMessage.innerHTML = `Are you sure you want to remove all rivers?`;
- $("#alert").dialog({resizable: false, title: "Remove all rivers",
- buttons: {
- Remove: function() {
- $(this).dialog("close");
- removeAllRivers();
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ const message = 'Are you sure you want to remove all rivers?
This action cannot be reverted';
+ const onConfirm = () => {
+ pack.rivers = [];
+ rivers.selectAll('*').remove();
+ riversOverviewAddLines();
+ };
+ confirmationDialog({title: 'Remove all rivers', message, confirm: 'Remove', onConfirm});
}
-
- function removeAllRivers() {
- pack.rivers = [];
- rivers.selectAll("*").remove();
- riversOverviewAddLines();
- }
-
}
diff --git a/modules/ui/routes-editor.js b/modules/ui/routes-editor.js
index 0b743652..e0ccd106 100644
--- a/modules/ui/routes-editor.js
+++ b/modules/ui/routes-editor.js
@@ -1,93 +1,94 @@
-"use strict";
+'use strict';
function editRoute(onClick) {
if (customization) return;
- if (!onClick && elSelected && d3.event.target.id === elSelected.attr("id")) return;
- closeDialogs(".stable");
- if (!layerIsOn("toggleRoutes")) toggleRoutes();
+ if (!onClick && elSelected && d3.event.target.id === elSelected.attr('id')) return;
+ closeDialogs('.stable');
+ if (!layerIsOn('toggleRoutes')) toggleRoutes();
- $("#routeEditor").dialog({
- title: "Edit Route", resizable: false,
- position: {my: "center top+60", at: "top", of: d3.event, collision: "fit"},
+ $('#routeEditor').dialog({
+ title: 'Edit Route',
+ resizable: false,
+ position: {my: 'center top+60', at: 'top', of: d3.event, collision: 'fit'},
close: closeRoutesEditor
});
- debug.append("g").attr("id", "controlPoints");
+ debug.append('g').attr('id', 'controlPoints');
const node = onClick ? elSelected.node() : d3.event.target;
- elSelected = d3.select(node).on("click", addInterimControlPoint);
+ elSelected = d3.select(node).on('click', addInterimControlPoint);
drawControlPoints(node);
selectRouteGroup(node);
- viewbox.on("touchmove mousemove", showEditorTips);
+ viewbox.on('touchmove mousemove', showEditorTips);
if (onClick) toggleRouteCreationMode();
if (modules.editRoute) return;
modules.editRoute = true;
// add listeners
- document.getElementById("routeGroupsShow").addEventListener("click", showGroupSection);
- document.getElementById("routeGroup").addEventListener("change", changeRouteGroup);
- document.getElementById("routeGroupAdd").addEventListener("click", toggleNewGroupInput);
- document.getElementById("routeGroupName").addEventListener("change", createNewGroup);
- document.getElementById("routeGroupRemove").addEventListener("click", removeRouteGroup);
- document.getElementById("routeGroupsHide").addEventListener("click", hideGroupSection);
- document.getElementById("routeElevationProfile").addEventListener("click", showElevationProfile);
+ document.getElementById('routeGroupsShow').addEventListener('click', showGroupSection);
+ document.getElementById('routeGroup').addEventListener('change', changeRouteGroup);
+ document.getElementById('routeGroupAdd').addEventListener('click', toggleNewGroupInput);
+ document.getElementById('routeGroupName').addEventListener('change', createNewGroup);
+ document.getElementById('routeGroupRemove').addEventListener('click', removeRouteGroup);
+ document.getElementById('routeGroupsHide').addEventListener('click', hideGroupSection);
+ document.getElementById('routeElevationProfile').addEventListener('click', showElevationProfile);
- document.getElementById("routeEditStyle").addEventListener("click", editGroupStyle);
- document.getElementById("routeSplit").addEventListener("click", toggleRouteSplitMode);
- document.getElementById("routeLegend").addEventListener("click", editRouteLegend);
- document.getElementById("routeNew").addEventListener("click", toggleRouteCreationMode);
- document.getElementById("routeRemove").addEventListener("click", removeRoute);
+ document.getElementById('routeEditStyle').addEventListener('click', editGroupStyle);
+ document.getElementById('routeSplit').addEventListener('click', toggleRouteSplitMode);
+ document.getElementById('routeLegend').addEventListener('click', editRouteLegend);
+ document.getElementById('routeNew').addEventListener('click', toggleRouteCreationMode);
+ document.getElementById('routeRemove').addEventListener('click', removeRoute);
function showEditorTips() {
showMainTip();
- if (routeNew.classList.contains("pressed")) return;
- if (d3.event.target.id === elSelected.attr("id")) tip("Click to add a control point"); else
- if (d3.event.target.parentNode.id === "controlPoints") tip("Drag to move, click to delete the control point");
+ if (routeNew.classList.contains('pressed')) return;
+ if (d3.event.target.id === elSelected.attr('id')) tip('Click to add a control point');
+ else if (d3.event.target.parentNode.id === 'controlPoints') tip('Drag to move, click to delete the control point');
}
function drawControlPoints(node) {
const l = node.getTotalLength();
const increment = l / Math.ceil(l / 4);
- for (let i=0; i <= l; i += increment) {
+ for (let i = 0; i <= l; i += increment) {
const point = node.getPointAtLength(i);
addControlPoint([point.x, point.y]);
}
- routeLength.innerHTML = rn(l * distanceScaleInput.value) + " " + distanceUnitInput.value;
+ routeLength.innerHTML = rn(l * distanceScaleInput.value) + ' ' + distanceUnitInput.value;
}
-
+
function addControlPoint(point, before = null) {
- debug.select("#controlPoints").insert("circle", before)
- .attr("cx", point[0]).attr("cy", point[1]).attr("r", .6)
- .call(d3.drag().on("drag", dragControlPoint))
- .on("click", clickControlPoint);
+ debug.select('#controlPoints').insert('circle', before).attr('cx', point[0]).attr('cy', point[1]).attr('r', 0.6).call(d3.drag().on('drag', dragControlPoint)).on('click', clickControlPoint);
}
function addInterimControlPoint() {
const point = d3.mouse(this);
- const controls = document.getElementById("controlPoints").querySelectorAll("circle");
- const points = Array.from(controls).map(circle => [+circle.getAttribute("cx"), +circle.getAttribute("cy")]);
+ const controls = document.getElementById('controlPoints').querySelectorAll('circle');
+ const points = Array.from(controls).map((circle) => [+circle.getAttribute('cx'), +circle.getAttribute('cy')]);
const index = getSegmentId(points, point, 2);
- addControlPoint(point, ":nth-child(" + (index+1) + ")");
+ addControlPoint(point, ':nth-child(' + (index + 1) + ')');
redrawRoute();
}
-
+
function dragControlPoint() {
- this.setAttribute("cx", d3.event.x);
- this.setAttribute("cy", d3.event.y);
+ this.setAttribute('cx', d3.event.x);
+ this.setAttribute('cy', d3.event.y);
redrawRoute();
}
function redrawRoute() {
- lineGen.curve(d3.curveCatmullRom.alpha(.1));
+ lineGen.curve(d3.curveCatmullRom.alpha(0.1));
const points = [];
- debug.select("#controlPoints").selectAll("circle").each(function() {
- points.push([this.getAttribute("cx"), this.getAttribute("cy")]);
- });
+ debug
+ .select('#controlPoints')
+ .selectAll('circle')
+ .each(function () {
+ points.push([this.getAttribute('cx'), this.getAttribute('cy')]);
+ });
- elSelected.attr("d", round(lineGen(points)));
+ elSelected.attr('d', round(lineGen(points)));
const l = elSelected.node().getTotalLength();
- routeLength.innerHTML = rn(l * distanceScaleInput.value) + " " + distanceUnitInput.value;
+ routeLength.innerHTML = rn(l * distanceScaleInput.value) + ' ' + distanceUnitInput.value;
if (modules.elevation) showEPForRoute(elSelected.node());
}
@@ -98,158 +99,169 @@ function editRoute(onClick) {
}
function showGroupSection() {
- document.querySelectorAll("#routeEditor > button").forEach(el => el.style.display = "none");
- document.getElementById("routeGroupsSelection").style.display = "inline-block";
+ document.querySelectorAll('#routeEditor > button').forEach((el) => (el.style.display = 'none'));
+ document.getElementById('routeGroupsSelection').style.display = 'inline-block';
}
function hideGroupSection() {
- document.querySelectorAll("#routeEditor > button").forEach(el => el.style.display = "inline-block");
- document.getElementById("routeGroupsSelection").style.display = "none";
- document.getElementById("routeGroupName").style.display = "none";
- document.getElementById("routeGroupName").value = "";
- document.getElementById("routeGroup").style.display = "inline-block";
+ document.querySelectorAll('#routeEditor > button').forEach((el) => (el.style.display = 'inline-block'));
+ document.getElementById('routeGroupsSelection').style.display = 'none';
+ document.getElementById('routeGroupName').style.display = 'none';
+ document.getElementById('routeGroupName').value = '';
+ document.getElementById('routeGroup').style.display = 'inline-block';
}
function selectRouteGroup(node) {
const group = node.parentNode.id;
- const select = document.getElementById("routeGroup");
+ const select = document.getElementById('routeGroup');
select.options.length = 0; // remove all options
- routes.selectAll("g").each(function() {
+ routes.selectAll('g').each(function () {
select.options.add(new Option(this.id, this.id, false, this.id === group));
});
}
-
+
function changeRouteGroup() {
document.getElementById(this.value).appendChild(elSelected.node());
}
-
+
function toggleNewGroupInput() {
- if (routeGroupName.style.display === "none") {
- routeGroupName.style.display = "inline-block";
+ if (routeGroupName.style.display === 'none') {
+ routeGroupName.style.display = 'inline-block';
routeGroupName.focus();
- routeGroup.style.display = "none";
+ routeGroup.style.display = 'none';
} else {
- routeGroupName.style.display = "none";
- routeGroup.style.display = "inline-block";
- }
+ routeGroupName.style.display = 'none';
+ routeGroup.style.display = 'inline-block';
+ }
}
-
+
function createNewGroup() {
- if (!this.value) {tip("Please provide a valid group name"); return;}
- const group = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, "");
+ if (!this.value) {
+ tip('Please provide a valid group name');
+ return;
+ }
+ const group = this.value
+ .toLowerCase()
+ .replace(/ /g, '_')
+ .replace(/[^\w\s]/gi, '');
if (document.getElementById(group)) {
- tip("Element with this id already exists. Please provide a unique name", false, "error");
+ tip('Element with this id already exists. Please provide a unique name', false, 'error');
return;
}
if (Number.isFinite(+group.charAt(0))) {
- tip("Group name should start with a letter", false, "error");
+ tip('Group name should start with a letter', false, 'error');
return;
}
// just rename if only 1 element left
const oldGroup = elSelected.node().parentNode;
- const basic = ["roads", "trails", "searoutes"].includes(oldGroup.id);
+ const basic = ['roads', 'trails', 'searoutes'].includes(oldGroup.id);
if (!basic && oldGroup.childElementCount === 1) {
- document.getElementById("routeGroup").selectedOptions[0].remove();
- document.getElementById("routeGroup").options.add(new Option(group, group, false, true));
+ document.getElementById('routeGroup').selectedOptions[0].remove();
+ document.getElementById('routeGroup').options.add(new Option(group, group, false, true));
oldGroup.id = group;
toggleNewGroupInput();
- document.getElementById("routeGroupName").value = "";
+ document.getElementById('routeGroupName').value = '';
return;
}
const newGroup = elSelected.node().parentNode.cloneNode(false);
- document.getElementById("routes").appendChild(newGroup);
+ document.getElementById('routes').appendChild(newGroup);
newGroup.id = group;
- document.getElementById("routeGroup").options.add(new Option(group, group, false, true));
+ document.getElementById('routeGroup').options.add(new Option(group, group, false, true));
document.getElementById(group).appendChild(elSelected.node());
toggleNewGroupInput();
- document.getElementById("routeGroupName").value = "";
+ document.getElementById('routeGroupName').value = '';
}
-
+
function removeRouteGroup() {
const group = elSelected.node().parentNode.id;
- const basic = ["roads", "trails", "searoutes"].includes(group);
+ const basic = ['roads', 'trails', 'searoutes'].includes(group);
const count = elSelected.node().parentNode.childElementCount;
- alertMessage.innerHTML = `Are you sure you want to remove
- ${basic ? "all elements in the group" : "the entire route group"}?
-
Routes to be removed: ${count}`;
- $("#alert").dialog({resizable: false, title: "Remove route group",
- buttons: {
- Remove: function() {
- $(this).dialog("close");
- $("#routeEditor").dialog("close");
- hideGroupSection();
- if (basic) routes.select("#"+group).selectAll("path").remove();
- else routes.select("#"+group).remove();
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+
+ const message = `Are you sure you want to remove ${basic ? 'all elements in the group' : 'the entire route group'}?
Routes to be removed: ${count}`;
+ const onConfirm = () => {
+ $('#routeEditor').dialog('close');
+ hideGroupSection();
+ if (basic)
+ routes
+ .select('#' + group)
+ .selectAll('path')
+ .remove();
+ else routes.select('#' + group).remove();
+ };
+ confirmationDialog({title: 'Remove route group', message, confirm: 'Remove', onConfirm});
}
function editGroupStyle() {
const g = elSelected.node().parentNode.id;
- editStyle("routes", g);
+ editStyle('routes', g);
}
function toggleRouteSplitMode() {
- document.getElementById("routeNew").classList.remove("pressed");
- this.classList.toggle("pressed");
+ document.getElementById('routeNew').classList.remove('pressed');
+ this.classList.toggle('pressed');
}
function clickControlPoint() {
- if (routeSplit.classList.contains("pressed")) splitRoute(this);
- else {this.remove(); redrawRoute();}
- }
-
- function splitRoute(clicked) {
- lineGen.curve(d3.curveCatmullRom.alpha(.1));
- const group = d3.select(elSelected.node().parentNode);
- routeSplit.classList.remove("pressed");
-
- const points1 = [], points2 = [];
- let points = points1;
- debug.select("#controlPoints").selectAll("circle").each(function() {
- points.push([this.getAttribute("cx"), this.getAttribute("cy")]);
- if (this === clicked) {
- points = points2;
- points.push([this.getAttribute("cx"), this.getAttribute("cy")]);
- }
+ if (routeSplit.classList.contains('pressed')) splitRoute(this);
+ else {
this.remove();
- });
+ redrawRoute();
+ }
+ }
- elSelected.attr("d", round(lineGen(points1)));
- const id = getNextId("route");
- group.append("path").attr("id", id).attr("d", lineGen(points2));
- debug.select("#controlPoints").selectAll("circle").remove();
+ function splitRoute(clicked) {
+ lineGen.curve(d3.curveCatmullRom.alpha(0.1));
+ const group = d3.select(elSelected.node().parentNode);
+ routeSplit.classList.remove('pressed');
+
+ const points1 = [],
+ points2 = [];
+ let points = points1;
+ debug
+ .select('#controlPoints')
+ .selectAll('circle')
+ .each(function () {
+ points.push([this.getAttribute('cx'), this.getAttribute('cy')]);
+ if (this === clicked) {
+ points = points2;
+ points.push([this.getAttribute('cx'), this.getAttribute('cy')]);
+ }
+ this.remove();
+ });
+
+ elSelected.attr('d', round(lineGen(points1)));
+ const id = getNextId('route');
+ group.append('path').attr('id', id).attr('d', lineGen(points2));
+ debug.select('#controlPoints').selectAll('circle').remove();
drawControlPoints(elSelected.node());
}
function toggleRouteCreationMode() {
- document.getElementById("routeSplit").classList.remove("pressed");
- document.getElementById("routeNew").classList.toggle("pressed");
- if (document.getElementById("routeNew").classList.contains("pressed")) {
- tip("Click on map to add control points", true);
- viewbox.on("click", addPointOnClick).style("cursor", "crosshair");
- elSelected.on("click", null);
+ document.getElementById('routeSplit').classList.remove('pressed');
+ document.getElementById('routeNew').classList.toggle('pressed');
+ if (document.getElementById('routeNew').classList.contains('pressed')) {
+ tip('Click on map to add control points', true);
+ viewbox.on('click', addPointOnClick).style('cursor', 'crosshair');
+ elSelected.on('click', null);
} else {
clearMainTip();
- viewbox.on("click", clicked).style("cursor", "default");
- elSelected.on("click", addInterimControlPoint).attr("data-new", null);
+ viewbox.on('click', clicked).style('cursor', 'default');
+ elSelected.on('click', addInterimControlPoint).attr('data-new', null);
}
}
function addPointOnClick() {
// create new route
- if (!elSelected.attr("data-new")) {
- debug.select("#controlPoints").selectAll("circle").remove();
+ if (!elSelected.attr('data-new')) {
+ debug.select('#controlPoints').selectAll('circle').remove();
const parent = elSelected.node().parentNode;
- const id = getNextId("route");
- elSelected = d3.select(parent).append("path").attr("id", id).attr("data-new", 1);
+ const id = getNextId('route');
+ elSelected = d3.select(parent).append('path').attr('id', id).attr('data-new', 1);
}
addControlPoint(d3.mouse(this));
@@ -257,30 +269,25 @@ function editRoute(onClick) {
}
function editRouteLegend() {
- const id = elSelected.attr("id");
+ const id = elSelected.attr('id');
editNotes(id, id);
}
function removeRoute() {
- alertMessage.innerHTML = "Are you sure you want to remove the route?";
- $("#alert").dialog({resizable: false, title: "Remove route",
- buttons: {
- Remove: function() {
- $(this).dialog("close");
- elSelected.remove();
- $("#routeEditor").dialog("close");
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ const message = 'Are you sure you want to remove the route?
This action cannot be reverted';
+ const onConfirm = () => {
+ elSelected.remove();
+ $('#routeEditor').dialog('close');
+ };
+ confirmationDialog({title: 'Remove route', message, confirm: 'Remove', onConfirm});
}
function closeRoutesEditor() {
- elSelected.attr("data-new", null).on("click", null);
+ elSelected.attr('data-new', null).on('click', null);
clearMainTip();
- routeSplit.classList.remove("pressed");
- routeNew.classList.remove("pressed");
- debug.select("#controlPoints").remove();
+ routeSplit.classList.remove('pressed');
+ routeNew.classList.remove('pressed');
+ debug.select('#controlPoints').remove();
unselect();
}
}
diff --git a/modules/ui/states-editor.js b/modules/ui/states-editor.js
index ffa86812..959028ed 100644
--- a/modules/ui/states-editor.js
+++ b/modules/ui/states-editor.js
@@ -1,63 +1,75 @@
-"use strict";
+'use strict';
function editStates() {
if (customization) return;
- closeDialogs("#statesEditor, .stable");
- if (!layerIsOn("toggleStates")) toggleStates();
- if (!layerIsOn("toggleBorders")) toggleBorders();
- if (layerIsOn("toggleCultures")) toggleCultures();
- if (layerIsOn("toggleBiomes")) toggleBiomes();
- if (layerIsOn("toggleReligions")) toggleReligions();
+ closeDialogs('#statesEditor, .stable');
+ if (!layerIsOn('toggleStates')) toggleStates();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ if (layerIsOn('toggleCultures')) toggleCultures();
+ if (layerIsOn('toggleBiomes')) toggleBiomes();
+ if (layerIsOn('toggleReligions')) toggleReligions();
- const body = document.getElementById("statesBodySection");
+ const body = document.getElementById('statesBodySection');
refreshStatesEditor();
if (modules.editStates) return;
modules.editStates = true;
- $("#statesEditor").dialog({
- title: "States Editor", resizable: false, width: fitContent(), close: closeStatesEditor,
- position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
+ $('#statesEditor').dialog({
+ title: 'States Editor',
+ resizable: false,
+ width: fitContent(),
+ close: closeStatesEditor,
+ position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}
});
// add listeners
- document.getElementById("statesEditorRefresh").addEventListener("click", refreshStatesEditor);
- document.getElementById("statesEditStyle").addEventListener("click", () => editStyle("regions"));
- document.getElementById("statesLegend").addEventListener("click", toggleLegend);
- document.getElementById("statesPercentage").addEventListener("click", togglePercentageMode);
- document.getElementById("statesChart").addEventListener("click", showStatesChart);
- document.getElementById("statesRegenerate").addEventListener("click", openRegenerationMenu);
- document.getElementById("statesRegenerateBack").addEventListener("click", exitRegenerationMenu);
- document.getElementById("statesRecalculate").addEventListener("click", () => recalculateStates(true));
- document.getElementById("statesRandomize").addEventListener("click", randomizeStatesExpansion);
- document.getElementById("statesNeutral").addEventListener("input", () => recalculateStates(false));
- document.getElementById("statesNeutralNumber").addEventListener("change", () => recalculateStates(false));
- document.getElementById("statesManually").addEventListener("click", enterStatesManualAssignent);
- document.getElementById("statesManuallyApply").addEventListener("click", applyStatesManualAssignent);
- document.getElementById("statesManuallyCancel").addEventListener("click", () => exitStatesManualAssignment());
- document.getElementById("statesAdd").addEventListener("click", enterAddStateMode);
- document.getElementById("statesExport").addEventListener("click", downloadStatesData);
+ document.getElementById('statesEditorRefresh').addEventListener('click', refreshStatesEditor);
+ document.getElementById('statesEditStyle').addEventListener('click', () => editStyle('regions'));
+ document.getElementById('statesLegend').addEventListener('click', toggleLegend);
+ document.getElementById('statesPercentage').addEventListener('click', togglePercentageMode);
+ document.getElementById('statesChart').addEventListener('click', showStatesChart);
+ document.getElementById('statesRegenerate').addEventListener('click', openRegenerationMenu);
+ document.getElementById('statesRegenerateBack').addEventListener('click', exitRegenerationMenu);
+ document.getElementById('statesRecalculate').addEventListener('click', () => recalculateStates(true));
+ document.getElementById('statesRandomize').addEventListener('click', randomizeStatesExpansion);
+ document.getElementById('statesNeutral').addEventListener('input', () => recalculateStates(false));
+ document.getElementById('statesNeutralNumber').addEventListener('change', () => recalculateStates(false));
+ document.getElementById('statesManually').addEventListener('click', enterStatesManualAssignent);
+ document.getElementById('statesManuallyApply').addEventListener('click', applyStatesManualAssignent);
+ document.getElementById('statesManuallyCancel').addEventListener('click', () => exitStatesManualAssignment());
+ document.getElementById('statesAdd').addEventListener('click', enterAddStateMode);
+ document.getElementById('statesExport').addEventListener('click', downloadStatesData);
- body.addEventListener("click", function(ev) {
- const el = ev.target, cl = el.classList, line = el.parentNode, state = +line.dataset.id;
- if (cl.contains("fillRect")) stateChangeFill(el); else
- if (cl.contains("name")) editStateName(state); else
- if (cl.contains("coaIcon")) editEmblem("state", "stateCOA"+state, pack.states[state]); else
- if (cl.contains("icon-star-empty")) stateCapitalZoomIn(state); else
- if (cl.contains("culturePopulation")) changePopulation(state); else
- if (cl.contains("icon-pin")) toggleFog(state, cl); else
- if (cl.contains("icon-trash-empty")) stateRemovePrompt(state);
+ body.addEventListener('click', function (ev) {
+ const el = ev.target,
+ cl = el.classList,
+ line = el.parentNode,
+ state = +line.dataset.id;
+ if (cl.contains('fillRect')) stateChangeFill(el);
+ else if (cl.contains('name')) editStateName(state);
+ else if (cl.contains('coaIcon')) editEmblem('state', 'stateCOA' + state, pack.states[state]);
+ else if (cl.contains('icon-star-empty')) stateCapitalZoomIn(state);
+ else if (cl.contains('culturePopulation')) changePopulation(state);
+ else if (cl.contains('icon-pin')) toggleFog(state, cl);
+ else if (cl.contains('icon-trash-empty')) stateRemovePrompt(state);
});
- body.addEventListener("input", function(ev) {
- const el = ev.target, cl = el.classList, line = el.parentNode, state = +line.dataset.id;
- if (cl.contains("stateCapital")) stateChangeCapitalName(state, line, el.value); else
- if (cl.contains("cultureType")) stateChangeType(state, line, el.value); else
- if (cl.contains("statePower")) stateChangeExpansionism(state, line, el.value);
+ body.addEventListener('input', function (ev) {
+ const el = ev.target,
+ cl = el.classList,
+ line = el.parentNode,
+ state = +line.dataset.id;
+ if (cl.contains('stateCapital')) stateChangeCapitalName(state, line, el.value);
+ else if (cl.contains('cultureType')) stateChangeType(state, line, el.value);
+ else if (cl.contains('statePower')) stateChangeExpansionism(state, line, el.value);
});
- body.addEventListener("change", function(ev) {
- const el = ev.target, cl = el.classList, line = el.parentNode, state = +line.dataset.id;
- if (cl.contains("stateCulture")) stateChangeCulture(state, line, el.value);
+ body.addEventListener('change', function (ev) {
+ const el = ev.target,
+ cl = el.classList,
+ line = el.parentNode,
+ state = +line.dataset.id;
+ if (cl.contains('stateCulture')) stateChangeCulture(state, line, el.value);
});
function refreshStatesEditor() {
@@ -67,13 +79,16 @@ function editStates() {
// add line for each state
function statesEditorAddLines() {
- const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value;
- const hidden = statesRegenerateButtons.style.display === "block" ? "" : "hidden"; // show/hide regenerate columns
- let lines = "", totalArea = 0, totalPopulation = 0, totalBurgs = 0;
+ const unit = areaUnit.value === 'square' ? ' ' + distanceUnitInput.value + '²' : ' ' + areaUnit.value;
+ const hidden = statesRegenerateButtons.style.display === 'block' ? '' : 'hidden'; // show/hide regenerate columns
+ let lines = '',
+ totalArea = 0,
+ totalPopulation = 0,
+ totalBurgs = 0;
for (const s of pack.states) {
if (s.removed) continue;
- const area = s.area * (distanceScaleInput.value ** 2);
+ const area = s.area * distanceScaleInput.value ** 2;
const rural = s.rural * populationRate.value;
const urban = s.urban * populationRate.value * urbanization.value;
const population = rn(rural + urban);
@@ -81,7 +96,7 @@ function editStates() {
totalArea += area;
totalPopulation += population;
totalBurgs += s.burgs;
- const focused = defs.select("#fog #focusState"+s.i).size();
+ const focused = defs.select('#fog #focusState' + s.i).size();
if (!s.i) {
// Neutral line
@@ -110,10 +125,12 @@ function editStates() {
}
const capital = pack.burgs[s.capital].name;
- COArenderer.trigger("stateCOA"+s.i, s.coa);
+ COArenderer.trigger('stateCOA' + s.i, s.coa);
lines += `
`;
}
body.innerHTML = lines;
// update footer
- statesFooterStates.innerHTML = pack.states.filter(s => s.i && !s.removed).length;
- statesFooterCells.innerHTML = pack.cells.h.filter(h => h >= 20).length;
+ statesFooterStates.innerHTML = pack.states.filter((s) => s.i && !s.removed).length;
+ statesFooterCells.innerHTML = pack.cells.h.filter((h) => h >= 20).length;
statesFooterBurgs.innerHTML = totalBurgs;
statesFooterArea.innerHTML = si(totalArea) + unit;
statesFooterPopulation.innerHTML = si(totalPopulation);
statesFooterArea.dataset.area = totalArea;
statesFooterPopulation.dataset.population = totalPopulation;
- body.querySelectorAll("div.states").forEach(el => {
- el.addEventListener("click", selectStateOnLineClick);
- el.addEventListener("mouseenter", ev => stateHighlightOn(ev));
- el.addEventListener("mouseleave", ev => stateHighlightOff(ev));
+ body.querySelectorAll('div.states').forEach((el) => {
+ el.addEventListener('click', selectStateOnLineClick);
+ el.addEventListener('mouseenter', (ev) => stateHighlightOn(ev));
+ el.addEventListener('mouseleave', (ev) => stateHighlightOff(ev));
});
- if (body.dataset.type === "percentage") {body.dataset.type = "absolute"; togglePercentageMode();}
+ if (body.dataset.type === 'percentage') {
+ body.dataset.type = 'absolute';
+ togglePercentageMode();
+ }
applySorting(statesHeader);
- $("#statesEditor").dialog({width: fitContent()});
+ $('#statesEditor').dialog({width: fitContent()});
}
-
+
function getCultureOptions(culture) {
- let options = "";
- pack.cultures.forEach(c => {if (!c.removed) { options += `
${c.name} ` }});
+ let options = '';
+ pack.cultures.forEach((c) => {
+ if (!c.removed) {
+ options += `
${c.name} `;
+ }
+ });
return options;
}
function getTypeOptions(type) {
- let options = "";
- const types = ["Generic", "River", "Lake", "Naval", "Nomadic", "Hunting", "Highland"];
- types.forEach(t => options += `
${t} `);
+ let options = '';
+ const types = ['Generic', 'River', 'Lake', 'Naval', 'Nomadic', 'Hunting', 'Highland'];
+ types.forEach((t) => (options += `
${t} `));
return options;
}
function stateHighlightOn(event) {
- if (!layerIsOn("toggleStates")) return;
- if (defs.select("#fog path").size()) return;
+ if (!layerIsOn('toggleStates')) return;
+ if (defs.select('#fog path').size()) return;
const state = +event.target.dataset.id;
if (customization || !state) return;
- const d = regions.select("#state"+state).attr("d");
+ const d = regions.select('#state' + state).attr('d');
- const path = debug.append("path").attr("class", "highlight").attr("d", d)
- .attr("fill", "none").attr("stroke", "red").attr("stroke-width", 1).attr("opacity", 1)
- .attr("filter", "url(#blur1)");
+ const path = debug.append('path').attr('class', 'highlight').attr('d', d).attr('fill', 'none').attr('stroke', 'red').attr('stroke-width', 1).attr('opacity', 1).attr('filter', 'url(#blur1)');
- const l = path.node().getTotalLength(), dur = (l + 5000) / 2;
- const i = d3.interpolateString("0," + l, l + "," + l);
- path.transition().duration(dur).attrTween("stroke-dasharray", function() {return t => i(t)});
+ const l = path.node().getTotalLength(),
+ dur = (l + 5000) / 2;
+ const i = d3.interpolateString('0,' + l, l + ',' + l);
+ path
+ .transition()
+ .duration(dur)
+ .attrTween('stroke-dasharray', function () {
+ return (t) => i(t);
+ });
}
function stateHighlightOff() {
- debug.selectAll(".highlight").each(function() {
- d3.select(this).transition().duration(1000).attr("opacity", 0).remove();
+ debug.selectAll('.highlight').each(function () {
+ d3.select(this).transition().duration(1000).attr('opacity', 0).remove();
});
}
function stateChangeFill(el) {
- const currentFill = el.getAttribute("fill");
+ const currentFill = el.getAttribute('fill');
const state = +el.parentNode.parentNode.dataset.id;
- const callback = function(fill) {
- el.setAttribute("fill", fill);
+ const callback = function (fill) {
+ el.setAttribute('fill', fill);
pack.states[state].color = fill;
- statesBody.select("#state"+state).attr("fill", fill);
- statesBody.select("#state-gap"+state).attr("stroke", fill);
- const halo = d3.color(fill) ? d3.color(fill).darker().hex() : "#666666";
- statesHalo.select("#state-border"+state).attr("stroke", halo);
+ statesBody.select('#state' + state).attr('fill', fill);
+ statesBody.select('#state-gap' + state).attr('stroke', fill);
+ const halo = d3.color(fill) ? d3.color(fill).darker().hex() : '#666666';
+ statesHalo.select('#state-border' + state).attr('stroke', halo);
// recolor regiments
- const solidColor = fill[0] === "#" ? fill : "#999";
+ const solidColor = fill[0] === '#' ? fill : '#999';
const darkerColor = d3.color(solidColor).darker().hex();
- armies.select("#army"+state).attr("fill", solidColor);
- armies.select("#army"+state).selectAll("g > rect:nth-of-type(2)").attr("fill", darkerColor);
- }
+ armies.select('#army' + state).attr('fill', solidColor);
+ armies
+ .select('#army' + state)
+ .selectAll('g > rect:nth-of-type(2)')
+ .attr('fill', darkerColor);
+ };
openPicker(currentFill, callback);
}
function editStateName(state) {
// reset input value and close add mode
- stateNameEditorCustomForm.value = "";
- const addModeActive = stateNameEditorCustomForm.style.display === "inline-block";
+ stateNameEditorCustomForm.value = '';
+ const addModeActive = stateNameEditorCustomForm.style.display === 'inline-block';
if (addModeActive) {
- stateNameEditorCustomForm.style.display = "none";
- stateNameEditorSelectForm.style.display = "inline-block";
+ stateNameEditorCustomForm.style.display = 'none';
+ stateNameEditorSelectForm.style.display = 'inline-block';
}
const s = pack.states[state];
- document.getElementById("stateNameEditor").dataset.state = state;
- document.getElementById("stateNameEditorShort").value = s.name || "";
+ document.getElementById('stateNameEditor').dataset.state = state;
+ document.getElementById('stateNameEditorShort').value = s.name || '';
applyOption(stateNameEditorSelectForm, s.formName);
- document.getElementById("stateNameEditorFull").value = s.fullName || "";
+ document.getElementById('stateNameEditorFull').value = s.fullName || '';
- $("#stateNameEditor").dialog({
- resizable: false, title: "Change state name", buttons: {
- Apply: function() {applyNameChange(s); $(this).dialog("close");},
- Cancel: function() {$(this).dialog("close");}
- }, position: {my: "center", at: "center", of: "svg"}
+ $('#stateNameEditor').dialog({
+ resizable: false,
+ title: 'Change state name',
+ buttons: {
+ Apply: function () {
+ applyNameChange(s);
+ $(this).dialog('close');
+ },
+ Cancel: function () {
+ $(this).dialog('close');
+ }
+ },
+ position: {my: 'center', at: 'center', of: 'svg'}
});
if (modules.editStateName) return;
modules.editStateName = true;
// add listeners
- document.getElementById("stateNameEditorShortCulture").addEventListener("click", regenerateShortNameCuture);
- document.getElementById("stateNameEditorShortRandom").addEventListener("click", regenerateShortNameRandom);
- document.getElementById("stateNameEditorAddForm").addEventListener("click", addCustomForm);
- document.getElementById("stateNameEditorCustomForm").addEventListener("change", addCustomForm);
- document.getElementById("stateNameEditorFullRegenerate").addEventListener("click", regenerateFullName);
+ document.getElementById('stateNameEditorShortCulture').addEventListener('click', regenerateShortNameCuture);
+ document.getElementById('stateNameEditorShortRandom').addEventListener('click', regenerateShortNameRandom);
+ document.getElementById('stateNameEditorAddForm').addEventListener('click', addCustomForm);
+ document.getElementById('stateNameEditorCustomForm').addEventListener('change', addCustomForm);
+ document.getElementById('stateNameEditorFullRegenerate').addEventListener('click', regenerateFullName);
function regenerateShortNameCuture() {
const state = +stateNameEditor.dataset.state;
const culture = pack.states[state].culture;
const name = Names.getState(Names.getCultureShort(culture), culture);
- document.getElementById("stateNameEditorShort").value = name;
+ document.getElementById('stateNameEditorShort').value = name;
}
function regenerateShortNameRandom() {
- const base = rand(nameBases.length-1);
+ const base = rand(nameBases.length - 1);
const name = Names.getState(Names.getBase(base), undefined, base);
- document.getElementById("stateNameEditorShort").value = name;
+ document.getElementById('stateNameEditorShort').value = name;
}
function addCustomForm() {
const value = stateNameEditorCustomForm.value;
- const addModeActive = stateNameEditorCustomForm.style.display === "inline-block";
- stateNameEditorCustomForm.style.display = addModeActive ? "none" : "inline-block";
- stateNameEditorSelectForm.style.display = addModeActive ? "inline-block" : "none";
+ const addModeActive = stateNameEditorCustomForm.style.display === 'inline-block';
+ stateNameEditorCustomForm.style.display = addModeActive ? 'none' : 'inline-block';
+ stateNameEditorSelectForm.style.display = addModeActive ? 'inline-block' : 'none';
if (value && addModeActive) applyOption(stateNameEditorSelectForm, value);
- stateNameEditorCustomForm.value = "";
+ stateNameEditorCustomForm.value = '';
}
function regenerateFullName() {
- const short = document.getElementById("stateNameEditorShort").value;
- const form = document.getElementById("stateNameEditorSelectForm").value;
- document.getElementById("stateNameEditorFull").value = getFullName();
+ const short = document.getElementById('stateNameEditorShort').value;
+ const form = document.getElementById('stateNameEditorSelectForm').value;
+ document.getElementById('stateNameEditorFull').value = getFullName();
function getFullName() {
if (!form) return short;
- if (!short && form) return "The " + form;
+ if (!short && form) return 'The ' + form;
const tick = +stateNameEditorFullRegenerate.dataset.tick;
- stateNameEditorFullRegenerate.dataset.tick = tick+1;
- return tick%2 ? getAdjective(short) + " " + form : form + " of " + short;
+ stateNameEditorFullRegenerate.dataset.tick = tick + 1;
+ return tick % 2 ? getAdjective(short) + ' ' + form : form + ' of ' + short;
}
}
function applyNameChange(s) {
- const nameInput = document.getElementById("stateNameEditorShort");
- const formSelect = document.getElementById("stateNameEditorSelectForm");
- const fullNameInput = document.getElementById("stateNameEditorFull");
+ const nameInput = document.getElementById('stateNameEditorShort');
+ const formSelect = document.getElementById('stateNameEditorSelectForm');
+ const fullNameInput = document.getElementById('stateNameEditorFull');
const nameChanged = nameInput.value !== s.name;
const formChanged = formSelect.value !== s.formName;
@@ -312,73 +353,85 @@ function editStates() {
const capital = pack.states[state].capital;
if (!capital) return;
pack.burgs[capital].name = value;
- document.querySelector("#burgLabel"+capital).textContent = value;
+ document.querySelector('#burgLabel' + capital).textContent = value;
}
function changePopulation(state) {
const s = pack.states[state];
- if (!s.cells) {tip("State does not have any cells, cannot change population", false, "error"); return;}
+ if (!s.cells) {
+ tip('State does not have any cells, cannot change population', false, 'error');
+ return;
+ }
const rural = rn(s.rural * populationRate.value);
const urban = rn(s.urban * populationRate.value * urbanization.value);
const total = rural + urban;
- const l = n => Number(n).toLocaleString();
+ const l = (n) => Number(n).toLocaleString();
alertMessage.innerHTML = `
Rural:
- Urban:
+ Urban:
Total population: ${l(total)} ⇒ ${l(total)} (100 %)
`;
- const update = function() {
+ const update = function () {
const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber;
if (isNaN(totalNew)) return;
totalPop.innerHTML = l(totalNew);
- totalPopPerc.innerHTML = rn(totalNew / total * 100);
- }
+ totalPopPerc.innerHTML = rn((totalNew / total) * 100);
+ };
ruralPop.oninput = () => update();
urbanPop.oninput = () => update();
- $("#alert").dialog({
- resizable: false, title: "Change state population", width: "24em", buttons: {
- Apply: function() {applyPopulationChange(); $(this).dialog("close");},
- Cancel: function() {$(this).dialog("close");}
- }, position: {my: "center", at: "center", of: "svg"}
+ $('#alert').dialog({
+ resizable: false,
+ title: 'Change state population',
+ width: '24em',
+ buttons: {
+ Apply: function () {
+ applyPopulationChange();
+ $(this).dialog('close');
+ },
+ Cancel: function () {
+ $(this).dialog('close');
+ }
+ },
+ position: {my: 'center', at: 'center', of: 'svg'}
});
function applyPopulationChange() {
const ruralChange = ruralPop.value / rural;
if (isFinite(ruralChange) && ruralChange !== 1) {
- const cells = pack.cells.i.filter(i => pack.cells.state[i] === state);
- cells.forEach(i => pack.cells.pop[i] *= ruralChange);
+ const cells = pack.cells.i.filter((i) => pack.cells.state[i] === state);
+ cells.forEach((i) => (pack.cells.pop[i] *= ruralChange));
}
if (!isFinite(ruralChange) && +ruralPop.value > 0) {
const points = ruralPop.value / populationRate.value;
- const cells = pack.cells.i.filter(i => pack.cells.state[i] === state);
+ const cells = pack.cells.i.filter((i) => pack.cells.state[i] === state);
const pop = 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) {
- const burgs = pack.burgs.filter(b => !b.removed && b.state === state);
- burgs.forEach(b => b.population = rn(b.population * urbanChange, 4));
+ const burgs = pack.burgs.filter((b) => !b.removed && b.state === state);
+ burgs.forEach((b) => (b.population = rn(b.population * urbanChange, 4)));
}
if (!isFinite(urbanChange) && +urbanPop.value > 0) {
const points = urbanPop.value / populationRate.value / urbanization.value;
- const burgs = pack.burgs.filter(b => !b.removed && b.state === state);
+ const burgs = pack.burgs.filter((b) => !b.removed && b.state === state);
const population = rn(points / burgs.length, 4);
- burgs.forEach(b => b.population = population);
+ burgs.forEach((b) => (b.population = population));
}
refreshStatesEditor();
}
-
}
function stateCapitalZoomIn(state) {
const capital = pack.states[state].capital;
const l = burgLabels.select("[data-id='" + capital + "']");
- const x = +l.attr("x"), y = +l.attr("y");
+ const x = +l.attr('x'),
+ y = +l.attr('y');
zoomTo(x, y, 8, 2000);
}
@@ -392,115 +445,126 @@ function editStates() {
}
function stateChangeExpansionism(state, line, value) {
- line.dataset.expansionism = pack.states[state].expansionism = value;
+ line.dataset.expansionism = pack.states[state].expansionism = value;
recalculateStates();
}
function toggleFog(state, cl) {
if (customization) return;
- const path = statesBody.select("#state"+state).attr("d"), id = "focusState"+state;
- cl.contains("inactive") ? fog(id, path) : unfog(id);
- cl.toggle("inactive");
+ const path = statesBody.select('#state' + state).attr('d'),
+ id = 'focusState' + state;
+ cl.contains('inactive') ? fog(id, path) : unfog(id);
+ cl.toggle('inactive');
}
function stateRemovePrompt(state) {
if (customization) return;
-
- alertMessage.innerHTML = "Are you sure you want to remove the state?
This action cannot be reverted";
- $("#alert").dialog({resizable: false, title: "Remove state",
- buttons: {
- Remove: function() {
- $(this).dialog("close");
- stateRemove(state);
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+ const message = 'Are you sure you want to remove the state?
This action cannot be reverted';
+ confirmationDialog({title: 'Remove state', message, confirm: 'Remove', onConfirm: () => stateRemove(state)});
}
function stateRemove(state) {
- statesBody.select("#state"+state).remove();
- statesBody.select("#state-gap"+state).remove();
- statesHalo.select("#state-border"+state).remove();
- labels.select("#stateLabel"+state).remove();
- defs.select("#textPath_stateLabel"+state).remove();
+ statesBody.select('#state' + state).remove();
+ statesBody.select('#state-gap' + state).remove();
+ statesHalo.select('#state-border' + state).remove();
+ labels.select('#stateLabel' + state).remove();
+ defs.select('#textPath_stateLabel' + state).remove();
- unfog("focusState"+state);
- pack.burgs.forEach(b => {if(b.state === state) b.state = 0;});
- pack.cells.state.forEach((s, i) => {if(s === state) pack.cells.state[i] = 0;});
+ unfog('focusState' + state);
+ pack.burgs.forEach((b) => {
+ if (b.state === state) b.state = 0;
+ });
+ pack.cells.state.forEach((s, i) => {
+ if (s === state) pack.cells.state[i] = 0;
+ });
// remove emblem
- const coaId = "stateCOA" + state;
+ const coaId = 'stateCOA' + state;
document.getElementById(coaId).remove();
emblems.select(`#stateEmblems > use[data-i='${state}']`).remove();
// remove provinces
- pack.states[state].provinces.forEach(p => {
+ pack.states[state].provinces.forEach((p) => {
pack.provinces[p] = {i: p, removed: true};
- pack.cells.province.forEach((pr, i) => {if(pr === p) pack.cells.province[i] = 0;});
- const coaId = "provinceCOA" + p;
+ pack.cells.province.forEach((pr, i) => {
+ if (pr === p) pack.cells.province[i] = 0;
+ });
+ const coaId = 'provinceCOA' + p;
if (document.getElementById(coaId)) document.getElementById(coaId).remove();
emblems.select(`#provinceEmblems > use[data-i='${p}']`).remove();
- const g = provs.select("#provincesBody");
- g.select("#province"+p).remove();
- g.select("#province-gap"+p).remove();
+ const g = provs.select('#provincesBody');
+ g.select('#province' + p).remove();
+ g.select('#province-gap' + p).remove();
});
// remove military
- pack.states[state].military.forEach(m => {
+ pack.states[state].military.forEach((m) => {
const id = `regiment${state}-${m.i}`;
- const index = notes.findIndex(n => n.id === id);
+ const index = notes.findIndex((n) => n.id === id);
if (index != -1) notes.splice(index, 1);
});
- armies.select("g#army"+state).remove();
+ armies.select('g#army' + state).remove();
const capital = pack.states[state].capital;
pack.burgs[capital].capital = 0;
pack.burgs[capital].state = 0;
- moveBurgToGroup(capital, "towns");
+ moveBurgToGroup(capital, 'towns');
pack.states[state] = {i: state, removed: true};
- debug.selectAll(".highlight").remove();
- if (!layerIsOn("toggleStates")) toggleStates(); else drawStates();
- if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
- if (layerIsOn("toggleProvinces")) drawProvinces();
+ debug.selectAll('.highlight').remove();
+ if (!layerIsOn('toggleStates')) toggleStates();
+ else drawStates();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ else drawBorders();
+ if (layerIsOn('toggleProvinces')) drawProvinces();
refreshStatesEditor();
}
function toggleLegend() {
- if (legend.selectAll("*").size()) {clearLegend(); return;}; // hide legend
- const data = pack.states.filter(s => s.i && !s.removed && s.cells).sort((a, b) => b.area - a.area).map(s => [s.i, s.color, s.name]);
- drawLegend("States", data);
+ if (legend.selectAll('*').size()) {
+ clearLegend();
+ return;
+ } // hide legend
+ const data = pack.states
+ .filter((s) => s.i && !s.removed && s.cells)
+ .sort((a, b) => b.area - a.area)
+ .map((s) => [s.i, s.color, s.name]);
+ drawLegend('States', data);
}
function togglePercentageMode() {
- if (body.dataset.type === "absolute") {
- body.dataset.type = "percentage";
+ if (body.dataset.type === 'absolute') {
+ body.dataset.type = 'percentage';
const totalCells = +statesFooterCells.innerHTML;
const totalBurgs = +statesFooterBurgs.innerHTML;
const totalArea = +statesFooterArea.dataset.area;
const totalPopulation = +statesFooterPopulation.dataset.population;
- body.querySelectorAll(":scope > div").forEach(function(el) {
- el.querySelector(".stateCells").innerHTML = rn(+el.dataset.cells / totalCells * 100) + "%";
- el.querySelector(".stateBurgs").innerHTML = rn(+el.dataset.burgs / totalBurgs * 100) + "%";
- el.querySelector(".biomeArea").innerHTML = rn(+el.dataset.area / totalArea * 100) + "%";
- el.querySelector(".culturePopulation").innerHTML = rn(+el.dataset.population / totalPopulation * 100) + "%";
+ body.querySelectorAll(':scope > div').forEach(function (el) {
+ el.querySelector('.stateCells').innerHTML = rn((+el.dataset.cells / totalCells) * 100) + '%';
+ el.querySelector('.stateBurgs').innerHTML = rn((+el.dataset.burgs / totalBurgs) * 100) + '%';
+ el.querySelector('.biomeArea').innerHTML = rn((+el.dataset.area / totalArea) * 100) + '%';
+ el.querySelector('.culturePopulation').innerHTML = rn((+el.dataset.population / totalPopulation) * 100) + '%';
});
} else {
- body.dataset.type = "absolute";
+ body.dataset.type = 'absolute';
statesEditorAddLines();
}
}
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 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 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;
@@ -515,46 +579,68 @@ function editStates() {
Burgs number
`;
alertMessage.innerHTML += `
`;
- 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);
+ 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.i)
- .on("mouseenter", d => showInfo(event, d))
- .on("mouseleave", d => hideInfo(event, d));
+ 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.i)
+ .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);
+ 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
+ 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`);
+ node
+ .append('text')
+ .style('font-size', (d) => rn((d.r ** 0.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);
+ 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 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);
+ 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);
@@ -562,40 +648,51 @@ function editStates() {
function hideInfo(ev) {
stateHighlightOff(ev);
- if (!document.getElementById("statesInfo")) return;
- statesInfo.innerHTML = "";
- d3.select(ev.target).select("circle").classed("selected", 0);
+ 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;
+ 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");
+ 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 ** 0.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 = "";}
+ $('#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() {
- statesBottom.querySelectorAll(":scope > button").forEach(el => el.style.display = "none");
- statesRegenerateButtons.style.display = "block";
+ statesBottom.querySelectorAll(':scope > button').forEach((el) => (el.style.display = 'none'));
+ statesRegenerateButtons.style.display = 'block';
- statesEditor.querySelectorAll(".show").forEach(el => el.classList.remove("hidden"));
- $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
+ statesEditor.querySelectorAll('.show').forEach((el) => el.classList.remove('hidden'));
+ $('#statesEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}});
}
function recalculateStates(must) {
@@ -603,57 +700,56 @@ function editStates() {
BurgsAndStates.expandStates();
BurgsAndStates.generateProvinces();
- if (!layerIsOn("toggleStates")) toggleStates(); else drawStates();
- if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
- if (layerIsOn("toggleProvinces")) drawProvinces();
+ if (!layerIsOn('toggleStates')) toggleStates();
+ else drawStates();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ else drawBorders();
+ if (layerIsOn('toggleProvinces')) drawProvinces();
if (adjustLabels.checked) BurgsAndStates.drawStateLabels();
refreshStatesEditor();
}
function randomizeStatesExpansion() {
- pack.states.forEach(s => {
+ pack.states.forEach((s) => {
if (!s.i || s.removed) return;
const expansionism = rn(Math.random() * 4 + 1, 1);
s.expansionism = expansionism;
- body.querySelector("div.states[data-id='"+s.i+"'] > input.statePower").value = expansionism;
+ body.querySelector("div.states[data-id='" + s.i + "'] > input.statePower").value = expansionism;
});
recalculateStates(true, true);
}
function exitRegenerationMenu() {
- statesBottom.querySelectorAll(":scope > button").forEach(el => el.style.display = "inline-block");
- statesRegenerateButtons.style.display = "none";
- statesEditor.querySelectorAll(".show").forEach(el => el.classList.add("hidden"));
- $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
+ statesBottom.querySelectorAll(':scope > button').forEach((el) => (el.style.display = 'inline-block'));
+ statesRegenerateButtons.style.display = 'none';
+ statesEditor.querySelectorAll('.show').forEach((el) => el.classList.add('hidden'));
+ $('#statesEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}});
}
function enterStatesManualAssignent() {
- if (!layerIsOn("toggleStates")) toggleStates();
+ if (!layerIsOn('toggleStates')) toggleStates();
customization = 2;
- statesBody.append("g").attr("id", "temp");
- document.querySelectorAll("#statesBottom > button").forEach(el => el.style.display = "none");
- document.getElementById("statesManuallyButtons").style.display = "inline-block";
- document.getElementById("statesHalo").style.display = "none";
+ statesBody.append('g').attr('id', 'temp');
+ document.querySelectorAll('#statesBottom > button').forEach((el) => (el.style.display = 'none'));
+ document.getElementById('statesManuallyButtons').style.display = 'inline-block';
+ document.getElementById('statesHalo').style.display = 'none';
- statesEditor.querySelectorAll(".hide").forEach(el => el.classList.add("hidden"));
- statesFooter.style.display = "none";
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "none");
- $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
+ statesEditor.querySelectorAll('.hide').forEach((el) => el.classList.add('hidden'));
+ statesFooter.style.display = 'none';
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'none'));
+ $('#statesEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}});
- tip("Click on state to select, drag the circle to change state", true);
- viewbox.style("cursor", "crosshair")
- .on("click", selectStateOnMapClick)
- .call(d3.drag().on("start", dragStateBrush))
- .on("touchmove mousemove", moveStateBrush);
+ tip('Click on state to select, drag the circle to change state', true);
+ viewbox.style('cursor', 'crosshair').on('click', selectStateOnMapClick).call(d3.drag().on('start', dragStateBrush)).on('touchmove mousemove', moveStateBrush);
- body.querySelector("div").classList.add("selected");
+ body.querySelector('div').classList.add('selected');
}
function selectStateOnLineClick() {
if (customization !== 2) return;
- if (this.parentNode.id !== "statesBodySection") return;
- body.querySelector("div.selected").classList.remove("selected");
- this.classList.add("selected");
+ if (this.parentNode.id !== 'statesBodySection') return;
+ body.querySelector('div.selected').classList.remove('selected');
+ this.classList.add('selected');
}
function selectStateOnMapClick() {
@@ -661,17 +757,17 @@ function editStates() {
const i = findCell(point[0], point[1]);
if (pack.cells.h[i] < 20) return;
- const assigned = statesBody.select("#temp").select("polygon[data-cell='"+i+"']");
- const state = assigned.size() ? +assigned.attr("data-state") : pack.cells.state[i];
+ const assigned = statesBody.select('#temp').select("polygon[data-cell='" + i + "']");
+ const state = assigned.size() ? +assigned.attr('data-state') : pack.cells.state[i];
- body.querySelector("div.selected").classList.remove("selected");
- body.querySelector("div[data-id='"+state+"']").classList.add("selected");
+ body.querySelector('div.selected').classList.remove('selected');
+ body.querySelector("div[data-id='" + state + "']").classList.add('selected');
}
function dragStateBrush() {
const r = +statesManuallyBrush.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);
@@ -684,21 +780,21 @@ function editStates() {
// change state within selection
function changeStateForSelection(selection) {
- const temp = statesBody.select("#temp");
- const selected = body.querySelector("div.selected");
+ const temp = statesBody.select('#temp');
+ const selected = body.querySelector('div.selected');
const stateNew = +selected.dataset.id;
- const color = pack.states[stateNew].color || "#ffffff";
+ const color = pack.states[stateNew].color || '#ffffff';
- selection.forEach(function(i) {
- const exists = temp.select("polygon[data-cell='"+i+"']");
- const stateOld = exists.size() ? +exists.attr("data-state") : pack.cells.state[i];
+ selection.forEach(function (i) {
+ const exists = temp.select("polygon[data-cell='" + i + "']");
+ const stateOld = exists.size() ? +exists.attr('data-state') : pack.cells.state[i];
if (stateNew === stateOld) return;
if (i === pack.states[stateOld].center) return;
// change of append new element
- if (exists.size()) exists.attr("data-state", stateNew).attr("fill", color).attr("stroke", color);
- else temp.append("polygon").attr("data-cell", i).attr("data-state", stateNew).attr("points", getPackPolygon(i)).attr("fill", color).attr("stroke", color);
+ if (exists.size()) exists.attr('data-state', stateNew).attr('fill', color).attr('stroke', color);
+ else temp.append('polygon').attr('data-cell', i).attr('data-state', stateNew).attr('points', getPackPolygon(i)).attr('fill', color).attr('stroke', color);
});
}
@@ -710,33 +806,42 @@ function editStates() {
}
function applyStatesManualAssignent() {
- const cells = pack.cells, affectedStates = [], affectedProvinces = [];
+ const cells = pack.cells,
+ affectedStates = [],
+ affectedProvinces = [];
- statesBody.select("#temp").selectAll("polygon").each(function() {
- const i = +this.dataset.cell;
- const c = +this.dataset.state;
- affectedStates.push(cells.state[i], c);
- affectedProvinces.push(cells.province[i]);
- cells.state[i] = c;
- if (cells.burg[i]) pack.burgs[cells.burg[i]].state = c;
- });
+ statesBody
+ .select('#temp')
+ .selectAll('polygon')
+ .each(function () {
+ const i = +this.dataset.cell;
+ const c = +this.dataset.state;
+ affectedStates.push(cells.state[i], c);
+ affectedProvinces.push(cells.province[i]);
+ cells.state[i] = c;
+ if (cells.burg[i]) pack.burgs[cells.burg[i]].state = c;
+ });
if (affectedStates.length) {
refreshStatesEditor();
- if (!layerIsOn("toggleStates")) toggleStates(); else drawStates();
+ if (!layerIsOn('toggleStates')) toggleStates();
+ else drawStates();
if (adjustLabels.checked) BurgsAndStates.drawStateLabels([...new Set(affectedStates)]);
adjustProvinces([...new Set(affectedProvinces)]);
- if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
- if (layerIsOn("toggleProvinces")) drawProvinces();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ else drawBorders();
+ if (layerIsOn('toggleProvinces')) drawProvinces();
}
exitStatesManualAssignment();
}
function adjustProvinces(affectedProvinces) {
- const cells = pack.cells, provinces = pack.provinces, states = pack.states;
- const form = {"Zone":1, "Area":1, "Territory":2, "Province":1};
+ const cells = pack.cells,
+ provinces = pack.provinces,
+ states = pack.states;
+ const form = {Zone: 1, Area: 1, Territory: 2, Province: 1};
- affectedProvinces.forEach(p => {
+ affectedProvinces.forEach((p) => {
// do nothing if neutral lands are captured
if (!p) return;
@@ -745,8 +850,8 @@ function editStates() {
if (states[old].provinces.includes(p)) states[old].provinces.splice(states[old].provinces.indexOf(p), 1);
// find states owning at least 1 province cell
- const provCells = cells.i.filter(i => cells.province[i] === p);
- const provStates = [...new Set(provCells.map(i => cells.state[i]))];
+ const provCells = cells.i.filter((i) => cells.province[i] === p);
+ const provStates = [...new Set(provCells.map((i) => cells.state[i]))];
// assign province to its center owner; if center is neutral, remove province
const owner = cells.state[provinces[p].center];
@@ -754,10 +859,10 @@ function editStates() {
const name = provinces[p].name;
// if province is historical part of abouther state province, unite with old province
- const part = states[owner].provinces.find(n => name.includes(provinces[n].name));
+ const part = states[owner].provinces.find((n) => name.includes(provinces[n].name));
if (part) {
provinces[p].removed = true;
- provCells.filter(i => cells.state[i] === owner).forEach(i => cells.province[i] = part);
+ provCells.filter((i) => cells.state[i] === owner).forEach((i) => (cells.province[i] = part));
} else {
provinces[p].state = owner;
states[owner].provinces.push(p);
@@ -765,66 +870,83 @@ function editStates() {
}
} else {
provinces[p].removed = true;
- provCells.filter(i => !cells.state[i]).forEach(i => cells.province[i] = 0);
+ provCells.filter((i) => !cells.state[i]).forEach((i) => (cells.province[i] = 0));
}
// create new provinces for non-main part
- provStates.filter(s => s && s !== owner).forEach(s => createProvince(p, s, provCells.filter(i => cells.state[i] === s)));
+ provStates
+ .filter((s) => s && s !== owner)
+ .forEach((s) =>
+ createProvince(
+ p,
+ s,
+ provCells.filter((i) => cells.state[i] === s)
+ )
+ );
});
function createProvince(initProv, state, provCells) {
const province = provinces.length;
- provCells.forEach(i => cells.province[i] = province);
+ provCells.forEach((i) => (cells.province[i] = province));
- const burgCell = provCells.find(i => cells.burg[i]);
+ const burgCell = provCells.find((i) => cells.burg[i]);
const center = burgCell ? burgCell : provCells[0];
const burg = burgCell ? cells.burg[burgCell] : 0;
- const name = burgCell && P(.7) ? getAdjective(pack.burgs[burg].name)
- : getAdjective(states[state].name) + " " + provinces[initProv].name.split(" ").slice(-1)[0];
- const formName = name.split(" ").length > 1 ? provinces[initProv].formName : rw(form);
- const fullName = name + " " + formName;
+ const name = burgCell && P(0.7) ? getAdjective(pack.burgs[burg].name) : getAdjective(states[state].name) + ' ' + provinces[initProv].name.split(' ').slice(-1)[0];
+ const formName = name.split(' ').length > 1 ? provinces[initProv].formName : rw(form);
+ const fullName = name + ' ' + formName;
const color = getMixedColor(states[state].color);
- provinces.push({i:province, state, center, burg, name, formName, fullName, color});
+ provinces.push({i: province, state, center, burg, name, formName, fullName, color});
}
-
}
-
+
function exitStatesManualAssignment(close) {
customization = 0;
- statesBody.select("#temp").remove();
+ statesBody.select('#temp').remove();
removeCircle();
- document.querySelectorAll("#statesBottom > button").forEach(el => el.style.display = "inline-block");
- document.getElementById("statesManuallyButtons").style.display = "none";
- document.getElementById("statesHalo").style.display = "block";
+ document.querySelectorAll('#statesBottom > button').forEach((el) => (el.style.display = 'inline-block'));
+ document.getElementById('statesManuallyButtons').style.display = 'none';
+ document.getElementById('statesHalo').style.display = 'block';
- statesEditor.querySelectorAll(".hide:not(.show)").forEach(el => el.classList.remove("hidden"));
- statesFooter.style.display = "block";
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "all");
- if(!close) $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
+ statesEditor.querySelectorAll('.hide:not(.show)').forEach((el) => el.classList.remove('hidden'));
+ statesFooter.style.display = 'block';
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'all'));
+ if (!close) $('#statesEditor').dialog({position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}});
restoreDefaultEvents();
clearMainTip();
- 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 enterAddStateMode() {
- if (this.classList.contains("pressed")) {exitAddStateMode(); return;};
+ if (this.classList.contains('pressed')) {
+ exitAddStateMode();
+ return;
+ }
customization = 3;
- this.classList.add("pressed");
- tip("Click on the map to create a new capital or promote an existing burg", true);
- viewbox.style("cursor", "crosshair").on("click", addState);
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "none");
+ this.classList.add('pressed');
+ tip('Click on the map to create a new capital or promote an existing burg', true);
+ viewbox.style('cursor', 'crosshair').on('click', addState);
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'none'));
}
function addState() {
- const states = pack.states, burgs = pack.burgs, cells = pack.cells;
+ const states = pack.states,
+ burgs = pack.burgs,
+ cells = pack.cells;
const point = d3.mouse(this);
const center = findCell(point[0], point[1]);
- if (cells.h[center] < 20) {tip("You cannot place state into the water. Please click on a land cell", false, "error"); return;}
+ if (cells.h[center] < 20) {
+ tip('You cannot place state into the water. Please click on a land cell', false, 'error');
+ return;
+ }
let burg = cells.burg[center];
- if (burg && burgs[burg].capital) {tip("Existing capital cannot be selected as a new state capital! Select other cell", false, "error"); return;}
+ if (burg && burgs[burg].capital) {
+ tip('Existing capital cannot be selected as a new state capital! Select other cell', false, 'error');
+ return;
+ }
if (!burg) burg = addBurg(point); // add new burg
const oldState = cells.state[center];
@@ -833,64 +955,78 @@ function editStates() {
// turn burg into a capital
burgs[burg].capital = 1;
burgs[burg].state = newState;
- moveBurgToGroup(burg, "cities");
+ moveBurgToGroup(burg, 'cities');
if (d3.event.shiftKey === false) exitAddStateMode();
const culture = cells.culture[center];
- const basename = center%5 === 0 ? burgs[burg].name : Names.getCulture(culture);
+ const basename = center % 5 === 0 ? burgs[burg].name : Names.getCulture(culture);
const name = Names.getState(basename, culture);
const color = getRandomColor();
const pole = cells.p[center];
// generate emblem
const cultureType = pack.cultures[culture].type;
- const coa = COA.generate(burgs[burg].coa, .4, null, cultureType);
+ const coa = COA.generate(burgs[burg].coa, 0.4, null, cultureType);
coa.shield = COA.getShield(culture, null);
// update diplomacy and reverse relations
- const diplomacy = states.map(s => {
- if (!s.i || s.removed) return "x";
+ const diplomacy = states.map((s) => {
+ if (!s.i || s.removed) return 'x';
if (!oldState) {
- s.diplomacy.push("Neutral");
- return "Neutral";
+ s.diplomacy.push('Neutral');
+ return 'Neutral';
}
let relations = states[oldState].diplomacy[s.i]; // relations between Nth state and old overlord
- if (s.i === oldState) relations = "Enemy"; // new state is Enemy to its old overlord
- else if (relations === "Ally") relations = "Suspicion";
- else if (relations === "Friendly") relations = "Suspicion";
- else if (relations === "Suspicion") relations = "Neutral";
- else if (relations === "Enemy") relations = "Friendly";
- else if (relations === "Rival") relations = "Friendly";
- else if (relations === "Vassal") relations = "Suspicion";
- else if (relations === "Suzerain") relations = "Enemy";
+ if (s.i === oldState) relations = 'Enemy';
+ // new state is Enemy to its old overlord
+ else if (relations === 'Ally') relations = 'Suspicion';
+ else if (relations === 'Friendly') relations = 'Suspicion';
+ else if (relations === 'Suspicion') relations = 'Neutral';
+ else if (relations === 'Enemy') relations = 'Friendly';
+ else if (relations === 'Rival') relations = 'Friendly';
+ else if (relations === 'Vassal') relations = 'Suspicion';
+ else if (relations === 'Suzerain') relations = 'Enemy';
s.diplomacy.push(relations);
return relations;
});
- diplomacy.push("x");
+ diplomacy.push('x');
states[0].diplomacy.push([`Independance declaration`, `${name} declared its independance from ${states[oldState].name}`]);
cells.state[center] = newState;
cells.province[center] = 0;
- states.push({i:newState, name, diplomacy, provinces:[], color, expansionism:.5, capital:burg, type:"Generic", center, culture, military:[], alert:1, coa, pole});
+ states.push({i: newState, name, diplomacy, provinces: [], color, expansionism: 0.5, capital: burg, type: 'Generic', center, culture, military: [], alert: 1, coa, pole});
BurgsAndStates.collectStatistics();
BurgsAndStates.defineStateForms([newState]);
adjustProvinces([cells.province[center]]);
- if (layerIsOn("toggleProvinces")) toggleProvinces();
- if (!layerIsOn("toggleStates")) toggleStates(); else drawStates();
- if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
+ if (layerIsOn('toggleProvinces')) toggleProvinces();
+ if (!layerIsOn('toggleStates')) toggleStates();
+ else drawStates();
+ if (!layerIsOn('toggleBorders')) toggleBorders();
+ else drawBorders();
// add label
- defs.select("#textPaths").append("path").attr("d", `M${pole[0]-50},${pole[1]+6}h${100}`).attr("id", "textPath_stateLabel"+newState);
- labels.select("#states")
- .append("text").attr("id", "stateLabel"+newState)
- .append("textPath").attr("xlink:href", "#textPath_stateLabel"+newState).attr("startOffset", "50%").attr("font-size", "50%")
- .append("tspan").attr("x", name.length * -3).text(name);
+ defs
+ .select('#textPaths')
+ .append('path')
+ .attr('d', `M${pole[0] - 50},${pole[1] + 6}h${100}`)
+ .attr('id', 'textPath_stateLabel' + newState);
+ labels
+ .select('#states')
+ .append('text')
+ .attr('id', 'stateLabel' + newState)
+ .append('textPath')
+ .attr('xlink:href', '#textPath_stateLabel' + newState)
+ .attr('startOffset', '50%')
+ .attr('font-size', '50%')
+ .append('tspan')
+ .attr('x', name.length * -3)
+ .text(name);
- COArenderer.add("state", newState, coa, states[newState].pole[0], states[newState].pole[1]);
+ COArenderer.add('state', newState, coa, states[newState].pole[0], states[newState].pole[1]);
statesEditorAddLines();
}
@@ -898,40 +1034,40 @@ function editStates() {
customization = 0;
restoreDefaultEvents();
clearMainTip();
- body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "all");
- if (statesAdd.classList.contains("pressed")) statesAdd.classList.remove("pressed");
+ body.querySelectorAll('div > input, select, span, svg').forEach((e) => (e.style.pointerEvents = 'all'));
+ if (statesAdd.classList.contains('pressed')) statesAdd.classList.remove('pressed');
}
function downloadStatesData() {
- const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value;
- let data = "Id,State,Form,Color,Capital,Culture,Type,Expansionism,Cells,Burgs,Area "+unit+",Total Population,Rural Population,Urban Population\n"; // headers
+ const unit = areaUnit.value === 'square' ? distanceUnitInput.value + '2' : areaUnit.value;
+ let data = 'Id,State,Form,Color,Capital,Culture,Type,Expansionism,Cells,Burgs,Area ' + unit + ',Total Population,Rural Population,Urban Population\n'; // headers
- body.querySelectorAll(":scope > div").forEach(function(el) {
+ body.querySelectorAll(':scope > div').forEach(function (el) {
const key = parseInt(el.dataset.id);
- data += el.dataset.id + ",";
- data += el.dataset.name + ",";
- data += el.dataset.form + ",";
- data += el.dataset.color + ",";
- data += el.dataset.capital + ",";
- data += el.dataset.culture + ",";
- data += el.dataset.type + ",";
- data += el.dataset.expansionism + ",";
- data += el.dataset.cells + ",";
- data += el.dataset.burgs + ",";
- data += el.dataset.area + ",";
- data += el.dataset.population + ",";
- data += `${Math.round(pack.states[key].rural*populationRate.value)},`;
- data += `${Math.round(pack.states[key].urban*populationRate.value * urbanization.value)}\n`;
+ data += el.dataset.id + ',';
+ data += el.dataset.name + ',';
+ data += el.dataset.form + ',';
+ data += el.dataset.color + ',';
+ data += el.dataset.capital + ',';
+ data += el.dataset.culture + ',';
+ data += el.dataset.type + ',';
+ data += el.dataset.expansionism + ',';
+ data += el.dataset.cells + ',';
+ data += el.dataset.burgs + ',';
+ data += el.dataset.area + ',';
+ data += el.dataset.population + ',';
+ data += `${Math.round(pack.states[key].rural * populationRate.value)},`;
+ data += `${Math.round(pack.states[key].urban * populationRate.value * urbanization.value)}\n`;
});
- const name = getFileName("States") + ".csv";
+ const name = getFileName('States') + '.csv';
downloadFile(data, name);
}
function closeStatesEditor() {
- if (customization === 2) exitStatesManualAssignment("close");
+ if (customization === 2) exitStatesManualAssignment('close');
if (customization === 3) exitAddStateMode();
- debug.selectAll(".highlight").remove();
- body.innerHTML = "";
+ debug.selectAll('.highlight').remove();
+ body.innerHTML = '';
}
}
diff --git a/modules/ui/style.js b/modules/ui/style.js
index 9386efe4..882cc8ff 100644
--- a/modules/ui/style.js
+++ b/modules/ui/style.js
@@ -1,8 +1,8 @@
// UI module to control the style
-"use strict";
+'use strict';
// store some style inputs as options
-styleElements.addEventListener("change", function(ev) {
+styleElements.addEventListener('change', function (ev) {
if (ev.target.dataset.stored) lock(ev.target.dataset.stored);
});
@@ -14,334 +14,347 @@ function editStyle(element, group) {
if (group) styleGroupSelect.options.add(new Option(group, group, true, true));
selectStyleElement();
- styleElementSelect.classList.add("glow");
- if (group) styleGroupSelect.classList.add("glow");
+ styleElementSelect.classList.add('glow');
+ if (group) styleGroupSelect.classList.add('glow');
setTimeout(() => {
- styleElementSelect.classList.remove("glow");
- if (group) styleGroupSelect.classList.remove("glow");
+ styleElementSelect.classList.remove('glow');
+ if (group) styleGroupSelect.classList.remove('glow');
}, 1500);
}
// Toggle style sections on element select
-styleElementSelect.addEventListener("change", selectStyleElement);
+styleElementSelect.addEventListener('change', selectStyleElement);
function selectStyleElement() {
const sel = styleElementSelect.value;
- let el = d3.select("#"+sel);
+ let el = d3.select('#' + sel);
- styleElements.querySelectorAll("tbody").forEach(e => e.style.display = "none"); // hide all sections
- const off = sel !== "ocean" && (el.style("display") === "none" || !el.selectAll("*").size()); // check if layer is off
+ styleElements.querySelectorAll('tbody').forEach((e) => (e.style.display = 'none')); // hide all sections
+ const off = sel !== 'ocean' && (el.style('display') === 'none' || !el.selectAll('*').size()); // check if layer is off
if (off) {
- styleIsOff.style.display = "block";
- setTimeout(() => styleIsOff.style.display = "none", 1500);
+ styleIsOff.style.display = 'block';
+ setTimeout(() => (styleIsOff.style.display = 'none'), 1500);
}
// active group element
const group = styleGroupSelect.value;
- if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders"].includes(sel)) {
- el = d3.select("#"+sel).select("g#"+group).size()
- ? d3.select("#"+sel).select("g#"+group)
- : d3.select("#"+sel).select("g");
+ if (['routes', 'labels', 'coastline', 'lakes', 'anchors', 'burgIcons', 'borders'].includes(sel)) {
+ el = d3
+ .select('#' + sel)
+ .select('g#' + group)
+ .size()
+ ? d3.select('#' + sel).select('g#' + group)
+ : d3.select('#' + sel).select('g');
}
- if (sel !== "landmass" && sel !== "legend") {
+ if (sel !== 'landmass' && sel !== 'legend') {
// opacity
- if (sel !== "ocean") {
- styleOpacity.style.display = "block";
- styleOpacityInput.value = styleOpacityOutput.value = el.attr("opacity") || 1;
+ if (sel !== 'ocean') {
+ styleOpacity.style.display = 'block';
+ styleOpacityInput.value = styleOpacityOutput.value = el.attr('opacity') || 1;
}
// filter
- styleFilter.style.display = "block";
- styleFilterInput.value = el.attr("filter") || "";
+ styleFilter.style.display = 'block';
+ styleFilterInput.value = el.attr('filter') || '';
}
// fill
- if (["rivers", "lakes", "landmass", "prec", "ice", "fogging"].includes(sel)) {
- styleFill.style.display = "block";
- styleFillInput.value = styleFillOutput.value = el.attr("fill");
+ if (['rivers', 'lakes', 'landmass', 'prec', 'ice', 'fogging'].includes(sel)) {
+ styleFill.style.display = 'block';
+ styleFillInput.value = styleFillOutput.value = el.attr('fill');
}
// stroke color and width
- if (["armies", "routes", "lakes", "borders", "cults", "relig", "cells", "coastline", "prec", "ice", "icons", "coordinates", "zones", "gridOverlay"].includes(sel)) {
- styleStroke.style.display = "block";
- styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke");
- styleStrokeWidth.style.display = "block";
- styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || "";
+ if (['armies', 'routes', 'lakes', 'borders', 'cults', 'relig', 'cells', 'coastline', 'prec', 'ice', 'icons', 'coordinates', 'zones', 'gridOverlay'].includes(sel)) {
+ styleStroke.style.display = 'block';
+ styleStrokeInput.value = styleStrokeOutput.value = el.attr('stroke');
+ styleStrokeWidth.style.display = 'block';
+ styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr('stroke-width') || '';
}
// stroke dash
- if (["routes", "borders", "temperature", "legend", "population", "coordinates", "zones", "gridOverlay"].includes(sel)) {
- styleStrokeDash.style.display = "block";
- styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || "";
- styleStrokeLinecapInput.value = el.attr("stroke-linecap") || "inherit";
+ if (['routes', 'borders', 'temperature', 'legend', 'population', 'coordinates', 'zones', 'gridOverlay'].includes(sel)) {
+ styleStrokeDash.style.display = 'block';
+ styleStrokeDasharrayInput.value = el.attr('stroke-dasharray') || '';
+ styleStrokeLinecapInput.value = el.attr('stroke-linecap') || 'inherit';
}
// clipping
- if (["cells", "gridOverlay", "coordinates", "compass", "terrain", "temperature", "routes", "texture", "biomes", "zones"].includes(sel)) {
- styleClipping.style.display = "block";
- styleClippingInput.value = el.attr("mask") || "";
+ if (['cells', 'gridOverlay', 'coordinates', 'compass', 'terrain', 'temperature', 'routes', 'texture', 'biomes', 'zones'].includes(sel)) {
+ styleClipping.style.display = 'block';
+ styleClippingInput.value = el.attr('mask') || '';
}
// show specific sections
- if (sel === "texture") styleTexture.style.display = "block";
- if (sel === "routes", "labels" || sel == "anchors" || sel == "burgIcons", "coastline", "lakes", "borders") styleGroup.style.display = "block";
+ if (sel === 'texture') styleTexture.style.display = 'block';
+ if ((sel === 'routes', 'labels' || sel == 'anchors' || sel == 'burgIcons', 'coastline', 'lakes', 'borders')) styleGroup.style.display = 'block';
- if (sel === "terrs") {
- styleHeightmap.style.display = "block";
- styleHeightmapScheme.value = terrs.attr("scheme");
- styleHeightmapTerracing.value = styleHeightmapTerracingOutput.value = terrs.attr("terracing");
- styleHeightmapSkip.value = styleHeightmapSkipOutput.value = terrs.attr("skip");
- styleHeightmapSimplification.value = styleHeightmapSimplificationOutput.value = terrs.attr("relax");
- styleHeightmapCurve.value = terrs.attr("curve");
+ if (sel === 'terrs') {
+ styleHeightmap.style.display = 'block';
+ styleHeightmapScheme.value = terrs.attr('scheme');
+ styleHeightmapTerracing.value = styleHeightmapTerracingOutput.value = terrs.attr('terracing');
+ styleHeightmapSkip.value = styleHeightmapSkipOutput.value = terrs.attr('skip');
+ styleHeightmapSimplification.value = styleHeightmapSimplificationOutput.value = terrs.attr('relax');
+ styleHeightmapCurve.value = terrs.attr('curve');
}
- if (sel === "markers") {
- styleMarkers.style.display = "block";
- styleRescaleMarkers.checked = +markers.attr("rescale");
+ if (sel === 'markers') {
+ styleMarkers.style.display = 'block';
+ styleRescaleMarkers.checked = +markers.attr('rescale');
}
- if (sel === "gridOverlay") {
- styleGrid.style.display = "block";
- styleGridType.value = el.attr("type");
- styleGridScale.value = el.attr("scale") || 1;
- styleGridShiftX.value = el.attr("dx") || 0;
- styleGridShiftY.value = el.attr("dy") || 0;
+ if (sel === 'gridOverlay') {
+ styleGrid.style.display = 'block';
+ styleGridType.value = el.attr('type');
+ styleGridScale.value = el.attr('scale') || 1;
+ styleGridShiftX.value = el.attr('dx') || 0;
+ styleGridShiftY.value = el.attr('dy') || 0;
calculateFriendlyGridSize();
}
- if (sel === "compass") {
- styleCompass.style.display = "block";
- const tr = parseTransform(compass.select("use").attr("transform"));
+ if (sel === 'compass') {
+ styleCompass.style.display = 'block';
+ const tr = parseTransform(compass.select('use').attr('transform'));
styleCompassShiftX.value = tr[0];
styleCompassShiftY.value = tr[1];
styleCompassSizeInput.value = styleCompassSizeOutput.value = tr[2];
}
- if (sel === "terrain") {
- styleRelief.style.display = "block";
- styleReliefSizeOutput.innerHTML = styleReliefSizeInput.value = terrain.attr("size");
- styleReliefDensityOutput.innerHTML = styleReliefDensityInput.value = terrain.attr("density");
- styleReliefSet.value = terrain.attr("set");
+ if (sel === 'terrain') {
+ styleRelief.style.display = 'block';
+ styleReliefSizeOutput.innerHTML = styleReliefSizeInput.value = terrain.attr('size');
+ styleReliefDensityOutput.innerHTML = styleReliefDensityInput.value = terrain.attr('density');
+ styleReliefSet.value = terrain.attr('set');
}
- if (sel === "population") {
- stylePopulation.style.display = "block";
- stylePopulationRuralStrokeInput.value = stylePopulationRuralStrokeOutput.value = population.select("#rural").attr("stroke");
- stylePopulationUrbanStrokeInput.value = stylePopulationUrbanStrokeOutput.value = population.select("#urban").attr("stroke");
- styleStrokeWidth.style.display = "block";
- styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || "";
+ if (sel === 'population') {
+ stylePopulation.style.display = 'block';
+ stylePopulationRuralStrokeInput.value = stylePopulationRuralStrokeOutput.value = population.select('#rural').attr('stroke');
+ stylePopulationUrbanStrokeInput.value = stylePopulationUrbanStrokeOutput.value = population.select('#urban').attr('stroke');
+ styleStrokeWidth.style.display = 'block';
+ styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr('stroke-width') || '';
}
- if (sel === "regions") {
- styleStates.style.display = "block";
- styleStatesHaloWidth.value = styleStatesHaloWidthOutput.value = statesHalo.attr("data-width");
- styleStatesHaloOpacity.value = styleStatesHaloOpacityOutput.value = statesHalo.attr("opacity");
+ if (sel === 'regions') {
+ styleStates.style.display = 'block';
+ styleStatesHaloWidth.value = styleStatesHaloWidthOutput.value = statesHalo.attr('data-width');
+ styleStatesHaloOpacity.value = styleStatesHaloOpacityOutput.value = statesHalo.attr('opacity');
}
- if (sel === "labels") {
- styleFill.style.display = "block";
- styleStroke.style.display = "block";
- styleStrokeWidth.style.display = "block";
+ if (sel === 'labels') {
+ styleFill.style.display = 'block';
+ styleStroke.style.display = 'block';
+ styleStrokeWidth.style.display = 'block';
loadDefaultFonts();
- styleFont.style.display = "block";
- styleSize.style.display = "block";
- styleVisibility.style.display = "block";
- styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#3e3e4b";
- styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3a3a3a";
- styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || 0;
- styleSelectFont.value = fonts.indexOf(el.attr("data-font"));
- styleInputFont.style.display = "none";
- styleInputFont.value = "";
- styleFontSize.value = el.attr("data-size");
+ styleFont.style.display = 'block';
+ styleSize.style.display = 'block';
+ styleVisibility.style.display = 'block';
+ styleFillInput.value = styleFillOutput.value = el.attr('fill') || '#3e3e4b';
+ styleStrokeInput.value = styleStrokeOutput.value = el.attr('stroke') || '#3a3a3a';
+ styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr('stroke-width') || 0;
+ styleSelectFont.value = fonts.indexOf(el.attr('data-font'));
+ styleInputFont.style.display = 'none';
+ styleInputFont.value = '';
+ styleFontSize.value = el.attr('data-size');
}
- if (sel === "provs") {
- styleFill.style.display = "block";
+ if (sel === 'provs') {
+ styleFill.style.display = 'block';
loadDefaultFonts();
- styleFont.style.display = "block";
- styleSize.style.display = "block";
- styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#111111";
- styleSelectFont.value = fonts.indexOf(el.attr("data-font"));
- styleInputFont.style.display = "none";
- styleInputFont.value = "";
- styleFontSize.value = el.attr("data-size");
+ styleFont.style.display = 'block';
+ styleSize.style.display = 'block';
+ styleFillInput.value = styleFillOutput.value = el.attr('fill') || '#111111';
+ styleSelectFont.value = fonts.indexOf(el.attr('data-font'));
+ styleInputFont.style.display = 'none';
+ styleInputFont.value = '';
+ styleFontSize.value = el.attr('data-size');
}
- if (sel == "burgIcons") {
- styleFill.style.display = "block";
- styleStroke.style.display = "block";
- styleStrokeWidth.style.display = "block";
- styleStrokeDash.style.display = "block";
- styleRadius.style.display = "block";
- styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff";
- styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b";
- styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || .24;
- styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || "";
- styleStrokeLinecapInput.value = el.attr("stroke-linecap") || "inherit";
- styleRadiusInput.value = el.attr("size") || 1;
+ if (sel == 'burgIcons') {
+ styleFill.style.display = 'block';
+ styleStroke.style.display = 'block';
+ styleStrokeWidth.style.display = 'block';
+ styleStrokeDash.style.display = 'block';
+ styleRadius.style.display = 'block';
+ styleFillInput.value = styleFillOutput.value = el.attr('fill') || '#ffffff';
+ styleStrokeInput.value = styleStrokeOutput.value = el.attr('stroke') || '#3e3e4b';
+ styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr('stroke-width') || 0.24;
+ styleStrokeDasharrayInput.value = el.attr('stroke-dasharray') || '';
+ styleStrokeLinecapInput.value = el.attr('stroke-linecap') || 'inherit';
+ styleRadiusInput.value = el.attr('size') || 1;
}
- if (sel == "anchors") {
- styleFill.style.display = "block";
- styleStroke.style.display = "block";
- styleStrokeWidth.style.display = "block";
- styleIconSize.style.display = "block";
- styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff";
- styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b";
- styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || .24;
- styleIconSizeInput.value = el.attr("size") || 2;
+ if (sel == 'anchors') {
+ styleFill.style.display = 'block';
+ styleStroke.style.display = 'block';
+ styleStrokeWidth.style.display = 'block';
+ styleIconSize.style.display = 'block';
+ styleFillInput.value = styleFillOutput.value = el.attr('fill') || '#ffffff';
+ styleStrokeInput.value = styleStrokeOutput.value = el.attr('stroke') || '#3e3e4b';
+ styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr('stroke-width') || 0.24;
+ styleIconSizeInput.value = el.attr('size') || 2;
}
- if (sel === "legend") {
- styleStroke.style.display = "block";
- styleStrokeWidth.style.display = "block";
+ if (sel === 'legend') {
+ styleStroke.style.display = 'block';
+ styleStrokeWidth.style.display = 'block';
loadDefaultFonts();
- styleFont.style.display = "block";
- styleSize.style.display = "block";
+ styleFont.style.display = 'block';
+ styleSize.style.display = 'block';
- styleLegend.style.display = "block";
- styleLegendColItemsOutput.value = styleLegendColItems.value = el.attr("data-columns");
- styleLegendBackOutput.value = styleLegendBack.value = el.select("#legendBox").attr("fill");
- styleLegendOpacityOutput.value = styleLegendOpacity.value = el.select("#legendBox").attr("fill-opacity");
+ styleLegend.style.display = 'block';
+ styleLegendColItemsOutput.value = styleLegendColItems.value = el.attr('data-columns');
+ styleLegendBackOutput.value = styleLegendBack.value = el.select('#legendBox').attr('fill');
+ styleLegendOpacityOutput.value = styleLegendOpacity.value = el.select('#legendBox').attr('fill-opacity');
- styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#111111";
- styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || .5;
- styleSelectFont.value = fonts.indexOf(el.attr("data-font"));
- styleInputFont.style.display = "none";
- styleInputFont.value = "";
- styleFontSize.value = el.attr("data-size");
+ styleStrokeInput.value = styleStrokeOutput.value = el.attr('stroke') || '#111111';
+ styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr('stroke-width') || 0.5;
+ styleSelectFont.value = fonts.indexOf(el.attr('data-font'));
+ styleInputFont.style.display = 'none';
+ styleInputFont.value = '';
+ styleFontSize.value = el.attr('data-size');
}
- if (sel === "ocean") {
- styleOcean.style.display = "block";
- styleOceanFill.value = styleOceanFillOutput.value = oceanLayers.select("#oceanBase").attr("fill");
- styleOceanPattern.value = document.getElementById("oceanicPattern")?.getAttribute("href");
- styleOceanPatternOpacity.value = styleOceanPatternOpacityOutput.value = document.getElementById("oceanPattern").getAttribute("opacity") || 1;
- outlineLayers.value = oceanLayers.attr("layers");
+ if (sel === 'ocean') {
+ styleOcean.style.display = 'block';
+ styleOceanFill.value = styleOceanFillOutput.value = oceanLayers.select('#oceanBase').attr('fill');
+ styleOceanPattern.value = document.getElementById('oceanicPattern')?.getAttribute('href');
+ styleOceanPatternOpacity.value = styleOceanPatternOpacityOutput.value = document.getElementById('oceanPattern').getAttribute('opacity') || 1;
+ outlineLayers.value = oceanLayers.attr('layers');
}
- if (sel === "temperature") {
- styleStrokeWidth.style.display = "block";
- styleTemperature.style.display = "block";
- styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || "";
- styleTemperatureFillOpacityInput.value = styleTemperatureFillOpacityOutput.value = el.attr("fill-opacity") || .1;
- styleTemperatureFillInput.value = styleTemperatureFillOutput.value = el.attr("fill") || "#000";
- styleTemperatureFontSizeInput.value = styleTemperatureFontSizeOutput.value = el.attr("font-size") || "8px";;
+ if (sel === 'temperature') {
+ styleStrokeWidth.style.display = 'block';
+ styleTemperature.style.display = 'block';
+ styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr('stroke-width') || '';
+ styleTemperatureFillOpacityInput.value = styleTemperatureFillOpacityOutput.value = el.attr('fill-opacity') || 0.1;
+ styleTemperatureFillInput.value = styleTemperatureFillOutput.value = el.attr('fill') || '#000';
+ styleTemperatureFontSizeInput.value = styleTemperatureFontSizeOutput.value = el.attr('font-size') || '8px';
}
- if (sel === "coordinates") {
- styleSize.style.display = "block";
- styleFontSize.value = el.attr("data-size");
+ if (sel === 'coordinates') {
+ styleSize.style.display = 'block';
+ styleFontSize.value = el.attr('data-size');
}
- if (sel === "armies") {
- styleArmies.style.display = "block";
- styleArmiesFillOpacity.value = styleArmiesFillOpacityOutput.value = el.attr("fill-opacity");
- styleArmiesSize.value = styleArmiesSizeOutput.value = el.attr("box-size");
+ if (sel === 'armies') {
+ styleArmies.style.display = 'block';
+ styleArmiesFillOpacity.value = styleArmiesFillOpacityOutput.value = el.attr('fill-opacity');
+ styleArmiesSize.value = styleArmiesSizeOutput.value = el.attr('box-size');
}
- if (sel === "emblems") {
- styleEmblems.style.display = "block";
- styleStrokeWidth.style.display = "block";
- styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || 1;
+ if (sel === 'emblems') {
+ styleEmblems.style.display = 'block';
+ styleStrokeWidth.style.display = 'block';
+ styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr('stroke-width') || 1;
}
// update group options
styleGroupSelect.options.length = 0; // remove all options
- if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders"].includes(sel)) {
- document.getElementById(sel).querySelectorAll("g").forEach(el => {
- if (el.id === "burgLabels") return;
- const count = el.childElementCount;
- styleGroupSelect.options.add(new Option(`${el.id} (${count})`, el.id, false, false));
- });
- styleGroupSelect.value = el.attr("id");
+ if (['routes', 'labels', 'coastline', 'lakes', 'anchors', 'burgIcons', 'borders'].includes(sel)) {
+ document
+ .getElementById(sel)
+ .querySelectorAll('g')
+ .forEach((el) => {
+ if (el.id === 'burgLabels') return;
+ const count = el.childElementCount;
+ styleGroupSelect.options.add(new Option(`${el.id} (${count})`, el.id, false, false));
+ });
+ styleGroupSelect.value = el.attr('id');
} else {
styleGroupSelect.options.add(new Option(sel, sel, false, true));
}
- if (sel === "coastline" && styleGroupSelect.value === "sea_island") {
- styleCoastline.style.display = "block";
- const auto = styleCoastlineAuto.checked = coastline.select("#sea_island").attr("auto-filter");
- if (auto) styleFilter.style.display = "none";
+ if (sel === 'coastline' && styleGroupSelect.value === 'sea_island') {
+ styleCoastline.style.display = 'block';
+ const auto = (styleCoastlineAuto.checked = coastline.select('#sea_island').attr('auto-filter'));
+ if (auto) styleFilter.style.display = 'none';
}
-
}
// Handle style inputs change
-styleGroupSelect.addEventListener("change", selectStyleElement);
+styleGroupSelect.addEventListener('change', selectStyleElement);
function getEl() {
- const el = styleElementSelect.value, g = styleGroupSelect.value;
- if (g === el) return svg.select("#"+el); else return svg.select("#"+el).select("#"+g);
+ const el = styleElementSelect.value,
+ g = styleGroupSelect.value;
+ if (g === el) return svg.select('#' + el);
+ else return svg.select('#' + el).select('#' + g);
}
-styleFillInput.addEventListener("input", function() {
+styleFillInput.addEventListener('input', function () {
styleFillOutput.value = this.value;
getEl().attr('fill', this.value);
});
-styleStrokeInput.addEventListener("input", function() {
+styleStrokeInput.addEventListener('input', function () {
styleStrokeOutput.value = this.value;
getEl().attr('stroke', this.value);
- if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
+ if (styleElementSelect.value === 'gridOverlay' && layerIsOn('toggleGrid')) drawGrid();
});
-styleStrokeWidthInput.addEventListener("input", function() {
+styleStrokeWidthInput.addEventListener('input', function () {
styleStrokeWidthOutput.value = this.value;
getEl().attr('stroke-width', +this.value);
- if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
+ if (styleElementSelect.value === 'gridOverlay' && layerIsOn('toggleGrid')) drawGrid();
});
-styleStrokeDasharrayInput.addEventListener("input", function() {
+styleStrokeDasharrayInput.addEventListener('input', function () {
getEl().attr('stroke-dasharray', this.value);
- if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
+ if (styleElementSelect.value === 'gridOverlay' && layerIsOn('toggleGrid')) drawGrid();
});
-styleStrokeLinecapInput.addEventListener("change", function() {
+styleStrokeLinecapInput.addEventListener('change', function () {
getEl().attr('stroke-linecap', this.value);
- if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
+ if (styleElementSelect.value === 'gridOverlay' && layerIsOn('toggleGrid')) drawGrid();
});
-styleOpacityInput.addEventListener("input", function() {
+styleOpacityInput.addEventListener('input', function () {
styleOpacityOutput.value = this.value;
getEl().attr('opacity', this.value);
});
-styleFilterInput.addEventListener("change", function() {
- if (styleGroupSelect.value === "ocean") {
+styleFilterInput.addEventListener('change', function () {
+ if (styleGroupSelect.value === 'ocean') {
oceanLayers.attr('filter', this.value);
return;
}
getEl().attr('filter', this.value);
});
-styleTextureInput.addEventListener("change", function() {
- if (this.value === "none") texture.select("image").attr("xlink:href", "");
- if (this.value === "default") texture.select("image").attr("xlink:href", getDefaultTexture());
- else getBase64(this.value, base64 => texture.select("image").attr("xlink:href", base64));
+styleTextureInput.addEventListener('change', function () {
+ if (this.value === 'none') texture.select('image').attr('xlink:href', '');
+ if (this.value === 'default') texture.select('image').attr('xlink:href', getDefaultTexture());
+ else getBase64(this.value, (base64) => texture.select('image').attr('xlink:href', base64));
});
-styleTextureShiftX.addEventListener("input", function() {
- texture.select("image").attr("x", this.value).attr("width", graphWidth - this.valueAsNumber);
+styleTextureShiftX.addEventListener('input', function () {
+ texture
+ .select('image')
+ .attr('x', this.value)
+ .attr('width', graphWidth - this.valueAsNumber);
});
-styleTextureShiftY.addEventListener("input", function() {
- texture.select("image").attr("y", this.value).attr("height", graphHeight - this.valueAsNumber);
+styleTextureShiftY.addEventListener('input', function () {
+ texture
+ .select('image')
+ .attr('y', this.value)
+ .attr('height', graphHeight - this.valueAsNumber);
});
-styleClippingInput.addEventListener("change", function() {
+styleClippingInput.addEventListener('change', function () {
getEl().attr('mask', this.value);
});
-styleGridType.addEventListener("change", function() {
- getEl().attr("type", this.value);
- if (layerIsOn("toggleGrid")) drawGrid();
+styleGridType.addEventListener('change', function () {
+ getEl().attr('type', this.value);
+ if (layerIsOn('toggleGrid')) drawGrid();
calculateFriendlyGridSize();
});
-styleGridScale.addEventListener("input", function() {
- getEl().attr("scale", this.value);
- if (layerIsOn("toggleGrid")) drawGrid();
+styleGridScale.addEventListener('input', function () {
+ getEl().attr('scale', this.value);
+ if (layerIsOn('toggleGrid')) drawGrid();
calculateFriendlyGridSize();
});
@@ -351,336 +364,354 @@ function calculateFriendlyGridSize() {
styleGridSizeFriendly.value = friendly;
}
-styleGridShiftX.addEventListener("input", function() {
- getEl().attr("dx", this.value);
- if (layerIsOn("toggleGrid")) drawGrid();
+styleGridShiftX.addEventListener('input', function () {
+ getEl().attr('dx', this.value);
+ if (layerIsOn('toggleGrid')) drawGrid();
});
-styleGridShiftY.addEventListener("input", function() {
- getEl().attr("dy", this.value);
- if (layerIsOn("toggleGrid")) drawGrid();
+styleGridShiftY.addEventListener('input', function () {
+ getEl().attr('dy', this.value);
+ if (layerIsOn('toggleGrid')) drawGrid();
});
-styleShiftX.addEventListener("input", shiftElement);
-styleShiftY.addEventListener("input", shiftElement);
+styleShiftX.addEventListener('input', shiftElement);
+styleShiftY.addEventListener('input', shiftElement);
function shiftElement() {
const x = styleShiftX.value || 0;
const y = styleShiftY.value || 0;
- getEl().attr("transform", `translate(${x},${y})`);
+ getEl().attr('transform', `translate(${x},${y})`);
}
-styleRescaleMarkers.addEventListener("change", function() {
- markers.attr("rescale", +this.checked);
+styleRescaleMarkers.addEventListener('change', function () {
+ markers.attr('rescale', +this.checked);
invokeActiveZooming();
});
-styleCoastlineAuto.addEventListener("change", function() {
- coastline.select("#sea_island").attr("auto-filter", +this.checked);
- styleFilter.style.display = this.checked ? "none" : "block";
+styleCoastlineAuto.addEventListener('change', function () {
+ coastline.select('#sea_island').attr('auto-filter', +this.checked);
+ styleFilter.style.display = this.checked ? 'none' : 'block';
invokeActiveZooming();
});
-styleOceanFill.addEventListener("input", function() {
- oceanLayers.select("rect").attr("fill", this.value);
+styleOceanFill.addEventListener('input', function () {
+ oceanLayers.select('rect').attr('fill', this.value);
styleOceanFillOutput.value = this.value;
});
-styleOceanPattern.addEventListener("change", function() {
- document.getElementById("oceanicPattern")?.setAttribute("href", this.value);
+styleOceanPattern.addEventListener('change', function () {
+ document.getElementById('oceanicPattern')?.setAttribute('href', this.value);
});
-styleOceanPatternOpacity.addEventListener("input", function() {
- document.getElementById("oceanPattern").setAttribute("opacity", this.value);
+styleOceanPatternOpacity.addEventListener('input', function () {
+ document.getElementById('oceanPattern').setAttribute('opacity', this.value);
styleOceanPatternOpacityOutput.value = this.value;
});
-outlineLayers.addEventListener("change", function() {
- oceanLayers.selectAll("path").remove();
- oceanLayers.attr("layers", this.value);
+outlineLayers.addEventListener('change', function () {
+ oceanLayers.selectAll('path').remove();
+ oceanLayers.attr('layers', this.value);
OceanLayers();
});
-styleHeightmapScheme.addEventListener("change", function() {
- terrs.attr("scheme", this.value);
+styleHeightmapScheme.addEventListener('change', function () {
+ terrs.attr('scheme', this.value);
drawHeightmap();
});
-styleHeightmapTerracing.addEventListener("input", function() {
+styleHeightmapTerracing.addEventListener('input', function () {
styleHeightmapTerracingOutput.value = this.value;
- terrs.attr("terracing", this.value);
+ terrs.attr('terracing', this.value);
drawHeightmap();
});
-styleHeightmapSkip.addEventListener("input", function() {
+styleHeightmapSkip.addEventListener('input', function () {
styleHeightmapSkipOutput.value = this.value;
- terrs.attr("skip", this.value);
+ terrs.attr('skip', this.value);
drawHeightmap();
});
-styleHeightmapSimplification.addEventListener("input", function() {
+styleHeightmapSimplification.addEventListener('input', function () {
styleHeightmapSimplificationOutput.value = this.value;
- terrs.attr("relax", this.value);
+ terrs.attr('relax', this.value);
drawHeightmap();
});
-styleHeightmapCurve.addEventListener("change", function() {
- terrs.attr("curve", this.value);
+styleHeightmapCurve.addEventListener('change', function () {
+ terrs.attr('curve', this.value);
drawHeightmap();
});
-styleReliefSet.addEventListener("change", function() {
- terrain.attr("set", this.value);
+styleReliefSet.addEventListener('change', function () {
+ terrain.attr('set', this.value);
ReliefIcons();
- if (!layerIsOn("toggleRelief")) toggleRelief();
+ if (!layerIsOn('toggleRelief')) toggleRelief();
});
-styleReliefSizeInput.addEventListener("change", function() {
+styleReliefSizeInput.addEventListener('change', function () {
styleReliefSizeOutput.value = this.value;
const size = +this.value;
- terrain.attr("size", size);
+ terrain.attr('size', size);
- terrain.selectAll("use").each(function(d) {
- const newSize = this.getAttribute("data-size") * size;
- const shift = (newSize - +this.getAttribute("width")) / 2;
- this.setAttribute("width", newSize);
- this.setAttribute("height", newSize);
- const x = +this.getAttribute("x");
- const y = +this.getAttribute("y");
- this.setAttribute("x", x - shift);
- this.setAttribute("y", y - shift);
+ terrain.selectAll('use').each(function (d) {
+ const newSize = this.getAttribute('data-size') * size;
+ const shift = (newSize - +this.getAttribute('width')) / 2;
+ this.setAttribute('width', newSize);
+ this.setAttribute('height', newSize);
+ const x = +this.getAttribute('x');
+ const y = +this.getAttribute('y');
+ this.setAttribute('x', x - shift);
+ this.setAttribute('y', y - shift);
});
});
-styleReliefDensityInput.addEventListener("input", function() {
- terrain.attr("density", this.value);
+styleReliefDensityInput.addEventListener('input', function () {
+ terrain.attr('density', this.value);
styleReliefDensityOutput.value = this.value;
ReliefIcons();
- if (!layerIsOn("toggleRelief")) toggleRelief();
+ if (!layerIsOn('toggleRelief')) toggleRelief();
});
-styleTemperatureFillOpacityInput.addEventListener("input", function() {
- temperature.attr("fill-opacity", this.value);
+styleTemperatureFillOpacityInput.addEventListener('input', function () {
+ temperature.attr('fill-opacity', this.value);
styleTemperatureFillOpacityOutput.value = this.value;
});
-styleTemperatureFontSizeInput.addEventListener("input", function() {
- temperature.attr("font-size", this.value + "px");
- styleTemperatureFontSizeOutput.value = this.value + "px";
+styleTemperatureFontSizeInput.addEventListener('input', function () {
+ temperature.attr('font-size', this.value + 'px');
+ styleTemperatureFontSizeOutput.value = this.value + 'px';
});
-styleTemperatureFillInput.addEventListener("input", function() {
- temperature.attr("fill", this.value);
+styleTemperatureFillInput.addEventListener('input', function () {
+ temperature.attr('fill', this.value);
styleTemperatureFillOutput.value = this.value;
});
-stylePopulationRuralStrokeInput.addEventListener("input", function() {
- population.select("#rural").attr("stroke", this.value);
+stylePopulationRuralStrokeInput.addEventListener('input', function () {
+ population.select('#rural').attr('stroke', this.value);
stylePopulationRuralStrokeOutput.value = this.value;
});
-stylePopulationUrbanStrokeInput.addEventListener("input", function() {
- population.select("#urban").attr("stroke", this.value);
+stylePopulationUrbanStrokeInput.addEventListener('input', function () {
+ population.select('#urban').attr('stroke', this.value);
stylePopulationUrbanStrokeOutput.value = this.value;
});
-styleCompassSizeInput.addEventListener("input", function() {
+styleCompassSizeInput.addEventListener('input', function () {
styleCompassSizeOutput.value = this.value;
shiftCompass();
});
-styleCompassShiftX.addEventListener("input", shiftCompass);
-styleCompassShiftY.addEventListener("input", shiftCompass);
+styleCompassShiftX.addEventListener('input', shiftCompass);
+styleCompassShiftY.addEventListener('input', shiftCompass);
function shiftCompass() {
const tr = `translate(${styleCompassShiftX.value} ${styleCompassShiftY.value}) scale(${styleCompassSizeInput.value})`;
- compass.select("use").attr("transform", tr);
+ compass.select('use').attr('transform', tr);
}
-styleLegendColItems.addEventListener("input", function() {
+styleLegendColItems.addEventListener('input', function () {
styleLegendColItemsOutput.value = this.value;
- legend.select("#legendBox").attr("data-columns", this.value);
+ legend.select('#legendBox').attr('data-columns', this.value);
redrawLegend();
});
-styleLegendBack.addEventListener("input", function() {
+styleLegendBack.addEventListener('input', function () {
styleLegendBackOutput.value = this.value;
- legend.select("#legendBox").attr("fill", this.value);
+ legend.select('#legendBox').attr('fill', this.value);
});
-styleLegendOpacity.addEventListener("input", function() {
+styleLegendOpacity.addEventListener('input', function () {
styleLegendOpacityOutput.value = this.value;
- legend.select("#legendBox").attr("fill-opacity", this.value);
+ legend.select('#legendBox').attr('fill-opacity', this.value);
});
-styleSelectFont.addEventListener("change", changeFont);
+styleSelectFont.addEventListener('change', changeFont);
function changeFont() {
const value = styleSelectFont.value;
- const font = fonts[value].split(':')[0].replace(/\+/g, " ");
- getEl().attr("font-family", font).attr("data-font", fonts[value]);
- if (styleElementSelect.value === "legend") redrawLegend();
+ const font = fonts[value].split(':')[0].replace(/\+/g, ' ');
+ getEl().attr('font-family', font).attr('data-font', fonts[value]);
+ if (styleElementSelect.value === 'legend') redrawLegend();
}
-styleFontAdd.addEventListener("click", function() {
- if (styleInputFont.style.display === "none") {
- styleInputFont.style.display = "inline-block";
+styleFontAdd.addEventListener('click', function () {
+ if (styleInputFont.style.display === 'none') {
+ styleInputFont.style.display = 'inline-block';
styleInputFont.focus();
- styleSelectFont.style.display = "none";
+ styleSelectFont.style.display = 'none';
} else {
- styleInputFont.style.display = "none";
- styleSelectFont.style.display = "inline-block";
+ styleInputFont.style.display = 'none';
+ styleSelectFont.style.display = 'inline-block';
}
});
-styleInputFont.addEventListener("change", function() {
- if (!this.value) {tip("Please provide a valid Google font name or link to a @font-face declaration"); return;}
- fetchFonts(this.value).then(fetched => {
+styleInputFont.addEventListener('change', function () {
+ if (!this.value) {
+ tip('Please provide a valid Google font name or link to a @font-face declaration');
+ return;
+ }
+ fetchFonts(this.value).then((fetched) => {
if (!fetched) return;
styleFontAdd.click();
- styleInputFont.value = "";
+ styleInputFont.value = '';
if (fetched !== 1) return;
- styleSelectFont.value = fonts.length-1;
+ styleSelectFont.value = fonts.length - 1;
changeFont(); // auto-change font if 1 font is fetched
});
});
-styleFontSize.addEventListener("change", function() {
+styleFontSize.addEventListener('change', function () {
changeFontSize(+this.value);
});
-styleFontPlus.addEventListener("click", function() {
- const size = Math.max(rn(getEl().attr("data-size") * 1.1, 2), 1);
+styleFontPlus.addEventListener('click', function () {
+ const size = Math.max(rn(getEl().attr('data-size') * 1.1, 2), 1);
changeFontSize(size);
});
-styleFontMinus.addEventListener("click", function() {
- const size = Math.max(rn(getEl().attr("data-size") * .9, 2), 1);
+styleFontMinus.addEventListener('click', function () {
+ const size = Math.max(rn(getEl().attr('data-size') * 0.9, 2), 1);
changeFontSize(size);
});
function changeFontSize(size) {
- const legend = styleElementSelect.value === "legend";
- const coords = styleElementSelect.value === "coordinates";
+ const legend = styleElementSelect.value === 'legend';
+ const coords = styleElementSelect.value === 'coordinates';
- const desSize = legend ? size : coords ? rn(size / scale ** .8, 2) : rn(size + (size / scale));
- getEl().attr("data-size", size).attr("font-size", desSize);
+ const desSize = legend ? size : coords ? rn(size / scale ** 0.8, 2) : rn(size + size / scale);
+ getEl().attr('data-size', size).attr('font-size', desSize);
styleFontSize.value = size;
if (legend) redrawLegend();
}
-styleRadiusInput.addEventListener("change", function() {
+styleRadiusInput.addEventListener('change', function () {
changeRadius(+this.value);
});
-styleRadiusPlus.addEventListener("click", function() {
- const size = Math.max(rn(getEl().attr("size") * 1.1, 2), .2);
+styleRadiusPlus.addEventListener('click', function () {
+ const size = Math.max(rn(getEl().attr('size') * 1.1, 2), 0.2);
changeRadius(size);
});
-styleRadiusMinus.addEventListener("click", function() {
- const size = Math.max(rn(getEl().attr("size") * .9, 2), .2);
+styleRadiusMinus.addEventListener('click', function () {
+ const size = Math.max(rn(getEl().attr('size') * 0.9, 2), 0.2);
changeRadius(size);
});
function changeRadius(size, group) {
- const el = group ? burgIcons.select("#"+group) : getEl();
- const g = el.attr("id");
- el.attr("size", size)
- el.selectAll("circle").each(function() {this.setAttribute("r", size)});
+ const el = group ? burgIcons.select('#' + group) : getEl();
+ const g = el.attr('id');
+ el.attr('size', size);
+ el.selectAll('circle').each(function () {
+ this.setAttribute('r', size);
+ });
styleRadiusInput.value = size;
- burgLabels.select("g#"+g).selectAll("text").each(function() {this.setAttribute("dy", `${size * -1.5}px`)});
+ burgLabels
+ .select('g#' + g)
+ .selectAll('text')
+ .each(function () {
+ this.setAttribute('dy', `${size * -1.5}px`);
+ });
changeIconSize(size * 2, g); // change also anchor icons
}
-styleIconSizeInput.addEventListener("change", function() {
+styleIconSizeInput.addEventListener('change', function () {
changeIconSize(+this.value);
});
-styleIconSizePlus.addEventListener("click", function() {
- const size = Math.max(rn(getEl().attr("size") * 1.1, 2), .2);
+styleIconSizePlus.addEventListener('click', function () {
+ const size = Math.max(rn(getEl().attr('size') * 1.1, 2), 0.2);
changeIconSize(size);
});
-styleIconSizeMinus.addEventListener("click", function() {
- const size = Math.max(rn(getEl().attr("size") * .9, 2), .2);
+styleIconSizeMinus.addEventListener('click', function () {
+ const size = Math.max(rn(getEl().attr('size') * 0.9, 2), 0.2);
changeIconSize(size);
});
function changeIconSize(size, group) {
- const el = group ? anchors.select("#"+group) : getEl();
- const oldSize = +el.attr("size");
+ const el = group ? anchors.select('#' + group) : getEl();
+ const oldSize = +el.attr('size');
const shift = (size - oldSize) / 2;
- el.attr("size", size);
- el.selectAll("use").each(function() {
- const x = +this.getAttribute("x");
- const y = +this.getAttribute("y");
- this.setAttribute("x", x - shift);
- this.setAttribute("y", y - shift);
- this.setAttribute("width", size);
- this.setAttribute("height", size);
- });;
+ el.attr('size', size);
+ el.selectAll('use').each(function () {
+ const x = +this.getAttribute('x');
+ const y = +this.getAttribute('y');
+ this.setAttribute('x', x - shift);
+ this.setAttribute('y', y - shift);
+ this.setAttribute('width', size);
+ this.setAttribute('height', size);
+ });
styleIconSizeInput.value = size;
}
-styleStatesHaloWidth.addEventListener("input", function() {
+styleStatesHaloWidth.addEventListener('input', function () {
styleStatesHaloWidthOutput.value = this.value;
- statesHalo.attr("data-width", this.value).attr("stroke-width", this.value);
+ statesHalo.attr('data-width', this.value).attr('stroke-width', this.value);
});
-styleStatesHaloOpacity.addEventListener("input", function() {
+styleStatesHaloOpacity.addEventListener('input', function () {
styleStatesHaloOpacityOutput.value = this.value;
- statesHalo.attr("opacity", this.value);
+ statesHalo.attr('opacity', this.value);
});
-styleArmiesFillOpacity.addEventListener("input", function() {
- armies.attr("fill-opacity", this.value);
+styleArmiesFillOpacity.addEventListener('input', function () {
+ armies.attr('fill-opacity', this.value);
styleArmiesFillOpacityOutput.value = this.value;
});
-styleArmiesSize.addEventListener("input", function() {
- armies.attr("box-size", this.value).attr("font-size", this.value*2);
+styleArmiesSize.addEventListener('input', function () {
+ armies.attr('box-size', this.value).attr('font-size', this.value * 2);
styleArmiesSizeOutput.value = this.value;
- armies.selectAll("g").remove(); // clear armies layer
- pack.states.forEach(s => {
+ armies.selectAll('g').remove(); // clear armies layer
+ pack.states.forEach((s) => {
if (!s.i || s.removed || !s.military.length) return;
Military.drawRegiments(s.military, s.i);
});
});
-styleEmblemsStateSizeInput.addEventListener("input", drawEmblems);
-styleEmblemsProvinceSizeInput.addEventListener("input", drawEmblems);
-styleEmblemsBurgSizeInput.addEventListener("input", drawEmblems);
+styleEmblemsStateSizeInput.addEventListener('input', drawEmblems);
+styleEmblemsProvinceSizeInput.addEventListener('input', drawEmblems);
+styleEmblemsBurgSizeInput.addEventListener('input', drawEmblems);
// request a URL to image to be used as a texture
function textureProvideURL() {
alertMessage.innerHTML = `Provide an image URL to be used as a texture:
`;
- $("#alert").dialog({resizable: false, title: "Load custom texture", width: "26em",
+ $('#alert').dialog({
+ resizable: false,
+ title: 'Load custom texture',
+ width: '26em',
buttons: {
- Apply: function() {
- const name = textureURL.value.split("/").pop();
- if (!name || name === "") {tip("Please provide a valid URL", false, "error"); return;}
- const opt = document.createElement("option");
+ Apply: function () {
+ const name = textureURL.value.split('/').pop();
+ if (!name || name === '') {
+ tip('Please provide a valid URL', false, 'error');
+ return;
+ }
+ const opt = document.createElement('option');
opt.value = textureURL.value;
opt.text = name.slice(0, 20);
styleTextureInput.add(opt);
styleTextureInput.value = textureURL.value;
- getBase64(textureURL.value, base64 => texture.select("image").attr("xlink:href", base64));
+ getBase64(textureURL.value, (base64) => texture.select('image').attr('xlink:href', base64));
zoom.scaleBy(svg, 1.00001); // enforce browser re-draw
- $(this).dialog("close");
+ $(this).dialog('close');
},
- Cancel: function() {$(this).dialog("close");}
+ Cancel: function () {
+ $(this).dialog('close');
+ }
}
});
}
function fetchTextureURL(url) {
- INFO && console.log("Provided URL is", url);
+ INFO && console.log('Provided URL is', url);
const img = new Image();
img.onload = function () {
- const canvas = document.getElementById("texturePreview");
- const ctx = canvas.getContext("2d");
+ const canvas = document.getElementById('texturePreview');
+ const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
@@ -692,11 +723,11 @@ const defaultStyles = {
styleGloom: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":"url(#land)"},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":""},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.3,"stroke-dasharray":".7 1","stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":14,"font-size":14,"stroke":"#4a4a4a","stroke-width":1,"stroke-dasharray":6,"stroke-linecap":null,"filter":"","mask":""},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(100 100) scale(0.3)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":1,"filter":null},"#cults":{"opacity":0.7,"stroke":"#777777","stroke-width":1.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e0e0e0","filter":null},"#markers":{"opacity":0.8,"rescale":1,"filter":"url(#dropShadow05)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000aa"},"#urban":{"stroke":"#9d0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.9,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":"","fill":"#779582"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":1,"stroke":"#8b4418","stroke-width":0.9,"stroke-dasharray":"2 3","stroke-linecap":"round","filter":"","mask":null},"#trails":{"opacity":1,"stroke":"#844017","stroke-width":0.2,"stroke-dasharray":".5 1","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#5e1865","stroke-width":0.6,"stroke-dasharray":"1.2 2.4","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"opacity":0.4,"filter":"url(#dropShadow)"},"#statesHalo":{"opacity":1,"data-width":10.2,"stroke-width":10.2},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":1,"font-size":"11px","fill":"#62001b","fill-opacity":0.3,"stroke":null,"stroke-width":2,"stroke-dasharray":2,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#emblems": {"opacity":0.6,"stroke-width":0.5,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.5,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":"url(#dropShadow01)","mask":null},"#ocean":{"opacity":1},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#4e6964"},"#oceanPattern":{"opacity":0.2},"#oceanicPattern":{"href":"./images/pattern3.jpg"},"#terrs":{"opacity":1,"scheme":"bright","terracing":0,"skip":0,"relax":1,"curve":1,"filter":"url(#filter-grayscale)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","data-size":7,"font-size":7,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":2,"stroke":"#444444","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":0.8,"fill":"#ffffff","size":4,"stroke":"#3e3e4b","stroke-width":1},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":3,"font-size":3,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #towns":{"opacity":0.95,"fill":"#ffffff","fill-opacity":0.7,"size":0.8,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1.6,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#4e4e4e","stroke":"#b5b5b5","stroke-width":0,"data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":""},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#1b1423","filter":null}}`,
styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":""},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":"","auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#regions":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0,"data-width":null,"stroke-width":0},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#ocean":{"opacity":null},"#oceanLayers":{"filter":"","layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanPattern":{"opacity":0.2},"#oceanicPattern":{"href":""},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":"","mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`,
styleMonochrome: `{"#map":{"background-color":"#000000","filter":"url(#filter-grayscale)","data-filter":"grayscale"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":null},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.4,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#000000","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#000000","stroke":"#515151","stroke-width":0,"filter":null},"#salt":{"opacity":1,"fill":"#000000","stroke":"#484848","stroke-width":0,"filter":null},"#sinkhole":{"opacity":1,"fill":"#000000","stroke":"#5f5f5f","stroke-width":0.5,"filter":null},"#frozen":{"opacity":1,"fill":"#000000","stroke":"#6f6f6f","stroke-width":0,"filter":null},"#lava":{"opacity":1,"fill":"#000000","stroke":"#5d5d5d","stroke-width":0,"filter":""},"#sea_island":{"opacity":1,"stroke":"#1f3846","stroke-width":0,"filter":"","auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":0.2,"filter":"url(#blur1)","fill":"#000000"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.7,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.25,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":1,"data-width":10,"stroke-width":10},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#texture":{"opacity":1,"filter":null,"mask":"url(#land)"},"#emblems": {"opacity": 0.5,"stroke-width": 0.5,"filter": null},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#ocean":{"opacity":0},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#000000"},"#oceanPattern":{"opacity":0.2},"#oceanicPattern":{"href":""},"#terrs":{"opacity":1,"scheme":"monochrome","terracing":0,"skip":5,"relax":0,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","data-size":7,"font-size":7,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`
-}
+};
// apply default or custom style settings on load
function applyStyleOnLoad() {
- const preset = localStorage.getItem("presetStyle");
+ const preset = localStorage.getItem('presetStyle');
const style = preset && (defaultStyles[preset] || localStorage.getItem(preset));
if (preset && style && JSON.isValid(style)) {
@@ -706,8 +737,8 @@ function applyStyleOnLoad() {
stylePreset.value = preset;
stylePreset.dataset.old = preset;
} else {
- if (preset && preset !== "styleDefault" && ERROR) console.error(`Style preset ${preset} is not available in localStorage, applying default style`);
- stylePreset.value = "styleDefault";
+ if (preset && preset !== 'styleDefault' && ERROR) console.error(`Style preset ${preset} is not available in localStorage, applying default style`);
+ stylePreset.value = 'styleDefault';
stylePreset.dataset.old = preset;
applyDefaultStyle();
}
@@ -715,90 +746,161 @@ function applyStyleOnLoad() {
// set default style
function applyDefaultStyle() {
- armies.attr("opacity", 1).attr("fill-opacity", 1).attr("font-size", 6).attr("box-size", 3).attr("stroke", "#000").attr("stroke-width", .3);
+ armies.attr('opacity', 1).attr('fill-opacity', 1).attr('font-size', 6).attr('box-size', 3).attr('stroke', '#000').attr('stroke-width', 0.3);
- biomes.attr("opacity", null).attr("filter", null).attr("mask", null);
- ice.attr("opacity", .9).attr("fill", "#e8f0f6").attr("stroke", "#e8f0f6").attr("stroke-width", 1).attr("filter", "url(#dropShadow05)");
- stateBorders.attr("opacity", .8).attr("stroke", "#56566d").attr("stroke-width", 1).attr("stroke-dasharray", "2").attr("stroke-linecap", "butt").attr("filter", null);
- provinceBorders.attr("opacity", .8).attr("stroke", "#56566d").attr("stroke-width", .5).attr("stroke-dasharray", "0 2").attr("stroke-linecap", "round").attr("filter", null);
- cells.attr("opacity", null).attr("stroke", "#808080").attr("stroke-width", .1).attr("filter", null).attr("mask", null);
+ biomes.attr('opacity', null).attr('filter', null).attr('mask', null);
+ ice.attr('opacity', 0.9).attr('fill', '#e8f0f6').attr('stroke', '#e8f0f6').attr('stroke-width', 1).attr('filter', 'url(#dropShadow05)');
+ stateBorders.attr('opacity', 0.8).attr('stroke', '#56566d').attr('stroke-width', 1).attr('stroke-dasharray', '2').attr('stroke-linecap', 'butt').attr('filter', null);
+ provinceBorders.attr('opacity', 0.8).attr('stroke', '#56566d').attr('stroke-width', 0.5).attr('stroke-dasharray', '0 2').attr('stroke-linecap', 'round').attr('filter', null);
+ cells.attr('opacity', null).attr('stroke', '#808080').attr('stroke-width', 0.1).attr('filter', null).attr('mask', null);
- gridOverlay.attr("opacity", .8).attr("type", "pointyHex").attr("scale", 1).attr("dx", 0).attr("dy", 0).attr("stroke", "#777777").attr("stroke-width", .5).attr("stroke-dasharray", null).attr("filter", null).attr("mask", null);
- coordinates.attr("opacity", 1).attr("data-size", 12).attr("font-size", 12).attr("stroke", "#d4d4d4").attr("stroke-width", 1).attr("stroke-dasharray", 5).attr("filter", null).attr("mask", null);
- compass.attr("opacity", .8).attr("transform", null).attr("filter", null).attr("mask", "url(#water)").attr("shape-rendering", "optimizespeed");
- if (!d3.select("#initial").size()) d3.select("#rose").attr("transform", "translate(80 80) scale(.25)");
+ gridOverlay
+ .attr('opacity', 0.8)
+ .attr('type', 'pointyHex')
+ .attr('scale', 1)
+ .attr('dx', 0)
+ .attr('dy', 0)
+ .attr('stroke', '#777777')
+ .attr('stroke-width', 0.5)
+ .attr('stroke-dasharray', null)
+ .attr('filter', null)
+ .attr('mask', null);
+ coordinates.attr('opacity', 1).attr('data-size', 12).attr('font-size', 12).attr('stroke', '#d4d4d4').attr('stroke-width', 1).attr('stroke-dasharray', 5).attr('filter', null).attr('mask', null);
+ compass.attr('opacity', 0.8).attr('transform', null).attr('filter', null).attr('mask', 'url(#water)').attr('shape-rendering', 'optimizespeed');
+ if (!d3.select('#initial').size()) d3.select('#rose').attr('transform', 'translate(80 80) scale(.25)');
- relig.attr("opacity", .7).attr("stroke", "#777777").attr("stroke-width", 0).attr("filter", null);
- cults.attr("opacity", .6).attr("stroke", "#777777").attr("stroke-width", .5).attr("filter", null);
- landmass.attr("opacity", 1).attr("fill", "#eef6fb").attr("filter", null);
- markers.attr("opacity", null).attr("rescale", 1).attr("filter", "url(#dropShadow01)");
+ relig.attr('opacity', 0.7).attr('stroke', '#777777').attr('stroke-width', 0).attr('filter', null);
+ cults.attr('opacity', 0.6).attr('stroke', '#777777').attr('stroke-width', 0.5).attr('filter', null);
+ landmass.attr('opacity', 1).attr('fill', '#eef6fb').attr('filter', null);
+ markers.attr('opacity', null).attr('rescale', 1).attr('filter', 'url(#dropShadow01)');
- prec.attr("opacity", null).attr("stroke", "#000000").attr("stroke-width", .1).attr("fill", "#003dff").attr("filter", null);
- population.attr("opacity", null).attr("stroke-width", 1.6).attr("stroke-dasharray", null).attr("stroke-linecap", "butt").attr("filter", null);
- population.select("#rural").attr("stroke", "#0000ff");
- population.select("#urban").attr("stroke", "#ff0000");
+ prec.attr('opacity', null).attr('stroke', '#000000').attr('stroke-width', 0.1).attr('fill', '#003dff').attr('filter', null);
+ population.attr('opacity', null).attr('stroke-width', 1.6).attr('stroke-dasharray', null).attr('stroke-linecap', 'butt').attr('filter', null);
+ population.select('#rural').attr('stroke', '#0000ff');
+ population.select('#urban').attr('stroke', '#ff0000');
- lakes.select("#freshwater").attr("opacity", .5).attr("fill", "#a6c1fd").attr("stroke", "#5f799d").attr("stroke-width", .7).attr("filter", null);
- lakes.select("#salt").attr("opacity", .5).attr("fill", "#409b8a").attr("stroke", "#388985").attr("stroke-width", .7).attr("filter", null);
- lakes.select("#sinkhole").attr("opacity", 1).attr("fill", "#5bc9fd").attr("stroke", "#53a3b0").attr("stroke-width", .7).attr("filter", null);
- lakes.select("#frozen").attr("opacity", .95).attr("fill", "#cdd4e7").attr("stroke", "#cfe0eb").attr("stroke-width", 0).attr("filter", null);
- lakes.select("#lava").attr("opacity", .7).attr("fill", "#90270d").attr("stroke", "#f93e0c").attr("stroke-width", 2).attr("filter", "url(#crumpled)");
- lakes.select("#dry").attr("opacity", 1).attr("fill", "#c9bfa7").attr("stroke", "#8e816f").attr("stroke-width", .7).attr("filter", null);
+ lakes.select('#freshwater').attr('opacity', 0.5).attr('fill', '#a6c1fd').attr('stroke', '#5f799d').attr('stroke-width', 0.7).attr('filter', null);
+ lakes.select('#salt').attr('opacity', 0.5).attr('fill', '#409b8a').attr('stroke', '#388985').attr('stroke-width', 0.7).attr('filter', null);
+ lakes.select('#sinkhole').attr('opacity', 1).attr('fill', '#5bc9fd').attr('stroke', '#53a3b0').attr('stroke-width', 0.7).attr('filter', null);
+ lakes.select('#frozen').attr('opacity', 0.95).attr('fill', '#cdd4e7').attr('stroke', '#cfe0eb').attr('stroke-width', 0).attr('filter', null);
+ lakes.select('#lava').attr('opacity', 0.7).attr('fill', '#90270d').attr('stroke', '#f93e0c').attr('stroke-width', 2).attr('filter', 'url(#crumpled)');
+ lakes.select('#dry').attr('opacity', 1).attr('fill', '#c9bfa7').attr('stroke', '#8e816f').attr('stroke-width', 0.7).attr('filter', null);
- coastline.select("#sea_island").attr("opacity", .5).attr("stroke", "#1f3846").attr("stroke-width", .7).attr("auto-filter", 1).attr("filter", "url(#dropShadow)");
- coastline.select("#lake_island").attr("opacity", 1).attr("stroke", "#7c8eaf").attr("stroke-width", .35).attr("filter", null);
+ coastline.select('#sea_island').attr('opacity', 0.5).attr('stroke', '#1f3846').attr('stroke-width', 0.7).attr('auto-filter', 1).attr('filter', 'url(#dropShadow)');
+ coastline.select('#lake_island').attr('opacity', 1).attr('stroke', '#7c8eaf').attr('stroke-width', 0.35).attr('filter', null);
- terrain.attr("opacity", null).attr("set", "simple").attr("size", 1).attr("density", .4).attr("filter", null).attr("mask", null);
- rivers.attr("opacity", null).attr("fill", "#5d97bb").attr("filter", null);
- ruler.attr("opacity", null).attr("filter", null);
+ terrain.attr('opacity', null).attr('set', 'simple').attr('size', 1).attr('density', 0.4).attr('filter', null).attr('mask', null);
+ rivers.attr('opacity', null).attr('fill', '#5d97bb').attr('filter', null);
+ ruler.attr('opacity', null).attr('filter', null);
- roads.attr("opacity", .9).attr("stroke", "#d06324").attr("stroke-width", .7).attr("stroke-dasharray", "2").attr("stroke-linecap", "butt").attr("filter", null).attr("mask", null);
- trails.attr("opacity", .9).attr("stroke", "#d06324").attr("stroke-width", .25).attr("stroke-dasharray", ".8 1.6").attr("stroke-linecap", "butt").attr("filter", null).attr("mask", null);
- searoutes.attr("opacity", .8).attr("stroke", "#ffffff").attr("stroke-width", .45).attr("stroke-dasharray", "1 2").attr("stroke-linecap", "round").attr("filter", null).attr("mask", null);
+ roads.attr('opacity', 0.9).attr('stroke', '#d06324').attr('stroke-width', 0.7).attr('stroke-dasharray', '2').attr('stroke-linecap', 'butt').attr('filter', null).attr('mask', null);
+ trails.attr('opacity', 0.9).attr('stroke', '#d06324').attr('stroke-width', 0.25).attr('stroke-dasharray', '.8 1.6').attr('stroke-linecap', 'butt').attr('filter', null).attr('mask', null);
+ searoutes.attr('opacity', 0.8).attr('stroke', '#ffffff').attr('stroke-width', 0.45).attr('stroke-dasharray', '1 2').attr('stroke-linecap', 'round').attr('filter', null).attr('mask', null);
- regions.attr("opacity", .4).attr("filter", null);
- statesHalo.attr("data-width", 10).attr("stroke-width", 10).attr("opacity", 1);
- provs.attr("opacity", .7).attr("fill", "#000000").attr("font-family", "Georgia").attr("data-font", "Georgia").attr("data-size", 10).attr("font-size", 10).attr("filter", null);
+ regions.attr('opacity', 0.4).attr('filter', null);
+ statesHalo.attr('data-width', 10).attr('stroke-width', 10).attr('opacity', 1);
+ provs.attr('opacity', 0.7).attr('fill', '#000000').attr('font-family', 'Georgia').attr('data-font', 'Georgia').attr('data-size', 10).attr('font-size', 10).attr('filter', null);
- temperature.attr("opacity", null).attr("fill", "#000000").attr("stroke-width", 1.8).attr("fill-opacity", .3).attr("font-size", "8px").attr("stroke-dasharray", null).attr("filter", null).attr("mask", null);
- texture.attr("opacity", null).attr("filter", null).attr("mask", "url(#land)");
- texture.select("#textureImage").attr("x", 0).attr("y", 0);
- zones.attr("opacity", .6).attr("stroke", "#333333").attr("stroke-width", 0).attr("stroke-dasharray", null).attr("stroke-linecap", "butt").attr("filter", null).attr("mask", null);
+ temperature
+ .attr('opacity', null)
+ .attr('fill', '#000000')
+ .attr('stroke-width', 1.8)
+ .attr('fill-opacity', 0.3)
+ .attr('font-size', '8px')
+ .attr('stroke-dasharray', null)
+ .attr('filter', null)
+ .attr('mask', null);
+ texture.attr('opacity', null).attr('filter', null).attr('mask', 'url(#land)');
+ texture.select('#textureImage').attr('x', 0).attr('y', 0);
+ zones.attr('opacity', 0.6).attr('stroke', '#333333').attr('stroke-width', 0).attr('stroke-dasharray', null).attr('stroke-linecap', 'butt').attr('filter', null).attr('mask', null);
// ocean and svg default style
- svg.attr("background-color", "#000000").attr("data-filter", null).attr("filter", null);
- oceanLayers.select("rect").attr("fill", "#466eab"); // old color #53679f
- oceanLayers.attr("filter", null).attr("layers", "-6,-3,-1");
- oceanPattern.attr("opacity", .2);
- svg.select("#oceanicPattern").attr("href", "./images/pattern1.png");
+ svg.attr('background-color', '#000000').attr('data-filter', null).attr('filter', null);
+ oceanLayers.select('rect').attr('fill', '#466eab'); // old color #53679f
+ oceanLayers.attr('filter', null).attr('layers', '-6,-3,-1');
+ oceanPattern.attr('opacity', 0.2);
+ svg.select('#oceanicPattern').attr('href', './images/pattern1.png');
// heightmap style
- terrs.attr("opacity", null).attr("filter", null).attr("mask", "url(#land)").attr("stroke", "none")
- .attr("scheme", "bright").attr("terracing", 0).attr("skip", 5).attr("relax", 0).attr("curve", 0);
+ terrs.attr('opacity', null).attr('filter', null).attr('mask', 'url(#land)').attr('stroke', 'none').attr('scheme', 'bright').attr('terracing', 0).attr('skip', 5).attr('relax', 0).attr('curve', 0);
// legend
- legend.attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", 13).attr("data-size", 13)
- .attr("data-x", 99).attr("data-y", 93).attr("data-columns", 8)
- .attr("stroke-width", 2.5).attr("stroke", "#812929").attr("stroke-dasharray", "0 4 10 4").attr("stroke-linecap", "round");
- legend.select("#legendBox").attr("fill", "#ffffff").attr("fill-opacity", .8);
+ legend
+ .attr('font-family', 'Almendra SC')
+ .attr('data-font', 'Almendra+SC')
+ .attr('font-size', 13)
+ .attr('data-size', 13)
+ .attr('data-x', 99)
+ .attr('data-y', 93)
+ .attr('data-columns', 8)
+ .attr('stroke-width', 2.5)
+ .attr('stroke', '#812929')
+ .attr('stroke-dasharray', '0 4 10 4')
+ .attr('stroke-linecap', 'round');
+ legend.select('#legendBox').attr('fill', '#ffffff').attr('fill-opacity', 0.8);
const citiesSize = Math.max(rn(8 - regionsInput.value / 20), 3);
- burgLabels.select("#cities").attr("fill", "#3e3e4b").attr("opacity", 1).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", citiesSize).attr("data-size", citiesSize);
- burgIcons.select("#cities").attr("opacity", 1).attr("size", 1).attr("stroke-width", .24).attr("fill", "#ffffff").attr("stroke", "#3e3e4b").attr("fill-opacity", .7).attr("stroke-dasharray", "").attr("stroke-linecap", "butt");
- anchors.select("#cities").attr("opacity", 1).attr("fill", "#ffffff").attr("stroke", "#3e3e4b").attr("stroke-width", 1.2).attr("size", 2);
+ burgLabels
+ .select('#cities')
+ .attr('fill', '#3e3e4b')
+ .attr('opacity', 1)
+ .attr('font-family', 'Almendra SC')
+ .attr('data-font', 'Almendra+SC')
+ .attr('font-size', citiesSize)
+ .attr('data-size', citiesSize);
+ burgIcons
+ .select('#cities')
+ .attr('opacity', 1)
+ .attr('size', 1)
+ .attr('stroke-width', 0.24)
+ .attr('fill', '#ffffff')
+ .attr('stroke', '#3e3e4b')
+ .attr('fill-opacity', 0.7)
+ .attr('stroke-dasharray', '')
+ .attr('stroke-linecap', 'butt');
+ anchors.select('#cities').attr('opacity', 1).attr('fill', '#ffffff').attr('stroke', '#3e3e4b').attr('stroke-width', 1.2).attr('size', 2);
- burgLabels.select("#towns").attr("fill", "#3e3e4b").attr("opacity", 1).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", 3).attr("data-size", 4);
- burgIcons.select("#towns").attr("opacity", 1).attr("size", .5).attr("stroke-width", .12).attr("fill", "#ffffff").attr("stroke", "#3e3e4b").attr("fill-opacity", .7).attr("stroke-dasharray", "").attr("stroke-linecap", "butt");
- anchors.select("#towns").attr("opacity", 1).attr("fill", "#ffffff").attr("stroke", "#3e3e4b").attr("stroke-width", 1.2).attr("size", 1);
+ burgLabels.select('#towns').attr('fill', '#3e3e4b').attr('opacity', 1).attr('font-family', 'Almendra SC').attr('data-font', 'Almendra+SC').attr('font-size', 3).attr('data-size', 4);
+ burgIcons
+ .select('#towns')
+ .attr('opacity', 1)
+ .attr('size', 0.5)
+ .attr('stroke-width', 0.12)
+ .attr('fill', '#ffffff')
+ .attr('stroke', '#3e3e4b')
+ .attr('fill-opacity', 0.7)
+ .attr('stroke-dasharray', '')
+ .attr('stroke-linecap', 'butt');
+ anchors.select('#towns').attr('opacity', 1).attr('fill', '#ffffff').attr('stroke', '#3e3e4b').attr('stroke-width', 1.2).attr('size', 1);
const stateLabelSize = Math.max(rn(24 - regionsInput.value / 6), 6);
- labels.select("#states").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", stateLabelSize).attr("data-size", stateLabelSize).attr("filter", null);
- labels.select("#addedLabels").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", 18).attr("data-size", 18).attr("filter", null);
+ labels
+ .select('#states')
+ .attr('fill', '#3e3e4b')
+ .attr('opacity', 1)
+ .attr('stroke', '#3a3a3a')
+ .attr('stroke-width', 0)
+ .attr('font-family', 'Almendra SC')
+ .attr('data-font', 'Almendra+SC')
+ .attr('font-size', stateLabelSize)
+ .attr('data-size', stateLabelSize)
+ .attr('filter', null);
+ labels
+ .select('#addedLabels')
+ .attr('fill', '#3e3e4b')
+ .attr('opacity', 1)
+ .attr('stroke', '#3a3a3a')
+ .attr('stroke-width', 0)
+ .attr('font-family', 'Almendra SC')
+ .attr('data-font', 'Almendra+SC')
+ .attr('font-size', 18)
+ .attr('data-size', 18)
+ .attr('filter', null);
- fogging.attr("opacity", .98).attr("fill", "#30426f");
- emblems.attr("opacity", .9).attr("stroke-width", 1).attr("filter", null);
+ fogging.attr('opacity', 0.98).attr('fill', '#30426f');
+ emblems.attr('opacity', 0.9).attr('stroke-width', 1).attr('filter', null);
- goods.attr("opacity", 1).attr("fill", "#000").attr("stroke", "#000").attr("stroke-width", .32).attr("filter", "url(#dropShadow01)");
+ goods.attr('opacity', 1).attr('fill', '#000').attr('stroke', '#000').attr('stroke-width', 0.32).attr('filter', 'url(#dropShadow01)');
}
// apply style settings in JSON
@@ -808,7 +910,7 @@ function applyStyle(style) {
if (!el) continue;
for (const attribute in style[selector]) {
const value = style[selector][attribute];
- if (value === "null" || value === null) el.removeAttribute(attribute);
+ if (value === 'null' || value === null) el.removeAttribute(attribute);
else el.setAttribute(attribute, value);
}
}
@@ -816,70 +918,76 @@ function applyStyle(style) {
// change current style preset to another saved one
function changeStylePreset(preset) {
- if (customization) {tip("Please exit the customization mode first", false, "error"); return;}
- alertMessage.innerHTML = "Are you sure you want to change the style preset? All unsaved style changes will be lost";
- $("#alert").dialog({resizable: false, title: "Change style preset", width: "23em",
- buttons: {
- Change: function() {
- const customPreset = localStorage.getItem(preset);
- if (customPreset) {
- if (JSON.isValid(customPreset)) applyStyle(JSON.parse(customPreset));
- else {
- tip("Cannot parse stored style JSON. Default style applied", false, "error", 5000);
- applyDefaultStyle();
- }
- } else if (defaultStyles[preset]) applyStyle(JSON.parse(defaultStyles[preset]));
- else applyDefaultStyle();
+ if (customization) return tip('Please exit the customization mode first', false, 'error');
- removeStyleButton.style.display = stylePreset.selectedOptions[0].dataset.system ? "none" : "inline-block";
- updateElements(); // change elements
- selectStyleElement(); // re-select element to trigger values update
- updateMapFilter();
- localStorage.setItem("presetStyle", preset); // save preset to use it onload
- stylePreset.dataset.old = stylePreset.value; // save current value
- $(this).dialog("close");
- },
- Cancel: function() {
- stylePreset.value = stylePreset.dataset.old;
- $(this).dialog("close");
+ const message = 'Are you sure you want to change the style preset?
All unsaved style changes will be lost';
+ const onConfirm = () => {
+ const customPreset = localStorage.getItem(preset);
+ if (customPreset) {
+ if (JSON.isValid(customPreset)) applyStyle(JSON.parse(customPreset));
+ else {
+ tip('Cannot parse stored style JSON. Default style applied', false, 'error', 5000);
+ applyDefaultStyle();
}
- }
- });
+ } else if (defaultStyles[preset]) applyStyle(JSON.parse(defaultStyles[preset]));
+ else applyDefaultStyle();
+
+ removeStyleButton.style.display = stylePreset.selectedOptions[0].dataset.system ? 'none' : 'inline-block';
+ updateElements(); // change elements
+ selectStyleElement(); // re-select element to trigger values update
+ updateMapFilter();
+ localStorage.setItem('presetStyle', preset); // save preset to use it onload
+ stylePreset.dataset.old = stylePreset.value; // save current value
+ };
+ confirmationDialog({title: 'Change style preset', message, confirm: 'Change', onConfirm});
}
function updateElements() {
// burgIcons to desired size
- burgIcons.selectAll("g").each(function(d) {
- const size = +this.getAttribute("size");
- d3.select(this).selectAll("circle").each(function() {this.setAttribute("r", size)});
- burgLabels.select("g#"+this.id).selectAll("text").each(function() {this.setAttribute("dy", `${size * -1.5}px`)});
+ burgIcons.selectAll('g').each(function (d) {
+ const size = +this.getAttribute('size');
+ d3.select(this)
+ .selectAll('circle')
+ .each(function () {
+ this.setAttribute('r', size);
+ });
+ burgLabels
+ .select('g#' + this.id)
+ .selectAll('text')
+ .each(function () {
+ this.setAttribute('dy', `${size * -1.5}px`);
+ });
});
// anchor icons to desired size
- anchors.selectAll("g").each(function(d) {
- const size = +this.getAttribute("size");
- d3.select(this).selectAll("use").each(function() {
- const id = +this.dataset.id;
- const x = pack.burgs[id].x, y = pack.burgs[id].y;
- this.setAttribute("x", rn(x - size * .47, 2));
- this.setAttribute("y", rn(y- size * .47, 2));
- this.setAttribute("width", size);
- this.setAttribute("height", size);
- });
+ anchors.selectAll('g').each(function (d) {
+ const size = +this.getAttribute('size');
+ d3.select(this)
+ .selectAll('use')
+ .each(function () {
+ const id = +this.dataset.id;
+ const x = pack.burgs[id].x,
+ y = pack.burgs[id].y;
+ this.setAttribute('x', rn(x - size * 0.47, 2));
+ this.setAttribute('y', rn(y - size * 0.47, 2));
+ this.setAttribute('width', size);
+ this.setAttribute('height', size);
+ });
});
// redraw elements
- if (layerIsOn("toggleHeight")) drawHeightmap();
- if (legend.selectAll("*").size() && window.redrawLegend) redrawLegend();
- oceanLayers.selectAll("path").remove();
+ if (layerIsOn('toggleHeight')) drawHeightmap();
+ if (legend.selectAll('*').size() && window.redrawLegend) redrawLegend();
+ oceanLayers.selectAll('path').remove();
OceanLayers();
invokeActiveZooming();
}
function addStylePreset() {
- $("#styleSaver").dialog({
- title: "Style Saver", width: "26em",
- position: {my: "center", at: "center", of: "svg"}
+ $('#styleSaver').dialog({
+ title: 'Style Saver',
+ width: '26em',
+ position: {my: 'center', at: 'center', of: 'svg'}
});
styleSaverJSON.value = JSON.stringify(getStyle(), null, 2);
@@ -889,243 +997,301 @@ function addStylePreset() {
modules.saveStyle = true;
// add listeners
- document.getElementById("styleSaverName").addEventListener("input", checkName);
- document.getElementById("styleSaverSave").addEventListener("click", saveStyle);
- document.getElementById("styleSaverDownload").addEventListener("click", styleDownload);
- document.getElementById("styleSaverLoad").addEventListener("click", () => styleToLoad.click());
- document.getElementById("styleToLoad").addEventListener("change", function() {uploadFile(this, styleUpload)});
+ document.getElementById('styleSaverName').addEventListener('input', checkName);
+ document.getElementById('styleSaverSave').addEventListener('click', saveStyle);
+ document.getElementById('styleSaverDownload').addEventListener('click', styleDownload);
+ document.getElementById('styleSaverLoad').addEventListener('click', () => styleToLoad.click());
+ document.getElementById('styleToLoad').addEventListener('change', function () {
+ uploadFile(this, styleUpload);
+ });
function getStyle() {
- const style = {}, attributes = {
- "#map":["background-color", "filter", "data-filter"],
- "#armies":["font-size","box-size","stroke","stroke-width","fill-opacity","filter"],
- "#biomes":["opacity", "filter", "mask"],
- "#stateBorders":["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
- "#provinceBorders":["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
- "#cells":["opacity", "stroke", "stroke-width", "filter", "mask"],
- "#gridOverlay":["opacity", "scale", "dx", "dy", "type", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "transform", "filter", "mask"],
- "#coordinates":["opacity", "data-size", "font-size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"],
- "#compass":["opacity", "transform", "filter", "mask", "shape-rendering"],
- "#rose":["transform"],
- "#relig":["opacity", "stroke", "stroke-width", "filter"],
- "#cults":["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
- "#landmass":["opacity", "fill", "filter"],
- "#markers":["opacity", "rescale", "filter"],
- "#prec":["opacity", "stroke", "stroke-width", "fill", "filter"],
- "#population":["opacity", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
- "#rural":["stroke"],
- "#urban":["stroke"],
- "#freshwater":["opacity", "fill", "stroke", "stroke-width", "filter"],
- "#salt":["opacity", "fill", "stroke", "stroke-width", "filter"],
- "#sinkhole":["opacity", "fill", "stroke", "stroke-width", "filter"],
- "#frozen":["opacity", "fill", "stroke", "stroke-width", "filter"],
- "#lava":["opacity", "fill", "stroke", "stroke-width", "filter"],
- "#dry":["opacity", "fill", "stroke", "stroke-width", "filter"],
- "#sea_island":["opacity", "stroke", "stroke-width", "filter", "auto-filter"],
- "#lake_island":["opacity", "stroke", "stroke-width", "filter"],
- "#terrain":["opacity", "set", "size", "density", "filter", "mask"],
- "#rivers":["opacity", "filter", "fill"],
- "#ruler":["opacity", "filter"],
- "#roads":["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"],
- "#trails":["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"],
- "#searoutes":["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"],
- "#regions":["opacity", "filter"],
- "#statesHalo":["opacity", "data-width", "stroke-width"],
- "#provs":["opacity", "fill", "font-size", "data-font", "font-family", "filter"],
- "#temperature":["opacity", "font-size", "fill", "fill-opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
- "#ice":["opacity", "fill", "stroke", "stroke-width", "filter"],
- "#emblems":["opacity", "stroke-width", "filter"],
- "#texture":["opacity", "filter", "mask"],
- "#textureImage":["x", "y"],
- "#zones":["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"],
- "#oceanLayers":["filter", "layers"],
- "#oceanBase":["fill"],
- "#oceanPattern":["opacity"],
- "#oceanicPattern":["href"],
- "#terrs":["opacity", "scheme", "terracing", "skip", "relax", "curve", "filter", "mask"],
- "#legend":["data-size", "font-size", "data-font", "font-family", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "data-x", "data-y", "data-columns"],
- "#legendBox":["fill", "fill-opacity"],
- "#burgLabels > #cities":["opacity", "fill", "data-size", "font-size", "data-font", "font-family"],
- "#burgIcons > #cities":["opacity", "fill", "fill-opacity", "size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap"],
- "#anchors > #cities":["opacity", "fill", "size", "stroke", "stroke-width"],
- "#burgLabels > #towns":["opacity", "fill", "data-size", "font-size", "data-font", "font-family"],
- "#burgIcons > #towns":["opacity", "fill", "fill-opacity", "size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap"],
- "#anchors > #towns":["opacity", "fill", "size", "stroke", "stroke-width"],
- "#labels > #states":["opacity", "fill", "stroke", "stroke-width", "data-size", "font-size", "data-font", "font-family", "filter"],
- "#labels > #addedLabels":["opacity", "fill", "stroke", "stroke-width", "data-size", "font-size", "data-font", "font-family", "filter"],
- "#fogging":["opacity", "fill", "filter"]
- };
+ const style = {},
+ attributes = {
+ '#map': ['background-color', 'filter', 'data-filter'],
+ '#armies': ['font-size', 'box-size', 'stroke', 'stroke-width', 'fill-opacity', 'filter'],
+ '#biomes': ['opacity', 'filter', 'mask'],
+ '#stateBorders': ['opacity', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter'],
+ '#provinceBorders': ['opacity', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter'],
+ '#cells': ['opacity', 'stroke', 'stroke-width', 'filter', 'mask'],
+ '#gridOverlay': ['opacity', 'scale', 'dx', 'dy', 'type', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'transform', 'filter', 'mask'],
+ '#coordinates': ['opacity', 'data-size', 'font-size', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter', 'mask'],
+ '#compass': ['opacity', 'transform', 'filter', 'mask', 'shape-rendering'],
+ '#rose': ['transform'],
+ '#relig': ['opacity', 'stroke', 'stroke-width', 'filter'],
+ '#cults': ['opacity', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter'],
+ '#landmass': ['opacity', 'fill', 'filter'],
+ '#markers': ['opacity', 'rescale', 'filter'],
+ '#prec': ['opacity', 'stroke', 'stroke-width', 'fill', 'filter'],
+ '#population': ['opacity', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter'],
+ '#rural': ['stroke'],
+ '#urban': ['stroke'],
+ '#freshwater': ['opacity', 'fill', 'stroke', 'stroke-width', 'filter'],
+ '#salt': ['opacity', 'fill', 'stroke', 'stroke-width', 'filter'],
+ '#sinkhole': ['opacity', 'fill', 'stroke', 'stroke-width', 'filter'],
+ '#frozen': ['opacity', 'fill', 'stroke', 'stroke-width', 'filter'],
+ '#lava': ['opacity', 'fill', 'stroke', 'stroke-width', 'filter'],
+ '#dry': ['opacity', 'fill', 'stroke', 'stroke-width', 'filter'],
+ '#sea_island': ['opacity', 'stroke', 'stroke-width', 'filter', 'auto-filter'],
+ '#lake_island': ['opacity', 'stroke', 'stroke-width', 'filter'],
+ '#terrain': ['opacity', 'set', 'size', 'density', 'filter', 'mask'],
+ '#rivers': ['opacity', 'filter', 'fill'],
+ '#ruler': ['opacity', 'filter'],
+ '#roads': ['opacity', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter', 'mask'],
+ '#trails': ['opacity', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter', 'mask'],
+ '#searoutes': ['opacity', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter', 'mask'],
+ '#regions': ['opacity', 'filter'],
+ '#statesHalo': ['opacity', 'data-width', 'stroke-width'],
+ '#provs': ['opacity', 'fill', 'font-size', 'data-font', 'font-family', 'filter'],
+ '#temperature': ['opacity', 'font-size', 'fill', 'fill-opacity', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter'],
+ '#ice': ['opacity', 'fill', 'stroke', 'stroke-width', 'filter'],
+ '#emblems': ['opacity', 'stroke-width', 'filter'],
+ '#texture': ['opacity', 'filter', 'mask'],
+ '#textureImage': ['x', 'y'],
+ '#zones': ['opacity', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'filter', 'mask'],
+ '#oceanLayers': ['filter', 'layers'],
+ '#oceanBase': ['fill'],
+ '#oceanPattern': ['opacity'],
+ '#oceanicPattern': ['href'],
+ '#terrs': ['opacity', 'scheme', 'terracing', 'skip', 'relax', 'curve', 'filter', 'mask'],
+ '#legend': ['data-size', 'font-size', 'data-font', 'font-family', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'data-x', 'data-y', 'data-columns'],
+ '#legendBox': ['fill', 'fill-opacity'],
+ '#burgLabels > #cities': ['opacity', 'fill', 'data-size', 'font-size', 'data-font', 'font-family'],
+ '#burgIcons > #cities': ['opacity', 'fill', 'fill-opacity', 'size', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap'],
+ '#anchors > #cities': ['opacity', 'fill', 'size', 'stroke', 'stroke-width'],
+ '#burgLabels > #towns': ['opacity', 'fill', 'data-size', 'font-size', 'data-font', 'font-family'],
+ '#burgIcons > #towns': ['opacity', 'fill', 'fill-opacity', 'size', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap'],
+ '#anchors > #towns': ['opacity', 'fill', 'size', 'stroke', 'stroke-width'],
+ '#labels > #states': ['opacity', 'fill', 'stroke', 'stroke-width', 'data-size', 'font-size', 'data-font', 'font-family', 'filter'],
+ '#labels > #addedLabels': ['opacity', 'fill', 'stroke', 'stroke-width', 'data-size', 'font-size', 'data-font', 'font-family', 'filter'],
+ '#fogging': ['opacity', 'fill', 'filter']
+ };
for (const selector in attributes) {
- const s = style[selector] = {};
- attributes[selector].forEach(attr => {
+ const s = (style[selector] = {});
+ attributes[selector].forEach((attr) => {
const el = document.querySelector(selector);
if (!el) return;
let value = el.getAttribute(attr);
- if (attr === "font-size" && el.hasAttribute("data-size")) value = el.getAttribute("data-size");
+ if (attr === 'font-size' && el.hasAttribute('data-size')) value = el.getAttribute('data-size');
s[attr] = parseValue(value);
});
}
function parseValue(value) {
- if (value === "null" || value === null) return null;
- if (value === "") return "";
+ if (value === 'null' || value === null) return null;
+ if (value === '') return '';
if (!isNaN(+value)) return +value;
return value;
}
-
+
return style;
}
function checkName() {
- let tip = "";
- const v = "style"+styleSaverName.value;
- const listed = Array.from(stylePreset.options).some(o => o.value == v);
+ let tip = '';
+ const v = 'style' + styleSaverName.value;
+ const listed = Array.from(stylePreset.options).some((o) => o.value == v);
const stored = localStorage.getItem(v);
- if (!stored && listed) tip = "default";
- else if (stored) tip = "existing";
- else if (styleSaverName.value) tip = "new";
+ if (!stored && listed) tip = 'default';
+ else if (stored) tip = 'existing';
+ else if (styleSaverName.value) tip = 'new';
styleSaverTip.innerHTML = tip;
}
function saveStyle() {
- if (!styleSaverJSON.value) {tip("Please provide a style JSON", false, "error"); return};
- if (!JSON.isValid(styleSaverJSON.value)) {tip("JSON string is not valid, please check the format", false, "error"); return};
- if (!styleSaverName.value) {tip("Please provide a preset name", false, "error"); return};
- if (styleSaverTip.innerHTML === "default") {tip("You cannot overwrite default preset, please change the name", false, "error"); return};
- const preset = "style" + styleSaverName.value;
+ if (!styleSaverJSON.value) {
+ tip('Please provide a style JSON', false, 'error');
+ return;
+ }
+ if (!JSON.isValid(styleSaverJSON.value)) {
+ tip('JSON string is not valid, please check the format', false, 'error');
+ return;
+ }
+ if (!styleSaverName.value) {
+ tip('Please provide a preset name', false, 'error');
+ return;
+ }
+ if (styleSaverTip.innerHTML === 'default') {
+ tip('You cannot overwrite default preset, please change the name', false, 'error');
+ return;
+ }
+ const preset = 'style' + styleSaverName.value;
applyOption(stylePreset, preset, styleSaverName.value); // add option
- localStorage.setItem("presetStyle", preset); // mark preset as default
+ localStorage.setItem('presetStyle', preset); // mark preset as default
localStorage.setItem(preset, styleSaverJSON.value); // save preset
- $("#styleSaver").dialog("close");
- removeStyleButton.style.display = "inline-block";
- tip("Style preset is saved", false, "warn", 4000);
+ $('#styleSaver').dialog('close');
+ removeStyleButton.style.display = 'inline-block';
+ tip('Style preset is saved', false, 'warn', 4000);
}
function styleDownload() {
- if (!styleSaverJSON.value) {tip("Please provide a style JSON", false, "error"); return};
- if (!JSON.isValid(styleSaverJSON.value)) {tip("JSON string is not valid, please check the format", false, "error"); return};
- if (!styleSaverName.value) {tip("Please provide a preset name", false, "error"); return};
+ if (!styleSaverJSON.value) {
+ tip('Please provide a style JSON', false, 'error');
+ return;
+ }
+ if (!JSON.isValid(styleSaverJSON.value)) {
+ tip('JSON string is not valid, please check the format', false, 'error');
+ return;
+ }
+ if (!styleSaverName.value) {
+ tip('Please provide a preset name', false, 'error');
+ return;
+ }
const data = styleSaverJSON.value;
- if (!data) {tip("Please provide a style JSON", false, "error"); return};
- downloadFile(data, "style" + styleSaverName.value + ".json", "application/json");
+ if (!data) {
+ tip('Please provide a style JSON', false, 'error');
+ return;
+ }
+ downloadFile(data, 'style' + styleSaverName.value + '.json', 'application/json');
}
function styleUpload(dataLoaded) {
- if (!dataLoaded) {tip("Cannot load the file. Please check the data format", false, "error"); return;}
+ if (!dataLoaded) {
+ tip('Cannot load the file. Please check the data format', false, 'error');
+ return;
+ }
const data = JSON.stringify(JSON.parse(dataLoaded), null, 2);
styleSaverJSON.value = data;
}
}
function removeStylePreset() {
- if (stylePreset.selectedOptions[0].dataset.system) {tip("Cannot remove system preset", false, "error"); return;};
- localStorage.removeItem("presetStyle");
+ if (stylePreset.selectedOptions[0].dataset.system) {
+ tip('Cannot remove system preset', false, 'error');
+ return;
+ }
+ localStorage.removeItem('presetStyle');
localStorage.removeItem(stylePreset.value);
stylePreset.selectedOptions[0].remove();
- removeStyleButton.style.display = "none";
+ removeStyleButton.style.display = 'none';
}
// GLOBAL FILTERS
-mapFilters.addEventListener("click", applyMapFilter);
+mapFilters.addEventListener('click', applyMapFilter);
function applyMapFilter(event) {
- if (event.target.tagName !== "BUTTON") return;
+ if (event.target.tagName !== 'BUTTON') return;
const button = event.target;
- svg.attr("data-filter", null).attr("filter", null);
- if (button.classList.contains("pressed")) {button.classList.remove("pressed"); return;}
- mapFilters.querySelectorAll(".pressed").forEach(button => button.classList.remove("pressed"));
- button.classList.add("pressed");
- svg.attr("data-filter", button.id).attr("filter", "url(#filter-" + button.id + ")");
+ svg.attr('data-filter', null).attr('filter', null);
+ if (button.classList.contains('pressed')) {
+ button.classList.remove('pressed');
+ return;
+ }
+ mapFilters.querySelectorAll('.pressed').forEach((button) => button.classList.remove('pressed'));
+ button.classList.add('pressed');
+ svg.attr('data-filter', button.id).attr('filter', 'url(#filter-' + button.id + ')');
}
function updateMapFilter() {
- const filter = svg.attr("data-filter");
- mapFilters.querySelectorAll(".pressed").forEach(button => button.classList.remove("pressed"));
+ const filter = svg.attr('data-filter');
+ mapFilters.querySelectorAll('.pressed').forEach((button) => button.classList.remove('pressed'));
if (!filter) return;
- mapFilters.querySelector("#"+filter).classList.add("pressed");
+ mapFilters.querySelector('#' + filter).classList.add('pressed');
}
// FONTS
// fetch default fonts if not done before
function loadDefaultFonts() {
if (!$('link[href="fonts.css"]').length) {
- $("head").append('
');
- const fontsToAdd = ["Amatic+SC:700", "IM+Fell+English", "Great+Vibes", "MedievalSharp", "Metamorphous",
- "Nova+Script", "Uncial+Antiqua", "Underdog", "Caesar+Dressing", "Bitter", "Yellowtail", "Montez",
- "Shadows+Into+Light", "Fredericka+the+Great", "Orbitron", "Dancing+Script:700",
- "Architects+Daughter", "Kaushan+Script", "Gloria+Hallelujah", "Satisfy", "Comfortaa:700", "Cinzel"];
- fontsToAdd.forEach(function(f) {if (fonts.indexOf(f) === -1) fonts.push(f);});
+ $('head').append('
');
+ const fontsToAdd = [
+ 'Amatic+SC:700',
+ 'IM+Fell+English',
+ 'Great+Vibes',
+ 'MedievalSharp',
+ 'Metamorphous',
+ 'Nova+Script',
+ 'Uncial+Antiqua',
+ 'Underdog',
+ 'Caesar+Dressing',
+ 'Bitter',
+ 'Yellowtail',
+ 'Montez',
+ 'Shadows+Into+Light',
+ 'Fredericka+the+Great',
+ 'Orbitron',
+ 'Dancing+Script:700',
+ 'Architects+Daughter',
+ 'Kaushan+Script',
+ 'Gloria+Hallelujah',
+ 'Satisfy',
+ 'Comfortaa:700',
+ 'Cinzel'
+ ];
+ fontsToAdd.forEach(function (f) {
+ if (fonts.indexOf(f) === -1) fonts.push(f);
+ });
updateFontOptions();
}
}
function fetchFonts(url) {
return new Promise((resolve, reject) => {
- if (url === "") {
- tip("Use a direct link to any @font-face declaration or just font name to fetch from Google Fonts");
+ if (url === '') {
+ tip('Use a direct link to any @font-face declaration or just font name to fetch from Google Fonts');
return;
}
- if (url.indexOf("http") === -1) {
- url = url.replace(url.charAt(0), url.charAt(0).toUpperCase()).split(" ").join("+");
- url = "https://fonts.googleapis.com/css?family=" + url;
+ if (url.indexOf('http') === -1) {
+ url = url.replace(url.charAt(0), url.charAt(0).toUpperCase()).split(' ').join('+');
+ url = 'https://fonts.googleapis.com/css?family=' + url;
}
- const fetched = addFonts(url).then(fetched => {
+ const fetched = addFonts(url).then((fetched) => {
if (fetched === undefined) {
- tip("Cannot fetch font for this value!", false, "error");
+ tip('Cannot fetch font for this value!', false, 'error');
return;
}
if (fetched === 0) {
- tip("Already in the fonts list!", false, "error");
+ tip('Already in the fonts list!', false, 'error');
return;
}
updateFontOptions();
if (fetched === 1) {
- tip("Font " + fonts[fonts.length - 1] + " is fetched");
+ tip('Font ' + fonts[fonts.length - 1] + ' is fetched');
} else if (fetched > 1) {
- tip(fetched + " fonts are added to the list");
+ tip(fetched + ' fonts are added to the list');
}
resolve(fetched);
});
- })
+ });
}
function addFonts(url) {
- $("head").append('
');
+ $('head').append('
');
return fetch(url)
- .then(resp => resp.text())
- .then(text => {
+ .then((resp) => resp.text())
+ .then((text) => {
let s = document.createElement('style');
s.innerHTML = text;
document.head.appendChild(s);
- let styleSheet = Array.prototype.filter.call(
- document.styleSheets,
- sS => sS.ownerNode === s)[0];
- let FontRule = rule => {
+ let styleSheet = Array.prototype.filter.call(document.styleSheets, (sS) => sS.ownerNode === s)[0];
+ let FontRule = (rule) => {
let family = rule.style.getPropertyValue('font-family');
- let font = family.replace(/['"]+/g, '').replace(/ /g, "+");
+ let font = family.replace(/['"]+/g, '').replace(/ /g, '+');
let weight = rule.style.getPropertyValue('font-weight');
- if (weight && weight !== "400") font += ":" + weight;
+ if (weight && weight !== '400') font += ':' + weight;
if (fonts.indexOf(font) == -1) {
fonts.push(font);
- fetched++
+ fetched++;
}
};
let fetched = 0;
- for (let r of styleSheet.cssRules) {FontRule(r);}
+ for (let r of styleSheet.cssRules) {
+ FontRule(r);
+ }
document.head.removeChild(s);
return fetched;
})
- .catch(function() {});
+ .catch(function () {});
}
// Update font list for Label and Burg Editors
function updateFontOptions() {
- styleSelectFont.innerHTML = "";
- for (let i=0; i < fonts.length; i++) {
+ styleSelectFont.innerHTML = '';
+ for (let i = 0; i < fonts.length; i++) {
const opt = document.createElement('option');
opt.value = i;
- const font = fonts[i].split(':')[0].replace(/\+/g, " ");
+ const font = fonts[i].split(':')[0].replace(/\+/g, ' ');
opt.style.fontFamily = opt.innerHTML = font;
styleSelectFont.add(opt);
}
-}
\ No newline at end of file
+}
diff --git a/modules/ui/units-editor.js b/modules/ui/units-editor.js
index 9c47a0ef..d6691bd2 100644
--- a/modules/ui/units-editor.js
+++ b/modules/ui/units-editor.js
@@ -1,57 +1,57 @@
-"use strict";
+'use strict';
function editUnits() {
- closeDialogs("#unitsEditor, .stable");
- $("#unitsEditor").dialog();
+ closeDialogs('#unitsEditor, .stable');
+ $('#unitsEditor').dialog();
if (modules.editUnits) return;
modules.editUnits = true;
- $("#unitsEditor").dialog({
- title: "Units Editor",
- position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
+ $('#unitsEditor').dialog({
+ title: 'Units Editor',
+ position: {my: 'right top', at: 'right-10 top+10', of: 'svg', collision: 'fit'}
});
// add listeners
- document.getElementById("distanceUnitInput").addEventListener("change", changeDistanceUnit);
- document.getElementById("distanceScaleOutput").addEventListener("input", changeDistanceScale);
- document.getElementById("distanceScaleInput").addEventListener("change", changeDistanceScale);
- document.getElementById("areaUnit").addEventListener("change", () => lock("areaUnit"));
- document.getElementById("heightUnit").addEventListener("change", changeHeightUnit);
- document.getElementById("heightExponentInput").addEventListener("input", changeHeightExponent);
- document.getElementById("heightExponentOutput").addEventListener("input", changeHeightExponent);
- document.getElementById("temperatureScale").addEventListener("change", changeTemperatureScale);
- document.getElementById("barSizeOutput").addEventListener("input", changeScaleBarSize);
- document.getElementById("barSize").addEventListener("input", changeScaleBarSize);
- document.getElementById("barLabel").addEventListener("input", changeScaleBarLabel);
- document.getElementById("barPosX").addEventListener("input", changeScaleBarPosition);
- document.getElementById("barPosY").addEventListener("input", changeScaleBarPosition);
- document.getElementById("barBackOpacity").addEventListener("input", changeScaleBarOpacity);
- document.getElementById("barBackColor").addEventListener("input", changeScaleBarColor);
+ document.getElementById('distanceUnitInput').addEventListener('change', changeDistanceUnit);
+ document.getElementById('distanceScaleOutput').addEventListener('input', changeDistanceScale);
+ document.getElementById('distanceScaleInput').addEventListener('change', changeDistanceScale);
+ document.getElementById('areaUnit').addEventListener('change', () => lock('areaUnit'));
+ document.getElementById('heightUnit').addEventListener('change', changeHeightUnit);
+ document.getElementById('heightExponentInput').addEventListener('input', changeHeightExponent);
+ document.getElementById('heightExponentOutput').addEventListener('input', changeHeightExponent);
+ document.getElementById('temperatureScale').addEventListener('change', changeTemperatureScale);
+ document.getElementById('barSizeOutput').addEventListener('input', changeScaleBarSize);
+ document.getElementById('barSize').addEventListener('input', changeScaleBarSize);
+ document.getElementById('barLabel').addEventListener('input', changeScaleBarLabel);
+ document.getElementById('barPosX').addEventListener('input', changeScaleBarPosition);
+ document.getElementById('barPosY').addEventListener('input', changeScaleBarPosition);
+ document.getElementById('barBackOpacity').addEventListener('input', changeScaleBarOpacity);
+ document.getElementById('barBackColor').addEventListener('input', changeScaleBarColor);
- document.getElementById("populationRateOutput").addEventListener("input", changePopulationRate);
- document.getElementById("populationRate").addEventListener("change", changePopulationRate);
- document.getElementById("urbanizationOutput").addEventListener("input", changeUrbanizationRate);
- document.getElementById("urbanization").addEventListener("change", changeUrbanizationRate);
+ document.getElementById('populationRateOutput').addEventListener('input', changePopulationRate);
+ document.getElementById('populationRate').addEventListener('change', changePopulationRate);
+ document.getElementById('urbanizationOutput').addEventListener('input', changeUrbanizationRate);
+ document.getElementById('urbanization').addEventListener('change', changeUrbanizationRate);
- document.getElementById("addLinearRuler").addEventListener("click", addRuler);
- document.getElementById("addOpisometer").addEventListener("click", toggleOpisometerMode);
- document.getElementById("addRouteOpisometer").addEventListener("click", toggleRouteOpisometerMode);
- document.getElementById("addPlanimeter").addEventListener("click", togglePlanimeterMode);
- document.getElementById("removeRulers").addEventListener("click", removeAllRulers);
- document.getElementById("unitsRestore").addEventListener("click", restoreDefaultUnits);
+ document.getElementById('addLinearRuler').addEventListener('click', addRuler);
+ document.getElementById('addOpisometer').addEventListener('click', toggleOpisometerMode);
+ document.getElementById('addRouteOpisometer').addEventListener('click', toggleRouteOpisometerMode);
+ document.getElementById('addPlanimeter').addEventListener('click', togglePlanimeterMode);
+ document.getElementById('removeRulers').addEventListener('click', removeAllRulers);
+ document.getElementById('unitsRestore').addEventListener('click', restoreDefaultUnits);
function changeDistanceUnit() {
- if (this.value === "custom_name") {
- prompt("Provide a custom name for a distance unit", {default:""}, custom => {
+ if (this.value === 'custom_name') {
+ prompt('Provide a custom name for a distance unit', {default: ''}, (custom) => {
this.options.add(new Option(custom, custom, false, true));
- lock("distanceUnit");
+ lock('distanceUnit');
drawScaleBar();
calculateFriendlyGridSize();
});
return;
}
- lock("distanceUnit");
+ lock('distanceUnit');
drawScaleBar();
calculateFriendlyGridSize();
}
@@ -59,285 +59,281 @@ function editUnits() {
function changeDistanceScale() {
const scale = +this.value;
if (!scale || isNaN(scale) || scale < 0) {
- tip("Distance scale should be a positive number", false, "error");
- this.value = document.getElementById("distanceScaleInput").dataset.value;
+ tip('Distance scale should be a positive number', false, 'error');
+ this.value = document.getElementById('distanceScaleInput').dataset.value;
return;
}
- document.getElementById("distanceScaleOutput").value = scale;
- document.getElementById("distanceScaleInput").value = scale;
- document.getElementById("distanceScaleInput").dataset.value = scale;
- lock("distanceScale");
+ document.getElementById('distanceScaleOutput').value = scale;
+ document.getElementById('distanceScaleInput').value = scale;
+ document.getElementById('distanceScaleInput').dataset.value = scale;
+ lock('distanceScale');
drawScaleBar();
calculateFriendlyGridSize();
}
function changeHeightUnit() {
- if (this.value === "custom_name") {
- prompt("Provide a custom name for a height unit", {default:""}, custom => {
+ if (this.value === 'custom_name') {
+ prompt('Provide a custom name for a height unit', {default: ''}, (custom) => {
this.options.add(new Option(custom, custom, false, true));
- lock("heightUnit");
+ lock('heightUnit');
});
return;
}
- lock("heightUnit");
+ lock('heightUnit');
}
function changeHeightExponent() {
- document.getElementById("heightExponentInput").value = this.value;
- document.getElementById("heightExponentOutput").value = this.value;
+ document.getElementById('heightExponentInput').value = this.value;
+ document.getElementById('heightExponentOutput').value = this.value;
calculateTemperatures();
- if (layerIsOn("toggleTemp")) drawTemp();
- lock("heightExponent");
+ if (layerIsOn('toggleTemp')) drawTemp();
+ lock('heightExponent');
}
function changeTemperatureScale() {
- lock("temperatureScale");
- if (layerIsOn("toggleTemp")) drawTemp();
+ lock('temperatureScale');
+ if (layerIsOn('toggleTemp')) drawTemp();
}
function changeScaleBarSize() {
- document.getElementById("barSize").value = this.value;
- document.getElementById("barSizeOutput").value = this.value;
+ document.getElementById('barSize').value = this.value;
+ document.getElementById('barSizeOutput').value = this.value;
drawScaleBar();
- lock("barSize");
+ lock('barSize');
}
function changeScaleBarPosition() {
- lock("barPosX");
- lock("barPosY");
+ lock('barPosX');
+ lock('barPosY');
fitScaleBar();
}
function changeScaleBarLabel() {
- lock("barLabel");
+ lock('barLabel');
drawScaleBar();
}
function changeScaleBarOpacity() {
- scaleBar.select("rect").attr("opacity", this.value);
- lock("barBackOpacity");
+ scaleBar.select('rect').attr('opacity', this.value);
+ lock('barBackOpacity');
}
function changeScaleBarColor() {
- scaleBar.select("rect").attr("fill", this.value);
- lock("barBackColor");
+ scaleBar.select('rect').attr('fill', this.value);
+ lock('barBackColor');
}
function changePopulationRate() {
const rate = +this.value;
if (!rate || isNaN(rate) || rate <= 0) {
- tip("Population rate should be a positive number", false, "error");
- this.value = document.getElementById("populationRate").dataset.value;
+ tip('Population rate should be a positive number', false, 'error');
+ this.value = document.getElementById('populationRate').dataset.value;
return;
}
- document.getElementById("populationRateOutput").value = rate;
- document.getElementById("populationRate").value = rate;
- document.getElementById("populationRate").dataset.value = rate;
- lock("populationRate");
+ document.getElementById('populationRateOutput').value = rate;
+ document.getElementById('populationRate').value = rate;
+ document.getElementById('populationRate').dataset.value = rate;
+ lock('populationRate');
}
function changeUrbanizationRate() {
const rate = +this.value;
if (!rate || isNaN(rate) || rate < 0) {
- tip("Urbanization rate should be a number", false, "error");
- this.value = document.getElementById("urbanization").dataset.value;
+ tip('Urbanization rate should be a number', false, 'error');
+ this.value = document.getElementById('urbanization').dataset.value;
return;
}
- document.getElementById("urbanizationOutput").value = rate;
- document.getElementById("urbanization").value = rate;
- document.getElementById("urbanization").dataset.value = rate;
- lock("urbanization");
+ document.getElementById('urbanizationOutput').value = rate;
+ document.getElementById('urbanization').value = rate;
+ document.getElementById('urbanization').dataset.value = rate;
+ lock('urbanization');
}
function restoreDefaultUnits() {
// distanceScale
- document.getElementById("distanceScaleOutput").value = 3;
- document.getElementById("distanceScaleInput").value = 3;
- document.getElementById("distanceScaleInput").dataset.value = 3;
- unlock("distanceScale");
+ document.getElementById('distanceScaleOutput').value = 3;
+ document.getElementById('distanceScaleInput').value = 3;
+ document.getElementById('distanceScaleInput').dataset.value = 3;
+ unlock('distanceScale');
// units
- const US = navigator.language === "en-US";
- const UK = navigator.language === "en-GB";
- distanceUnitInput.value = US || UK ? "mi" : "km";
- heightUnit.value = US || UK ? "ft" : "m";
- temperatureScale.value = US ? "°F" : "°C";
- areaUnit.value = "square";
- localStorage.removeItem("distanceUnit");
- localStorage.removeItem("heightUnit");
- localStorage.removeItem("temperatureScale");
- localStorage.removeItem("areaUnit");
+ const US = navigator.language === 'en-US';
+ const UK = navigator.language === 'en-GB';
+ distanceUnitInput.value = US || UK ? 'mi' : 'km';
+ heightUnit.value = US || UK ? 'ft' : 'm';
+ temperatureScale.value = US ? '°F' : '°C';
+ areaUnit.value = 'square';
+ localStorage.removeItem('distanceUnit');
+ localStorage.removeItem('heightUnit');
+ localStorage.removeItem('temperatureScale');
+ localStorage.removeItem('areaUnit');
calculateFriendlyGridSize();
// height exponent
heightExponentInput.value = heightExponentOutput.value = 1.8;
- localStorage.removeItem("heightExponent");
+ localStorage.removeItem('heightExponent');
calculateTemperatures();
// scale bar
barSizeOutput.value = barSize.value = 2;
- barLabel.value = "";
- barBackOpacity.value = .2;
- barBackColor.value = "#ffffff";
+ barLabel.value = '';
+ barBackOpacity.value = 0.2;
+ barBackColor.value = '#ffffff';
barPosX.value = barPosY.value = 99;
- localStorage.removeItem("barSize");
- localStorage.removeItem("barLabel");
- localStorage.removeItem("barBackOpacity");
- localStorage.removeItem("barBackColor");
- localStorage.removeItem("barPosX");
- localStorage.removeItem("barPosY");
+ localStorage.removeItem('barSize');
+ localStorage.removeItem('barLabel');
+ localStorage.removeItem('barBackOpacity');
+ localStorage.removeItem('barBackColor');
+ localStorage.removeItem('barPosX');
+ localStorage.removeItem('barPosY');
drawScaleBar();
// population
populationRateOutput.value = populationRate.value = 1000;
urbanizationOutput.value = urbanization.value = 1;
- localStorage.removeItem("populationRate");
- localStorage.removeItem("urbanization");
+ localStorage.removeItem('populationRate');
+ localStorage.removeItem('urbanization');
}
function addRuler() {
- if (!layerIsOn("toggleRulers")) toggleRulers();
+ if (!layerIsOn('toggleRulers')) toggleRulers();
const pt = document.getElementById('map').createSVGPoint();
- pt.x = graphWidth / 2, pt.y = graphHeight / 4;
+ (pt.x = graphWidth / 2), (pt.y = graphHeight / 4);
const p = pt.matrixTransform(viewbox.node().getScreenCTM().inverse());
const dx = graphWidth / 4 / scale;
const dy = (rulers.data.length * 40) % (graphHeight / 2);
- const from = [p.x-dx | 0, p.y+dy | 0];
- const to = [p.x+dx | 0, p.y+dy | 0];
+ const from = [(p.x - dx) | 0, (p.y + dy) | 0];
+ const to = [(p.x + dx) | 0, (p.y + dy) | 0];
rulers.create(Ruler, [from, to]).draw();
}
function toggleOpisometerMode() {
- if (this.classList.contains("pressed")) {
+ if (this.classList.contains('pressed')) {
restoreDefaultEvents();
clearMainTip();
- this.classList.remove("pressed");
+ this.classList.remove('pressed');
} else {
- if (!layerIsOn("toggleRulers")) toggleRulers();
- tip("Draw a curve to measure length. Hold Shift to disallow path optimization", true);
- unitsBottom.querySelectorAll(".pressed").forEach(button => button.classList.remove("pressed"));
- this.classList.add("pressed");
- viewbox.style("cursor", "crosshair").call(d3.drag().on("start", function() {
- const point = d3.mouse(this);
- const opisometer = rulers.create(Opisometer, [point]).draw();
-
- d3.event.on("drag", function() {
+ if (!layerIsOn('toggleRulers')) toggleRulers();
+ tip('Draw a curve to measure length. Hold Shift to disallow path optimization', true);
+ unitsBottom.querySelectorAll('.pressed').forEach((button) => button.classList.remove('pressed'));
+ this.classList.add('pressed');
+ viewbox.style('cursor', 'crosshair').call(
+ d3.drag().on('start', function () {
const point = d3.mouse(this);
- opisometer.addPoint(point);
- });
+ const opisometer = rulers.create(Opisometer, [point]).draw();
- d3.event.on("end", function() {
- restoreDefaultEvents();
- clearMainTip();
- addOpisometer.classList.remove("pressed");
- if (opisometer.points.length < 2) rulers.remove(opisometer.id);
- if (!d3.event.sourceEvent.shiftKey) opisometer.optimize();
- });
- }));
+ d3.event.on('drag', function () {
+ const point = d3.mouse(this);
+ opisometer.addPoint(point);
+ });
+
+ d3.event.on('end', function () {
+ restoreDefaultEvents();
+ clearMainTip();
+ addOpisometer.classList.remove('pressed');
+ if (opisometer.points.length < 2) rulers.remove(opisometer.id);
+ if (!d3.event.sourceEvent.shiftKey) opisometer.optimize();
+ });
+ })
+ );
}
}
function toggleRouteOpisometerMode() {
- if (this.classList.contains("pressed")) {
+ if (this.classList.contains('pressed')) {
restoreDefaultEvents();
clearMainTip();
- this.classList.remove("pressed");
+ this.classList.remove('pressed');
} else {
- if (!layerIsOn("toggleRulers")) toggleRulers();
- tip("Draw a curve along routes to measure length. Hold Shift to measure away from roads.", true);
- unitsBottom.querySelectorAll(".pressed").forEach(button => button.classList.remove("pressed"));
- this.classList.add("pressed");
- viewbox.style("cursor", "crosshair").call(d3.drag().on("start", function() {
- const cells = pack.cells;
- const burgs = pack.burgs;
- const point = d3.mouse(this);
- const c = findCell(point[0], point[1]);
- if (cells.road[c] || d3.event.sourceEvent.shiftKey) {
- const b = cells.burg[c];
- const x = b ? burgs[b].x : cells.p[c][0];
- const y = b ? burgs[b].y : cells.p[c][1];
- const routeOpisometer = rulers.create(RouteOpisometer, [[x, y]]).draw();
+ if (!layerIsOn('toggleRulers')) toggleRulers();
+ tip('Draw a curve along routes to measure length. Hold Shift to measure away from roads.', true);
+ unitsBottom.querySelectorAll('.pressed').forEach((button) => button.classList.remove('pressed'));
+ this.classList.add('pressed');
+ viewbox.style('cursor', 'crosshair').call(
+ d3.drag().on('start', function () {
+ const cells = pack.cells;
+ const burgs = pack.burgs;
+ const point = d3.mouse(this);
+ const c = findCell(point[0], point[1]);
+ if (cells.road[c] || d3.event.sourceEvent.shiftKey) {
+ const b = cells.burg[c];
+ const x = b ? burgs[b].x : cells.p[c][0];
+ const y = b ? burgs[b].y : cells.p[c][1];
+ const routeOpisometer = rulers.create(RouteOpisometer, [[x, y]]).draw();
- d3.event.on("drag", function () {
- const point = d3.mouse(this);
- const c = findCell(point[0], point[1]);
- if (cells.road[c] || d3.event.sourceEvent.shiftKey) {
- routeOpisometer.trackCell(c, true);
- }
- });
+ d3.event.on('drag', function () {
+ const point = d3.mouse(this);
+ const c = findCell(point[0], point[1]);
+ if (cells.road[c] || d3.event.sourceEvent.shiftKey) {
+ routeOpisometer.trackCell(c, true);
+ }
+ });
- d3.event.on("end", function () {
+ d3.event.on('end', function () {
+ restoreDefaultEvents();
+ clearMainTip();
+ addRouteOpisometer.classList.remove('pressed');
+ if (routeOpisometer.points.length < 2) {
+ rulers.remove(routeOpisometer.id);
+ }
+ });
+ } else {
restoreDefaultEvents();
clearMainTip();
- addRouteOpisometer.classList.remove("pressed");
- if (routeOpisometer.points.length < 2) {
- rulers.remove(routeOpisometer.id);
- }
- });
- } else {
- restoreDefaultEvents();
- clearMainTip();
- addRouteOpisometer.classList.remove("pressed");
- tip("Must start in a cell with a route in it", false, "error");
- }
- }));
+ addRouteOpisometer.classList.remove('pressed');
+ tip('Must start in a cell with a route in it', false, 'error');
+ }
+ })
+ );
}
}
function togglePlanimeterMode() {
- if (this.classList.contains("pressed")) {
+ if (this.classList.contains('pressed')) {
restoreDefaultEvents();
clearMainTip();
- this.classList.remove("pressed");
+ this.classList.remove('pressed');
} else {
- if (!layerIsOn("toggleRulers")) toggleRulers();
- tip("Draw a curve to measure its area. Hold Shift to disallow path optimization", true);
- unitsBottom.querySelectorAll(".pressed").forEach(button => button.classList.remove("pressed"));
- this.classList.add("pressed");
- viewbox.style("cursor", "crosshair").call(d3.drag().on("start", function() {
- const point = d3.mouse(this);
- const planimeter = rulers.create(Planimeter, [point]).draw();
-
- d3.event.on("drag", function() {
+ if (!layerIsOn('toggleRulers')) toggleRulers();
+ tip('Draw a curve to measure its area. Hold Shift to disallow path optimization', true);
+ unitsBottom.querySelectorAll('.pressed').forEach((button) => button.classList.remove('pressed'));
+ this.classList.add('pressed');
+ viewbox.style('cursor', 'crosshair').call(
+ d3.drag().on('start', function () {
const point = d3.mouse(this);
- planimeter.addPoint(point);
- });
+ const planimeter = rulers.create(Planimeter, [point]).draw();
- d3.event.on("end", function() {
- restoreDefaultEvents();
- clearMainTip();
- addPlanimeter.classList.remove("pressed");
- if (planimeter.points.length < 3) rulers.remove(planimeter.id);
- else if (!d3.event.sourceEvent.shiftKey) planimeter.optimize();
- });
- }));
+ d3.event.on('drag', function () {
+ const point = d3.mouse(this);
+ planimeter.addPoint(point);
+ });
+ d3.event.on('end', function () {
+ restoreDefaultEvents();
+ clearMainTip();
+ addPlanimeter.classList.remove('pressed');
+ if (planimeter.points.length < 3) rulers.remove(planimeter.id);
+ else if (!d3.event.sourceEvent.shiftKey) planimeter.optimize();
+ });
+ })
+ );
}
}
function removeAllRulers() {
if (!rulers.data.length) return;
- alertMessage.innerHTML = `
- Are you sure you want to remove all placed rulers?
-
If you just want to hide rulers, toggle the Rulers layer off in Menu`;
- $("#alert").dialog({resizable: false, title: "Remove all rulers",
- buttons: {
- Remove: function() {
- $(this).dialog("close");
- rulers.undraw();
- rulers = new Rulers();
- },
- Cancel: function() {$(this).dialog("close");}
- }
- });
+
+ const message = 'Are you sure you want to remove all placed rulers?
If you just want to hide rulers, toggle the Rulers layer off in Menu';
+ const onConfirm = () => {
+ rulers.undraw();
+ rulers = new Rulers();
+ };
+ confirmationDialog({title: 'Remove all rulers', message, confirm: 'Remove', onConfirm});
}
-
-
}
-