import * as fs from "fs" ; import { IBaseNode } from "@/core/base/BaseNode" ; import { ITypedNode } from "@/core/typed/TypedNode" ; import { TypedGraph } from "@/core/typed/TypedGraph" ; import { IGraph , BaseGraph } from "@/core/base/BaseGraph" ; import { labelKeys } from "../interfaces" ; import { EdgeDupeChecker , PotentialEdgeInfo } from "../common/Dupes" ; import * as uuid from "uuid" ; const v4 = uuid . v4 ; import { Logger } from "../../utils/Logger" ; const logger = new Logger ( ) ; const DEFAULT_WEIGHT = 1 ; export interface JSONEdge { to : string ; directed ? : string ; weight ? : string ; type ? : string ; } export interface JSONNode { edges : Array < JSONEdge > ; coords ? : { [ key ] : Number ; } ; features ? : { [ key ] : any ; } ; } export interface JSONGraph { typeRLT : { nodes : { } ; edges : { } ; } ; name : string ; nodes : number ; edges : number ; data : { [ key ] : JSONNode ; } ; } export interface IJSONInConfig { explicit_direction ? : boolean ; directed ? : boolean ; weighted ? : boolean ; typed ? : boolean ; dupeCheck ? : boolean ; } export interface IJSONInput { _config : IJSONInConfig ; readFromJSONFile ( file , graph ? ) : IGraph ; readFromJSON ( json , graph ? ) : IGraph ; } class JSONInput implements IJSONInput { _config : IJSONInConfig ; constructor ( config = { } ) { this . _config = { explicit_direction : config . explicit_direction != null ? config . explicit_direction : true , directed : config . directed != null ? config . directed : false , weighted : config . weighted != null ? config . weighted : false , dupeCheck : config . dupeCheck != null ? config . dupeCheck : true , } ; } param filepath param graph readFromJSONFile ( filepath , graph ? ) { let json = JSON . parse ( fs . readFileSync ( filepath ) . toString ( ) ) ; return this . readFromJSON ( json , graph ) ; } param json param graph readFromJSON ( json , graph ? ) { graph = graph || new BaseGraph ( json . name ) ; const edc = new EdgeDupeChecker ( graph ) ; const rlt = json . typeRLT ; this . addNodesToGraph ( json , graph ) ; for ( let node_id in json . data ) { let node = graph . getNodeById ( node_id ) ; let edges = json . data [ node_id ] [ labelKeys . edges ] ; for ( let e in edges ) { const edge_input = edges [ e ] ; const target_node = this . getTargetNode ( graph , edge_input ) ; const edge_label = edge_input [ labelKeys . e_label ] ; const edge_type = ( rlt && rlt . edges [ edge_input [ labelKeys . e_type ] ] ) || null ; const directed = this . _config . explicit_direction ? ! ! edge_input [ labelKeys . e_dir ] : this . _config . directed ; const weight_float = JSONInput . handleEdgeWeights ( edge_input ) ; const weight_info = weight_float === weight_float ? weight_float : DEFAULT_WEIGHT ; const edge_weight = this . _config . weighted ? weight_info : undefined ; todo const target_node_id = edge_input [ labelKeys . e_to ] ; const dir_char = directed ? "d" : "u" ; const edge_id = node_id + "_" + target_node_id + "_" + dir_char ; const newEdge = { a : node , b : target_node , label : edge_label , dir : directed , weighted : this . _config . weighted , weight : edge_weight , typed : ! ! edge_type , type : edge_type , } ; if ( this . _config . dupeCheck && edc . isDupe ( newEdge ) ) { continue ; } graph . addEdgeByID ( edge_id , node , target_node , { label : edge_label , directed : directed , weighted : this . _config . weighted , weight : edge_weight , typed : ! ! edge_type , type : edge_type , } ) ; } } return graph ; } addNodesToGraph ( json , graph ) { const rlt = json . typeRLT ; let coords_json , coords , coord_idx , features ; for ( let node_id in json . data ) { const type = BaseGraph . isTyped ( graph ) ? rlt && rlt . nodes [ json . data [ node_id ] [ labelKeys . n_type ] ] : null ; const label = json . data [ node_id ] [ labelKeys . n_label ] ; const node = graph . addNodeByID ( node_id , { label , type } ) ; features = json . data [ node_id ] [ labelKeys . n_features ] ; if ( features ) { node . setFeatures ( features ) ; } coords_json = json . data [ node_id ] [ labelKeys . coords ] ; if ( coords_json ) { coords = { } ; for ( coord_idx in coords_json ) { coords [ coord_idx ] = + coords_json [ coord_idx ] ; } node . setFeature ( labelKeys . coords , coords ) ; } } } todo getTargetNode ( graph , edge_input ) { const target_node_id = edge_input [ labelKeys . e_to ] ; const target_node = graph . getNodeById ( target_node_id ) ; if ( ! target_node ) { throw new Error ( "Node referenced by edge does not exist" ) ; } return target_node ; } param edge_input static handleEdgeWeights ( edge_input ) { switch ( edge_input [ labelKeys . e_weight ] ) { case "undefined" : return DEFAULT_WEIGHT ; case "Infinity" : return Number . POSITIVE_INFINITY ; case "-Infinity" : return Number . NEGATIVE_INFINITY ; case "MAX" : return Number . MAX_VALUE ; case "MIN" : return Number . MIN_VALUE ; default : return parseFloat ( edge_input [ labelKeys . e_weight ] ) ; } } } export { JSONInput } ;