Ensure seamless toggling between selected labels and the complete graph
This commit is contained in:
@@ -50,9 +50,17 @@ const GraphLabels = () => {
|
|||||||
[getSearchEngine]
|
[getSearchEngine]
|
||||||
)
|
)
|
||||||
|
|
||||||
const setQueryLabel = useCallback((label: string) => {
|
const setQueryLabel = useCallback((newLabel: string) => {
|
||||||
if (label.startsWith('And ') && label.endsWith(' others')) return
|
if (newLabel.startsWith('And ') && newLabel.endsWith(' others')) return
|
||||||
useSettingsStore.getState().setQueryLabel(label)
|
|
||||||
|
const currentLabel = useSettingsStore.getState().queryLabel
|
||||||
|
|
||||||
|
// When selecting the same label (except '*'), switch to '*'
|
||||||
|
if (newLabel === currentLabel && newLabel !== '*') {
|
||||||
|
useSettingsStore.getState().setQueryLabel('*')
|
||||||
|
} else {
|
||||||
|
useSettingsStore.getState().setQueryLabel(newLabel)
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -70,6 +78,7 @@ const GraphLabels = () => {
|
|||||||
placeholder="Search labels..."
|
placeholder="Search labels..."
|
||||||
value={label !== null ? label : ''}
|
value={label !== null ? label : ''}
|
||||||
onChange={setQueryLabel}
|
onChange={setQueryLabel}
|
||||||
|
clearable={false} // Prevent clearing value on reselect
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import Graph, { DirectedGraph } from 'graphology'
|
import Graph, { DirectedGraph } from 'graphology'
|
||||||
import { useCallback, useEffect } from 'react'
|
import { useCallback, useEffect, useRef } from 'react'
|
||||||
import { randomColor, errorMessage } from '@/lib/utils'
|
import { randomColor, errorMessage } from '@/lib/utils'
|
||||||
import * as Constants from '@/lib/constants'
|
import * as Constants from '@/lib/constants'
|
||||||
import { useGraphStore, RawGraph } from '@/stores/graph'
|
import { useGraphStore, RawGraph } from '@/stores/graph'
|
||||||
@@ -161,9 +161,9 @@ const createSigmaGraph = (rawGraph: RawGraph | null) => {
|
|||||||
return graph
|
return graph
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastQueryLabel = { label: '', maxQueryDepth: 0, minDegree: 0 }
|
|
||||||
|
|
||||||
const useLightrangeGraph = () => {
|
const useLightrangeGraph = () => {
|
||||||
|
// Use useRef to maintain lastQueryLabel state between renders
|
||||||
|
const lastQueryLabelRef = useRef({ label: '', maxQueryDepth: 0, minDegree: 0 })
|
||||||
const queryLabel = useSettingsStore.use.queryLabel()
|
const queryLabel = useSettingsStore.use.queryLabel()
|
||||||
const rawGraph = useGraphStore.use.rawGraph()
|
const rawGraph = useGraphStore.use.rawGraph()
|
||||||
const sigmaGraph = useGraphStore.use.sigmaGraph()
|
const sigmaGraph = useGraphStore.use.sigmaGraph()
|
||||||
@@ -188,37 +188,44 @@ const useLightrangeGraph = () => {
|
|||||||
if (queryLabel) {
|
if (queryLabel) {
|
||||||
// Always fetch data for "*" label
|
// Always fetch data for "*" label
|
||||||
// For other labels, only fetch when parameters change
|
// For other labels, only fetch when parameters change
|
||||||
const shouldUpdate = queryLabel === '*' ||
|
const shouldUpdate = true;
|
||||||
lastQueryLabel.label !== queryLabel ||
|
|
||||||
lastQueryLabel.maxQueryDepth !== maxQueryDepth ||
|
|
||||||
lastQueryLabel.minDegree !== minDegree;
|
|
||||||
|
|
||||||
if (shouldUpdate) {
|
if (shouldUpdate) {
|
||||||
lastQueryLabel.label = queryLabel
|
lastQueryLabelRef.current = {
|
||||||
lastQueryLabel.maxQueryDepth = maxQueryDepth
|
label: queryLabel,
|
||||||
lastQueryLabel.minDegree = minDegree
|
maxQueryDepth,
|
||||||
|
minDegree
|
||||||
|
}
|
||||||
|
|
||||||
const state = useGraphStore.getState()
|
|
||||||
state.reset()
|
|
||||||
fetchGraph(queryLabel, maxQueryDepth, minDegree).then((data) => {
|
fetchGraph(queryLabel, maxQueryDepth, minDegree).then((data) => {
|
||||||
// console.debug('Query label: ' + queryLabel)
|
const state = useGraphStore.getState()
|
||||||
state.setSigmaGraph(createSigmaGraph(data))
|
const newSigmaGraph = createSigmaGraph(data)
|
||||||
data?.buildDynamicMap()
|
data?.buildDynamicMap()
|
||||||
|
|
||||||
|
// Update all graph data at once to minimize UI flicker
|
||||||
|
state.clearSelection()
|
||||||
|
state.setMoveToSelectedNode(false)
|
||||||
|
state.setSigmaGraph(newSigmaGraph)
|
||||||
state.setRawGraph(data)
|
state.setRawGraph(data)
|
||||||
|
|
||||||
// Extract labels from graph data
|
// Extract labels from graph data
|
||||||
if (data) {
|
if (data) {
|
||||||
const labelSet = new Set<string>(['*'])
|
const labelSet = new Set<string>();
|
||||||
for (const node of data.nodes) {
|
for (const node of data.nodes) {
|
||||||
if (node.labels && Array.isArray(node.labels)) {
|
if (node.labels && Array.isArray(node.labels)) {
|
||||||
for (const label of node.labels) {
|
for (const label of node.labels) {
|
||||||
labelSet.add(label)
|
if (label !== '*') { // filter out label "*"
|
||||||
|
labelSet.add(label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.setGraphLabels(Array.from(labelSet).sort())
|
}
|
||||||
|
// Put * on top of other labels
|
||||||
|
const sortedLabels = Array.from(labelSet).sort();
|
||||||
|
state.setGraphLabels(['*', ...sortedLabels]);
|
||||||
} else {
|
} else {
|
||||||
state.setGraphLabels(['*'])
|
// Ensure * is there eventhough there is no graph data
|
||||||
|
state.setGraphLabels(['*']);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -93,7 +93,7 @@ const useGraphStoreBase = create<GraphState>()((set) => ({
|
|||||||
|
|
||||||
rawGraph: null,
|
rawGraph: null,
|
||||||
sigmaGraph: null,
|
sigmaGraph: null,
|
||||||
graphLabels: [],
|
graphLabels: ['*'],
|
||||||
|
|
||||||
setSelectedNode: (nodeId: string | null, moveToSelectedNode?: boolean) =>
|
setSelectedNode: (nodeId: string | null, moveToSelectedNode?: boolean) =>
|
||||||
set({ selectedNode: nodeId, moveToSelectedNode }),
|
set({ selectedNode: nodeId, moveToSelectedNode }),
|
||||||
@@ -115,7 +115,7 @@ const useGraphStoreBase = create<GraphState>()((set) => ({
|
|||||||
focusedEdge: null,
|
focusedEdge: null,
|
||||||
rawGraph: null,
|
rawGraph: null,
|
||||||
sigmaGraph: null,
|
sigmaGraph: null,
|
||||||
graphLabels: [],
|
graphLabels: ['*'],
|
||||||
moveToSelectedNode: false
|
moveToSelectedNode: false
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user