feat: implement highlighting of mutuality

This commit is contained in:
julius 2025-02-25 18:36:58 +01:00
parent c2d94c0400
commit fd323db6d0
Signed by: julius
GPG Key ID: C80A63E6A5FD7092
3 changed files with 67 additions and 22 deletions

View File

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

View File

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

View File

@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { apiAuth } from "./api";
import { GraphCanvas, GraphCanvasRef, GraphEdge, GraphNode, SelectionProps, SelectionResult, useSelection } from "reagraph";
import { customTheme } from "./NetworkTheme";
@ -25,6 +25,7 @@ export const GraphComponent = () => {
const [threed, setThreed] = useState(false);
const [likes, setLikes] = useState(2);
const [popularity, setPopularity] = useState(false);
const [mutuality, setMutuality] = useState(false);
const logo = document.getElementById("logo")
if (logo) {
logo.className = "logo networkroute";
@ -50,9 +51,11 @@ export const GraphComponent = () => {
function handlePopularity() {
setPopularity(!popularity)
//graphRef.current?.fitNodesInView();
//graphRef.current?.centerGraph();
//graphRef.current?.resetControls();
}
function handleMutuality() {
colorMatches(!mutuality);
setMutuality(!mutuality);
}
function showLabel() {
@ -63,6 +66,27 @@ 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"; 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({
ref: graphRef,
nodes: data.nodes,
@ -77,6 +101,14 @@ export const GraphComponent = () => {
<div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, right: 0 }}>
<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}>
<span>2D</span>
<div className="switch">