Как использовать javascript для поиска позиции (svg) ранее существовавших элементов в встроенном svg - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь использовать JavaScript для рисования линий между различными элементами SVG. Элементы svg находятся в ранее существующем svg-изображении (созданном с помощью inkScape), которое загружается внутри.

Я зацикливаюсь на поиске правильных координат существующих элементов SVG относительно самого документа SVG для рисования линий.

См. Следующий фрагмент, например. Я пытаюсь реализовать функцию FindSVGPosition.

$(function() {
  $("[id^=sys_]").addClass("sysGroup");
  $(".sysGroup").click(function(e) {
    var sysElement = $(this);
    var id = $(sysElement).attr("id");
    var sysName = id.substr(4);
    var metaNameId = "meta_" + sysName;
    var metaElmnt = $("#" + metaNameId);
    if (metaElmnt != undefined) {
      //showCenter('system1');
      if ($(metaElmnt).is(":visible")) {
        $(metaElmnt).hide("fast");
      } else {
        var position = findDOMPosition(sysName);
        $(metaElmnt).css(
          "top",
          window.scrollY + position.height + position.y + 2
        );
        $(metaElmnt).css("left", window.scrollX + position.x);
        $(metaElmnt).show("fast");
      }
    }
  });

  function drawPath(fromSystemName, toSystemName) {
    var pathBetween = findPathBetween(fromSystemName, toSystemName);
    var newLine = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "line"
    );
    newLine.setAttribute(
      "id",
      pathBetween.fromSystemName + "_" + pathBetween.toSystemName
    );
    newLine.setAttribute("x1", pathBetween.fromX);
    newLine.setAttribute("y1", pathBetween.fromY);
    newLine.setAttribute("x2", pathBetween.toX);
    newLine.setAttribute("y2", pathBetween.toY);
    newLine.setAttribute("stroke", "red");
    $("#svg8").append(newLine);
    return pathBetween;
  }

  function findPathBetween(fromSystemName, toSystemName) {
    var fromPosition = findSVGPosition(fromSystemName);
    var toPosition = findSVGPosition(toSystemName);
    if (fromPosition == null || toPosition == null) return null;

    //center to center
    var response = {
      fromSystem: fromSystemName,
      fromX: fromPosition.x + fromPosition.width / 2,
      fromY: fromPosition.top + fromPosition.height / 2,
      fromSide: "center",
      toSystem: toSystemName,
      toX: toPosition.x + toPosition.width / 2,
      toY: toPosition.top + toPosition.height / 2,
      toSide: "center"
    };
    return response;
  }

  function findSVGPosition(systemName) {
    //d.x, d.y, d.top, d.right, d.bottom, d.height
    
  }
  
  function findDOMPosition(systemName) {
    //d.x, d.y, d.top, d.right, d.bottom, d.height
    var systemElement = $("#sys_" + systemName);
    if (systemElement == null) return null;
    return $(systemElement)
      .get(0)
      .getBoundingClientRect();
  }
});
#systemDiagram{
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.meta{
  width: 350px;
  font-size: smaller;
}
p, ul{
  margin-top: 0px;
}
.metaHeader{
  font-size: large;  
}
text:hover{
  cursor: default;
}
.sysGroup:hover{
    cursor: pointer;
}
.sysGroup text:hover{
  cursor: pointer;
}
#info-box, .meta {
  display: none;
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 1;
  background-color: #eaeded;
  border: 2px solid #239b56;
  border-radius: 5px;
  padding: 5px;
  font-family: arial;
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js">
</script>
<div>
  <p>lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum. lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum. lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum.</p>
  <p>lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum. lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum. lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum.</p>  
  
</div>
<div id="info-box"></div>
<div class="meta" id="meta_system1">
  <div><span class="metaHeader">Description</span></div>
  <p>description</p>
</div>  
<div class="meta" id="meta_system2">
  <div>Something here for system2</div>
</div>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="14in"
   height="8.5in"
   viewBox="0 0 355.6 215.9"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
   sodipodi:docname="drawing.02.svg">
  <defs
     id="defs2" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="1.0404412"
     inkscape:cx="485.6749"
     inkscape:cy="543.80097"
     inkscape:document-units="mm"
     inkscape:current-layer="layer1"
     showgrid="false"
     inkscape:window-width="1920"
     inkscape:window-height="1018"
     inkscape:window-x="-8"
     inkscape:window-y="-8"
     inkscape:window-maximized="1"
     units="in" />
  <metadata
     id="metadata5">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:groupmode="layer"
     id="layer2"
     inkscape:label="systemGroups" />
  <g
     inkscape:groupmode="layer"
     id="layer3"
     inkscape:label="ancillary"
     style="display:none"
     sodipodi:insensitive="true">
    <rect
       style="display:inline;opacity:0.4;fill:#ffcc00;fill-opacity:1;stroke:none;stroke-width:0.23668619"
       id="rect175"
       width="115.25188"
       height="27.459745"
       x="127.27588"
       y="14.725033" />
  </g>
  <g
     inkscape:label="systems"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(0,-81.1)"
     style="display:inline">
    <g
       id="sys_system1"
       transform="translate(15.595292,0.08990834)"
       inkscape:label="#g164">
      <rect
         style="fill:#000080;fill-opacity:1;stroke-width:0.1389997"
         y="102.51232"
         x="48.695206"
         height="12.662203"
         width="23.878363"
         id="rect47"
         inkscape:label="#rect4524-9" />
      <text
         id="text51"
         y="110.01817"
         x="51.767498"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
           y="110.01817"
           x="51.767498"
           id="tspan49"
           sodipodi:role="line">System1</tspan></text>
    </g>
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect95"
       width="177.46696"
       height="27.528765"
       x="10.156241"
       y="95.21151" />
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect97"
       width="133.36749"
       height="39.555889"
       x="19.777945"
       y="94.142426" />
    <g
       id="sys_system2"
       inkscape:label="#g90"
       transform="translate(-5.0449918)">
      <rect
         style="fill:#aa8800;fill-opacity:1;stroke-width:0.13352577"
         y="139.75128"
         x="70.257324"
         height="12.662203"
         width="22.034693"
         id="rect47-1"
         inkscape:label="#rect4524-9" />
      <text
         id="text51-2"
         y="147.25714"
         x="73.32962"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#000000;fill-opacity:1;stroke-width:0.26458332"
           y="147.25714"
           x="73.32962"
           id="tspan49-8"
           sodipodi:role="line">System2</tspan></text>
    </g>
  </g>
</svg>

Я могу найти координаты элементов svg относительно DOM и правильно разместить div под этими элементами.

Я могу нарисовать линию на svg, используя javascript в произвольной начальной и конечной точках.

Я не могу получить доступ к атрибутам svg (x, y, высота, ширина) существующих элементов svg относительно изображения svg.

Большинство примеров, которые я могу найти, используют contentDocument элемента svg. Но в моем случае, что бы я ни пытался - contentDocument имеет значение null.

Так как я не запускаю это действие при загрузке страницы - я уверен, что svg должен быть полностью загружен в dom при запуске кода.

Кажется, что это легко можно сделать без каких-либо библиотек, но я слишком долго пытался понять это и мог бы действительно использовать некоторую помощь.

1 Ответ

3 голосов
/ 02 мая 2019
  1. Во-первых, вы все усложняете для себя из-за всех атрибутов transform для элементов в SVG. Моя первая рекомендация - избавиться от них всех.

    Самый простой способ сделать это в Inkscape - это разгруппировать, а затем перегруппировать объекты.

  2. Если вы сделаете это, ваша функция проста:

    function findSVGPosition(systemName) {
      return document.getElementById(systemName).getBBox();
    }
    

    Функция getBBox() возвращает ограничивающий прямоугольник элемента SVG. Но ограничивающий прямоугольник не учитывает преобразования элемента или его родительских элементов. Границы не будут полезны, если есть преобразования. Вот почему мы избавились от них на шаге № 1.

  3. Затем исправьте опечатки в findPathBetween(): .top должен .y.

  4. Наконец, вам нужно вызвать функцию drawPath().

    drawPath('sys_system1', 'sys_system2');
    
  5. Но линия сверху коробок. Так что вы, вероятно, захотите сделать .prepend() вместо .append(). Так что линия находится перед - и, следовательно, под - коробки.

    $("#svg8").prepend(newLine);
    

Тогда вы в конечном итоге с этим.

function drawPath(fromSystemName, toSystemName) {
    var pathBetween = findPathBetween(fromSystemName, toSystemName);
    var newLine = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "line"
    );
    newLine.setAttribute(
      "id",
      pathBetween.fromSystemName + "_" + pathBetween.toSystemName
    );
    newLine.setAttribute("x1", pathBetween.fromX);
    newLine.setAttribute("y1", pathBetween.fromY);
    newLine.setAttribute("x2", pathBetween.toX);
    newLine.setAttribute("y2", pathBetween.toY);
    newLine.setAttribute("stroke", "red");
    $("#svg8").prepend(newLine);
    return pathBetween;
  }

  function findPathBetween(fromSystemName, toSystemName) {
    var fromPosition = findSVGPosition(fromSystemName);
    var toPosition = findSVGPosition(toSystemName);
    if (fromPosition == null || toPosition == null) return null;

    //center to center
    var response = {
      fromSystem: fromSystemName,
      fromX: fromPosition.x + fromPosition.width / 2,
      fromY: fromPosition.y + fromPosition.height / 2,
      fromSide: "center",
      toSystem: toSystemName,
      toX: toPosition.x + toPosition.width / 2,
      toY: toPosition.y + toPosition.height / 2,
      toSide: "center"
    };
    return response;
  }

  function findSVGPosition(systemName) {
    return document.getElementById(systemName).getBBox();
  }
  
  
  
  drawPath('sys_system1', 'sys_system2');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="14in"
   height="8.5in"
   viewBox="0 0 355.6 215.9"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
   sodipodi:docname="line.svg">
  <defs
     id="defs2" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="1.0404412"
     inkscape:cx="166.09894"
     inkscape:cy="543.80097"
     inkscape:document-units="mm"
     inkscape:current-layer="svg8"
     showgrid="false"
     inkscape:window-width="2560"
     inkscape:window-height="1378"
     inkscape:window-x="1592"
     inkscape:window-y="-8"
     inkscape:window-maximized="1"
     units="in" />
  <metadata
     id="metadata5">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title />
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:groupmode="layer"
     id="layer2"
     inkscape:label="systemGroups"
     style="display:inline" />
  <g
     inkscape:groupmode="layer"
     id="layer3"
     inkscape:label="ancillary"
     style="display:none"
     sodipodi:insensitive="true">
    <rect
       style="display:inline;opacity:0.4;fill:#ffcc00;fill-opacity:1;stroke:none;stroke-width:0.23668619"
       id="rect175"
       width="115.25188"
       height="27.459745"
       x="127.27588"
       y="14.725033" />
  </g>
  <g
     id="g864"
     inkscape:label="systems">
    <g
       id="sys_system1">
      <rect
         style="fill:#000080;fill-opacity:1;stroke-width:0.1389997"
         y="21.502226"
         x="64.290497"
         height="12.662203"
         width="23.878363"
         id="rect47"
         inkscape:label="#rect4524-9" />
      <text
         id="text51"
         y="29.008078"
         x="67.362793"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
           y="29.008078"
           x="67.362793"
           id="tspan49"
           sodipodi:role="line">System1</tspan></text>
    </g>
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect95"
       width="177.46696"
       height="27.528765"
       x="10.156241"
       y="14.111509" />
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect97"
       width="133.36749"
       height="39.555889"
       x="19.777945"
       y="13.042425" />
    <g
       id="sys_system2">
      <rect
         style="fill:#aa8800;fill-opacity:1;stroke-width:0.13352577"
         y="58.651283"
         x="65.212334"
         height="12.662203"
         width="22.034693"
         id="rect47-1"
         inkscape:label="#rect4524-9" />
      <text
         id="text51-2"
         y="66.157143"
         x="68.28463"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#000000;fill-opacity:1;stroke-width:0.26458332"
           y="66.157143"
           x="68.28463"
           id="tspan49-8"
           sodipodi:role="line">System2</tspan></text>
    </g>
  </g>
</svg>

Обновление - лучшая версия

Вот лучшая версия, которая не требует, чтобы вы перенесли все преобразования в Inkscape.

В этой версии мы выбираем наши конечные точки линии, а затем используем getCTM(), чтобы найти общее преобразование от элемента к странице.

Небольшое осложнение состоит в том, что getCTM() включает в себя все преобразования. Включая преобразование, вызванное масштабированием viewBox. Но мы не хотим, чтобы преобразование включало этот последний шаг. Итак, чтобы исправить это, мы называем getCTM для корневого <svg> элемента, а затем используем его для отмены viewBox части преобразования.

function drawPath(fromSystemName, toSystemName) {
    var pathBetween = findPathBetween(fromSystemName, toSystemName);
    var newLine = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "line"
    );
    newLine.setAttribute(
      "id",
      pathBetween.fromSystem + "_" + pathBetween.toSystem
    );
    newLine.setAttribute("x1", pathBetween.fromX);
    newLine.setAttribute("y1", pathBetween.fromY);
    newLine.setAttribute("x2", pathBetween.toX);
    newLine.setAttribute("y2", pathBetween.toY);
    newLine.setAttribute("stroke", "red");
    $("#svg8").prepend(newLine);
    return pathBetween;
  }

  function findPathBetween(fromSystemName, toSystemName) {
    var fromPosition = findSVGPosition(fromSystemName);
    var toPosition = findSVGPosition(toSystemName);
    if (fromPosition == null || toPosition == null) return null;

    //center to center
    var response = {
      fromSystem: fromSystemName,
      fromX: fromPosition.x,
      fromY: fromPosition.y,
      fromSide: "center",
      toSystem: toSystemName,
      toX: toPosition.x,
      toY: toPosition.y,
      toSide: "center"
    };
    return response;
  }

  function findSVGPosition(systemName) {
    var elem = document.getElementById(systemName);
    var bbox = elem.getBBox();
    var point = elem.ownerSVGElement.createSVGPoint();
    point.x = bbox.x + bbox.width / 2;
    point.y = bbox.y + bbox.height / 2;
    var elemToViewportTransform = elem.getCTM();  // includes SVG scaling
    var svgToViewportTransform = getViewportTransform(elem);
    return point.matrixTransform(elemToViewportTransform)  // apply elem transform
                .matrixTransform(svgToViewportTransform.inverse());  // but take off the svg scaling
  }
  
  function getViewportTransform(elem) {
    if (elem.ownerSVGElement.getCTM) {
      var result = elem.ownerSVGElement.getCTM()
      if (result != null)
        return result;
    }
    // Workaround for Firefox and other browsers that don't support transform
    // on the `<svg> element yet (it's an SVG2 thing).
    var svg = elem.ownerSVGElement;
    var g = document.createElementNS(svg.namespaceURI, "g");
    svg.appendChild(g);
    var result = g.getCTM();
    svg.removeChild(g);
    return result;
  }
  
  drawPath('sys_system1', 'sys_system2');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="14in"
   height="8.5in"
   viewBox="0 0 355.6 215.9"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
   sodipodi:docname="drawing.02.svg">
  <defs
     id="defs2" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="1.0404412"
     inkscape:cx="485.6749"
     inkscape:cy="543.80097"
     inkscape:document-units="mm"
     inkscape:current-layer="layer1"
     showgrid="false"
     inkscape:window-width="1920"
     inkscape:window-height="1018"
     inkscape:window-x="-8"
     inkscape:window-y="-8"
     inkscape:window-maximized="1"
     units="in" />
  <metadata
     id="metadata5">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:groupmode="layer"
     id="layer2"
     inkscape:label="systemGroups" />
  <g
     inkscape:groupmode="layer"
     id="layer3"
     inkscape:label="ancillary"
     style="display:none"
     sodipodi:insensitive="true">
    <rect
       style="display:inline;opacity:0.4;fill:#ffcc00;fill-opacity:1;stroke:none;stroke-width:0.23668619"
       id="rect175"
       width="115.25188"
       height="27.459745"
       x="127.27588"
       y="14.725033" />
  </g>
  <g
     inkscape:label="systems"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(0,-81.1)"
     style="display:inline">
    <g
       id="sys_system1"
       transform="translate(15.595292,0.08990834)"
       inkscape:label="#g164">
      <rect
         style="fill:#000080;fill-opacity:1;stroke-width:0.1389997"
         y="102.51232"
         x="48.695206"
         height="12.662203"
         width="23.878363"
         id="rect47"
         inkscape:label="#rect4524-9" />
      <text
         id="text51"
         y="110.01817"
         x="51.767498"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
           y="110.01817"
           x="51.767498"
           id="tspan49"
           sodipodi:role="line">System1</tspan></text>
    </g>
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect95"
       width="177.46696"
       height="27.528765"
       x="10.156241"
       y="95.21151" />
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect97"
       width="133.36749"
       height="39.555889"
       x="19.777945"
       y="94.142426" />
    <g
       id="sys_system2"
       inkscape:label="#g90"
       transform="translate(-5.0449918)">
      <rect
         style="fill:#aa8800;fill-opacity:1;stroke-width:0.13352577"
         y="139.75128"
         x="70.257324"
         height="12.662203"
         width="22.034693"
         id="rect47-1"
         inkscape:label="#rect4524-9" />
      <text
         id="text51-2"
         y="147.25714"
         x="73.32962"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#000000;fill-opacity:1;stroke-width:0.26458332"
           y="147.25714"
           x="73.32962"
           id="tspan49-8"
           sodipodi:role="line">System2</tspan></text>
    </g>
  </g>
</svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...