feat(markers): add more properties for custom markers

This commit is contained in:
Christopher Möller
2021-10-15 11:51:54 +02:00
parent d3b1148bca
commit 1b73c8fff5
3 changed files with 37 additions and 27 deletions
+6 -2
View File
@@ -56,7 +56,12 @@ const initialElements: Elements = [
labelStyle: { fill: 'red', fontWeight: 700 }, labelStyle: { fill: 'red', fontWeight: 700 },
style: { stroke: '#ffcc00' }, style: { stroke: '#ffcc00' },
markerEnd: { markerEnd: {
type: ArrowHeadType.ArrowClosed, type: ArrowHeadType.Arrow,
color: '#FFCC00',
units: 'userSpaceOnUse',
width: 20,
height: 20,
strokeWidth: 2,
}, },
markerStart: { markerStart: {
type: ArrowHeadType.Arrow, type: ArrowHeadType.Arrow,
@@ -73,7 +78,6 @@ const initialElements: Elements = [
labelBgStyle: { fill: '#FFCC00', color: '#fff', fillOpacity: 0.7 }, labelBgStyle: { fill: '#FFCC00', color: '#fff', fillOpacity: 0.7 },
markerEnd: { markerEnd: {
type: ArrowHeadType.ArrowClosed, type: ArrowHeadType.ArrowClosed,
color: '#FFCC00',
}, },
}, },
{ {
@@ -2,43 +2,35 @@ import React, { useMemo } from 'react';
import { useStoreState } from '../../store/hooks'; import { useStoreState } from '../../store/hooks';
import { EdgeMarker, ArrowHeadType } from '../../types'; import { EdgeMarker, ArrowHeadType } from '../../types';
import { getMarkerId } from '../../utils/graph'; import { getMarkerId } from '../../utils/graph';
interface MarkerProps { interface MarkerProps extends EdgeMarker {
id: string; id: string;
type: ArrowHeadType;
color: string;
} }
interface MarkerDefinitionsProps { interface MarkerDefinitionsProps {
defaultColor: string; defaultColor: string;
} }
interface SymbolProps { type SymbolProps = Omit<MarkerProps, 'id' | 'type'>;
color: string;
}
interface EdgeMarkerExtended extends EdgeMarker { const ArrowSymbol = ({ color = 'none', strokeWidth = 1 }: SymbolProps) => {
id: string;
}
const ArrowSymbol = ({ color }: SymbolProps) => {
return ( return (
<polyline <polyline
stroke={color} stroke={color}
strokeLinecap="round" strokeLinecap="round"
strokeLinejoin="round" strokeLinejoin="round"
strokeWidth="1" strokeWidth={strokeWidth}
fill={color} fill="none"
points="-5,-4 0,0 -5,4 -5,-4" points="-5,-4 0,0 -5,4"
/> />
); );
}; };
const ArrowClosedSymbol = ({ color }: SymbolProps) => { const ArrowClosedSymbol = ({ color = 'none', strokeWidth = 1 }: SymbolProps) => {
return ( return (
<polyline <polyline
stroke={color} stroke={color}
strokeLinecap="round" strokeLinecap="round"
strokeLinejoin="round" strokeLinejoin="round"
strokeWidth="1" strokeWidth={strokeWidth}
fill={color} fill={color}
points="-5,-4 0,0 -5,4 -5,-4" points="-5,-4 0,0 -5,4 -5,-4"
/> />
@@ -50,21 +42,22 @@ const markerSymbols = {
[ArrowHeadType.ArrowClosed]: ArrowClosedSymbol, [ArrowHeadType.ArrowClosed]: ArrowClosedSymbol,
}; };
const Marker = ({ id, type, color }: MarkerProps) => { const Marker = ({ id, type, color, width = 12.5, height = 12.5, units = 'strokeWidth', strokeWidth }: MarkerProps) => {
const Symbol = markerSymbols[type]; const Symbol = markerSymbols[type];
return ( return (
<marker <marker
className="react-flow__arrowhead" className="react-flow__arrowhead"
id={id} id={id}
markerWidth="12.5" markerUnits={units}
markerHeight="12.5" markerWidth={`${width}`}
markerHeight={`${height}`}
viewBox="-10 -10 20 20" viewBox="-10 -10 20 20"
orient="auto" orient="auto"
refX="0" refX="0"
refY="0" refY="0"
> >
<Symbol color={color} /> <Symbol color={color} strokeWidth={strokeWidth} />
</marker> </marker>
); );
}; };
@@ -74,24 +67,33 @@ const MarkerDefinitions = ({ defaultColor }: MarkerDefinitionsProps) => {
const markers = useMemo(() => { const markers = useMemo(() => {
const ids: string[] = []; const ids: string[] = [];
return edges.reduce<EdgeMarkerExtended[]>((markers, edge) => { return edges.reduce<MarkerProps[]>((markers, edge) => {
[edge.markerStart, edge.markerEnd].forEach((marker) => { [edge.markerStart, edge.markerEnd].forEach((marker) => {
if (marker && typeof marker === 'object') { if (marker && typeof marker === 'object') {
const markerId = getMarkerId(marker); const markerId = getMarkerId(marker);
if (!ids.includes(markerId)) { if (!ids.includes(markerId)) {
markers.push({ id: markerId, ...marker }); markers.push({ id: markerId, color: marker.color || defaultColor, ...marker });
ids.push(markerId); ids.push(markerId);
} }
} }
}); });
return markers.sort((a, b) => a.id.localeCompare(b.id)); return markers.sort((a, b) => a.id.localeCompare(b.id));
}, []); }, []);
}, [edges]); }, [edges, defaultColor]);
return ( return (
<defs> <defs>
{markers.map((marker: EdgeMarkerExtended) => ( {markers.map((marker: MarkerProps) => (
<Marker id={marker.id} key={marker.id} type={marker.type} color={marker.color || defaultColor} /> <Marker
id={marker.id}
key={marker.id}
type={marker.type}
color={marker.color}
width={marker.width}
height={marker.height}
units={marker.units}
strokeWidth={marker.strokeWidth}
/>
))} ))}
</defs> </defs>
); );
+4
View File
@@ -60,6 +60,10 @@ export enum ArrowHeadType {
export interface EdgeMarker { export interface EdgeMarker {
type: ArrowHeadType; type: ArrowHeadType;
color?: string; color?: string;
width?: number;
height?: number;
units?: 'userSpaceOnUse' | 'strokeWidth';
strokeWidth?: number;
} }
export type EdgeMarkerType = string | EdgeMarker; export type EdgeMarkerType = string | EdgeMarker;