Skip to content

Instantly share code, notes, and snippets.

@rubillionaire
Last active May 12, 2022 16:29
Show Gist options
  • Save rubillionaire/9406350 to your computer and use it in GitHub Desktop.
Save rubillionaire/9406350 to your computer and use it in GitHub Desktop.
Transition viewBox.

Example of using the viewBox to zoom into a number of areas of interest.

<!DOCTYPE html>
<html>
<head>
<title>Transition ViewBox</title>
<link rel='stylesheet' type='text/css' href='' />
<meta http-equiv='content-type' content='text/html; charset=utf-8' />
<meta name='viewport' content='initial-scale=1.0 maximum-scale=1.0'>
<style>
.body {
width: 960px;
height: 500px;
margin: 0;
padding: 0;
}
.big {
fill: rgb(65, 45, 109);
}
.small {
fill: white;
opacity: 0.5;
}
.label {
font-family: Helvetica;
font-size: 100px;
font-weight: bold;
position: absolute;
left: 10%;
color: white;
text-align: center;
}
</style>
</head>
<body>
<svg width="960" height="500">
<g>
<rect x="0" y="0" width="960" height="500" class="aoi big" data-name="all"/>
<rect x="140" y="140" width="38.4" height="20" class="aoi small" data-name="region1"/>
<rect x="180" y="180" width="76.8" height="40" class="aoi small" data-name="region2"/>
<rect x="300" y="400" width="192" height="100" class="aoi small" data-name="region3"/>
<rect x="500" y="100" width="200" height="104.16" class="aoi small" data-name="region4"/>
<rect x="200" y="200" width="576" height="300" class="aoi small" data-name="region5"/>
</g>
</svg>
<p class="label"></p>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
// get selection from DOM
var svg = d3.select('svg')
label = d3.select('.label');
// get the overall area to define
// the viewbox.
var width = svg.attr('width'),
height = svg.attr('height');
// set the initial view box
// 0 0 are the x and y coordinates
// preserveAspectRatio will ensure
// things scale properly
svg.attr('viewBox', '0 0 ' + width + ' ' + height)
.attr('preserveAspectRatio', 'xMinYMin meet');
// stash all areas of interest;
var aois = {}
// get data for each of the
// areas of interest, based
// on the elements with `.aoi`
svg.selectAll('.aoi')
.datum(function () {
// define the datum for this selection
// based on the data- attributes for
// the elements
return this.dataset;
})
.each(function (d) {
// d is the current datum
// aoi is the current element
var aoi = d3.select(this);
// assuming none of the area of interest
// are named the same
aois[d.name] = {
viewBox: aoi.attr('x') + ' ' +
aoi.attr('y') + ' ' +
aoi.attr('width') + ' ' +
aoi.attr('height')
};
});
// make scale to rotate
// through different AOIs
var scale = d3.scale.ordinal()
.range(Object.keys(aois)),
count = 0;
setInterval(function () {
count += 1;
var current = scale(count);
// transition the svg
svg.transition()
.duration(1000)
.each('start', function () {
// at the beginning of the transition
// set the label to nothing, move it out
// of the way
label.text('')
.style('top', '-100%');
})
.attr('viewBox', aois[current].viewBox)
.each('end', function () {
// at the end of the transition
// set the label to the name of the
// current AOI, move it back into place
label.text(current)
.style('top', '10%');
});
}, 2000);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment