d3力有向图与细React语句

lfapxunr  于 2023-06-06  发布在  React
关注(0)|答案(1)|浏览(139)

我试图用svelte reactive语句制作一个简单的d3力定向图,但显然,它不起作用。

第一个例子,这是我制作图(working REPL)的最简单方法:

<script>
    import * as d3 from 'd3'
    import { onMount } from 'svelte'
    import data from './data.json'

    let svg,
            width = 500,
            height = 400,
            links, nodes
    
    let simulation = d3.forceSimulation(data)

</script>

<svg 
         bind:this={svg}
         width={width}
         height={height}
         viewBox="{-width/2} {-height/2} {width} {height}"
         >
    {#each data as node}
        <g class="g-nodes" >
            <circle bind:this={nodes}
                fill="cornflowerblue"
                r="5"
                cx={node.x}
                cy={node.y}
                ></circle>
        </g>
    {/each}
</svg>

第二个例子,我想用reactive语句添加一些force,比如说forceX,它不起作用,直到我在.tick()(working REPL)中添加simulation.tick(100)或任何> 0的数字:

<script>
    // the before part is still the same
    
    let simulation = d3.forceSimulation(data)

    $: simulation.force("x", d3.forceX(0)) // not working, the circle stay at the initial position
    $: simulation.tick(100) // the force worked, but not animating from the initial position

</script>

<!-- the rest of svg is still the same -->

第三个例子,我尝试了.on(“tick”)函数。函数被触发(我只给予了一个console.log来测试tick是否工作),但我不知道如何将修改后的数据传递给{#each}块。查看update函数中的console.log(data),xy的数据在每一个tick都在改变,但并没有更新实际的circle位置。(working REPL):

<script>
    // the before part is still the same
    
    let simulation = d3.forceSimulation(data)

    function update() {
       console.log(data)
       return data // I don't know if it's the correct way, but still not working tho
    }

    $: simulation.force("x", d3.forceX(0))
    $: simulation.on("tick", update)

</script>

<!-- the rest of svg is still the same -->

data.json

[
    {value: 10},
    {value: 12},
    {value: 15},
    {value: 8},
    {value: 7},
    {value: 12},
    {value: 25},
    {value: 20},
    {value: 16},
    {value: 13},
    {value: 5},
    {value: 7},
    {value: 8},
    {value: 10},
    {value: 12},
    {value: 14},
    {value: 24},
    {value: 23},
    {value: 22},
    {value: 11},
    
]
stszievb

stszievb1#

解决步骤3中问题的最简单方法是声明一个displayData数组,在update函数中将data复制到displayData中,并在displayData上迭代#each块。
data是一个导入变量,你不能直接重新分配给它,因为你不能重新分配给它,它不是React性的,data更新不会触发重新渲染。
通过在update函数中将data赋值给displayData(该函数将在每个tick上运行),您将触发#each块的重新渲染(假设您现在迭代displayData)。
Working REPL

相关问题