refactoring+

This commit is contained in:
Gregory Bednov 2025-01-29 00:04:11 +03:00
commit 1e9a6d3052
11 changed files with 561 additions and 376 deletions

10
.prettierrc Normal file
View file

@ -0,0 +1,10 @@
{
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "always",
"printWidth": 80
}

View file

@ -1,141 +1,212 @@
const stateInstrument = { export const stateInstrument = {
фиксация: 'НаМесте', фиксация: 'НаМесте',
типПрибора: 'Величина', типПрибора: 'Величина',
величина: 'Напряжение', величина: 'Напряжение',
уточнение: null, являетсяПАЗ: false,
функции: [] уточнение: null,
}; функции: [] as string[],
}
const stateMechanism = { export const stateMechanism = {
ручной: false, ручной: false,
направление: null as string | null направление: null as string | null,
}; }
// Настройки для выбора значений // Настройки для выбора значений
const функцииПоТипу = { const функцииПоТипу = {
ВыполняемаяФункция: [ ВыполняемаяФункция: [
'Сигнализация' 'Сигнализация',
, 'АвтоматическоеРегулирование' 'АвтоматическоеРегулирование',
, 'ВеличинаОтклоненияОтЗаданной' 'ВеличинаОтклоненияОтЗаданной',
, 'Регистрация' 'Регистрация',
], ],
ФункциональныйПризнак: [ ФункциональныйПризнак: [
'ЧувствительныйЭлемент' 'ЧувствительныйЭлемент',
, 'Преобразование' 'Преобразование',
, 'ПервичныйПоказывающийПрибор' 'ПервичныйПоказывающийПрибор',
, 'СтанцияУправления' 'СтанцияУправления',
, 'ВключениеОтключениеПереключение' 'ВключениеОтключениеПереключение',
] ],
};
// Создание элементов формы
export function createInstrumentForm(container: HTMLElement | null) {
const form = document.createElement('form');
// Фиксация
const fixationLabel = document.createElement('label');
fixationLabel.innerText = 'Фиксация:';
const fixationSelect = document.createElement('select');
fixationSelect.innerHTML = '<option value="НаМесте">На месте</option><option value="НаЩите">На щите</option>';
fixationSelect.value = stateInstrument.фиксация;
fixationSelect.addEventListener('change', (e) => {
const target = e.target as HTMLInputElement;
stateInstrument.фиксация = target.value;
});
fixationLabel.appendChild(fixationSelect);
form.appendChild(fixationLabel);
// Тип прибора
const typeLabel = document.createElement('label');
typeLabel.innerText = 'Тип прибора:';
const typeSelect = document.createElement('select');
typeSelect.innerHTML = '<option value="Величина">Величина</option><option value="Мультивеличина">Мультивеличина</option>';
typeSelect.value = stateInstrument.типПрибора;
typeSelect.addEventListener('change', (e) => {
const target = e.target as HTMLInputElement;
stateInstrument.типПрибора = target.value;
});
typeLabel.appendChild(typeSelect);
form.appendChild(typeLabel);
// Величина
const magnitudeLabel = document.createElement('label');
magnitudeLabel.innerText = 'Величина:';
const magnitudeSelect = document.createElement('select');
const choices = [
{ value: 'A', label: 'Анализ, качество' },
{ value: 'B', label: 'Пламя, горение' },
{ value: 'C', label: 'Дополнительная величина (C)' },
{ value: 'D', label: 'Дополнительная величина (D)' },
{ value: 'E', label: 'Напряжение' },
{ value: 'F', label: 'Расход' },
{ value: 'G', label: 'Дополнительная величина (G)' },
{ value: 'H', label: 'Ручное воздействие' },
{ value: 'I', label: 'Ток' },
{ value: 'J', label: 'Мощность' },
{ value: 'K', label: 'Время' },
{ value: 'L', label: 'Уровень' },
{ value: 'M', label: 'Дополнительная величина (N)' },
{ value: 'N', label: 'Дополнительная величина (N))' },
{ value: 'O', label: 'Дополнительная величина (O)' },
{ value: 'P', label: 'Давление' },
{ value: 'Q', label: 'Количество' },
{ value: 'E', label: 'Радиоактивность' },
{ value: 'S', label: 'Скорость, частота' },
{ value: 'T', label: 'Температура' },
{ value: 'U', label: 'Разнородные величины' }, // несколько величин ТОЛЬКО здесь
{ value: 'V', label: 'Вибрация' },
{ value: 'W', label: 'Вес' },
{ value: 'X', label: 'Дополнительная величина (нерекомендованная буква X)' },
{ value: 'Y', label: 'Событие' },
{ value: 'Z', label: 'Размер' }
];
choices.forEach(element => {
const opt = document.createElement<'option'>('option')
opt.setAttribute('value', element.value)
opt.appendChild(document.createTextNode(element.label))
magnitudeSelect.appendChild(opt)
});
magnitudeSelect.addEventListener('change', (e) => {
const target = e.target as HTMLInputElement;
stateInstrument.величина = target.value;
});
magnitudeLabel.appendChild(magnitudeSelect);
form.appendChild(magnitudeLabel);
// Добавить форму на страницу
container?.appendChild(form);
} }
export function createMechanismForm(container: HTMLElement | null) { export function createInstrumentForm(): HTMLElement {
const form = document.createElement('form'); const form = document.createElement('form')
// Ручное управление // Фиксация
const manualControlLabel = document.createElement('label'); const fixationLabel = document.createElement('label')
manualControlLabel.innerText = 'Имеет ручное управление:'; fixationLabel.innerText = 'Фиксация:'
const manualControlCheckbox = document.createElement('input'); const fixationSelect = document.createElement('select')
manualControlCheckbox.type = 'checkbox'; fixationSelect.innerHTML =
manualControlCheckbox.checked = stateMechanism.ручной; '<option value="НаМесте">На месте</option><option value="НаЩите">На щите</option>'
manualControlCheckbox.addEventListener('change', (e) => { fixationSelect.value = stateInstrument.фиксация
const target = e.target as HTMLInputElement; fixationSelect.addEventListener('change', (e) => {
stateMechanism.ручной = target.checked; const target = e.target as HTMLInputElement
}); stateInstrument.фиксация = target.value
manualControlLabel.appendChild(manualControlCheckbox); })
form.appendChild(manualControlLabel); fixationLabel.appendChild(fixationSelect)
form.appendChild(fixationLabel)
// Направление const manualControlLabel = document.createElement('label')
const directionLabel = document.createElement('label'); manualControlLabel.innerText = 'Является ПАЗ:'
directionLabel.innerText = 'Направление:'; const manualControlCheckbox = document.createElement('input')
const directionSelect = document.createElement('select'); manualControlCheckbox.type = 'checkbox'
directionSelect.innerHTML = '<option value="Открывается">Открывается</option><option value="Закрывается">Закрывается</option><option value="ОстаётсяНаМесте">Остаётся на месте</option>'; manualControlCheckbox.checked = stateInstrument.являетсяПАЗ
directionSelect.value = stateMechanism.направление || ''; manualControlCheckbox.addEventListener('change', (e) => {
directionSelect.addEventListener('change', (e) => { const target = e.target as HTMLInputElement
const target = e.target as HTMLInputElement; stateInstrument.являетсяПАЗ = target.checked
stateMechanism.направление = target.value; })
}); manualControlLabel.appendChild(manualControlCheckbox)
directionLabel.appendChild(directionSelect); form.appendChild(manualControlLabel)
form.appendChild(directionLabel);
// Добавить форму на страницу // Тип прибора
container?.appendChild(form); const typeLabel = document.createElement('label')
typeLabel.innerText = 'Тип прибора:'
const typeSelect = document.createElement('select')
typeSelect.innerHTML =
'<option value="Величина">Величина</option><option value="Мультивеличина">Мультивеличина</option>'
typeSelect.value = stateInstrument.типПрибора
typeSelect.addEventListener('change', (e) => {
const target = e.target as HTMLInputElement
stateInstrument.типПрибора = target.value
})
typeLabel.appendChild(typeSelect)
form.appendChild(typeLabel)
// Величина
const magnitudeLabel = document.createElement('label')
magnitudeLabel.innerText = 'Величина:'
const magnitudeSelect = document.createElement('select')
const choices = [
{ value: 'A', label: 'Анализ, качество' },
{ value: 'B', label: 'Пламя, горение' },
{ value: 'C', label: 'Дополнительная величина (C)' },
{ value: 'D', label: 'Дополнительная величина (D)' },
{ value: 'E', label: 'Напряжение' },
{ value: 'F', label: 'Расход' },
{ value: 'G', label: 'Дополнительная величина (G)' },
{ value: 'H', label: 'Ручное воздействие' },
{ value: 'I', label: 'Ток' },
{ value: 'J', label: 'Мощность' },
{ value: 'K', label: 'Время' },
{ value: 'L', label: 'Уровень' },
{ value: 'M', label: 'Дополнительная величина (N)' },
{ value: 'N', label: 'Дополнительная величина (N))' },
{ value: 'O', label: 'Дополнительная величина (O)' },
{ value: 'P', label: 'Давление' },
{ value: 'Q', label: 'Количество' },
{ value: 'E', label: 'Радиоактивность' },
{ value: 'S', label: 'Скорость, частота' },
{ value: 'T', label: 'Температура' },
{ value: 'U', label: 'Разнородные величины' },
{ value: 'V', label: 'Вибрация' },
{ value: 'W', label: 'Вес' },
{
value: 'X',
label: 'Дополнительная величина (нерекомендованная буква X)',
},
{ value: 'Y', label: 'Событие' },
{ value: 'Z', label: 'Размер' },
]
choices.forEach((element) => {
const opt = document.createElement('option')
opt.setAttribute('value', element.value)
opt.appendChild(document.createTextNode(element.label))
magnitudeSelect.appendChild(opt)
})
magnitudeSelect.value = stateInstrument.величина
magnitudeSelect.addEventListener('change', (e) => {
const target = e.target as HTMLInputElement
stateInstrument.величина = target.value
})
magnitudeLabel.appendChild(magnitudeSelect)
form.appendChild(magnitudeLabel)
// Функции
const functionsLabel = document.createElement('label')
functionsLabel.innerText = 'Функции:'
const functionsContainer = document.createElement('div')
const updateFunctionsUI = () => {
functionsContainer.innerHTML = ''
stateInstrument.функции.forEach((func, index) => {
const funcWrapper = document.createElement('div')
funcWrapper.style.display = 'flex'
funcWrapper.style.alignItems = 'center'
const funcSelect = document.createElement('select')
функцииПоТипу.ВыполняемаяФункция
.concat(функцииПоТипу.ФункциональныйПризнак)
.forEach((f) => {
const option = document.createElement('option')
option.value = f
option.textContent = f
funcSelect.appendChild(option)
})
funcSelect.value = func
funcSelect.addEventListener('change', (e) => {
const target = e.target as HTMLSelectElement
stateInstrument.функции[index] = target.value
})
const removeButton = document.createElement('button')
removeButton.type = 'button'
removeButton.innerText = 'x'
removeButton.addEventListener('click', () => {
stateInstrument.функции.splice(index, 1)
updateFunctionsUI()
})
funcWrapper.appendChild(funcSelect)
funcWrapper.appendChild(removeButton)
functionsContainer.appendChild(funcWrapper)
})
}
const addButton = document.createElement('button')
addButton.type = 'button'
addButton.innerText = '+'
addButton.addEventListener('click', () => {
stateInstrument.функции.push('')
updateFunctionsUI()
})
updateFunctionsUI()
functionsLabel.appendChild(functionsContainer)
form.appendChild(functionsLabel)
form.appendChild(addButton)
return form
}
export function createMechanismForm(): HTMLElement {
const form = document.createElement('form')
// Ручное управление
const manualControlLabel = document.createElement('label')
manualControlLabel.innerText = 'Имеет ручное управление:'
const manualControlCheckbox = document.createElement('input')
manualControlCheckbox.type = 'checkbox'
manualControlCheckbox.checked = stateMechanism.ручной
manualControlCheckbox.addEventListener('change', (e) => {
const target = e.target as HTMLInputElement
stateMechanism.ручной = target.checked
})
manualControlLabel.appendChild(manualControlCheckbox)
form.appendChild(manualControlLabel)
// Направление
const directionLabel = document.createElement('label')
directionLabel.innerText = 'Направление:'
const directionSelect = document.createElement('select')
directionSelect.innerHTML =
'<option value="Открывается">Открывается</option><option value="Закрывается">Закрывается</option><option value="ОстаётсяНаМесте">Остаётся на месте</option>'
directionSelect.value = stateMechanism.направление || ''
directionSelect.addEventListener('change', (e) => {
const target = e.target as HTMLInputElement
stateMechanism.направление = target.value
})
directionLabel.appendChild(directionSelect)
form.appendChild(directionLabel)
return form
} }

View file

@ -20,31 +20,29 @@ import ShapeRendererModule from './modules/ShapeRendererModule'
import OutlineModule from './modules/OutlineModule' import OutlineModule from './modules/OutlineModule'
export default function Editor(container: HTMLElement): Diagram { export default function Editor(container: HTMLElement): Diagram {
return new Diagram( return new Diagram({
{ canvas: { container },
canvas: {container}, modules: [
modules: [ BendpointMoveModule,
BendpointMoveModule ConnectModule,
, ConnectModule ContextPadModule,
, ContextPadModule CreateModule,
, CreateModule GlobalConnectModule,
, GlobalConnectModule LassoToolModule,
, LassoToolModule ModelingModule,
, ModelingModule MoveCanvasModule,
, MoveCanvasModule MoveModule,
, MoveModule PaletteModule,
, PaletteModule
//, ResizeModule //, ResizeModule
, RulesModule RulesModule,
, SelectionModule SelectionModule,
, ZoomScrollModule ZoomScrollModule,
, StyleModule StyleModule,
, ManhattanConnectionModule ManhattanConnectionModule,
, PaletteModule PaletteModule,
, GlobalConnectRulesModule GlobalConnectRulesModule,
, ShapeRendererModule ShapeRendererModule,
, OutlineModule OutlineModule,
] ],
} })
)
} }

View file

@ -1,21 +1,33 @@
import {createInstrumentForm, createMechanismForm} from './addObjectForm' import {
stateInstrument,
stateMechanism,
createInstrumentForm,
createMechanismForm,
} from './addObjectForm'
import Editor from './editor' import Editor from './editor'
import 'diagram-js/assets/diagram-js.css' import 'diagram-js/assets/diagram-js.css'
const instrumentContainer = document.getElementById('instrument-form') const instrMechContainer = document.getElementById('instrument-form')
const mechanismContainer = document.getElementById('mechanism-form') const instrument = createInstrumentForm()
const mechanism = createMechanismForm()
createInstrumentForm(instrumentContainer) instrument.onchange = function () {
createMechanismForm(mechanismContainer) console.log(stateInstrument)
}
mechanism.onchange = function () {
console.log(stateMechanism)
}
instrMechContainer?.appendChild(instrument)
instrMechContainer?.appendChild(mechanism)
const diagramElement = document.getElementById('diagram') const diagramElement = document.getElementById('diagram')
if (!diagramElement) { if (!diagramElement) {
throw new Error('Element with ID "diagram" not found in DOM.') throw new Error('Element with ID "diagram" not found in DOM.')
} }
diagramElement.style.width='297mm' diagramElement.style.width = '297mm'
diagramElement.style.height='210mm' diagramElement.style.height = '210mm'
diagramElement.style.border='solid' diagramElement.style.border = 'solid'
diagramElement.style.borderColor='canvastext' diagramElement.style.borderColor = 'canvastext'
diagramElement.style.borderWidth='1px' diagramElement.style.borderWidth = '1px'
const diagram = Editor(diagramElement) const diagram = Editor(diagramElement)
export default diagram export default diagram

View file

@ -1,35 +1,34 @@
import RuleProvider from 'diagram-js/lib/features/rules/RuleProvider'; import RuleProvider from 'diagram-js/lib/features/rules/RuleProvider'
class CustomGlobalConnectRules extends RuleProvider { class CustomGlobalConnectRules extends RuleProvider {
static $inject = ['eventBus']; static $inject = ['eventBus']
constructor(eventBus: any) { constructor(eventBus: any) {
super(eventBus); super(eventBus)
} }
init(): void { init(): void {
this.addRule('connection.start', (context) => { this.addRule('connection.start', (context) => {
return true; return true
const { source } = context; const { source } = context
if (source?.businessObject?.type === 'custom:connectable') { if (source?.businessObject?.type === 'custom:connectable') {
return true; // Разрешить соединение return true // Разрешить соединение
} }
return false; // Запретить соединение return false // Запретить соединение
}); })
// Правило для создания соединения // Правило для создания соединения
this.addRule('connection.create', (context) => { this.addRule('connection.create', (context) => {
// const { source, target } = context; // const { source, target } = context;
return { type: 'Connection' }; return { type: 'Connection' }
return false; // Запретить соединение return false // Запретить соединение
}); })
} }
} }
export default { export default {
__init__: ['customGlobalConnectRules'], __init__: ['customGlobalConnectRules'],
customGlobalConnectRules: ['type', CustomGlobalConnectRules] customGlobalConnectRules: ['type', CustomGlobalConnectRules],
}; }

View file

@ -1,53 +1,54 @@
import { connectPoints } from 'diagram-js/lib/layout/ManhattanLayout'; import { connectPoints } from 'diagram-js/lib/layout/ManhattanLayout'
import Modeling from 'diagram-js/lib/features/modeling/Modeling'; import Modeling from 'diagram-js/lib/features/modeling/Modeling'
import EventBus from 'diagram-js/lib/core/EventBus'; import EventBus from 'diagram-js/lib/core/EventBus'
import type { Connection } from 'diagram-js/lib/model/Types'; import type { Connection } from 'diagram-js/lib/model/Types'
export function updateWaypointsByManhattan (connection: Connection, modeling: Modeling ): void { export function updateWaypointsByManhattan(
connection: Connection,
modeling: Modeling
): void {
if (connection.source && connection.target) { if (connection.source && connection.target) {
const x0 = connection.source.x + connection.source.width / 2; const x0 = connection.source.x + connection.source.width / 2
const x1 = connection.target.x + connection.target.width / 2; const x1 = connection.target.x + connection.target.width / 2
const y0 = connection.source.y + connection.source.height / 2; const y0 = connection.source.y + connection.source.height / 2
const y1 = connection.target.y + connection.target.height / 2; const y1 = connection.target.y + connection.target.height / 2
const x2 = (Math.abs(x0-x1) < 5) ? x0 : x1; const x2 = Math.abs(x0 - x1) < 5 ? x0 : x1
const y2 = (Math.abs(y0-y1) < 5) ? y0 : y1; const y2 = Math.abs(y0 - y1) < 5 ? y0 : y1
const waypoints = connectPoints( const waypoints = connectPoints({ x: x0, y: y0 }, { x: x2, y: y2 })
{ x: x0, y: y0 },
{ x: x2, y: y2 });
const hasChanged = JSON.stringify(connection.waypoints) != JSON.stringify(waypoints); const hasChanged =
if (hasChanged) { JSON.stringify(connection.waypoints) != JSON.stringify(waypoints)
modeling.updateWaypoints(connection, waypoints) if (hasChanged) {
} modeling.updateWaypoints(connection, waypoints)
}
} }
} }
function ManhattanLayoutPlugin(eventBus: EventBus, modeling: Modeling) { function ManhattanLayoutPlugin(eventBus: EventBus, modeling: Modeling) {
eventBus.on('commandStack.connection.create.executed', (event) => { eventBus.on('commandStack.connection.create.executed', (event) => {
var connection = (event as any).element; var connection = (event as any).element
if (connection) { if (connection) {
updateWaypointsByManhattan(connection, modeling); updateWaypointsByManhattan(connection, modeling)
} }
}); })
eventBus.on('shape.move.end', (event) => { eventBus.on('shape.move.end', (event) => {
const shape = (event as any).shape; const shape = (event as any).shape
if (shape.incoming) { if (shape.incoming) {
shape.incoming.forEach((element: Connection) => { shape.incoming.forEach((element: Connection) => {
updateWaypointsByManhattan(element, modeling); updateWaypointsByManhattan(element, modeling)
}); })
} }
if (shape.outgoing) { if (shape.outgoing) {
shape.outgoing.forEach((element: Connection) => { shape.outgoing.forEach((element: Connection) => {
updateWaypointsByManhattan(element, modeling); updateWaypointsByManhattan(element, modeling)
}); })
} }
}); })
} }
export default { export default {
__init__: [ 'manhattanLayoutPlugin' ], __init__: ['manhattanLayoutPlugin'],
manhattanLayoutPlugin: [ 'type', ManhattanLayoutPlugin ] manhattanLayoutPlugin: ['type', ManhattanLayoutPlugin],
}; }

View file

@ -1,60 +1,57 @@
import { Element } from 'diagram-js/lib/model/Types'; import { Element } from 'diagram-js/lib/model/Types'
import { Outline } from 'diagram-js/lib/features/outline/OutlineProvider'; import { Outline } from 'diagram-js/lib/features/outline/OutlineProvider'
import { import { attr as svgAttr, create as svgCreate } from 'tiny-svg'
attr as svgAttr,
create as svgCreate} from 'tiny-svg';
import Styles from 'diagram-js/lib/draw/Styles'; import Styles from 'diagram-js/lib/draw/Styles'
function CustomOutlineProvider(this: any, outline:Outline, styles:Styles) { function CustomOutlineProvider(this: any, outline: Outline, styles: Styles) {
this._styles = styles; this._styles = styles
outline.registerProvider(this); outline.registerProvider(this)
} }
CustomOutlineProvider.$inject = [ CustomOutlineProvider.$inject = ['outline', 'styles']
'outline',
'styles'
];
CustomOutlineProvider.prototype.getOutline = function(element:Element) { //CustomOutlineProvider.prototype.getOutline = function(element:Element) {
if (element.type === 'custom:circle') { // if (element.type === 'mechanism') {
const outline = svgCreate('circle'); // const outline = svgCreate('circle');
//
// svgAttr(outline , {
// x: `${element.x}`,
// y: `${element.y}`,
// cx: element.width / 2,
// cy: element.height / 2,
// r: 60,
// fill: "none",
// });
// return outline;
// }
//}
svgAttr(outline , { CustomOutlineProvider.prototype.updateOutline = function (
element: Element,
outline: Outline
) {
if (element.type === 'mechanism') {
outline = svgCreate('rect')
svgAttr(outline, {
x: `${element.x}`, x: `${element.x}`,
y: `${element.y}`, y: `${element.y}`,
cx: element.width / 2, cx: element.width / 2,
cy: element.height / 2, cy: element.height / 2,
r: 60, r: 60,
fill: "none", fill: 'none',
}); })
return outline;
}
}
CustomOutlineProvider.prototype.updateOutline = function(element: Element, outline: Outline) {
if (element.type === 'custom:circle') {
outline = svgCreate('rect');
svgAttr(outline , {
x: `${element.x}`,
y: `${element.y}`,
cx: element.width / 2,
cy: element.height / 2,
r: 60,
fill: "none",
});
} }
return false; return false
} }
import Ouline from 'diagram-js/lib/features/outline'; // idk why it's called such way import Ouline from 'diagram-js/lib/features/outline' // idk why it's called such way
export default { export default {
__init__: ['outlineProvider'], __init__: ['outlineProvider'],
__depends__: [ Ouline ], __depends__: [Ouline],
outlineProvider: ['type', CustomOutlineProvider] outlineProvider: ['type', CustomOutlineProvider],
} }

View file

@ -14,8 +14,8 @@ export default {
LassoToolModule, LassoToolModule,
HandToolModule, HandToolModule,
GlobalConnectModule, GlobalConnectModule,
translate translate,
], ],
__init__: [ 'paletteProvider' ], __init__: ['paletteProvider'],
paletteProvider: [ 'type', PaletteProvider ] paletteProvider: ['type', PaletteProvider],
}; }

View file

@ -1,11 +1,12 @@
import ElementFactory from "diagram-js/lib/core/ElementFactory"; import ElementFactory from 'diagram-js/lib/core/ElementFactory'
import Palette from "diagram-js/lib/features/palette/Palette" import Palette from 'diagram-js/lib/features/palette/Palette'
import LassoTool from "diagram-js/lib/features/lasso-tool/LassoTool"; import LassoTool from 'diagram-js/lib/features/lasso-tool/LassoTool'
import Create from "diagram-js/lib/features/create/Create"; import Create from 'diagram-js/lib/features/create/Create'
import GlobalConnect from "diagram-js/lib/features/global-connect/GlobalConnect"; import GlobalConnect from 'diagram-js/lib/features/global-connect/GlobalConnect'
import Translate from "diagram-js/lib/i18n/translate/Translate"; import Translate from 'diagram-js/lib/i18n/translate/Translate'
import HandTool from "diagram-js/lib/features/hand-tool/HandTool"; import HandTool from 'diagram-js/lib/features/hand-tool/HandTool'
import { assign } from "min-dash"; import { assign } from 'min-dash'
import { stateInstrument, stateMechanism } from '../addObjectForm'
export default function PaletteProvider( export default function PaletteProvider(
this: any, this: any,
@ -13,17 +14,18 @@ export default function PaletteProvider(
create: Create, create: Create,
elementFactory: ElementFactory, elementFactory: ElementFactory,
lassoTool: LassoTool, lassoTool: LassoTool,
handTool:HandTool, handTool: HandTool,
globalConnect:GlobalConnect, globalConnect: GlobalConnect,
translate:typeof Translate) { translate: typeof Translate
this._palette = palette; ) {
this._create = create; this._palette = palette
this._elementFactory = elementFactory; this._create = create
this._lassoTool = lassoTool; this._elementFactory = elementFactory
this._handTool = handTool; this._lassoTool = lassoTool
this._globalConnect = globalConnect; this._handTool = handTool
this._translate = translate; this._globalConnect = globalConnect
palette.registerProvider(this); this._translate = translate
palette.registerProvider(this)
} }
PaletteProvider.$inject = [ PaletteProvider.$inject = [
@ -33,18 +35,17 @@ PaletteProvider.$inject = [
'lassoTool', 'lassoTool',
'handTool', 'handTool',
'globalConnect', 'globalConnect',
'translate' 'translate',
] ]
PaletteProvider.prototype.getPaletteEntries = function() { PaletteProvider.prototype.getPaletteEntries = function () {
var actions = {}, var actions = {},
create = this._create, create = this._create,
elementFactory = this._elementFactory, elementFactory = this._elementFactory,
lassoTool = this._lassoTool, lassoTool = this._lassoTool,
handTool = this._handTool, handTool = this._handTool,
globalConnect = this._globalConnect, globalConnect = this._globalConnect,
translate = this._translate; translate = this._translate
assign(actions, { assign(actions, {
'hand-tool': { 'hand-tool': {
@ -52,69 +53,85 @@ PaletteProvider.prototype.getPaletteEntries = function() {
className: 'icon-hand-tool', className: 'icon-hand-tool',
title: translate('Activate hand tool'), title: translate('Activate hand tool'),
action: { action: {
click: function(event: Event) { click: function (event: Event) {
handTool.activateHand(event); handTool.activateHand(event)
} },
} },
}, },
'lasso-tool': { 'lasso-tool': {
group: 'tools', group: 'tools',
className: 'icon-lasso-tool', className: 'icon-lasso-tool',
title: translate('Activate lasso tool'), title: translate('Activate lasso tool'),
action: { action: {
click: function(event: Event) { click: function (event: Event) {
lassoTool.activateSelection(event); lassoTool.activateSelection(event)
} },
} },
}, },
'global-connect-tool': { 'global-connect-tool': {
group: 'tools', group: 'tools',
className: 'icon-connect', className: 'icon-connect',
title: translate('Activate global connect tool'), title: translate('Activate global connect tool'),
action: { action: {
click: function(event: Event) { click: function (event: Event) {
globalConnect.start(event); globalConnect.start(event)
} },
} },
}, },
'tool-separator': { 'tool-separator': {
group: 'tools', group: 'tools',
separator: true separator: true,
}, },
'create-shape': { 'create-shape': {
group: 'create', group: 'create',
className: 'icon-create-shape', className: 'icon-create-shape',
title: 'Create Shape', title: 'Create Shape',
action: { action: {
click: function() { click: function () {
var shape = elementFactory.createShape({ var shape = elementFactory.createShape({
width: 100, width: 100,
height: 80, height: 80,
canStartConnection:true canStartConnection: true,
}); })
console.log(shape.canStartConnection); create.start(event, shape)
create.start(event, shape); },
} },
}
}, },
'create-device': { 'create-device': {
group: 'create', group: 'create',
className: 'icon-create-shape', className: 'icon-create-shape',
title: 'Create Device', title: 'Добавить Прибор',
action: { action: {
click: function() { click: function () {
var shape = elementFactory.createShape({ var shape = elementFactory.createShape({
width: 100, width: 50,
height: 80, height: 120,
canStartConnection:true, canStartConnection: true,
type: 'custom:circle' type: 'instrument',
}); obj: structuredClone(stateInstrument),
console.log(shape.canStartConnection); })
create.start(event, shape); create.start(event, shape)
} },
} },
}, },
}); 'create-mechanism': {
group: 'create',
className: 'icon-create-shape',
title: 'Добавить Исполнительный Механизм',
action: {
click: function () {
var shape = elementFactory.createShape({
width: 50,
height: 120,
canStartConnection: true,
type: 'mechanism',
obj: structuredClone(stateMechanism),
})
create.start(event, shape)
},
},
},
})
return actions; return actions
}; }

View file

@ -3,59 +3,126 @@ import { assign } from 'min-dash'
import { import {
append as svgAppend, append as svgAppend,
attr as svgAttr, attr as svgAttr,
create as svgCreate create as svgCreate,
} from 'tiny-svg' } from 'tiny-svg'
import { Shape } from 'diagram-js/lib/model/Types'
const HIGH_PRIORITY = 1500; const HIGH_PRIORITY = 1500
class CustomShapeRenderer extends BaseRenderer { class CustomShapeRenderer extends BaseRenderer {
styles: any styles: any
SHAPE_STYLE: any SHAPE_STYLE: any
static $inject = ['eventBus', 'styles'] static $inject = ['eventBus', 'styles']
constructor(eventBus: any, styles: any) { constructor(eventBus: any, styles: any) {
super(eventBus, HIGH_PRIORITY) super(eventBus, HIGH_PRIORITY)
this.styles = styles this.styles = styles
this.SHAPE_STYLE = styles.style({ fill: 'Canvas', stroke: 'CanvasText', strokeWidth: 2 }) this.SHAPE_STYLE = styles.style({
fill: 'Canvas',
stroke: 'CanvasText',
strokeWidth: 2,
})
} }
canRender(element: any): boolean { canRender(element: any): boolean {
return element.type === 'custom:circle'; return element.type === 'mechanism' || element.type == 'instrument'
} }
drawShape(visuals: Element, element: { width: number; height: number; }) : SVGElement { drawShape(visuals: Element, shape: Shape): SVGElement {
var circle = svgCreate('circle'); var g = svgCreate('g')
if (shape.type == 'mechanism') {
g = drawMechanism(shape)
}
if (shape.type == 'instrument') {
g = drawInstrument(shape)
}
svgAttr(circle, { svgAttr(g, assign({}, this.SHAPE_STYLE))
cx: `${element.width / 2}`, svgAppend(visuals, g)
cy: `${element.height / 2 - 52}`,
r: '2.5mm',
fill: "none",
stroke: "CanvasText",
});
var line = svgCreate('line'); return g
svgAttr(line, { }
x1: element.width / 2, }
x2: element.width / 2,
y1: element.height/2,
y2: element.height/2 - 40 - 2,
stroke: "CanvasText",
function drawMechanism(shape: Shape): SVGGElement {
var circle = svgCreate('circle')
svgAttr(circle, {
cx: `${shape.width / 2}`,
cy: `${shape.height / 2 - 52}`,
r: '2.5mm',
fill: 'none',
stroke: 'CanvasText',
})
var line = svgCreate('line')
svgAttr(line, {
x1: shape.width / 2,
x2: shape.width / 2,
y1: shape.height / 2,
y2: shape.height / 2 - 40 - 2,
stroke: 'CanvasText',
})
var text = svgCreate('text')
svgAttr(text, {
x: shape.width / 2 - 4,
y: shape.height / 2 - 40 - 10,
'font-size': 10,
'font-family': 'Arial',
})
text.innerHTML = 'M'
var g = svgCreate('g')
svgAppend(g, circle)
svgAppend(g, line)
if (shape.obj.ручной) {
svgAppend(g, text)
}
return g
}
function drawInstrument(shape: Shape): SVGGElement {
var g = svgCreate('g')
if (!shape.obj.является_паз) {
const circle = svgCreate('circle', {
cx: shape.width / 2,
cy: shape.height / 2,
r: '5mm',
stroke: 'CanvasText',
fill: 'Canvas',
}) })
svgAppend(g, circle)
var g = svgCreate('g'); } else {
svgAppend(g, circle); function diamond(w: number, h: number, x: number, y: number) {
svgAppend(g, line); return svgCreate('polygon', {
svgAttr(g, assign({}, this.SHAPE_STYLE)); points: `${x + w / 2}, ${y - h / 2}, ${x + w + w / 2}, ${y + h / 2}, ${x + w / 2}, ${y + h + h / 2}, ${x - w / 2}, ${y + h / 2}`,
svgAppend(visuals, g); stroke: 'CanvasText',
fill: 'Canvas',
return g; })
}
svgAppend(g, diamond(shape.width, shape.height, 0, 0))
} }
if (shape.obj.фиксация == 'НаЩите') {
svgAppend(
g,
svgCreate('line', {
x1: shape.width / 2 - 20,
y1: shape.height / 2,
x2: shape.width / 2 + 20,
y2: shape.height / 2,
stroke: 'CanvasText',
fill: 'Canvas',
})
)
}
return g
} }
export default { export default {
__init__: ['customShapeRenderer'], __init__: ['customShapeRenderer'],
customShapeRenderer: ['type', CustomShapeRenderer] customShapeRenderer: ['type', CustomShapeRenderer],
}; }

View file

@ -1,11 +1,24 @@
export default { export default {
__init__: [ 'customRenderer' ], __init__: ['customRenderer'],
customRenderer: [ customRenderer: [
'type', 'type',
function (defaultRenderer: any) { function (defaultRenderer: any) {
defaultRenderer.CONNECTION_STYLE = { fill: 'none', strokeWidth: 5, stroke: 'CanvasText' }; defaultRenderer.CONNECTION_STYLE = {
defaultRenderer.SHAPE_STYLE = { fill: 'Canvas', stroke: 'CanvasText', strokeWidth: 2 }; fill: 'none',
defaultRenderer.FRAME_STYLE = { fill: 'none', stroke: 'CanvasText', strokeDasharray: 4, strokeWidth: 2 }; strokeWidth: 5,
} stroke: 'CanvasText',
] }
}; defaultRenderer.SHAPE_STYLE = {
fill: 'Canvas',
stroke: 'CanvasText',
strokeWidth: 2,
}
defaultRenderer.FRAME_STYLE = {
fill: 'none',
stroke: 'CanvasText',
strokeDasharray: 4,
strokeWidth: 2,
}
},
],
}