Notes
-
There are two separate SVG elements on the page:
- main (for the main SVG)
- mini (for the minimap)
-
Each SVG lies within a div, named after its purpose (
div#main
anddiv#mini
) -
The main SVG is nested within another SVG (svg.aperture)
- This allows us to have a "magnifying glass"
- The layout is then something like this:
- section.vis -> div#main -> svg.aperture -> svg#butterfly
- section.vis -> div#mini -> svg
-
Use CSS to size the SVGs appropriately on the page
- Here I'm using flexbox, and setting the main SVG to be 3 times the size of the minimap
-
About widths and heights:
- The butterfly SVG from Bill White's examples has
width
andheight
attributes- I've rounded those up to round integer values in
svg#butterfly
- These values are copied into the containing SVG (
svg.aperture
), so that the viewport of that main svg is defined.- This holds the aspect ratio of
svg.aperture
constant on the page, while itsviewBox
string changes (this method uses that viewBox string to zoom and translate). - CSS is additionally used to size the SVG itself to fit on the screen with a 3:1 ratio vs the minimap
- Using
flex-grow: 3
for the main SVG andflex-grow: 1
for the minimap will ensure that the main is 3 times as large as the minimap on screen. The two SVGs might still have identical width and height attributes.
- Using
- This holds the aspect ratio of
- The rounded up width and height are used to define the
viewBox
attribute the magnifying SVG (svg.aperture
)viewBox
is the string of the form"<min-x> <min-y> width height"
so we get"0 0 400 250"
- The same
viewBox
is also applied to the minimap SVG
- I've rounded those up to round integer values in
- The magnifying glass effect on
svg.aperture
is due to itspreserveAspectRatio
attribute beingnone
- This attribute value means that
svg#butterfly
(which is contained withinsvg.aperture
) will stretch to fit its parent (svg.aperture
), regardless of width:height ratio
- This attribute value means that
- The butterfly SVG from Bill White's examples has
-
Rendering the SVG twice
- The butterfly svg has an
id
attribute. This is required for this technique to work. - The minimap svg re-renders the main svg via the
<use xlink:href="#butterfly">
- This means that whatever dynamic behaviour your main SVG has will reflect in the minimap
- see the Josquin ribbon for a working example
- This means that whatever dynamic behaviour your main SVG has will reflect in the minimap
- The butterfly svg has an
-
Zoom behavior
- a single d3.zoom object is applied to both:
svg.aperture
and the minimap SVG.- The minimap's zoom callback calls the main svg's zoom callback, which then:
- calculates the new viewBox values based on the zoom.transform's
x
,y
andk
values- x and y are the initial coordinates and the initial viewBox lengths are multiplied by the k-value
- sends the viewbox dimensions as extents for brush.move()
- manually sets the
__zoom
property on the minimap.
- calculates the new viewBox values based on the zoom.transform's
- The minimap's zoom callback calls the main svg's zoom callback, which then:
- d3.brush is applied to the minimap SVG.
- It doesn't call any of the zoom callbacks. Instead it:
- sets the
__zoom
property for the main and minimap SVGs - sets the main SVGs viewBox based on the brush.extent()
- sets the
- It doesn't call any of the zoom callbacks. Instead it:
- Thus, mouse wheel events on either SVG leads to zoom
- By storing the
__zoom
property on each, we ensure that both SVGs have the same zoom values at all times.
- By storing the
- a single d3.zoom object is applied to both:
Links
- Bill White's original work
- His update using d3v4 (also works in v5)
- and the ensuing discussion
- A most important primer on SVG coordinate systems
Built with blockbuilder.org
forked from seemantk's block: "Minimap" Zoom/Pan with viewBox
If we drag on main SVG, it goes to opposite direction and sometimes also got stuck.
Is there any way to drag main SVG smooth like we do from minimap ?