From 9f54b1e3f0f7384f0e88265f658de00067f22da5 Mon Sep 17 00:00:00 2001 From: Evolvedexperiment Date: Sat, 16 May 2020 09:12:25 +0000 Subject: [PATCH 01/12] Added colour, biomes, adjustable height, and changed graph code to use d3 more --- index.css | 10 ++ index.html | 16 +++ modules/ui/elevation-profile.js | 223 +++++++++++++++++++++----------- modules/ui/rivers-editor.js | 4 +- modules/ui/routes-editor.js | 4 +- 5 files changed, 174 insertions(+), 83 deletions(-) diff --git a/index.css b/index.css index 1cd18ea7..ac5669c5 100644 --- a/index.css +++ b/index.css @@ -2101,6 +2101,16 @@ svg.button { text-shadow: 0px 1px 4px #4c3a35; } +.epgrid line { + stroke: lightgrey; + stroke-opacity: 0.7; + shape-rendering: crispEdges; +} + +.epgrid path { + stroke-width: 0; +} + #debug { font-size: 1px; opacity: .8; diff --git a/index.html b/index.html index 7c0e1c5f..4a64ad88 100644 --- a/index.html +++ b/index.html @@ -2134,6 +2134,22 @@ diff --git a/modules/ui/elevation-profile.js b/modules/ui/elevation-profile.js index 073bf25a..1d05db06 100644 --- a/modules/ui/elevation-profile.js +++ b/modules/ui/elevation-profile.js @@ -1,4 +1,5 @@ "use strict"; + function showEPForRoute(node) { const points = []; debug.select("#controlPoints").selectAll("circle").each(function() { @@ -21,19 +22,23 @@ function showEPForRiver(node) { showElevationProfile(points, riverLen, true); } -function resizeElevationProfile() { +function closeElevationProfile() { + modules.elevation = false; } function showElevationProfile(data, routeLen, isRiver) { - // data is an array of cell indexes, routeLen is the distance, isRiver should be true for rivers, false otherwise - document.getElementById("elevationGraph").innerHTML = ""; + // data is an array of cell indexes, routeLen is the distance (in actual metres/feet), isRiver should be true for rivers, false otherwise + + document.getElementById("epScaleRange").addEventListener("change", draw); + document.getElementById("epCurve").addEventListener("change", draw); $("#elevationProfile").dialog({ title: "Elevation profile", resizable: false, width: window.width, - position: {my: "left top", at: "left+20 bottom-240", of: window, collision: "fit"} + close: closeElevationProfile, + position: {my: "left top", at: "left+20 bottom-500", of: window, collision: "fit"} }); - // prevent river graphs from showing rivers as flowing uphill + // prevent river graphs from showing rivers as flowing uphill - remember the general slope var slope = 0; if (isRiver) { if (pack.cells.h[data[0]] < pack.cells.h[data[data.length-1]]) { @@ -43,12 +48,19 @@ function showElevationProfile(data, routeLen, isRiver) { } } - const points = []; - var prevB=0, prevH=-1, i=0, j=0, cell=0, b=0, ma=0, mi=100, h=0; - for (var i=0; i d.x * w / points.length + xOffset).y(d => h-d.y + yOffset); - chart.append("path").attr("d", lineFunc(points)).attr("stroke", "purple").attr("fill", "none").attr("id", "elevationLine"); - - // y-axis labels for starting and ending heights - chart.append("text").attr("id", "epy0").attr("x", xOffset-10).attr("y", h-points[0].y + yOffset).attr("text-anchor", "end"); - document.getElementById("epy0").innerHTML = getHeight(points[0].y); - chart.append("text").attr("id", "epy1").attr("x", w+100).attr("y", h-points[points.length-1].y + yOffset).attr("text-anchor", "start"); - document.getElementById("epy1").innerHTML = getHeight(points[points.length-1].y); - - // y-axis labels for minimum and maximum heights (if not too close to start/end heights) - if (Math.abs(ma - points[0].y) > 3 && Math.abs(ma - points[points.length-1].y) > 3) { - chart.append("text").attr("id", "epy2").attr("x", xOffset-10).attr("y", h-ma + yOffset).attr("text-anchor", "end"); - document.getElementById("epy2").innerHTML = getHeight(ma); - } - if (Math.abs(mi - points[0].y) > 3 && Math.abs(mi - points[points.length-1].y) > 3) { - chart.append("text").attr("id", "epy3").attr("x", xOffset-10).attr("y", h-mi + yOffset).attr("text-anchor", "end"); - document.getElementById("epy3").innerHTML = getHeight(mi); - } + const xscale = d3.scaleLinear().domain([0, data.length]).range([0, chartWidth]); + const yscale = d3.scaleLinear().domain([0, (chartData.ma-chartData.mi) * heightScale]).range([chartHeight, 0]); - // x-axis label for start, quarter, halfway and three-quarter, and end - chart.append("text").attr("id", "epx1").attr("x", xOffset).attr("y", h+yOffset).attr("text-anchor", "middle"); - chart.append("text").attr("id", "epx2").attr("x", w / 4 + xOffset).attr("y", h+yOffset).attr("text-anchor", "middle"); - chart.append("text").attr("id", "epx3").attr("x", w / 2 + xOffset).attr("y", h+yOffset).attr("text-anchor", "middle"); - chart.append("text").attr("id", "epx4").attr("x", w / 4*3 + xOffset).attr("y", h+yOffset).attr("text-anchor", "middle"); - chart.append("text").attr("id", "epx5").attr("x", w + xOffset).attr("y", h+yOffset).attr("text-anchor", "middle"); - document.getElementById("epx1").innerHTML = "0 " + distanceUnitInput.value; - document.getElementById("epx2").innerHTML = rn(routeLen / 4) + " " + distanceUnitInput.value; - document.getElementById("epx3").innerHTML = rn(routeLen / 2) + " " + distanceUnitInput.value; - document.getElementById("epx4").innerHTML = rn(routeLen / 4*3) + " " + distanceUnitInput.value; - document.getElementById("epx5").innerHTML = rn(routeLen) + " " + distanceUnitInput.value; - - chart.append("path").attr("id", "epx11").attr("d", "M" + (xOffset).toString() + ",0L" + (xOffset).toString() +"," + (h+yOffset-15).toString()).attr("stroke", "lightgray").attr("stroke-width", "1"); - chart.append("path").attr("id", "epx12").attr("d", "M" + (w / 4 + xOffset).toString() + "," + (h+yOffset-15).toString() + "L" + (w / 4 + xOffset).toString() + ",0").attr("stroke", "lightgray").attr("stroke-width", "1"); - chart.append("path").attr("id", "epx13").attr("d", "M" + (w / 2 + xOffset).toString() + "," + (h+yOffset-15).toString() + "L" + (w / 2 + xOffset).toString() + ",0").attr("stroke", "lightgray").attr("stroke-width", "1"); - chart.append("path").attr("id", "epx14").attr("d", "M" + (w / 4*3 + xOffset).toString() + "," + (h+yOffset-15).toString() + "L" + (w / 4*3 + xOffset).toString() + ",0").attr("stroke", "lightgray").attr("stroke-width", "1"); - chart.append("path").attr("id", "epx15").attr("d", "M" + (w + xOffset).toString() + ",0L" + (w + xOffset).toString() +"," + (h+yOffset-15).toString()).attr("stroke", "lightgray").attr("stroke-width", "1"); - - // draw city labels - try to avoid putting labels over one another - var y1 = 0; - var add = 15; - points.forEach(function(p) { - if (p.b > 0) { - var x1 = p.x * w / points.length + xOffset; - y1+=add; - if (y1 >= yOffset) { y1 = add; } - var d1 = 0; - - // burg name - chart.append("text").attr("id", "ep" + p.b).attr("x", x1).attr("y", y1).attr("text-anchor", "middle"); - document.getElementById("ep" + p.b).innerHTML = pack.burgs[p.b].name; - - // arrow from burg name to graph line - chart.append("path").attr("id", "eparrow" + p.b).attr("d", "M" + x1.toString() + "," + (y1).toString() + "L" + x1.toString() + "," + parseInt(h-p.y-3+yOffset).toString()).attr("stroke", "black").attr("stroke-width", "1").attr("marker-end", "url(#arrowhead)"); + for (let i=0; i 0) { + let b = chartData.burg[k]; + + var x1 = chartData.points[k][0]; + y1+=add; + if (y1 >= yOffset) { y1 = add; } + var d1 = 0; + + // burg name + g.append("text").attr("id", "ep" + b).attr("class", "epburglabel").attr("x", x1).attr("y", y1).attr("text-anchor", "middle"); + document.getElementById("ep" + b).innerHTML = pack.burgs[b].name; + + // arrow from burg name to graph line + g.append("path").attr("id", "eparrow" + b).attr("d", "M" + x1.toString() + "," + (y1+3).toString() + "L" + x1.toString() + "," + parseInt(chartData.points[k][1]-3).toString()).attr("stroke", "darkgray").attr("fill", "lightgray").attr("stroke-width", "1").attr("marker-end", "url(#arrowhead)"); + } + } + } } diff --git a/modules/ui/rivers-editor.js b/modules/ui/rivers-editor.js index 85551976..cf25f04f 100644 --- a/modules/ui/rivers-editor.js +++ b/modules/ui/rivers-editor.js @@ -55,7 +55,7 @@ function editRiver(id) { function drawControlPoints(node) { const l = node.getTotalLength() / 2; - const segments = Math.ceil(l / 8); + const segments = Math.ceil(l / 4); const increment = rn(l / segments * 1e5); for (let i=increment*segments, c=i; i >= 0; i -= increment, c += increment) { const p1 = node.getPointAtLength(i / 1e5); @@ -183,7 +183,7 @@ function editRiver(id) { function showElevationProfile() { modules.elevation = true; - showEPForRiver(node); + showEPForRiver(elSelected.node()); } function showRiverWidth() { diff --git a/modules/ui/routes-editor.js b/modules/ui/routes-editor.js index 98974f29..b34732e2 100644 --- a/modules/ui/routes-editor.js +++ b/modules/ui/routes-editor.js @@ -47,7 +47,7 @@ function editRoute(onClick) { function drawControlPoints(node) { const l = node.getTotalLength(); - const increment = l / Math.ceil(l / 8); + const increment = l / Math.ceil(l / 4); for (let i=0; i <= l; i += increment) {addControlPoint(node.getPointAtLength(i));} routeLength.innerHTML = rn(l * distanceScaleInput.value) + " " + distanceUnitInput.value; } @@ -110,7 +110,7 @@ function editRoute(onClick) { function showElevationProfile() { modules.elevation = true; - showEPForRoute(node); + showEPForRoute(elSelected.node()); } function showGroupSection() { From bb0e57158772c0a4856fcbf544aa5029f69d2be4 Mon Sep 17 00:00:00 2001 From: Evolvedexperiment Date: Sat, 16 May 2020 12:12:15 +0000 Subject: [PATCH 02/12] Changed elevation profile to use heightmap colours --- modules/ui/elevation-profile.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/ui/elevation-profile.js b/modules/ui/elevation-profile.js index 1d05db06..9e090a76 100644 --- a/modules/ui/elevation-profile.js +++ b/modules/ui/elevation-profile.js @@ -49,14 +49,14 @@ function showElevationProfile(data, routeLen, isRiver) { } const chartWidth = window.innerWidth-280; - const chartHeight = 200; // height of our land/sea profile, excluding the biomes data below + const chartHeight = 300; // height of our land/sea profile, excluding the biomes data below const xOffset = 160; - const yOffset = 140; // this is our drawing starting point from top-left (y = 0) of SVG + const yOffset = 70; // this is our drawing starting point from top-left (y = 0) of SVG const biomesHeight = 40; - let chartData = {biome:[], burg:[], cell:[], height:[], mi:1000000, ma:0, points:[] } + let chartData = {biome:[], burg:[], cell:[], height:[], mi:1000000, ma:0, mih: 100, mah: 0, points:[] } for (let i=0, prevB=0, prevH=-1; i= 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"); + } // land let curve = d3.line().curve(d3.curveBasis); // see https://github.com/d3/d3-shape#curves From bdf5c048a8bdffc60d6b920a23274e4241619f3c Mon Sep 17 00:00:00 2001 From: Evolvedexperiment Date: Sat, 16 May 2020 16:52:28 +0000 Subject: [PATCH 03/12] Fix for FMG/MFCG sea direction integration --- modules/ui/burg-editor.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/ui/burg-editor.js b/modules/ui/burg-editor.js index f58dee11..da68ad20 100644 --- a/modules/ui/burg-editor.js +++ b/modules/ui/burg-editor.js @@ -318,7 +318,17 @@ function editBurg(id) { if (deg < 0) deg += 360; let norm = rn(normalize(deg, 0, 360) * 8) / 4; if (norm === 2) norm = 0; - return "sea="+norm; + switch(norm) { + case 0 : return "&southSea=1"; + case 0.25 : return "&southSea=1&westSea=1"; + case 0.50 : return "&westSea=1"; + case 0.75 : return "&westSea=1&northSea=1"; + case 1 : return "&northSea=1"; + case 1.25 : return "&northSea=1&eastSea=1"; + case 1.5 : return "&eastSea=1"; + case 1.75 : return "&eastSea=1&southSea=1"; + } + return "&sea="+norm; // debug.selectAll("*").remove(); // pack.burgs.filter(b => b.port).forEach(b => { // var p1 = pack.cells.p[b.cell]; @@ -450,4 +460,4 @@ function editBurg(id) { unselect(); } -} \ No newline at end of file +} From 63b5744dccdeed82f97e7d45ebf056fff47d3160 Mon Sep 17 00:00:00 2001 From: Evolvedexperiment Date: Sun, 17 May 2020 15:35:17 +0000 Subject: [PATCH 04/12] Fixes for elevation profile and CSV download --- index.css | 4 ++ index.html | 30 +++++----- modules/ui/elevation-profile.js | 101 +++++++++++++++++++++++++++----- 3 files changed, 106 insertions(+), 29 deletions(-) diff --git a/index.css b/index.css index ac5669c5..781728c7 100644 --- a/index.css +++ b/index.css @@ -2111,6 +2111,10 @@ svg.button { stroke-width: 0; } +.centered { + text-align: center; +} + #debug { font-size: 1px; opacity: .8; diff --git a/index.html b/index.html index 4a64ad88..abfdb0d8 100644 --- a/index.html +++ b/index.html @@ -2134,23 +2134,23 @@