diff --git a/CHANGELOG.md b/CHANGELOG.md index 98c5f77..3fefd91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 bengali, brazilian, bulgarian, catalan, cjk (i.e. chinese, japanese, korean), czech, danish, dutch, english, finnish, french, galician, german, greek, hindi, hungarian, indonesian, irish, italian, latvian, lithuanian, norwegian, persian, romanian, russian, sorani, spanish, swedish, turkish, thai. +- Added toggle to show/hide edges on graph. ### Changed diff --git a/frontend/src/components/atoms/GraphHideEdgesButton.tsx b/frontend/src/components/atoms/GraphHideEdgesButton.tsx new file mode 100644 index 0000000..c566e4e --- /dev/null +++ b/frontend/src/components/atoms/GraphHideEdgesButton.tsx @@ -0,0 +1,19 @@ +import { Switch } from "@blueprintjs/core"; +import * as React from "react"; +import styled from "styled-components"; +import FloatingCard from "./FloatingCard"; + +const StyledSwitch = styled(Switch)` + margin: 0; +`; + +interface IGraphHideEdgesButtonProps { + isShowingEdges: boolean; + toggleEdges: () => void; +} +const GraphHideEdgesButton: React.FC = ({ isShowingEdges, toggleEdges }) => ( + + + +); +export default GraphHideEdgesButton; diff --git a/frontend/src/components/atoms/index.ts b/frontend/src/components/atoms/index.ts index 1b966d4..c4b5190 100644 --- a/frontend/src/components/atoms/index.ts +++ b/frontend/src/components/atoms/index.ts @@ -2,4 +2,5 @@ export { default as Page } from "./Page"; export { default as FloatingCard } from "./FloatingCard"; export { default as GraphKey } from "./GraphKey"; export { default as GraphResetButton } from "./GraphResetButton"; +export { default as GraphHideEdgesButton } from "./GraphHideEdgesButton"; export { default as InstanceType } from "./InstanceType"; diff --git a/frontend/src/components/molecules/Cytoscape.tsx b/frontend/src/components/molecules/Cytoscape.tsx index df06369..6de3d98 100644 --- a/frontend/src/components/molecules/Cytoscape.tsx +++ b/frontend/src/components/molecules/Cytoscape.tsx @@ -28,6 +28,7 @@ interface ICytoscapeProps { hoveringOver?: string; ranges?: { [key: string]: [number, number] }; searchResultIds?: string[]; + showEdges: boolean; navigateToInstancePath?: (domain: string) => void; navigateToRoot?: () => void; } @@ -85,7 +86,7 @@ class Cytoscape extends React.PureComponent { "font-size": "mapData(size, 1, 6, 10, 100)", "min-zoomed-font-size": 16 }) - .selector(".hidden") // used to hide nodes not in the neighborhood of the selected + .selector(".hidden") // used to hide nodes not in the neighborhood of the selected, or to hide edges .style({ display: "none" }) @@ -146,6 +147,13 @@ class Cytoscape extends React.PureComponent { if (!isEqual(prevProps.searchResultIds, this.props.searchResultIds)) { this.updateSearchResultNodeClass(); } + if (prevProps.showEdges !== this.props.showEdges) { + if (this.props.showEdges) { + this.showEdges(); + } else { + this.hideEdges(); + } + } } public componentWillUnmount() { @@ -319,6 +327,20 @@ class Cytoscape extends React.PureComponent { } }); }; + + private showEdges = () => { + if (!this.cy) { + throw new Error("Expected cytoscape, but there wasn't one!"); + } + this.cy.edges().removeClass("hidden"); + }; + + private hideEdges = () => { + if (!this.cy) { + throw new Error("Expected cytoscape, but there wasn't one!"); + } + this.cy.edges().addClass("hidden"); + }; } export default Cytoscape; diff --git a/frontend/src/components/molecules/GraphTools.tsx b/frontend/src/components/molecules/GraphTools.tsx index 2ef75d0..bb6e8b8 100644 --- a/frontend/src/components/molecules/GraphTools.tsx +++ b/frontend/src/components/molecules/GraphTools.tsx @@ -1,7 +1,7 @@ import React from "react"; import styled from "styled-components"; import { IColorScheme } from "../../types"; -import { GraphKey, GraphResetButton } from "../atoms"; +import { GraphHideEdgesButton, GraphKey, GraphResetButton } from "../atoms"; const GraphToolsContainer = styled.div` position: absolute; @@ -14,20 +14,25 @@ const GraphToolsContainer = styled.div` interface IGraphToolsProps { currentColorScheme?: IColorScheme; colorSchemes: IColorScheme[]; + isShowingEdges: boolean; ranges?: { [key: string]: [number, number] }; onColorSchemeSelect: (colorScheme?: IColorScheme) => void; onResetButtonClick: () => void; + toggleEdges: () => void; } const GraphTools: React.FC = ({ currentColorScheme, colorSchemes, + isShowingEdges, ranges, onColorSchemeSelect, - onResetButtonClick + onResetButtonClick, + toggleEdges }) => { return ( + { private cytoscapeComponent: React.RefObject; @@ -34,7 +35,7 @@ class GraphImpl extends React.PureComponent { public constructor(props: IGraphProps) { super(props); this.cytoscapeComponent = React.createRef(); - this.state = { colorScheme: undefined }; + this.state = { colorScheme: undefined, isShowingEdges: true }; } public componentDidMount() { @@ -59,14 +60,17 @@ class GraphImpl extends React.PureComponent { navigateToInstancePath={this.navigateToInstancePath} navigateToRoot={this.navigateToRoot} searchResultIds={this.props.searchResultDomains} + showEdges={this.state.isShowingEdges} ref={this.cytoscapeComponent} /> ); @@ -87,6 +91,10 @@ class GraphImpl extends React.PureComponent { } }; + private toggleEdges = () => { + this.setState({ isShowingEdges: !this.state.isShowingEdges }); + }; + private setColorScheme = (colorScheme?: IColorScheme) => { this.setState({ colorScheme }); }; diff --git a/frontend/src/components/screens/InstanceScreen.tsx b/frontend/src/components/screens/InstanceScreen.tsx index d08c199..7a3f7f3 100644 --- a/frontend/src/components/screens/InstanceScreen.tsx +++ b/frontend/src/components/screens/InstanceScreen.tsx @@ -236,6 +236,7 @@ class InstanceScreenImpl extends React.PureComponent