Skip to content

Commit

Permalink
Feature: Interest groups bubble plotting (#865)
Browse files Browse the repository at this point in the history
* Add click event to the interest group bubbles.

* Fix barragge animation.

* Fix click event.

* Fix barrage animation.
Remove timeline line in interactive mode.

* Fix samll bugs in protected audience.

* Fix order of calling.

* Add default height and width for canvas.
Introduce bubbles config to handle interest group bubbles animation.

* Set canvas height and width.

* Remove barrage animation code from flow.

* Remove drawSmallcircles from timeline.
Fix references.

* Remove drawPreviousCircles from utils.

* Create bubbles file to handle interest group bubbles.

* Fix barrage animation and reverseBarrage animation.

* Add isExpanded listener.

* Change interest group design.

* Fix click event and circle addition to the interest group.

* Remove comment.

* Fix arrow background.

* Add click event at correct place.

* Calculate the maximum number of bubbles that can be drawn in the big circle.

* Make the text of interest group count white.

* Make interest group travel from the minified circle to the runAdAuction box.

* Add text for interestgroup bubbles.

* Use d3js for expanded mode.

* Fix in barrage animation.

* Group IG by websites.

* Ad randomised value generation.

* Use d3js for bubble containers.

* Center the expanded bubble container.

* Complete usage of D3.js.

* Add text to interest group bubbles.

* Fix bug.
reduce IG counts

* Add expanding animation.
Remove expanded bubble.
Dynamically change zIndex of interest group canvas during barrage animation.

* Use interest group name instead of uuid.

* remove uuid.

* Change value to length of string.

* blur background when container expands.

* Add a cross button for intuitive closing of the expanded bubble.

* Remove circle transition to right when no bubble is added.

* Round the p tag and create method to make the color visible.

* use interest group names.

* Fix bubble reverse barrage animation.

* Fix issues post merge.

* Remove ee folder.

* Revert removal of interest group.

* Move bubble to top left corner of the circle.

* Expand circle on hover.

* have click animation to depict click.

* Add collapse and expand button.

* Stop barrage animation when bubble is expanded.

* Add cursor pointer.

* Remove background blur use flex for count display.

* Change colors of the expand and collapse button.

* Calculate angle and place close button there.

* Fix close button not clickable.

* Add escape event to close the bubble.

* Remove unused code.
Add play and pause mechanism

* Dont show bubbles which have been paused during barrage animation.

* Fix click listeners.

* Remove delay.

* Add ripple effect to the auction flow.

* Fix expansion and minification of the interst group bubbles.

* Convert all setInterval to requestAnimationFrame.

* Fix ripple effect cutting off boxes

* Move bubbles to modules and add JSDocs

* Fix spacing

---------

Co-authored-by: sayedtaqui <[email protected]>
  • Loading branch information
amovar18 and mohdsayed authored Nov 18, 2024
1 parent aa53dae commit 1af5770
Show file tree
Hide file tree
Showing 13 changed files with 1,020 additions and 325 deletions.
123 changes: 121 additions & 2 deletions packages/explorable-explanations/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
padding: 0;
}

.overflowing-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.hidden {
display: none;
}
Expand All @@ -26,14 +32,14 @@
position: absolute;
top: 0;
left: 0;
pointer-events: none;
pointer-events: none;
}

#user-canvas {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
pointer-events: none;
}

button {
Expand All @@ -47,12 +53,108 @@
width: 20px;
height: 20px;
}

#canvas-container {
width: 100%;
height: 100%;
position: relative;
}

#bubble-container {
position: absolute;
pointer-events: none;
top: 0px;
left: 0px;
}

.minified-bubble-container {
position: absolute;
top: 10px;
left: 10px;
height: 50px;
width: 50px;
border-radius: 50%;
background-color: white;
border: 1px solid #808080;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: width 0.5s ease, height 0.5s ease, top 0.5s ease, left 0.5s ease;
}

.circle-svg:hover:active {
cursor: pointer;
}

.text-class {
pointer-events: none;
}

.svg {
cursor: pointer;
}

.circle-svg {
transition: transform .2s;
}

.circle-svg:hover {
transform: scale(1.05);
cursor: pointer;
}

text {
cursor: pointer;
}

.minified-bubble-container.expanded {
position: absolute;
display: block;
top: 0px;
height: 500px;
width: 500px;
border-radius: 50%;
border: 1px solid #808080;
backdrop-filter: blur(10px);
}

.bubble-container {
position: absolute;
pointer-events: auto;
}

.bubble-container.expanded {
backdrop-filter: blur(1px);
z-index: 4;
height: 100vh;
width: 100vw;
}

#close-button {
position: absolute;
top: 10px;
cursor: pointer;
display: none;
}

#open-button {
position: absolute;
top: 50px;
left: 50px;
cursor: pointer;
display: none;
}

#count-display {
font-size: 16px;
position: absolute;
margin: 0px;
backdrop-filter: blur(4px);
font-weight: bolder;
border-radius: 50%;
}

.play-pause-button {
margin-right: 10px;
}
Expand Down Expand Up @@ -89,6 +191,23 @@
</div>
</div>
<div id="interest-canvas"></div>
<div id="bubble-container-div" class="bubble-container">
<div id="minified-bubble-container" class="minified-bubble-container">
<span id="count-display"></span>
</div>
<div id="open-button" style="color: black">
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"
fill="#808080">
<path d="M200-200v-240h80v160h160v80H200Zm480-320v-160H520v-80h240v240h-80Z" />
</svg>
</div>
<div id="close-button" style="color: black">
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"
fill="currentColor">
<path d="M440-440v240h-80v-160H200v-80h240Zm160-320v160h160v80H520v-240h80Z" />
</svg>
</div>
</div>
<div id="user-canvas"></div>
</main>

Expand Down
5 changes: 5 additions & 0 deletions packages/explorable-explanations/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ const app = {
flow: {
intervals: {},
},
bubbles: {
positions: [],
minifiedSVG: null,
expandedSVG: null,
},
utils: {},
p: null,
igp: null,
Expand Down
53 changes: 34 additions & 19 deletions packages/explorable-explanations/src/components/branches.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import ProgressLine from './progressLine';
import app from '../app';
import config from '../config';
import Box from './box';
import utils from '../lib/utils';

const LEFT_MARGIN = 70; // Margin from the left side of the canvas
const ANIMATION_SPEED = 5; // Controls the speed of the horizontal line drawing
const EXPAND_ICON_SIZE = 20;

let spacing, progress, interval, renderedBranchIds, endpoints;
let spacing, progress, renderedBranchIds, endpoints;

// @todo: Handle canvas width changes when the branches do not fit in the existing size.
const Branches = async ({ x1, y1, branches }) => {
x1 = typeof x1 === 'function' ? x1() : x1;
y1 = typeof y1 === 'function' ? y1() : y1;
Expand All @@ -38,7 +38,6 @@ const Branches = async ({ x1, y1, branches }) => {
}));

progress = 0;
interval = null;
renderedBranchIds = [];
endpoints = [];

Expand All @@ -53,10 +52,29 @@ const Branches = async ({ x1, y1, branches }) => {
});

return new Promise((resolve) => {
interval = setInterval(async () => {
await drawAnimatedTimeline(LEFT_MARGIN, y2 - 9, branches);
resolve(endpoints);
}, 20);
const animate = () => {
if (app.timeline.isPaused) {
requestAnimationFrame(animate); // Continue loop but remain paused
return;
}

// Clear canvas or update logic (if necessary)
utils.wipeAndRecreateInterestCanvas();

// Draw the animated timeline
drawAnimatedTimeline(LEFT_MARGIN, y2 - 9, branches).then(() => {
resolve(endpoints);
});

// Continue animation until progress completes
if (progress < (branches.length - 1) * spacing) {
progress += ANIMATION_SPEED;
requestAnimationFrame(animate);
}
};

// Start the animation loop
requestAnimationFrame(animate);
});
};

Expand All @@ -69,25 +87,17 @@ const drawAnimatedTimeline = (x, y, branches) => {
p.strokeWeight(1);

return new Promise((resolve) => {
// Draw the animated horizontal line
if (progress < (branches.length - 1) * spacing) {
progress += ANIMATION_SPEED; // Increase the length of the horizontal line
} else {
clearInterval(interval);
resolve();
}

// Draw the horizontal line
p.line(x, y, x + progress, y);

// Draw each vertical line and label when the horizontal line reaches its position
// Draw vertical lines and labels as the horizontal line progresses
for (let i = 0; i < branches.length; i++) {
const branchX = x + i * spacing;
const branch = branches[i];
let endpoint;

if (progress >= i * spacing && !(branch.id in renderedBranchIds)) {
// Start drawing each vertical line once the horizontal line reaches it
// Draw vertical line fully
if (progress >= i * spacing && !renderedBranchIds.includes(branch.id)) {
// Draw vertical line once the horizontal line reaches its position
p.stroke(0);
p.line(branchX, y, branchX, y + 20);

Expand All @@ -108,6 +118,11 @@ const drawAnimatedTimeline = (x, y, branches) => {
renderedBranchIds.push(branch.id);
}
}

// Resolve if the progress exceeds the required length
if (progress >= (branches.length - 1) * spacing) {
resolve();
}
});
};

Expand Down
49 changes: 25 additions & 24 deletions packages/explorable-explanations/src/components/progressLine.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const ProgressLine = ({
}) => {
const width = config.flow.lineWidth - ARROW_SIZE;
const height = config.flow.lineHeight - ARROW_SIZE;
const incrementBy = 1; // @todo Use it to control speed.
const incrementBy = 1; // Adjust to control speed
const p = app.p;

x1 = typeof x1 === 'function' ? x1() : x1;
Expand All @@ -50,16 +50,21 @@ const ProgressLine = ({
};

return new Promise((resolve) => {
app.flow.intervals['progressline'] = setInterval(() => {
const animate = () => {
if (app.timeline.isPaused) {
requestAnimationFrame(animate); // Keep the animation loop alive but paused
return;
}

p.stroke(0);
p.strokeWeight(1);

switch (direction) {
case 'right':
currentX += incrementBy;
if (currentX - x1 > width) {
clearInterval(app.flow.intervals['progressline']);
resolve({
x: currentX,
y: y2,
});
resolve({ x: currentX, y: y2 });
return;
}
p.line(x1, y1, currentX, y2);
drawArrow(currentX, y1, direction);
Expand All @@ -68,12 +73,9 @@ const ProgressLine = ({
case 'left':
targetX -= incrementBy;
if (x2 - targetX > width) {
clearInterval(app.flow.intervals['progressline']);
utils.drawText(text, targetX + width / 2, y1 + height / 2);
resolve({
x: targetX,
y: y1 + 10,
});
resolve({ x: targetX, y: y1 + 10 });
return;
}
p.line(x2, y2 + 10, targetX, y1 + 10);
drawArrow(targetX, y1 + 4, direction);
Expand All @@ -82,16 +84,13 @@ const ProgressLine = ({
case 'down':
currentY += incrementBy;
if (currentY - y1 > height) {
clearInterval(app.flow.intervals['progressline']);
utils.drawText(
text,
x1 - (text.startsWith('$') ? 10 : width / 2),
y1 + height / 2
);
resolve({
x: x2,
y: currentY,
});
resolve({ x: x2, y: currentY });
return;
}
p.line(x1, y1, x2, currentY);
drawArrow(x1, currentY, direction);
Expand All @@ -100,26 +99,28 @@ const ProgressLine = ({
case 'up':
currentY -= incrementBy;
if (y1 - currentY > height) {
clearInterval(app.flow.intervals['progressline']);
utils.drawText(
text,
x1 + (text.startsWith('$') ? 10 : width / 2),
y1 - height / 2
);
resolve({
x: x2,
y: currentY,
});
resolve({ x: x2, y: currentY });
return;
}
p.line(x1, y1, x2, currentY);
drawArrow(x1, currentY, direction);
break;

default:
clearInterval(app.flow.intervals['progressline']);
throw new Error(`Invalid direction: ${direction}`);
}
}, 10);

// Continue the animation loop
requestAnimationFrame(animate);
};

// Start the animation loop
requestAnimationFrame(animate);
});
};

Expand Down
Loading

0 comments on commit 1af5770

Please sign in to comment.