@@ -0,0 +1,113 @@
|
||||
import { create } from "zustand";
|
||||
import type { GraphData, GraphNode, GraphLink } from "../types";
|
||||
|
||||
interface GraphState {
|
||||
data: GraphData;
|
||||
highlightNodes: Set<string>;
|
||||
highlightLinks: Set<GraphLink>;
|
||||
isLinkMode: boolean;
|
||||
selectedNode: GraphNode | null;
|
||||
|
||||
// Действия с данными
|
||||
setData: (data: GraphData) => void;
|
||||
addNode: (node: GraphNode) => void;
|
||||
removeNode: (nodeId: string) => void;
|
||||
addLink: (link: GraphLink) => void;
|
||||
removeLink: (link: GraphLink) => void;
|
||||
|
||||
// Подсветка
|
||||
setHighlight: (nodeIds: Set<string>, links: Set<GraphLink>) => void;
|
||||
|
||||
// Режим связи
|
||||
toggleLinkMode: () => void;
|
||||
setSelectedNode: (node: GraphNode | null) => void;
|
||||
createLink: (sourceId: string, targetId: string) => void;
|
||||
|
||||
// Экспорт
|
||||
exportData: () => void;
|
||||
}
|
||||
|
||||
export const useGraphStore = create<GraphState>((set, get) => ({
|
||||
data: { nodes: [], links: [] },
|
||||
highlightNodes: new Set(),
|
||||
highlightLinks: new Set(),
|
||||
isLinkMode: false,
|
||||
selectedNode: null,
|
||||
|
||||
setData: (data) => set({ data }),
|
||||
|
||||
addNode: (node) => {
|
||||
set((state) => ({
|
||||
data: {
|
||||
...state.data,
|
||||
nodes: [...state.data.nodes, node],
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
removeNode: (nodeId) => {
|
||||
set((state) => ({
|
||||
data: {
|
||||
nodes: state.data.nodes.filter((n) => n.id !== nodeId),
|
||||
links: state.data.links.filter(
|
||||
(l) => l.source !== nodeId && l.target !== nodeId,
|
||||
),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
addLink: (link) => {
|
||||
set((state) => ({
|
||||
data: {
|
||||
...state.data,
|
||||
links: [...state.data.links, link],
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
removeLink: (linkToRemove) => {
|
||||
set((state) => ({
|
||||
data: {
|
||||
...state.data,
|
||||
links: state.data.links.filter((l) => l !== linkToRemove),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
setHighlight: (nodeIds, links) =>
|
||||
set({ highlightNodes: nodeIds, highlightLinks: links }),
|
||||
|
||||
toggleLinkMode: () =>
|
||||
set((state) => ({
|
||||
isLinkMode: !state.isLinkMode,
|
||||
selectedNode: null,
|
||||
})),
|
||||
|
||||
setSelectedNode: (node) => set({ selectedNode: node }),
|
||||
|
||||
createLink: (sourceId, targetId) => {
|
||||
const { data, addLink } = get();
|
||||
|
||||
const linkExists = data.links.some(
|
||||
(link) =>
|
||||
(link.source === sourceId && link.target === targetId) ||
|
||||
(link.source === targetId && link.target === sourceId),
|
||||
);
|
||||
|
||||
if (!linkExists) {
|
||||
addLink({ source: sourceId, target: targetId, type: "custom" });
|
||||
}
|
||||
},
|
||||
|
||||
exportData: () => {
|
||||
const { data } = get();
|
||||
const dataStr = JSON.stringify(data, null, 2);
|
||||
const blob = new Blob([dataStr], { type: "application/json" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = "graph-data.json";
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
},
|
||||
}));
|
||||
Reference in New Issue
Block a user