【问题标题】:D3 force layout forceY does not map to rangeD3 强制布局 forceY 不映射到范围
【发布时间】:2021-02-17 18:58:34
【问题描述】:

我正在尝试使用forceY() 属性在 D3 强制布局中垂直排序我的节点,但我未能限制我的 y 轴的上限。我的画布高度为 200 像素,我有 50 个类别要订购并投影到高度为 1000 像素的平面上。我最初想看到顶部的 200px,而其余的节点可以在底部看不见。如果需要,我让用户在那里平移。

我使用let y_scale = d3.scaleLinear().domain([0, 50]).range([0, 1000]);d3.forceSimulation(nodes).force("y", d3.forceY().y(d => y_scale(d.category))) 结合使用,我认为这会使节点自然地绘制在 0 像素或更低,但事实并非如此。节点是根据类别排序的,但 0 类别不映射到 0px,而是说 -400px,这在顶部是看不见的。

有没有办法让forceY 真正映射到[0, 1000] 范围?

我知道我可以使用Math.max(0, d.y)之类的东西在svg上绘制时限制节点的y,但这只会使所有会在顶部拖尾的节点堆叠在0行。

【问题讨论】:

    标签: javascript d3.js force-layout


    【解决方案1】:

    对于分类变量,您应该改用d3.scaleBand()。这应该是定位怪异的主要原因:

    const fruits = ["Apple", "Apple", "Pear", "Pear", "Orange", "Grape"];
    const data = fruits.map(d => ({
      x: 50,
      fruit: d
    }));
    const colours = ["Red", "Green", "Orange", "Purple"];
    const unique = arr => arr.filter((d, i) => arr.indexOf(d) === i);
    
    const yscale = d3.scaleBand()
      .domain(unique(fruits))
      .range([50, 150]);
    
    const colour = d3.scaleOrdinal()
      .domain(unique(fruits))
      .range(colours);
    
    const circle = d3.select("body")
      .append("svg")
      .attr("height", 200)
      .selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("r", 4)
      .attr("cx", d => d.x)
      .attr("cy", d => yscale(d.fruit))
      .attr("fill", d => colour(d.fruit));
    
    
    var graphLayout = d3.forceSimulation(data)
        .force("collide", d3.forceCollide().radius(5))
        .force("x", d3.forceX(50))
        .force("y", d3.forceY().y(d => yscale(d.fruit)))
        .on("tick", ticked);
    
    function ticked() {
      circle
        .attr("cx", d => d.x)
        .attr("cy", d => d.y)
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

    【讨论】:

      猜你喜欢
      • 2013-07-15
      • 2014-05-17
      • 1970-01-01
      • 2013-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多