D3 force simulation with svelte

355 Views Asked by At

I'm building a d3 force simulation that's working fine in plain d3 (I was testing it in Observable here), but I'm struggling to translate it to svelte, I think in part because I'm fetching data from a URL and the promise is tripping me up.

The data comes through fine and the svg populates with circles, but the circles are just stacked on top of each other in 3 groups. I'm clearly not actually running the simulation, but am confused what I'm doing wrong. Any help would be greatly appreciated!

Here's my code:

<script>
    import * as d3 from 'd3';
    import rough from 'roughjs';
    import { onMount } from 'svelte';
    //import {forceSimulation} from 'd3Force';

    let width = 800;
    let height = 800;

    const m = 3;

    const colors = {
        words: '#fcd6d9',
        acts: '#fcb6be',
        gifts: '#f995a4',
        time: '#f3728d',
        touch: '#ec4977'
    }

    let points;
    let simulation;

    const rawData = d3.csv('https://raw.githubusercontent.com/sarachodosh/60days/main/60days_data.csv')
        .then(data => {
            
            points = data.map(d => {
                let i = Math.floor(Math.random() * m) //the cluster id
                let focusX = 110 * Math.cos(i / m * Math.PI * 2)
                let focusY = 110 * Math.sin(i / m * Math.PI * 2)

                let dataPoint = {
                    day: d.day,
                    cluster: +d.cluster,
                    person: d.person,
                    act_type: d.act_type,
                    r: d.person === 'both' ? 10 : 15,
                    x: focusX,
                    y: focusY,
                    focusX: focusX,
                    focusY: focusY
                } 
                return dataPoint

            })
        
            console.log(points)
            
            simulation = d3.forceSimulation()
                .force('center', d3.forceCenter(width/2, height/2))
                .nodes(points)
                .on("tick", () => {
                    points = points
                    
                })      
            
            simulation.tick()
            
        })

</script>

<main>

<svg viewBox='0 0 {width} {height}'>
    <g>
        {#if points}
        {#each points as d}
            <circle r='{d.r}' cx='{d.x}' cy='{d.y}' fill='{colors[d.act_type]}'></circle>
        {/each}
        {/if}
    </g>
</svg>

</main>
0

There are 0 best solutions below