Статья про редактор текста как на рисунке. Исходный код прилагается.
Многострочный текст в SVG
В SVG нет символа переноса строки. Для многострочного текста в SVG используется <tspan>.
<text x="0" y="0">
<tspan x="0" y="0">Line 1</tspan>
<tspan x="0" y="20px">Line 2</tspan>
<!-- Line 3 is empty
<tspan x="0" y="40px"></tspan> -->
<tspan x="0" y="60px">Line 4</tspan>
</text>
Листинг 1. Многострочный текст в SVG. Третья строка пустая. Высота строки 20px.
Положение элементов <tspan> задается относительно верхнего края <text>. Значение атрибута ‘y’ надо рассчитывать.
Расчетов атрибута ‘y’ можно избежать. Листинг 2 дает тот же результат. Используется атрибут ‘dy’ с фиксированным значением. ‘dy’ указывает положение относительно предыдущего элемента.
<text x="0" y="0">
<tspan x="0" dy="0">Line 1</tspan>
<tspan x="0" dy="20px">Line 2</tspan>
<tspan x="0" dy="20px" visibility="hidden">.</tspan>
<tspan x="0" dy="20px">Line 4</tspan>
</text>
Листинг 2. Многострочный текст в SVG. Третья строка пустая. Высота строки 20px. Отступ задается относительно предыдущего элемента.
Формируем многострочную разметку на JavaScript
Функция ниже делает разметку с фиксированным атрибутом ‘dy’. Разметка получается как в листинге 2.
/**
* create multiline tspan markup
* @param {string} str
* @param {number} lineHeight
* @returns {string}
*/
function svgStrToTspan(str, lineHeight) {
return str.split('\n').map((t, i) => {
return `<tspan
x="0"
dy="${i === 0 ? '0' : `${lineHeight}px`}"
${t.length === 0 ? 'visibility="hidden"' : ''}>
${t.length === 0
? '.'
: escapeHtml(t).replaceAll(' ', ' ')}
</tspan>`;
}).join('');
}
Листинг 3. Функция делает многострочную разметку
На рисунке 1 при добавлении строки текст смещается вверх. Таким образом текст всегда по центру круга. Листинге 4 показывает как это реализовано:
/**
* @param {SVGTextElement} textEl target text element
* @param {string} str
* @param {{lineHeight:number, verticalMiddle?:number}} param
* @returns {void}
*/
export function svgTextDraw(textEl, str, param) {
textEl.innerHTML = svgStrToTspan(str, param.lineHeight);
if (param.verticalMiddle != null) {
textEl.y.baseVal[0].value =
param.verticalMiddle - textEl.getBBox().height / 2;
}
}
Листинг 4. Функция вставляет текст в SVG. При указании verticalMiddle текст центрируется по вертикали.
Редактор текста
Редактор должен поддерживать все стандартные возможности:
навигацию по тексту, выделение, вставку, копирование;
автозамену, проверку правописания;
работать на пк и мобильных.
Для стандартных возможностей есть стандартная <textarea>.
Алгоритм работы редактора:
Прозрачная <textarea> располагается над текстом.
Шрифт <textarea> тоже прозрачный;При вводе вызывается svgTextDraw из листинга 4;
Размеры и положение <textarea> пересчитываются.
Алгоритм реализован в функции textareaCreate. Код функции в отдельном файле на GitHub.
Редактор можно сделать для любого элемента <text>:
const textEditor = textareaCreate(
// {SVGTextElement}
textEl,
// text params
{ lineHeight: 20, verticalMiddle: 10 },
// init value
'init text',
// onchange
val => {...},
// onblur
val => {...});
…
// delete textarea
textEditor.remove();
Листинг 5. Создание редактора текста для <text>
Другие статьи про dgrm.net
JavaScript редактор диаграмм, который открывает диаграммы из PNG картинок (open source)
JavaScript редактор текста для SVG
bipiem
SVG + table \ database
Хочется создать динамическую связь SVG (app.dgrm.net, а лучше draw.io) с google Sheets или с Excel (или с БД). Чтобы как в связке с visio + excel: поменял данные в excel и они тут же изменились на схеме в visio (и наоборот).
И тут также: поменял данные в google Sheets \ Excel и они тут же изменились на схеме app.dgrm.net \ drawio. Есть такие интеграции?
Хороший пример интеграции draw.io с редактором VS Code:
Editing the Diagram and its XML Side by Side
Что-то подобное бы, но редактировать table \ database и видеть изменения в .svg \ .drawio. И наоборот.
Alex_BBB Автор
https://mermaid-js.github.io/ ?
bipiem
GraphViz, Mermaid, PlantUML – это генераторы схем из скрипта. Для простых схем это работает, но сложные схемы как правило требуют ручной корректировки размещения «проблемных элементов». Кроме того, технология
1 Таблица
2 GraphViz, Mermaid, PlantUML и т.п.
3 Векторный рисунок
все равно требует переход «таблица - скрипт» (почему-то с переносами слов проблемы).
Связка google Sheets + Draw.io показана тут:
Карта процессов верхнего уровня компании и матрица RACI c помощью drawio и google sheets
Главное же, что нужно реализовать именно связку с «полной строкой данных», как это работает в visio+excel. Т.е. по клику на объект на схеме мы «проваливаемся» в объект таблицы (в общем случае, базы данных), где есть как видимые на схеме атрибуты (называние фигуры, например), так и не видимые на схеме (все поля строки).
Примерно, как на любой интерактивной карте местности: выбрали на схеме svg графический объект и активировали (отобразили) карточку объекта: что там размещено (какие магазины по этому адресу), какие события там были (в зависимости от тематики карты). В принципе и простенький гео – инструмент подошёл бы (саму гео-карту не использовать), но интересна задача привязывать информацию (в виде отдельных полей) к структурной схеме и схеме workflow.
В общем, чтобы получилось упрощенное подобие ARIS (BPM). Аналитическую часть (контроль уникальности имени экземпляра объекта и т.п.) – потом сделать можно путем анализа таблицы \ БД.
KhodeN
D3