d3.js - d3 - graph is rendered outside the svg - Stack Overflow

admin2025-04-30  0

As per the pictures below the g element is rendered outside the svg (above the svg) so many nodes are covered by other HTML elements.

The svg element's position:

The g element's position:

I'd expect the position of the g will be inside the svg but the height of g is 0... I am sure I am doing something funky but I can't figure out what I am missing. I discovered if I add transform after .append('g') then the graph is positioned lower but I don't know what value I should use.

The code I am using is below

            const width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0) * 0.8 / 2
            const height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0) * 0.8 / 2;

            const ticked = (): void => {
                link.attr("x1", (d: any) => d.source.x)
                    .attr("y1", (d: any) => d.source.y)
                    .attr("x2", (d: any) => d.target.x)
                    .attr("y2", (d: any) => d.target.y);
    
                // node.attr("cx", (d: any) => d.x)
                //     .attr("cy", (d: any) => d.y);
                node.attr('transform', (d: any) => `translate(${d.x - 8},${d.y - 8})`);
            }

            function onSimulationTick() {
                if (Date.now() < simulationEndTime) {
                    ticked()
                } else {
                    simulation.stop();
                }
            }

            const simulation = d3.forceSimulation(nodes)
                        .alphaTarget(0.01)
                        .velocityDecay(0.3)
                        .force("collide", d3.forceCollide().radius((d: any) => nodeSize + 1).iterations(2))
                        .force('link', d3.forceLink(links).id((l: any) => l.id).strength(0.05).iterations(3))
                        .force('charge', d3.forceManyBody().strength(-50))
                        .force('center', d3.forceCenter(width / 2, height / 2))
                        // .force("x", d3.forceX().strength(0.001))
                        // .force("y", d3.forceY().strength(0.001))
                        .on('tick', onSimulationTick)

            const svg = d3
                        .select(graphRef.current)
                        .attr("preserveAspectRatio", "xMinYMin meet")
                        .attr("viewBox", "0 0 960 500")

            const link = svg
                        .append('g')
                        .attr('stroke', '#999')
                        .attr('stroke-opacity', 0.6)
                        // .attr('transform','translate('+height+','+width/2+')')
                        .selectAll()
                        .data(links)
                        .join('line')
                        .attr('stroke-width', (d: any) => Math.sqrt(d.value))    

            const node = svg
                .append('g')
                .attr('stroke', '#fff')
                .attr('stroke-width', 0.1)
                // .attr('transform','translate('+height+','+width/2+')')
                .selectAll('g')
                .data(nodes)
                .join('g')
                        
            node.append("text")
                .attr("text-anchor", "middle")
                .attr("dx", 10)
                .attr("dy", ".35em")
                .attr('stroke', 'black')
                .attr("style","font-size:10px;")
                .text((d: any) => cut(d.name))

            node.append("image")
                .attr("xlink:href", ".ico")
                .attr("width", nodeSize)
                .attr("height", nodeSize)         

            node.call(d3.drag()
                        .on('start', dragStarted)
                        .on('drag', dragged)
                        .on('end', dragEnded))

I'd appreciate any help please. Thanks a lot!

转载请注明原文地址:http://anycun.com/QandA/1746027251a91536.html