How am I structuring my bubbles incorrectly in Pixi.js?

18 Views Asked by At

I'm running into an issue with my bubble structure in Pixi.js. They are rendering correctly on the page but are overlapping with the data structure from my backend. How can I structure my code so that the timelines do not overlap?

import * as PIXI from 'pixi.js';
import React, { useEffect, useRef } from 'react';

const PixiTimeline2 = ({allTimelines}) => {

    // Create a reference for the container and the app
    const containerRef = useRef();
    let app;

    // Define the renderTimeline function
    const renderTimeline = (timelineData) => {
        console.log('Rendering timeline with', timelineData.length, 'events');
        // Group events by year and month
        const eventsByYearAndMonth = {};
        
        timelineData.forEach((event) => {
            const date = new Date(event.startDate || event.date);
            const year = date.getFullYear();
            const month = date.getMonth();
            if(!eventsByYearAndMonth[year]){
                eventsByYearAndMonth[year] = {}
            }
            if(!eventsByYearAndMonth[year][month]){
                eventsByYearAndMonth[year][month] = [];
            }
            eventsByYearAndMonth[year][month].push(event);
        });
        console.log('Events grouped by year and month:', eventsByYearAndMonth);


        const bubbleSize = 10;
        const spacingX = 30;
        const spacingY = 30;
        
        const years = Object.keys(eventsByYearAndMonth);
        const maxEventsInMonth = Math.max(1,...years.map(year => Object.values(eventsByYearAndMonth[year]).map(month => month.length).flat()));
        const totalMonths = years.reduce((acc, year) => acc + Object.keys(eventsByYearAndMonth[year]).length, 0);

        
        const maxX = totalMonths * spacingX;
        const maxY = maxEventsInMonth * spacingY;

        let currentX = (app.screen.width - maxX) / 2;
        let currentY = (app.screen.height - maxY) / 2;
        
        
        
        const timelineColors = ['#FF5733', '#33FF57', '#5733FF', '#FF33D4', '#33D4FF', '#D4FF33'];
        
        // Render bubbles for each year and month
        Object.keys(eventsByYearAndMonth).forEach((year, yearIndex) => {
            currentX = (app.screen.width - maxX) / 2;
            Object.keys(eventsByYearAndMonth[year]).forEach((month, monthIndex) => {
                const events = eventsByYearAndMonth[year][month];
                const numEvents = events.length;
        
                // Calculate the total width of events for this month
                const totalWidth = numEvents * (bubbleSize + spacingX);
                
                // Calculate the starting X position for this row of events
                const startX = currentX - totalWidth / 2;
                
                events.forEach((event, index) => {
                    const y = currentY + monthIndex * (bubbleSize + spacingY);
                    const x = startX + index * (bubbleSize + spacingX); 
                    console.log(monthIndex, spacingY);
                    console.log('const x: ',x)
                    console.log('const y: ',y)

                    console.log('Rendering bubble at (x, y):', x, y);
                    // Create bubble graphics
                    const bubble = new PIXI.Graphics();
                    const color = timelineColors[allTimelines.findIndex((timeline) => timeline.id === event.timelineId) % timelineColors.length];
                    bubble.beginFill(color);
                    bubble.drawCircle(0, 0, bubbleSize);
                    bubble.endFill();
                    bubble.x = x;
                    bubble.y = y;

                    app.stage.addChild(bubble);

                    // Increment x and y for the next event
                    // currentX += spacingX;
                });
                currentY += spacingY
            });
        });
    };

    useEffect(() => {
        if (containerRef.current) {
            app = new PIXI.Application({
                width: 400,
                height: 400
            });

            containerRef.current.appendChild(app.view);

            let yOffset = 0;
            const timelines = {};

            allTimelines.forEach(timeline => {
                timelines[timeline.id] = new PIXI.Container();
                app.stage.addChild(timelines[timeline.id])
                timeline.events.sort((a,b) => {
                    const aDate = a.startDate || a.date;
                    const bDate = b.startDate || b.date;
                    return new Date(aDate) - new Date(bDate);
                });
                console.log('Timeline events sorted:', timeline.events);
                yOffset += 20
                renderTimeline(timeline.events, timelines[timeline.id], yOffset);
            });
        }

        // Cleanup function
        return () => {
            if (app) {
                app.destroy(true);
            }
        };
    }, [allTimelines]);

    return (
        <div ref={containerRef} className="pixi-container" style={{
            display:'flex',
            alignItems: 'center',
            justifyContent: 'center',
            padding: '10px'
        }}>
        </div>
    );
}

export default PixiTimeline2;

I'm creating a timeline where it sorts the events by year horizontally and vertically by month. Each timeline will be a different color, but it is prioritizing the events.

0

There are 0 best solutions below