doc/BPM/graphic_editor/visio/ai/viewer.md
2025-08-28 12:43:52 +03:00

16 KiB
Raw Blame History

1 Напиши код на js, который бы отображал схему visio (vsdx) в браузере (visio viewer).

Введение

Просмотр схем Visio (vsdx) в браузере средствами JavaScript — задача нетривиальная, так как формат VSDX — это zip-архив с XML-файлами, и не существует официальной открытой JS-библиотеки для полноценного рендеринга Visio-файлов в браузере. Однако, можно реализовать базовый просмотр схем с помощью сторонних библиотек для чтения zip/XML и отрисовки SVG.

Возможные подходы

  1. Использование сторонних сервисов
    Microsoft предоставляет онлайн Visio Viewer только в составе SharePoint Online и Office 365,,.
    Есть бесплатные онлайн-сервисы для просмотра VSDX, но они не предоставляют открытого JS-кода для встраивания в свой сайт,.

  2. Собственная реализация на JS

    • Распаковать VSDX (zip) с помощью JS-библиотеки (например, JSZip).
    • Прочитать XML-файлы внутри архива.
    • Извлечь SVG-данные (или преобразовать XML-описание в SVG).
    • Отобразить SVG в браузере.

Пример кода: базовый просмотр VSDX как SVG

Этот пример не поддерживает все возможности Visio, но показывает базовый подход:

<input type="file" id="vsdxInput" accept=".vsdx" />
<div id="viewer"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<script>
document.getElementById('vsdxInput').addEventListener('change', async function(event) {
    const file = event.target.files[0];
    if (!file) return;

    const arrayBuffer = await file.arrayBuffer();
    const zip = await JSZip.loadAsync(arrayBuffer);

    // В VSDX SVG обычно лежит в папке /visio/pages/page1.xml
    const pageXml = await zip.file('visio/pages/page1.xml').async('string');
    // Преобразуем XML в DOM
    const parser = new DOMParser();
    const xmlDoc = parser.parseFromString(pageXml, "application/xml");

    // Вытаскиваем SVG-описание (если оно есть)
    // В реальных VSDX SVG нет, но можно попробовать сгенерировать SVG из Shape-данных
    // Для примера просто выводим XML как текст
    document.getElementById('viewer').textContent = pageXml;

    // Для полноценного рендера потребуется парсить Shape-элементы и строить SVG вручную
});
</script>

Важные замечания

  • Полноценный рендеринг VSDX в браузере требует сложного парсинга и преобразования XML-описания Visio в SVG или Canvas.
  • Готовых open-source JS-библиотек для этого нет, но можно использовать коммерческие решения (например, Aspose.Diagram Cloud API, GroupDocs Viewer API и др.) — они предоставляют REST API для конвертации VSDX в SVG/PNG, которые можно отобразить в браузере,.
  • Если нужен только просмотр, проще использовать онлайн-сервисы или встроить iframe с Microsoft Visio Online (если есть лицензия).

Альтернативы

  • Aspose.Diagram Cloud API — позволяет конвертировать VSDX в SVG/PNG через REST-запросы, после чего SVG можно отобразить в браузере.
  • GroupDocs Viewer API — аналогично, конвертирует VSDX в SVG/HTML.

Вывод

Встроить полноценный Visio Viewer на чистом JS в браузере — задача сложная и требует значительных усилий по парсингу и рендерингу. Для прототипа можно распаковать VSDX и попробовать отобразить содержимое, но для production-решения лучше использовать сторонние API или сервисы.

Пример кода выше выводит только XML-содержимое страницы схемы Visio (например, page1.xml) в виде текста, а не графику. То есть, в окне браузера вы увидите "сырой" XML-код, а не визуальную схему. Это потому, что внутри VSDX нет готового SVG — схема описана в виде XML-элементов (Shape, Connect, и т.д.), которые нужно дополнительно обработать и преобразовать в графику.
Чтобы увидеть графику, нужно:
Преобразовать XML-описание схемы в SVG или Canvas.
Это сложная задача: нужно парсить XML, извлекать координаты, типы фигур, линии, цвета и т.д., и строить на их основе SVG-элементы.

2 Да, нужно "парсить XML, извлекать координаты, типы фигур, линии, цвета и т.д., и строить на их основе SVG-элементы".

Пример: Парсинг простого Visio XML и рендеринг в SVG на JS

Давай рассмотрим упрощённый пример: допустим, у нас есть XML-фрагмент из Visio, где описаны простые прямоугольники и эллипсы с координатами и цветами. Мы напишем код, который:

  1. Парсит XML (например, из строки или файла)
  2. Извлекает фигуры, их координаты, размеры и цвета
  3. Строит SVG-элементы и вставляет их в DOM

1. Пример XML (упрощённый)
<Shapes>
  <Shape type="rect" x="10" y="20" width="100" height="50" fill="#ff0000"/>
  <Shape type="ellipse" x="150" y="40" rx="40" ry="20" fill="#00ff00"/>
</Shapes>

2. JS-код для парсинга и рендеринга
<div id="svg-container"></div>
<script>
const xmlString = `
<Shapes>
  <Shape type="rect" x="10" y="20" width="100" height="50" fill="#ff0000"/>
  <Shape type="ellipse" x="150" y="40" rx="40" ry="20" fill="#00ff00"/>
</Shapes>
`;

// 1. Парсим XML в DOM
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "application/xml"); // [[5]]

// 2. Создаём SVG-элемент
const svgNS = "http://www.w3.org/2000/svg";
const svg = document.createElementNS(svgNS, "svg");
svg.setAttribute("width", 300);
svg.setAttribute("height", 150);

// 3. Извлекаем фигуры и добавляем их в SVG
const shapes = xmlDoc.getElementsByTagName("Shape");
for (let shape of shapes) {
  const type = shape.getAttribute("type");
  let svgShape;
  if (type === "rect") {
    svgShape = document.createElementNS(svgNS, "rect");
    svgShape.setAttribute("x", shape.getAttribute("x"));
    svgShape.setAttribute("y", shape.getAttribute("y"));
    svgShape.setAttribute("width", shape.getAttribute("width"));
    svgShape.setAttribute("height", shape.getAttribute("height"));
    svgShape.setAttribute("fill", shape.getAttribute("fill"));
  } else if (type === "ellipse") {
    svgShape = document.createElementNS(svgNS, "ellipse");
    svgShape.setAttribute("cx", shape.getAttribute("x"));
    svgShape.setAttribute("cy", shape.getAttribute("y"));
    svgShape.setAttribute("rx", shape.getAttribute("rx"));
    svgShape.setAttribute("ry", shape.getAttribute("ry"));
    svgShape.setAttribute("fill", shape.getAttribute("fill"));
  }
  svg.appendChild(svgShape);
}

// 4. Вставляем SVG в контейнер
document.getElementById("svg-container").appendChild(svg);
</script>

Как это работает?

  • DOMParser превращает XML-строку в DOM-объект.
  • JS-код перебирает все <Shape> и создает соответствующие SVG-фигуры.
  • SVG вставляется в контейнер на странице, и вы видите графику.

Как адаптировать под настоящий Visio XML?

  • В реальном VSDX/Visio XML структура сложнее: фигуры могут быть вложены, координаты относительные, есть линии, тексты и т.д.
  • Нужно будет:
    • Изучить структуру XML Visio (обычно это <Shapes>, <Shape>, <XForm>, <Line>, <Fill> и т.д.)
    • Для каждой фигуры извлекать нужные параметры (координаты, размеры, цвет, тип)
    • Для связей (линий) использовать SVG <line> или <path>
    • Для текста — SVG <text>

Итог

Этот подход — базовый шаблон для парсинга и рендеринга.
Для реального Visio потребуется более сложный парсер, но принцип тот же:
Парсим XML → Извлекаем параметры → Рисуем SVG.

3 Сгенерируй простой vsdx файл, содержащий прямоугольник и овал. Переведи его в XML-содержимое и сгененируй SVG. Добавь подробное пояснение кода.

Создание простого VSDX-файла с прямоугольником и овалом, его XML-содержимое и генерация SVG на JS


1. Что такое VSDX и почему сложно сгенерировать вручную?

  • VSDX — это формат Microsoft Visio, основанный на ZIP-архиве с множеством XML-файлов внутри.
  • Вручную писать полноценный VSDX сложно, т.к. это пакет с несколькими взаимосвязанными XML.
  • Но можно создать упрощённый XML, который описывает фигуры, и на его основе сгенерировать SVG.

2. Упрощённый пример XML, имитирующий содержимое VSDX с двумя фигурами

<Shapes>
  <Shape id="1" type="rect" x="10" y="10" width="120" height="80" fill="#3498db"/>
  <Shape id="2" type="ellipse" x="180" y="50" rx="60" ry="40" fill="#e74c3c"/>
</Shapes>
  • Здесь:
    • Прямоугольник с координатами (10,10), шириной 120, высотой 80, с синим цветом.
    • Овал с центром (180,50), радиусами 60 и 40, красного цвета.

3. JS-код для парсинга этого XML и генерации SVG

<div id="svg-container"></div>

<script>
// 1. XML-строка с фигурами
const xmlString = `
<Shapes>
  <Shape id="1" type="rect" x="10" y="10" width="120" height="80" fill="#3498db"/>
  <Shape id="2" type="ellipse" x="180" y="50" rx="60" ry="40" fill="#e74c3c"/>
</Shapes>
`;

// 2. Парсим XML в DOM-объект
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "application/xml");

// 3. Создаём SVG-элемент с нужными размерами
const svgNS = "http://www.w3.org/2000/svg";
const svg = document.createElementNS(svgNS, "svg");
svg.setAttribute("width", 300);
svg.setAttribute("height", 150);
svg.style.border = "1px solid #ccc"; // для наглядности

// 4. Извлекаем все фигуры из XML
const shapes = xmlDoc.getElementsByTagName("Shape");

// 5. Проходим по каждой фигуре и создаём соответствующий SVG-элемент
for (let shape of shapes) {
  const type = shape.getAttribute("type");
  let svgShape;

  if (type === "rect") {
    // Создаём прямоугольник
    svgShape = document.createElementNS(svgNS, "rect");
    svgShape.setAttribute("x", shape.getAttribute("x"));
    svgShape.setAttribute("y", shape.getAttribute("y"));
    svgShape.setAttribute("width", shape.getAttribute("width"));
    svgShape.setAttribute("height", shape.getAttribute("height"));
    svgShape.setAttribute("fill", shape.getAttribute("fill"));
  } else if (type === "ellipse") {
    // Создаём овал
    svgShape = document.createElementNS(svgNS, "ellipse");
    svgShape.setAttribute("cx", shape.getAttribute("x"));
    svgShape.setAttribute("cy", shape.getAttribute("y"));
    svgShape.setAttribute("rx", shape.getAttribute("rx"));
    svgShape.setAttribute("ry", shape.getAttribute("ry"));
    svgShape.setAttribute("fill", shape.getAttribute("fill"));
  }

  // Добавляем фигуру в SVG
  if (svgShape) {
    svg.appendChild(svgShape);
  }
}

// 6. Вставляем SVG в контейнер на странице
document.getElementById("svg-container").appendChild(svg);
</script>

4. Подробное пояснение кода

  • Шаг 1: В переменной xmlString хранится упрощённый XML с двумя фигурами — прямоугольником и овалом.
  • Шаг 2: С помощью DOMParser мы превращаем строку XML в объект DOM, чтобы можно было работать с элементами как с узлами.
  • Шаг 3: Создаём SVG-элемент с пространством имён SVG (http://www.w3.org/2000/svg), задаём размеры и рамку для наглядности.
  • Шаг 4: Получаем список всех <Shape> из XML.
  • Шаг 5: Для каждой фигуры смотрим атрибут type:
    • Если rect — создаём SVG <rect>, задаём координаты, размеры и цвет.
    • Если ellipse — создаём SVG <ellipse>, задаём центр, радиусы и цвет.
  • Шаг 6: Добавляем созданные SVG-элементы внутрь SVG.
  • Шаг 7: Вставляем SVG в контейнер на странице, чтобы отобразить результат.

5. Итог

  • Мы сгенерировали упрощённый XML, который можно считать аналогом содержимого VSDX с двумя фигурами.
  • Затем спарсили этот XML и создали SVG-элементы на его основе.
  • Такой подход можно расширять, добавляя линии, тексты, сложные фигуры и трансформации.

Если хочешь, могу помочь с более сложным примером или с реальным парсингом VSDX-файлов!