mirror of
https://github.com/OFFIS-ESC/constellation-analyzer
synced 2026-01-26 23:43:40 +00:00
112 lines
2.9 KiB
TypeScript
112 lines
2.9 KiB
TypeScript
import type { Actor, Relation, NodeTypeConfig, EdgeTypeConfig } from '../../types';
|
|
import type { ConstellationDocument } from './types';
|
|
import { createDocument } from './saver';
|
|
import { validateDocument, deserializeGraphState } from './loader';
|
|
|
|
/**
|
|
* File I/O - Export and import ConstellationDocument to/from files
|
|
*/
|
|
|
|
/**
|
|
* Export current graph state to a JSON file
|
|
*/
|
|
export function exportGraphToFile(
|
|
nodes: Actor[],
|
|
edges: Relation[],
|
|
nodeTypes: NodeTypeConfig[],
|
|
edgeTypes: EdgeTypeConfig[]
|
|
): void {
|
|
// Create the document using the existing saver
|
|
const doc = createDocument(nodes, edges, nodeTypes, edgeTypes);
|
|
|
|
// Convert to JSON with pretty formatting
|
|
const jsonString = JSON.stringify(doc, null, 2);
|
|
const blob = new Blob([jsonString], { type: 'application/json' });
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
// Create download link
|
|
const link = window.document.createElement('a');
|
|
link.href = url;
|
|
const dateStr = new Date().toISOString().slice(0, 10);
|
|
link.download = `constellation-analysis-${dateStr}.json`;
|
|
|
|
// Trigger download
|
|
window.document.body.appendChild(link);
|
|
link.click();
|
|
|
|
// Cleanup
|
|
window.document.body.removeChild(link);
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
/**
|
|
* Import graph state from a JSON file
|
|
*/
|
|
export function importGraphFromFile(
|
|
file: File,
|
|
onSuccess: (data: {
|
|
nodes: Actor[];
|
|
edges: Relation[];
|
|
nodeTypes: NodeTypeConfig[];
|
|
edgeTypes: EdgeTypeConfig[];
|
|
}) => void,
|
|
onError: (error: string) => void
|
|
): void {
|
|
const reader = new FileReader();
|
|
|
|
reader.onload = (event) => {
|
|
try {
|
|
const jsonString = event.target?.result as string;
|
|
const parsed = JSON.parse(jsonString);
|
|
|
|
// Validate using the existing loader validation
|
|
if (!validateDocument(parsed)) {
|
|
throw new Error('Invalid file format: File does not match expected Constellation Analyzer format');
|
|
}
|
|
|
|
// Deserialize the graph state
|
|
const graphState = deserializeGraphState(parsed as ConstellationDocument);
|
|
|
|
if (!graphState) {
|
|
throw new Error('Failed to parse graph data from file');
|
|
}
|
|
|
|
onSuccess(graphState);
|
|
} catch (error) {
|
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred while importing file';
|
|
onError(errorMessage);
|
|
}
|
|
};
|
|
|
|
reader.onerror = () => {
|
|
onError('Failed to read file');
|
|
};
|
|
|
|
reader.readAsText(file);
|
|
}
|
|
|
|
/**
|
|
* Trigger file selection dialog for import
|
|
*/
|
|
export function selectFileForImport(
|
|
onSuccess: (data: {
|
|
nodes: Actor[];
|
|
edges: Relation[];
|
|
nodeTypes: NodeTypeConfig[];
|
|
edgeTypes: EdgeTypeConfig[];
|
|
}) => void,
|
|
onError: (error: string) => void
|
|
): void {
|
|
const input = document.createElement('input');
|
|
input.type = 'file';
|
|
input.accept = '.json';
|
|
|
|
input.onchange = (event) => {
|
|
const file = (event.target as HTMLInputElement).files?.[0];
|
|
if (file) {
|
|
importGraphFromFile(file, onSuccess, onError);
|
|
}
|
|
};
|
|
|
|
input.click();
|
|
}
|