未在svg上指定宽度和高度时,使用viewbox和keepaspect比率的自适应svg

dag*_*da1 4 html css svg

我有一个很大的svg图像,我希望它在不同情况下都能很好地缩放(请参见代码段)。

我最初使用的是svg 的widthand height属性,并且每次屏幕调整大小时都要设置这些值。

然后,我发现了视图框。

我不明白的是,如果没有svg width和height属性,该如何设置viewBox的width和height参数。

我有这个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');
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

我已经将prepareAspect比率设置为默认值,xMinYMin meet但是我不知道如何设置width和height的初始值。

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

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

我只是使用试验和错误来获取初始的viewBox值,并且我想知道programmaticallyy如何基于parenet元素或其他方式获取它们。

在线阅读很多文章,但对于第一个值和svg何时分布在整个页面上,初始值应该是什么仍然一无所知。

enx*_*eta 5

这并不完全是您所期望的答案,但我希望它可以帮助您改善问题。

这是我所做的:

  1. 在SVG中,我添加了一个<defs>元素,并在其中放置了一个多边形#thehex。接下来,我删除了SVG中的所有多边形,并使用将其替换为<use>元素#thehex。另外,在<defs>我的推杆作为<symbol>zoomout__container,因为你需要它几次。
  2. 为了减少冗长,我在CSS中移动了样式。至少对于我来说,不太冗长的SVG更易于阅读。
  3. 我已经<svg>用组或符号替换了嵌套元素。

  4. 在CSS中,我添加了vector-effect: non-scaling-stroke;,因为这样可以避免在SVG很小时丢失这些路径。

  5. 文本问题:当SVG非常小时,无法阅读文本。因此,当SVG元素的宽度小于400px时,我将删除文本,但是您可能需要重新考虑这一点。总帐组的文本也有问题,该文本具有dy="-1em,使文本出现在六边形上。您将需要对此做出决定。

  6. 同样在CSS中,我max-width: 140vh;为SHG元素添加了以使其始终位于视口中。

我没有删除您的课程,因为我认为它们可能很重要。

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);
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)