Skip to content
Snippets Groups Projects
Commit ff3d18a0 authored by Matthias Konitzny's avatar Matthias Konitzny :fire:
Browse files

Lots of comments. Also improved some variable names.

parent 066111ed
No related branches found
No related tags found
1 merge request!3Master into new editor
Showing with 102 additions and 26 deletions
......@@ -10,6 +10,15 @@ interface CollapsibleProps {
}
// Implementation details partially from https://medium.com/edonec/build-a-react-collapsible-component-from-scratch-using-react-hooks-typescript-73dfd02c9208
/**
* Collapisble section
* @param open Sets the default state of the collapsible section
* @param header Title text
* @param children React child elements
* @param color Optional bottom border color
* @param heightTransition Weather or not this section should render a smooth transition if the content height changes.
* @constructor
*/
function Collapsible({
open,
header,
......@@ -61,7 +70,12 @@ function Collapsible({
{header}
</button>
</div>
<div className={`collapsible-content ${heightTransition ? "collapsible-transition-height" : ""}`} style={{ height }}>
<div
className={`collapsible-content ${
heightTransition ? "collapsible-transition-height" : ""
}`}
style={{ height }}
>
<div ref={ref}>
<div className={"collapsible-content-padding"}>
{children}
......
......@@ -6,6 +6,11 @@ interface FancyScrollbarProps {
children?: React.ReactNode | React.ReactNode[];
}
/**
* Wraps other elements into a <div> section providing a thin scrollbar.
* @param children React children
* @constructor
*/
function FancyScrollbar({ children }: FancyScrollbarProps) {
return <div className={"fancy-scrollbar"}>{children}</div>;
}
......
import React, { useState } from "react";
import "./filtermenu.css";
import ClassLabel from "./classlabel";
import Label from "./label";
interface FilterMenuProps {
classes: Map<string, string>;
onVisibilityChange?: (visibility: Map<string, boolean>) => void;
}
/**
* Displays a menu which can be used to filter nodes by type.
* @param classes Map of available node classes with associated colors.
* @param onVisibilityChange Optional handler for visibility changes.
* @constructor
*/
function FilterMenu({ classes, onVisibilityChange }: FilterMenuProps) {
const classList = [...classes.keys()];
const chars = Math.max(
......@@ -38,12 +44,12 @@ function FilterMenu({ classes, onVisibilityChange }: FilterMenuProps) {
return (
<div className={"filter-menu"} style={{ width }}>
{classList.map((cls: string, idx) => (
<ClassLabel
<Label
key={cls}
type={cls}
text={cls}
color={classes.get(cls)}
width={labelWidth}
visible={visibility[idx]}
active={visibility[idx]}
onClick={() => handleClick(idx)}
/>
))}
......
import React from "react";
import "./classlabel.css";
import "./label.css";
interface ClassLabelProps {
type: string;
text: string;
color: string;
width: number;
visible?: boolean;
active?: boolean;
onClick?: (type: string) => void;
}
function ClassLabel({
type,
/**
* Displays a small text label with an associated color strip (at the bottom).
* @param text Text displayed in the label.
* @param color Color of the color strip.
* @param width Width of the color strip (the text will be left-aligned).
* @param onClick Optional onClick handler.
* @param active If false, the label will be displayed partially transparent.
* @constructor
*/
function Label({
text,
color,
width,
onClick,
visible = true,
active = true,
}: ClassLabelProps) {
const handleClick = () => {
if (onClick) {
onClick(type);
onClick(text);
}
};
const opacity = visible ? 1.0 : 0.4;
const opacity = active ? 1.0 : 0.4;
return (
<div
className={"filter-class-label"}
style={{ opacity }}
onClick={handleClick}
>
<p>{type}</p>
<p>{text}</p>
<div
className={"filter-class-label-color-strip"}
style={{ width: width + "px", backgroundColor: color }}
......@@ -39,4 +48,4 @@ function ClassLabel({
);
}
export default ClassLabel;
export default Label;
......@@ -10,6 +10,14 @@ interface MediaAreaProps {
references?: string[];
}
/**
* This component displays media-related information associated with a specific node.
* @param description The node description.
* @param image Link to an image.
* @param video Link to a video.
* @param references List of additional reference links.
* @constructor
*/
function MediaArea({ description, image, video, references }: MediaAreaProps) {
return (
<div className={"media-area"}>
......
......@@ -12,6 +12,13 @@ interface NeighborsProps {
nodeClickedCallback?: (node: NodeData) => void;
}
/**
* Shows a list of neighbors of a specific node separated by node type.
* @param neighbors List of neighbors
* @param nodeClickedCallback Optional callback to handle clicks on neighbors.
* @param nodeColors Mapping of node types to colors.
* @constructor
*/
function Neighbors({
neighbors,
nodeClickedCallback,
......
......@@ -11,29 +11,35 @@ interface InfoBarProps {
height: number;
node: NodeData;
nodeColors?: Map<string, string>;
nodeClosedCallback?: () => void;
onClose?: () => void;
nodeClickedCallback?: (node: NodeData) => void;
}
/**
* Displays a sidebar showing information on a specific node.
* @param height Height of the sidebar.
* @param node Node which drives the presented information.
* @param nodeColors Mapping of node types to colors.
* @param onClose Optional callback, called when the menu is closed.
* @param nodeClickedCallback Optional callback, called when a neighbor of the current node gets selected.
* @constructor
*/
function NodeInfoBar({
height,
node,
nodeColors,
nodeClosedCallback,
onClose,
nodeClickedCallback,
}: InfoBarProps) {
return (
<div className={"node-info-bar"} style={{ height }}>
<div
className={"node-info-bar-close-button"}
onClick={nodeClosedCallback}
>
<div className={"node-info-bar-close-button"} onClick={onClose}>
<p>&#10006;</p>
</div>
<div className={"node-info-bar-info-area"}>
<FancyScrollbar>
<TitleArea name={node.name} image={node.banner} />
<TitleArea title={node.name} image={node.banner} />
<MediaArea
description={node.description}
image={node.banner}
......
......@@ -4,6 +4,11 @@ interface ReferencesProps {
references: string[];
}
/**
* Displays a list of links.
* @param references List of links.
* @constructor
*/
function References({ references }: ReferencesProps) {
return (
<ul>
......
......@@ -3,16 +3,22 @@ import React from "react";
import "./titlearea.css";
interface TitleAreaProps {
name: string;
title: string;
image?: string;
}
function TitleArea({ name, image }: TitleAreaProps) {
/**
* Displays a title with an associated image
* @param title The title.
* @param image Link to an image.
* @constructor
*/
function TitleArea({ title, image }: TitleAreaProps) {
const marginTop = image ? 0 : 25;
return (
<div className={"title-area"} style={{ marginTop }}>
{image && <img src={image} className={"title-area-image"} />}
<h2 className={"title-area-headline"}>{name}</h2>
<h2 className={"title-area-headline"}>{title}</h2>
</div>
);
}
......
......@@ -10,6 +10,9 @@ 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>
......@@ -125,7 +128,7 @@ class Display extends React.Component<
node={this.state.currentNode}
nodeColors={this.state.graph.nodeColors}
height={this.state.nodeActive ? this.state.height : 0}
nodeClosedCallback={this.handleNodeClose}
onClose={this.handleNodeClose}
nodeClickedCallback={this.handleNodeChangeRequest}
></NodeInfoBar>
)}
......
......@@ -31,6 +31,9 @@ export interface Coordinate {
z: number;
}
/**
* Basic graph data structure.
*/
export default class Graph {
public nodes: NodeData[];
public links: LinkData[];
......
......@@ -32,6 +32,10 @@ export interface GraphLink extends LinkData {
// It is important to extend from React.PureComponent here to remove unnecessary re-renders!
// see https://www.robinwieruch.de/react-prevent-rerender-component/
/**
* Renders contents of a Graph object as 3d-graph representation.
*/
export class GraphRenderer extends React.PureComponent<
InferType<typeof GraphRenderer.propTypes>,
InferType<typeof GraphRenderer.stateTypes>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment