diff --git a/package.json b/package.json
index 4ee3b0c0..5754d5fc 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"@types/delaunator": "^5.0.0",
"@types/jquery": "^3.5.14",
"@types/jqueryui": "^1.12.16",
+ "@types/polylabel": "^1.0.5",
"c8": "^7.12.0",
"happy-dom": "^6.0.4",
"rollup": "^2.75.7",
diff --git a/src/assets/styles/ancient.json b/src/assets/styles/ancient.json
index ffc3e775..3f5b3281 100644
--- a/src/assets/styles/ancient.json
+++ b/src/assets/styles/ancient.json
@@ -78,13 +78,13 @@
"#relig": {
"opacity": 0.7,
"stroke": "#404040",
- "stroke-width": 0.7,
+ "stroke-width": 3,
"filter": null
},
"#cults": {
"opacity": 0.6,
"stroke": "#777777",
- "stroke-width": 0.5,
+ "stroke-width": 3,
"stroke-dasharray": null,
"stroke-linecap": null,
"filter": null
diff --git a/src/assets/styles/atlas.json b/src/assets/styles/atlas.json
index c26848a0..6a6917c3 100644
--- a/src/assets/styles/atlas.json
+++ b/src/assets/styles/atlas.json
@@ -78,13 +78,13 @@
"#relig": {
"opacity": 0.7,
"stroke": "#777777",
- "stroke-width": 0,
+ "stroke-width": 3,
"filter": null
},
"#cults": {
"opacity": 0.6,
"stroke": "#777777",
- "stroke-width": 0.5,
+ "stroke-width": 3,
"stroke-dasharray": null,
"stroke-linecap": null,
"filter": null
diff --git a/src/assets/styles/clean.json b/src/assets/styles/clean.json
index fd00c5ad..4fed8dea 100644
--- a/src/assets/styles/clean.json
+++ b/src/assets/styles/clean.json
@@ -79,13 +79,13 @@
"#relig": {
"opacity": 0.7,
"stroke": "#404040",
- "stroke-width": 0.7,
+ "stroke-width": 3,
"filter": null
},
"#cults": {
"opacity": 0.6,
"stroke": "#777777",
- "stroke-width": 0.5,
+ "stroke-width": 3,
"stroke-dasharray": null,
"stroke-linecap": null,
"filter": null
diff --git a/src/assets/styles/cyberpunk.json b/src/assets/styles/cyberpunk.json
index 579d093b..31c493f2 100644
--- a/src/assets/styles/cyberpunk.json
+++ b/src/assets/styles/cyberpunk.json
@@ -78,13 +78,13 @@
"#relig": {
"opacity": 0.5,
"stroke": "#404040",
- "stroke-width": 2,
+ "stroke-width": 3,
"filter": "url(#splotch)"
},
"#cults": {
"opacity": 0.35,
"stroke": "#777777",
- "stroke-width": 2,
+ "stroke-width": 3,
"stroke-dasharray": null,
"stroke-linecap": null,
"filter": "url(#splotch)"
diff --git a/src/assets/styles/default.json b/src/assets/styles/default.json
index 37a52b33..775bdbd2 100644
--- a/src/assets/styles/default.json
+++ b/src/assets/styles/default.json
@@ -78,13 +78,13 @@
"#relig": {
"opacity": 0.7,
"stroke": "#777777",
- "stroke-width": 0,
+ "stroke-width": 3,
"filter": null
},
"#cults": {
"opacity": 0.6,
"stroke": "#777777",
- "stroke-width": 0.5,
+ "stroke-width": 3,
"stroke-dasharray": null,
"stroke-linecap": null,
"filter": null
diff --git a/src/assets/styles/gloom.json b/src/assets/styles/gloom.json
index 95dee382..b5096a95 100644
--- a/src/assets/styles/gloom.json
+++ b/src/assets/styles/gloom.json
@@ -79,13 +79,13 @@
"#relig": {
"opacity": 0.7,
"stroke": "#404040",
- "stroke-width": 1,
+ "stroke-width": 3,
"filter": null
},
"#cults": {
"opacity": 0.7,
"stroke": "#777777",
- "stroke-width": 1.5,
+ "stroke-width": 3,
"stroke-dasharray": null,
"stroke-linecap": null,
"filter": null
diff --git a/src/assets/styles/light.json b/src/assets/styles/light.json
index 6a225e86..b6dd72ed 100644
--- a/src/assets/styles/light.json
+++ b/src/assets/styles/light.json
@@ -78,13 +78,13 @@
"#relig": {
"opacity": 0.5,
"stroke": null,
- "stroke-width": 0,
+ "stroke-width": 3,
"filter": null
},
"#cults": {
"opacity": 0.5,
"stroke": "#777777",
- "stroke-width": 0,
+ "stroke-width": 3,
"stroke-dasharray": null,
"stroke-linecap": null,
"filter": null
diff --git a/src/assets/styles/monochrome.json b/src/assets/styles/monochrome.json
index e94f5a7b..0c843f0c 100644
--- a/src/assets/styles/monochrome.json
+++ b/src/assets/styles/monochrome.json
@@ -79,13 +79,13 @@
"#relig": {
"opacity": 0.7,
"stroke": "#404040",
- "stroke-width": 0.7,
+ "stroke-width": 3,
"filter": null
},
"#cults": {
"opacity": 0.6,
"stroke": "#777777",
- "stroke-width": 0.5,
+ "stroke-width": 3,
"stroke-dasharray": null,
"stroke-linecap": null,
"filter": null
diff --git a/src/assets/styles/watercolor.json b/src/assets/styles/watercolor.json
index 99908126..24d7787b 100644
--- a/src/assets/styles/watercolor.json
+++ b/src/assets/styles/watercolor.json
@@ -78,13 +78,13 @@
"#relig": {
"opacity": 0.7,
"stroke": "#777777",
- "stroke-width": 0,
+ "stroke-width": 3,
"filter": "url(#bluredSplotch)"
},
"#cults": {
"opacity": 0.6,
"stroke": "#777777",
- "stroke-width": 0.5,
+ "stroke-width": 3,
"stroke-dasharray": null,
"stroke-linecap": null,
"filter": "url(#splotch)"
diff --git a/src/index.css b/src/index.css
index b5180a25..a626de1c 100644
--- a/src/index.css
+++ b/src/index.css
@@ -102,7 +102,7 @@ a {
}
#biomes {
- stroke-width: 0.7;
+ stroke-width: 3;
}
#landmass {
diff --git a/src/layers/renderers/drawBiomes.js b/src/layers/renderers/drawBiomes.js
deleted file mode 100644
index 5e406cb5..00000000
--- a/src/layers/renderers/drawBiomes.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import {clipPoly} from "utils/lineUtils";
-import {TIME} from "config/logging";
-
-export function drawBiomes() {
- TIME && console.time("drawBiomes");
- biomes.selectAll("path").remove();
-
- const {cells, vertices} = pack;
- const n = cells.i.length;
-
- const used = new Uint8Array(cells.i.length);
- const paths = new Array(biomesData.i.length).fill("");
-
- for (const i of cells.i) {
- if (!cells.biome[i]) continue; // no need to mark marine biome (liquid water)
- if (used[i]) continue; // already marked
- const b = cells.biome[i];
- const onborder = cells.c[i].some(n => cells.biome[n] !== b);
- if (!onborder) continue;
- const edgeVerticle = cells.v[i].find(v => vertices.c[v].some(i => cells.biome[i] !== b));
- const chain = connectVertices(edgeVerticle, b);
- if (chain.length < 3) continue;
- const points = clipPoly(chain.map(v => vertices.p[v]));
- paths[b] += "M" + points.join("L") + "Z";
- }
-
- paths.forEach(function (d, i) {
- if (d.length < 10) return;
- biomes
- .append("path")
- .attr("d", d)
- .attr("fill", biomesData.color[i])
- .attr("stroke", biomesData.color[i])
- .attr("id", "biome" + i);
- });
-
- // connect vertices to chain
- function connectVertices(start, b) {
- const chain = []; // vertices chain to form a path
- for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) {
- const prev = chain[chain.length - 1]; // previous vertex in chain
- chain.push(current); // add current vertex to sequence
- const c = vertices.c[current]; // cells adjacent to vertex
- c.filter(c => cells.biome[c] === b).forEach(c => (used[c] = 1));
- const c0 = c[0] >= n || cells.biome[c[0]] !== b;
- const c1 = c[1] >= n || cells.biome[c[1]] !== b;
- const c2 = c[2] >= n || cells.biome[c[2]] !== b;
- const v = vertices.v[current]; // neighboring vertices
- if (v[0] !== prev && c0 !== c1) current = v[0];
- else if (v[1] !== prev && c1 !== c2) current = v[1];
- else if (v[2] !== prev && c0 !== c2) current = v[2];
- if (current === chain[chain.length - 1]) {
- ERROR && console.error("Next vertex is not found");
- break;
- }
- }
- return chain;
- }
-
- TIME && console.timeEnd("drawBiomes");
-}
diff --git a/src/layers/renderers/drawBiomes.ts b/src/layers/renderers/drawBiomes.ts
new file mode 100644
index 00000000..382f858f
--- /dev/null
+++ b/src/layers/renderers/drawBiomes.ts
@@ -0,0 +1,29 @@
+import {pick} from "utils/functionUtils";
+import {byId} from "utils/shorthands";
+import {getPaths} from "./utils/getVertexPaths";
+
+export function drawBiomes() {
+ /* global */ const {cells, vertices, features} = pack;
+ /* global */ const colors = biomesData.color;
+
+ const paths = getPaths({
+ getType: (cellId: number) => cells.biome[cellId],
+ cells: pick(cells, "c", "v", "b", "h", "f"),
+ vertices,
+ features,
+ options: {fill: true, waterGap: true, halo: false}
+ });
+
+ console.log(paths);
+
+ const htmlPaths = paths.map(([index, {fill, waterGap}]) => {
+ const color = colors[Number(index)];
+
+ return /* html */ `
+
+
+ `;
+ });
+
+ byId("biomes")!.innerHTML = htmlPaths.join("");
+}
diff --git a/src/layers/renderers/drawCultures.ts b/src/layers/renderers/drawCultures.ts
index aa9189ef..9d3cdeae 100644
--- a/src/layers/renderers/drawCultures.ts
+++ b/src/layers/renderers/drawCultures.ts
@@ -1,44 +1,28 @@
-import * as d3 from "d3";
-
-import {getPaths} from "./utilts";
import {pick} from "utils/functionUtils";
+import {byId} from "utils/shorthands";
+import {getPaths} from "./utils/getVertexPaths";
export function drawCultures() {
- d3.select("#cults").selectAll("g").remove();
-
- /* uses */ const {cells, vertices, features, cultures} = pack;
+ /* global */ const {cells, vertices, features, cultures} = pack;
const paths = getPaths({
getType: (cellId: number) => cells.culture[cellId],
cells: pick(cells, "c", "v", "b", "h", "f"),
vertices,
- features
+ features,
+ options: {fill: true, waterGap: true, halo: false}
});
- const getColor = (i: number) => (cultures[i] as ICulture).color;
+ const getColor = (i: string) => (cultures[Number(i)] as ICulture).color;
- d3.select("#cults")
- .append("g")
- .attr("fill", "none")
- .attr("stroke-width", 3)
- .selectAll("path")
- .remove()
- .data(paths)
- .enter()
- .append("path")
- .attr("d", ([, path]) => path.waterGap)
- .attr("stroke", ([i]) => getColor(Number(i)))
- .attr("id", ([i]) => "culture-gap" + i);
+ const htmlPaths = paths.map(([index, {fill, waterGap}]) => {
+ const color = getColor(index);
- d3.select("#cults")
- .append("g")
- .attr("stroke", "none")
- .selectAll("path")
- .remove()
- .data(paths)
- .enter()
- .append("path")
- .attr("d", ([, path]) => path.fill)
- .attr("fill", ([i]) => getColor(Number(i)))
- .attr("id", ([i]) => "culture" + i);
+ return /* html */ `
+
+
+ `;
+ });
+
+ byId("cults")!.innerHTML = htmlPaths.join("");
}
diff --git a/src/layers/renderers/drawFeatures.ts b/src/layers/renderers/drawFeatures.ts
index 7832e84a..41ccba46 100644
--- a/src/layers/renderers/drawFeatures.ts
+++ b/src/layers/renderers/drawFeatures.ts
@@ -5,7 +5,7 @@ import {filterOutOfCanvasPoints} from "utils/lineUtils";
import {round} from "utils/stringUtils";
export function drawFeatures() {
- /* uses */ const {vertices, features} = pack;
+ /* global */ const {vertices, features} = pack;
const landMask = defs.select("#land");
const waterMask = defs.select("#water");
diff --git a/src/layers/renderers/drawReligions.js b/src/layers/renderers/drawReligions.js
deleted file mode 100644
index e81810b4..00000000
--- a/src/layers/renderers/drawReligions.js
+++ /dev/null
@@ -1,91 +0,0 @@
-export function drawReligions() {
- relig.selectAll("path").remove();
- const {cells, vertices, religions} = pack;
- const n = cells.i.length;
-
- const used = new Uint8Array(cells.i.length);
- const body = new Array(religions.length).fill(""); // store path around each religion
- const gap = new Array(religions.length).fill(""); // store path along water for each religion to fill the gaps
-
- for (const i of cells.i) {
- if (!cells.religion[i]) continue;
- if (used[i]) continue;
- used[i] = 1;
- const r = cells.religion[i];
- const onborder = cells.c[i].filter(n => cells.religion[n] !== r);
- if (!onborder.length) continue;
- const borderWith = cells.c[i].map(c => cells.religion[c]).find(n => n !== r);
- const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.religion[i] === borderWith));
- const chain = connectVertices(vertex, r, borderWith);
- if (chain.length < 3) continue;
- const points = chain.map(v => vertices.p[v[0]]);
-
- body[r] += "M" + points.join("L") + "Z";
- 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]);
- relig
- .selectAll("path")
- .data(bodyData)
- .enter()
- .append("path")
- .attr("d", d => d[0])
- .attr("fill", d => d[2])
- .attr("id", d => "religion" + d[1]);
-
- const gapData = gap.map((p, i) => [p.length > 10 ? p : null, i, religions[i].color]).filter(d => d[0]);
- relig
- .selectAll(".path")
- .data(gapData)
- .enter()
- .append("path")
- .attr("d", d => d[0])
- .attr("fill", "none")
- .attr("stroke", d => d[2])
- .attr("id", d => "religion-gap" + d[1])
- .attr("stroke-width", "10px");
-
- // connect vertices to chain
- function connectVertices(start, t, religion) {
- const chain = []; // vertices chain to form a path
- let land = vertices.c[start].some(c => cells.h[c] >= 20 && cells.religion[c] !== t);
- function check(i) {
- religion = cells.religion[i];
- land = cells.h[i] >= 20;
- }
-
- for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) {
- const prev = chain[chain.length - 1] ? chain[chain.length - 1][0] : -1; // previous vertex in chain
- chain.push([current, religion, land]); // add current vertex to sequence
- const c = vertices.c[current]; // cells adjacent to vertex
- c.filter(c => cells.religion[c] === t).forEach(c => (used[c] = 1));
- const c0 = c[0] >= n || cells.religion[c[0]] !== t;
- const c1 = c[1] >= n || cells.religion[c[1]] !== t;
- const c2 = c[2] >= n || cells.religion[c[2]] !== t;
- const v = vertices.v[current]; // neighboring vertices
- if (v[0] !== prev && c0 !== c1) {
- current = v[0];
- check(c0 ? c[0] : c[1]);
- } else if (v[1] !== prev && c1 !== c2) {
- current = v[1];
- check(c1 ? c[1] : c[2]);
- } else if (v[2] !== prev && c0 !== c2) {
- current = v[2];
- check(c2 ? c[2] : c[0]);
- }
- if (current === chain[chain.length - 1][0]) {
- ERROR && console.error("Next vertex is not found");
- break;
- }
- }
- return chain;
- }
-}
diff --git a/src/layers/renderers/drawReligions.ts b/src/layers/renderers/drawReligions.ts
new file mode 100644
index 00000000..19c63354
--- /dev/null
+++ b/src/layers/renderers/drawReligions.ts
@@ -0,0 +1,28 @@
+import {pick} from "utils/functionUtils";
+import {byId} from "utils/shorthands";
+import {getPaths} from "./utils/getVertexPaths";
+
+export function drawReligions() {
+ /* global */ const {cells, vertices, features, religions} = pack;
+
+ const paths = getPaths({
+ getType: (cellId: number) => cells.religion[cellId],
+ cells: pick(cells, "c", "v", "b", "h", "f"),
+ vertices,
+ features,
+ options: {fill: true, waterGap: true, halo: false}
+ });
+
+ const getColor = (i: string) => (religions[Number(i)] as IReligion).color;
+
+ const htmlPaths = paths.map(([index, {fill, waterGap}]) => {
+ const color = getColor(index);
+
+ return /* html */ `
+
+
+ `;
+ });
+
+ byId("relig")!.innerHTML = htmlPaths.join("");
+}
diff --git a/src/layers/renderers/drawRoutes.ts b/src/layers/renderers/drawRoutes.ts
index f6362490..dc269981 100644
--- a/src/layers/renderers/drawRoutes.ts
+++ b/src/layers/renderers/drawRoutes.ts
@@ -10,9 +10,7 @@ const lineGenTypeMap: {[key in IRoute["type"]]: d3.CurveFactory | d3.CurveFactor
};
export function drawRoutes() {
- routes.selectAll("path").remove();
-
- /* uses */ const {cells, burgs} = pack;
+ /* global */ const {cells, burgs} = pack;
const lineGen = d3.line();
const SHARP_ANGLE = 135;
@@ -32,6 +30,7 @@ export function drawRoutes() {
routePaths[type].push(``);
}
+ routes.selectAll("path").remove();
for (const type in routePaths) {
routes.select(`[data-type=${type}]`).html(routePaths[type].join(""));
}
diff --git a/src/layers/renderers/drawStates.js b/src/layers/renderers/drawStates.js
deleted file mode 100644
index 2c7e1cd7..00000000
--- a/src/layers/renderers/drawStates.js
+++ /dev/null
@@ -1,149 +0,0 @@
-import * as d3 from "d3";
-
-import polylabel from "polylabel";
-
-export function drawStates() {
- regions.selectAll("path").remove();
-
- const {cells, vertices, features} = pack;
- const states = pack.states;
- const n = cells.i.length;
-
- const used = new Uint8Array(cells.i.length);
- const vArray = new Array(states.length); // store vertices array
- const body = new Array(states.length).fill(""); // path around each state
- const gap = new Array(states.length).fill(""); // path along water for each state to fill the gaps
- const halo = new Array(states.length).fill(""); // path around states, but not lakes
-
- const getStringPoint = v => vertices.p[v[0]].join(",");
-
- // define inner-state lakes to omit on border render
- const innerLakes = features.map(feature => {
- if (feature.type !== "lake") return false;
-
- const shoreline = feature.shoreline || [];
- const states = shoreline.map(i => cells.state[i]);
- return new Set(states).size > 1 ? false : true;
- });
-
- for (const i of cells.i) {
- if (!cells.state[i] || used[i]) continue;
- const state = cells.state[i];
-
- const onborder = cells.c[i].some(n => cells.state[n] !== state);
- if (!onborder) continue;
-
- const borderWith = cells.c[i].map(c => cells.state[c]).find(n => n !== state);
- const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.state[i] === borderWith));
- const chain = connectVertices(vertex, state);
-
- const noInnerLakes = chain.filter(v => v[1] !== "innerLake");
- if (noInnerLakes.length < 3) continue;
-
- // get path around the state
- if (!vArray[state]) vArray[state] = [];
- const points = noInnerLakes.map(v => vertices.p[v[0]]);
- vArray[state].push(points);
- body[state] += "M" + points.join("L");
-
- // connect path for halo
- let discontinued = true;
- halo[state] += noInnerLakes
- .map(v => {
- if (v[1] === "border") {
- discontinued = true;
- return "";
- }
-
- const operation = discontinued ? "M" : "L";
- discontinued = false;
- return `${operation}${getStringPoint(v)}`;
- })
- .join("");
-
- // connect gaps between state and water into a single path
- discontinued = true;
- gap[state] += chain
- .map(v => {
- if (v[1] === "land") {
- discontinued = true;
- return "";
- }
-
- const operation = discontinued ? "M" : "L";
- discontinued = false;
- return `${operation}${getStringPoint(v)}`;
- })
- .join("");
- }
-
- // find state visual center
- vArray.forEach((ar, i) => {
- const sorted = ar.sort((a, b) => b.length - a.length); // sort by points number
- states[i].pole = polylabel(sorted, 1.0); // pole of inaccessibility
- });
-
- const bodyData = body.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
- const gapData = gap.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
- const haloData = halo.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
-
- const bodyString = bodyData.map(d => ``).join("");
- const gapString = gapData.map(d => ``).join("");
- const clipString = bodyData
- .map(d => ``)
- .join("");
- const haloString = haloData
- .map(
- d =>
- ``
- )
- .join("");
-
- statesBody.html(bodyString + gapString);
- defs.select("#statePaths").html(clipString);
- statesHalo.html(haloString);
-
- // connect vertices to chain
- function connectVertices(start, state) {
- const chain = []; // vertices chain to form a path
- const getType = c => {
- const borderCell = c.find(i => cells.b[i]);
- if (borderCell) return "border";
-
- const waterCell = c.find(i => cells.h[i] < 20);
- if (!waterCell) return "land";
- if (innerLakes[cells.f[waterCell]]) return "innerLake";
- return features[cells.f[waterCell]].type;
- };
-
- for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) {
- const prev = chain.length ? chain[chain.length - 1][0] : -1; // previous vertex in chain
-
- const c = vertices.c[current]; // cells adjacent to vertex
- chain.push([current, getType(c)]); // add current vertex to sequence
-
- c.filter(c => cells.state[c] === state).forEach(c => (used[c] = 1));
- const c0 = c[0] >= n || cells.state[c[0]] !== state;
- const c1 = c[1] >= n || cells.state[c[1]] !== state;
- const c2 = c[2] >= n || cells.state[c[2]] !== state;
-
- const v = vertices.v[current]; // neighboring vertices
-
- if (v[0] !== prev && c0 !== c1) current = v[0];
- else if (v[1] !== prev && c1 !== c2) current = v[1];
- else if (v[2] !== prev && c0 !== c2) current = v[2];
-
- if (current === prev) {
- ERROR && console.error("Next vertex is not found");
- break;
- }
- }
-
- if (chain.length) chain.push(chain[0]);
- return chain;
- }
-
- Zoom.invoke();
-}
diff --git a/src/layers/renderers/drawStates.ts b/src/layers/renderers/drawStates.ts
new file mode 100644
index 00000000..1c5f65b2
--- /dev/null
+++ b/src/layers/renderers/drawStates.ts
@@ -0,0 +1,48 @@
+import * as d3 from "d3";
+
+import {pick} from "utils/functionUtils";
+import {byId} from "utils/shorthands";
+import {getPaths} from "./utils/getVertexPaths";
+
+export function drawStates() {
+ /* global */ const {cells, vertices, features, states} = pack;
+
+ const paths = getPaths({
+ getType: (cellId: number) => cells.state[cellId],
+ cells: pick(cells, "c", "v", "b", "h", "f"),
+ vertices,
+ features,
+ options: {fill: true, waterGap: true, halo: true}
+ });
+
+ const getColor = (i: number) => (states[i] as IState).color;
+
+ const maxLength = states.length - 1;
+ const bodyPaths = new Array(maxLength);
+ const clipPaths = new Array(maxLength);
+ const haloPaths = new Array(maxLength);
+
+ for (const [index, {fill, waterGap, halo}] of paths) {
+ const color = getColor(Number(index));
+ const haloColor = d3.color(color)?.darker().formatHex() || "#666666";
+
+ bodyPaths.push(/* html */ `
+
+
+ `);
+
+ clipPaths.push(/* html */ `
+
+ `);
+
+ haloPaths.push(/* html */ `
+
+ `);
+ }
+
+ byId("statesBody")!.innerHTML = bodyPaths.join("");
+ byId("statePaths")!.innerHTML = clipPaths.join("");
+ byId("statesHalo")!.innerHTML = haloPaths.join("");
+
+ /* global */ window.Zoom.invoke();
+}
diff --git a/src/layers/renderers/utilts.ts b/src/layers/renderers/utils/getVertexPaths.ts
similarity index 84%
rename from src/layers/renderers/utilts.ts
rename to src/layers/renderers/utils/getVertexPaths.ts
index 7931004a..6231c359 100644
--- a/src/layers/renderers/utilts.ts
+++ b/src/layers/renderers/utils/getVertexPaths.ts
@@ -8,12 +8,14 @@ export function getPaths({
vertices,
getType,
features,
- cells
+ cells,
+ options
}: {
vertices: IGraphVertices;
getType: (cellId: number) => number;
features: TPackFeatures;
cells: Pick;
+ options: {[key in keyof TPath]: boolean};
}) {
const paths: Dict = {};
@@ -55,11 +57,12 @@ export function getPaths({
function getFillPath(vertexChain: number[]) {
const points: TPoints = vertexChain.map(getVertexPoint);
const firstPoint = points.shift();
- return `M${firstPoint} L${points.join(" ")} Z`;
+ return `M${firstPoint} L${points.join(" ")}`;
}
function getBorderPath(vertexChain: number[], discontinue: (vertex: number) => boolean) {
let discontinued = true;
+ let lastOperation = "";
const path = vertexChain.map(vertex => {
if (discontinue(vertex)) {
discontinued = true;
@@ -67,8 +70,12 @@ export function getPaths({
}
const operation = discontinued ? "M" : "L";
+ const command = operation === lastOperation ? "" : operation;
+
discontinued = false;
- return ` ${operation}${getVertexPoint(vertex)}`;
+ lastOperation = operation;
+
+ return ` ${command}${getVertexPoint(vertex)}`;
});
return path.join("").trim();
@@ -87,9 +94,9 @@ export function getPaths({
function addPath(index: number, vertexChain: number[]) {
if (!paths[index]) paths[index] = {fill: "", waterGap: "", halo: ""};
- paths[index].fill += getFillPath(vertexChain);
- paths[index].halo += getBorderPath(vertexChain, isBorderVertex);
- paths[index].waterGap += getBorderPath(vertexChain, isLandVertex);
+ if (options.fill) paths[index].fill += getFillPath(vertexChain);
+ if (options.halo) paths[index].halo += getBorderPath(vertexChain, isBorderVertex);
+ if (options.waterGap) paths[index].waterGap += getBorderPath(vertexChain, isLandVertex);
}
}
diff --git a/src/scripts/generation/generation.ts b/src/scripts/generation/generation.ts
index 6d776f82..0b83ef0f 100644
--- a/src/scripts/generation/generation.ts
+++ b/src/scripts/generation/generation.ts
@@ -26,7 +26,8 @@ import {createGrid} from "./grid/grid";
import {createPack} from "./pack/pack";
import {getInputValue, setInputValue} from "utils/nodeUtils";
import {calculateMapCoordinates} from "modules/coordinates";
-import {drawPolygons} from "utils/debugUtils";
+import {drawPoint, drawPolygons} from "utils/debugUtils";
+import {isReligion} from "utils/typeUtils";
const {Zoom, ThreeD} = window;
@@ -70,10 +71,15 @@ async function generate(options?: IGenerationOptions) {
// renderLayer("biomes");
renderLayer("burgs");
renderLayer("routes");
- renderLayer("cultures");
- //renderLayer("religions");
+ // renderLayer("states");
+ renderLayer("religions");
// drawPolygons(pack.cells.religion, pack.cells.v, pack.vertices.p, {fillOpacity: 0.8, excludeZeroes: true});
+ pack.religions.filter(isReligion).forEach(({center}) =>
+ drawPoint(pack.cells.p[center], {
+ radius: 5
+ })
+ );
WARN && console.warn(`TOTAL: ${rn((performance.now() - timeStart) / 1000, 2)}s`);
// showStatistics();
diff --git a/src/scripts/generation/pack/religions/generateReligions.ts b/src/scripts/generation/pack/religions/generateReligions.ts
index 8a92c224..c0dfe85a 100644
--- a/src/scripts/generation/pack/religions/generateReligions.ts
+++ b/src/scripts/generation/pack/religions/generateReligions.ts
@@ -32,8 +32,6 @@ export function generateReligions({
pick(cells, "i", "c", "biome", "culture", "burg", "state", "route")
);
- console.log(religions);
-
TIME && console.timeEnd("generateReligions");
return {religionIds, religions};
}
diff --git a/src/types/pack/states.d.ts b/src/types/pack/states.d.ts
index 01c216e8..1a104e4b 100644
--- a/src/types/pack/states.d.ts
+++ b/src/types/pack/states.d.ts
@@ -9,6 +9,7 @@ interface IState {
fullName: string;
capital: Logical;
coa: ICoa | string;
+ // pole: TPoint ?
removed?: boolean;
}
diff --git a/yarn.lock b/yarn.lock
index b0f6d4ff..e5e80b0e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -422,6 +422,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3"
integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==
+"@types/polylabel@^1.0.5":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@types/polylabel/-/polylabel-1.0.5.tgz#9262f269de36f1e9248aeb9dee0ee9d10065e043"
+ integrity sha512-gnaNmo1OJiYNBFAZMZdqLZ3hKx2ee4ksAzqhKWBxuQ61PmhINHMcvIqsGmyCD1WFKCkwRt9NFhMSmKE6AgYY+w==
+
"@types/qs@^6.2.31":
version "6.9.7"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"