This example demonstrates using d3-zoom to drive changes to scales’ domains via transform.rescaleX and transform.rescaleY. The transformed scales are used to draw axes. The transform is also applied via SVG transform to the colorful rainbow rect. (The colors are from Nadieh Bremer’s lovely SVG gradient tutorial.)
xxxxxxxxxx
<meta charset="utf-8">
<style>
.axis path {
display: none;
}
.axis line {
stroke-opacity: 0.3;
shape-rendering: crispEdges;
}
.view {
fill: url(#gradient);
stroke: #000;
}
button {
position: absolute;
top: 20px;
left: 20px;
}
</style>
<button>Reset</button>
<svg width="960" height="500">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0.0%" stop-color="#2c7bb6"></stop>
<stop offset="12.5%" stop-color="#00a6ca"></stop>
<stop offset="25.0%" stop-color="#00ccbc"></stop>
<stop offset="37.5%" stop-color="#90eb9d"></stop>
<stop offset="50.0%" stop-color="#ffff8c"></stop>
<stop offset="62.5%" stop-color="#f9d057"></stop>
<stop offset="75.0%" stop-color="#f29e2e"></stop>
<stop offset="87.5%" stop-color="#e76818"></stop>
<stop offset="100.0%" stop-color="#d7191c"></stop>
</linearGradient>
</defs>
</svg>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var zoom = d3.zoom()
.scaleExtent([1, 40])
.translateExtent([[-100, -100], [width + 90, height + 100]])
.on("zoom", zoomed);
var x = d3.scaleLinear()
.domain([-1, width + 1])
.range([-1, width + 1]);
var y = d3.scaleLinear()
.domain([-1, height + 1])
.range([-1, height + 1]);
var xAxis = d3.axisBottom(x)
.ticks((width + 2) / (height + 2) * 10)
.tickSize(height)
.tickPadding(8 - height);
var yAxis = d3.axisRight(y)
.ticks(10)
.tickSize(width)
.tickPadding(8 - width);
var view = svg.append("rect")
.attr("class", "view")
.attr("x", 0.5)
.attr("y", 0.5)
.attr("width", width - 1)
.attr("height", height - 1);
var gX = svg.append("g")
.attr("class", "axis axis--x")
.call(xAxis);
var gY = svg.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
d3.select("button")
.on("click", resetted);
svg.call(zoom);
function zoomed() {
view.attr("transform", d3.event.transform);
gX.call(xAxis.scale(d3.event.transform.rescaleX(x)));
gY.call(yAxis.scale(d3.event.transform.rescaleY(y)));
}
function resetted() {
svg.transition()
.duration(750)
.call(zoom.transform, d3.zoomIdentity);
}
</script>
https://d3js.org/d3.v5.min.js