mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
115 lines
3.6 KiB
JavaScript
115 lines
3.6 KiB
JavaScript
import * as d3 from "d3";
|
|
|
|
import {rn} from "../utils/numberUtils";
|
|
import {parseTransform} from "utils/stringUtils";
|
|
|
|
export function drawLegend(name, data) {
|
|
legend.selectAll("*").remove(); // fully redraw every time
|
|
legend.attr("data", data.join("|")); // store data
|
|
|
|
const itemsInCol = +styleLegendColItems.value;
|
|
const fontSize = +legend.attr("font-size");
|
|
const backClr = styleLegendBack.value;
|
|
const opacity = +styleLegendOpacity.value;
|
|
|
|
const lineHeight = Math.round(fontSize * 1.7);
|
|
const colorBoxSize = Math.round(fontSize / 1.7);
|
|
const colOffset = fontSize;
|
|
const vOffset = fontSize / 2;
|
|
|
|
// append items
|
|
const boxes = legend.append("g").attr("stroke-width", 0.5).attr("stroke", "#111111").attr("stroke-dasharray", "none");
|
|
const labels = legend.append("g").attr("fill", "#000000").attr("stroke", "none");
|
|
|
|
const columns = Math.ceil(data.length / itemsInCol);
|
|
for (let column = 0, i = 0; column < columns; column++) {
|
|
const linesInColumn = Math.ceil(data.length / columns);
|
|
const offset = column ? colOffset * 2 + legend.node().getBBox().width : colOffset;
|
|
|
|
for (let l = 0; l < linesInColumn && data[i]; l++, i++) {
|
|
boxes
|
|
.append("rect")
|
|
.attr("fill", data[i][1])
|
|
.attr("x", offset)
|
|
.attr("y", lineHeight + l * lineHeight + vOffset)
|
|
.attr("width", colorBoxSize)
|
|
.attr("height", colorBoxSize);
|
|
|
|
labels
|
|
.append("text")
|
|
.text(data[i][2])
|
|
.attr("x", offset + colorBoxSize * 1.6)
|
|
.attr("y", fontSize / 1.6 + lineHeight + l * lineHeight + vOffset);
|
|
}
|
|
}
|
|
|
|
// append label
|
|
const offset = colOffset + legend.node().getBBox().width / 2;
|
|
labels
|
|
.append("text")
|
|
.attr("text-anchor", "middle")
|
|
.attr("font-weight", "bold")
|
|
.attr("font-size", "1.2em")
|
|
.attr("id", "legendLabel")
|
|
.text(name)
|
|
.attr("x", offset)
|
|
.attr("y", fontSize * 1.1 + vOffset / 2);
|
|
|
|
// append box
|
|
const bbox = legend.node().getBBox();
|
|
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);
|
|
|
|
fitLegendBox();
|
|
}
|
|
|
|
// fit Legend box to canvas size
|
|
export function fitLegendBox() {
|
|
if (!legend.selectAll("*").size()) return;
|
|
const px = isNaN(+legend.attr("data-x")) ? 99 : legend.attr("data-x") / 100;
|
|
const py = isNaN(+legend.attr("data-y")) ? 93 : legend.attr("data-y") / 100;
|
|
const bbox = legend.node().getBBox();
|
|
const x = rn(svgWidth * px - bbox.width),
|
|
y = rn(svgHeight * py - bbox.height);
|
|
legend.attr("transform", `translate(${x},${y})`);
|
|
}
|
|
|
|
// draw legend with the same data, but using different settings
|
|
export function redrawLegend() {
|
|
if (!legend.select("rect").size()) return;
|
|
const name = legend.select("#legendLabel").text();
|
|
const data = legend
|
|
.attr("data")
|
|
.split("|")
|
|
.map(l => l.split(","));
|
|
drawLegend(name, data);
|
|
}
|
|
|
|
export function dragLegendBox() {
|
|
const tr = parseTransform(this.getAttribute("transform"));
|
|
const x = +tr[0] - d3.event.x;
|
|
const y = +tr[1] - d3.event.y;
|
|
const bbox = legend.node().getBBox();
|
|
|
|
d3.event.on("drag", function () {
|
|
const px = rn(((x + d3.event.x + bbox.width) / svgWidth) * 100, 2);
|
|
const py = rn(((y + d3.event.y + bbox.height) / svgHeight) * 100, 2);
|
|
const transform = `translate(${x + d3.event.x},${y + d3.event.y})`;
|
|
legend.attr("transform", transform).attr("data-x", px).attr("data-y", py);
|
|
});
|
|
}
|
|
|
|
export function clearLegend() {
|
|
legend.selectAll("*").remove();
|
|
legend.attr("data", null);
|
|
}
|