如何将 SVG 导入/转换为原生 Draw.io 形状?

问题描述 投票:0回答:1

我正在寻找一个图表编辑器,它支持导入复杂的形状,同时保持页面的样式。 Draw.io 看起来很有前途,但如果我没记错的话,它主要促进 SVG 导入或原始 XML 输入,而不提供所见即所得的界面。

StackOverflow 上有各种与此相关的问题,但似乎都没有解决我的具体问题。例如,这个问题详细介绍了导入 SVG 然后更改其颜色的过程。

为了说明我的观点,我在下面提供了两张屏幕截图。左边的屏幕截图描绘了我导入的 SVG,而右边的屏幕截图则展示了标准的 Draw.io 形状。据观察,我只能修改 SVG 的 Fill .cls-1 或 Line .cls-1 等属性。相反,对于标准形状,我可以指定独特的风格。

我梦想有一个图表编辑器,可以导入复杂的形状并保留页面的样式。 Draw.io 有潜力,但据我了解,它只支持 SVG 导入或原始 XML 代码,没有所见即所得编辑器。

存在许多关于SO的问题,但目前没有人回答我的问题。展示如何导入 SVG 然后编辑颜色。

例如,在此屏幕截图中,左侧是导入的 SVG,右侧是常规的 Draw.io 形状。你可以看到,对于SVG,我只能编辑

Fill .cls-1
Line .cls-1
,但对于第二个形状,我可以关联一个样式:

有没有一种方法可以将 SVG 转换为原生 Draw.io 形状,从而启用样式应用?

我天真的做法是翻译 SVG:

<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" 
     viewBox="0 0 91.5 91.5">
  <defs>
    <style>
      .cls-1 {
        fill: none;
        stroke: #231f20;
        stroke-miterlimit: 10;
      }
    </style>
  </defs>
  <g id="Layer_1-2" data-name="Layer 1">
    <rect class="cls-1" x=".5" y=".5" width="90.5" height="90.5"/>
    <polygon class="cls-1" points="61.09 19.17 30.4 19.17 
    15.06 45.75 30.4 72.32 61.09 72.32 76.44 45.75 61.09 19.17"/>
    <line class="cls-1" x1="30.4" y1="72.32" x2="61.09" y2="19.17"/>
    <line class="cls-1" x1="76.44" y1="45.75" x2="15.86" y2="45.75"/>
    <line class="cls-1" x1="30.4" y1="19.17" x2="61.09" y2="72.32"/>
  </g>
</svg>

进入Draw.io形状语言:

<shape aspect="variable" h="90.5" w="90.5" strokewidth="inherit">    
  <background>
    <rect h="90.5" w="90.5" x="0.5" y=".5"/>
  </background>  
  <foreground>
    <fillstroke />
    <path>
      <move x="61.09" y="19.17"/>
      <line x="30.4" y="19.17"/>
      <line x="15.06" y="45.75"/>
      <line x="30.4" y="72.32"/>
      <line x="30.4" y="72.32"/>
      <line x="61.09" y="72.32"/>
      <line x="76.44" y="45.75"/>
      <line x="61.09" y="19.17"/>
    </path>
    <stroke />
    <path>
      <move x="30.4" y="72.32"/>
      <line x="61.09" y="19.17"/>
    </path>
    <stroke />
    <path>
      <move x="76.44" y="45.75"/>
      <line x="15.86" y="45.75"/>
    </path>
    <stroke />
    <path>
      <move x="30.4" y="19.17"/>
      <line x="61.09" y="72.32"/> 
    </path>
    <stroke />
  </foreground>
</shape>
svg diagram draw.io
1个回答
0
投票

为什么不使用 minidom 编写 Python 脚本?

from xml.dom import minidom
file = minidom.parse('specimen.svg')
svg = file.getElementsByTagName('svg')[0]
viewBox = svg.getAttribute('viewBox').split(' ')
width, height = float(viewBox[2]), float(viewBox[3])


def create_constraint(document, parent, x, y, perimeter=1):
    """ Create a constraint """
    constraint = document.createElement('constraint')
    constraint.setAttribute('x', str(x))
    constraint.setAttribute('y', str(y))
    constraint.setAttribute('perimeter', str(perimeter))
    parent.appendChild(constraint)


def create_connections(document, parent, height, width, nx=3, ny=3):
    connections = document.createElement('connections')
    parent.appendChild(connections)

    nx += 1
    ny += 1
    for x in [1/nx*n for n in range(1, nx)]:
        create_constraint(document, connections, 0, x)
        create_constraint(document, connections, 1, x)
        create_constraint(document, connections, x, 0)
        create_constraint(document, connections, x, 1)


def process_rect(document, parent, rect):
    rectangle = document.createElement('rect')
    rectangle.setAttribute('x', rect.getAttribute('x'))
    rectangle.setAttribute('y', rect.getAttribute('y'))
    rectangle.setAttribute('width', rect.getAttribute('width'))
    rectangle.setAttribute('height', rect.getAttribute('height'))
    parent.appendChild(rectangle)
    parent.appendChild(document.createElement('stroke'))


def process_polygon(document, parent, polygon):
    """ Process a polygon """
    points = polygon.getAttribute('points').split(' ')
    points = zip(*(iter(points),) * 2)
    path = document.createElement('path')
    parent.appendChild(path)
    move = document.createElement('move')
    p = next(points)
    move.setAttribute('x', p[0])
    move.setAttribute('y', p[1])
    path.appendChild(move)
    for (x, y) in points:
        line = document.createElement('line')
        line.setAttribute('x', x)
        line.setAttribute('y', y)
        path.appendChild(line)
    parent.appendChild(document.createElement('stroke'))


def process_line(document, parent, line):
    """ Process a line """
    x1 = line.getAttribute('x1')
    y1 = line.getAttribute('y1')
    x2 = line.getAttribute('x2')
    y2 = line.getAttribute('y2')
    path = document.createElement('path')
    parent.appendChild(path)
    move = document.createElement('move')
    move.setAttribute('x', x1)
    move.setAttribute('y', y1)
    path.appendChild(move)
    line = document.createElement('line')
    line.setAttribute('x', x2)
    line.setAttribute('y', y2)
    path.appendChild(line)
    parent.appendChild(document.createElement('stroke'))


def process_group(document, parent, group):
    """ Process a group """
    for child in group.childNodes:
        if child.nodeType != child.ELEMENT_NODE:
            continue

        if child.tagName == 'g':
            process_group(document, parent, child)
        elif child.tagName == 'polygon':
            process_polygon(document, parent, child)
        elif child.tagName == 'line':
            process_line(document, parent, child)
        elif child.tagName == 'rect':
            process_rect(document, parent, child)


document = minidom.Document()
shape = document.createElement('shape')
shape.setAttribute('aspect', 'variable')
shape.setAttribute('h', viewBox[2])
shape.setAttribute('w', viewBox[3])
shape.setAttribute('strokewidth', "inherit")

parent = document.appendChild(shape)

create_connections(document, parent, height, width)

background = document.createElement('background')
rect = document.createElement('rect')
rect.setAttribute('x', viewBox[0])
rect.setAttribute('y', viewBox[1])
rect.setAttribute('w', viewBox[2])
rect.setAttribute('h', viewBox[3])
background.appendChild(rect)
foreground = document.createElement('foreground')
foreground.appendChild(document.createElement('fillstroke'))
shape.appendChild(background)
shape.appendChild(foreground)

process_group(document, foreground, svg)
print(document.toprettyxml())
© www.soinside.com 2019 - 2024. All rights reserved.