You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.6 KiB
JavaScript
110 lines
2.6 KiB
JavaScript
import { useVueFlow } from '@vue-flow/core';
|
|
import { ref, watch } from 'vue';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
|
|
const getId = (type) => {
|
|
return `${type}_${uuidv4().replaceAll('-', '_')}`;
|
|
};
|
|
|
|
const cmToPx = (cm) => {
|
|
return cm * 96 / 2.54;
|
|
};
|
|
|
|
|
|
const getOption = (e) => {
|
|
if (e === 'text') {
|
|
return { name: '', field: '', default: '' };
|
|
} else if (e === 'image') {
|
|
return { name: '', field: '', imageSrc: '', imageType: '' };
|
|
} else {
|
|
return {};
|
|
}
|
|
};
|
|
const getNodeSize = (e) => {
|
|
if (e === 'line' || e === 'multiLines' || e === 'bar' || e === 'multiBars' || e === 'curve' || e === 'multiCurves' || e === 'customBoard' || e === 'pie') {
|
|
return { width: cmToPx(5), height: cmToPx(2) };
|
|
} else {
|
|
return { width: cmToPx(5), height: cmToPx(2) };
|
|
}
|
|
};
|
|
|
|
const tool = () => {
|
|
const nodeType = ref('');
|
|
const parentId = ref('');
|
|
const { addNodes, screenToFlowCoordinate, onNodesInitialized, updateNode } = useVueFlow();
|
|
const onDragStart = (event, type, pid) => {
|
|
if (event.dataTransfer) {
|
|
event.dataTransfer.setData('application/vueflow', type);
|
|
event.dataTransfer.effectAllowed = 'move';
|
|
}
|
|
|
|
nodeType.value = type;
|
|
parentId.value = pid;
|
|
document.addEventListener('drop', onDragEnd);
|
|
};
|
|
const onDragEnd = () => {
|
|
nodeType.value = null;
|
|
document.removeEventListener('drop', onDragEnd);
|
|
};
|
|
const onDrop = (event) => {
|
|
const dimensions = getNodeSize(nodeType.value);
|
|
|
|
const position = screenToFlowCoordinate({
|
|
x: event.clientX, y: event.clientY
|
|
});
|
|
|
|
const nodeId = getId(nodeType.value);
|
|
const newNode = {
|
|
id: nodeId,
|
|
name: nodeType.value,
|
|
type: nodeType.value,
|
|
parentNode: parentId.value,
|
|
extent: 'parent',
|
|
dimensions,
|
|
position,
|
|
data: { options: getOption(nodeType.value), outputData: {} }
|
|
};
|
|
|
|
|
|
const { off } = onNodesInitialized(() => {
|
|
updateNode(nodeId, (node) => ({
|
|
position: { x: node.position.x - node.dimensions.width / 2, y: node.position.y - node.dimensions.height / 2 }
|
|
}));
|
|
|
|
off();
|
|
});
|
|
|
|
addNodes(newNode);
|
|
|
|
};
|
|
const onDragOver = (event) => {
|
|
event.preventDefault();
|
|
|
|
if (nodeType.value) {
|
|
|
|
if (event.dataTransfer) {
|
|
event.dataTransfer.dropEffect = 'move';
|
|
}
|
|
}
|
|
};
|
|
return {
|
|
onDragStart, onDragEnd, onDrop, onDragOver
|
|
};
|
|
};
|
|
export default tool;
|
|
|
|
export const options = {
|
|
isD: false, isJSON: (str) => {
|
|
if (typeof str === 'string') {
|
|
try {
|
|
JSON.parse(str);
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
return false;
|
|
}, cmToPx: cmToPx
|
|
};
|