Skip to content
Snippets Groups Projects
Commit dcf3d1ad authored by Leonardo's avatar Leonardo Committed by Vink, S.A. (Sjoerd)
Browse files

feat(map_nodelink): added nodelink layer

parent 8b3a332c
No related branches found
No related tags found
1 merge request!151feat(map_nodelink)
import React, { useMemo } from 'react';
import { SettingsContainer } from '../../components/config';
import { layerTypes } from './components/layers';
import { EntityPill, Input } from '../../..';
import { VisualizationSettingsPropTypes } from '../../common';
import { MapProps } from './mapvis';
import { nodeColorHex } from '../nodelinkvis/components/utils';
const DataLayerSettings = ({
layer,
settings,
graphMetadata,
updateSettings,
}: VisualizationSettingsPropTypes<MapProps> & { layer: keyof typeof layerTypes }) => {
switch (layer) {
case 'nodelink':
return (
<>
{graphMetadata.nodes.labels.map((item, index) => (
<div className="flex m-1 items-center" key={item}>
<div className="w-3/4 mr-6">
<EntityPill title={item} />
</div>
<div className="w-1/2">
<div className={`h-5 w-5 border-2 border-sec-300`} style={{ backgroundColor: nodeColorHex(index + 1) }}></div>
</div>
</div>
))}
<Input
label="Enable brushing"
type="boolean"
value={settings.enableBrushing}
onChange={(val) => {
console.log('update brush', val);
updateSettings({ enableBrushing: val as boolean });
}}
/>
</>
);
default:
return;
}
};
export const MapSettings = ({ settings, graphMetadata, updateSettings }: VisualizationSettingsPropTypes<MapProps>) => {
const spatialAttributes = useMemo(() => {
if (!settings.node || !(Object.keys(graphMetadata.nodes.types).length > 0)) return [];
return Object.entries(graphMetadata.nodes.types[settings.node].attributes).map((kv) => kv[0]);
}, [settings.node]);
return (
<SettingsContainer>
<Input
label="Data layer"
type="dropdown"
inline
value={settings.layer}
options={Object.keys(layerTypes)}
onChange={(val) => updateSettings({ layer: val as string })}
/>
<Input
label="Node Label"
type="dropdown"
inline
value={settings.node}
options={[...Object.keys(graphMetadata.nodes.types)]}
disabled={Object.keys(graphMetadata.nodes.types).length < 1}
onChange={(val) => {
updateSettings({ node: val as string });
}}
/>
<Input
label="Latitude Location"
type="dropdown"
inline
value={settings.lat}
options={[...spatialAttributes]}
disabled={!settings.node || spatialAttributes.length < 1}
onChange={(val) => updateSettings({ lat: val as string })}
/>
<Input
inline
label="Longitude Location accessor"
type="dropdown"
value={settings.lon}
options={[...spatialAttributes]}
disabled={!settings.node || spatialAttributes.length < 1}
onChange={(val) => updateSettings({ lon: val as string })}
/>
<DataLayerSettings layer={settings.layer} settings={settings} graphMetadata={graphMetadata} updateSettings={updateSettings} />
</SettingsContainer>
);
};
import { ChoroplethLayer } from './choropleth-layer/newChoroplethLayer';
import { HeatLayer } from './heatmap-layer/HeatLayer';
import { NodeLinkLayer } from './nodelink-layer/NodeLinkLayer';
import { NodeLayer } from './node-layer/NodeLayer';
import { NodeIconLayer } from './icon-layer/IconLayer';
export const layerTypes: Record<string, any> = {
node: NodeLayer,
icon: NodeIconLayer,
nodelink: NodeLinkLayer,
choropleth: ChoroplethLayer,
heatmap: HeatLayer,
};
import React from 'react';
import { CompositeLayer } from 'deck.gl';
import { LineLayer, ScatterplotLayer, TextLayer } from '@deck.gl/layers';
import { LayerProps } from '../../../mapvis.types';
import { BrushingExtension, CollisionFilterExtension } from '@deck.gl/extensions';
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;
shouldUpdateState({ props, oldProps, context, changeFlags }: { props: any; oldProps: any; context: any; changeFlags: any }) {
return changeFlags.propsChanged;
}
renderLayers() {
const { graph, config, visible, getNodeLocation, selected } = this.props;
const layers = [];
const brushingExtension = new BrushingExtension();
const collisionFilter = new CollisionFilterExtension();
layers.push(
new ScatterplotLayer({
hidden: visible,
data: graph.nodes,
pickable: true,
radiusScale: 6,
radiusMinPixels: 7,
radiusMaxPixels: 100,
lineWidthMinPixels: 1,
getPosition: (d: any) => getNodeLocation(d.id),
getFillColor: (d: any) => {
if (d.label === 'PERSON') {
return [182, 154, 239];
} else if (d.label === 'INCIDENT') {
return [169, 25, 25];
}
return [0, 0, 0];
},
getRadius: (d: any) => 5,
}),
);
layers.push(
new LineLayer({
id: 'edges',
data: graph.edges,
pickable: true,
getWidth: (d: any) => 2,
getSourcePosition: (d: any) => getNodeLocation(d.from),
getTargetPosition: (d: any) => getNodeLocation(d.to),
getColor: (d: any) => [145, 168, 208],
radiusScale: 3000,
brushingEnabled: config.enableBrushing,
extensions: [brushingExtension],
}),
);
layers.push(
new TextLayer({
id: 'label-target',
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',
}),
);
return [...layers];
}
}
NodeLinkLayer.layerName = 'NodeLink';
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment