Canvas: Refactor ConnectionSVG utils (#77578)

Co-authored-by: Krishna Dhakal <7krishna7dhakal7@gmail.com>
This commit is contained in:
Adela Almasan 2023-11-02 12:09:07 -05:00 committed by GitHub
parent 01af8f61f1
commit 087e081c5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 44 deletions

View File

@ -7,6 +7,7 @@ import { config } from 'app/core/config';
import { Scene } from 'app/features/canvas/runtime/scene';
import { ConnectionState } from '../../types';
import { calculateCoordinates, getConnectionStyles } from '../../utils';
type Props = {
setSVGRef: (anchorElement: SVGSVGElement) => void;
@ -97,19 +98,6 @@ export const ConnectionSVG = ({ setSVGRef, setLineRef, scene }: Props) => {
}
};
// @TODO revisit, currently returning last row index for field
const getRowIndex = (fieldName: string | undefined) => {
if (fieldName) {
const series = scene.context.getPanelData()?.series[0];
const field = series?.fields.find((f) => (f.name = fieldName));
const data = field?.values;
return data ? data.length - 1 : 0;
}
return 0;
};
// Figure out target and then target's relative coordinates drawing (if no target do parent)
const renderConnections = () => {
return scene.connections.state.map((v, idx) => {
@ -122,40 +110,12 @@ export const ConnectionSVG = ({ setSVGRef, setLineRef, scene }: Props) => {
return;
}
const sourceHorizontalCenter = sourceRect.left - parentRect.left + sourceRect.width / 2;
const sourceVerticalCenter = sourceRect.top - parentRect.top + sourceRect.height / 2;
const { x1, y1, x2, y2 } = calculateCoordinates(sourceRect, parentRect, info, target);
// Convert from connection coords to DOM coords
// TODO: Break this out into util function and add tests
const x1 = sourceHorizontalCenter + (info.source.x * sourceRect.width) / 2;
const y1 = sourceVerticalCenter - (info.source.y * sourceRect.height) / 2;
let x2;
let y2;
if (info.targetName) {
const targetRect = target.div?.getBoundingClientRect();
const targetHorizontalCenter = targetRect!.left - parentRect.left + targetRect!.width / 2;
const targetVerticalCenter = targetRect!.top - parentRect.top + targetRect!.height / 2;
x2 = targetHorizontalCenter + (info.target.x * targetRect!.width) / 2;
y2 = targetVerticalCenter - (info.target.y * targetRect!.height) / 2;
} else {
const parentHorizontalCenter = parentRect.width / 2;
const parentVerticalCenter = parentRect.height / 2;
x2 = parentHorizontalCenter + (info.target.x * parentRect.width) / 2;
y2 = parentVerticalCenter - (info.target.y * parentRect.height) / 2;
}
const { strokeColor, strokeWidth } = getConnectionStyles(info, scene, defaultArrowSize);
const isSelected = selectedConnection === v && scene.panel.context.instanceState.selectedConnection;
const strokeColor = info.color ? scene.context.getColor(info.color).value() : defaultArrowColor;
const lastRowIndex = getRowIndex(info.size?.field);
const strokeWidth = info.size ? scene.context.getScale(info.size).get(lastRowIndex) : defaultArrowSize;
const connectionCursorStyle = scene.isEditingEnabled ? 'grab' : '';
const selectedStyles = { stroke: '#44aaff', strokeOpacity: 0.6, strokeWidth: strokeWidth + 5 };

View File

@ -2,7 +2,7 @@ import { isNumber, isString } from 'lodash';
import { AppEvents, Field, getFieldDisplayName, LinkModel, PluginState, SelectableValue } from '@grafana/data';
import appEvents from 'app/core/app_events';
import { hasAlphaPanels } from 'app/core/config';
import { hasAlphaPanels, config } from 'app/core/config';
import {
defaultElementItems,
advancedElementItems,
@ -10,6 +10,7 @@ import {
canvasElementRegistry,
CanvasElementOptions,
TextConfig,
CanvasConnection,
} from 'app/features/canvas';
import { notFoundItem } from 'app/features/canvas/elements/notFound';
import { ElementState } from 'app/features/canvas/runtime/element';
@ -184,3 +185,56 @@ export function updateConnectionsForSource(element: ElementState, scene: Scene)
connection.source.onChange({ ...connection.source.options, connections });
});
}
export const calculateCoordinates = (
sourceRect: DOMRect,
parentRect: DOMRect,
info: CanvasConnection,
target: ElementState
) => {
const sourceHorizontalCenter = sourceRect.left - parentRect.left + sourceRect.width / 2;
const sourceVerticalCenter = sourceRect.top - parentRect.top + sourceRect.height / 2;
// Convert from connection coords to DOM coords
const x1 = sourceHorizontalCenter + (info.source.x * sourceRect.width) / 2;
const y1 = sourceVerticalCenter - (info.source.y * sourceRect.height) / 2;
let x2;
let y2;
if (info.targetName) {
const targetRect = target.div?.getBoundingClientRect();
const targetHorizontalCenter = targetRect!.left - parentRect.left + targetRect!.width / 2;
const targetVerticalCenter = targetRect!.top - parentRect.top + targetRect!.height / 2;
x2 = targetHorizontalCenter + (info.target.x * targetRect!.width) / 2;
y2 = targetVerticalCenter - (info.target.y * targetRect!.height) / 2;
} else {
const parentHorizontalCenter = parentRect.width / 2;
const parentVerticalCenter = parentRect.height / 2;
x2 = parentHorizontalCenter + (info.target.x * parentRect.width) / 2;
y2 = parentVerticalCenter - (info.target.y * parentRect.height) / 2;
}
return { x1, y1, x2, y2 };
};
// @TODO revisit, currently returning last row index for field
export const getRowIndex = (fieldName: string | undefined, scene: Scene) => {
if (fieldName) {
const series = scene.context.getPanelData()?.series[0];
const field = series?.fields.find((f) => (f.name = fieldName));
const data = field?.values;
return data ? data.length - 1 : 0;
}
return 0;
};
export const getConnectionStyles = (info: CanvasConnection, scene: Scene, defaultArrowSize: number) => {
const defaultArrowColor = config.theme2.colors.text.primary;
const lastRowIndex = getRowIndex(info.size?.field, scene);
const strokeColor = info.color ? scene.context.getColor(info.color).value() : defaultArrowColor;
const strokeWidth = info.size ? scene.context.getScale(info.size).get(lastRowIndex) : defaultArrowSize;
return { strokeColor, strokeWidth };
};