mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-23 08:05:59 +00:00
diagram: select more nodes by drag rectangke
This commit is contained in:
@@ -41,6 +41,8 @@
|
||||
import { GraphDefinition, GraphLayout } from './GraphLayout';
|
||||
import { saveFileToDisk } from '../utility/exportElectronFile';
|
||||
import { apiCall } from '../utility/api';
|
||||
import moveDrag from '../utility/moveDrag';
|
||||
import { rectanglesHaveIntersection } from './designerMath';
|
||||
|
||||
export let value;
|
||||
export let onChange;
|
||||
@@ -55,6 +57,8 @@
|
||||
let domCanvas;
|
||||
let canvasWidth = 3000;
|
||||
let canvasHeight = 3000;
|
||||
let dragStartPoint = null;
|
||||
let dragCurrentPoint = null;
|
||||
|
||||
const sourceDragColumn$ = writable(null);
|
||||
const targetDragColumn$ = writable(null);
|
||||
@@ -542,6 +546,41 @@
|
||||
tick().then(recomputeReferencePositions);
|
||||
};
|
||||
|
||||
const handleMoveStart = (x, y) => {
|
||||
dragStartPoint = { x, y };
|
||||
};
|
||||
const handleMove = (dx, dy, x, y) => {
|
||||
dragCurrentPoint = { x, y };
|
||||
};
|
||||
const handleMoveEnd = (x, y) => {
|
||||
if (dragStartPoint && dragCurrentPoint) {
|
||||
const bounds = {
|
||||
left: Math.min(dragStartPoint.x, dragCurrentPoint.x),
|
||||
right: Math.max(dragStartPoint.x, dragCurrentPoint.x),
|
||||
top: Math.min(dragStartPoint.y, dragCurrentPoint.y),
|
||||
bottom: Math.max(dragStartPoint.y, dragCurrentPoint.y),
|
||||
};
|
||||
|
||||
callChange(
|
||||
current => ({
|
||||
...current,
|
||||
tables: (current.tables || []).map(x => {
|
||||
const domTable = domTables[x.designerId] as any;
|
||||
const rect = domTable.getRect();
|
||||
return {
|
||||
...x,
|
||||
isSelectedTable: rectanglesHaveIntersection(rect, bounds),
|
||||
};
|
||||
}),
|
||||
}),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
dragStartPoint = null;
|
||||
dragCurrentPoint = null;
|
||||
};
|
||||
|
||||
function recomputeReferencePositions() {
|
||||
for (const ref of Object.values(referenceRefs) as any[]) {
|
||||
if (ref) ref.recomputePosition();
|
||||
@@ -651,6 +690,7 @@
|
||||
);
|
||||
}
|
||||
}}
|
||||
use:moveDrag={settings?.canSelectTables ? [handleMoveStart, handleMove, handleMoveEnd] : null}
|
||||
>
|
||||
{#each references || [] as ref (ref.designerId)}
|
||||
<svelte:component
|
||||
@@ -700,6 +740,20 @@
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if dragStartPoint && dragCurrentPoint}
|
||||
<svg class="drag-rect">
|
||||
<polyline
|
||||
points={`
|
||||
${dragStartPoint.x},${dragStartPoint.y}
|
||||
${dragStartPoint.x},${dragCurrentPoint.y}
|
||||
${dragCurrentPoint.x},${dragCurrentPoint.y}
|
||||
${dragCurrentPoint.x},${dragStartPoint.y}
|
||||
${dragStartPoint.x},${dragStartPoint.y}
|
||||
`}
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -715,4 +769,24 @@
|
||||
.canvas {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
svg.drag-rect {
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
:global(.dbgate-screen) svg.drag-rect {
|
||||
visibility: visible;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
:global(.dbgate-screen) svg.drag-rect polyline {
|
||||
fill: none;
|
||||
stroke: var(--theme-bg-4);
|
||||
stroke-width: 2;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import contextMenu from '../utility/contextMenu';
|
||||
import moveDrag from '../utility/moveDrag';
|
||||
import ColumnLine from './ColumnLine.svelte';
|
||||
import { rectanglesHaveIntersection } from './designerMath';
|
||||
import DomTableRef from './DomTableRef';
|
||||
|
||||
export let table;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { arrayDifference } from 'interval-operations';
|
||||
import { intersection, arrayDifference } from 'interval-operations';
|
||||
import _ from 'lodash';
|
||||
|
||||
export interface IPoint {
|
||||
x: number;
|
||||
y: number;
|
||||
@@ -101,6 +102,13 @@ export function rectangleIntersectArea(rect1: IBoxBounds, rect2: IBoxBounds) {
|
||||
return x_overlap * y_overlap;
|
||||
}
|
||||
|
||||
export function rectanglesHaveIntersection(rect1: IBoxBounds, rect2: IBoxBounds) {
|
||||
const xIntersection = intersection([rect1.left, rect1.right], [rect2.left, rect2.right]);
|
||||
const yIntersection = intersection([rect1.top, rect1.bottom], [rect2.top, rect2.bottom]);
|
||||
|
||||
return !!xIntersection && !!yIntersection;
|
||||
}
|
||||
|
||||
export class Vector2D {
|
||||
constructor(public x: number, public y: number) {}
|
||||
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
export default function moveDrag(node, dragEvents) {
|
||||
if (!dragEvents) return;
|
||||
|
||||
|
||||
const [onStart, onMove, onEnd] = dragEvents;
|
||||
let startX = null;
|
||||
let startY = null;
|
||||
|
||||
let clientX = null;
|
||||
let clientY = null;
|
||||
|
||||
const handleMoveDown = e => {
|
||||
if (e.button != 0) return;
|
||||
|
||||
const clientRect = node.getBoundingClientRect();
|
||||
clientX = clientRect.left;
|
||||
clientY = clientRect.top;
|
||||
|
||||
startX = e.clientX;
|
||||
startY = e.clientY;
|
||||
document.addEventListener('mousemove', handleMoveMove, true);
|
||||
document.addEventListener('mouseup', handleMoveEnd, true);
|
||||
onStart();
|
||||
onStart(e.clientX - clientX, e.clientY - clientY);
|
||||
};
|
||||
|
||||
const handleMoveMove = e => {
|
||||
@@ -21,7 +29,7 @@ export default function moveDrag(node, dragEvents) {
|
||||
const diffY = e.clientY - startY;
|
||||
startY = e.clientY;
|
||||
|
||||
onMove(diffX, diffY);
|
||||
onMove(diffX, diffY, e.clientX - clientX, e.clientY - clientY);
|
||||
};
|
||||
const handleMoveEnd = e => {
|
||||
e.preventDefault();
|
||||
@@ -29,7 +37,7 @@ export default function moveDrag(node, dragEvents) {
|
||||
startY = null;
|
||||
document.removeEventListener('mousemove', handleMoveMove, true);
|
||||
document.removeEventListener('mouseup', handleMoveEnd, true);
|
||||
onEnd();
|
||||
onEnd(e.clientX - clientX, e.clientY - clientY);
|
||||
};
|
||||
|
||||
node.addEventListener('mousedown', handleMoveDown);
|
||||
|
||||
Reference in New Issue
Block a user