chore: 修改渲染设置
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useEffect, useRef, useMemo } from 'react';
|
||||
import { Graph } from '@antv/g6';
|
||||
import type { GraphData, Node, Edge, GraphLayoutConfig } from '../../types/graph';
|
||||
import { getNodeColors } from '../../config/colors';
|
||||
import { FORCE_LAYOUT_CONFIG, GRAPH_BEHAVIORS } from '../../config/layout';
|
||||
import { GRAPH_DEFAULT_HEIGHT } from '../../config/constants';
|
||||
import { getNodeStyle, getEdgeStyle } from '../../utils/graphStyle';
|
||||
|
||||
interface GraphViewProps {
|
||||
data: GraphData;
|
||||
@@ -30,6 +31,8 @@ export const GraphView = ({
|
||||
|
||||
const onNodeClickRef = useRef(onNodeClick);
|
||||
|
||||
const nodeMap = useMemo(() => new Map(data.nodes.map((node: Node) => [node.id, node])), [data.nodes]);
|
||||
|
||||
useEffect(() => {
|
||||
onNodeClickRef.current = onNodeClick;
|
||||
}, [onNodeClick]);
|
||||
@@ -69,26 +72,27 @@ export const GraphView = ({
|
||||
},
|
||||
};
|
||||
}),
|
||||
edges: data.edges.map((edge: Edge) => ({
|
||||
id: edge.id,
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
label: edge.label,
|
||||
data: {
|
||||
edges: data.edges.map((edge: Edge) => {
|
||||
return {
|
||||
id: edge.id,
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
label: edge.label,
|
||||
type: edge.type,
|
||||
properties: edge.properties,
|
||||
},
|
||||
style: {
|
||||
stroke: '#95A5A6',
|
||||
lineWidth: 2,
|
||||
labelText: edge.label,
|
||||
labelFill: '#666',
|
||||
labelFontSize: 10,
|
||||
},
|
||||
})),
|
||||
data: {
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
label: edge.label,
|
||||
type: edge.type,
|
||||
properties: edge.properties,
|
||||
},
|
||||
style: {
|
||||
stroke: '#95A5A6',
|
||||
labelText: edge.label,
|
||||
labelFill: '#666',
|
||||
labelFontSize: 10,
|
||||
},
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
// 创建图谱配置
|
||||
@@ -101,8 +105,8 @@ export const GraphView = ({
|
||||
node: {
|
||||
type: 'circle',
|
||||
style: {
|
||||
size: 50,
|
||||
lineWidth: 2,
|
||||
...getNodeStyle(),
|
||||
},
|
||||
state: {
|
||||
selected: {
|
||||
@@ -117,13 +121,12 @@ export const GraphView = ({
|
||||
edge: {
|
||||
type: 'line',
|
||||
style: {
|
||||
lineWidth: 1,
|
||||
endArrow: true,
|
||||
...getEdgeStyle(nodeMap),
|
||||
},
|
||||
state: {
|
||||
selected: {
|
||||
stroke: '#1890FF',
|
||||
lineWidth: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -5,5 +5,20 @@ export const API_TIMEOUT = 10000;
|
||||
// 图谱渲染配置
|
||||
export const GRAPH_DEFAULT_HEIGHT = 600;
|
||||
|
||||
// 节点大小配置
|
||||
export const DEFAULT_NODE_SIZE = 50;
|
||||
export const NODE_SIZE_MIN = 10;
|
||||
export const NODE_SIZE_MAX = 60;
|
||||
|
||||
// 边宽度配置
|
||||
export const DEFAULT_EDGE_WIDTH = 1.5;
|
||||
export const EDGE_WIDTH_MIN = 1;
|
||||
export const EDGE_WIDTH_MAX = 2;
|
||||
|
||||
// Importance 配置
|
||||
export const IMPORTANCE_DEFAULT = 0.8;
|
||||
export const IMPORTANCE_MIN = 0;
|
||||
export const IMPORTANCE_MAX = 1;
|
||||
|
||||
// 搜索相关常量
|
||||
export const SEARCH_RESULT_MAX_HEIGHT = 256; // 16rem
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import type { Node } from '../types/graph';
|
||||
import {
|
||||
NODE_SIZE_MIN,
|
||||
NODE_SIZE_MAX,
|
||||
EDGE_WIDTH_MIN,
|
||||
EDGE_WIDTH_MAX,
|
||||
IMPORTANCE_MIN,
|
||||
IMPORTANCE_MAX,
|
||||
} from '../config/constants';
|
||||
|
||||
/**
|
||||
* 归一化值到 [0,1] 范围
|
||||
*/
|
||||
function normalizeValue(value: number, min: number, max: number): number {
|
||||
if (isNaN(value) || !isFinite(value)) {
|
||||
return 0.5;
|
||||
}
|
||||
const clamped = Math.max(min, Math.min(max, value));
|
||||
return (clamped - min) / (max - min);
|
||||
}
|
||||
|
||||
/**
|
||||
* 反归一化值从 [0,1] 到目标范围
|
||||
*/
|
||||
function denormalizeValue(value: number, min: number, max: number): number {
|
||||
if (isNaN(value) || !isFinite(value)) {
|
||||
return (min + max) / 2;
|
||||
}
|
||||
const clamped = Math.max(0, Math.min(1, value));
|
||||
return clamped * (max - min) + min;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算节点大小
|
||||
*/
|
||||
export function calculateNodeSize(properties?: any): number {
|
||||
const importance = properties?.importance ?? IMPORTANCE_MAX;
|
||||
const normalized = normalizeValue(importance, IMPORTANCE_MIN, IMPORTANCE_MAX);
|
||||
const size = denormalizeValue(normalized, NODE_SIZE_MIN, NODE_SIZE_MAX) ?? NODE_SIZE_MIN;
|
||||
return Math.round(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算边的宽度
|
||||
*/
|
||||
export function calculateEdgeWidth(sourceProperties?: any, targetProperties?: any): number {
|
||||
const sourceImportance = sourceProperties?.importance ?? IMPORTANCE_MAX;
|
||||
const targetImportance = targetProperties?.importance ?? IMPORTANCE_MAX;
|
||||
const avgImportance = (sourceImportance + targetImportance) / 2;
|
||||
const normalized = normalizeValue(avgImportance, IMPORTANCE_MIN, IMPORTANCE_MAX);
|
||||
const width = denormalizeValue(normalized, EDGE_WIDTH_MIN, EDGE_WIDTH_MAX) ?? EDGE_WIDTH_MIN;
|
||||
return parseFloat(width.toFixed(2));
|
||||
}
|
||||
|
||||
/**
|
||||
* G6 节点动态样式配置函数
|
||||
* 根据 G6 文档推荐的动态配置方式实现
|
||||
*/
|
||||
export const getNodeStyle = () => ({
|
||||
size: (datum: any) => {
|
||||
const size = calculateNodeSize(datum.data?.properties);
|
||||
return size;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* G6 边动态样式配置函数
|
||||
* 根据 G6 文档推荐的动态配置方式实现
|
||||
*/
|
||||
export const getEdgeStyle = (nodeMap: Map<string, Node>) => ({
|
||||
lineWidth: (datum: any) => {
|
||||
const sourceNode = nodeMap.get(datum.source);
|
||||
const targetNode = nodeMap.get(datum.target);
|
||||
return calculateEdgeWidth(sourceNode?.properties, targetNode?.properties);
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user