UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

90 lines (77 loc) 2.36 kB
import { type JSONObject, type KeyValue, ObjectExt } from '../../common' import type { CellView } from '../../view' import { markerRegistry } from '../marker' import type { AttrDefinition, ComplexAttrs, SimpleAttrs } from './index' function qualify(value: any) { return typeof value === 'string' || ObjectExt.isPlainObject(value) } export const sourceMarker: AttrDefinition = { qualify, set(marker: string | JSONObject, { view, attrs }) { return createMarker('marker-start', marker, view, attrs) }, } export const targetMarker: AttrDefinition = { qualify, set(marker: string | JSONObject, { view, attrs }) { return createMarker('marker-end', marker, view, attrs, { transform: 'rotate(180)', }) }, } export const vertexMarker: AttrDefinition = { qualify, set(marker: string | JSONObject, { view, attrs }) { return createMarker('marker-mid', marker, view, attrs) }, } function createMarker( type: 'marker-start' | 'marker-end' | 'marker-mid', marker: string | JSONObject, view: CellView, attrs: ComplexAttrs, manual: SimpleAttrs = {}, ) { const def = typeof marker === 'string' ? { name: marker } : marker const { name, args, ...others } = def let preset = others if (name && typeof name === 'string') { const fn = markerRegistry.get(name) if (fn) { preset = fn({ ...others, ...(args as KeyValue) }) } else { return markerRegistry.onNotFound(name) } } const options: any = { ...normalizeAttr(attrs, type), ...manual, ...preset, } return { [type]: `url(#${view.graph.defineMarker(options)})`, } } function normalizeAttr( attr: ComplexAttrs, type: 'marker-start' | 'marker-end' | 'marker-mid', ) { const result: SimpleAttrs = {} // The context 'fill' is disregared here. The usual case is to use the // marker with a connection(for which 'fill' attribute is set to 'none'). const stroke = attr.stroke if (typeof stroke === 'string') { result.stroke = stroke result.fill = stroke } if (type !== 'marker-mid') { const strokeWidth = parseFloat( (attr.strokeWidth || attr['stroke-width']) as string, ) if (Number.isFinite(strokeWidth) && strokeWidth > 1) { const offset = Math.ceil(strokeWidth / 2) result.refX = type === 'marker-start' ? offset : -offset } } return result }