Skip to content
Snippets Groups Projects
display.tsx 5.05 KiB
Newer Older
  • Learn to ignore specific revisions
  • import React from "react";
    
    import screenfull from "screenfull";
    
    Matthias Konitzny's avatar
    Matthias Konitzny committed
    import PropTypes, { InferType } from "prop-types";
    
    
    import { GraphNode, GraphRenderer } from "./renderer";
    
    import * as Helpers from "./helpers";
    
    import Graph, { NodeData } from "./graph";
    
    import { loadGraphJson } from "../datasets";
    
    import NodeInfoBar from "./components/nodeinfo/nodeinfobar";
    
    import FilterMenu from "./components/nodefilter/filtermenu";
    
    /**
     * This component manages and renders a 3d-force-graph with additional menus to navigate, filter and view information on nodes.
     */
    
    class Display extends React.Component<
        InferType<typeof Display.propTypes>,
        InferType<typeof Display.stateTypes>
    > {
        props: InferType<typeof Display.propTypes>;
        state: InferType<typeof Display.stateTypes>;
    
        fullscreenRef: React.RefObject<HTMLDivElement>;
    
        rendererRef: React.RefObject<GraphRenderer>;
    
        static propTypes = {
            spaceId: PropTypes.string.isRequired,
        };
    
        static stateTypes = {
    
            graph: PropTypes.instanceOf(Graph),
            currentNode: PropTypes.object,
            nodeActive: PropTypes.bool,
    
            width: PropTypes.number,
            height: PropTypes.number,
    
        };
    
        constructor(props: InferType<typeof Display.propTypes>) {
            super(props);
    
            this.fullscreenRef = React.createRef();
    
            this.rendererRef = React.createRef();
    
            this.state = {
                graph: null,
    
                currentNode: null,
                nodeActive: false,
    
                width: 0,
                height: 0,
    
            this.handleNodeClicked = this.handleNodeClicked.bind(this);
            this.handleNodeClose = this.handleNodeClose.bind(this);
    
            this.handleNodeChangeRequest = this.handleNodeChangeRequest.bind(this);
    
            this.handleNodeFilter = this.handleNodeFilter.bind(this);
    
            this.setState({
                width: Helpers.getWidth(),
                height: Helpers.getHeight(),
            });
    
    
            const fetchGraph = async () => {
                const graphData = await loadGraphJson(this.props.spaceId);
    
                this.graph = new Graph(graphData.nodes, graphData.links);
                this.setState({ graph: this.graph });
    
        handleNodeClicked(node: NodeData) {
            this.setState({ currentNode: node, nodeActive: true });
    
        handleNodeChangeRequest(node: NodeData) {
            this.rendererRef.current.focusOnNode(node as GraphNode);
            this.handleNodeClicked(node);
        }
    
    
        handleNodeClose() {
            this.setState({ nodeActive: false });
    
        handleNodeFilter(visibility: Map<string, boolean>) {
            const graph = this.graph.view(visibility);
            this.setState({ graph: graph });
        }
    
    
        toggleFullscreen() {
            if (screenfull.isEnabled) {
    
                if (!screenfull.isFullscreen) {
                    this.setState({
                        width: screen.width,
                        height: screen.height,
                    });
                } else {
                    this.setState({
                        width: Helpers.getWidth(),
                        height: Helpers.getHeight(),
                    });
                }
    
                screenfull.toggle(this.fullscreenRef.current);
    
            } else {
                console.log("No fullscreen mode available :(");
            }
        }
    
    
                <div
                    id="kg-display"
                    style={{ position: "relative" }}
                    ref={this.fullscreenRef}
                >
    
                        className={"display-fullscreen-button no-select"}
    
                        title={"Vollbild"}
                        onClick={this.toggleFullscreen.bind(this)}
                    >
                        <p>&#10530;</p>
                    </div>
    
                    {/*{this.graph && (*/}
                    {/*    <FilterOverlay graph={this.graph} type={"node"} />*/}
                    {/*)}*/}
    
    
                    {this.state.currentNode && (
                        <NodeInfoBar
                            node={this.state.currentNode}
    
                            nodeColors={this.state.graph.nodeColors}
    
                            height={this.state.nodeActive ? this.state.height : 0}
    
                            onClose={this.handleNodeClose}
    
                            nodeClickedCallback={this.handleNodeChangeRequest}
    
                    {this.state.graph && (
                        <FilterMenu
    
                            onVisibilityChange={this.handleNodeFilter}
                        />
                    )}
    
    
                    <div id="3d-graph">
                        {this.state.graph && (
                            <GraphRenderer
    
                                graph={this.state.graph}
                                width={this.state.width}
                                height={this.state.height}
    
                                onNodeClicked={this.handleNodeClicked}