Skip to content

Commit

Permalink
feat: Updated relative positioning
Browse files Browse the repository at this point in the history
  • Loading branch information
noahonyejese committed Sep 19, 2024
1 parent 23d75d3 commit bc1b7e7
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 22 deletions.
66 changes: 49 additions & 17 deletions components/team-communication/TeamCommunication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import { useConfig } from '@/contexts/config-context';
import { useDisplay } from '@/contexts/display-context';
import { useWindowDimensions } from '@/hooks/use-window-dimensions';
import { MetricTypes } from '@/types/display-types';
import { getMetricType, resolveCollisions } from '@/utils/normalize';
import {
calculatePreferredWhiteSpace,
calulcateAvailableSpace,
getMetricType,
relativeTeamCommunicationMemberSize,
resolveCollisions,
} from '@/utils/normalize';
import { motion } from 'framer-motion';
import { FC, Fragment, useEffect, useState } from 'react';

Expand Down Expand Up @@ -41,6 +47,21 @@ const TeamCommunication: FC = () => {
const [hasRendered, setHasRendered] = useState(false);
const [textOpacity, setTextOpacity] = useState(true);
const [active, setActive] = useState<string>('');
const { width, height } = useWindowDimensions();
const whiteSpaceRatio = (metricConfigs?.config.defaults.ratio as [
number,
number
]) || [0.9, 0.9];

const whiteSpace = calculatePreferredWhiteSpace(
width,
height,
whiteSpaceRatio
);

const defaultMemberSize: number =
(metricConfigs?.config.defaults.minimumCircleSize as number) || 10;
const availableSpace = calulcateAvailableSpace(width * height, whiteSpace);

useEffect(() => {
if (hasRendered) {
Expand All @@ -58,17 +79,36 @@ const TeamCommunication: FC = () => {
useEffect(() => {
setHasRendered(true); // Mark component as rendered after first mount
}, []);
const defaultMemberSize =
metricConfigs?.config.defaults.circleMultiplicator || 10;

const { width, height } = useWindowDimensions();

useEffect(() => {
if (!width || !height) return;

const totalMessages = displayData.reduce(
(acc, sensor) =>
acc +
sensor.value.reduce(
(innerAcc, member) => innerAcc + member.messages,
0
),
0
);

let updatedNodes: Node[] = displayData.flatMap((sensor) =>
sensor.value.map((member, i) => {
const radius = member.messages * defaultMemberSize || defaultMemberSize;
console.log(
relativeTeamCommunicationMemberSize(
member.messages,
availableSpace,
totalMessages,
defaultMemberSize
)
);
const radius = relativeTeamCommunicationMemberSize(
member.messages,
availableSpace,
totalMessages,
defaultMemberSize
);
const existingNode = nodes.find((node) => node.name === member.name);
const hasChanged = existingNode?.radius !== radius;
const fallbackPosition = radius + RADIUS_PADDING + SCREEN_PADDING;
Expand Down Expand Up @@ -155,7 +195,7 @@ const TeamCommunication: FC = () => {
const midY = (sourceY + targetY) / 2;

// Define arc height adjustment based on index
const arcHeight = 30 + index * 20;
const arcHeight = 15 + index * 10;

// Calculate the control point in 2D space where the arcs will meet
const deltaX = targetX - sourceX;
Expand Down Expand Up @@ -342,20 +382,13 @@ const TeamCommunication: FC = () => {
cx: node.x,
cy: node.y,
r: node.radius,
filter: active === node.id ? 'url(#glow)' : '',
}}
filter={active === node.id ? 'url(#glow)' : ''}
onAnimationComplete={() =>
setTimeout(() => {
setActive('');
}, 2000)
}
transition={{
duration: 1.5,
ease: easingCubic,
}}
/>
{active === node.id && (
{active === node.id && !hasRendered && (
<motion.circle
id={node.name}
key={`node-${node.id}-${i}`}
Expand All @@ -365,7 +398,6 @@ const TeamCommunication: FC = () => {
fill={node.color}
initial={{
opacity: 0,

filter: '',
}}
animate={{
Expand Down Expand Up @@ -403,7 +435,7 @@ const TeamCommunication: FC = () => {
transition={{
duration: 1, // Fade-out transition duration of 5s
delay: 3, // Add delay before opacity transitions
ease: 'easeInOut',
ease: easingCubic,
}}
textAnchor="left"
fill="white"
Expand Down
2 changes: 1 addition & 1 deletion types/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface Metric {
export interface Config {
type: ConfigType;
defaults: {
[key: string]: number;
[key: string]: number | [number, number];
};
}

Expand Down
35 changes: 31 additions & 4 deletions utils/normalize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Node } from '@/components/team-communication/TeamCommunication';
import { SCREEN_PADDING } from '@/configs/styling';
import { RADIUS_PADDING, SCREEN_PADDING } from '@/configs/styling';
import { MetricForDisplayType, MetricTypes } from '@/types/display-types';
export interface MetricBody {
[key: `sensor-${number}`]: MetricNode<object>;
Expand Down Expand Up @@ -56,8 +56,6 @@ export const resolveCollisions = (
width: number,
height: number
): Node[] => {
const collisionPadding = 16; // Extra padding to avoid tight overlaps

for (let i = 0; i < nodes.length; i++) {
for (let j = i + 1; j < nodes.length; j++) {
const nodeA = nodes[i];
Expand All @@ -66,7 +64,7 @@ export const resolveCollisions = (
const dx = nodeA.x - nodeB.x;
const dy = nodeA.y - nodeB.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const minDistance = nodeA.radius + nodeB.radius + collisionPadding;
const minDistance = nodeA.radius + nodeB.radius + RADIUS_PADDING;

if (distance < minDistance) {
// Calculate overlap and resolve by shifting the nodes apart
Expand Down Expand Up @@ -98,3 +96,32 @@ export const resolveCollisions = (

return nodes;
};

export const calculatePreferredWhiteSpace = (
width: number,
height: number,
ratio: [number, number]
): number => {
const [preferredWidth, preferredHeight] = ratio;

const widthWhiteSpace = width * (0.99 + preferredWidth / 100);
const heightWhiteSpace = height * (0.99 + preferredHeight / 100);

return widthWhiteSpace * heightWhiteSpace;
};

export const calulcateAvailableSpace = (space: number, whiteSpace: number) => {
return space - whiteSpace;
};
export const relativeTeamCommunicationMemberSize = (
messages: number,
availableSpace: number,
totalMessages: number,
absoluteRadius: number
): number => {
const messageProportion = messages / totalMessages;

const scaledRadius = Math.sqrt(messageProportion * availableSpace) / 2;

return Math.max(scaledRadius, absoluteRadius);
};

0 comments on commit bc1b7e7

Please sign in to comment.