diff --git a/packages/gi-assets-algorithm/src/NodesSimilarity/Component.tsx b/packages/gi-assets-algorithm/src/NodesSimilarity/Component.tsx index 685c4dc0a..09feb12e5 100644 --- a/packages/gi-assets-algorithm/src/NodesSimilarity/Component.tsx +++ b/packages/gi-assets-algorithm/src/NodesSimilarity/Component.tsx @@ -19,10 +19,11 @@ export interface CommunityDiscoveryProps extends NodeFormatProps { onOpen?: () => void; nodeSelectionMode: string[]; nodeLabel: string; + filter?: (node: any) => boolean; } export enum NodesSimilarityAlgorithm { - nodesConsineSimilarity = 'nodes-cosine-similarity', + nodesCosineSimilarity = 'nodes-cosine-similarity', } interface ResData { @@ -30,12 +31,12 @@ interface ResData { similarNodes: any[] | undefined; } const CommunityDiscovery: React.FC = props => { - const { controlledValues, style = {}, onOpen, nodeSelectionMode, nodeLabel, labelFormat } = props; + const { controlledValues, style = {}, onOpen, nodeSelectionMode, nodeLabel, labelFormat, filter } = props; const { data, graph, updateHistory } = useContext(); - const [communityAlgo, setCommunityAlgo] = useState(NodesSimilarityAlgorithm.nodesConsineSimilarity); + const [communityAlgo, setCommunityAlgo] = useState(NodesSimilarityAlgorithm.nodesCosineSimilarity); const [initData, setInitData] = useState({ nodes: [], edges: [] }); - const [similarityAlgo, setSimilarityAlgo] = useState(NodesSimilarityAlgorithm.nodesConsineSimilarity); + const [similarityAlgo, setSimilarityAlgo] = useState(NodesSimilarityAlgorithm.nodesCosineSimilarity); const [resData, setResData] = useState({ similarityRes: [], similarNodes: [] }); const [hasAnalysis, setHasAnalysis] = useState(false); const [seedNodeId, setSeedNodeId] = useState(null); @@ -176,7 +177,7 @@ const CommunityDiscovery: React.FC = props => { const { seed } = await form.validateFields(); setSeedNodeId(seed); switch (algorithm || similarityAlgo) { - case NodesSimilarityAlgorithm.nodesConsineSimilarity: + case NodesSimilarityAlgorithm.nodesCosineSimilarity: if (!graph || graph.destroyed) { handleUpdateHistory( false, @@ -243,7 +244,7 @@ const CommunityDiscovery: React.FC = props => { ); } - if (similarityAlgo === NodesSimilarityAlgorithm.nodesConsineSimilarity) { + if (similarityAlgo === NodesSimilarityAlgorithm.nodesCosineSimilarity) { return (
@@ -259,7 +260,7 @@ const CommunityDiscovery: React.FC = props => { form.resetFields(); resetMapping([], []); setResData({ similarityRes: [], similarNodes: [] }); - setCommunityAlgo(NodesSimilarityAlgorithm.nodesConsineSimilarity); + setCommunityAlgo(NodesSimilarityAlgorithm.nodesCosineSimilarity); setTopReset(true); }; @@ -286,6 +287,7 @@ const CommunityDiscovery: React.FC = props => { }), }, ]} + filter={filter} data={data.nodes} labelFormat={labelFormat} nodeLabel={nodeLabel} diff --git a/packages/gi-assets-basic/src/components/PathAnalysis/Component.tsx b/packages/gi-assets-basic/src/components/PathAnalysis/Component.tsx index 876b1d3e2..bff689941 100644 --- a/packages/gi-assets-basic/src/components/PathAnalysis/Component.tsx +++ b/packages/gi-assets-basic/src/components/PathAnalysis/Component.tsx @@ -1,6 +1,6 @@ import { CaretRightOutlined } from '@ant-design/icons'; import { findShortestPath } from '@antv/algorithm'; -import { NodeSelectionWrap } from '@antv/gi-common-components'; +import { NodeSelectionWrap, getNodeSelectionLabel } from '@antv/gi-common-components'; import type { NodeFormatProps } from '@antv/gi-common-components'; import { useContext } from '@antv/gi-sdk'; import { Button, Col, Collapse, Empty, Form, InputNumber, Row, Space, Switch, Timeline, message } from 'antd'; @@ -27,6 +27,7 @@ export interface IPathAnalysisProps extends NodeFormatProps { direction: string; }; onOpen: () => void; + filter?: (node: any) => boolean; } enableMapSet(); @@ -40,6 +41,7 @@ const PathAnalysis: React.FC = props => { hasMaxDeep, hasDirection, labelFormat, + filter, } = props; const { data: graphData, graph, sourceDataMap, updateHistory } = useContext(); @@ -344,6 +346,7 @@ const PathAnalysis: React.FC = props => { graph={graph} form={form} items={items} + filter={filter} data={graphData.nodes} labelFormat={labelFormat} nodeLabel={pathNodeLabel} @@ -426,7 +429,11 @@ const PathAnalysis: React.FC = props => { {path.map(nodeId => { const nodeConfig = sourceDataMap.nodes[nodeId]; const data = nodeConfig?.data || {}; - return {data[pathNodeLabel] || nodeId}; + return ( + + {getNodeSelectionLabel(data, { nodeLabel: pathNodeLabel, labelFormat }) || nodeId} + + ); })} diff --git a/packages/gi-common-components/src/NodeSelectionWrap/index.tsx b/packages/gi-common-components/src/NodeSelectionWrap/index.tsx index 80b0076a0..4b7953ca6 100644 --- a/packages/gi-common-components/src/NodeSelectionWrap/index.tsx +++ b/packages/gi-common-components/src/NodeSelectionWrap/index.tsx @@ -91,6 +91,7 @@ interface NodeSelectionProps extends NodeFormatProps { data: Record[]; nodeLabel: string; nodeSelectionMode: string[]; + filter?: (node: any) => boolean; } interface NodeSelectionWrapProps extends NodeSelectionProps { @@ -110,6 +111,31 @@ interface NodeSelectionFormItemProps extends NodeSelectionProps { setSelecting: React.Dispatch>; } +export const getNodeSelectionLabel = ( + node: Record, + config: Pick, +) => { + const { nodeLabel, labelFormat } = config; + const value = node[nodeLabel]; + + const getByKey = (key: string) => node[key] ?? node.data[key]; + + if (!labelFormat?.enable) return {value}; + const { mainLabel, subLabel } = labelFormat; + const mainLabelText: string = mainLabel && getByKey(mainLabel[0]); + const subLabelText: string = subLabel && getByKey(subLabel[0]); + + if (!mainLabelText && !subLabelText) return {value}; + if (!mainLabelText) return {subLabelText}; + if (!subLabelText) return {mainLabelText}; + return ( + <> + {mainLabelText} + ({subLabelText}) + + ); +}; + let nodeClickListener = e => {}; const NodeSelectionFormItem: React.FC = memo(props => { @@ -127,6 +153,7 @@ const NodeSelectionFormItem: React.FC = memo(props = color, showDot, labelFormat, + filter, } = props; const isList = nodeSelectionMode.includes(NodeSelectionMode.List); const isCanvas = nodeSelectionMode.includes(NodeSelectionMode.Canvas); @@ -171,32 +198,18 @@ const NodeSelectionFormItem: React.FC = memo(props = onChange={() => { setSelecting(''); }} - options={data.map(node => { - const value = node[nodeLabel]; - - const getLabel = () => { - const getByKey = (key: string) => node[key] ?? node.data[key]; - - if (!labelFormat?.enable) return {value}; - const { mainLabel, subLabel } = labelFormat; - const mainLabelText: string = mainLabel && getByKey(mainLabel[0]); - const subLabelText: string = subLabel && getByKey(subLabel[0]); - - if (!mainLabelText && !subLabelText) return {value}; - if (!mainLabelText) return {subLabelText}; - if (!subLabelText) return {mainLabelText}; - return ( - <> - {mainLabelText} - ({subLabelText}) - - ); - }; + options={data + .filter(node => { + if (filter) return filter(node); + return true; + }) + .map(node => { + const value = node[nodeLabel]; - const label = getLabel(); + const label = getNodeSelectionLabel(node, { nodeLabel, labelFormat }); - return { label, value }; - })} + return { label, value }; + })} {...selectProps} /> @@ -222,7 +235,7 @@ const NodeSelectionFormItem: React.FC = memo(props = }); const NodeSelectionWrap: React.FC = memo(props => { - const { graph, nodeSelectionMode, nodeLabel, items, form, data, labelFormat } = props; + const { graph, nodeSelectionMode, nodeLabel, items, form, data, labelFormat, filter } = props; const [selecting, setSelecting] = useState(''); const colors = ['#1650FF', '#FFC53D']; const handleSwap = async () => { @@ -242,6 +255,7 @@ const NodeSelectionWrap: React.FC = memo(props => { name={item.name} label={item.label} data={data} + filter={filter} nodeLabel={nodeLabel} labelFormat={labelFormat} nodeSelectionMode={nodeSelectionMode} diff --git a/packages/gi-common-components/src/index.ts b/packages/gi-common-components/src/index.ts index d86395d36..92da217ea 100644 --- a/packages/gi-common-components/src/index.ts +++ b/packages/gi-common-components/src/index.ts @@ -17,5 +17,10 @@ export { Icon, icons, registerIconFonts } from './Icon/index'; export { default as RadiusTabs } from './RadiusTabs'; export { default as SchemaField } from './SchemaField'; export { default as Utils } from './Utils'; -export { default as NodeSelectionWrap, NodeSelectionMode, getNodeFormatOption } from './NodeSelectionWrap'; +export { + default as NodeSelectionWrap, + NodeSelectionMode, + getNodeFormatOption, + getNodeSelectionLabel, +} from './NodeSelectionWrap'; export type { NodeFormatProps } from './NodeSelectionWrap';