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;
+}