dagda1
dagda1

Reputation: 28810

responsive svg using viewbox and preserveaspect ratio when no width and height is specified on the svg

I have a large svg image and I want it scales well in different scenarios (see snippet).

I originally was using the width and height attributes of the svg and was setting these values everytime the screen resized.

I then discovered the viewbox.

What I do not understand is what do I set width and height arguments of the viewBox to if there are no svg width and height attributes.

I have this svg document

document.addEventListener("DOMContentLoaded",function(){
  var container = document.querySelector('.chart');

  container.addEventListener('click', popOut, false)
});

function popOut() {
  var container = document.querySelector('.chart');

  if (container.className.split(/\s+/).indexOf("popper") === -1) {
container.classList.add('popper');
  } 

  var svg = document.querySelector('svg');
}
html {
  min-height: 100%;
  height: 100%;
  margin: 0;
}

div {
  border: 1px solid gray;
}

body {
  height: 100%;
  font-size: 20px;
}

path {
  stroke: #000;
}

.container {
  display: flex;
  flex-direction: column;
  flex: 1;
  height: 100%;
}

.container>div {
  flex: 1;
}

.row {
  display: flex;
}

.item {
  flex: 1;
  padding: 8px;
}

.chart {
  display: inline-block;
  position: relative;
  width: 100%;
  height: 100%;
  vertical-align: top;
  overflow: hidden;
  "

}

.popper {
  z-index: 1000 !important;
  width: 100% !important;
  height: 100% !important;
  position: fixed !important;
  top: 0 !important;
  left: 0;
  background-color: #fff;
}
<html>

  <body>
<div class="container">
  <div class="item">Div One</div>
  <div class="row">
    <div class="item chart">
      <button type="button" onClick="window.popOut()">
      Pop Out
      </button>
      <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 1200 800"><g class="vx-group vx-tree" transform="translate(30, 37)"><g transform="matrix(1,0,0,1,0,0)"><g class="vx-group" transform="translate(0, 0)"><path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,176.75,567.8181818181819,176.75,567.8181818181819,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M567.8181818181819,353.5C567.8181818181819,176.75,567.8181818181819,176.75,567.8181818181819,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M946.3636363636364,353.5C946.3636363636364,176.75,567.8181818181819,176.75,567.8181818181819,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,530.25,94.63636363636364,530.25,94.63636363636364,707" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,530.25,283.90909090909093,530.25,283.90909090909093,707" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path></g><g class="vx-group" transform="translate(0, 0)"><g class="vx-group node__0" transform="translate(567.8181818181819, 0)" opacity="1"><g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon undefined"></polygon></svg>
      <g class="node__plan undefined node__inactive">
        <use xlink:href="#icon-Plan"></use>
      </g>
      <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.63100051879883" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Finance BCP</tspan></text></svg><svg x="0" y="0"
          style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.63100051879883" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Plan</tspan></text></svg></g>
      </g>
      </g>
      <g class="vx-group node__1" transform="translate(189.27272727272728, 353.5)" opacity="1">
        <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon node__active"></polygon></svg>
          <g class="node__service node__active">
            <use xlink:href="#icon-Service"></use>
          </g>
          <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Accounts Receivable</tspan></text></svg>
            <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Service</tspan></text></svg>
          </g><svg class="zoomout__container" height="20" width="20" viewBox="15 55 30 20"><g><circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle><line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line></g></svg></g>
      </g>
      <g class="vx-group node__2" transform="translate(567.8181818181819, 353.5)" opacity="1">
        <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
          <g class="node__service node__inactive">
            <use xlink:href="#icon-Service"></use>
          </g>
          <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">General Accounting</tspan></text></svg>
            <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Service</tspan></text></svg>
          </g><svg class="zoomout__container" height="20" width="20" viewBox="15 55 30 20"><g><circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle><line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line><line x1="16" y1="5" x2="16" y2="15" stroke-width="2"></line></g></svg></g>
      </g>
      <g class="vx-group node__3" transform="translate(946.3636363636364, 353.5)" opacity="1">
        <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
          <g class="node__service node__inactive">
            <use xlink:href="#icon-Service"></use>
          </g>
          <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Accounts Payable</tspan></text></svg>
            <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Service</tspan></text></svg>
          </g><svg class="zoomout__container" height="20" width="20" viewBox="15 55 30 20"><g><circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle><line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line><line x1="16" y1="5" x2="16" y2="15" stroke-width="2"></line></g></svg></g>
      </g>
      <g class="vx-group node__4" transform="translate(94.63636363636364, 707)" opacity="1">
        <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
          <g class="node__activity node__inactive">
            <use xlink:href="#icon-Activity"></use>
          </g>
          <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="52.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="-1em">General Ledger Group</tspan><tspan x="0" dy="1em">Accounting</tspan></text></svg>
            <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="72.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Activity</tspan></text></svg>
          </g>0</g>
      </g>
      <g class="vx-group node__5" transform="translate(283.90909090909093, 707)" opacity="1">
        <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
          <g class="node__activity node__inactive">
            <use xlink:href="#icon-Activity"></use>
          </g>
          <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="52.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Accounts Receivable</tspan></text></svg>
            <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="72.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Activity</tspan></text></svg>
          </g>0</g>
      </g>
      </g>
      </g>
      </g>
      </svg>
    </div>
    <div class="item">Column two</div>
    <div class="item">Column Tree</div>
  </div>
</div>

  </body>

</html>

I have set the preserveAspect ratio to the default value of xMinYMin meet but I have no idea what to set the initial values of width and height.

In my example, the svg chart starts out as a small image in the bottom left and then can popout to take over the whole page.

I really do not understand how to get the values.

I've just used trial and error to get the initial viewBox values and I'd like to know programatticaly how to get them based on the parenet element or some other way.

Read lots online but still in the dark about what the initial values should be for both the first value and when the svg spreads out over the whole page.

Upvotes: 4

Views: 1263

Answers (2)

Mark Schultheiss
Mark Schultheiss

Reputation: 34168

The important part you seem to be having a challenge with is the numbers inside the viewBox="0 0 1200 800" right?

Let's break it down just a bit: For our example, let's go with something familiar we can touch and see, a wall. Think of the viewBox as a wall. That wall is a viewport (box) you have with a nail on the wall. SVG is a squared box - like a wall the box has a width and a height. The nail falls within our wall somewhere, the nail also has a location on our wall with an x and y coordinate (top/left).

Using that as a base, these numbers (in viewBox attribute) tell you the x (left) and y (top) point on the wall where your nail is; for example viewBox="x y 1200 800" or viewBox="100 50 1200 800" says your "nail" is at position 100 (x) from left and 50 (y) from top of the wall. The nail is just used to measure from for drawing.

viewBox="left top 1200 800" Now we also have the other two numbers (1200, 800). Those are the width and height of our wall viewBox="left top width height" (the "drawing" area for our SVG in a width (1200) and height (800). Thus, we can "paint" on our wall using an x/y coordinate system and our "nail" tells us where the painting starts and where top(0) left(0) is in our coordinates on our wall. We can still paint our entire wall but where 0,0 is is defined by the "nail" (top left) point. In your case, your nail is at the top left (0,0 point) on the wall so your "paint by numbers" starts from there and can go 1200 over to the right and 800 down to the bottom.

Going with our building concept we have an opposite wall with a window in it that we look through to see our SVG wall.

NOW, think of the normal CSS top: 10px; left: 100px; as where our "window" falls on our "wall" - the top, left corner of our window is set to that we see our "svg wall" at 10px from top and 100px from left and has our 1200,800 size - so we cannot see the top 10px or the left 100px of our "wall" through our window.

For my example code, based on yours, I set this CSS so that when you pop the SVG wall up on the building and look through the window on the opposite side of our buildings room, that is where the window is:

.popper>.svgoutter {
  /*  z-index: 1000;
   width: 100%;
 height: 100%;*/
  position: fixed;
  top: 10px;
  left: 100px;
  background-color: #fff;
}

Now that we have a wall (SVG) tacked on our building (page) we can set it so that we can look at our wall there through a window we "hold" at a given place. I gave my window a lime green border and set my window size to look at our wall scaled a bit, so my "window" does not sees ALL of the svg wall but scaled, in my case to 70 percent width and height.

.svgoutter {
  border: 1px dotted lime;
  width: 70%;
  height: 70%;
}

Click the button and see the "window" pop up, click it again and see the "window" pop back.

Note that I put my "nail" at 100,50 so when you "draw" on the wall, you start your measurement from that with positive numbers, making you draw a bit "off" given your coordinates. IF you were to take all your numbers in the SVG and alter them by that 100,50 change that I made (so 133 would be 33 for the x) you would see the same thing you had with 0,0 location wise.

Note: I altered the SECOND example to show this but to get these values using code you can do something like this:

var svg = document.querySelector('svg.svgoutter');
var box = svg.getAttribute('viewBox');
var nums = box.split(/\s+|,/);
console.log(nums);
var bvbox = svg.viewBox.baseVal;
console.log( bvbox.x, bvbox.y, bvbox.width, bvbox.height );

Note the explanation how to scale the view vs changing these values which would require changing the internal numbers as well.

//document.addEventListener("DOMContentLoaded", function() {
(function() {
  let container = document.querySelector('.chart');
  container.addEventListener('click', popOut, false);
})();
//});

function popOut() {
  let popcontainer = document.querySelector('.chart');
  let popperclass = 'popper';
  popcontainer.classList.toggle(popperclass);
  // same thing as prior line:
  /*  if (!popcontainer.classList.contains(popperclass)) {
      popcontainer.classList.add(popperclass);
    } else {
      popcontainer.classList.remove(popperclass);
    }
  */
  // var svg = document.querySelector('svg');
  var svg = document.querySelector('svg.svgoutter');
var box = svg.getAttribute('viewBox');
var nums = box.split(/\s+|,/);
console.log(nums);
var bvbox = svg.viewBox.baseVal;
console.log( bvbox.x, bvbox.y, bvbox.width, bvbox.height );
}
html {
  min-height: 100%;
  height: 100%;
  margin: 0;
}

div {
  border: 1px solid grey;
}

body {
  height: 100%;
  font-size: 20px;
}

path {
  stroke: #000;
}

.container {
  display: flex;
  flex-direction: column;
  flex: 1;
  height: 100%;
}

.container>div {
  flex: 1;
}

.row {
  display: flex;
}

.item {
  flex: 1;
  padding: 8px;
}

.chart {
  display: inline-block;
  position: relative;
  width: 100%;
  height: 100%;
  /* vertical-align: top;
  overflow: hidden;*/
}

.popper>.svgoutter {
  /*  z-index: 1000;
   width: 100%;
 height: 100%;*/
  position: fixed;
  top: 10px;
  left: 100px;
  background-color: #fff;
}

.svgoutter {
  border: 1px dotted lime;
  width: 70%;
  height: 70%;
}
<body>
  <div class="container">
    <div class="item">Div One</div>
    <div class="row">
      <div class="item chart">
        <button type="button">
      Pop Out
      </button>
        <svg class="svgoutter" preserveAspectRatio="xMinYMin meet" viewBox="100 50 1200 800"><g class="vx-group vx-tree" transform="translate(30, 37)"><g transform="matrix(1,0,0,1,0,0)"><g class="vx-group" transform="translate(0, 0)"><path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,176.75,567.8181818181819,176.75,567.8181818181819,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M567.8181818181819,353.5C567.8181818181819,176.75,567.8181818181819,176.75,567.8181818181819,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M946.3636363636364,353.5C946.3636363636364,176.75,567.8181818181819,176.75,567.8181818181819,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,530.25,94.63636363636364,530.25,94.63636363636364,707" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,530.25,283.90909090909093,530.25,283.90909090909093,707" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path></g><g class="vx-group" transform="translate(0, 0)"><g class="vx-group node__0" transform="translate(567.8181818181819, 0)" opacity="1"><g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon undefined"></polygon></svg>
        <g class="node__plan undefined node__inactive">
          <use xlink:href="#icon-Plan"></use>
        </g>
        <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.63100051879883" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Finance BCP</tspan></text></svg><svg x="0" y="0"
            style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.63100051879883" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Plan</tspan></text></svg></g>
        </g>
        </g>
        <g class="vx-group node__1" transform="translate(189.27272727272728, 353.5)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon node__active"></polygon></svg>
            <g class="node__service node__active">
              <use xlink:href="#icon-Service"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Accounts Receivable</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Service</tspan></text></svg>
            </g><svg class="zoomout__container" height="20" width="20" viewBox="15 55 30 20"><g><circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle><line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line></g></svg></g>
        </g>
        <g class="vx-group node__2" transform="translate(567.8181818181819, 353.5)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
            <g class="node__service node__inactive">
              <use xlink:href="#icon-Service"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">General Accounting</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Service</tspan></text></svg>
            </g><svg class="zoomout__container" height="20" width="20" viewBox="15 55 30 20"><g><circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle><line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line><line x1="16" y1="5" x2="16" y2="15" stroke-width="2"></line></g></svg></g>
        </g>
        <g class="vx-group node__3" transform="translate(946.3636363636364, 353.5)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
            <g class="node__service node__inactive">
              <use xlink:href="#icon-Service"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Accounts Payable</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Service</tspan></text></svg>
            </g><svg class="zoomout__container" height="20" width="20" viewBox="15 55 30 20"><g><circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle><line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line><line x1="16" y1="5" x2="16" y2="15" stroke-width="2"></line></g></svg></g>
        </g>
        <g class="vx-group node__4" transform="translate(94.63636363636364, 707)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
            <g class="node__activity node__inactive">
              <use xlink:href="#icon-Activity"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="52.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="-1em">General Ledger Group</tspan><tspan x="0" dy="1em">Accounting</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="72.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Activity</tspan></text></svg>
            </g>0</g>
        </g>
        <g class="vx-group node__5" transform="translate(283.90909090909093, 707)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
            <g class="node__activity node__inactive">
              <use xlink:href="#icon-Activity"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="52.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Accounts Receivable</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="72.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Activity</tspan></text></svg>
            </g>0</g>
        </g>
        </g>
        </g>
        </g>
        </svg>
      </div>
      <div class="item">Column two</div>
      <div class="item">Column Tree</div>
    </div>
  </div>

</body>

Alternate example: Here I change the 1200,800 to 400, 266.666666667 (one third), then divided the numbers in the first two lines by 3 thus those two lines appear the same as when at the larger scale.

//document.addEventListener("DOMContentLoaded", function() {
(function() {
  let container = document.querySelector('.chart');
  container.addEventListener('click', popOut, false);
})();
//});

function popOut() {
  let popcontainer = document.querySelector('.chart');
  let popperclass = 'popper';
  popcontainer.classList.toggle(popperclass);
  // same thing as prior line:
  /*  if (!popcontainer.classList.contains(popperclass)) {
      popcontainer.classList.add(popperclass);
    } else {
      popcontainer.classList.remove(popperclass);
    }
  */
  // var svg = document.querySelector('svg');
}
html {
  min-height: 100%;
  height: 100%;
  margin: 0;
}

div {
  border: 1px solid grey;
}

body {
  height: 100%;
  font-size: 20px;
}

path {
  stroke: #000;
}

.container {
  display: flex;
  flex-direction: column;
  flex: 1;
  height: 100%;
}

.container>div {
  flex: 1;
}

.row {
  display: flex;
}

.item {
  flex: 1;
  padding: 8px;
}

.chart {
  display: inline-block;
  position: relative;
  width: 100%;
  height: 100%;
  /* vertical-align: top;
  overflow: hidden;*/
}

.popper>.svgoutter {
  /*  z-index: 1000;
   width: 100%;
 height: 100%;*/
  position: fixed;
  top: 0px;
  left: 0px;
  background-color: #fff;
}

.svgoutter {
  border: 1px dotted lime;
  width: 70%;
  height: 70%;
}
<body>
  <div class="container">
    <div class="item">Div One</div>
    <div class="row">
      <div class="item chart">
        <button type="button">
      Pop Out
      </button>
        <svg class="svgoutter" preserveAspectRatio="xMinYMin meet" viewBox="100 50 400 266.666666667><g class="vx-group vx-tree" transform="translate(30, 37)"><g transform="matrix(1,0,0,1,0,0)"><g class="vx-group" transform="translate(0, 0)"><path class="vx-link-vertical link__node" d="M63.0909090909,117.833333333C63.0909090909,58.9166666667,189.272727273,58.9166666667,189.272727273,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M189.272727273,117.833333333C189.272727273,176.75,189.272727273,176.75,189.272727273,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M946.3636363636364,353.5C946.3636363636364,176.75,567.8181818181819,176.75,567.8181818181819,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,530.25,94.63636363636364,530.25,94.63636363636364,707" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path><path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,530.25,283.90909090909093,530.25,283.90909090909093,707" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path></g><g class="vx-group" transform="translate(0, 0)"><g class="vx-group node__0" transform="translate(567.8181818181819, 0)" opacity="1"><g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon undefined"></polygon></svg>
        <g class="node__plan undefined node__inactive">
          <use xlink:href="#icon-Plan"></use>
        </g>
        <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.63100051879883" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Finance BCP</tspan></text></svg><svg x="0" y="0"
            style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.63100051879883" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Plan</tspan></text></svg></g>
        </g>
        </g>
        <g class="vx-group node__1" transform="translate(189.27272727272728, 353.5)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon node__active"></polygon></svg>
            <g class="node__service node__active">
              <use xlink:href="#icon-Service"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Accounts Receivable</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Service</tspan></text></svg>
            </g><svg class="zoomout__container" height="20" width="20" viewBox="15 55 30 20"><g><circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle><line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line></g></svg></g>
        </g>
        <g class="vx-group node__2" transform="translate(567.8181818181819, 353.5)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
            <g class="node__service node__inactive">
              <use xlink:href="#icon-Service"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">General Accounting</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Service</tspan></text></svg>
            </g><svg class="zoomout__container" height="20" width="20" viewBox="15 55 30 20"><g><circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle><line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line><line x1="16" y1="5" x2="16" y2="15" stroke-width="2"></line></g></svg></g>
        </g>
        <g class="vx-group node__3" transform="translate(946.3636363636364, 353.5)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
            <g class="node__service node__inactive">
              <use xlink:href="#icon-Service"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="48.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Accounts Payable</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="68.92399978637695" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Service</tspan></text></svg>
            </g><svg class="zoomout__container" height="20" width="20" viewBox="15 55 30 20"><g><circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle><line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line><line x1="16" y1="5" x2="16" y2="15" stroke-width="2"></line></g></svg></g>
        </g>
        <g class="vx-group node__4" transform="translate(94.63636363636364, 707)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
            <g class="node__activity node__inactive">
              <use xlink:href="#icon-Activity"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="52.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="-1em">General Ledger Group</tspan><tspan x="0" dy="1em">Accounting</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="72.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Activity</tspan></text></svg>
            </g>0</g>
        </g>
        <g class="vx-group node__5" transform="translate(283.90909090909093, 707)" opacity="1">
          <g transform="matrix(1,0,0,1,0,0)" class="node__container"><svg class="node__inactive" x="0" y="0" style="overflow: visible;"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon></svg>
            <g class="node__activity node__inactive">
              <use xlink:href="#icon-Activity"></use>
            </g>
            <g><svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__name" width="150" y="52.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0em">Accounts Receivable</tspan></text></svg>
              <svg x="0" y="0" style="overflow: visible;"><text class="label-down__item__type" width="150" y="72.00199890136719" x="0" text-anchor="middle" style="pointer-events: none;"><tspan x="0" dy="0.71em">Activity</tspan></text></svg>
            </g>0</g>
        </g>
        </g>
        </g>
        </g>
        </svg>
      </div>
      <div class="item">Column two</div>
      <div class="item">Column Tree</div>
    </div>
  </div>

</body>

Upvotes: 1

enxaneta
enxaneta

Reputation: 33044

This is not exactly the answer you are expecting but I hope it will help you improve your question.

This is what I've done:

  1. In the SVG I've added a <defs> element and I've putted a polygon #thehex inside. Next I removed all the polygons in the SVG, and replaced them with <use> elements using #thehex. Also in the <defs> I've putted as a <symbol> the zoomout__container since you need it several times.
  2. In order to reduce verbosity I've moved the styles in the CSS. A less verbose SVG is easier to read, at least for me.
  3. I've replaced the nested <svg> elements with groups or symbols.

  4. In the CSS I've added vector-effect: non-scaling-stroke;, since this avoid losing those paths when the SVG is very small.

  5. The problem with the text: When the SVG is very small, is imposible to read the text. so I'm removing the text when the SVG element is under 400px wide but you may want to reconsider this. There is also a problem with the text for the General Ledger Group this text has a dy="-1em, making the text apear over the hexagon. You will need to take a decision about this.

  6. Also in the CSS I've added max-width: 140vh; for the SHG element in order to keep it always in the view port.

I didn't removed your classes since I thought they may be important.

let S = window.getComputedStyle(svg, null);
let W = parseInt(S.getPropertyValue("width"));

function init() {
  S = window.getComputedStyle(svg, null);
  W = parseInt(S.getPropertyValue("width"));
  if (W < 400) {
    svg.style.setProperty("--display", "none");
  } else {
    svg.style.setProperty("--display", "block");
  }
}

setTimeout(function() {
  init();
  addEventListener("resize", init, false);
}, 15);
svg {
  border: 1px solid;
  overflow: visible;
  max-width: 140vh;
  display: block;
  margin: 0 auto;
}
circle {
  fill: red;
}
path {
  stroke: #000;
  vector-effect: non-scaling-stroke;
}

text {
  pointer-events: none;
  text-anchor: middle;
  font-size: 25px;
  display: var(--display);
}

line {
  stroke: gold;
  stroke-width: 50;
}
<svg id="svg" viewBox="-30 -37 1200 837" style="--display:block;">
<defs><polygon  id="thehex" points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon undefined"></polygon> 
<symbol id="zoomout__container" viewBox="0 0 30 20">
    <circle class="node__shape-fill" cx="15" cy="10" r="10" stroke-width="2"></circle>
    <line class="node__shape-fill" x1="8.5" y1="10" x2="21" y2="10" stroke-width="2"></line>
    <line x1="16" y1="5" x2="16" y2="15" stroke-width="2"></line> 
  </symbol>
</defs>
<g class="vx-group vx-tree">

<g class="vx-group" >
             <desc>connectors</desc>
             <path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,176.75,567.8181818181819,176.75,567.8181818181819,0" stroke-width="1" stroke-opacity="0.2" fill="none" ></path>
             <path class="vx-link-vertical link__node" d="M567.8181818181819,353.5C567.8181818181819,176.75,567.8181818181819,176.75,567.8181818181819,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path>
             <path class="vx-link-vertical link__node" d="M946.3636363636364,353.5C946.3636363636364,176.75,567.8181818181819,176.75,567.8181818181819,0" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none" ></path>
             <path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,530.25,94.63636363636364,530.25,94.63636363636364,707" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path>
             <path class="vx-link-vertical link__node" d="M189.27272727272728,353.5C189.27272727272728,530.25,283.90909090909093,530.25,283.90909090909093,707" percent="20.5" stroke-width="1" stroke-opacity="0.2" fill="none"></path>
 </g><!--connectors-->
            
<g class="vx-group">
  
<g class="vx-group node__0" transform="translate(567.8181818181819, 0)" opacity="1">
<g class="node__container">
<g class="node__inactive">
<use xlink:href="#thehex"></use> 
</g>
<g class="text">
<text class="label-down__item__name" y="48.63100051879883"><tspan x="0" dy="0em">Finance BCP</tspan></text>
<text class="label-down__item__type" y="68.63100051879883"><tspan x="0" dy="0.71em">Plan</tspan></text>
</g> 
<g class="node__plan undefined node__inactive">
<use xlink:href="#icon-Plan"></use>
</g>
</g>
</g><!--node__0-->
              
              
<g class="vx-group node__1" transform="translate(189.27272727272728, 353.5)" opacity="1">
<g class="node__container">
<g class="node__inactive">
<use xlink:href="#thehex"></use>
</g>
<g class="text">
<text class="label-down__item__name" y="48.92399978637695"><tspan x="0" dy="0em">Accounts Receivable</tspan></text>
            <text class="label-down__item__type" y="68.92399978637695"><tspan x="0" dy="0.71em">Service</tspan></text>
</g>          
<g class="node__service node__active">
<use xlink:href="#icon-Service"></use>
</g>          
<use xlink:href="#zoomout__container" class="zoomout__container" x=-10 y="-10"  height="20" width="20" />                   
</g>
</g><!--node__1-->
      
              
<g class="vx-group node__2" transform="translate(567.8181818181819, 353.5)" opacity="1">
<g class="node__container">
<g class="node__inactive">
<use xlink:href="#thehex"></use>
</g>
<g class="text">
<text class="label-down__item__name" width="150" y="48.92399978637695"><tspan>General Accounting</tspan></text>
<text class="label-down__item__type" width="150" y="68.92399978637695"><tspan dy="0.71em">Service</tspan></text></g> 
<g class="node__service node__inactive">
<use xlink:href="#icon-Service"></use>
</g>
<use xlink:href="#zoomout__container" class="zoomout__container" x=-10 y="-10"  height="20" width="20" />
</g>
</g><!--node__2-->
              
  
<g class="vx-group node__3" transform="translate(946.3636363636364, 353.5)" opacity="1">
<g class="node__container">
<g class="node__inactive">
<use xlink:href="#thehex"></use>
</g>
<g class="text">
<text class="label-down__item__name" y="48.92399978637695" x="0"><tspan x="0" dy="0em">Accounts Payable</tspan></text>
<text class="label-down__item__type" width="150" y="68.92399978637695"><tspan x="0" dy="0.71em">Service</tspan></text>
</g>   
<g class="node__service node__inactive">
<use xlink:href="#icon-Service"></use>
</g>
<use xlink:href="#zoomout__container" class="zoomout__container" x=-10 y="-10"  height="20" width="20" />
</g>
</g><!--node__3-->
  
  
<g class="vx-group node__4" transform="translate(94.63636363636364, 707)" opacity="1">
<g class="node__container">
<g class="node__inactive">
<use xlink:href="#thehex"></use>
</g>
<g class="text">
<text class="label-down__item__name" y="52.00199890136719"><tspan dy="-1em">General Ledger Group</tspan><tspan x="0" dy="1em">Accounting</tspan></text>
<text class="label-down__item__type" y="72.00199890136719"><tspan dy="0.71em">Activity</tspan></text>
</g> 
<g class="node__activity node__inactive">
<use xlink:href="#icon-Activity"></use>
</g>
</g>
</g><!--node__4-->
  
<g class="vx-group node__5" transform="translate(283.90909090909093, 707)" opacity="1">
<g class="node__container">
<g class="node__inactive">
<use xlink:href="#thehex"></use></g>
<g class="text">
<text class="label-down__item__name" width="150" y="52.00199890136719"><tspan x="0" dy="0em">Accounts Receivable</tspan></text>
<text class="label-down__item__type" width="150" y="72.00199890136719"><tspan dy="0.71em">Activity</tspan></text>
</g>  
<g class="node__activity node__inactive">
<use xlink:href="#icon-Activity"></use></g>        
</g>
</g><!--node__5-->

</g><!--nodes-->

</g><!--tree-->
</svg>

Upvotes: 5

Related Questions