diff --git a/libs/shared/lib/vis/visualizations/mapvis/layers/heatmap-layer/HeatLayerOptions.tsx b/libs/shared/lib/vis/visualizations/mapvis/layers/heatmap-layer/HeatLayerOptions.tsx index 37487054729e54a587db6b0ad8aa3b820e767b2d..2007d3330d08f32dac4d3330ed5e30ea764e845e 100644 --- a/libs/shared/lib/vis/visualizations/mapvis/layers/heatmap-layer/HeatLayerOptions.tsx +++ b/libs/shared/lib/vis/visualizations/mapvis/layers/heatmap-layer/HeatLayerOptions.tsx @@ -1,8 +1,8 @@ import React, { useState, useMemo, useEffect } from 'react'; import { VisualizationSettingsPropTypes } from '@graphpolaris/shared/lib/vis/common'; import { MapProps } from '../../mapvis'; -import { EntityPill, Icon, Input } from '@graphpolaris/shared/lib/components'; -import { SubdirectoryArrowRight } from '@mui/icons-material'; +import { Button, EntityPill, Icon, Input } from '@graphpolaris/shared/lib/components'; +import { SubdirectoryArrowRight, Visibility, VisibilityOff } from '@mui/icons-material'; export default function HeatLayerOptions({ settings, graphMetadata, updateSettings }: VisualizationSettingsPropTypes<MapProps>) { const [collapsed, setCollapsed] = useState<Record<string, boolean>>({}); @@ -49,10 +49,13 @@ export default function HeatLayerOptions({ settings, graphMetadata, updateSettin <EntityPill title={nodeType} /> </div> <div className="w-1/2"> - {/* <ColorPicker - value={settings?.[nodeType]?.['color'] ? settings?.[nodeType]?.['color'] : [0, 0, 0]} - updateValue={(val: number[]) => updateSettings({ [nodeType]: { ...settings?.[nodeType], color: val } })} - /> */} + <Button + iconComponent={settings?.[nodeType].hidden ? <VisibilityOff /> : <Visibility />} + variant="ghost" + onClick={() => { + updateSettings({ [nodeType]: { ...settings?.[nodeType], hidden: !settings?.[nodeType].hidden as boolean } }); + }} + /> </div> </div> @@ -77,18 +80,6 @@ export default function HeatLayerOptions({ settings, graphMetadata, updateSettin disabled={!settings.node || spatialAttributes[nodeType].length < 1} onChange={(val) => updateSettings({ [nodeType]: { ...settings?.[nodeType], lat: val as string } })} /> - - <div className="ml-2"> - <div className="flex items-center gap-1"> - <Icon component={<SubdirectoryArrowRight />} size={16} color="text-secondary-300" /> - <Input - label="Hidden" - type="boolean" - value={settings?.[nodeType]?.hidden ?? false} - onChange={(val: boolean) => updateSettings({ [nodeType]: { ...settings?.[nodeType], hidden: val } })} - /> - </div> - </div> </div> )} </div> diff --git a/libs/shared/lib/vis/visualizations/mapvis/layers/index.tsx b/libs/shared/lib/vis/visualizations/mapvis/layers/index.tsx index bda96ae30a91b354b55031cf06043ab8189c4cd3..fc09070cc0043dde9c39f5386b87c0a0bd191164 100644 --- a/libs/shared/lib/vis/visualizations/mapvis/layers/index.tsx +++ b/libs/shared/lib/vis/visualizations/mapvis/layers/index.tsx @@ -11,18 +11,18 @@ import ChoroplethOptions from './choropleth-layer/ChoroplethOptions'; import { TileLayer, BitmapLayer } from 'deck.gl'; export const layerTypes: Record<string, any> = { - node: NodeLayer, - icon: NodeIconLayer, + // node: NodeLayer, + // icon: NodeIconLayer, nodelink: NodeLinkLayer, heatmap: HeatLayer, // choropleth: ChoroplethLayer, }; export const layerSettings: Record<string, any> = { - node: NodeOptions, nodelink: NodeLinkOptions, - icon: IconOptions, heatmap: HeatLayerOptions, + // node: NodeOptions, + // icon: IconOptions, // choropleth: ChoroplethOptions, }; diff --git a/libs/shared/lib/vis/visualizations/mapvis/layers/nodelink-layer/NodeLinkLayer.tsx b/libs/shared/lib/vis/visualizations/mapvis/layers/nodelink-layer/NodeLinkLayer.tsx index 97bc58e72ca4c0eb4b71296c154093555980478a..25677d43268c75f489a1ad26e4b1373b42e8fa1c 100644 --- a/libs/shared/lib/vis/visualizations/mapvis/layers/nodelink-layer/NodeLinkLayer.tsx +++ b/libs/shared/lib/vis/visualizations/mapvis/layers/nodelink-layer/NodeLinkLayer.tsx @@ -1,9 +1,10 @@ import React from 'react'; import { CompositeLayer } from 'deck.gl'; -import { LineLayer, ScatterplotLayer, TextLayer } from '@deck.gl/layers'; +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'; @@ -26,19 +27,22 @@ export class NodeLinkLayer extends CompositeLayer<LayerProps> { layerIds.push(layerId); layers.push( - new ScatterplotLayer({ + new IconLayer({ id: layerId, visible: !config[label].hidden, data: graph.nodes.filter((node: Node) => node.label === label), pickable: true, - filled: true, - radiusScale: 6, - radiusMinPixels: 7, - radiusMaxPixels: 100, - lineWidthMinPixels: 1, + getColor: (d) => [200, 140, 0], + getSize: (d: any) => config[label].size, getPosition: (d: any) => getNodeLocation(d._id), - getFillColor: (d: any) => config[label].color, - getRadius: (d: any) => 5, + getIcon: (d: any) => { + return { + url: createIcon(config[label].shape ?? 'circle', config[label].color), + width: 24, + height: 24, + }; + }, + mask: true, }), ); }); @@ -54,6 +58,7 @@ export class NodeLinkLayer extends CompositeLayer<LayerProps> { new LineLayer({ id: layerId, data: edgeData, + visible: !config[label].hidden, pickable: true, getWidth: (d: any) => config[label].width, getSourcePosition: (d: any) => getNodeLocation(d.from), diff --git a/libs/shared/lib/vis/visualizations/mapvis/layers/nodelink-layer/NodeLinkOptions.tsx b/libs/shared/lib/vis/visualizations/mapvis/layers/nodelink-layer/NodeLinkOptions.tsx index abab54f011a4ee126b17a7faefa68734189407eb..07d7e97f877b71e3267fe6b6a7213a280278f22f 100644 --- a/libs/shared/lib/vis/visualizations/mapvis/layers/nodelink-layer/NodeLinkOptions.tsx +++ b/libs/shared/lib/vis/visualizations/mapvis/layers/nodelink-layer/NodeLinkOptions.tsx @@ -1,9 +1,10 @@ -import React, { useState, useMemo, useEffect } from 'react'; +import React, { useState, useEffect } from 'react'; import ColorPicker from '@graphpolaris/shared/lib/components/colorComponents/colorPicker'; import { VisualizationSettingsPropTypes } from '@graphpolaris/shared/lib/vis/common'; import { MapProps } from '../../mapvis'; -import { EntityPill, Icon, Input, RelationPill } from '@graphpolaris/shared/lib/components'; -import { SubdirectoryArrowRight } from '@mui/icons-material'; +import { Button, EntityPill, Icon, Input, RelationPill } from '@graphpolaris/shared/lib/components'; +import { SubdirectoryArrowRight, Visibility, VisibilityOff } from '@mui/icons-material'; +import { IconButton } from '@graphpolaris/shared/lib/components/buttons/button.stories'; export default function NodeLinkOptions({ settings, graphMetadata, updateSettings }: VisualizationSettingsPropTypes<MapProps>) { const [collapsed, setCollapsed] = useState<Record<string, boolean>>({}); @@ -14,6 +15,8 @@ export default function NodeLinkOptions({ settings, graphMetadata, updateSetting [node]: { color: [0, 0, 0], hidden: false, + shape: '', + size: 10, fixed: true, min: 0, max: 10, @@ -60,14 +63,21 @@ export default function NodeLinkOptions({ settings, graphMetadata, updateSetting {graphMetadata.nodes.labels.map((nodeType) => ( <div className="mt-2" key={nodeType}> <div className="flex items-center"> - <div className="w-3/4 mr-6 cursor-pointer" onClick={() => handleCollapseToggle(nodeType)}> + <div className="flex flex-grow mr-2 cursor-pointer" onClick={() => handleCollapseToggle(nodeType)}> <EntityPill title={nodeType} /> </div> - <div className="w-1/2"> + <div className="flex items-center space-x-2"> <ColorPicker value={settings?.[nodeType]?.['color'] ? settings?.[nodeType]?.['color'] : [0, 0, 0]} updateValue={(val: number[]) => updateSettings({ [nodeType]: { ...settings?.[nodeType], color: val } })} /> + <Button + iconComponent={settings?.[nodeType].hidden ? <VisibilityOff /> : <Visibility />} + variant="ghost" + onClick={() => { + updateSettings({ [nodeType]: { ...settings?.[nodeType], hidden: !settings?.[nodeType].hidden as boolean } }); + }} + /> </div> </div> @@ -92,6 +102,24 @@ export default function NodeLinkOptions({ settings, graphMetadata, updateSetting disabled={!settings.node || spatialAttributes[nodeType].length < 1} onChange={(val) => updateSettings({ [nodeType]: { ...settings?.[nodeType], lat: val as string } })} /> + <Input + inline + label="Shape" + type="dropdown" + value={settings?.[nodeType]?.shape} + options={['circle', 'square', 'triangle', 'diamond', 'location', 'star']} + disabled={!settings.shape} + onChange={(val) => updateSettings({ [nodeType]: { ...settings?.[nodeType], shape: val as string } })} + /> + <Input + label="Size" + type="slider" + min={0} + max={20} + step={1} + value={settings?.[nodeType]?.size} + onChange={(val) => updateSettings({ [nodeType]: { ...settings?.[nodeType], size: val as number } })} + /> </div> )} </div> @@ -99,15 +127,22 @@ export default function NodeLinkOptions({ settings, graphMetadata, updateSetting {graphMetadata.edges.labels.map((edgeType) => ( <div className="mt-2" key={edgeType}> - <div className="flex items-center" onClick={() => handleCollapseToggle(edgeType)}> - <div className="w-3/4 mr-6 cursor-pointer"> + <div className="flex items-center"> + <div className="w-3/4 mr-6 cursor-pointer" onClick={() => handleCollapseToggle(edgeType)}> <RelationPill title={edgeType} /> </div> - <div className="w-1/2"> + <div className="w-1/2 flex"> <ColorPicker value={settings?.[edgeType]?.['color'] ? settings?.[edgeType]?.['color'] : [0, 0, 0]} updateValue={(val: number[]) => updateSettings({ [edgeType]: { ...settings?.[edgeType], color: val } })} /> + <Button + iconComponent={settings?.[edgeType].hidden ? <VisibilityOff /> : <Visibility />} + variant="ghost" + onClick={() => { + updateSettings({ [edgeType]: { ...settings?.[edgeType], hidden: !settings?.[edgeType].hidden as boolean } }); + }} + /> </div> </div> diff --git a/libs/shared/lib/vis/visualizations/mapvis/mapvis.stories.tsx b/libs/shared/lib/vis/visualizations/mapvis/mapvis.stories.tsx index 6fbf525ffb05220bc199b1f7cbb2de6e8e865344..a590ae956f3d990858c7682507bbc6b4ee56bbdf 100644 --- a/libs/shared/lib/vis/visualizations/mapvis/mapvis.stories.tsx +++ b/libs/shared/lib/vis/visualizations/mapvis/mapvis.stories.tsx @@ -34,64 +34,6 @@ const Component: Meta<typeof MapComponent.component> = { ], }; -export const Node = { - args: { - ...(await mockData.mockMobilityQueryResult()), - settings: { - layer: 'node', - parkings: { - color: [6, 147, 227], - fixed: true, - hidden: false, - lat: 'lat', - lon: 'long', - max: 10, - min: 0, - radius: 1, - sizeAttribute: '', - }, - rides: { - color: [6, 147, 227], - fixed: true, - hidden: false, - max: 10, - min: 0, - width: 1, - widthAttribute: '', - }, - }, - }, -}; - -export const Icon = { - args: { - ...(await mockData.mockMobilityQueryResult()), - settings: { - layer: 'icon', - parkings: { - color: [6, 147, 227], - fixed: true, - hidden: false, - lat: 'lat', - lon: 'long', - max: 10, - min: 0, - radius: 1, - sizeAttribute: '', - }, - rides: { - color: [6, 147, 227], - fixed: true, - hidden: false, - max: 10, - min: 0, - width: 1, - widthAttribute: '', - }, - }, - }, -}; - export const NodeLink = { args: { ...(await mockData.mockMobilityQueryResult()),