Skip to content

Instantly share code, notes, and snippets.

@hperantunes
Last active April 11, 2023 02:23
Show Gist options
  • Save hperantunes/1110816 to your computer and use it in GitHub Desktop.
Save hperantunes/1110816 to your computer and use it in GitHub Desktop.
hexagons map
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Hexagons Test</title>
<script type="text/javascript" src="https://d3js.org/d3.v6.min.js"></script>
<style type="text/css">
svg {
border: solid 1px #aaa;
background: #eee;
}
path {
fill: lightsteelblue;
stroke: #000;
stroke-width: .5px;
}
</style>
</head>
<body>
<script type="text/javascript">
var w = 960,
h = 500,
padding = 50;
var diameter = 50;
var offset = diameter / Math.sqrt(3) * 3 / 4;
var data = [];
var index = 0;
d3.range(0, w * 2, Math.sqrt(3) * diameter / 2).map(function (v1, i) {
d3.range(0, h * 2, diameter * 3 / 4).map(function (v2, j) {
var x = j % 2 ? v1 + offset : v1,
y = v2;
data.push({
id: index++,
centroid: [x, y],
coordinates: [i, j, (i + j) * -1],
customName: 'test',
visible: x >= padding && x <= w - padding && y >= padding && y <= h - padding,
clicked: false
});
});
});
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h)
.attr("pointer-events", "all");
svg.call(d3.zoom().on("zoom", event => move(event)));
svg.append("line")
.attr("stroke", "red")
.attr("x1", 0 + padding)
.attr("y1", 0 + padding)
.attr("x2", w - padding)
.attr("y2", 0 + padding);
svg.append("line")
.attr("stroke", "red")
.attr("x1", 0 + padding)
.attr("y1", h - padding)
.attr("x2", w - padding)
.attr("y2", h - padding);
svg.append("line")
.attr("stroke", "red")
.attr("x1", 0 + padding)
.attr("y1", 0 + padding)
.attr("x2", 0 + padding)
.attr("y2", h - padding);
svg.append("line")
.attr("stroke", "red")
.attr("x1", w - padding)
.attr("y1", 0 + padding)
.attr("x2", w - padding)
.attr("y2", h - padding);
render();
function mouseover(d, i) {
d3.select(this)
.style("fill", "red");
}
function mouseout(d, i) {
d3.select(this)
.style("fill", d.clicked ? "yellow" : "lightsteelblue");
}
function click(d, i) {
d.customName = Date.now();
console.log("click", d, i);
d.clicked = !d.clicked;
d3.select(this)
.style("fill", d.clicked ? "yellow" : "lightsteelblue");
}
function move(event) {
var transform = event.transform;
data.forEach(function (d) {
var x = d.centroid[0] * transform.k + transform.x,
y = d.centroid[1] * transform.k + transform.y;
d.visible = x >= padding && x <= w - padding && y >= padding && y <= h - padding;
});
render();
svg.selectAll("path")
.attr("transform", transform.toString());
}
function render() {
var grid = svg.selectAll("path")
.data(
data.filter(function (d) {
return d.visible;
}),
function (d) {
return d.id;
}
);
grid.join(
enter => enter
.append("path")
.attr("d", function (d) {
return "M" + hex(d.centroid, diameter).join("L") + "Z";
})
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click", click),
update => update,
exit => exit.remove()
);
}
function hex(centroid, diameter, tilted) {
if (centroid == null || centroid.length != 2) {
throw new Error("centroid must be an array [x, y]");
}
if (diameter == null) {
diameter = 0;
}
if (tilted == null) {
tilted = false;
}
var a = diameter / 2,
b = (Math.sqrt(3) * a) / 2,
x = centroid[0],
y = centroid[1];
return tilted
? [[x - a / 2, y - b], [x - a, y], [x - a / 2, y + b], [x + a / 2, y + b], [x + a, y], [x + a / 2, y - b]]
: [[x - b, y - a / 2], [x - b, y + a / 2], [x, y + a], [x + b, y + a / 2], [x + b, y - a / 2], [x, y - a]];
};
</script>
</body>
</html>
<!-- Updated with suggestions from GPT-4 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment