From 5877b82be3a682f58b9a73e59eeb03885210b7d4 Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Fri, 28 May 2021 18:42:32 -0400 Subject: [PATCH] Track corner intersaction --- app/src/modules/insights/components/panel.vue | 26 ++++++++- app/src/modules/insights/routes/dashboard.vue | 57 +++++++++++++++++-- app/src/utils/point-on-line.ts | 23 ++++++++ 3 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 app/src/utils/point-on-line.ts diff --git a/app/src/modules/insights/components/panel.vue b/app/src/modules/insights/components/panel.vue index cf3018c35e..76242da0c2 100644 --- a/app/src/modules/insights/components/panel.vue +++ b/app/src/modules/insights/components/panel.vue @@ -2,7 +2,14 @@
@@ -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); +} diff --git a/app/src/modules/insights/routes/dashboard.vue b/app/src/modules/insights/routes/dashboard.vue index 7f284c1df5..18a969ab2b 100644 --- a/app/src/modules/insights/routes/dashboard.vue +++ b/app/src/modules/insights/routes/dashboard.vue @@ -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[]>([]); + const stagedPanels = ref[]>([]); 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; diff --git a/app/src/utils/point-on-line.ts b/app/src/utils/point-on-line.ts new file mode 100644 index 0000000000..d77ef001d2 --- /dev/null +++ b/app/src/utils/point-on-line.ts @@ -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; +}