mirror of
https://github.com/directus/directus.git
synced 2026-02-02 06:45:36 -05:00
Track corner intersaction
This commit is contained in:
@@ -2,7 +2,14 @@
|
||||
<div
|
||||
class="panel"
|
||||
:style="positioning"
|
||||
:class="{ editing: editMode, dragging }"
|
||||
:class="{
|
||||
editing: editMode,
|
||||
dragging,
|
||||
'br-tl': dragging || panel.borderRadius[0],
|
||||
'br-tr': dragging || panel.borderRadius[1],
|
||||
'br-br': dragging || panel.borderRadius[2],
|
||||
'br-bl': dragging || panel.borderRadius[3],
|
||||
}"
|
||||
data-move
|
||||
@pointerdown="onPointerDown('move', $event)"
|
||||
>
|
||||
@@ -219,7 +226,6 @@ export default defineComponent({
|
||||
grid-column: var(--pos-x) / span var(--width);
|
||||
background-color: var(--background-page);
|
||||
border: 1px solid var(--border-subdued);
|
||||
border-radius: var(--border-radius-outline);
|
||||
box-shadow: 0 0 0 1px var(--border-subdued);
|
||||
}
|
||||
|
||||
@@ -371,4 +377,20 @@ export default defineComponent({
|
||||
height: 12px;
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
|
||||
.br-tl {
|
||||
border-top-left-radius: var(--border-radius-outline);
|
||||
}
|
||||
|
||||
.br-tr {
|
||||
border-top-right-radius: var(--border-radius-outline);
|
||||
}
|
||||
|
||||
.br-br {
|
||||
border-bottom-right-radius: var(--border-radius-outline);
|
||||
}
|
||||
|
||||
.br-bl {
|
||||
border-bottom-left-radius: var(--border-radius-outline);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -82,6 +82,7 @@ import { omit } from 'lodash';
|
||||
import { unexpectedError } from '@/utils/unexpected-error';
|
||||
import api from '@/api';
|
||||
import InsightsPanel from '../components/panel.vue';
|
||||
import { pointOnLine } from '@/utils/point-on-line';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'InsightsDashboard',
|
||||
@@ -107,12 +108,12 @@ export default defineComponent({
|
||||
insightsStore.state.dashboards.find((dashboard) => dashboard.id === props.primaryKey)
|
||||
);
|
||||
|
||||
const stagedPanels = ref<Partial<Panel>[]>([]);
|
||||
const stagedPanels = ref<Partial<Panel & { borderRadius: [boolean, boolean, boolean, boolean] }>[]>([]);
|
||||
|
||||
const panels = computed(() => {
|
||||
const savedPanels = currentDashboard.value?.panels || [];
|
||||
|
||||
return [
|
||||
const raw = [
|
||||
...savedPanels.map((panel) => {
|
||||
const updates = stagedPanels.value.find((updatedPanel) => updatedPanel.id === panel.id);
|
||||
|
||||
@@ -124,14 +125,58 @@ export default defineComponent({
|
||||
}),
|
||||
...stagedPanels.value.filter((panel) => panel.id?.startsWith('_')),
|
||||
];
|
||||
|
||||
const withCoords = raw.map((panel) => ({
|
||||
...panel,
|
||||
_coordinates: [
|
||||
[panel.position_x!, panel.position_y!],
|
||||
[panel.position_x! + panel.width!, panel.position_y!],
|
||||
[panel.position_x! + panel.width!, panel.position_y! + panel.height!],
|
||||
[panel.position_x!, panel.position_y! + panel.height!],
|
||||
] as [number, number][],
|
||||
}));
|
||||
|
||||
const withBorderRadii = withCoords.map((panel) => {
|
||||
let topLeftIntersects = false;
|
||||
let topRightIntersects = false;
|
||||
let bottomRightIntersects = false;
|
||||
let bottomLeftIntersects = false;
|
||||
|
||||
for (const otherPanel of withCoords) {
|
||||
if (otherPanel.id === panel.id) continue;
|
||||
|
||||
const borders = [
|
||||
[otherPanel._coordinates[0], otherPanel._coordinates[1]],
|
||||
[otherPanel._coordinates[1], otherPanel._coordinates[2]],
|
||||
[otherPanel._coordinates[2], otherPanel._coordinates[3]],
|
||||
[otherPanel._coordinates[3], otherPanel._coordinates[0]],
|
||||
];
|
||||
|
||||
if (topLeftIntersects === false)
|
||||
topLeftIntersects = borders.some(([p1, p2]) => pointOnLine(panel._coordinates[0], p1, p2));
|
||||
if (topRightIntersects === false)
|
||||
topRightIntersects = borders.some(([p1, p2]) => pointOnLine(panel._coordinates[1], p1, p2));
|
||||
if (bottomRightIntersects === false)
|
||||
bottomRightIntersects = borders.some(([p1, p2]) => pointOnLine(panel._coordinates[2], p1, p2));
|
||||
if (bottomLeftIntersects === false)
|
||||
bottomLeftIntersects = borders.some(([p1, p2]) => pointOnLine(panel._coordinates[3], p1, p2));
|
||||
}
|
||||
|
||||
return {
|
||||
...panel,
|
||||
borderRadius: [!topLeftIntersects, !topRightIntersects, !bottomRightIntersects, !bottomLeftIntersects],
|
||||
};
|
||||
});
|
||||
|
||||
return withBorderRadii;
|
||||
});
|
||||
|
||||
const workspaceSize = computed(() => {
|
||||
const furthestPanelX = panels.value.reduce(
|
||||
(aggr, panel) => {
|
||||
if (panel.position_x! > aggr.position_x!) {
|
||||
aggr.position_x = panel.position_x;
|
||||
aggr.width = panel.width;
|
||||
aggr.position_x = panel.position_x!;
|
||||
aggr.width = panel.width!;
|
||||
}
|
||||
|
||||
return aggr;
|
||||
@@ -142,8 +187,8 @@ export default defineComponent({
|
||||
const furthestPanelY = panels.value.reduce(
|
||||
(aggr, panel) => {
|
||||
if (panel.position_y! > aggr.position_y!) {
|
||||
aggr.position_y = panel.position_y;
|
||||
aggr.height = panel.height;
|
||||
aggr.position_y = panel.position_y!;
|
||||
aggr.height = panel.height!;
|
||||
}
|
||||
|
||||
return aggr;
|
||||
|
||||
23
app/src/utils/point-on-line.ts
Normal file
23
app/src/utils/point-on-line.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
type Point = [number, number];
|
||||
|
||||
/**
|
||||
* Check if a given X, Y coordinate is on the line between two other points
|
||||
*/
|
||||
export function pointOnLine(current: Point, point1: Point, point2: Point) {
|
||||
const [curX, curY] = current;
|
||||
const [p1X, p1Y] = point1;
|
||||
const [p2X, p2Y] = point2;
|
||||
|
||||
const dxc = curX - p1X;
|
||||
const dyc = curY - p1Y;
|
||||
|
||||
const dxl = p2X - p1X;
|
||||
const dyl = p2Y - p1Y;
|
||||
|
||||
const cross = dxc * dyl - dyc * dxl;
|
||||
|
||||
if (cross !== 0) return false;
|
||||
|
||||
if (Math.abs(dxl) >= Math.abs(dyl)) return dxl > 0 ? p1X <= curX && curX <= p2X : p2X <= curX && curX <= p1X;
|
||||
else return dyl > 0 ? p1Y <= curY && curY <= p2Y : p2Y <= curY && curY <= p1Y;
|
||||
}
|
||||
Reference in New Issue
Block a user