D3.JS V4 Minimap

D3.JS V4 Minimap utilizing transforms, duplicating html elements, pan and zoom

by Ben Sailors

HTML

<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="clone">
  <svg id="home"></svg>
</div>

CSS

#home {
  position: absolute;
  top: 15;
  left: 15;
}

#minimap {
  position: absolute;
  top: 15;
  left: 550px;
}

#minimapViewer {
  cursor: move;
  stroke: white;
  stroke-opacity: 0.75;
  stroke-width: 2px;
}

.shadow {
  border-radius: 1px;
  box-shadow: 0px 0px 0px 2px rgba(0, 0, 0, 0.5);
}

JavaScript

var aspectRatioHeight = null;
 var aspectRatioWidth = null;
 var body = null;
 var centerPoint = null;
 var currentX = null;
 var currentY = null;
 var dragBehavior = null;
 var duplicate = null;
 var elementBounds = null;
 var elementPoint = null;
 var getView = null;
 var home = null;
 var inverseK = null;
 var minimap = null;
 var minimapBackground = null;
 var minimapBoundaries = null;
 var minimapDimensions = null;
 var minimapViewer = null;
 var minimapViewerDimensions = null;
 var mouseSVGPoint = null;
 var offSetX = null;
 var offSetY = null;
 var selectedElement = null;
 var selectedX = null;
 var selectedY = null;
 var svgSource = null;
 var translateHeightRatio = null;
 var translateK = null;
 var translateWidthRatio = null;
 var translateY = null;
 var translateZ = null;
 var toBeDuplicated = null;
 var viewerBoundaries = null;
 var viewerPoint = null;
 var viewerCoords = null;
 var viewportBoundaries = null;
 var viewportDimensions = null;
 var zoom = null;

 viewportDimensions = {
   height: 300,
   width: 500
 }

 aspectRatioHeight = 0.25;
 aspectRatioWidth = 0.25;

 minimapDimensions = {
   height: viewportDimensions.height * aspectRatioHeight,
   width: viewportDimensions.width * aspectRatioWidth
 };

 minimapViewerDimensions = {
   height: minimapDimensions.height,
   width: minimapDimensions.width
 }

 home = d3.select("svg#home")
   .attr("height", viewportDimensions.height + "px")
   .attr("width", viewportDimensions.width + "px")
   .attr("class", "shadow");

 gradient = home.append("defs")
   .append("linearGradient")
   .attr("id", "gradient")
   .attr("x1", "0%")
   .attr("y1", "0%")
   .attr("x2", "100%")
   .attr("y2", "100%")
   .attr("spreadMethod", "pad")

 gradient.append("stop")
   .attr("offset", "0%")
   .attr("stop-color", "navy")
   .attr("stop-opacity", 1);

 gradient.append("stop")
   .attr("offset", "100%")
   .attr("stop-color", "gray")
   .attr("stop-opacity", 1);

 mainViewPort = home.append("rect")
   .attr("id",...