【问题标题】:How to add text to d3.js force directed circles?如何将文本添加到 d3.js 强制定向圆圈?
【发布时间】:2020-03-14 22:14:20
【问题描述】:

我正在研究一个力有向图,并成功地显示了由链接连接的圆圈。但是,当尝试将文本附加到节点时,我遇到了麻烦。

我已尝试更改内容,使圆圈和文本包含在单个节点中,但随后强制功能不再起作用,并且圆圈重叠显示在容器的左上角。

这就是我现在所拥有的(我在 react 组件内构建)。

import React, { useRef, useEffect } from 'react';
import * as d3 from 'd3';
import '../../custom_styles/bpForceDirected.css';

interface IProps {
    data?: string;
    linkData?: string;
}

/* Component */
export const MyD3Component = (props: IProps) => {

    const d3Container = useRef(null);

    useEffect(
        () => {
            if (props.data && d3Container.current) {
                var w=500;
                var h=500;
                const svg = d3.select(d3Container.current)
                            .attr("viewBox", "0 0 " + w + " " + h )
                            .attr("preserveAspectRatio", "xMidYMid meet");

                var simulation = d3.forceSimulation()
                    .nodes(props.data);
                simulation
                    .force("charge_force", d3.forceManyBody())
                    .force("center_force", d3.forceCenter(w / 2, h / 2));

                //draw circles for the nodes and adding text
                var node = svg.append("g")
                        .attr("class", "nodes")
                        .selectAll("circle")
                        .data(props.data)
                        .enter()
                        .append("circle")
                        .attr("r", 10)
                        .attr("fill", circleColor);

                node.append("text")
                    .attr("dx", 12)
                    .attr("dy", ".35em")
                    .text(function(d) { return d.id });

                function tickActions() {

                    node
                        .attr("cx", function(d) { return d.x; })
                        .attr("cy", function(d) { return d.y; });

                    link
                        .attr("x1", function(d) { return d.source.x; })
                        .attr("y1", function(d) { return d.source.y; })
                        .attr("x2", function(d) { return d.target.x; })
                        .attr("y2", function(d) { return d.target.y; });
                }  

                  simulation.on("tick", tickActions );

                var link_force =  d3.forceLink(props.linkData)
                    .id(function(d) { return d.id; })

                simulation.force("links",link_force)

                var link = svg.append("g")
                    .attr("class", "links")
                    .selectAll("line")
                    .data(props.linkData)
                    .enter().append("line")
                        .attr("stroke-width", 2)
                        .style("stroke", linkColor);
            }
        },

        [props.data, d3Container.current])

    return (
        <svg
            className="d3-component"
            ref={d3Container}
        />
    );
}

export default MyD3Component;

【问题讨论】:

    标签: d3.js


    【解决方案1】:

    您不能将 text 元素附加到 circle。 首先,为每个节点创建一个g

    var node = svg.append("g")
      .attr("class", "nodes")
      .selectAll("g")
      .data(props.data)
      .enter()
      .append("g")
    

    然后,将一个circle和一个text附加到每个g

    node.append('circle').attr('r', ...)
    node.append('text').text(...)
    ...
    

    替换

    node.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
    

    与:

    node.attr('transform', d => `translate(${d.x},${d.y})`);
    

    【讨论】:

    • 进行更改时,我在生成的标记中看到圆圈和文本位于单个节点中,但现在force simulation 对节点没有影响。节点显示在容器的左上角重叠。有任何想法吗?看起来我的 tickActions 函数应该还在更新位置。
    • 更新的答案有效!从一个节点到其他节点的文本有一些重叠,但我相信通过向节点添加拖动功能可以帮助解决这个问题。原件和替换件node.attr 之间究竟有什么区别?抱歉,我是 D3 的新手,所以我仍在努力解决这一切。
    • 'cx' 和 'cy' 是 的属性,但它们不适用于 的坐标和比例可以通过'transform'属性改变
    猜你喜欢
    • 2012-11-16
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多