Javascript 设置D3.js循环报告边界

Javascript 设置D3.js循环报告边界,javascript,d3.js,data-visualization,Javascript,D3.js,Data Visualization,我正在尝试设置一个可视化,以便更高值的单元格在重力作用下位于顶部和左侧,但我无法在带有红色区域的div边界内保持多个圆。你能帮我解决这个问题吗 function CreateCirclesOfProcessos(seletor, data, numWidth, numHeight) { let numBoundaryDiameter = 50; let numBoundaryRadius = 5; let numMaxRadius = 100; let

我正在尝试设置一个可视化,以便更高值的单元格在重力作用下位于顶部和左侧,但我无法在带有红色区域的div边界内保持多个圆。你能帮我解决这个问题吗

    function CreateCirclesOfProcessos(seletor, data, numWidth, numHeight) {

    let numBoundaryDiameter = 50;
    let numBoundaryRadius = 5;
    let numMaxRadius = 100;
    let numMargin = data.length * 10;
    let n = 50;
    
    const radiusScale = d3.scaleSqrt()
        .domain([0, d3.max(data, d => d.value)])
        .range([0, numMaxRadius]);

    const radius = function (d) {
        return radiusScale(d.value);
    }

    let objNodes = CreateProcessosNodes(n, numBoundaryRadius, numBoundaryDiameter, data, numWidth, numHeight);

    let objGraphData = GetProcessosGraphData(radius, objNodes);

    const objSVG = seletor.append('svg')
        .attr("width", numWidth)
        .attr("height", numHeight + numMargin);

    let objGroup = objSVG.append('g')
        .attr("transform", "translate(" + 70 + ", " + 70 + ")");

    objGroup.append("rect")
        .attr("x", 0)
        .attr("y", 0)
        .attr("width", numWidth)
        .attr("height", numHeight)
        .style("stroke", "none")
        .style("fill", "none");

    let objCircles = objGroup.selectAll("circle")
        .data(objGraphData.nodes)
        .enter()
        .append("g")
        .style("cursor", "pointer")
        .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });

    objCircles.append("circle")
        .attr("cx", 0)
        .attr("cy", 0)
        .attr("r", radius)
        .style("fill", "#FF5532")
        .style("stroke", "white");           
}    
谢谢!!


提供一个自定义勾号函数,并使用它将项目保持在边界内。我们还可以使用
forceCenter
将项目保持在中心位置:

const force = d3.forceSimulation(objNodes)
    .force("x", d3.forceX().x(CoordinatePosition).strength(GetStrength))
    .force("y", d3.forceY().y(CoordinatePosition).strength(GetStrength))
    .force('many', d3.forceManyBody().strength(2))
    .force('collide', d3.forceCollide().radius(numRadius).strength(1))
    .force("center", d3.forceCenter())
    .on('tick', () => {
        nodes.attr("cx", d => d.x = Math.max(radius, Math.min(width - radius, d.x)))
             .attr("cy", d => d.y = Math.max(radius, Math.min(height - radius, d.y)));
    })
    .stop();
其中,
节点
表示您的圆。在这种情况下,您必须通过代码前面的
objCircles
选择:

  let objCircles = objGroup.selectAll("circle")
    .data(objGraphData.nodes)
    .enter()
    .append("g")
    .style("cursor", "pointer")
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    });

  let objGraphData = GetProcessosGraphData(radius, objNodes, objCircles);

  // ...

  function GetProcessosGraphData(numRadius, objNodes, nodes) {
    // ...
  }

提供一个自定义勾号函数,并使用它将项目保持在边界内。我们还可以使用
forceCenter
将项目保持在中心位置:

const force = d3.forceSimulation(objNodes)
    .force("x", d3.forceX().x(CoordinatePosition).strength(GetStrength))
    .force("y", d3.forceY().y(CoordinatePosition).strength(GetStrength))
    .force('many', d3.forceManyBody().strength(2))
    .force('collide', d3.forceCollide().radius(numRadius).strength(1))
    .force("center", d3.forceCenter())
    .on('tick', () => {
        nodes.attr("cx", d => d.x = Math.max(radius, Math.min(width - radius, d.x)))
             .attr("cy", d => d.y = Math.max(radius, Math.min(height - radius, d.y)));
    })
    .stop();
其中,
节点
表示您的圆。在这种情况下,您必须通过代码前面的
objCircles
选择:

  let objCircles = objGroup.selectAll("circle")
    .data(objGraphData.nodes)
    .enter()
    .append("g")
    .style("cursor", "pointer")
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    });

  let objGraphData = GetProcessosGraphData(radius, objNodes, objCircles);

  // ...

  function GetProcessosGraphData(numRadius, objNodes, nodes) {
    // ...
  }
我使用,在我的模拟方法上实现以下代码来解决我的问题

const wallForce = d3.forceLimit()
                    .radius(node => node.r)
                    .x0(0)
                    .x1(numWidth)
                    .y0(0)
                    .y1(numHeight);

const force = d3.forceSimulation()
                .nodes(objNodes)
                .force("x", d3.forceX().x(CoordinatePosition).strength(GetStrength))
                .force("y", d3.forceY().y(CoordinatePosition).strength(GetStrength))
                .force('many', d3.forceManyBody().strength(1))
                .force('collide', d3.forceCollide().radius(numRadius).strength(2.5))
                .force('walls', wallForce)
                .stop();
我使用,在我的模拟方法上实现以下代码来解决我的问题

const wallForce = d3.forceLimit()
                    .radius(node => node.r)
                    .x0(0)
                    .x1(numWidth)
                    .y0(0)
                    .y1(numHeight);

const force = d3.forceSimulation()
                .nodes(objNodes)
                .force("x", d3.forceX().x(CoordinatePosition).strength(GetStrength))
                .force("y", d3.forceY().y(CoordinatePosition).strength(GetStrength))
                .force('many', d3.forceManyBody().strength(1))
                .force('collide', d3.forceCollide().radius(numRadius).strength(2.5))
                .force('walls', wallForce)
                .stop();

但是我的objcircles选择在.data()中使用objGraphData.nodes。但是我的objcircles选择在.data()中使用objGraphData.nodes。