Canvas: Support dashed connection lines (#84496)

* feat(canvas): add connection types
This commit is contained in:
Ihor Yeromin 2024-03-19 17:56:10 +01:00 committed by GitHub
parent aa9dc9c821
commit 3c97476390
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 60 additions and 3 deletions

View File

@ -49,6 +49,7 @@ export interface CanvasConnection {
path: ConnectionPath;
color?: ColorDimensionConfig;
size?: ScaleDimensionConfig;
lineStyle?: string;
vertices?: ConnectionCoordinates[];
// See https://github.com/anseki/leader-line#options for more examples of more properties
}

View File

@ -134,7 +134,7 @@ export const ConnectionSVG = ({
const { x1, y1, x2, y2 } = calculateCoordinates(sourceRect, parentRect, info, target, transformScale);
const midpoint = calculateMidpoint(x1, y1, x2, y2);
const { strokeColor, strokeWidth } = getConnectionStyles(info, scene, defaultArrowSize);
const { strokeColor, strokeWidth, lineStyle } = getConnectionStyles(info, scene, defaultArrowSize);
const isSelected = selectedConnection === v && scene.panel.context.instanceState.selectedConnection;
@ -199,6 +199,7 @@ export const ConnectionSVG = ({
d={pathString}
stroke={strokeColor}
strokeWidth={strokeWidth}
strokeDasharray={lineStyle}
fill={'none'}
markerEnd={`url(#${CONNECTION_HEAD_ID})`}
/>
@ -261,6 +262,7 @@ export const ConnectionSVG = ({
stroke={strokeColor}
pointerEvents="auto"
strokeWidth={strokeWidth}
strokeDasharray={lineStyle}
markerEnd={`url(#${CONNECTION_HEAD_ID})`}
x1={x1}
y1={y1}

View File

@ -0,0 +1,24 @@
import React, { useCallback } from 'react';
import { SelectableValue, StandardEditorProps } from '@grafana/data';
import { RadioButtonGroup } from '@grafana/ui/src';
import { LineStyle } from '../types';
const options: Array<SelectableValue<LineStyle>> = [
{ value: LineStyle.Solid, label: 'Solid' },
{ value: LineStyle.Dashed, label: 'Dashed' },
];
export const LineStyleEditor = ({ value, onChange }: StandardEditorProps<string, undefined, undefined>) => {
const lineStyle = value ?? LineStyle.Solid;
const onLineStyleChange = useCallback(
(lineStyle: string) => {
onChange(lineStyle);
},
[onChange]
);
return <RadioButtonGroup value={lineStyle} options={options} onChange={onLineStyleChange} fullWidth />;
};

View File

@ -36,6 +36,7 @@ export function getConnectionEditor(opts: CanvasConnectionEditorOptions): Nested
const ctx = { ...context, options: opts.connection.info };
optionBuilder.addColor(builder, ctx);
optionBuilder.addSize(builder, ctx);
optionBuilder.addLineStyle(builder, ctx);
},
};
}

View File

@ -3,11 +3,16 @@ import { CanvasConnection, CanvasElementOptions } from 'app/features/canvas';
import { ColorDimensionEditor, ResourceDimensionEditor, ScaleDimensionEditor } from 'app/features/dimensions/editors';
import { BackgroundSizeEditor } from 'app/features/dimensions/editors/BackgroundSizeEditor';
import { LineStyle } from '../types';
import { LineStyleEditor } from './LineStyleEditor';
interface OptionSuppliers {
addBackground: PanelOptionsSupplier<CanvasElementOptions>;
addBorder: PanelOptionsSupplier<CanvasElementOptions>;
addColor: PanelOptionsSupplier<CanvasConnection>;
addSize: PanelOptionsSupplier<CanvasConnection>;
addLineStyle: PanelOptionsSupplier<CanvasConnection>;
}
const getCategoryName = (str: string, type: string | undefined) => {
@ -120,4 +125,17 @@ export const optionBuilder: OptionSuppliers = {
},
});
},
addLineStyle: (builder, context) => {
const category = ['Line style'];
builder.addCustomEditor({
category,
id: 'lineStyle',
path: 'lineStyle',
name: 'Line style',
editor: LineStyleEditor,
settings: {},
defaultValue: { value: LineStyle.Solid, label: 'Solid' },
});
},
};

View File

@ -43,3 +43,13 @@ export interface ConnectionState {
info: CanvasConnection;
vertices?: ConnectionCoordinates[];
}
export enum LineStyle {
Solid = 'solid',
Dashed = 'dashed',
}
export enum StrokeDasharray {
Solid = '0',
Dashed = '8 8',
}

View File

@ -17,7 +17,7 @@ import { FrameState } from 'app/features/canvas/runtime/frame';
import { Scene, SelectionParams } from 'app/features/canvas/runtime/scene';
import { DimensionContext } from 'app/features/dimensions';
import { AnchorPoint, ConnectionState } from './types';
import { AnchorPoint, ConnectionState, LineStyle, StrokeDasharray } from './types';
export function doSelect(scene: Scene, element: ElementState | FrameState) {
try {
@ -379,7 +379,8 @@ export const getConnectionStyles = (info: CanvasConnection, scene: Scene, defaul
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 };
const lineStyle = info.lineStyle === LineStyle.Dashed ? StrokeDasharray.Dashed : StrokeDasharray.Solid;
return { strokeColor, strokeWidth, lineStyle };
};
export const getParentBoundingClientRect = (scene: Scene) => {