designer - draw references

This commit is contained in:
Jan Prochazka
2021-03-18 17:10:51 +01:00
parent 93b7a9a674
commit 9e9df60d37
4 changed files with 162 additions and 16 deletions

View File

@@ -10,13 +10,14 @@
export let designer; export let designer;
export let designerId; export let designerId;
export let onChangeColumn; export let onChangeColumn;
export let domLine;
$: designerColumn = (designer.columns || []).find( $: designerColumn = (designer.columns || []).find(
x => x.designerId == designerId && x.columnName == column.columnName x => x.designerId == designerId && x.columnName == column.columnName
); );
</script> </script>
<div> <div bind:this={domLine}>
<CheckboxField <CheckboxField
checked={!!(designer.columns || []).find( checked={!!(designer.columns || []).find(
x => x.designerId == designerId && x.columnName == column.columnName && x.isOutput x => x.designerId == designerId && x.columnName == column.columnName && x.isOutput

View File

@@ -8,17 +8,23 @@
import { getTableInfo } from '../utility/metadataLoaders'; import { getTableInfo } from '../utility/metadataLoaders';
import cleanupDesignColumns from './cleanupDesignColumns'; import cleanupDesignColumns from './cleanupDesignColumns';
import _ from 'lodash'; import _ from 'lodash';
import createRef from '../utility/createRef';
import DesignerReference from './DesignerReference.svelte';
export let value; export let value;
export let onChange; export let onChange;
export let conid; export let conid;
export let database; export let database;
let domWrapper; let domCanvas;
$: tables = value?.tables as any[]; $: tables = value?.tables as any[];
$: references = value?.references as any[]; $: references = value?.references as any[];
const tableRefs = {};
const referenceRefs = {};
$: domTables = _.mapValues(tableRefs, (tbl: any) => tbl.getDomTable());
function fixPositions(tables) { function fixPositions(tables) {
const minLeft = _.min(tables.map(x => x.left)); const minLeft = _.min(tables.map(x => x.left));
const minTop = _.min(tables.map(x => x.top)); const minTop = _.min(tables.map(x => x.top));
@@ -260,6 +266,12 @@
}; };
}); });
}; };
function handleMoveReferences() {
for(const ref of Object.values(referenceRefs) as any[]) {
ref.recomputePosition();
}
}
</script> </script>
<div class="wrapper"> <div class="wrapper">
@@ -267,18 +279,18 @@
<div class="empty">Drag &amp; drop tables or views from left panel here</div> <div class="empty">Drag &amp; drop tables or views from left panel here</div>
{/if} {/if}
<div class="canvas" bind:this={domWrapper} on:dragover={e => e.preventDefault()} on:drop={handleDrop}> <div class="canvas" bind:this={domCanvas} on:dragover={e => e.preventDefault()} on:drop={handleDrop}>
<!-- {#each references || [] as ref (ref.designerId)} {#each references || [] as ref (ref.designerId)}
<DesignerReference <DesignerReference
{changeToken} bind:this={referenceRefs[ref.designerId]}
{domTablesRef} {domTables}
reference={ref} reference={ref}
onChangeReference={changeReference} onChangeReference={changeReference}
onRemoveReference={removeReference} onRemoveReference={removeReference}
designer={value} designer={value}
/> />
{/each} {/each}
<!--
{sourceDragColumn} {sourceDragColumn}
{setSourceDragColumn} {setSourceDragColumn}
{targetDragColumn} {targetDragColumn}
@@ -287,21 +299,21 @@
{setChangeToken} {setChangeToken}
onChangeDomTable={table => { onChangeDomTable={table => {
domTablesRef.current[table.designerId] = table; domTablesRef.current[table.designerId] = table;
}} }} -->
-->
{#each tables || [] as table (table.designerId)} {#each tables || [] as table (table.designerId)}
<DesignerTable <DesignerTable
bind:this={tableRefs[table.designerId]}
onCreateReference={handleCreateReference} onCreateReference={handleCreateReference}
onSelectColumn={handleSelectColumn} onSelectColumn={handleSelectColumn}
onChangeColumn={handleChangeColumn} onChangeColumn={handleChangeColumn}
onAddReferenceByColumn={handleAddReferenceByColumn} onAddReferenceByColumn={handleAddReferenceByColumn}
onMoveReferences={handleMoveReferences}
{table} {table}
onChangeTable={changeTable} onChangeTable={changeTable}
onBringToFront={bringToFront} onBringToFront={bringToFront}
onRemoveTable={removeTable} onRemoveTable={removeTable}
{domWrapper} {domCanvas}
designer={value} designer={value}
/> />
{/each} {/each}

View File

@@ -0,0 +1,109 @@
<script lang="ts">
import _ from 'lodash';
export let reference;
export let onRemoveReference;
export let onChangeReference;
export let designer;
export let domTables;
let src = null;
let dst = null;
let minpos;
let columnsY = [];
const buswi = 10;
const extwi = 25;
// const lineStyle = { fill: 'none', stroke: 'black', strokeWidth: 2 };
export function recomputePosition() {
const { designerId, sourceId, targetId, columns, joinType } = reference;
/** @type {DomTableRef} */
const sourceTable = domTables[sourceId];
/** @type {DomTableRef} */
const targetTable = domTables[targetId];
if (!sourceTable || !targetTable) return null;
const sourceRect = sourceTable.getRect();
const targetRect = targetTable.getRect();
if (!sourceRect || !targetRect) return null;
const possibilities = [];
possibilities.push({ xsrc: sourceRect.left - buswi, dirsrc: -1, xdst: targetRect.left - buswi, dirdst: -1 });
possibilities.push({ xsrc: sourceRect.left - buswi, dirsrc: -1, xdst: targetRect.right + buswi, dirdst: 1 });
possibilities.push({ xsrc: sourceRect.right + buswi, dirsrc: 1, xdst: targetRect.left - buswi, dirdst: -1 });
possibilities.push({ xsrc: sourceRect.right + buswi, dirsrc: 1, xdst: targetRect.right + buswi, dirdst: 1 });
minpos = _.minBy(possibilities, p => Math.abs(p.xsrc - p.xdst));
let srcY = _.mean(columns.map(x => sourceTable.getColumnY(x.source)));
let dstY = _.mean(columns.map(x => targetTable.getColumnY(x.target)));
if (columns.length == 0) {
srcY = sourceTable.getColumnY('');
dstY = targetTable.getColumnY('');
}
src = { x: minpos.xsrc, y: srcY };
dst = { x: minpos.xdst, y: dstY };
columnsY = columns.map((col, colIndex) => {
const y1 = sourceTable.getColumnY(col.source);
const y2 = targetTable.getColumnY(col.target);
return [y1, y2];
});
}
$: {
domTables;
recomputePosition();
}
</script>
{#if src && dst && minpos}
<svg>
<polyline
points={`
${src.x},${src.y}
${src.x + extwi * minpos.dirsrc},${src.y}
${dst.x + extwi * minpos.dirdst},${dst.y}
${dst.x},${dst.y}
`}
/>
{#each columnsY as coly}
<polyline
points={`
${src.x},${src.y}
${src.x},${coly[0]}
${src.x - buswi * minpos.dirsrc},${coly[0]}
`}
/>
<polyline
points={`
${dst.x},${dst.y}
${dst.x},${coly[1]}
${dst.x - buswi * minpos.dirdst},${coly[1]}
`}
/>
{/each}
</svg>>
{/if}
<style>
svg {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
polyline {
fill: none;
stroke: var(--theme-bg-4);
stroke-width: 2;
}
</style>

View File

@@ -1,7 +1,10 @@
<script lang="ts"> <script lang="ts">
import { tick } from 'svelte';
import FontIcon from '../icons/FontIcon.svelte'; import FontIcon from '../icons/FontIcon.svelte';
import moveDrag from '../utility/moveDrag'; import moveDrag from '../utility/moveDrag';
import ColumnLine from './ColumnLine.svelte'; import ColumnLine from './ColumnLine.svelte';
import DomTableRef from './DomTableRef';
export let table; export let table;
export let onChangeTable; export let onChangeTable;
@@ -15,15 +18,20 @@
export let setSourceDragColumn; export let setSourceDragColumn;
export let targetDragColumn; export let targetDragColumn;
export let setTargetDragColumn; export let setTargetDragColumn;
export let onChangeDomTable; // export let onChangeDomTable;
export let domWrapper; export let domCanvas;
export let domTablesRef;
export let designer; export let designer;
export let onMoveReferences;
let movingPosition = null; let movingPosition = null;
let domWrapper;
const columnRefs = {};
$: pureName = table?.pureName; $: pureName = table?.pureName;
$: alias = table?.alias; $: alias = table?.alias;
$: columns = table?.columns; $: columns = table?.columns as any[];
$: designerId = table?.designerId; $: designerId = table?.designerId;
$: objectTypeField = table?.objectTypeField; $: objectTypeField = table?.objectTypeField;
$: left = table?.left; $: left = table?.left;
@@ -35,6 +43,7 @@
function handleMove(x, y) { function handleMove(x, y) {
movingPosition.left += x; movingPosition.left += x;
movingPosition.top += y; movingPosition.top += y;
tick().then(onMoveReferences);
} }
function handleMoveEnd() { function handleMoveEnd() {
onChangeTable({ onChangeTable({
@@ -43,12 +52,20 @@
top: movingPosition.top, top: movingPosition.top,
}); });
movingPosition = null; movingPosition = null;
tick().then(onMoveReferences);
}
export function getDomTable() {
const domRefs = { ...columnRefs };
domRefs[''] = domWrapper;
return new DomTableRef(table, domRefs, domCanvas);
} }
</script> </script>
<div <div
class="wrapper" class="wrapper"
style={`left: ${movingPosition ? movingPosition.left : left}px; top:${movingPosition ? movingPosition.top : top}px`} style={`left: ${movingPosition ? movingPosition.left : left}px; top:${movingPosition ? movingPosition.top : top}px`}
bind:this={domWrapper}
> >
<div <div
class="header" class="header"
@@ -63,7 +80,14 @@
</div> </div>
<div class="columns"> <div class="columns">
{#each columns || [] as column} {#each columns || [] as column}
<ColumnLine {column} {table} {designer} {designerId} {onChangeColumn} /> <ColumnLine
{column}
{table}
{designer}
{designerId}
{onChangeColumn}
bind:domLine={columnRefs[column.columnName]}
/>
{/each} {/each}
</div> </div>
</div> </div>