Compare commits

..

No commits in common. "a46427c6b85108ce57451ef50fb6119a0884ed16" and "f94c3402c2072396ce577fa587dbdabd3f7eb5f7" have entirely different histories.

3 changed files with 25 additions and 72 deletions

View File

@ -76,11 +76,7 @@ def graph_json():
"source": c.user, "source": c.user,
"target": p, "target": p,
"size": max(1.0 - 0.1 * i, 0.3), "size": max(1.0 - 0.1 * i, 0.3),
"data": { "data": {"relation": 2},
"relation": 2,
"origSize": max(1.0 - 0.1 * i, 0.3),
"origFill": "#bed4ff",
},
} }
) )
for p in c.hate: for p in c.hate:
@ -90,7 +86,7 @@ def graph_json():
"source": c.user, "source": c.user,
"target": p, "target": p,
"size": 0.3, "size": 0.3,
"data": {"relation": 0, "origSize": 0.3, "origFill": "#ff7c7c"}, "data": {"relation": 0},
"fill": "#ff7c7c", "fill": "#ff7c7c",
} }
) )

View File

@ -28,42 +28,33 @@ footer {
.controls { .controls {
z-index: 9; z-index: 9;
position: absolute; position: absolute;
width: 240px;
right: 24px;
top: 1vh; top: 1vh;
right: 0px; padding: 16px;
padding: 8px;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
.control { .control {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; margin: 4px 2px;
max-width: 240px; background-color: aliceblue;
margin: 0px;
background-color: #F0F8FFdd;
.slider, * {
span { margin: 4px;
padding-left: 4px;
padding-right: 4px;
} }
} }
#three-slider { #three-slider {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
margin: auto;
justify-content: center;
align-items: center;
} }
} }
/* The switch - the box around the slider */ /* The switch - the box around the slider */
.switch { .switch {
position: relative; position: relative;
width: 48px; width: 68px;
height: 24px; height: 42px;
} }
/* Hide default HTML checkbox */ /* Hide default HTML checkbox */
@ -90,10 +81,10 @@ footer {
.slider:before { .slider:before {
position: absolute; position: absolute;
content: ""; content: "";
height: 18px; height: 26px;
width: 18px; width: 26px;
left: 3px; left: 4px;
bottom: 3px; bottom: 4px;
background-color: white; background-color: white;
border-radius: 50%; border-radius: 50%;
-webkit-transition: .4s; -webkit-transition: .4s;
@ -109,9 +100,9 @@ input:focus+.slider {
} }
input:checked+.slider:before { input:checked+.slider:before {
-webkit-transform: translateX(24px); -webkit-transform: translateX(26px);
-ms-transform: translateX(24px); -ms-transform: translateX(26px);
transform: translateX(24px); transform: translateX(26px);
} }
.grey { .grey {

View File

@ -1,4 +1,4 @@
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { apiAuth } from "./api"; import { apiAuth } from "./api";
import { GraphCanvas, GraphCanvasRef, GraphEdge, GraphNode, SelectionProps, SelectionResult, useSelection } from "reagraph"; import { GraphCanvas, GraphCanvasRef, GraphEdge, GraphNode, SelectionProps, SelectionResult, useSelection } from "reagraph";
import { customTheme } from "./NetworkTheme"; import { customTheme } from "./NetworkTheme";
@ -8,14 +8,12 @@ interface NetworkData {
edges: GraphEdge[], edges: GraphEdge[],
} }
interface CustomSelectionProps extends SelectionProps { interface CustomSelectionProps extends SelectionProps {
ignore: (GraphEdge | undefined)[]; ignore: string[];
} }
const useCustomSelection = (props: CustomSelectionProps): SelectionResult => { const useCustomSelection = (props: CustomSelectionProps): SelectionResult => {
var result = useSelection(props); var result = useSelection(props);
result.actives = result.actives.filter((s) => !props.ignore.map((edge) => edge?.id).includes(s)) result.actives = result.actives.filter((s) => !props.ignore.includes(s))
const ignored_nodes = props.ignore.map((edge) => (edge && result.selections?.includes(edge.source) && !result.selections?.includes(edge.target)) ? edge.target : "")
result.actives = result.actives.filter((s) => !ignored_nodes.includes(s))
return result return result
} }
@ -25,7 +23,6 @@ export const GraphComponent = () => {
const [threed, setThreed] = useState(false); const [threed, setThreed] = useState(false);
const [likes, setLikes] = useState(2); const [likes, setLikes] = useState(2);
const [popularity, setPopularity] = useState(false); const [popularity, setPopularity] = useState(false);
const [mutuality, setMutuality] = useState(false);
const logo = document.getElementById("logo") const logo = document.getElementById("logo")
if (logo) { if (logo) {
logo.className = "logo networkroute"; logo.className = "logo networkroute";
@ -51,11 +48,9 @@ export const GraphComponent = () => {
function handlePopularity() { function handlePopularity() {
setPopularity(!popularity) setPopularity(!popularity)
} //graphRef.current?.fitNodesInView();
//graphRef.current?.centerGraph();
function handleMutuality() { //graphRef.current?.resetControls();
colorMatches(!mutuality);
setMutuality(!mutuality);
} }
function showLabel() { function showLabel() {
@ -66,32 +61,11 @@ export const GraphComponent = () => {
} }
} }
function findMatches(edges: GraphEdge[]) {
const adjacencyList = edges.map((edge) => edge.source + edge.target + edge.data.relation);
return edges.filter((edge) => adjacencyList.includes(edge.target + edge.source + edge.data.relation))
}
//const matches = useMemo(() => findMatches(data.edges), [])
function colorMatches(mutuality: boolean) {
const matches = findMatches(data.edges);
const newEdges = data.edges;
if (mutuality) {
newEdges.forEach((edge) => { if ((likes === 1 || edge.data.relation === likes) && matches.map((edge) => edge.id).includes(edge.id)) { edge.fill = "#9c3"; if (edge.size) edge.size = edge.size * 1.5 } })
} else {
newEdges.forEach((edge) => { if ((likes === 1 || edge.data.relation === likes) && matches.map((edge) => edge.id).includes(edge.id)) { edge.fill = edge.data.origFill; edge.size = edge.data.origSize } })
}
setData({ nodes: data.nodes, edges: newEdges })
}
useEffect(() => {
if (mutuality) colorMatches(false);
colorMatches(mutuality)
}, [likes])
const { selections, actives, onNodeClick, onCanvasClick } = useCustomSelection({ const { selections, actives, onNodeClick, onCanvasClick } = useCustomSelection({
ref: graphRef, ref: graphRef,
nodes: data.nodes, nodes: data.nodes,
edges: data.edges.filter((edge) => edge.data.relation === likes), edges: data.edges.filter((edge) => edge.data.relation === likes),
ignore: data.edges.map((edge) => { if (likes === 1 && edge.data.relation !== 2) return edge }), ignore: data.edges.map((edge) => { return (likes === 1 && edge.data.relation !== 2) ? edge.id : "" }),
pathSelectionType: 'out', pathSelectionType: 'out',
type: 'multiModifier' type: 'multiModifier'
}); });
@ -101,14 +75,6 @@ export const GraphComponent = () => {
<div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, right: 0 }}> <div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, right: 0 }}>
<div className="controls" > <div className="controls" >
<div className="control" onClick={handleMutuality}>
<div className="switch">
<input type="checkbox" checked={mutuality} />
<span className="slider round"></span>
</div>
<span>mutuality</span>
</div>
<div className="control" onClick={handleThreed}> <div className="control" onClick={handleThreed}>
<span>2D</span> <span>2D</span>
<div className="switch"> <div className="switch">