没有指定SVG宽高时,使用viewbox和preserveAspectRatio实现响应式SVG

4

我有一个很大的SVG图像,希望它能在不同的场景下进行良好的缩放(请参见代码片段)。

最初,我使用svg的widthheight属性,并在屏幕大小调整时设置这些值。

然后,我发现了viewBox。

我不明白的是,如果没有svg的宽度和高度属性,我该将viewBox的宽度和高度参数设置为什么。

我有这个SVG文档:

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>

我已将preserveAspectRatio设置为默认值xMinYMin meet,但我不知道要将宽度和高度的初始值设为什么。

在我的示例中,svg图表从左下角开始作为小图像,然后可以弹出并占据整个页面。

我真的不明白如何获得这些值。

我只是使用试错法来获取初始viewBox值,我想以编程方式根据父元素或其他方式获取它们。

阅读了很多文章,但仍然不清楚第一个值和svg扩展到整个页面时应该是什么初始值。


2
我认为这会对您有所帮助: https://css-tricks.com/scale-svg/ - Krunal
你想要精确地实现什么?在页面调整大小时调整视图框? - NVRM
我已经添加了一些边框来显示它最初需要缩放的区域。 - dagda1
是的,我基本上理解它创建了一个新的用户坐标系,但基于什么,我不明白。如果SVG具有高度和宽度属性,我可以理解它,并且我了解如果viewBox的宽度和高度与SVG的宽度和高度不同,它如何缩放以及缩放的工作原理,但如果这些值不存在,通常情况下它们不存在,那么我就不明白它是如何工作的。我理解minX和minY是变换。 - dagda1
为什么不把您的<svg>转换成svg文件,然后使用 background: url('some.svg'); 来包含它,使用 background-size: cover/contain/value's 来设置样式。当需要 "弹出" 时,只需扩展 column 1 并将其放置到其他 div 的上方,使用 position:fixedabsolute 并设置 z-index 即可。 - Ramon de Vries
显示剩余5条评论
2个回答

5
这并不是您期望的答案,但我希望它能帮助您改进问题。
以下是我的操作步骤:
1. 在SVG中添加了一个

谢谢你的回答。你从哪里获取了你的viewBox值?这是我真正难以理解的部分。你从哪里得到这些值的? - dagda1
在你的代码中,你有viewBox="0 0 1200 800",然后你将所有内容都翻译成了transform="translate(30, 37)"。由于我不喜欢太多的变换,所以我删除了它,并将viewBox更改为viewBox="-30 -37 1200 800"。然后我给SVG添加了一个边框,发现图表溢出了,所以我增加了一点额外的高度。 - enxaneta
我通过试错得到了这些值,你知道获取这些值的更编程化的方法吗?虽然它们能够工作,但我不明白为什么。 - dagda1
你需要将所有内容都包裹在一个<g>元素中,然后在JS代码中使用theG.getBBox()来获取<g>元素。该方法返回的是所有内容的边界框,您可以使用它来设置SVG的viewBox。重要提示:不要对theG应用变换。 theG.getBBox()返回一个对象,其中包含xywidthheight属性。wiewBox应该如下所示:“x,y,width,height”。 - enxaneta
你会将 <svg /> 元素包裹在一个 <g /> 元素中吗? - dagda1
不,你需要将SVG中的所有内容都包裹在一个g元素内部。 - enxaneta

1
你似乎遇到了一个挑战,就是viewBox="0 0 1200 800"中的数字部分,对吧?
让我们稍微解释一下:以我们熟悉的可以触摸和看到的墙为例,将viewBox视为一面墙。这堵墙是一个视口(盒子),上面有一个钉子。SVG是一个正方形盒子——像墙一样,该盒子有宽度和高度。钉子落在我们的墙上的某个地方,钉子在我们的墙上也有一个位置,具有x和y坐标(顶部/左侧)。
以此为基础,这些数字(在viewBox属性中)告诉您钉子在墙上的x(左)和y(上)点的位置;例如,viewBox="x y 1200 800"或viewBox="100 50 1200 800"表示您的“钉子”位于距离墙左侧100(x)和距离墙顶部50(y)的位置。钉子只是用来测量绘图的。 viewBox="left top 1200 800"现在我们还有另外两个数字(1200,800)。这些是我们墙壁的宽度和高度viewBox="left top width height"(SVG中“绘图”区域的宽度(1200)和高度(800))。因此,我们可以使用x/y坐标系在我们的“墙壁”上“绘画”,而我们的“钉子”告诉我们绘画从哪里开始,在我们的坐标系中顶部(0)左侧(0)在我们的墙上。我们仍然可以在整个墙上绘画,但0,0在哪里由“钉子”(左上角)点定义。在您的情况下,您的钉子位于墙壁的左上角(0,0点),因此您的“按号码涂色”从那里开始,并且可以向右移动1200并向下移动800。
按照我们的建筑概念,我们有一面相反的墙壁,其中有一个窗户,我们通过它看到我们的SVG墙壁。
现在,将普通的CSS top: 10px; left: 100px; 视为我们的“窗口”在我们的“墙”上的位置 - 窗口的左上角设置为我们从顶部看到“svg 墙”的距离为10px,距左侧100px,大小为1200,800 - 因此,我们无法通过窗户看到我们“墙”的顶部10px或左侧100px。
对于我的示例代码,基于您的代码,我设置了这个CSS,以便当您将SVG墙弹出到建筑物上并从建筑物房间的另一侧的窗户中观察时,那就是窗户的位置:
.popper>.svgoutter {
  /*  z-index: 1000;
   width: 100%;
 height: 100%;*/
  position: fixed;
  top: 10px;
  left: 100px;
  background-color: #fff;
}

现在我们在建筑物(页面)上贴上了一堵墙(SVG),我们可以将其设置为通过我们“持有”的窗口在那里查看我们的墙。我给我的窗户加了一个青柠绿色的边框,并将窗口大小设置为稍微缩放后查看我们的墙壁,因此我的“窗户”没有看到所有的SVG墙壁,而是缩放到70%的宽度和高度。
.svgoutter {
  border: 1px dotted lime;
  width: 70%;
  height: 70%;
}

点击按钮,看到“窗口”弹出,再次点击,看到“窗口”弹回。

请注意,我将我的“钉子”放在100,50处,因此当您在墙上“绘画”时,您从那里开始测量正数,使您的坐标有点“偏离”。如果您将SVG中的所有数字更改为我所做的100,50更改(因此133的x为33),则在位置方面会看到与0,0相同的内容。

注意:我更改了第二个示例以显示此内容,但要使用代码获取这些值,您可以执行以下操作:

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 );

请注意如何缩放视图而不更改这些值,这将需要同时更改内部数字。

//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>

另一个例子:这里我将1200、800更改为400、266.666666667(三分之一),然后将前两行中的数字除以3,因此这两行在较大比例尺下出现相同。

//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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接