mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
markers rework - editor functions
This commit is contained in:
parent
def32b7f74
commit
95f9d990d9
8 changed files with 633 additions and 214 deletions
|
|
@ -10,6 +10,7 @@ window.Markers = (function () {
|
|||
TIME && console.time("addMarkers");
|
||||
|
||||
const culturesSet = document.getElementById("culturesSet").value;
|
||||
// TODO: don't put multiple markers to the same cell
|
||||
|
||||
addVolcanoes();
|
||||
addHotSprings();
|
||||
|
|
@ -120,7 +121,9 @@ window.Markers = (function () {
|
|||
const {cells, burgs} = pack;
|
||||
|
||||
const meanFlux = d3.mean(cells.fl.filter(fl => fl));
|
||||
let bridges = Array.from(cells.i.filter(i => cells.burg[i] && cells.t[i] !== 1 && burgs[cells.burg[i]].population > 20 && cells.r[i] && cells.fl[i] > meanFlux));
|
||||
let bridges = Array.from(
|
||||
cells.i.filter(i => cells.burg[i] && cells.t[i] !== 1 && burgs[cells.burg[i]].population > 20 && cells.r[i] && cells.fl[i] > meanFlux)
|
||||
);
|
||||
let quantity = getQuantity(bridges, 1, 5);
|
||||
if (!quantity) return;
|
||||
|
||||
|
|
@ -143,13 +146,233 @@ window.Markers = (function () {
|
|||
let quantity = getQuantity(taverns, 1, 100);
|
||||
if (!quantity) return;
|
||||
|
||||
const colors = ["Dark", "Light", "Bright", "Golden", "White", "Black", "Red", "Pink", "Purple", "Blue", "Green", "Yellow", "Amber", "Orange", "Brown", "Grey"];
|
||||
const animals = ["Antelope", "Ape", "Badger", "Bear", "Beaver", "Bison", "Boar", "Buffalo", "Cat", "Crane", "Crocodile", "Crow", "Deer", "Dog", "Eagle", "Elk", "Fox", "Goat", "Goose", "Hare", "Hawk", "Heron", "Horse", "Hyena", "Ibis", "Jackal", "Jaguar", "Lark", "Leopard", "Lion", "Mantis", "Marten", "Moose", "Mule", "Narwhal", "Owl", "Panther", "Rat", "Raven", "Rook", "Scorpion", "Shark", "Sheep", "Snake", "Spider", "Swan", "Tiger", "Turtle", "Wolf", "Wolverine", "Camel", "Falcon", "Hound", "Ox"];
|
||||
const adjectives = ["New", "Good", "High", "Old", "Great", "Big", "Major", "Happy", "Main", "Huge", "Far", "Beautiful", "Fair", "Prime", "Ancient", "Golden", "Proud", "Lucky", "Fat", "Honest", "Giant", "Distant", "Friendly", "Loud", "Hungry", "Magical", "Superior", "Peaceful", "Frozen", "Divine", "Favorable", "Brave", "Sunny", "Flying"];
|
||||
const methods = ["Boiled", "Grilled", "Roasted", "Spit-roasted", "Stewed", "Stuffed", "Jugged", "Mashed", "Baked", "Braised", "Poached", "Marinated", "Pickled", "Smoked", "Dried", "Dry-aged", "Corned", "Fried", "Pan-fried", "Deep-fried", "Dressed", "Steamed", "Cured", "Syrupped", "Flame-Broiled"];
|
||||
const courses = ["beef", "pork", "bacon", "chicken", "lamb", "chevon", "hare", "rabbit", "hart", "deer", "antlers", "bear", "buffalo", "badger", "beaver", "turkey", "pheasant", "duck", "goose", "teal", "quail", "pigeon", "seal", "carp", "bass", "pike", "catfish", "sturgeon", "escallop", "pie", "cake", "pottage", "pudding", "onions", "carrot", "potato", "beet", "garlic", "cabbage", "eggplant", "eggs", "broccoli", "zucchini", "pepper", "olives", "pumpkin", "spinach", "peas", "chickpea", "beans", "rice", "pasta", "bread", "apples", "peaches", "pears", "melon", "oranges", "mango", "tomatoes", "cheese", "corn", "rat tails", "pig ears"];
|
||||
const colors = [
|
||||
"Dark",
|
||||
"Light",
|
||||
"Bright",
|
||||
"Golden",
|
||||
"White",
|
||||
"Black",
|
||||
"Red",
|
||||
"Pink",
|
||||
"Purple",
|
||||
"Blue",
|
||||
"Green",
|
||||
"Yellow",
|
||||
"Amber",
|
||||
"Orange",
|
||||
"Brown",
|
||||
"Grey"
|
||||
];
|
||||
const animals = [
|
||||
"Antelope",
|
||||
"Ape",
|
||||
"Badger",
|
||||
"Bear",
|
||||
"Beaver",
|
||||
"Bison",
|
||||
"Boar",
|
||||
"Buffalo",
|
||||
"Cat",
|
||||
"Crane",
|
||||
"Crocodile",
|
||||
"Crow",
|
||||
"Deer",
|
||||
"Dog",
|
||||
"Eagle",
|
||||
"Elk",
|
||||
"Fox",
|
||||
"Goat",
|
||||
"Goose",
|
||||
"Hare",
|
||||
"Hawk",
|
||||
"Heron",
|
||||
"Horse",
|
||||
"Hyena",
|
||||
"Ibis",
|
||||
"Jackal",
|
||||
"Jaguar",
|
||||
"Lark",
|
||||
"Leopard",
|
||||
"Lion",
|
||||
"Mantis",
|
||||
"Marten",
|
||||
"Moose",
|
||||
"Mule",
|
||||
"Narwhal",
|
||||
"Owl",
|
||||
"Panther",
|
||||
"Rat",
|
||||
"Raven",
|
||||
"Rook",
|
||||
"Scorpion",
|
||||
"Shark",
|
||||
"Sheep",
|
||||
"Snake",
|
||||
"Spider",
|
||||
"Swan",
|
||||
"Tiger",
|
||||
"Turtle",
|
||||
"Wolf",
|
||||
"Wolverine",
|
||||
"Camel",
|
||||
"Falcon",
|
||||
"Hound",
|
||||
"Ox"
|
||||
];
|
||||
const adjectives = [
|
||||
"New",
|
||||
"Good",
|
||||
"High",
|
||||
"Old",
|
||||
"Great",
|
||||
"Big",
|
||||
"Major",
|
||||
"Happy",
|
||||
"Main",
|
||||
"Huge",
|
||||
"Far",
|
||||
"Beautiful",
|
||||
"Fair",
|
||||
"Prime",
|
||||
"Ancient",
|
||||
"Golden",
|
||||
"Proud",
|
||||
"Lucky",
|
||||
"Fat",
|
||||
"Honest",
|
||||
"Giant",
|
||||
"Distant",
|
||||
"Friendly",
|
||||
"Loud",
|
||||
"Hungry",
|
||||
"Magical",
|
||||
"Superior",
|
||||
"Peaceful",
|
||||
"Frozen",
|
||||
"Divine",
|
||||
"Favorable",
|
||||
"Brave",
|
||||
"Sunny",
|
||||
"Flying"
|
||||
];
|
||||
const methods = [
|
||||
"Boiled",
|
||||
"Grilled",
|
||||
"Roasted",
|
||||
"Spit-roasted",
|
||||
"Stewed",
|
||||
"Stuffed",
|
||||
"Jugged",
|
||||
"Mashed",
|
||||
"Baked",
|
||||
"Braised",
|
||||
"Poached",
|
||||
"Marinated",
|
||||
"Pickled",
|
||||
"Smoked",
|
||||
"Dried",
|
||||
"Dry-aged",
|
||||
"Corned",
|
||||
"Fried",
|
||||
"Pan-fried",
|
||||
"Deep-fried",
|
||||
"Dressed",
|
||||
"Steamed",
|
||||
"Cured",
|
||||
"Syrupped",
|
||||
"Flame-Broiled"
|
||||
];
|
||||
const courses = [
|
||||
"beef",
|
||||
"pork",
|
||||
"bacon",
|
||||
"chicken",
|
||||
"lamb",
|
||||
"chevon",
|
||||
"hare",
|
||||
"rabbit",
|
||||
"hart",
|
||||
"deer",
|
||||
"antlers",
|
||||
"bear",
|
||||
"buffalo",
|
||||
"badger",
|
||||
"beaver",
|
||||
"turkey",
|
||||
"pheasant",
|
||||
"duck",
|
||||
"goose",
|
||||
"teal",
|
||||
"quail",
|
||||
"pigeon",
|
||||
"seal",
|
||||
"carp",
|
||||
"bass",
|
||||
"pike",
|
||||
"catfish",
|
||||
"sturgeon",
|
||||
"escallop",
|
||||
"pie",
|
||||
"cake",
|
||||
"pottage",
|
||||
"pudding",
|
||||
"onions",
|
||||
"carrot",
|
||||
"potato",
|
||||
"beet",
|
||||
"garlic",
|
||||
"cabbage",
|
||||
"eggplant",
|
||||
"eggs",
|
||||
"broccoli",
|
||||
"zucchini",
|
||||
"pepper",
|
||||
"olives",
|
||||
"pumpkin",
|
||||
"spinach",
|
||||
"peas",
|
||||
"chickpea",
|
||||
"beans",
|
||||
"rice",
|
||||
"pasta",
|
||||
"bread",
|
||||
"apples",
|
||||
"peaches",
|
||||
"pears",
|
||||
"melon",
|
||||
"oranges",
|
||||
"mango",
|
||||
"tomatoes",
|
||||
"cheese",
|
||||
"corn",
|
||||
"rat tails",
|
||||
"pig ears"
|
||||
];
|
||||
const types = ["hot", "cold", "fire", "ice", "smoky", "misty", "shiny", "sweet", "bitter", "salty", "sour", "sparkling", "smelly"];
|
||||
const drinks = ["wine", "brandy", "jinn", "whisky", "rom", "beer", "cider", "mead", "liquor", "spirit", "vodka", "tequila", "absinthe", "nectar", "milk", "kvass", "kumis", "tea", "water", "juice", "sap"];
|
||||
const drinks = [
|
||||
"wine",
|
||||
"brandy",
|
||||
"jinn",
|
||||
"whisky",
|
||||
"rom",
|
||||
"beer",
|
||||
"cider",
|
||||
"mead",
|
||||
"liquor",
|
||||
"spirit",
|
||||
"vodka",
|
||||
"tequila",
|
||||
"absinthe",
|
||||
"nectar",
|
||||
"milk",
|
||||
"kvass",
|
||||
"kumis",
|
||||
"tea",
|
||||
"water",
|
||||
"juice",
|
||||
"sap"
|
||||
];
|
||||
|
||||
while (quantity) {
|
||||
const [cell] = extractAnyElement(taverns);
|
||||
|
|
@ -282,7 +505,14 @@ window.Markers = (function () {
|
|||
|
||||
const subjects = ["Locals", "Old folks", "Old books", "Tipplers"];
|
||||
const species = ["Ogre", "Troll", "Cyclops", "Giant", "Monster", "Beast", "Dragon", "Undead", "Ghoul", "Vampire"];
|
||||
const modusOperandi = ["steals their cattle", "doesn't mind eating children", "doesn't mind of human flesh", "keeps the region at bay", "eats their kids", "abducts young women"];
|
||||
const modusOperandi = [
|
||||
"steals their cattle",
|
||||
"doesn't mind eating children",
|
||||
"doesn't mind of human flesh",
|
||||
"keeps the region at bay",
|
||||
"eats their kids",
|
||||
"abducts young women"
|
||||
];
|
||||
|
||||
while (quantity) {
|
||||
const [cell] = extractAnyElement(hills);
|
||||
|
|
@ -376,7 +606,38 @@ window.Markers = (function () {
|
|||
let quantity = getQuantity(roads, 50, 100);
|
||||
if (!quantity) return;
|
||||
|
||||
const animals = ["Apes", "Badgers", "Bears", "Beavers", "Bisons", "Boars", "Cats", "Crows", "Dogs", "Foxes", "Hares", "Hawks", "Hyenas", "Jackals", "Jaguars", "Leopards", "Lions", "Owls", "Panthers", "Rats", "Ravens", "Rooks", "Scorpions", "Sharks", "Snakes", "Spiders", "Tigers", "Wolfs", "Wolverines", "Falcons"];
|
||||
const animals = [
|
||||
"Apes",
|
||||
"Badgers",
|
||||
"Bears",
|
||||
"Beavers",
|
||||
"Bisons",
|
||||
"Boars",
|
||||
"Cats",
|
||||
"Crows",
|
||||
"Dogs",
|
||||
"Foxes",
|
||||
"Hares",
|
||||
"Hawks",
|
||||
"Hyenas",
|
||||
"Jackals",
|
||||
"Jaguars",
|
||||
"Leopards",
|
||||
"Lions",
|
||||
"Owls",
|
||||
"Panthers",
|
||||
"Rats",
|
||||
"Ravens",
|
||||
"Rooks",
|
||||
"Scorpions",
|
||||
"Sharks",
|
||||
"Snakes",
|
||||
"Spiders",
|
||||
"Tigers",
|
||||
"Wolfs",
|
||||
"Wolverines",
|
||||
"Falcons"
|
||||
];
|
||||
const types = {brigands: 4, bandits: 3, robbers: 1, highwaymen: 1};
|
||||
|
||||
while (quantity) {
|
||||
|
|
@ -385,7 +646,18 @@ window.Markers = (function () {
|
|||
const culture = cells.culture[cell];
|
||||
const biome = cells.biome[cell];
|
||||
const height = cells.p[cell];
|
||||
const locality = height >= 70 ? "highlander" : [1, 2].includes(biome) ? "desert" : [3, 4].includes(biome) ? "mounted" : [5, 6, 7, 8, 9].includes(biome) ? "forest" : biome === 12 ? "swamp" : "angry";
|
||||
const locality =
|
||||
height >= 70
|
||||
? "highlander"
|
||||
: [1, 2].includes(biome)
|
||||
? "desert"
|
||||
: [3, 4].includes(biome)
|
||||
? "mounted"
|
||||
: [5, 6, 7, 8, 9].includes(biome)
|
||||
? "forest"
|
||||
: biome === 12
|
||||
? "swamp"
|
||||
: "angry";
|
||||
const name = `${Names.getCulture(culture)} ${ra(animals)}`;
|
||||
const legend = `A gang of ${locality} ${rw(types)}`;
|
||||
notes.push({id, name, legend});
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ function clicked() {
|
|||
else if (grand.id === "burgIcons") editBurg();
|
||||
else if (parent.id === "ice") editIce();
|
||||
else if (parent.id === "terrain") editReliefIcon();
|
||||
else if (grand.id === "markers") editMarker();
|
||||
else if (grand.id === "markers" || great.id === "markers") editMarker();
|
||||
else if (grand.id === "coastline") editCoastline();
|
||||
else if (great.id === "armies") editRegiment();
|
||||
else if (pack.cells.t[i] === 1) {
|
||||
|
|
@ -332,7 +332,15 @@ function drawLegend(name, data) {
|
|||
const width = bbox.width + colOffset * 2;
|
||||
const height = bbox.height + colOffset / 2 + vOffset;
|
||||
|
||||
legend.insert("rect", ":first-child").attr("id", "legendBox").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", backClr).attr("fill-opacity", opacity);
|
||||
legend
|
||||
.insert("rect", ":first-child")
|
||||
.attr("id", "legendBox")
|
||||
.attr("x", 0)
|
||||
.attr("y", 0)
|
||||
.attr("width", width)
|
||||
.attr("height", height)
|
||||
.attr("fill", backClr)
|
||||
.attr("fill-opacity", opacity);
|
||||
|
||||
fitLegendBox();
|
||||
}
|
||||
|
|
@ -385,7 +393,15 @@ function createPicker() {
|
|||
const closePicker = () => contaiter.style("display", "none");
|
||||
|
||||
const contaiter = d3.select("body").append("svg").attr("id", "pickerContainer").attr("width", "100%").attr("height", "100%");
|
||||
contaiter.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%").attr("opacity", 0.2).on("mousemove", cl).on("click", closePicker);
|
||||
contaiter
|
||||
.append("rect")
|
||||
.attr("x", 0)
|
||||
.attr("y", 0)
|
||||
.attr("width", "100%")
|
||||
.attr("height", "100%")
|
||||
.attr("opacity", 0.2)
|
||||
.on("mousemove", cl)
|
||||
.on("click", closePicker);
|
||||
const picker = contaiter
|
||||
.append("g")
|
||||
.attr("id", "picker")
|
||||
|
|
@ -484,9 +500,25 @@ function createPicker() {
|
|||
const width = bbox.width + 8;
|
||||
const height = bbox.height + 9;
|
||||
|
||||
picker.insert("rect", ":first-child").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "#ffffff").attr("stroke", "#5d4651").on("mousemove", pos);
|
||||
picker
|
||||
.insert("rect", ":first-child")
|
||||
.attr("x", 0)
|
||||
.attr("y", 0)
|
||||
.attr("width", width)
|
||||
.attr("height", height)
|
||||
.attr("fill", "#ffffff")
|
||||
.attr("stroke", "#5d4651")
|
||||
.on("mousemove", pos);
|
||||
picker.insert("text", ":first-child").attr("x", 291).attr("y", -10).attr("id", "pickerCloseText").text("✕");
|
||||
picker.insert("rect", ":first-child").attr("x", 288).attr("y", -21).attr("id", "pickerCloseRect").attr("width", 14).attr("height", 14).on("mousemove", cl).on("click", closePicker);
|
||||
picker
|
||||
.insert("rect", ":first-child")
|
||||
.attr("x", 288)
|
||||
.attr("y", -21)
|
||||
.attr("id", "pickerCloseRect")
|
||||
.attr("width", 14)
|
||||
.attr("height", 14)
|
||||
.on("mousemove", cl)
|
||||
.on("click", closePicker);
|
||||
picker.insert("text", ":first-child").attr("x", 12).attr("y", -10).attr("id", "pickerLabel").text("Color Picker").on("mousemove", pos);
|
||||
picker.insert("rect", ":first-child").attr("x", 0).attr("y", -30).attr("width", width).attr("height", 30).attr("id", "pickerHeader").on("mousemove", pos);
|
||||
picker.attr("transform", `translate(${(svgWidth - width) / 2},${(svgHeight - height) / 2})`);
|
||||
|
|
@ -705,7 +737,14 @@ function highlightElement(element) {
|
|||
|
||||
const highlight = debug.append("rect").attr("x", box.x).attr("y", box.y).attr("width", box.width).attr("height", box.height).attr("transform", transform);
|
||||
|
||||
highlight.classed("highlighted", 1).transition(enter).style("outline-offset", "0px").transition(exit).style("outline-color", "transparent").delay(1000).remove();
|
||||
highlight
|
||||
.classed("highlighted", 1)
|
||||
.transition(enter)
|
||||
.style("outline-offset", "0px")
|
||||
.transition(exit)
|
||||
.style("outline-color", "transparent")
|
||||
.delay(1000)
|
||||
.remove();
|
||||
|
||||
const tr = parseTransform(transform);
|
||||
let x = box.x + box.width / 2;
|
||||
|
|
@ -922,6 +961,7 @@ function selectIcon(initial, callback) {
|
|||
}
|
||||
}
|
||||
|
||||
input.oninput = e => callback(input.value);
|
||||
table.onclick = e => {
|
||||
if (e.target.tagName === "TD") {
|
||||
input.value = e.target.innerHTML;
|
||||
|
|
@ -948,6 +988,31 @@ function selectIcon(initial, callback) {
|
|||
});
|
||||
}
|
||||
|
||||
function confirmationDialog(options) {
|
||||
const {
|
||||
title = "Confirm action",
|
||||
message = "Are you sure you want to continue? <br>The action cannot be reverted",
|
||||
cancel = "Cancel",
|
||||
confirm = "Continue",
|
||||
onCancel,
|
||||
onConfirm
|
||||
} = options;
|
||||
|
||||
const buttons = {
|
||||
[confirm]: function () {
|
||||
if (onConfirm) onConfirm();
|
||||
$(this).dialog("close");
|
||||
},
|
||||
[cancel]: function () {
|
||||
if (onCancel) onCancel();
|
||||
$(this).dialog("close");
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById("alertMessage").innerHTML = message;
|
||||
$("#alert").dialog({resizable: false, title, buttons});
|
||||
}
|
||||
|
||||
// add and register event listeners to clean up on editor closure
|
||||
function listen(element, event, handler) {
|
||||
element.addEventListener(event, handler);
|
||||
|
|
|
|||
|
|
@ -196,7 +196,8 @@ function drawHeightmap() {
|
|||
for (const i of d3.range(20, 101)) {
|
||||
if (paths[i].length < 10) continue;
|
||||
const color = getColor(i, scheme);
|
||||
if (terracing) terrs.append("path").attr("d", paths[i]).attr("transform", "translate(.7,1.4)").attr("fill", d3.color(color).darker(terracing)).attr("data-height", i);
|
||||
if (terracing)
|
||||
terrs.append("path").attr("d", paths[i]).attr("transform", "translate(.7,1.4)").attr("fill", d3.color(color).darker(terracing)).attr("data-height", i);
|
||||
terrs.append("path").attr("d", paths[i]).attr("fill", color).attr("data-height", i);
|
||||
}
|
||||
|
||||
|
|
@ -798,7 +799,10 @@ function drawReligions() {
|
|||
if (!vArray[r]) vArray[r] = [];
|
||||
vArray[r].push(points);
|
||||
body[r] += "M" + points.join("L");
|
||||
gap[r] += "M" + vertices.p[chain[0][0]] + chain.reduce((r2, v, i, d) => (!i ? r2 : !v[2] ? r2 + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r2 + "M" + vertices.p[v[0]] : r2), "");
|
||||
gap[r] +=
|
||||
"M" +
|
||||
vertices.p[chain[0][0]] +
|
||||
chain.reduce((r2, v, i, d) => (!i ? r2 : !v[2] ? r2 + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r2 + "M" + vertices.p[v[0]] : r2), "");
|
||||
}
|
||||
|
||||
const bodyData = body.map((p, i) => [p.length > 10 ? p : null, i, religions[i].color]).filter(d => d[0]);
|
||||
|
|
@ -966,7 +970,12 @@ function drawStates() {
|
|||
const gapString = gapData.map(d => `<path id="state-gap${d[1]}" d="${d[0]}" fill="none" stroke="${d[2]}"/>`).join("");
|
||||
const clipString = bodyData.map(d => `<clipPath id="state-clip${d[1]}"><use href="#state${d[1]}"/></clipPath>`).join("");
|
||||
const haloString = haloData
|
||||
.map(d => `<path id="state-border${d[1]}" d="${d[0]}" clip-path="url(#state-clip${d[1]})" stroke="${d3.color(d[2]) ? d3.color(d[2]).darker().hex() : "#666666"}"/>`)
|
||||
.map(
|
||||
d =>
|
||||
`<path id="state-border${d[1]}" d="${d[0]}" clip-path="url(#state-clip${d[1]})" stroke="${
|
||||
d3.color(d[2]) ? d3.color(d[2]).darker().hex() : "#666666"
|
||||
}"/>`
|
||||
)
|
||||
.join("");
|
||||
|
||||
statesBody.html(bodyString + gapString);
|
||||
|
|
@ -1219,7 +1228,10 @@ function getProvincesVertices() {
|
|||
if (!vArray[p]) vArray[p] = [];
|
||||
vArray[p].push(points);
|
||||
body[p] += "M" + points.join("L");
|
||||
gap[p] += "M" + vertices.p[chain[0][0]] + chain.reduce((r, v, i, d) => (!i ? r : !v[2] ? r + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r + "M" + vertices.p[v[0]] : r), "");
|
||||
gap[p] +=
|
||||
"M" +
|
||||
vertices.p[chain[0][0]] +
|
||||
chain.reduce((r, v, i, d) => (!i ? r : !v[2] ? r + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r + "M" + vertices.p[v[0]] : r), "");
|
||||
}
|
||||
|
||||
// find province visual center
|
||||
|
|
@ -1300,7 +1312,12 @@ function drawGrid() {
|
|||
const maxWidth = Math.max(+mapWidthInput.value, graphWidth);
|
||||
const maxHeight = Math.max(+mapHeightInput.value, graphHeight);
|
||||
|
||||
d3.select(pattern).attr("stroke", stroke).attr("stroke-width", width).attr("stroke-dasharray", dasharray).attr("stroke-linecap", linecap).attr("patternTransform", tr);
|
||||
d3.select(pattern)
|
||||
.attr("stroke", stroke)
|
||||
.attr("stroke-width", width)
|
||||
.attr("stroke-dasharray", dasharray)
|
||||
.attr("stroke-linecap", linecap)
|
||||
.attr("patternTransform", tr);
|
||||
gridOverlay
|
||||
.append("rect")
|
||||
.attr("width", maxWidth)
|
||||
|
|
@ -1510,23 +1527,23 @@ function toggleMarkers(event) {
|
|||
drawMarkers();
|
||||
if (event && isCtrlClick(event)) editStyle("markers");
|
||||
} else {
|
||||
if (event && isCtrlClick(event)) {
|
||||
editStyle("markers");
|
||||
return;
|
||||
}
|
||||
if (event && isCtrlClick(event)) return editStyle("markers");
|
||||
markers.selectAll("*").remove();
|
||||
turnButtonOff("toggleMarkers");
|
||||
}
|
||||
}
|
||||
|
||||
function drawMarkers() {
|
||||
const html = pack.markers.map(drawMarker);
|
||||
const rescale = +markers.attr("rescale");
|
||||
const html = pack.markers.map(marker => drawMarker(marker, rescale));
|
||||
markers.html(html.join(""));
|
||||
}
|
||||
|
||||
const getPin = (shape = "bubble", fill = "#fff", stroke = "#000") => {
|
||||
if (shape === "bubble") return `<path d="M6,19 l9,10 L24,19" fill="${stroke}" stroke="none" /><circle cx="15" cy="15" r="10" fill="${fill}" stroke="${stroke}"/>`;
|
||||
if (shape === "pin") return `<path d="m 15,3 c -5.5,0 -9.7,4.09 -9.7,9.3 0,6.8 9.7,17 9.7,17 0,0 9.7,-10.2 9.7,-17 C 24.7,7.09 20.5,3 15,3 Z" fill="${fill}" stroke="${stroke}"/>`;
|
||||
if (shape === "bubble")
|
||||
return `<path d="M6,19 l9,10 L24,19" fill="${stroke}" stroke="none" /><circle cx="15" cy="15" r="10" fill="${fill}" stroke="${stroke}"/>`;
|
||||
if (shape === "pin")
|
||||
return `<path d="m 15,3 c -5.5,0 -9.7,4.09 -9.7,9.3 0,6.8 9.7,17 9.7,17 0,0 9.7,-10.2 9.7,-17 C 24.7,7.09 20.5,3 15,3 Z" fill="${fill}" stroke="${stroke}"/>`;
|
||||
if (shape === "square") return `<path d="m 20,25 -5,4 -5,-4 z" fill="${stroke}"/><path d="M 5,5 H 25 V 25 H 5 Z" fill="${fill}" stroke="${stroke}"/>`;
|
||||
if (shape === "squarish") return `<path d="m 5,5 h 20 v 20 h -6 l -4,4 -4,-4 H 5 Z" fill="${fill}" stroke="${stroke}" />`;
|
||||
if (shape === "diamond") return `<path d="M 2,15 15,1 28,15 15,29 Z" fill="${fill}" stroke="${stroke}" />`;
|
||||
|
|
@ -1540,14 +1557,14 @@ const getPin = (shape = "bubble", fill = "#fff", stroke = "#000") => {
|
|||
if (shape === "no") return "";
|
||||
};
|
||||
|
||||
function drawMarker(marker) {
|
||||
function drawMarker(marker, rescale = 1) {
|
||||
const {i, icon, x, y, dx = 50, dy = 50, px = 12, size = 30} = marker;
|
||||
const id = `marker${i}`;
|
||||
const zoomSize = Math.max(rn(size / 5 + 24 / scale, 2), 1);
|
||||
const zoomSize = rescale ? Math.max(rn(size / 5 + 24 / scale, 2), 1) : 1;
|
||||
const viewX = rn(x - zoomSize / 2, 1);
|
||||
const viewY = rn(y - zoomSize, 1);
|
||||
|
||||
return `<svg id="${id}" viewbox="0 0 30 30" width="${zoomSize}" height="${zoomSize}" x="${viewX}" y="${viewY}">${getPin()}<text x="${dx}%" y="${dy}%" font-size="${px}px" >${icon}</text></svg>`;
|
||||
return `<svg id="${id}" viewbox="0 0 30 30" width="${zoomSize}" height="${zoomSize}" x="${viewX}" y="${viewY}"><g>${getPin()}</g><text x="${dx}%" y="${dy}%" font-size="${px}px" >${icon}</text></svg>`;
|
||||
}
|
||||
|
||||
function toggleLabels(event) {
|
||||
|
|
@ -1717,15 +1734,21 @@ function drawEmblems() {
|
|||
}
|
||||
|
||||
const burgNodes = nodes.filter(node => node.type === "burg");
|
||||
const burgString = burgNodes.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`).join("");
|
||||
const burgString = burgNodes
|
||||
.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`)
|
||||
.join("");
|
||||
emblems.select("#burgEmblems").attr("font-size", sizeBurgs).html(burgString);
|
||||
|
||||
const provinceNodes = nodes.filter(node => node.type === "province");
|
||||
const provinceString = provinceNodes.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`).join("");
|
||||
const provinceString = provinceNodes
|
||||
.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`)
|
||||
.join("");
|
||||
emblems.select("#provinceEmblems").attr("font-size", sizeProvinces).html(provinceString);
|
||||
|
||||
const stateNodes = nodes.filter(node => node.type === "state");
|
||||
const stateString = stateNodes.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`).join("");
|
||||
const stateString = stateNodes
|
||||
.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`)
|
||||
.join("");
|
||||
emblems.select("#stateEmblems").attr("font-size", sizeStates).html(stateString);
|
||||
|
||||
invokeActiveZooming();
|
||||
|
|
|
|||
|
|
@ -3,23 +3,28 @@ function editMarker() {
|
|||
if (customization) return;
|
||||
closeDialogs(".stable");
|
||||
|
||||
const element = d3.event.target.parentElement;
|
||||
elSelected = d3.select(element).call(d3.drag().on("start", dragMarker)).classed("draggable", true);
|
||||
const marker = pack.markers.find(({i}) => Number(elSelected.attr("id").slice(6)) === i);
|
||||
const element = d3.event.target.closest("svg");
|
||||
const marker = pack.markers.find(({i}) => Number(element.id.slice(6)) === i);
|
||||
if (!marker) return;
|
||||
|
||||
elSelected = d3.select(element).raise().call(d3.drag().on("start", dragMarker)).classed("draggable", true);
|
||||
|
||||
// dom elements
|
||||
const markerSelectGroup = document.getElementById("markerSelectGroup");
|
||||
const markerType = document.getElementById("markerType");
|
||||
const markerIcon = document.getElementById("markerIcon");
|
||||
const markerIconSelect = document.getElementById("markerIconSelect");
|
||||
const markerIconSize = document.getElementById("markerIconSize");
|
||||
const markerIconShiftX = document.getElementById("markerIconShiftX");
|
||||
const markerIconShiftY = document.getElementById("markerIconShiftY");
|
||||
|
||||
const markerSize = document.getElementById("markerSize");
|
||||
const markerBaseStroke = document.getElementById("markerBaseStroke");
|
||||
const markerBaseFill = document.getElementById("markerBaseFill");
|
||||
const markerPin = document.getElementById("markerPin");
|
||||
const markerFill = document.getElementById("markerFill");
|
||||
const markerStroke = document.getElementById("markerStroke");
|
||||
|
||||
const markerToggleBubble = document.getElementById("markerToggleBubble");
|
||||
const markerIconSelect = document.getElementById("markerIconSelect");
|
||||
const markerNotes = document.getElementById("markerNotes");
|
||||
const addMarker = document.getElementById("addMarker");
|
||||
const markerAdd = document.getElementById("markerAdd");
|
||||
const markerRemove = document.getElementById("markerRemove");
|
||||
|
||||
updateInputs();
|
||||
|
||||
|
|
@ -31,22 +36,27 @@ function editMarker() {
|
|||
});
|
||||
|
||||
const listeners = [
|
||||
listen(markerSelectGroup, "change", changeGroup),
|
||||
listen(document.getElementById("markerIcon"), "click", toggleIconSection),
|
||||
listen(markerType, "change", changeMarkerType),
|
||||
listen(markerIcon, "input", changeMarkerIcon),
|
||||
listen(markerIconSelect, "click", selectMarkerIcon),
|
||||
listen(markerIconSize, "input", changeIconSize),
|
||||
listen(markerIconShiftX, "input", changeIconShiftX),
|
||||
listen(markerIconShiftY, "input", changeIconShiftY),
|
||||
listen(document.getElementById("markerIconSelect"), "click", selectMarkerIcon),
|
||||
listen(document.getElementById("markerStyle"), "click", toggleStyleSection),
|
||||
listen(markerSize, "input", changeMarkerSize),
|
||||
listen(markerBaseStroke, "input", changePinStroke),
|
||||
listen(markerBaseFill, "input", changePinFill),
|
||||
listen(markerToggleBubble, "click", togglePinVisibility),
|
||||
listen(document.getElementById("markerLegendButton"), "click", editMarkerLegend),
|
||||
listen(document.getElementById("markerAdd"), "click", toggleAddMarker),
|
||||
listen(document.getElementById("markerRemove"), "click", removeMarker)
|
||||
listen(markerPin, "change", changeMarkerPin),
|
||||
listen(markerFill, "input", changePinFill),
|
||||
listen(markerStroke, "input", changePinStroke),
|
||||
listen(markerNotes, "click", editMarkerLegend),
|
||||
listen(markerAdd, "click", toggleAddMarker),
|
||||
listen(markerRemove, "click", confirmMarkerDeletion)
|
||||
];
|
||||
|
||||
function getSameTypeMarkers() {
|
||||
const currentType = marker.type;
|
||||
if (!currentType) return [marker];
|
||||
return pack.markers.filter(({type}) => type === currentType);
|
||||
}
|
||||
|
||||
function dragMarker() {
|
||||
const dx = +this.getAttribute("x") - d3.event.x;
|
||||
const dy = +this.getAttribute("y") - d3.event.y;
|
||||
|
|
@ -70,173 +80,147 @@ function editMarker() {
|
|||
}
|
||||
|
||||
function updateInputs() {
|
||||
const {icon, type = "", size = 30, dx = 50, dy = 50, px = 12, stroke = "#000", fill = "#fff", pin = "bubble"} = marker;
|
||||
const {icon, type = "", size = 30, dx = 50, dy = 50, px = 12, stroke = "#000000", fill = "#ffffff", pin = "bubble"} = marker;
|
||||
|
||||
markerSelectGroup.value = type;
|
||||
markerType.value = type;
|
||||
markerIcon.value = icon;
|
||||
markerIconSize.value = px;
|
||||
markerIconShiftX.value = dx;
|
||||
markerIconShiftY.value = dy;
|
||||
|
||||
markerSize.value = size;
|
||||
markerBaseStroke.value = stroke;
|
||||
markerBaseFill.value = fill;
|
||||
|
||||
markerToggleBubble.className = pin;
|
||||
markerIconSelect.innerHTML = icon;
|
||||
markerPin.value = pin;
|
||||
markerFill.value = fill;
|
||||
markerStroke.value = stroke;
|
||||
}
|
||||
|
||||
function toggleGroupSection() {
|
||||
if (markerGroupSection.style.display === "inline-block") {
|
||||
markerEditor.querySelectorAll("button:not(#markerGroup)").forEach(b => (b.style.display = "inline-block"));
|
||||
markerGroupSection.style.display = "none";
|
||||
} else {
|
||||
markerEditor.querySelectorAll("button:not(#markerGroup)").forEach(b => (b.style.display = "none"));
|
||||
markerGroupSection.style.display = "inline-block";
|
||||
}
|
||||
function changeMarkerType() {
|
||||
marker.type = this.value;
|
||||
}
|
||||
|
||||
function changeGroup() {
|
||||
elSelected.attr("xlink:href", "#" + this.value);
|
||||
elSelected.attr("data-id", "#" + this.value);
|
||||
}
|
||||
|
||||
function toggleIconSection() {
|
||||
console.log(marker);
|
||||
if (markerIconSection.style.display === "inline-block") {
|
||||
markerEditor.querySelectorAll("button:not(#markerIcon)").forEach(b => (b.style.display = "inline-block"));
|
||||
markerIconSection.style.display = "none";
|
||||
markerIconSelect.style.display = "none";
|
||||
} else {
|
||||
markerEditor.querySelectorAll("button:not(#markerIcon)").forEach(b => (b.style.display = "none"));
|
||||
markerIconSection.style.display = "inline-block";
|
||||
markerIconSelect.style.display = "inline-block";
|
||||
}
|
||||
function changeMarkerIcon() {
|
||||
const icon = this.value;
|
||||
getSameTypeMarkers().forEach(marker => {
|
||||
marker.icon = icon;
|
||||
redrawIcon(marker);
|
||||
});
|
||||
}
|
||||
|
||||
function selectMarkerIcon() {
|
||||
selectIcon(this.innerHTML, v => {
|
||||
this.innerHTML = v;
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select("#defs-markers").select(id).select("text").text(v);
|
||||
selectIcon(marker.icon, icon => {
|
||||
markerIcon.value = icon;
|
||||
getSameTypeMarkers().forEach(marker => {
|
||||
marker.icon = icon;
|
||||
redrawIcon(marker);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function changeIconSize() {
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select("#defs-markers")
|
||||
.select(id)
|
||||
.select("text")
|
||||
.attr("font-size", this.value + "px");
|
||||
const px = +this.value;
|
||||
getSameTypeMarkers().forEach(marker => {
|
||||
marker.px = px;
|
||||
redrawIcon(marker);
|
||||
});
|
||||
}
|
||||
|
||||
function changeIconShiftX() {
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select("#defs-markers")
|
||||
.select(id)
|
||||
.select("text")
|
||||
.attr("x", this.value + "%");
|
||||
const dx = +this.value;
|
||||
getSameTypeMarkers().forEach(marker => {
|
||||
marker.dx = dx;
|
||||
redrawIcon(marker);
|
||||
});
|
||||
}
|
||||
|
||||
function changeIconShiftY() {
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select("#defs-markers")
|
||||
.select(id)
|
||||
.select("text")
|
||||
.attr("y", this.value + "%");
|
||||
}
|
||||
|
||||
function toggleStyleSection() {
|
||||
if (markerStyleSection.style.display === "inline-block") {
|
||||
markerEditor.querySelectorAll("button:not(#markerStyle)").forEach(b => (b.style.display = "inline-block"));
|
||||
markerStyleSection.style.display = "none";
|
||||
} else {
|
||||
markerEditor.querySelectorAll("button:not(#markerStyle)").forEach(b => (b.style.display = "none"));
|
||||
markerStyleSection.style.display = "inline-block";
|
||||
}
|
||||
const dy = +this.value;
|
||||
getSameTypeMarkers().forEach(marker => {
|
||||
marker.dy = dy;
|
||||
redrawIcon(marker);
|
||||
});
|
||||
}
|
||||
|
||||
function changeMarkerSize() {
|
||||
const id = elSelected.attr("data-id");
|
||||
document.querySelectorAll("use[data-id='" + id + "']").forEach(e => {
|
||||
const x = +e.dataset.x,
|
||||
y = +e.dataset.y;
|
||||
const desired = (e.dataset.size = +markerSize.value);
|
||||
const size = Math.max(desired * 5 + 25 / scale, 1);
|
||||
const size = +this.value;
|
||||
const rescale = +markers.attr("rescale");
|
||||
|
||||
e.setAttribute("x", x - size / 2);
|
||||
e.setAttribute("y", y - size / 2);
|
||||
e.setAttribute("width", size);
|
||||
e.setAttribute("height", size);
|
||||
getSameTypeMarkers().forEach(marker => {
|
||||
marker.size = size;
|
||||
const {i, x, y, hidden} = marker;
|
||||
const el = !hidden && document.getElementById(`marker${i}`);
|
||||
if (!el) return;
|
||||
|
||||
const zoomedSize = rescale ? Math.max(rn(size / 5 + 24 / scale, 2), 1) : size;
|
||||
el.setAttribute("width", zoomedSize);
|
||||
el.setAttribute("height", zoomedSize);
|
||||
el.setAttribute("x", rn(x - zoomedSize / 2, 1));
|
||||
el.setAttribute("y", rn(y - zoomedSize, 1));
|
||||
});
|
||||
invokeActiveZooming();
|
||||
}
|
||||
|
||||
function changePinStroke() {
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select(id).select("path").attr("fill", this.value);
|
||||
d3.select(id).select("circle").attr("stroke", this.value);
|
||||
function changeMarkerPin() {
|
||||
const pin = this.value;
|
||||
getSameTypeMarkers().forEach(marker => {
|
||||
marker.pin = pin;
|
||||
redrawPin(marker);
|
||||
});
|
||||
}
|
||||
|
||||
function changePinFill() {
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select(id).select("circle").attr("fill", this.value);
|
||||
const fill = this.value;
|
||||
getSameTypeMarkers().forEach(marker => {
|
||||
marker.fill = fill;
|
||||
redrawPin(marker);
|
||||
});
|
||||
}
|
||||
|
||||
function changeIconStrokeWidth() {
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select("#defs-markers").select(id).select("text").attr("stroke-width", this.value);
|
||||
function changePinStroke() {
|
||||
const stroke = this.value;
|
||||
getSameTypeMarkers().forEach(marker => {
|
||||
marker.stroke = stroke;
|
||||
redrawPin(marker);
|
||||
});
|
||||
}
|
||||
|
||||
function changeIconStroke() {
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select("#defs-markers").select(id).select("text").attr("stroke", this.value);
|
||||
function redrawIcon({i, hidden, icon, dx = 50, dy = 50, px = 12}) {
|
||||
const iconElement = !hidden && document.querySelector(`#marker${i} > text`);
|
||||
if (iconElement) {
|
||||
iconElement.innerHTML = icon;
|
||||
iconElement.setAttribute("x", dx + "%");
|
||||
iconElement.setAttribute("y", dy + "%");
|
||||
iconElement.setAttribute("font-size", px + "px");
|
||||
}
|
||||
}
|
||||
|
||||
function changeIconFill() {
|
||||
const id = elSelected.attr("data-id");
|
||||
d3.select("#defs-markers").select(id).select("text").attr("fill", this.value);
|
||||
}
|
||||
|
||||
function togglePinVisibility() {
|
||||
const id = elSelected.attr("data-id");
|
||||
let show = 1;
|
||||
if (this.className === "icon-info-circled") {
|
||||
this.className = "icon-info";
|
||||
show = 0;
|
||||
} else this.className = "icon-info-circled";
|
||||
d3.select(id).select("circle").attr("opacity", show);
|
||||
d3.select(id).select("path").attr("opacity", show);
|
||||
function redrawPin({i, hidden, pin = "bubble", fill = "#fff", stroke = "#000"}) {
|
||||
const pinGroup = !hidden && document.querySelector(`#marker${i} > g`);
|
||||
if (pinGroup) pinGroup.innerHTML = getPin(pin, fill, stroke);
|
||||
}
|
||||
|
||||
function editMarkerLegend() {
|
||||
const id = elSelected.attr("id");
|
||||
const id = element.id;
|
||||
editNotes(id, id);
|
||||
}
|
||||
|
||||
function toggleAddMarker() {
|
||||
document.getElementById("addMarker").click();
|
||||
addMarker.click();
|
||||
}
|
||||
|
||||
function removeMarker() {
|
||||
alertMessage.innerHTML = "Are you sure you want to remove the marker?";
|
||||
$("#alert").dialog({
|
||||
resizable: false,
|
||||
function confirmMarkerDeletion() {
|
||||
confirmationDialog({
|
||||
title: "Remove marker",
|
||||
buttons: {
|
||||
Remove: function () {
|
||||
$(this).dialog("close");
|
||||
const index = notes.findIndex(n => n.id === elSelected.attr("id"));
|
||||
if (index != -1) notes.splice(index, 1);
|
||||
elSelected.remove();
|
||||
$("#markerEditor").dialog("close");
|
||||
},
|
||||
Cancel: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
message: "Are you sure you want to remove this marker? The action cannot be reverted",
|
||||
confirm: "Remove",
|
||||
onConfirm: deleteMarker
|
||||
});
|
||||
}
|
||||
|
||||
function deleteMarker() {
|
||||
notes = notes.filter(note => note.id !== element.id);
|
||||
pack.markers = pack.markers.filter(m => m.i !== marker.i);
|
||||
element.remove();
|
||||
$("#markerEditor").dialog("close");
|
||||
}
|
||||
|
||||
function closeMarkerEditor() {
|
||||
listeners.forEach(removeListener => removeListener());
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,9 @@ toolsContent.addEventListener("click", function (event) {
|
|||
},
|
||||
open: function () {
|
||||
const pane = $(this).dialog("widget").find(".ui-dialog-buttonpane");
|
||||
$('<span><input id="dontAsk" class="checkbox" type="checkbox"><label for="dontAsk" class="checkbox-label dontAsk"><i>do not ask again</i></label><span>').prependTo(pane);
|
||||
$(
|
||||
'<span><input id="dontAsk" class="checkbox" type="checkbox"><label for="dontAsk" class="checkbox-label dontAsk"><i>do not ask again</i></label><span>'
|
||||
).prependTo(pane);
|
||||
},
|
||||
close: function () {
|
||||
const box = $(this).dialog("widget").find(".checkbox")[0];
|
||||
|
|
@ -262,7 +264,8 @@ function regenerateBurgs() {
|
|||
|
||||
const score = new Int16Array(cells.s.map(s => s * Math.random())); // cell score for capitals placement
|
||||
const sorted = cells.i.filter(i => score[i] > 0 && cells.culture[i]).sort((a, b) => score[b] - score[a]); // filtered and sorted array of indexes
|
||||
const burgsCount = manorsInput.value == 1000 ? rn(sorted.length / 5 / (grid.points.length / 10000) ** 0.8) + states.length : +manorsInput.value + states.length;
|
||||
const burgsCount =
|
||||
manorsInput.value == 1000 ? rn(sorted.length / 5 / (grid.points.length / 10000) ** 0.8) + states.length : +manorsInput.value + states.length;
|
||||
const spacing = (graphWidth + graphHeight) / 150 / (burgsCount ** 0.7 / 66); // base min distance between towns
|
||||
|
||||
//clear locked list since ids will change
|
||||
|
|
@ -414,6 +417,7 @@ function regenerateIce() {
|
|||
}
|
||||
|
||||
function regenerateMarkers(event) {
|
||||
// TODO: rework for new markers system
|
||||
if (isCtrlClick(event)) prompt("Please provide markers number multiplier", {default: 1, step: 0.01, min: 0, max: 100}, v => addNumberOfMarkers(v));
|
||||
else addNumberOfMarkers(gauss(1, 0.5, 0.3, 5, 2));
|
||||
|
||||
|
|
@ -475,7 +479,18 @@ function addLabelOnClick() {
|
|||
const id = getNextId("label");
|
||||
|
||||
let group = labels.select("#addedLabels");
|
||||
if (!group.size()) group = labels.append("g").attr("id", "addedLabels").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("font-size", 18).attr("data-size", 18).attr("filter", null);
|
||||
if (!group.size())
|
||||
group = labels
|
||||
.append("g")
|
||||
.attr("id", "addedLabels")
|
||||
.attr("fill", "#3e3e4b")
|
||||
.attr("opacity", 1)
|
||||
.attr("stroke", "#3a3a3a")
|
||||
.attr("stroke-width", 0)
|
||||
.attr("font-family", "Almendra SC")
|
||||
.attr("font-size", 18)
|
||||
.attr("data-size", 18)
|
||||
.attr("filter", null);
|
||||
|
||||
const example = group.append("text").attr("x", 0).attr("x", 0).text(name);
|
||||
const width = example.node().getBBox().width;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue