diff --git a/index.html b/index.html
index 03e702de..0c7703f6 100644
--- a/index.html
+++ b/index.html
@@ -437,14 +437,12 @@
data-tip="Click to save displayed layers as a new preset"
class="icon-plus sideButton"
style="display: none"
- onclick="savePreset()"
>
@@ -1348,7 +1346,7 @@
|
-
+
|
@@ -1386,14 +1384,14 @@
|
-
+
|
|
-
+
|
@@ -5576,7 +5574,7 @@
id="showLabels"
class="checkbox"
type="checkbox"
- onchange="hideLabels.checked = !this.checked; invokeActiveZooming()"
+ onchange="hideLabels.checked = !this.checked; Zoom.invoke()"
checked
/>
diff --git a/src/main.js b/src/main.js
index 825d00f6..1c3d3a78 100644
--- a/src/main.js
+++ b/src/main.js
@@ -6,7 +6,6 @@ console.log("Hello World");
import "./components";
import {ERROR, INFO, TIME, WARN} from "./config/logging";
import {UINT16_MAX} from "./constants";
-import {invokeActiveZooming} from "./modules/activeZooming";
import {clearLegend} from "./modules/legend";
import {drawScaleBar, Ruler, Rulers} from "./modules/measurers";
import {applyPreset, drawBorders, drawRivers, drawStates} from "./modules/ui/layers";
@@ -33,6 +32,7 @@ import {minmax, normalize, rn} from "./utils/numberUtils";
import {gauss, generateSeed, P, ra, rand, rw} from "./utils/probabilityUtils";
import {byId} from "./utils/shorthands";
import {round} from "./utils/stringUtils";
+import {restoreLayers} from "./modules/ui/layers";
addGlobalListeners();
@@ -286,7 +286,7 @@ function findBurgForMFCG(params) {
}
Zoom.to(b.x, b.y, 8, 1600);
- invokeActiveZooming();
+ Zoom.invoke();
tip("Here stands the glorious city of " + b.name, true, "success", 15000);
}
@@ -357,7 +357,7 @@ async function generate(options) {
const timeStart = performance.now();
const {seed: precreatedSeed, graph: precreatedGraph} = options || {};
- invokeActiveZooming();
+ Zoom.invoke();
setSeed(precreatedSeed);
INFO && console.group("Generated Map " + seed);
diff --git a/src/modules/dynamic/auto-update.js b/src/modules/dynamic/auto-update.js
index 52627212..0249d940 100644
--- a/src/modules/dynamic/auto-update.js
+++ b/src/modules/dynamic/auto-update.js
@@ -2,6 +2,7 @@ import {findCell} from "/src/utils/graphUtils";
import {rn} from "/src/utils/numberUtils";
import {rand, P, rw} from "/src/utils/probabilityUtils";
import {parseTransform} from "/src/utils/stringUtils";
+import {turnLayerButtonOn, turnLayerButtonOff} from "/src/modules/ui/layers";
// update old .map version to the current one
export function resolveVersionConflicts(version) {
@@ -69,7 +70,7 @@ export function resolveVersionConflicts(version) {
addZones();
if (!markers.selectAll("*").size()) {
Markers.generate();
- turnButtonOn("toggleMarkers");
+ turnLayerButtonOn("toggleMarkers");
}
// v1.0 add fogging layer (state focus)
@@ -282,7 +283,7 @@ export function resolveVersionConflicts(version) {
.attr("box-size", 3)
.attr("stroke", "#000")
.attr("stroke-width", 0.3);
- turnButtonOn("toggleMilitary");
+ turnLayerButtonOn("toggleMilitary");
Military.generate();
}
@@ -443,9 +444,9 @@ export function resolveVersionConflicts(version) {
ruler.selectAll("*").remove();
if (rulers.data.length) {
- turnButtonOn("toggleRulers");
+ turnLayerButtonOn("toggleRulers");
rulers.draw();
- } else turnButtonOff("toggleRulers");
+ } else turnLayerButtonOff("toggleRulers");
// 1.61 changed oceanicPattern from rect to image
const pattern = document.getElementById("oceanic");
diff --git a/src/modules/dynamic/heightmap-selection.js b/src/modules/dynamic/heightmap-selection.js
index 3e747751..41f38f9b 100644
--- a/src/modules/dynamic/heightmap-selection.js
+++ b/src/modules/dynamic/heightmap-selection.js
@@ -1,6 +1,7 @@
import {shouldRegenerateGrid, generateGrid} from "/src/utils/graphUtils";
import {byId} from "/src/utils/shorthands";
import {generateSeed} from "/src/utils/probabilityUtils";
+import {getColorScheme} from "/src/utils/colorUtils";
const initialSeed = generateSeed();
let graph = getGraph(grid);
diff --git a/src/modules/io/export.js b/src/modules/io/export.js
index 028ddaec..bd81913c 100644
--- a/src/modules/io/export.js
+++ b/src/modules/io/export.js
@@ -4,6 +4,7 @@ import {tip} from "/src/scripts/tooltips";
import {getCoordinates} from "/src/utils/coordinateUtils";
import {rn} from "/src/utils/numberUtils";
import {getBase64} from "/src/utils/functionUtils";
+import {getColorScheme, getHeightColor} from "/src/utils/colorUtils";
// download map as SVG
async function saveSVG() {
@@ -368,7 +369,7 @@ function updateMeshCells(clone) {
.join("polygon")
.attr("points", d => getGridPolygon(d))
.attr("id", d => "cell" + d)
- .attr("stroke", d => getColor(grid.cells.h[d], scheme));
+ .attr("stroke", d => getHeightColor(grid.cells.h[d], scheme));
}
// for each g element get inline style
diff --git a/src/modules/io/load.js b/src/modules/io/load.js
index d430886b..ad97bc12 100644
--- a/src/modules/io/load.js
+++ b/src/modules/io/load.js
@@ -579,7 +579,7 @@ async function parseLoadedData(data) {
restoreDefaultEvents();
focusOn(); // based on searchParams focus on point, cell or burg
- invokeActiveZooming();
+ Zoom.invoke();
WARN && console.warn(`TOTAL: ${rn((performance.now() - uploadMap.timeStart) / 1000, 2)}s`);
showStatistics();
diff --git a/src/modules/submap.js b/src/modules/submap.js
index 684d25ee..dec90236 100644
--- a/src/modules/submap.js
+++ b/src/modules/submap.js
@@ -28,7 +28,7 @@ window.Submap = (function () {
const inverse = options.inverse;
const stage = s => INFO && console.log("SUBMAP:", s);
const timeStart = performance.now();
- invokeActiveZooming();
+ Zoom.invoke();
// copy seed
seed = parentMap.seed;
diff --git a/src/modules/ui/elevation-profile.js b/src/modules/ui/elevation-profile.js
index 597e8d48..9b808544 100644
--- a/src/modules/ui/elevation-profile.js
+++ b/src/modules/ui/elevation-profile.js
@@ -1,5 +1,6 @@
import {findCell} from "/src/utils/graphUtils";
import {rn} from "/src/utils/numberUtils";
+import {getColorScheme, getHeightColor} from "/src/utils/colorUtils";
export function showEPForRoute(node) {
const points = [];
@@ -208,18 +209,18 @@ function showElevationProfile(data, routeLen, isRiver) {
landdef
.append("stop")
.attr("offset", "0%")
- .attr("style", "stop-color:" + getColor(chartData.mih, colors) + ";stop-opacity:1");
+ .attr("style", "stop-color:" + getHeightColor(chartData.mih, colors) + ";stop-opacity:1");
landdef
.append("stop")
.attr("offset", "100%")
- .attr("style", "stop-color:" + getColor(chartData.mah, colors) + ";stop-opacity:1");
+ .attr("style", "stop-color:" + getHeightColor(chartData.mah, colors) + ";stop-opacity:1");
} else {
for (let k = chartData.mah; k >= chartData.mih; k--) {
let perc = 1 - (k - chartData.mih) / (chartData.mah - chartData.mih);
landdef
.append("stop")
.attr("offset", perc * 100 + "%")
- .attr("style", "stop-color:" + getColor(k, colors) + ";stop-opacity:1");
+ .attr("style", "stop-color:" + getHeightColor(k, colors) + ";stop-opacity:1");
}
}
diff --git a/src/modules/ui/heightmap-editor.js b/src/modules/ui/heightmap-editor.js
index f29bc0ac..eb184cbf 100644
--- a/src/modules/ui/heightmap-editor.js
+++ b/src/modules/ui/heightmap-editor.js
@@ -7,6 +7,8 @@ import {rn, minmax, lim} from "/src/utils/numberUtils";
import {link} from "/src/utils/linkUtils";
import {prompt} from "/src/scripts/prompt";
import {throttle} from "/src/utils/functionUtils";
+import {turnLayerButtonOn, turnLayerButtonOff} from "/src/modules/ui/layers";
+import {getColorScheme, getHeightColor} from "/src/utils/colorUtils";
export function editHeightmap(options) {
const {mode, tool} = options || {};
@@ -115,7 +117,7 @@ export function editHeightmap(options) {
.style("transform", "scale(1)");
} else exitCustomization.style.display = "block";
- turnButtonOn("toggleHeight");
+ turnLayerButtonOn("toggleHeight");
layersPreset.value = "heightmap";
layersPreset.disabled = true;
mockHeightmap();
@@ -191,7 +193,7 @@ export function editHeightmap(options) {
// restore initial layers
//viewbox.select("#heights").remove();
byId("heights").remove();
- turnButtonOff("toggleHeight");
+ turnLayerButtonOff("toggleHeight");
document
.getElementById("mapLayers")
.querySelectorAll("li")
@@ -492,7 +494,7 @@ export function editHeightmap(options) {
.join("polygon")
.attr("points", d => getGridPolygon(d))
.attr("id", d => "cell" + d)
- .attr("fill", d => getColor(grid.cells.h[d], scheme));
+ .attr("fill", d => getHeightColor(grid.cells.h[d], scheme));
}
// draw or update heightmap for a selection of cells
@@ -512,7 +514,7 @@ export function editHeightmap(options) {
.append("polygon")
.attr("points", getGridPolygon(i))
.attr("id", "cell" + i);
- cell.attr("fill", getColor(grid.cells.h[i], scheme));
+ cell.attr("fill", getHeightColor(grid.cells.h[i], scheme));
});
}
@@ -1279,7 +1281,7 @@ export function editHeightmap(options) {
return lum | 0; // land
};
- const scheme = d3.range(101).map(i => getColor(i, color()));
+ const scheme = d3.range(101).map(i => getHeightColor(i, color()));
const hues = scheme.map(rgb => d3.hsl(rgb).h | 0);
const getHeightByScheme = function (color) {
let height = scheme.indexOf(color);
diff --git a/src/modules/ui/layers.js b/src/modules/ui/layers.js
index 51f880d0..3bb2b5cb 100644
--- a/src/modules/ui/layers.js
+++ b/src/modules/ui/layers.js
@@ -1,202 +1,115 @@
import {TIME} from "/src/config/logging";
-import {invokeActiveZooming} from "../activeZooming";
-import {getGridPolygon} from "/src/utils/graphUtils";
-import {last} from "/src/utils/arrayUtils";
-import {stored, store} from "/src/utils/shorthands";
-import {tip} from "/src/scripts/tooltips";
-import {byId} from "/src/utils/shorthands";
-import {clipPoly} from "/src/utils/lineUtils";
-import {rn, minmax, normalize} from "/src/utils/numberUtils";
-import {isCtrlClick} from "/src/utils/keyboardUtils";
import {prompt} from "/src/scripts/prompt";
-import {rand, P} from "/src/utils/probabilityUtils";
-import {convertTemperature} from "/src/utils/unitUtils";
+import {tip} from "/src/scripts/tooltips";
+import {last} from "/src/utils/arrayUtils";
import {getBase64} from "/src/utils/functionUtils";
+import {getGridPolygon} from "/src/utils/graphUtils";
+import {isCtrlClick} from "/src/utils/keyboardUtils";
+import {clipPoly} from "/src/utils/lineUtils";
+import {minmax, normalize, rn} from "/src/utils/numberUtils";
+import {P, rand} from "/src/utils/probabilityUtils";
+import {byId, store, stored} from "/src/utils/shorthands";
+import {convertTemperature} from "/src/utils/unitUtils";
+import {getColorScheme, getHeightColor} from "/src/utils/colorUtils";
let presets = {};
restoreCustomPresets(); // run on-load
-addToggleLayersListener();
-
-function getDefaultPresets() {
- return {
- political: [
- "toggleBorders",
- "toggleIcons",
- "toggleIce",
- "toggleLabels",
- "toggleRivers",
- "toggleRoutes",
- "toggleScaleBar",
- "toggleStates"
- ],
- cultural: [
- "toggleBorders",
- "toggleCultures",
- "toggleIcons",
- "toggleLabels",
- "toggleRivers",
- "toggleRoutes",
- "toggleScaleBar"
- ],
- religions: [
- "toggleBorders",
- "toggleIcons",
- "toggleLabels",
- "toggleReligions",
- "toggleRivers",
- "toggleRoutes",
- "toggleScaleBar"
- ],
- provinces: ["toggleBorders", "toggleIcons", "toggleProvinces", "toggleRivers", "toggleScaleBar"],
- biomes: ["toggleBiomes", "toggleIce", "toggleRivers", "toggleScaleBar"],
- heightmap: ["toggleHeight", "toggleRivers"],
- physical: ["toggleCoordinates", "toggleHeight", "toggleIce", "toggleRivers", "toggleScaleBar"],
- poi: [
- "toggleBorders",
- "toggleHeight",
- "toggleIce",
- "toggleIcons",
- "toggleMarkers",
- "toggleRivers",
- "toggleRoutes",
- "toggleScaleBar"
- ],
- military: [
- "toggleBorders",
- "toggleIcons",
- "toggleLabels",
- "toggleMilitary",
- "toggleRivers",
- "toggleRoutes",
- "toggleScaleBar",
- "toggleStates"
- ],
- emblems: [
- "toggleBorders",
- "toggleIcons",
- "toggleIce",
- "toggleEmblems",
- "toggleRivers",
- "toggleRoutes",
- "toggleScaleBar",
- "toggleStates"
- ],
- landmass: ["toggleScaleBar"]
- };
-}
+addLayerListeners();
function restoreCustomPresets() {
- presets = getDefaultPresets();
- const storedPresets = JSON.parse(localStorage.getItem("presets"));
- if (!storedPresets) return;
+ const storedPresets = JSON.parse(stored("presets"));
+ if (!storedPresets) {
+ presets = defaultPresets.slice();
+ return;
+ }
for (const preset in storedPresets) {
if (presets[preset]) continue;
- layersPreset.add(new Option(preset, preset));
+ byId("layersPreset").add(new Option(preset, preset));
}
presets = storedPresets;
}
-// run on map generation
-export function applyPreset() {
- const preset = stored("preset") || byId("layersPreset")?.value || "political";
- changePreset(preset);
+function addLayerListeners() {
+ byId("mapLayers").on("click", toggleLayer);
+ byId("savePresetButton").on("click", savePreset);
+ byId("removePresetButton").on("click", removePreset);
}
-// toggle layers on preset change
-function changePreset(preset) {
- const layers = presets[preset]; // layers to be turned on
- const $layerButtons = byId("mapLayers").querySelectorAll("li");
-
- $layerButtons.forEach(function ($layerButton) {
- const {id} = $layerButton;
- if (layers.includes(id) && !layerIsOn(id)) $layerButton.click();
- else if (!layers.includes(id) && layerIsOn(id)) $layerButton.click();
- });
-
- byId("layersPreset").value = preset;
- store("preset", preset);
-
- const isDefault = getDefaultPresets()[preset];
- byId("removePresetButton").style.display = isDefault ? "none" : "inline-block";
- byId("savePresetButton").style.display = "none";
- if (byId("canvas3d")) setTimeout(ThreeD.update(), 400);
+function toggleLayer(event) {
+ const targetId = event.target.id;
+ if (!targetId || targetId === "mapLayers" || !layerTogglesMap[targetId]) return;
+ layerTogglesMap[targetId]();
}
-function savePreset() {
- prompt("Please provide a preset name", {default: ""}, preset => {
- presets[preset] = Array.from(byId("mapLayers").querySelectorAll("li:not(.buttonoff)"))
- .map(node => node.id)
- .sort();
- layersPreset.add(new Option(preset, preset, false, true));
- localStorage.setItem("presets", JSON.stringify(presets));
- localStorage.setItem("preset", preset);
- removePresetButton.style.display = "inline-block";
- savePresetButton.style.display = "none";
- });
-}
+const defaultPresets = {
+ political: [
+ "toggleBorders",
+ "toggleIcons",
+ "toggleIce",
+ "toggleLabels",
+ "toggleRivers",
+ "toggleRoutes",
+ "toggleScaleBar",
+ "toggleStates"
+ ],
+ cultural: [
+ "toggleBorders",
+ "toggleCultures",
+ "toggleIcons",
+ "toggleLabels",
+ "toggleRivers",
+ "toggleRoutes",
+ "toggleScaleBar"
+ ],
+ religions: [
+ "toggleBorders",
+ "toggleIcons",
+ "toggleLabels",
+ "toggleReligions",
+ "toggleRivers",
+ "toggleRoutes",
+ "toggleScaleBar"
+ ],
+ provinces: ["toggleBorders", "toggleIcons", "toggleProvinces", "toggleRivers", "toggleScaleBar"],
+ biomes: ["toggleBiomes", "toggleIce", "toggleRivers", "toggleScaleBar"],
+ heightmap: ["toggleHeight", "toggleRivers"],
+ physical: ["toggleCoordinates", "toggleHeight", "toggleIce", "toggleRivers", "toggleScaleBar"],
+ poi: [
+ "toggleBorders",
+ "toggleHeight",
+ "toggleIce",
+ "toggleIcons",
+ "toggleMarkers",
+ "toggleRivers",
+ "toggleRoutes",
+ "toggleScaleBar"
+ ],
+ military: [
+ "toggleBorders",
+ "toggleIcons",
+ "toggleLabels",
+ "toggleMilitary",
+ "toggleRivers",
+ "toggleRoutes",
+ "toggleScaleBar",
+ "toggleStates"
+ ],
+ emblems: [
+ "toggleBorders",
+ "toggleIcons",
+ "toggleIce",
+ "toggleEmblems",
+ "toggleRivers",
+ "toggleRoutes",
+ "toggleScaleBar",
+ "toggleStates"
+ ],
+ landmass: ["toggleScaleBar"]
+};
-function removePreset() {
- const preset = layersPreset.value;
- delete presets[preset];
- const index = Array.from(layersPreset.options).findIndex(o => o.value === preset);
- layersPreset.options.remove(index);
- layersPreset.value = "custom";
- removePresetButton.style.display = "none";
- savePresetButton.style.display = "inline-block";
-
- localStorage.setItem("presets", JSON.stringify(presets));
- localStorage.removeItem("preset");
-}
-
-function getCurrentPreset() {
- const $toggledOnLayers = byId("mapLayers").querySelectorAll("li:not(.buttonoff)");
- const currentLayers = Array.from($toggledOnLayers)
- .map(node => node.id)
- .sort();
-
- const defaultPresets = getDefaultPresets();
- for (const preset in presets) {
- if (JSON.stringify(presets[preset].sort()) !== JSON.stringify(currentLayers)) continue;
-
- byId("layersPreset").value = preset;
- byId("removePresetButton").style.display = defaultPresets[preset] ? "none" : "inline-block";
- byId("savePresetButton").style.display = "none";
- return;
- }
-
- byId("layersPreset").value = "custom";
- byId("removePresetButton").style.display = "none";
- byId("savePresetButton").style.display = "inline-block";
-}
-
-// run on map regeneration
-export function restoreLayers() {
- if (layerIsOn("toggleHeight")) drawHeightmap();
- if (layerIsOn("toggleCells")) drawCells();
- if (layerIsOn("toggleGrid")) drawGrid();
- if (layerIsOn("toggleCoordinates")) drawCoordinates();
- if (layerIsOn("toggleCompass")) compass.style("display", "block");
- if (layerIsOn("toggleTemp")) drawTemp();
- if (layerIsOn("togglePrec")) drawPrec();
- if (layerIsOn("togglePopulation")) drawPopulation();
- if (layerIsOn("toggleBiomes")) drawBiomes();
- if (layerIsOn("toggleRelief")) ReliefIcons();
- if (layerIsOn("toggleCultures")) drawCultures();
- if (layerIsOn("toggleProvinces")) drawProvinces();
- if (layerIsOn("toggleReligions")) drawReligions();
- if (layerIsOn("toggleIce")) drawIce();
- if (layerIsOn("toggleEmblems")) drawEmblems();
- if (layerIsOn("toggleMarkers")) drawMarkers();
-
- // some layers are rendered each time, remove them if they are not on
- if (!layerIsOn("toggleBorders")) borders.selectAll("path").remove();
- if (!layerIsOn("toggleStates")) regions.selectAll("path").remove();
- if (!layerIsOn("toggleRivers")) rivers.selectAll("*").remove();
-}
-
-export const layerTogglesMap = {
+const layerTogglesMap = {
toggleBiomes,
toggleBorders,
toggleCells,
@@ -226,14 +139,116 @@ export const layerTogglesMap = {
toggleZones
};
-function toggleLayer(event) {
- const targetId = event.target.id;
- if (!targetId || targetId === "mapLayers" || !layerTogglesMap[targetId]) return;
- layerTogglesMap[targetId]();
+// run on map generation
+export function applyPreset() {
+ const preset = stored("preset") || byId("layersPreset")?.value || "political";
+ changePreset(preset);
}
-export function addToggleLayersListener() {
- byId("mapLayers").on("click", toggleLayer);
+// toggle layers on preset change
+function changePreset(preset) {
+ const layers = presets[preset]; // layers to be turned on
+ const $layerButtons = byId("mapLayers").querySelectorAll("li");
+
+ $layerButtons.forEach(function ($layerButton) {
+ const {id} = $layerButton;
+ if (layers.includes(id) && !layerIsOn(id)) $layerButton.click();
+ else if (!layers.includes(id) && layerIsOn(id)) $layerButton.click();
+ });
+
+ byId("layersPreset").value = preset;
+ store("preset", preset);
+
+ const isDefault = defaultPresets[preset];
+ byId("removePresetButton").style.display = isDefault ? "none" : "inline-block";
+ byId("savePresetButton").style.display = "none";
+ if (byId("canvas3d")) setTimeout(ThreeD.update(), 400);
+}
+
+function savePreset() {
+ prompt("Please provide a preset name", {default: ""}, preset => {
+ presets[preset] = Array.from(byId("mapLayers").querySelectorAll("li:not(.buttonoff)"))
+ .map(node => node.id)
+ .sort();
+ layersPreset.add(new Option(preset, preset, false, true));
+ localStorage.setItem("presets", JSON.stringify(presets));
+ localStorage.setItem("preset", preset);
+ removePresetButton.style.display = "inline-block";
+ savePresetButton.style.display = "none";
+ });
+}
+
+function removePreset() {
+ const preset = layersPreset.value;
+ delete presets[preset];
+ const index = Array.from(layersPreset.options).findIndex(o => o.value === preset);
+ layersPreset.options.remove(index);
+ layersPreset.value = "custom";
+ removePresetButton.style.display = "none";
+ savePresetButton.style.display = "inline-block";
+
+ store("presets", JSON.stringify(presets));
+ localStorage.removeItem("preset");
+}
+
+// run on map regeneration
+export function restoreLayers() {
+ if (layerIsOn("toggleHeight")) drawHeightmap();
+ if (layerIsOn("toggleCells")) drawCells();
+ if (layerIsOn("toggleGrid")) drawGrid();
+ if (layerIsOn("toggleCoordinates")) drawCoordinates();
+ if (layerIsOn("toggleCompass")) compass.style("display", "block");
+ if (layerIsOn("toggleTemp")) drawTemp();
+ if (layerIsOn("togglePrec")) drawPrec();
+ if (layerIsOn("togglePopulation")) drawPopulation();
+ if (layerIsOn("toggleBiomes")) drawBiomes();
+ if (layerIsOn("toggleRelief")) ReliefIcons();
+ if (layerIsOn("toggleCultures")) drawCultures();
+ if (layerIsOn("toggleProvinces")) drawProvinces();
+ if (layerIsOn("toggleReligions")) drawReligions();
+ if (layerIsOn("toggleIce")) drawIce();
+ if (layerIsOn("toggleEmblems")) drawEmblems();
+ if (layerIsOn("toggleMarkers")) drawMarkers();
+
+ // some layers are rendered each time, remove them if they are not on
+ if (!layerIsOn("toggleBorders")) borders.selectAll("path").remove();
+ if (!layerIsOn("toggleStates")) regions.selectAll("path").remove();
+ if (!layerIsOn("toggleRivers")) rivers.selectAll("*").remove();
+}
+
+export function layerIsOn(el) {
+ const buttonoff = byId(el).classList.contains("buttonoff");
+ return !buttonoff;
+}
+
+function turnLayerButtonOn(el) {
+ byId(el).classList.remove("buttonoff");
+ updatePresetInput();
+}
+
+function turnLayerButtonOff(el) {
+ byId(el).classList.add("buttonoff");
+ updatePresetInput();
+}
+
+function updatePresetInput() {
+ const $toggledOnLayers = byId("mapLayers").querySelectorAll("li:not(.buttonoff)");
+ const currentLayers = Array.from($toggledOnLayers)
+ .map(node => node.id)
+ .sort();
+
+ for (const preset in presets) {
+ if (JSON.stringify(presets[preset].sort()) !== JSON.stringify(currentLayers)) continue;
+
+ byId("layersPreset").value = preset;
+ byId("removePresetButton").style.display = defaultPresets[preset] ? "none" : "inline-block";
+ byId("savePresetButton").style.display = "none";
+ return;
+ }
+
+ byId("layersPreset").value = "custom";
+ byId("removePresetButton").style.display = "none";
+ byId("savePresetButton").style.display = "inline-block";
}
function toggleHeight(event) {
@@ -243,7 +258,7 @@ function toggleHeight(event) {
}
if (!terrs.selectAll("*").size()) {
- turnButtonOn("toggleHeight");
+ turnLayerButtonOn("toggleHeight");
drawHeightmap();
if (event && isCtrlClick(event)) editStyle("terrs");
} else {
@@ -251,7 +266,7 @@ function toggleHeight(event) {
editStyle("terrs");
return;
}
- turnButtonOff("toggleHeight");
+ turnLayerButtonOff("toggleHeight");
terrs.selectAll("*").remove();
}
}
@@ -309,9 +324,10 @@ function drawHeightmap() {
.attr("width", graphWidth)
.attr("height", graphHeight)
.attr("fill", scheme(0.8)); // draw base layer
+
for (const i of d3.range(20, 101)) {
if (paths[i].length < 10) continue;
- const color = getColor(i, scheme);
+ const color = getHeightColor(i, scheme);
if (terracing)
terrs
.append("path")
@@ -354,21 +370,9 @@ function drawHeightmap() {
TIME && console.timeEnd("drawHeightmap");
}
-function getColorScheme(scheme) {
- if (scheme === "bright") return d3.scaleSequential(d3.interpolateSpectral);
- if (scheme === "light") return d3.scaleSequential(d3.interpolateRdYlGn);
- if (scheme === "green") return d3.scaleSequential(d3.interpolateGreens);
- if (scheme === "monochrome") return d3.scaleSequential(d3.interpolateGreys);
- return d3.scaleSequential(d3.interpolateSpectral);
-}
-
-function getColor(value, scheme = getColorScheme()) {
- return scheme(1 - (value < 20 ? value - 5 : value) / 100);
-}
-
function toggleTemp(event) {
if (!temperature.selectAll("*").size()) {
- turnButtonOn("toggleTemp");
+ turnLayerButtonOn("toggleTemp");
drawTemp();
if (event && isCtrlClick(event)) editStyle("temperature");
} else {
@@ -376,7 +380,7 @@ function toggleTemp(event) {
editStyle("temperature");
return;
}
- turnButtonOff("toggleTemp");
+ turnLayerButtonOff("toggleTemp");
temperature.selectAll("*").remove();
}
}
@@ -500,7 +504,7 @@ function drawTemp() {
function toggleBiomes(event) {
if (!biomes.selectAll("path").size()) {
- turnButtonOn("toggleBiomes");
+ turnLayerButtonOn("toggleBiomes");
drawBiomes();
if (event && isCtrlClick(event)) editStyle("biomes");
} else {
@@ -509,7 +513,7 @@ function toggleBiomes(event) {
return;
}
biomes.selectAll("path").remove();
- turnButtonOff("toggleBiomes");
+ turnLayerButtonOff("toggleBiomes");
}
}
@@ -573,7 +577,7 @@ function drawBiomes() {
function togglePrec(event) {
if (!prec.selectAll("circle").size()) {
- turnButtonOn("togglePrec");
+ turnLayerButtonOn("togglePrec");
drawPrec();
if (event && isCtrlClick(event)) editStyle("prec");
} else {
@@ -581,7 +585,7 @@ function togglePrec(event) {
editStyle("prec");
return;
}
- turnButtonOff("togglePrec");
+ turnLayerButtonOff("togglePrec");
const hide = d3.transition().duration(1000).ease(d3.easeSinIn);
prec.selectAll("text").attr("opacity", 1).transition(hide).attr("opacity", 0);
prec.selectAll("circle").transition(hide).attr("r", 0).remove();
@@ -615,7 +619,7 @@ function drawPrec() {
function togglePopulation(event) {
if (!population.selectAll("line").size()) {
- turnButtonOn("togglePopulation");
+ turnLayerButtonOn("togglePopulation");
drawPopulation();
if (event && isCtrlClick(event)) editStyle("population");
} else {
@@ -623,7 +627,7 @@ function togglePopulation(event) {
editStyle("population");
return;
}
- turnButtonOff("togglePopulation");
+ turnLayerButtonOff("togglePopulation");
const isD3data = population.select("line").datum();
if (!isD3data) {
// just remove
@@ -690,7 +694,7 @@ function drawPopulation(event) {
function toggleCells(event) {
if (!cells.selectAll("path").size()) {
- turnButtonOn("toggleCells");
+ turnLayerButtonOn("toggleCells");
drawCells();
if (event && isCtrlClick(event)) editStyle("cells");
} else {
@@ -699,7 +703,7 @@ function toggleCells(event) {
return;
}
cells.selectAll("path").remove();
- turnButtonOff("toggleCells");
+ turnLayerButtonOff("toggleCells");
}
}
@@ -714,7 +718,7 @@ function drawCells() {
function toggleIce(event) {
if (!layerIsOn("toggleIce")) {
- turnButtonOn("toggleIce");
+ turnLayerButtonOn("toggleIce");
$("#ice").fadeIn();
if (!ice.selectAll("*").size()) drawIce();
if (event && isCtrlClick(event)) editStyle("ice");
@@ -724,7 +728,7 @@ function toggleIce(event) {
return;
}
$("#ice").fadeOut();
- turnButtonOff("toggleIce");
+ turnLayerButtonOff("toggleIce");
}
}
@@ -805,7 +809,7 @@ function toggleCultures(event) {
const cultures = pack.cultures.filter(c => c.i && !c.removed);
const empty = !cults.selectAll("path").size();
if (empty && cultures.length) {
- turnButtonOn("toggleCultures");
+ turnLayerButtonOn("toggleCultures");
drawCultures();
if (event && isCtrlClick(event)) editStyle("cults");
} else {
@@ -814,7 +818,7 @@ function toggleCultures(event) {
return;
}
cults.selectAll("path").remove();
- turnButtonOff("toggleCultures");
+ turnLayerButtonOff("toggleCultures");
}
}
@@ -879,7 +883,7 @@ function drawCultures() {
function toggleReligions(event) {
const religions = pack.religions.filter(r => r.i && !r.removed);
if (!relig.selectAll("path").size() && religions.length) {
- turnButtonOn("toggleReligions");
+ turnLayerButtonOn("toggleReligions");
drawReligions();
if (event && isCtrlClick(event)) editStyle("relig");
} else {
@@ -888,7 +892,7 @@ function toggleReligions(event) {
return;
}
relig.selectAll("path").remove();
- turnButtonOff("toggleReligions");
+ turnLayerButtonOff("toggleReligions");
}
}
@@ -990,7 +994,7 @@ function drawReligions() {
function toggleStates(event) {
if (!layerIsOn("toggleStates")) {
- turnButtonOn("toggleStates");
+ turnLayerButtonOn("toggleStates");
regions.style("display", null);
drawStates();
if (event && isCtrlClick(event)) editStyle("regions");
@@ -1000,7 +1004,7 @@ function toggleStates(event) {
return;
}
regions.style("display", "none").selectAll("path").remove();
- turnButtonOff("toggleStates");
+ turnLayerButtonOff("toggleStates");
}
}
@@ -1148,13 +1152,13 @@ export function drawStates() {
return chain;
}
- invokeActiveZooming();
+ Zoom.invoke();
TIME && console.timeEnd("drawStates");
}
function toggleBorders(event) {
if (!layerIsOn("toggleBorders")) {
- turnButtonOn("toggleBorders");
+ turnLayerButtonOn("toggleBorders");
drawBorders();
if (event && isCtrlClick(event)) editStyle("borders");
} else {
@@ -1162,7 +1166,7 @@ function toggleBorders(event) {
editStyle("borders");
return;
}
- turnButtonOff("toggleBorders");
+ turnLayerButtonOff("toggleBorders");
borders.selectAll("path").remove();
}
}
@@ -1276,7 +1280,7 @@ export function drawBorders() {
function toggleProvinces(event) {
if (!layerIsOn("toggleProvinces")) {
- turnButtonOn("toggleProvinces");
+ turnLayerButtonOn("toggleProvinces");
drawProvinces();
if (event && isCtrlClick(event)) editStyle("provs");
} else {
@@ -1285,7 +1289,7 @@ function toggleProvinces(event) {
return;
}
provs.selectAll("*").remove();
- turnButtonOff("toggleProvinces");
+ turnLayerButtonOff("toggleProvinces");
}
}
@@ -1415,7 +1419,7 @@ function getProvincesVertices() {
function toggleGrid(event) {
if (!gridOverlay.selectAll("*").size()) {
- turnButtonOn("toggleGrid");
+ turnLayerButtonOn("toggleGrid");
drawGrid();
calculateFriendlyGridSize();
@@ -1425,7 +1429,7 @@ function toggleGrid(event) {
editStyle("gridOverlay");
return;
}
- turnButtonOff("toggleGrid");
+ turnLayerButtonOff("toggleGrid");
gridOverlay.selectAll("*").remove();
}
}
@@ -1461,7 +1465,7 @@ function drawGrid() {
function toggleCoordinates(event) {
if (!coordinates.selectAll("*").size()) {
- turnButtonOn("toggleCoordinates");
+ turnLayerButtonOn("toggleCoordinates");
drawCoordinates();
if (event && isCtrlClick(event)) editStyle("coordinates");
} else {
@@ -1469,7 +1473,7 @@ function toggleCoordinates(event) {
editStyle("coordinates");
return;
}
- turnButtonOff("toggleCoordinates");
+ turnLayerButtonOff("toggleCoordinates");
coordinates.selectAll("*").remove();
}
}
@@ -1540,7 +1544,7 @@ function getViewPoint(x, y) {
function toggleCompass(event) {
if (!layerIsOn("toggleCompass")) {
- turnButtonOn("toggleCompass");
+ turnLayerButtonOn("toggleCompass");
$("#compass").fadeIn();
if (!compass.selectAll("*").size()) {
compass.append("use").attr("xlink:href", "#rose");
@@ -1553,13 +1557,13 @@ function toggleCompass(event) {
return;
}
$("#compass").fadeOut();
- turnButtonOff("toggleCompass");
+ turnLayerButtonOff("toggleCompass");
}
}
function toggleRelief(event) {
if (!layerIsOn("toggleRelief")) {
- turnButtonOn("toggleRelief");
+ turnLayerButtonOn("toggleRelief");
if (!terrain.selectAll("*").size()) ReliefIcons();
$("#terrain").fadeIn();
if (event && isCtrlClick(event)) editStyle("terrain");
@@ -1569,13 +1573,13 @@ function toggleRelief(event) {
return;
}
$("#terrain").fadeOut();
- turnButtonOff("toggleRelief");
+ turnLayerButtonOff("toggleRelief");
}
}
function toggleTexture(event) {
if (!layerIsOn("toggleTexture")) {
- turnButtonOn("toggleTexture");
+ turnLayerButtonOn("toggleTexture");
// append default texture image selected by default. Don't append on load to not harm performance
if (!texture.selectAll("*").size()) {
const x = +styleTextureShiftX.value;
@@ -1596,19 +1600,19 @@ function toggleTexture(event) {
} else {
if (event && isCtrlClick(event)) return editStyle("texture");
$("#texture").fadeOut();
- turnButtonOff("toggleTexture");
+ turnLayerButtonOff("toggleTexture");
}
}
function toggleRivers(event) {
if (!layerIsOn("toggleRivers")) {
- turnButtonOn("toggleRivers");
+ turnLayerButtonOn("toggleRivers");
drawRivers();
if (event && isCtrlClick(event)) editStyle("rivers");
} else {
if (event && isCtrlClick(event)) return editStyle("rivers");
rivers.selectAll("*").remove();
- turnButtonOff("toggleRivers");
+ turnLayerButtonOff("toggleRivers");
}
}
@@ -1639,7 +1643,7 @@ export function drawRivers() {
function toggleRoutes(event) {
if (!layerIsOn("toggleRoutes")) {
- turnButtonOn("toggleRoutes");
+ turnLayerButtonOn("toggleRoutes");
$("#routes").fadeIn();
if (event && isCtrlClick(event)) editStyle("routes");
} else {
@@ -1648,13 +1652,13 @@ function toggleRoutes(event) {
return;
}
$("#routes").fadeOut();
- turnButtonOff("toggleRoutes");
+ turnLayerButtonOff("toggleRoutes");
}
}
function toggleMilitary(event) {
if (!layerIsOn("toggleMilitary")) {
- turnButtonOn("toggleMilitary");
+ turnLayerButtonOn("toggleMilitary");
$("#armies").fadeIn();
if (event && isCtrlClick(event)) editStyle("armies");
} else {
@@ -1663,19 +1667,19 @@ function toggleMilitary(event) {
return;
}
$("#armies").fadeOut();
- turnButtonOff("toggleMilitary");
+ turnLayerButtonOff("toggleMilitary");
}
}
function toggleMarkers(event) {
if (!layerIsOn("toggleMarkers")) {
- turnButtonOn("toggleMarkers");
+ turnLayerButtonOn("toggleMarkers");
drawMarkers();
if (event && isCtrlClick(event)) editStyle("markers");
} else {
if (event && isCtrlClick(event)) return editStyle("markers");
markers.selectAll("*").remove();
- turnButtonOff("toggleMarkers");
+ turnLayerButtonOff("toggleMarkers");
}
}
@@ -1724,23 +1728,23 @@ function drawMarker(marker, rescale = 1) {
function toggleLabels(event) {
if (!layerIsOn("toggleLabels")) {
- turnButtonOn("toggleLabels");
+ turnLayerButtonOn("toggleLabels");
labels.style("display", null);
- invokeActiveZooming();
+ Zoom.invoke();
if (event && isCtrlClick(event)) editStyle("labels");
} else {
if (event && isCtrlClick(event)) {
editStyle("labels");
return;
}
- turnButtonOff("toggleLabels");
+ turnLayerButtonOff("toggleLabels");
labels.style("display", "none");
}
}
function toggleIcons(event) {
if (!layerIsOn("toggleIcons")) {
- turnButtonOn("toggleIcons");
+ turnLayerButtonOn("toggleIcons");
$("#icons").fadeIn();
if (event && isCtrlClick(event)) editStyle("burgIcons");
} else {
@@ -1748,14 +1752,14 @@ function toggleIcons(event) {
editStyle("burgIcons");
return;
}
- turnButtonOff("toggleIcons");
+ turnLayerButtonOff("toggleIcons");
$("#icons").fadeOut();
}
}
function toggleRulers(event) {
if (!layerIsOn("toggleRulers")) {
- turnButtonOn("toggleRulers");
+ turnLayerButtonOn("toggleRulers");
if (event && isCtrlClick(event)) editStyle("ruler");
rulers.draw();
ruler.style("display", null);
@@ -1764,7 +1768,7 @@ function toggleRulers(event) {
editStyle("ruler");
return;
}
- turnButtonOff("toggleRulers");
+ turnLayerButtonOff("toggleRulers");
ruler.selectAll("*").remove();
ruler.style("display", "none");
}
@@ -1772,7 +1776,7 @@ function toggleRulers(event) {
function toggleScaleBar(event) {
if (!layerIsOn("toggleScaleBar")) {
- turnButtonOn("toggleScaleBar");
+ turnLayerButtonOn("toggleScaleBar");
$("#scaleBar").fadeIn();
if (event && isCtrlClick(event)) editUnits();
} else {
@@ -1781,13 +1785,13 @@ function toggleScaleBar(event) {
return;
}
$("#scaleBar").fadeOut();
- turnButtonOff("toggleScaleBar");
+ turnLayerButtonOff("toggleScaleBar");
}
}
function toggleZones(event) {
if (!layerIsOn("toggleZones")) {
- turnButtonOn("toggleZones");
+ turnLayerButtonOn("toggleZones");
$("#zones").fadeIn();
if (event && isCtrlClick(event)) editStyle("zones");
} else {
@@ -1795,14 +1799,14 @@ function toggleZones(event) {
editStyle("zones");
return;
}
- turnButtonOff("toggleZones");
+ turnLayerButtonOff("toggleZones");
$("#zones").fadeOut();
}
}
function toggleEmblems(event) {
if (!layerIsOn("toggleEmblems")) {
- turnButtonOn("toggleEmblems");
+ turnLayerButtonOn("toggleEmblems");
if (!emblems.selectAll("use").size()) drawEmblems();
$("#emblems").fadeIn();
if (event && isCtrlClick(event)) editStyle("emblems");
@@ -1812,7 +1816,7 @@ function toggleEmblems(event) {
return;
}
$("#emblems").fadeOut();
- turnButtonOff("toggleEmblems");
+ turnLayerButtonOff("toggleEmblems");
}
}
@@ -1914,34 +1918,18 @@ function drawEmblems() {
const stateString = stateNodes
.map(
d =>
- ``
+ ``
)
.join("");
emblems.select("#stateEmblems").attr("font-size", sizeStates).html(stateString);
- invokeActiveZooming();
+ Zoom.invoke();
});
TIME && console.timeEnd("drawEmblems");
}
-export function layerIsOn(el) {
- const buttonoff = byId(el).classList.contains("buttonoff");
- return !buttonoff;
-}
-
-function turnButtonOff(el) {
- byId(el).classList.add("buttonoff");
- getCurrentPreset();
-}
-
-function turnButtonOn(el) {
- byId(el).classList.remove("buttonoff");
- getCurrentPreset();
-}
-
// move layers on mapLayers dragging (jquery sortable)
$("#mapLayers").sortable({items: "li:not(.solid)", containment: "parent", cancel: ".solid", update: moveLayer});
function moveLayer(event, ui) {
diff --git a/src/modules/ui/provinces-editor.js b/src/modules/ui/provinces-editor.js
index b50b7304..0161cf93 100644
--- a/src/modules/ui/provinces-editor.js
+++ b/src/modules/ui/provinces-editor.js
@@ -7,6 +7,7 @@ import {rn} from "/src/utils/numberUtils";
import {rand, P} from "/src/utils/probabilityUtils";
import {parseTransform} from "/src/utils/stringUtils";
import {si} from "/src/utils/unitUtils";
+import {turnLayerButtonOff} from "/src/modules/ui/layers";
export function editProvinces() {
if (customization) return;
@@ -1118,7 +1119,7 @@ export function editProvinces() {
if (!layerIsOn("toggleBorders")) toggleBorders();
else drawBorders();
provs.select("#provincesBody").remove();
- turnButtonOff("toggleProvinces");
+ turnLayerButtonOff("toggleProvinces");
provincesEditorAddLines();
},
diff --git a/src/modules/ui/style.js b/src/modules/ui/style.js
index 3b1aad53..b57c5c63 100644
--- a/src/modules/ui/style.js
+++ b/src/modules/ui/style.js
@@ -430,13 +430,13 @@ function shiftElement() {
styleRescaleMarkers.addEventListener("change", function () {
markers.attr("rescale", +this.checked);
- invokeActiveZooming();
+ Zoom.invoke();
});
styleCoastlineAuto.addEventListener("change", function () {
coastline.select("#sea_island").attr("auto-filter", +this.checked);
styleFilter.style.display = this.checked ? "none" : "block";
- invokeActiveZooming();
+ Zoom.invoke();
});
styleOceanFill.addEventListener("input", function () {
@@ -834,7 +834,7 @@ function updateElements() {
if (legend.selectAll("*").size() && window.redrawLegend) redrawLegend();
oceanLayers.selectAll("path").remove();
OceanLayers();
- invokeActiveZooming();
+ Zoom.invoke();
}
// GLOBAL FILTERS
diff --git a/src/modules/ui/stylePresets.js b/src/modules/ui/stylePresets.js
index 1d2bcc5b..7d07e026 100644
--- a/src/modules/ui/stylePresets.js
+++ b/src/modules/ui/stylePresets.js
@@ -127,7 +127,7 @@ function applyStyleWithUiRefresh(style) {
updateMapFilter();
stylePreset.dataset.old = stylePreset.value;
- invokeActiveZooming();
+ Zoom.invoke();
setPresetRemoveButtonVisibiliy();
}
diff --git a/src/modules/ui/submap.js b/src/modules/ui/submap.js
index c3a8d351..f4bf62bb 100644
--- a/src/modules/ui/submap.js
+++ b/src/modules/ui/submap.js
@@ -3,6 +3,7 @@ import {clearMainTip} from "/src/scripts/tooltips";
import {parseError} from "/src/utils/errorUtils";
import {rn, minmax} from "/src/utils/numberUtils";
import {debounce} from "/src/utils/functionUtils";
+import {restoreLayers} from "/src/modules/ui/layers";
window.UISubmap = (function () {
byId("submapPointsInput").addEventListener("input", function () {
@@ -298,7 +299,7 @@ window.UISubmap = (function () {
moveAllBurgsToGroup("towns", groupName);
changeRadius(rn(oldScale * 0.8, 2), groupName);
changeFontSize(svg.select(`#labels #${groupName}`), rn(oldScale * 2, 2));
- invokeActiveZooming();
+ Zoom.invoke();
}
if (options.rescaleStyles) changeStyles(oldScale);
} catch (error) {
diff --git a/src/modules/ui/tools.js b/src/modules/ui/tools.js
index 1560d567..bd738a54 100644
--- a/src/modules/ui/tools.js
+++ b/src/modules/ui/tools.js
@@ -7,6 +7,7 @@ import {isCtrlClick} from "/src/utils/keyboardUtils";
import {prompt} from "/src/scripts/prompt";
import {getNextId} from "/src/utils/nodeUtils";
import {P, generateSeed} from "/src/utils/probabilityUtils";
+import {turnLayerButtonOn} from "/src/modules/ui/layers";
toolsContent.addEventListener("click", function (event) {
if (customization) return tip("Please exit the customization mode first", false, "warning");
@@ -436,7 +437,7 @@ function regenerateIce() {
function regenerateMarkers() {
Markers.regenerate();
- turnButtonOn("toggleMarkers");
+ turnLayerButtonOn("toggleMarkers");
drawMarkers();
if (document.getElementById("markersOverviewRefresh").offsetParent) markersOverviewRefresh.click();
}
diff --git a/src/modules/zoom.js b/src/modules/zoom.js
index 065e8fbc..2163eefe 100644
--- a/src/modules/zoom.js
+++ b/src/modules/zoom.js
@@ -1,12 +1,15 @@
import {debounce} from "/src/utils/functionUtils";
-import {handleZoom} from "/src/modules/activeZooming";
+import {handleZoom, invokeActiveZooming} from "/src/modules/activeZooming";
-// temporary expose to global
+// temporary expose to window
window.scale = 1;
window.viewX = 0;
window.viewY = 0;
window.Zoom = (function () {
+ const onZoomDebouced = debounce(onZoom, 50);
+ const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", onZoomDebouced);
+
function onZoom() {
if (!d3.event?.transform) return;
const {k, x, y} = d3.event.transform;
@@ -21,13 +24,15 @@ window.Zoom = (function () {
handleZoom(isScaleChanged, isPositionChanged);
}
- const onZoomDebouced = debounce(onZoom, 50);
- const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", onZoomDebouced);
function setZoomBehavior() {
svg.call(zoom);
}
+ function invoke() {
+ invokeActiveZooming();
+ }
+
// zoom to a specific point
function to(x, y, z = 8, d = 2000) {
const transform = d3.zoomIdentity.translate(x * -z + graphWidth / 2, y * -z + graphHeight / 2).scale(z);
@@ -54,5 +59,5 @@ window.Zoom = (function () {
zoom.scaleTo(element, scale);
}
- return {setZoomBehavior, to, reset, scaleExtent, translateExtent, scaleTo};
+ return {setZoomBehavior, invoke, to, reset, scaleExtent, translateExtent, scaleTo};
})();
diff --git a/src/types/common.d.ts b/src/types/common.d.ts
index ef2b66a5..63afecd1 100644
--- a/src/types/common.d.ts
+++ b/src/types/common.d.ts
@@ -3,3 +3,6 @@ type UnknownObject = {[key: string]: unknown};
interface Dict {
[key: string]: T;
}
+
+type RGB = `rgb(${number}, ${number}, ${number})`;
+type Hex = `#${string}`;
diff --git a/src/utils/colorUtils.ts b/src/utils/colorUtils.ts
index a71b51b7..732290a5 100644
--- a/src/utils/colorUtils.ts
+++ b/src/utils/colorUtils.ts
@@ -1,6 +1,6 @@
const d3 = window.d3;
-const c12 = [
+const c12: Hex[] = [
"#dababf",
"#fb8072",
"#80b1d3",
@@ -38,3 +38,21 @@ export function getMixedColor(hexColor: string, mixation = 0.2, bright = 0.3) {
return d3.color(mixedColor).brighter(bright).hex();
}
+
+export function getColorScheme(schemeName: string) {
+ return colorSchemeMap[schemeName] || colorSchemeMap.default;
+}
+
+type ColorScheme = (n: number) => RGB;
+const colorSchemeMap: Dict = {
+ default: d3.scaleSequential(d3.interpolateSpectral),
+ bright: d3.scaleSequential(d3.interpolateSpectral),
+ light: d3.scaleSequential(d3.interpolateRdYlGn),
+ green: d3.scaleSequential(d3.interpolateGreens),
+ monochrome: d3.scaleSequential(d3.interpolateGreys)
+};
+
+export function getHeightColor(height: number, scheme = getColorScheme("default")) {
+ const fittedValue = height < 20 ? height - 5 : height;
+ return scheme(1 - fittedValue / 100);
+}