@deck.gl-community/layers
Version:
Add-on layers for deck.gl
171 lines • 7.31 kB
JavaScript
// deck.gl-community
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import { CompositeLayer } from '@deck.gl/core';
import { ArcLayer, LineLayer, PathLayer } from '@deck.gl/layers';
import { createPathMarkers, PathDirection } from "./create-path-markers.js";
import { GeometryLayer } from "./geometry-layer.js";
export { PathDirection };
const defaultProps = {
getPath: PathLayer.defaultProps.getPath,
getColor: LineLayer.defaultProps.getColor,
getWidth: LineLayer.defaultProps.getWidth,
widthUnits: LineLayer.defaultProps.widthUnits,
widthScale: LineLayer.defaultProps.widthScale,
widthMinPixels: LineLayer.defaultProps.widthMinPixels,
widthMaxPixels: LineLayer.defaultProps.widthMaxPixels,
arcNumSegments: ArcLayer.defaultProps.numSegments,
getArcHeight: ArcLayer.defaultProps.getHeight,
getArcTilt: ArcLayer.defaultProps.getTilt,
mode: 'path',
markerSizeScale: 10,
highlightIndex: -1,
highlightPoint: null,
getMarkerColor: { type: 'accessor', value: undefined },
getDirection: { type: 'accessor', value: PathDirection.FORWARD },
getMarkerSize: { type: 'accessor', value: [1, 1] },
getMarkerPlacements: { type: 'accessor', value: [0.5] }
};
/** Renders paths, lines, or arcs with directional dependency markers. */
export class DependencyArrowLayer extends CompositeLayer {
static layerName = 'DependencyArrowLayer';
static defaultProps = defaultProps;
state = {
markers: []
};
updateState({ props, oldProps, changeFlags }) {
const shouldRebuildMarkers = changeFlags.dataChanged ||
props.mode !== oldProps.mode ||
props.positionFormat !== oldProps.positionFormat ||
props.getPath !== oldProps.getPath ||
props.getDirection !== oldProps.getDirection ||
props.getMarkerPlacements !== oldProps.getMarkerPlacements ||
(changeFlags.updateTriggersChanged &&
(changeFlags.updateTriggersChanged['getPath'] ||
changeFlags.updateTriggersChanged['getDirection'] ||
changeFlags.updateTriggersChanged['getMarkerPlacements']));
if (shouldRebuildMarkers) {
const { data, mode, getPath, getDirection, getMarkerPlacements } = this.props;
this.state.markers = createPathMarkers({
data: data,
positionSize: props.positionFormat.length,
getPath,
getDirection,
getMarkerPlacements,
mode
});
}
}
getPickingInfo({ info }) {
const pickedObject = info.object;
if (pickedObject && pickedObject.__source) {
info.object = pickedObject.__source.object;
}
return info;
}
renderLayers() {
const { mode, getPath, getColor, getMarkerColor, getMarkerSize, markerSizeScale, updateTriggers = {} } = this.props;
let pathLayer = null;
if (mode === 'path') {
pathLayer = new PathLayer(this.props, this.getSubLayerProps({
id: 'links-path',
updateTriggers: {
getPath: updateTriggers['getPath'],
getColor: updateTriggers['getColor'],
getWidth: updateTriggers['getWidth']
}
}));
}
else {
const positionSize = this.props.positionFormat.length;
const sharedProps = {
...this.props,
data: this.props.data,
getSourcePosition: (datum, info) => {
const path = getPath(datum, info);
return getFirstPoint(path, positionSize) ?? [NaN, NaN];
},
getTargetPosition: (datum, info) => {
const path = getPath(datum, info);
return getLastPoint(path, positionSize) ?? [NaN, NaN];
}
};
if (mode === 'arc') {
pathLayer = new ArcLayer(sharedProps, {
getSourceColor: this.props.getColor,
getTargetColor: this.props.getColor,
numSegments: this.props.arcNumSegments,
getHeight: this.props.getArcHeight,
getTilt: this.props.getArcTilt
}, this.getSubLayerProps({
id: 'links-arc',
updateTriggers: {
getSourcePosition: updateTriggers['getPath'],
getTargetPosition: updateTriggers['getPath'],
getSourceColor: updateTriggers['getColor'],
getTargetColor: updateTriggers['getColor'],
getWidth: updateTriggers['getWidth'],
getHeight: updateTriggers['getArcHeight'],
getTilt: updateTriggers['getArcTilt']
}
}));
}
else {
pathLayer = new LineLayer(sharedProps, this.getSubLayerProps({
id: 'links-line',
updateTriggers: {
getSourcePosition: updateTriggers['getPath'],
getTargetPosition: updateTriggers['getPath'],
getColor: updateTriggers['getColor'],
getWidth: updateTriggers['getWidth']
}
}));
}
}
return [
pathLayer,
new GeometryLayer(this.getSubLayerProps({
id: 'arrows',
updateTriggers: {
getSize: updateTriggers['getMarkerSize'],
getColor: getMarkerColor
? updateTriggers['getMarkerColor']
: updateTriggers['getColor'],
getArcHeight: updateTriggers['getArcHeight'],
getArcTilt: updateTriggers['getArcTilt']
}
}), {
data: this.state.markers,
sizeUnits: 'pixels',
sizeScale: markerSizeScale,
interpolationMode: mode === 'arc' ? 'arc' : 'line',
getSourcePosition: d => d.source,
getTargetPosition: d => d.target,
getPositionRatio: d => d.percentage,
getSize: this.getSubLayerAccessor(getMarkerSize),
getColor: this.getSubLayerAccessor(getMarkerColor ?? getColor),
getArcHeight: this.getSubLayerAccessor(this.props.getArcHeight),
getArcTilt: this.getSubLayerAccessor(this.props.getArcTilt),
getPickingColor: d => this.encodePickingColor(d.__source.index)
})
];
}
}
function getFirstPoint(path, size) {
if (!path || path.length === 0)
return null;
if (Array.isArray(path[0])) {
return path[0];
}
return path.slice(0, size);
}
function getLastPoint(path, size) {
if (!path || path.length === 0)
return null;
if (Array.isArray(path[0])) {
return path[path.length - 1];
}
const len = Math.floor(path.length / size) * size;
return path.slice(len - size, len);
}
//# sourceMappingURL=dependency-arrow-layer.js.map