Browse Source

Make map zoom-able, pan-able.

master
Ben Kurtovic 4 years ago
parent
commit
da60b89cb6
4 changed files with 85 additions and 35 deletions
  1. +3
    -5
      static/main.css
  2. +19
    -0
      static/map.css
  3. +62
    -29
      static/map.js
  4. +1
    -1
      templates/map/map.mako

+ 3
- 5
static/main.css View File

@@ -52,11 +52,7 @@ abbr[title], acronym[title] {
}

main, header, footer {
background-color: rgba(0, 0, 0, 0.8);
}

main {
border-width: 1px;
background-color: rgba(0, 0, 0, 0.85);
}

header {
@@ -84,6 +80,7 @@ header > div, footer > div {
main {
margin: 2em auto;
padding: 0.5em 1.5em;
border-width: 1px;
}

header > div {
@@ -117,6 +114,7 @@ header > div, footer > div {
main {
margin: 1.5em auto;
padding: 0 1em;
border-width: 1px 0;
}

footer > div {


+ 19
- 0
static/map.css View File

@@ -1,3 +1,22 @@
.map-1 {
display: flex;
}

.map-2 {
flex: 1;
}

.map-3 {
height: 100%;
}

@media (min-width: 800px) {
.map-2 {
max-width: none;
margin: 2em;
}
}

#map .system {
fill: currentColor;
}

+ 62
- 29
static/map.js View File

@@ -1,47 +1,80 @@
var get_bounds = function(data) {
var xmin = Infinity, xmax = -Infinity,
ymin = Infinity, ymax = -Infinity;

for (var sid in data["galaxy"]) {
var system = data["galaxy"][sid];
var x = system["coords"][0];
var y = system["coords"][2];
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}

var xspan = xmax - xmin;
var yspan = ymax - ymin;

return [xmin, ymin, xspan, yspan];
}

$(function() {
$("#map").html("<p>Loading map data...</p>");
$.getJSON( "map/data.json", function(data) {
$("#map").empty();
var svg = d3.select("#map").append("svg")
.attr("width", 1000)
.attr("height", 1000); // TODO: dynamic

var xmin = Infinity, xmax = -Infinity,
ymin = Infinity, ymax = -Infinity;
for (var sid in data["galaxy"]) {
var system = data["galaxy"][sid];
var x = system["coords"][0];
var y = system["coords"][2];
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}

var width = xmax - xmin;
var height = ymax - ymin;
$("#map").append($("<p>").text("Loading map data..."));
$.getJSON( "map/data.json", data => {
var [xmin, ymin, xspan, yspan] = get_bounds(data);
var scale = 1000;

svg.attr("viewBox", "0 0 " + scale + " " + scale);
$("#container > div").addClass("map-1");
$("main").addClass("map-2");
$("#map").empty().addClass("map-3");

svg.selectAll("circle")
var svg = d3.select("#map").append("svg")
.attr("viewBox", (-0.5 * scale) + " " + (-0.5 * scale) +
" " + scale + " " + scale);
var stars = svg.append("g");

stars.selectAll("circle")
.data(Object.values(data["galaxy"]))
.enter()
.append("circle")
.attr("cx", (d) => {
.attr("cx", d => {
var x = d["coords"][0];
return (x - xmin) / width * scale;
return ((x - xmin) / xspan - 0.5) * scale;
})
.attr("cy", (d) => {
.attr("cy", d => {
var y = d["coords"][2];
return (y - ymin) / height * scale;
return ((y - ymin) / yspan - 0.5) * scale;
})
.attr("r", 1)
.attr("class", (d) => {
.attr("r", 2)
.attr("class", d => {
var sec = d["security"];
var klass = sec < 0.05 ? "null" :
Number(sec).toFixed(1).replace(".", "_");
return "system sec-" + klass;
});

var lastk = 1;
var zoom = d3.zoom()
.scaleExtent([1, 50])
.on("zoom", () => {
var trans = d3.event.transform;
var clamp = (scale / 2) * (trans.k - 1);
trans.x = Math.max(Math.min(trans.x, clamp), -clamp);
trans.y = Math.max(Math.min(trans.y, clamp), -clamp);
stars.attr("transform", trans);
if (trans.k != lastk) {
stars.selectAll("circle").attr("r", 6 / (trans.k + 2));
lastk = trans.k;
}
})
svg.call(zoom);

$(window).resize(() => {
svg.style("display", "none")
.attr("width", $("#map").width())
.attr("height", $("#map").height() - 5)
.style("display", "");
});
$(window).resize();
});
});

+ 1
- 1
templates/map/map.mako View File

@@ -9,8 +9,8 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.4.1/d3.min.js" integrity="sha256-4mL8TQfOJSbg0f42dQw5cKLl2ngQXUSXqfQnvK11M44=" crossorigin="anonymous"></script>
${self.support.makejs("map.js")}
</%block>
<h2>Map</h2>
<div id="map">
<h2>Map</h2>
<noscript>
<p>JavaScript is required to display the galaxy map.</p>
</noscript>


Loading…
Cancel
Save