feat: burg groups - support styling

This commit is contained in:
Azgaar 2024-12-19 22:35:36 +01:00
parent 4185611791
commit c86f7de9de
6 changed files with 146 additions and 127 deletions

View file

@ -1059,6 +1059,46 @@
</tr> </tr>
</tbody> </tbody>
<tbody id="styleBurgIcons">
<tr data-tip="Select group icon">
<td>Icon</td>
<td>
<select id="styleBurgIconsIcon">
<option value="#icon-circle">Circle</option>
<option value="#icon-square">Square</option>
<option value="#icon-triangle">Triangle</option>
<option value="#icon-star">Star</option>
</select>
</td>
</tr>
<tr data-tip="Set icon size">
<td>Icon size</td>
<td>
<slider-input id="styleBurgIconsIconSize" min="0.01" max="20" step=".01"></slider-input>
</td>
</tr>
<tr data-tip="Set icon stroke linejoin"></tr>
<td>Stroke linejoin</td>
<td>
<select id="styleBurgIconsStrokeLinejoin">
<option value="inherit" selected>Inherit</option>
<option value="butt">Butt</option>
<option value="round">Round</option>
<option value="square">Square</option>
</select>
</td>
</tr>
<tr data-tip="Define transparency of fill color">
<td>Fill opacity</td>
<td>
<slider-input id="styleBurgIconsFillOpacity" min="0" max="1" step=".01"></slider-input>
</td>
</tr>
</tbody>
<tbody id="styleGrid"> <tbody id="styleGrid">
<tr data-tip="Select grid overlay type"> <tr data-tip="Select grid overlay type">
<td>Type</td> <td>Type</td>
@ -1177,7 +1217,7 @@
<tr data-tip="Set stroke width"> <tr data-tip="Set stroke width">
<td>Stroke width</td> <td>Stroke width</td>
<td> <td>
<slider-input id="styleStrokeWidthInput" min="0" max="5" step=".01"></slider-input> <slider-input id="styleStrokeWidthInput" min="0" max="10" step=".01"></slider-input>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -1186,7 +1226,7 @@
<tr data-tip="Set letter spacing"> <tr data-tip="Set letter spacing">
<td>Letter spacing</td> <td>Letter spacing</td>
<td> <td>
<slider-input id="styleLetterSpacingInput" min="0" max="20" step=".01"></slider-input> <slider-input id="styleLetterSpacingInput" min="-1" max="10" step=".01"></slider-input>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -1236,24 +1276,11 @@
</tr> </tr>
</tbody> </tbody>
<tbody id="styleRadius"> <tbody id="styleFontShift">
<tr data-tip="Set icon size"> <tr data-tip="Set font shoft along Y axis">
<td>Radius</td> <td>Font shift Y</td>
<td> <td>
<button id="styleRadiusPlus" data-tip="Multiply radius by 1.1" class="whiteButton">+</button> <slider-input id="styleFontShiftY" min="-5" max="5" step=".01"></slider-input>
<button id="styleRadiusMinus" data-tip="Multiply radius by 1.1" class="whiteButton">-</button>
<input id="styleRadiusInput" type="number" min=".2" max="10" step=".02" value="1" />
</td>
</tr>
</tbody>
<tbody id="styleIconSize">
<tr data-tip="Set icon size">
<td>Size</td>
<td>
<button id="styleIconSizePlus" data-tip="Multiply size by 1.1" class="whiteButton">+</button>
<button id="styleIconSizeMinus" data-tip="Multiply size by 1.1" class="whiteButton">-</button>
<input id="styleIconSizeInput" type="number" min=".2" max="10" step=".02" value="1" />
</td> </td>
</tr> </tr>
</tbody> </tbody>

View file

@ -10,6 +10,7 @@ function drawBurgLabels() {
const labelGroup = burgLabels.select("#" + name); const labelGroup = burgLabels.select("#" + name);
if (labelGroup.empty()) continue; if (labelGroup.empty()) continue;
const dy = labelGroup.attr("data-dy");
labelGroup labelGroup
.selectAll("text") .selectAll("text")
@ -20,7 +21,7 @@ function drawBurgLabels() {
.attr("data-id", d => d.i) .attr("data-id", d => d.i)
.attr("x", d => d.x) .attr("x", d => d.x)
.attr("y", d => d.y) .attr("y", d => d.y)
.attr("dy", "-0.4em") .attr("dy", dy + "em")
.text(d => d.name); .text(d => d.name);
} }
@ -28,14 +29,16 @@ function drawBurgLabels() {
} }
function drawBurgLabel(burg) { function drawBurgLabel(burg) {
burgLabels const group = burgLabels.select("#" + burg.group);
.select("#" + burg.group) const dy = labelGroup.attr("data-dy");
group
.append("text") .append("text")
.attr("id", "burgLabel" + burg.i) .attr("id", "burgLabel" + burg.i)
.attr("data-id", burg.i) .attr("data-id", burg.i)
.attr("x", burg.x) .attr("x", burg.x)
.attr("y", burg.y) .attr("y", burg.y)
.attr("dy", "-0.4em") .attr("dy", dy + "em")
.text(burg.name); .text(burg.name);
} }

View file

@ -317,16 +317,6 @@ function addStylePreset() {
] ]
}; };
const burgIconsAttributes = [
"opacity",
"fill",
"fill-opacity",
"size",
"stroke",
"stroke-width",
"stroke-dasharray",
"stroke-linecap"
];
const burgLabelsAttributes = [ const burgLabelsAttributes = [
"opacity", "opacity",
"fill", "fill",
@ -334,11 +324,24 @@ function addStylePreset() {
"letter-spacing", "letter-spacing",
"data-size", "data-size",
"font-size", "font-size",
"font-family" "font-family",
"data-dy"
];
const burgIconsAttributes = [
"opacity",
"data-icon",
"font-size",
"fill",
"fill-opacity",
"stroke",
"stroke-width",
"stroke-dasharray",
"stroke-linecap",
"stroke-linejoin"
]; ];
options.burgs.groups.forEach(({name}) => { options.burgs.groups.forEach(({name}) => {
attributes[`#burgIcons > g#${name}`] = burgIconsAttributes;
attributes[`#burgLabels > g#${name}`] = burgLabelsAttributes; attributes[`#burgLabels > g#${name}`] = burgLabelsAttributes;
attributes[`#burgIcons > g#${name}`] = burgIconsAttributes;
}); });
for (const selector in attributes) { for (const selector in attributes) {

View file

@ -140,9 +140,17 @@ function selectStyleElement() {
// stroke dash // stroke dash
if ( if (
["borders", "cells", "coordinates", "gridOverlay", "legend", "population", "routes", "temperature", "zones"].includes( [
styleElement "borders",
) "cells",
"coordinates",
"gridOverlay",
"legend",
"population",
"routes",
"temperature",
"zones"
].includes(styleElement)
) { ) {
styleStrokeDash.style.display = "block"; styleStrokeDash.style.display = "block";
styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || ""; styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || "";
@ -240,6 +248,16 @@ function selectStyleElement() {
styleStatesHaloBlur.value = parseFloat(statesHalo.attr("filter")?.match(/blur\(([^)]+)\)/)?.[1]) || 0; styleStatesHaloBlur.value = parseFloat(statesHalo.attr("filter")?.match(/blur\(([^)]+)\)/)?.[1]) || 0;
} }
if (styleElement === "provs") {
styleFill.style.display = "block";
styleSize.style.display = "block";
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#111111";
styleFont.style.display = "block";
styleSelectFont.value = el.attr("font-family");
styleFontSize.value = el.attr("font-size");
}
if (styleElement === "labels") { if (styleElement === "labels") {
styleFill.style.display = "block"; styleFill.style.display = "block";
styleStroke.style.display = "block"; styleStroke.style.display = "block";
@ -258,41 +276,38 @@ function selectStyleElement() {
styleFont.style.display = "block"; styleFont.style.display = "block";
styleSelectFont.value = el.attr("font-family"); styleSelectFont.value = el.attr("font-family");
styleFontSize.value = el.attr("data-size"); styleFontSize.value = el.attr("data-size");
if (el.node().parentNode.id === "burgLabels") {
styleFontShift.style.display = "block";
styleFontShiftY.value = el.attr("data-dy") || 0;
} }
if (styleElement === "provs") {
styleFill.style.display = "block";
styleSize.style.display = "block";
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#111111";
styleFont.style.display = "block";
styleSelectFont.value = el.attr("font-family");
styleFontSize.value = el.attr("font-size");
} }
if (styleElement == "burgIcons") { if (styleElement == "burgIcons") {
styleBurgIcons.style.display = "block";
styleBurgIconsIcon.value = el.attr("data-icon");
styleBurgIconsIconSize.value = el.attr("font-size");
styleBurgIconsStrokeLinejoin.value = el.attr("stroke-linejoin");
styleBurgIconsFillOpacity.value = el.attr("fill-opacity");
styleFill.style.display = "block"; styleFill.style.display = "block";
styleStroke.style.display = "block"; styleStroke.style.display = "block";
styleStrokeWidth.style.display = "block"; styleStrokeWidth.style.display = "block";
styleStrokeDash.style.display = "block"; styleStrokeDash.style.display = "block";
styleRadius.style.display = "block";
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff"; styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff";
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b"; styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b";
styleStrokeWidthInput.value = el.attr("stroke-width") || 0.24; styleStrokeWidthInput.value = el.attr("stroke-width") || 0.24;
styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || ""; styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || "";
styleStrokeLinecapInput.value = el.attr("stroke-linecap") || "inherit"; styleStrokeLinecapInput.value = el.attr("stroke-linecap") || "inherit";
styleRadiusInput.value = el.attr("size") || 1;
} }
if (styleElement == "anchors") { if (styleElement == "anchors") {
styleFill.style.display = "block"; styleFill.style.display = "block";
styleStroke.style.display = "block"; styleStroke.style.display = "block";
styleStrokeWidth.style.display = "block"; styleStrokeWidth.style.display = "block";
styleIconSize.style.display = "block";
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff"; styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff";
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b"; styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b";
styleStrokeWidthInput.value = el.attr("stroke-width") || 0.24; styleStrokeWidthInput.value = el.attr("stroke-width") || 0.24;
styleIconSizeInput.value = el.attr("size") || 2;
} }
if (styleElement === "legend") { if (styleElement === "legend") {
@ -750,6 +765,25 @@ stylePopulationUrbanStrokeInput.on("input", e => {
stylePopulationUrbanStrokeOutput.value = e.target.value; stylePopulationUrbanStrokeOutput.value = e.target.value;
}); });
styleBurgIconsIcon.on("change", e => {
getEl()
.attr("data-icon", e.target.value)
.selectAll("use")
.attr("href", d => e.target.value);
});
styleBurgIconsIconSize.on("input", e => {
getEl().attr("font-size", e.target.value);
});
styleBurgIconsStrokeLinejoin.on("change", e => {
getEl().attr("stroke-linejoin", e.target.value);
});
styleBurgIconsFillOpacity.on("input", e => {
getEl().attr("fill-opacity", e.target.value);
});
styleCompassSizeInput.on("input", shiftCompass); styleCompassSizeInput.on("input", shiftCompass);
styleCompassShiftX.on("input", shiftCompass); styleCompassShiftX.on("input", shiftCompass);
styleCompassShiftY.on("input", shiftCompass); styleCompassShiftY.on("input", shiftCompass);
@ -858,71 +892,13 @@ function changeFontSize(el, size) {
if (styleElementSelect.value === "legend") redrawLegend(); if (styleElementSelect.value === "legend") redrawLegend();
} }
styleRadiusInput.on("change", function () { styleFontShiftY.on("input", e => {
changeRadius(+this.value); getEl()
}); .attr("data-dy", e.target.value)
styleRadiusPlus.on("click", function () {
const size = Math.max(rn(getEl().attr("size") * 1.1, 2), 0.2);
changeRadius(size);
});
styleRadiusMinus.on("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);
});
styleRadiusInput.value = size;
burgLabels
.select("g#" + g)
.selectAll("text") .selectAll("text")
.each(function () { .attr("dy", e.target.value + "em");
this.setAttribute("dy", `${size * -1.5}px`);
});
changeIconSize(size * 2, g); // change also anchor icons
}
styleIconSizeInput.on("change", function () {
changeIconSize(+this.value);
}); });
styleIconSizePlus.on("click", function () {
const size = Math.max(rn(getEl().attr("size") * 1.1, 2), 0.2);
changeIconSize(size);
});
styleIconSizeMinus.on("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();
if (!el.size()) {
console.warn(`Group ${group} not found. Can not set icon size!`);
return;
}
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);
});
styleIconSizeInput.value = size;
}
styleStatesBodyOpacity.on("input", e => { styleStatesBodyOpacity.on("input", e => {
statesBody.attr("opacity", e.target.value); statesBody.attr("opacity", e.target.value);
}); });

View file

@ -82,10 +82,11 @@ function openSubmapTool() {
function rescaleBurgStyles(scale) { function rescaleBurgStyles(scale) {
const burgIcons = [...byId("burgIcons").querySelectorAll("g")]; const burgIcons = [...byId("burgIcons").querySelectorAll("g")];
for (const group of burgIcons) { for (const group of burgIcons) {
const newRadius = rn(minmax(group.getAttribute("size") * scale, 0.2, 10), 2); const newSize = rn(minmax(group.getAttribute("size") * scale, 0.2, 10), 2);
changeRadius(newRadius, group.id); group.setAttribute("font-size", newSize);
const strokeWidth = group.attributes["stroke-width"];
strokeWidth.value = strokeWidth.value * scale; const newStroke = rn(group.getAttribute("stroke-width") * scale, 2);
group.setAttribute("stroke-width", newStroke);
} }
const burgLabels = [...byId("burgLabels").querySelectorAll("g")]; const burgLabels = [...byId("burgLabels").querySelectorAll("g")];

View file

@ -335,7 +335,8 @@
"letter-spacing": 0, "letter-spacing": 0,
"data-size": 7, "data-size": 7,
"font-size": 7, "font-size": 7,
"font-family": "Almendra SC" "font-family": "Almendra SC",
"data-dy": -0.4
}, },
"#burgIcons > g#capitals": { "#burgIcons > g#capitals": {
"data-icon": "#icon-square", "data-icon": "#icon-square",
@ -356,7 +357,8 @@
"letter-spacing": 0, "letter-spacing": 0,
"data-size": 5, "data-size": 5,
"font-size": 5, "font-size": 5,
"font-family": "Almendra SC" "font-family": "Almendra SC",
"data-dy": -0.4
}, },
"#burgIcons > g#cities": { "#burgIcons > g#cities": {
"data-icon": "#icon-circle", "data-icon": "#icon-circle",
@ -377,7 +379,8 @@
"letter-spacing": 0, "letter-spacing": 0,
"data-size": 2, "data-size": 2,
"font-size": 2, "font-size": 2,
"font-family": "Almendra SC" "font-family": "Almendra SC",
"data-dy": -0.4
}, },
"#burgIcons > g#forts": { "#burgIcons > g#forts": {
"data-icon": "#icon-triangle", "data-icon": "#icon-triangle",
@ -398,7 +401,8 @@
"letter-spacing": 0, "letter-spacing": 0,
"data-size": 2, "data-size": 2,
"font-size": 2, "font-size": 2,
"font-family": "Almendra SC" "font-family": "Almendra SC",
"data-dy": -0.4
}, },
"#burgIcons > g#monasteries": { "#burgIcons > g#monasteries": {
"data-icon": "#icon-triangle", "data-icon": "#icon-triangle",
@ -419,7 +423,8 @@
"letter-spacing": 0, "letter-spacing": 0,
"data-size": 2, "data-size": 2,
"font-size": 2, "font-size": 2,
"font-family": "Almendra SC" "font-family": "Almendra SC",
"data-dy": -0.4
}, },
"#burgIcons > g#caravanserais": { "#burgIcons > g#caravanserais": {
"data-icon": "#icon-triangle", "data-icon": "#icon-triangle",
@ -440,7 +445,8 @@
"letter-spacing": 0, "letter-spacing": 0,
"data-size": 2, "data-size": 2,
"font-size": 2, "font-size": 2,
"font-family": "Almendra SC" "font-family": "Almendra SC",
"data-dy": -0.4
}, },
"#burgIcons > g#trading_posts": { "#burgIcons > g#trading_posts": {
"data-icon": "#icon-triangle", "data-icon": "#icon-triangle",
@ -461,7 +467,8 @@
"letter-spacing": 0, "letter-spacing": 0,
"data-size": 3, "data-size": 3,
"font-size": 3, "font-size": 3,
"font-family": "Almendra SC" "font-family": "Almendra SC",
"data-dy": -0.4
}, },
"#burgIcons > g#villages": { "#burgIcons > g#villages": {
"data-icon": "#icon-circle", "data-icon": "#icon-circle",
@ -482,7 +489,8 @@
"letter-spacing": 0, "letter-spacing": 0,
"data-size": 2, "data-size": 2,
"font-size": 2, "font-size": 2,
"font-family": "Almendra SC" "font-family": "Almendra SC",
"data-dy": -0.4
}, },
"#burgIcons > g#hamlets": { "#burgIcons > g#hamlets": {
"data-icon": "#icon-circle", "data-icon": "#icon-circle",
@ -503,7 +511,8 @@
"letter-spacing": 0, "letter-spacing": 0,
"data-size": 4, "data-size": 4,
"font-size": 4, "font-size": 4,
"font-family": "Almendra SC" "font-family": "Almendra SC",
"data-dy": -0.4
}, },
"#burgIcons > g#towns": { "#burgIcons > g#towns": {
"data-icon": "#icon-circle", "data-icon": "#icon-circle",