16 KiB
1 Напиши код на js, который бы отображал схему visio (vsdx) в браузере (visio viewer).
Введение
Просмотр схем Visio (vsdx) в браузере средствами JavaScript — задача нетривиальная, так как формат VSDX — это zip-архив с XML-файлами, и не существует официальной открытой JS-библиотеки для полноценного рендеринга Visio-файлов в браузере. Однако, можно реализовать базовый просмотр схем с помощью сторонних библиотек для чтения zip/XML и отрисовки SVG.
Возможные подходы
-
Использование сторонних сервисов
Microsoft предоставляет онлайн Visio Viewer только в составе SharePoint Online и Office 365,,.
Есть бесплатные онлайн-сервисы для просмотра VSDX, но они не предоставляют открытого JS-кода для встраивания в свой сайт,. -
Собственная реализация на 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, где описаны простые прямоугольники и эллипсы с координатами и цветами. Мы напишем код, который:
- Парсит XML (например, из строки или файла)
- Извлекает фигуры, их координаты, размеры и цвета
- Строит 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>
- Изучить структуру XML Visio (обычно это
Итог
Этот подход — базовый шаблон для парсинга и рендеринга.
Для реального 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-файлов!