Source code for ehn.graph.vis

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

"""
Please refer the tutorial ":ref:`tutorial-graph`".
"""

__author__ = "Mu Yang <http://muyang.pro>"
__copyright__ = "2018-2021 CKIP Lab"
__license__ = "GPL-3.0"

from dataclasses import (
    dataclass,
)

from ..parse.node import (
    EhnParseFunction,
    EhnParseNormalEntity,
    EhnParseRestrictionPlaceholder,
)

################################################################################################################################


[docs]@dataclass class EhnVisGraph: """The E-HowNet graph for vis.js.""" nodes: dict edges: list
[docs]class EhnVisGraphBuilder: """The E-HowNet graph builder for vis.js.""" def __init__(self, definite_labels=None): if definite_labels is not None: self.definite_labels = definite_labels else: self.definite_labels = set() def __call__(self, root, label): worker = EhnVisGraphBuilderWorker(root, label, definite_labels=self.definite_labels) return EhnVisGraph( nodes=worker.nodes, edges=worker.edges, )
[docs]class EhnVisGraphBuilderWorker: """The E-HowNet graph builder worker for vis.js.""" def __init__(self, root, label, *, definite_labels): self.definite_labels = definite_labels self.nodes = {} self.edges = [] tail_id = self._expand_node(root) node_id = "root" self.nodes[node_id] = { "id": node_id, "label": label, "group": "Root", } self.edges.append( { "from": node_id, "to": tail_id, "label": "IS", } ) def _expand_node(self, node): node_id = node.get_coindex() or str(id(node)) # Check definite is_definite = False if isinstance(node, EhnParseNormalEntity) and node.head in self.definite_labels: is_definite = True node_id = node.head # Check function is_function = isinstance(node, EhnParseFunction) # Restriction if isinstance(node, EhnParseRestrictionPlaceholder): # Create node if node_id not in self.nodes: self.nodes[node_id] = { "id": node_id, "label": "ANY", "group": node.node_type, } tail_id = self._expand_node(node.value) self.edges.append( { "from": node_id, "to": tail_id, "label": "RESTRICT", } ) else: # Function head if node.get_function(): node_id = self._expand_node(node.function) # Create node if node_id not in self.nodes: self.nodes[node_id] = { "id": node_id, "label": node.head + ("()" if is_function else ""), "group": "Definite" if is_definite else node.node_type, } # Features for feature in node.get_features(): tail_id, label = self._expand_feature(feature) self.edges.append( { "from": node_id, "to": tail_id, "label": label, } ) # Get Argument for argument in node.get_arguments(): tail_id = self._expand_node(argument) self.edges.append( { "from": node_id, "to": tail_id, "label": "ARGUMENT", } ) # Get Value if node.get_value(): tail_id = self._expand_node(node.value) self.edges.append( { "from": node_id, "to": tail_id, "label": "VALUE", } ) return node_id def _expand_feature(self, feature): if not feature.get_function(): return self._expand_node(feature.value), feature.head node_id = self._expand_node(feature) tail_id = self._expand_node(feature.value) self.edges.append( { "from": node_id, "to": tail_id, "label": "VALUE", } ) return node_id, "FEATURE"