JSFiddle - React, Tailwind, and code Playground
HTML
<div id="main">
<h1>Responsive <br/>D3 "Semantic Zooming" grid <br/> with Scales</h1>
<div class="intgraph" />
</div>
CSS
line.grid {
fill: none;
stroke: #9ecae1;
stroke-width: 1.5px;
}
svg {
display:block; /* required for firefox to give valid
height and width used values for getComputedStyle()
see https://bugzilla.mozilla.org/show_bug.cgi?id=874919
*/
border: solid 1px gray;
margin:1em;
height:calc(100% - 2em);
width: calc(100% - 2em);
}
div{
height: 100%;
}
JavaScript
var w = 400,
h = 400,
gridSpacing = 10,
vLines,
hLines;
/*** Create scales to handle zoom coordinates ***/
var xScale = d3.scale.linear()
.domain([0,w]);
var yScale = d3.scale.linear()
.domain([0,h]);
//ranges will be set later based on the size
//of the SVG
/*** Configure zoom behaviour ***/
var zoomer = d3.behavior.zoom()
.scaleExtent([0.1,10])
//allow 10 times zoom in or out
.on("zoom", zoom);
//define the event handler function
function zoom() {
console.log("zoom", d3.event.translate, d3.event.scale);
//the zoom behaviour has already changed
//the domain of the x and y scales
//so we just have to redraw using them
drawLines();
}
function drawLines() {
//put positioning in a separate function
//that can be called at initialization as well
vLines.attr("x1", function(d){
return xScale(d);
})
.attr("y1", yScale(0) )
.attr("x2", function(d){
return xScale(d);
})
.attr("y2", yScale(w));
hLines.attr("x1", xScale(0))
.attr("y1", function(d){
return yScale(d);
})
.attr("x2", xScale(h))
.attr("y2", function(d){
return yScale(d);
});
}
/** Initialize SVG ***/
var svg = d3.select(".intgraph").append("svg:svg")
.attr("width", w)
.attr("height", h);
//these will be over-written with CSS
var graph = svg.append("g")
.attr("class", "graph")
.call(zoomer); //Attach zoom behaviour.
// Add a transparent background rectangle to catch
// mouse events for the zoom behaviour.
// Note that the rectangle must be inside the element (graph)
// which has the zoom behaviour attached, but must be *outside*
// the group that is going to be transformed.
var rect = graph.append("rect")
//.style("fill", "none")
//make transparent (vs black if commented-out)
...