mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Canvas: Render selected connection last (#85492)
This commit is contained in:
@@ -124,358 +124,363 @@ export const ConnectionSVG = ({
|
||||
|
||||
// Figure out target and then target's relative coordinates drawing (if no target do parent)
|
||||
const renderConnections = () => {
|
||||
return scene.connections.state.map((v, idx) => {
|
||||
const { source, target, info, vertices } = v;
|
||||
const sourceRect = source.div?.getBoundingClientRect();
|
||||
const parent = source.div?.parentElement;
|
||||
const transformScale = scene.scale;
|
||||
const parentRect = getParentBoundingClientRect(scene);
|
||||
return (
|
||||
scene.connections.state
|
||||
// Render selected connection last, ensuring it is above other connections
|
||||
.sort((_a, b) => (selectedConnection === b && scene.panel.context.instanceState.selectedConnection ? -1 : 0))
|
||||
.map((v, idx) => {
|
||||
const { source, target, info, vertices } = v;
|
||||
const sourceRect = source.div?.getBoundingClientRect();
|
||||
const parent = source.div?.parentElement;
|
||||
const transformScale = scene.scale;
|
||||
const parentRect = getParentBoundingClientRect(scene);
|
||||
|
||||
if (!sourceRect || !parent || !parentRect) {
|
||||
return;
|
||||
}
|
||||
if (!sourceRect || !parent || !parentRect) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { x1, y1, x2, y2 } = calculateCoordinates(sourceRect, parentRect, info, target, transformScale);
|
||||
const midpoint = calculateMidpoint(x1, y1, x2, y2);
|
||||
const xDist = x2 - x1;
|
||||
const yDist = y2 - y1;
|
||||
const { x1, y1, x2, y2 } = calculateCoordinates(sourceRect, parentRect, info, target, transformScale);
|
||||
const midpoint = calculateMidpoint(x1, y1, x2, y2);
|
||||
const xDist = x2 - x1;
|
||||
const yDist = y2 - y1;
|
||||
|
||||
const { strokeColor, strokeWidth, strokeRadius, arrowDirection, lineStyle } = getConnectionStyles(
|
||||
info,
|
||||
scene,
|
||||
defaultArrowSize,
|
||||
defaultArrowDirection
|
||||
);
|
||||
const { strokeColor, strokeWidth, strokeRadius, arrowDirection, lineStyle } = getConnectionStyles(
|
||||
info,
|
||||
scene,
|
||||
defaultArrowSize,
|
||||
defaultArrowDirection
|
||||
);
|
||||
|
||||
const isSelected = selectedConnection === v && scene.panel.context.instanceState.selectedConnection;
|
||||
const isSelected = selectedConnection === v && scene.panel.context.instanceState.selectedConnection;
|
||||
|
||||
const connectionCursorStyle = scene.isEditingEnabled ? 'grab' : '';
|
||||
const selectedStyles = { stroke: '#44aaff', strokeOpacity: 0.6, strokeWidth: strokeWidth + 5 };
|
||||
const connectionCursorStyle = scene.isEditingEnabled ? 'grab' : '';
|
||||
const selectedStyles = { stroke: '#44aaff', strokeOpacity: 0.6, strokeWidth: strokeWidth + 5 };
|
||||
|
||||
const CONNECTION_HEAD_ID_START = `connectionHeadStart-${headId + Math.random()}`;
|
||||
const CONNECTION_HEAD_ID_END = `connectionHeadEnd-${headId + Math.random()}`;
|
||||
const CONNECTION_HEAD_ID_START = `connectionHeadStart-${headId + Math.random()}`;
|
||||
const CONNECTION_HEAD_ID_END = `connectionHeadEnd-${headId + Math.random()}`;
|
||||
|
||||
const radius = strokeRadius;
|
||||
// Create vertex path and populate array of add vertex controls
|
||||
const addVertices: ConnectionCoordinates[] = [];
|
||||
let pathString = `M${x1} ${y1} `;
|
||||
if (vertices?.length) {
|
||||
vertices.map((vertex, index) => {
|
||||
const x = vertex.x;
|
||||
const y = vertex.y;
|
||||
const radius = strokeRadius;
|
||||
// Create vertex path and populate array of add vertex controls
|
||||
const addVertices: ConnectionCoordinates[] = [];
|
||||
let pathString = `M${x1} ${y1} `;
|
||||
if (vertices?.length) {
|
||||
vertices.map((vertex, index) => {
|
||||
const x = vertex.x;
|
||||
const y = vertex.y;
|
||||
|
||||
// Convert vertex relative coordinates to scene coordinates
|
||||
const X = x * xDist + x1;
|
||||
const Y = y * yDist + y1;
|
||||
// Convert vertex relative coordinates to scene coordinates
|
||||
const X = x * xDist + x1;
|
||||
const Y = y * yDist + y1;
|
||||
|
||||
// Initialize coordinates for first arc control point
|
||||
let xa = X;
|
||||
let ya = Y;
|
||||
// Initialize coordinates for first arc control point
|
||||
let xa = X;
|
||||
let ya = Y;
|
||||
|
||||
// Initialize coordinates for second arc control point
|
||||
let xb = X;
|
||||
let yb = Y;
|
||||
// Initialize coordinates for second arc control point
|
||||
let xb = X;
|
||||
let yb = Y;
|
||||
|
||||
// Initialize half arc distance and segment angles
|
||||
let lHalfArc = 0;
|
||||
let angle1 = 0;
|
||||
let angle2 = 0;
|
||||
// Initialize half arc distance and segment angles
|
||||
let lHalfArc = 0;
|
||||
let angle1 = 0;
|
||||
let angle2 = 0;
|
||||
|
||||
// Only calculate arcs if there is a radius
|
||||
if (radius) {
|
||||
if (index < vertices.length - 1) {
|
||||
const Xn = vertices[index + 1].x * xDist + x1;
|
||||
const Yn = vertices[index + 1].y * yDist + y1;
|
||||
if (index === 0) {
|
||||
// First vertex
|
||||
angle1 = calculateAngle(x1, y1, X, Y);
|
||||
angle2 = calculateAngle(X, Y, Xn, Yn);
|
||||
} else {
|
||||
// All vertices
|
||||
const previousVertex = vertices[index - 1];
|
||||
const Xp = previousVertex.x * xDist + x1;
|
||||
const Yp = previousVertex.y * yDist + y1;
|
||||
angle1 = calculateAngle(Xp, Yp, X, Y);
|
||||
angle2 = calculateAngle(X, Y, Xn, Yn);
|
||||
}
|
||||
} else {
|
||||
// Last vertex
|
||||
let previousVertex = { x: 0, y: 0 };
|
||||
if (index > 0) {
|
||||
// Not also the first vertex
|
||||
previousVertex = vertices[index - 1];
|
||||
}
|
||||
const Xp = previousVertex.x * xDist + x1;
|
||||
const Yp = previousVertex.y * yDist + y1;
|
||||
angle1 = calculateAngle(Xp, Yp, X, Y);
|
||||
angle2 = calculateAngle(X, Y, x2, y2);
|
||||
}
|
||||
|
||||
// Calculate angle between two segments where arc will be placed
|
||||
const theta = angle2 - angle1; //radians
|
||||
// Attempt to determine if arc is counter clockwise (ccw)
|
||||
const ccw = theta < 0;
|
||||
// Half arc is used for arc control points
|
||||
lHalfArc = radius * Math.tan(theta / 2);
|
||||
if (ccw) {
|
||||
lHalfArc *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Only calculate arcs if there is a radius
|
||||
if (radius) {
|
||||
if (index < vertices.length - 1) {
|
||||
const Xn = vertices[index + 1].x * xDist + x1;
|
||||
const Yn = vertices[index + 1].y * yDist + y1;
|
||||
if (index === 0) {
|
||||
// First vertex
|
||||
angle1 = calculateAngle(x1, y1, X, Y);
|
||||
angle2 = calculateAngle(X, Y, Xn, Yn);
|
||||
// For first vertex
|
||||
addVertices.push(calculateMidpoint(0, 0, x, y));
|
||||
|
||||
// Only calculate arcs if there is a radius
|
||||
if (radius) {
|
||||
// Length of segment
|
||||
const lSegment = calculateDistance(X, Y, x1, y1);
|
||||
if (Math.abs(lHalfArc) > 0.5 * Math.abs(lSegment)) {
|
||||
// Limit curve control points to mid segment
|
||||
lHalfArc = 0.5 * lSegment;
|
||||
}
|
||||
// Default next point to last point
|
||||
let Xn = x2;
|
||||
let Yn = y2;
|
||||
if (index < vertices.length - 1) {
|
||||
// Not also the last point
|
||||
const nextVertex = vertices[index + 1];
|
||||
Xn = nextVertex.x * xDist + x1;
|
||||
Yn = nextVertex.y * yDist + y1;
|
||||
}
|
||||
|
||||
// Length of next segment
|
||||
const lSegmentNext = calculateDistance(X, Y, Xn, Yn);
|
||||
if (Math.abs(lHalfArc) > 0.5 * Math.abs(lSegmentNext)) {
|
||||
// Limit curve control points to mid segment
|
||||
lHalfArc = 0.5 * lSegmentNext;
|
||||
}
|
||||
// Calculate arc control points
|
||||
const lDelta = lSegment - lHalfArc;
|
||||
xa = lDelta * Math.cos(angle1) + x1;
|
||||
ya = lDelta * Math.sin(angle1) + y1;
|
||||
xb = lHalfArc * Math.cos(angle2) + X;
|
||||
yb = lHalfArc * Math.sin(angle2) + Y;
|
||||
|
||||
// Check if arc control points are inside of segment, otherwise swap sign
|
||||
if ((xa > X && xa > x1) || (xa < X && xa < x1)) {
|
||||
xa = (lDelta + 2 * lHalfArc) * Math.cos(angle1) + x1;
|
||||
ya = (lDelta + 2 * lHalfArc) * Math.sin(angle1) + y1;
|
||||
xb = -lHalfArc * Math.cos(angle2) + X;
|
||||
yb = -lHalfArc * Math.sin(angle2) + Y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// All vertices
|
||||
// For all other vertices
|
||||
const previousVertex = vertices[index - 1];
|
||||
const Xp = previousVertex.x * xDist + x1;
|
||||
const Yp = previousVertex.y * yDist + y1;
|
||||
angle1 = calculateAngle(Xp, Yp, X, Y);
|
||||
angle2 = calculateAngle(X, Y, Xn, Yn);
|
||||
}
|
||||
} else {
|
||||
// Last vertex
|
||||
let previousVertex = { x: 0, y: 0 };
|
||||
if (index > 0) {
|
||||
// Not also the first vertex
|
||||
previousVertex = vertices[index - 1];
|
||||
}
|
||||
const Xp = previousVertex.x * xDist + x1;
|
||||
const Yp = previousVertex.y * yDist + y1;
|
||||
angle1 = calculateAngle(Xp, Yp, X, Y);
|
||||
angle2 = calculateAngle(X, Y, x2, y2);
|
||||
}
|
||||
addVertices.push(calculateMidpoint(previousVertex.x, previousVertex.y, x, y));
|
||||
|
||||
// Calculate angle between two segments where arc will be placed
|
||||
const theta = angle2 - angle1; //radians
|
||||
// Attempt to determine if arc is counter clockwise (ccw)
|
||||
const ccw = theta < 0;
|
||||
// Half arc is used for arc control points
|
||||
lHalfArc = radius * Math.tan(theta / 2);
|
||||
if (ccw) {
|
||||
lHalfArc *= -1;
|
||||
}
|
||||
// Only calculate arcs if there is a radius
|
||||
if (radius) {
|
||||
// Convert previous vertex relative coorindates to scene coordinates
|
||||
const Xp = previousVertex.x * xDist + x1;
|
||||
const Yp = previousVertex.y * yDist + y1;
|
||||
|
||||
// Length of segment
|
||||
const lSegment = calculateDistance(X, Y, Xp, Yp);
|
||||
if (Math.abs(lHalfArc) > 0.5 * Math.abs(lSegment)) {
|
||||
// Limit curve control points to mid segment
|
||||
lHalfArc = 0.5 * lSegment;
|
||||
}
|
||||
// Default next point to last point
|
||||
let Xn = x2;
|
||||
let Yn = y2;
|
||||
if (index < vertices.length - 1) {
|
||||
// Not also the last point
|
||||
const nextVertex = vertices[index + 1];
|
||||
Xn = nextVertex.x * xDist + x1;
|
||||
Yn = nextVertex.y * yDist + y1;
|
||||
}
|
||||
|
||||
// Length of next segment
|
||||
const lSegmentNext = calculateDistance(X, Y, Xn, Yn);
|
||||
if (Math.abs(lHalfArc) > 0.5 * Math.abs(lSegmentNext)) {
|
||||
// Limit curve control points to mid segment
|
||||
lHalfArc = 0.5 * lSegmentNext;
|
||||
}
|
||||
|
||||
// Calculate arc control points
|
||||
const lDelta = lSegment - lHalfArc;
|
||||
xa = lDelta * Math.cos(angle1) + Xp;
|
||||
ya = lDelta * Math.sin(angle1) + Yp;
|
||||
xb = lHalfArc * Math.cos(angle2) + X;
|
||||
yb = lHalfArc * Math.sin(angle2) + Y;
|
||||
|
||||
// Check if arc control points are inside of segment, otherwise swap sign
|
||||
if ((xa > X && xa > Xp) || (xa < X && xa < Xp)) {
|
||||
xa = (lDelta + 2 * lHalfArc) * Math.cos(angle1) + Xp;
|
||||
ya = (lDelta + 2 * lHalfArc) * Math.sin(angle1) + Yp;
|
||||
xb = -lHalfArc * Math.cos(angle2) + X;
|
||||
yb = -lHalfArc * Math.sin(angle2) + Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (index === vertices.length - 1) {
|
||||
// For last vertex only
|
||||
addVertices.push(calculateMidpoint(1, 1, x, y));
|
||||
}
|
||||
// Add segment to path
|
||||
pathString += `L${xa} ${ya} `;
|
||||
|
||||
if (lHalfArc !== 0) {
|
||||
// Add arc if applicable
|
||||
pathString += `Q ${X} ${Y} ${xb} ${yb} `;
|
||||
}
|
||||
});
|
||||
// Add last segment
|
||||
pathString += `L${x2} ${y2}`;
|
||||
}
|
||||
|
||||
if (index === 0) {
|
||||
// For first vertex
|
||||
addVertices.push(calculateMidpoint(0, 0, x, y));
|
||||
const markerStart =
|
||||
arrowDirection === ConnectionDirection.Reverse || arrowDirection === ConnectionDirection.Both
|
||||
? `url(#${CONNECTION_HEAD_ID_START})`
|
||||
: undefined;
|
||||
|
||||
// Only calculate arcs if there is a radius
|
||||
if (radius) {
|
||||
// Length of segment
|
||||
const lSegment = calculateDistance(X, Y, x1, y1);
|
||||
if (Math.abs(lHalfArc) > 0.5 * Math.abs(lSegment)) {
|
||||
// Limit curve control points to mid segment
|
||||
lHalfArc = 0.5 * lSegment;
|
||||
}
|
||||
// Default next point to last point
|
||||
let Xn = x2;
|
||||
let Yn = y2;
|
||||
if (index < vertices.length - 1) {
|
||||
// Not also the last point
|
||||
const nextVertex = vertices[index + 1];
|
||||
Xn = nextVertex.x * xDist + x1;
|
||||
Yn = nextVertex.y * yDist + y1;
|
||||
}
|
||||
const markerEnd =
|
||||
arrowDirection === ConnectionDirection.Forward || arrowDirection === ConnectionDirection.Both
|
||||
? `url(#${CONNECTION_HEAD_ID_END})`
|
||||
: undefined;
|
||||
|
||||
// Length of next segment
|
||||
const lSegmentNext = calculateDistance(X, Y, Xn, Yn);
|
||||
if (Math.abs(lHalfArc) > 0.5 * Math.abs(lSegmentNext)) {
|
||||
// Limit curve control points to mid segment
|
||||
lHalfArc = 0.5 * lSegmentNext;
|
||||
}
|
||||
// Calculate arc control points
|
||||
const lDelta = lSegment - lHalfArc;
|
||||
xa = lDelta * Math.cos(angle1) + x1;
|
||||
ya = lDelta * Math.sin(angle1) + y1;
|
||||
xb = lHalfArc * Math.cos(angle2) + X;
|
||||
yb = lHalfArc * Math.sin(angle2) + Y;
|
||||
|
||||
// Check if arc control points are inside of segment, otherwise swap sign
|
||||
if ((xa > X && xa > x1) || (xa < X && xa < x1)) {
|
||||
xa = (lDelta + 2 * lHalfArc) * Math.cos(angle1) + x1;
|
||||
ya = (lDelta + 2 * lHalfArc) * Math.sin(angle1) + y1;
|
||||
xb = -lHalfArc * Math.cos(angle2) + X;
|
||||
yb = -lHalfArc * Math.sin(angle2) + Y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// For all other vertices
|
||||
const previousVertex = vertices[index - 1];
|
||||
addVertices.push(calculateMidpoint(previousVertex.x, previousVertex.y, x, y));
|
||||
|
||||
// Only calculate arcs if there is a radius
|
||||
if (radius) {
|
||||
// Convert previous vertex relative coorindates to scene coordinates
|
||||
const Xp = previousVertex.x * xDist + x1;
|
||||
const Yp = previousVertex.y * yDist + y1;
|
||||
|
||||
// Length of segment
|
||||
const lSegment = calculateDistance(X, Y, Xp, Yp);
|
||||
if (Math.abs(lHalfArc) > 0.5 * Math.abs(lSegment)) {
|
||||
// Limit curve control points to mid segment
|
||||
lHalfArc = 0.5 * lSegment;
|
||||
}
|
||||
// Default next point to last point
|
||||
let Xn = x2;
|
||||
let Yn = y2;
|
||||
if (index < vertices.length - 1) {
|
||||
// Not also the last point
|
||||
const nextVertex = vertices[index + 1];
|
||||
Xn = nextVertex.x * xDist + x1;
|
||||
Yn = nextVertex.y * yDist + y1;
|
||||
}
|
||||
|
||||
// Length of next segment
|
||||
const lSegmentNext = calculateDistance(X, Y, Xn, Yn);
|
||||
if (Math.abs(lHalfArc) > 0.5 * Math.abs(lSegmentNext)) {
|
||||
// Limit curve control points to mid segment
|
||||
lHalfArc = 0.5 * lSegmentNext;
|
||||
}
|
||||
|
||||
// Calculate arc control points
|
||||
const lDelta = lSegment - lHalfArc;
|
||||
xa = lDelta * Math.cos(angle1) + Xp;
|
||||
ya = lDelta * Math.sin(angle1) + Yp;
|
||||
xb = lHalfArc * Math.cos(angle2) + X;
|
||||
yb = lHalfArc * Math.sin(angle2) + Y;
|
||||
|
||||
// Check if arc control points are inside of segment, otherwise swap sign
|
||||
if ((xa > X && xa > Xp) || (xa < X && xa < Xp)) {
|
||||
xa = (lDelta + 2 * lHalfArc) * Math.cos(angle1) + Xp;
|
||||
ya = (lDelta + 2 * lHalfArc) * Math.sin(angle1) + Yp;
|
||||
xb = -lHalfArc * Math.cos(angle2) + X;
|
||||
yb = -lHalfArc * Math.sin(angle2) + Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (index === vertices.length - 1) {
|
||||
// For last vertex only
|
||||
addVertices.push(calculateMidpoint(1, 1, x, y));
|
||||
}
|
||||
// Add segment to path
|
||||
pathString += `L${xa} ${ya} `;
|
||||
|
||||
if (lHalfArc !== 0) {
|
||||
// Add arc if applicable
|
||||
pathString += `Q ${X} ${Y} ${xb} ${yb} `;
|
||||
}
|
||||
});
|
||||
// Add last segment
|
||||
pathString += `L${x2} ${y2}`;
|
||||
}
|
||||
|
||||
const markerStart =
|
||||
arrowDirection === ConnectionDirection.Reverse || arrowDirection === ConnectionDirection.Both
|
||||
? `url(#${CONNECTION_HEAD_ID_START})`
|
||||
: undefined;
|
||||
|
||||
const markerEnd =
|
||||
arrowDirection === ConnectionDirection.Forward || arrowDirection === ConnectionDirection.Both
|
||||
? `url(#${CONNECTION_HEAD_ID_END})`
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<svg className={styles.connection} key={idx}>
|
||||
<g onClick={() => selectConnection(v)}>
|
||||
<defs>
|
||||
<marker
|
||||
id={CONNECTION_HEAD_ID_START}
|
||||
markerWidth="10"
|
||||
markerHeight="7"
|
||||
refX="0"
|
||||
refY="3.5"
|
||||
orient="auto"
|
||||
stroke={strokeColor}
|
||||
>
|
||||
<polygon points="10 0, 0 3.5, 10 7" fill={strokeColor} />
|
||||
</marker>
|
||||
<marker
|
||||
id={CONNECTION_HEAD_ID_END}
|
||||
markerWidth="10"
|
||||
markerHeight="7"
|
||||
refX="10"
|
||||
refY="3.5"
|
||||
orient="auto"
|
||||
stroke={strokeColor}
|
||||
>
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill={strokeColor} />
|
||||
</marker>
|
||||
</defs>
|
||||
{vertices?.length ? (
|
||||
<g>
|
||||
<path
|
||||
id={`${CONNECTION_LINE_ID}_transparent`}
|
||||
d={pathString}
|
||||
cursor={connectionCursorStyle}
|
||||
pointerEvents="auto"
|
||||
stroke="transparent"
|
||||
strokeWidth={15}
|
||||
fill={'none'}
|
||||
style={isSelected ? selectedStyles : {}}
|
||||
/>
|
||||
<path
|
||||
d={pathString}
|
||||
stroke={strokeColor}
|
||||
strokeWidth={strokeWidth}
|
||||
strokeDasharray={lineStyle}
|
||||
fill={'none'}
|
||||
markerEnd={markerEnd}
|
||||
markerStart={markerStart}
|
||||
/>
|
||||
{isSelected && (
|
||||
return (
|
||||
<svg className={styles.connection} key={idx}>
|
||||
<g onClick={() => selectConnection(v)}>
|
||||
<defs>
|
||||
<marker
|
||||
id={CONNECTION_HEAD_ID_START}
|
||||
markerWidth="10"
|
||||
markerHeight="7"
|
||||
refX="0"
|
||||
refY="3.5"
|
||||
orient="auto"
|
||||
stroke={strokeColor}
|
||||
>
|
||||
<polygon points="10 0, 0 3.5, 10 7" fill={strokeColor} />
|
||||
</marker>
|
||||
<marker
|
||||
id={CONNECTION_HEAD_ID_END}
|
||||
markerWidth="10"
|
||||
markerHeight="7"
|
||||
refX="10"
|
||||
refY="3.5"
|
||||
orient="auto"
|
||||
stroke={strokeColor}
|
||||
>
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill={strokeColor} />
|
||||
</marker>
|
||||
</defs>
|
||||
{vertices?.length ? (
|
||||
<g>
|
||||
{vertices.map((value, index) => {
|
||||
const { x, y } = calculateAbsoluteCoords(x1, y1, x2, y2, value.x, value.y);
|
||||
return (
|
||||
<circle
|
||||
id={CONNECTION_VERTEX_ID}
|
||||
data-index={index}
|
||||
key={`${CONNECTION_VERTEX_ID}${index}_${idx}`}
|
||||
cx={x}
|
||||
cy={y}
|
||||
r={5}
|
||||
stroke={strokeColor}
|
||||
className={styles.vertex}
|
||||
cursor={'crosshair'}
|
||||
pointerEvents="auto"
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{vertices.length < maximumVertices &&
|
||||
addVertices.map((value, index) => {
|
||||
const { x, y } = calculateAbsoluteCoords(x1, y1, x2, y2, value.x, value.y);
|
||||
return (
|
||||
<circle
|
||||
id={CONNECTION_VERTEX_ADD_ID}
|
||||
data-index={index}
|
||||
key={`${CONNECTION_VERTEX_ADD_ID}${index}_${idx}`}
|
||||
cx={x}
|
||||
cy={y}
|
||||
r={4}
|
||||
stroke={strokeColor}
|
||||
className={styles.addVertex}
|
||||
cursor={'crosshair'}
|
||||
pointerEvents="auto"
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<path
|
||||
id={`${CONNECTION_LINE_ID}_transparent`}
|
||||
d={pathString}
|
||||
cursor={connectionCursorStyle}
|
||||
pointerEvents="auto"
|
||||
stroke="transparent"
|
||||
strokeWidth={15}
|
||||
fill={'none'}
|
||||
style={isSelected ? selectedStyles : {}}
|
||||
/>
|
||||
<path
|
||||
d={pathString}
|
||||
stroke={strokeColor}
|
||||
strokeWidth={strokeWidth}
|
||||
strokeDasharray={lineStyle}
|
||||
fill={'none'}
|
||||
markerEnd={markerEnd}
|
||||
markerStart={markerStart}
|
||||
/>
|
||||
{isSelected && (
|
||||
<g>
|
||||
{vertices.map((value, index) => {
|
||||
const { x, y } = calculateAbsoluteCoords(x1, y1, x2, y2, value.x, value.y);
|
||||
return (
|
||||
<circle
|
||||
id={CONNECTION_VERTEX_ID}
|
||||
data-index={index}
|
||||
key={`${CONNECTION_VERTEX_ID}${index}_${idx}`}
|
||||
cx={x}
|
||||
cy={y}
|
||||
r={5}
|
||||
stroke={strokeColor}
|
||||
className={styles.vertex}
|
||||
cursor={'crosshair'}
|
||||
pointerEvents="auto"
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{vertices.length < maximumVertices &&
|
||||
addVertices.map((value, index) => {
|
||||
const { x, y } = calculateAbsoluteCoords(x1, y1, x2, y2, value.x, value.y);
|
||||
return (
|
||||
<circle
|
||||
id={CONNECTION_VERTEX_ADD_ID}
|
||||
data-index={index}
|
||||
key={`${CONNECTION_VERTEX_ADD_ID}${index}_${idx}`}
|
||||
cx={x}
|
||||
cy={y}
|
||||
r={4}
|
||||
stroke={strokeColor}
|
||||
className={styles.addVertex}
|
||||
cursor={'crosshair'}
|
||||
pointerEvents="auto"
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</g>
|
||||
)}
|
||||
</g>
|
||||
) : (
|
||||
<g>
|
||||
<line
|
||||
id={`${CONNECTION_LINE_ID}_transparent`}
|
||||
cursor={connectionCursorStyle}
|
||||
pointerEvents="auto"
|
||||
stroke="transparent"
|
||||
strokeWidth={15}
|
||||
style={isSelected ? selectedStyles : {}}
|
||||
x1={x1}
|
||||
y1={y1}
|
||||
x2={x2}
|
||||
y2={y2}
|
||||
/>
|
||||
<line
|
||||
id={CONNECTION_LINE_ID}
|
||||
stroke={strokeColor}
|
||||
pointerEvents="auto"
|
||||
strokeWidth={strokeWidth}
|
||||
markerEnd={markerEnd}
|
||||
markerStart={markerStart}
|
||||
strokeDasharray={lineStyle}
|
||||
x1={x1}
|
||||
y1={y1}
|
||||
x2={x2}
|
||||
y2={y2}
|
||||
cursor={connectionCursorStyle}
|
||||
/>
|
||||
{isSelected && (
|
||||
<circle
|
||||
id={CONNECTION_VERTEX_ADD_ID}
|
||||
data-index={0}
|
||||
cx={midpoint.x}
|
||||
cy={midpoint.y}
|
||||
r={4}
|
||||
stroke={strokeColor}
|
||||
className={styles.addVertex}
|
||||
cursor={'crosshair'}
|
||||
pointerEvents="auto"
|
||||
/>
|
||||
)}
|
||||
</g>
|
||||
)}
|
||||
</g>
|
||||
) : (
|
||||
<g>
|
||||
<line
|
||||
id={`${CONNECTION_LINE_ID}_transparent`}
|
||||
cursor={connectionCursorStyle}
|
||||
pointerEvents="auto"
|
||||
stroke="transparent"
|
||||
strokeWidth={15}
|
||||
style={isSelected ? selectedStyles : {}}
|
||||
x1={x1}
|
||||
y1={y1}
|
||||
x2={x2}
|
||||
y2={y2}
|
||||
/>
|
||||
<line
|
||||
id={CONNECTION_LINE_ID}
|
||||
stroke={strokeColor}
|
||||
pointerEvents="auto"
|
||||
strokeWidth={strokeWidth}
|
||||
markerEnd={markerEnd}
|
||||
markerStart={markerStart}
|
||||
strokeDasharray={lineStyle}
|
||||
x1={x1}
|
||||
y1={y1}
|
||||
x2={x2}
|
||||
y2={y2}
|
||||
cursor={connectionCursorStyle}
|
||||
/>
|
||||
{isSelected && (
|
||||
<circle
|
||||
id={CONNECTION_VERTEX_ADD_ID}
|
||||
data-index={0}
|
||||
cx={midpoint.x}
|
||||
cy={midpoint.y}
|
||||
r={4}
|
||||
stroke={strokeColor}
|
||||
className={styles.addVertex}
|
||||
cursor={'crosshair'}
|
||||
pointerEvents="auto"
|
||||
/>
|
||||
)}
|
||||
</g>
|
||||
)}
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
});
|
||||
</svg>
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user