import React from 'react'; import { CompositeLayer } from 'deck.gl'; import { IconLayer, LineLayer, ScatterplotLayer, TextLayer } from '@deck.gl/layers'; import { LayerProps } from '../../mapvis.types'; import { BrushingExtension, CollisionFilterExtension } from '@deck.gl/extensions'; import { Edge, Node } from '@graphpolaris/shared/lib/data-access'; import { createIcon } from './shapeFactory'; export class NodeLinkLayer extends CompositeLayer<LayerProps> { static type = 'NodeLink'; updateState({ changeFlags }: { changeFlags: any }) { return changeFlags.propsOrDataChanged || changeFlags.somethingChanged; } renderLayers() { const { graph, config, getNodeLocation, selected, setLayerIds, metaData } = this.props; const layers = []; const layerIds = []; const brushingExtension = new BrushingExtension(); const collisionFilter = new CollisionFilterExtension(); metaData.nodes.labels.forEach((label: string) => { const layerId = `${label}-nodes-scatterplot`; layerIds.push(layerId); layers.push( new IconLayer({ id: layerId, visible: !config[label].hidden, data: graph.nodes.filter((node: Node) => node.label === label), pickable: true, getColor: (d) => [200, 140, 0], getSize: (d: any) => config[label].size, getPosition: (d: any) => getNodeLocation(d._id), getIcon: (d: any) => { return { url: createIcon(config[label].shape ?? 'circle', config[label].color), width: 24, height: 24, }; }, mask: true, }), ); }); metaData.edges.labels.forEach((label: string) => { const layerId = `${label}-edges-line`; layerIds.push(layerId); const edgeData = selected.length > 0 ? graph.edges.filter((edge: Edge) => selected.includes(edge.from) || selected.includes(edge.to)) : graph.edges; layers.push( new LineLayer({ id: layerId, data: edgeData, visible: !config[label]?.hidden, pickable: true, getWidth: (d: any) => config[label].width, getSourcePosition: (d: any) => getNodeLocation(d.from), getTargetPosition: (d: any) => getNodeLocation(d.to), getColor: (d: any) => config[d.label].color, radiusScale: 3000, brushingEnabled: config.enableBrushing, extensions: [brushingExtension], }), ); }); const textLayerId = 'label-target'; layerIds.push(textLayerId); layers.push( new TextLayer({ id: textLayerId, data: graph.nodes, getPosition: (d: any) => getNodeLocation(d._id), getText: (d: any) => d.id, getSize: 15, visible: true, getAlignmentBaseline: 'top', background: true, getPixelOffset: [10, 10], extensions: [collisionFilter], collisionEnabled: true, getCollisionPriority: (d: any) => d.id, collisionTestProps: { sizeScale: 10 }, getRadius: 10, radiusUnits: 'pixels', collisionGroup: 'text', }), ); setLayerIds(layerIds); return layers; } } NodeLinkLayer.layerName = 'NodeLink';