|
<!DOCTYPE html> |
|
<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>Fix it</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="//d3js.org/d3.v4.min.js"></script> |
|
<script> |
|
|
|
var padding = {top: 100, right: 100, bottom: 100, left: 100}; |
|
|
|
var svg = d3.select("svg"), |
|
width = +svg.attr("width") - padding.top - padding.bottom, |
|
height = +svg.attr("height") - padding.left - padding.right; |
|
|
|
svg.append("defs") |
|
.append('clipPath') |
|
.attr('id', "myClipPath") |
|
.append('rect') |
|
.attr('width', width) |
|
.attr('height', height); |
|
|
|
var zoom = d3.zoom() |
|
.extent([[0, 0], [width, height]]) |
|
.scaleExtent([1, 40]) |
|
.translateExtent([[0, 0], [width, height]]) |
|
.on("zoom", zoomed); |
|
|
|
var x = d3.scaleLinear() |
|
.domain([0, width]) |
|
.range([0, width]); |
|
|
|
var y = d3.scaleLinear() |
|
.domain([0, height]) |
|
.range([0, height]); |
|
|
|
var xAxis = d3.axisBottom(x) |
|
.tickSize(height) |
|
.tickPadding(8 - height); |
|
|
|
var yAxis = d3.axisRight(y) |
|
.ticks(4) |
|
.tickSize(width) |
|
.tickPadding(8 - width); |
|
|
|
var view = svg |
|
.append("g") |
|
.attr("transform", "translate(" + padding.left + "," + padding.top + ")") |
|
.style("clip-path", "url(#myClipPath)") |
|
.append("rect") |
|
.attr("class", "view") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
var gX = svg.append("g") |
|
.attr("class", "axis axis--x") |
|
.attr("transform", "translate(" + padding.left + "," + padding.top + ")") |
|
.call(xAxis); |
|
|
|
var gY = svg.append("g") |
|
.attr("class", "axis axis--y") |
|
.attr("transform", "translate(" + padding.left + "," + padding.top + ")") |
|
.call(yAxis); |
|
|
|
d3.select("button") |
|
.on("click", fixIt); |
|
|
|
var zoomCatcher = svg |
|
.append("rect") |
|
.attr("class", "zoomCatcher") |
|
.attr("x", padding.left) |
|
.attr("y", padding.top) |
|
.attr("width", width) |
|
.attr("height", height) |
|
.attr("fill", "transparent") |
|
.attr("stroke", "none") |
|
.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 fixIt() { |
|
zoomCatcher |
|
.call(zoom.transform, d3.zoomIdentity); |
|
|
|
zoomCatcher |
|
.attr("transform", "translate(" + padding.left + "," + padding.top + ")") |
|
.attr("x", 0) |
|
.attr("y", 0); |
|
} |
|
|
|
</script> |