Skip to content
Snippets Groups Projects

feat(map_nodelink)

Merged Vink, S.A. (Sjoerd) requested to merge feat/map_nodelink into main
3 files
+ 207
0
Compare changes
  • Side-by-side
  • Inline
Files
3
import React from 'react';
import { CompositeLayer } from 'deck.gl';
import { IconLayer, LineLayer, TextLayer } from '@deck.gl/layers';
import NodeLinkOptions from './NodeLinkOptions';
import { createIcon } from './shapeFactory';
import { getProperty } from '../../../utlis';
import { Edge, Node, LayerProps } from '../../../mapvis.types';
export const NodeLinkConfig = {
showLabels: false,
nodeShapeDynamic: false,
shapeAccessor: '',
iconMapping: {},
colorMapping: {},
edgesOnHover: true,
nodeSizeDynamic: true,
nodeSize: 2,
edgeWidth: 1.5,
};
export class NodeLinkLayer extends CompositeLayer<LayerProps> {
static type = 'NodeLink';
static layerOptions = NodeLinkConfig;
static generateLayerOptions(layer: any, updatedLayer: void, graphInfo: { [key: string]: any }, deleteLayer: void) {
return <NodeLinkOptions layer={layer} updatedLayer={updatedLayer} graphInfo={graphInfo} deleteLayer={deleteLayer} />;
}
shouldUpdateState({ props, oldProps, context, changeFlags }: { props: any; oldProps: any; context: any; changeFlags: any }) {
return changeFlags.propsChanged;
}
updateState({ props, oldProps, context, changeFlags }: { props: any; oldProps: any; context: any; changeFlags: any }) {
console.log(props, oldProps, context, changeFlags);
}
renderLayers() {
const { graph, config, visible, isSelecting, hoverObject } = this.props;
// if (!visible) return;
const layers = [];
layers.push(
new IconLayer(
this.getSubLayerProps({
id: 'all-nodes',
data: graph.getNodes().filter((node: Node) => !this.props.selected.includes(node)),
pickable: true,
sizeScale: 5,
getSize: (d: any) => (config.nodeSizeDynamic ? Math.min(d.connectedEdges.length, 5) : config.nodeSize),
opacity: this.props.selected.length > 0 ? 0.05 : 1,
getPosition: (d: any) => [d.attributes.long, d.attributes.lat],
getIcon: (d: any) => {
const shapeProperty = getProperty(d, `attributes.${this.props.config.shapeAccessor}`);
const shape = this.props.config.iconMapping[shapeProperty];
const color = this.props.config.colorMapping[shapeProperty] || [255, 125, 0];
return {
url: createIcon(shape, color),
width: 24,
height: 24,
};
},
mask: true,
}),
),
);
if (this.props.selected.length > 0) {
const edges = graph.getEdges().filter((edge: Edge) => new Set(this.props.selected.map((node: Node) => node.id)).has(edge.from));
const nodes = edges.map((edge: Edge) => graph.getNode(edge.to));
layers.push([
new IconLayer(
this.getSubLayerProps({
id: 'selected-nodes',
data: this.props.selected,
pickable: true,
sizeScale: 5,
getSize: (d: any) => (config.nodeSizeDynamic ? Math.min(d.connectedEdges.length, 5) : config.nodeSize),
opacity: 1,
getPosition: (d: any) => [d.attributes.long, d.attributes.lat],
getIcon: (d: any) => {
const shapeProperty = getProperty(d, `attributes.${this.props.config.shapeAccessor}`);
const shape = this.props.config.iconMapping[shapeProperty];
const color = this.props.config.colorMapping[shapeProperty] || [255, 125, 0];
return {
url: createIcon(shape, color),
width: 24,
height: 24,
};
},
mask: true,
getColor: (d: any) => [200, 140, 0],
}),
),
new IconLayer(
this.getSubLayerProps({
id: 'target-nodes',
data: nodes,
pickable: true,
sizeScale: 5,
getSize: (d: any) => (config.nodeSizeDynamic ? Math.min(d.connectedEdges.length, 5) : config.nodeSize),
opacity: 1,
getPosition: (d: any) => [d.attributes.long, d.attributes.lat],
getIcon: (d: any) => {
const shapeProperty = getProperty(d, `attributes.${this.props.config.shapeAccessor}`);
const shape = this.props.config.iconMapping[shapeProperty];
const color = this.props.config.colorMapping[shapeProperty] || [255, 125, 0];
return {
url: createIcon(shape, color),
width: 24,
height: 24,
};
},
mask: true,
getColor: (d: any) => [200, 140, 0],
}),
),
new LineLayer(
this.getSubLayerProps({
id: 'edges',
data: edges,
pickable: true,
getWidth: (d: any) => config.edgeWidth,
getSourcePosition: (d: any) => graph.getNodeLocation(d.from),
getTargetPosition: (d: any) => graph.getNodeLocation(d.to),
getColor: (d: any) => [0, 0, 0],
}),
),
new TextLayer(
this.getSubLayerProps({
id: 'label-selected',
data: this.props.selected,
getPosition: (d: any) => [d.attributes.long, d.attributes.lat],
getText: (d: any) => d.id,
getSize: 15,
visible: config.showLabels,
getAlignmentBaseline: 'top',
background: true,
getBackgroundColor: [255, 125, 0],
getPixelOffset: [10, 10],
}),
),
new TextLayer(
this.getSubLayerProps({
id: 'label-target',
data: nodes,
getPosition: (d: any) => [d.attributes.long, d.attributes.lat],
getText: (d: any) => d.id,
getSize: 15,
visible: config.showLabels,
getAlignmentBaseline: 'top',
background: true,
getPixelOffset: [10, 10],
}),
),
]);
}
if (hoverObject && config.edgesOnHover) {
layers.push(
new LineLayer(
this.getSubLayerProps({
id: 'edges-hover',
data: graph.getEdges().filter((edge: Edge) => edge.from === hoverObject.id),
pickable: true,
getWidth: (d: any) => config.edgeWidth,
getSourcePosition: (d: any) => graph.getNodeLocation(d.from),
getTargetPosition: (d: any) => graph.getNodeLocation(d.to),
getColor: (d: any) => [0, 0, 0],
}),
),
);
}
return [...layers];
}
}
NodeLinkLayer.layerName = 'NodeLink';
Loading