gpt4 book ai didi

javascript - 静态尺寸的圆形包装

转载 作者:行者123 更新时间:2023-12-04 01:45:32 25 4
gpt4 key购买 nike

我正在尝试实现 D3 pack layout使用静态大小的圆形值,我希望 D3 只负责放置,但我看到 d3 覆盖了提供的圆形大小。我不确定如何保持从数据传递的相同大小。请参阅下面的代码,其中,当我使用标签 RAD 更改 child 的大小时来自 1005000 ,我看到其他圆圈的大小正在变化,我怎样才能使布局以我从数据中获得的确切大小呈现?请给我一些指针或jsfiddle

链接到 codepen - https://codepen.io/navinleon/pen/mxZJWr

提前致谢。

var w = 1000,
h = 500;

var data = {
name: "root",
children: [{
label: 'RAD',
size: 100,
color: '#c99700'
}, {
label: 'BIL',
size: 100,
color: '#008ce6'
}, {
label: 'EEN',
size: 100,
color: '#007377'
}, {
label: 'INO',
size: 100,
color: '#b4975a'
}, ]
};

var canvas = d3.select("#canvas")
.append("svg:svg")
.attr('width', w)
.attr('height', h);

var nodes = d3.layout.pack()
.value(function (d) {
return d.size;
}).padding(100)
.size([w, h])
.nodes(data);

// Get rid of root node
nodes.shift();

canvas.selectAll('circles')
.data(nodes)
.enter()
.append('svg:circle')
.attr('cx', function (d) {
return d.x;
})
.attr('cy', function (d) {
return d.y;
})
.attr('r', function (d) {
return d.r;
})
.attr('fill', function (d) {
return d.color;
});

最佳答案

使用 d3.packSiblings():

其实有一个方便的方法,叫做d3.packSiblings ,这似乎正是您需要(没有任何力模拟)来定位节点。

根据API :

Packs the specified array of circles, each of which must have a circle.r property specifying the circle’s radius.



因此,更改 size数据中的属性到 r ,你所需要的只是:
var packed = d3.packSiblings(data.children);

这是演示:

var data = {
name: "root",
children: [{
label: 'RAD',
r: 50,
color: '#c99700'
}, {
label: 'BIL',
r: 75,
color: '#008ce6'
}, {
label: 'EEN',
r: 20,
color: '#007377'
}, {
label: 'INO',
r: 42,
color: '#b4975a'
}, ]
};

var packed = d3.packSiblings(data.children);

var w = 500,
h = 400;
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h)
.append("g")
.attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

var color = d3.scaleOrdinal(d3.schemeCategory10);

var nodes = svg.selectAll(null)
.data(data.children)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x
})
.attr("cy", function(d) {
return d.y
})
.attr("r", function(d) {
return d.r
})
.style("fill", function(_, i) {
return color(i)
})
<script src="https://d3js.org/d3.v5.min.js"></script>


使用力模拟

你居然 不想圆形包布局。圆包布局必须适合 pack.size 指定区域中的所有圆。大批。

由于您想自己设置圆的大小并且您希望 D3 只负责放置,所以我想到的最明显的选择是使用力模拟。

在这个提议的解决方案中,我们将使用 forceX 将焦点设置为 SVG 的中心。和 forceY .然后,我们将停止模拟并运行它给定的次数(你拥有的元素越少,你需要的迭代就越少):
var simulation = d3.forceSimulation(data.children)
.force("x", d3.forceX(w / 2))
.force("y", d3.forceY(h / 2))
.force("collide", d3.forceCollide(function(d) {
return d.size
}))
.stop();

这里有一些演示。

首先,将所有圆的半径设置为 100:

var w = 500,
h = 400;
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);

var color = d3.scaleOrdinal(d3.schemeCategory10)

var data = {
name: "root",
children: [{
label: 'RAD',
size: 100,
color: '#c99700'
}, {
label: 'BIL',
size: 100,
color: '#008ce6'
}, {
label: 'EEN',
size: 100,
color: '#007377'
}, {
label: 'INO',
size: 100,
color: '#b4975a'
}, ]
};

var simulation = d3.forceSimulation(data.children)
.force("x", d3.forceX(w / 2))
.force("y", d3.forceY(h / 2))
.force("collide", d3.forceCollide(function(d) {
return d.size
}))
.stop();

for (var i = 0; i < 100; ++i) simulation.tick();

var nodes = svg.selectAll(null)
.data(data.children)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x
})
.attr("cy", function(d) {
return d.y
})
.attr("r", function(d) {
return d.size
})
.style("fill", function(_, i) {
return color(i)
})
<script src="https://d3js.org/d3.v5.min.js"></script>


现在让我们将 3 个圆圈的大小减少到 20 个:

var w = 500,
h = 400;
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);

var color = d3.scaleOrdinal(d3.schemeCategory10)

var data = {
name: "root",
children: [{
label: 'RAD',
size: 20,
color: '#c99700'
}, {
label: 'BIL',
size: 100,
color: '#008ce6'
}, {
label: 'EEN',
size: 20,
color: '#007377'
}, {
label: 'INO',
size: 20,
color: '#b4975a'
}, ]
};

var simulation = d3.forceSimulation(data.children)
.force("x", d3.forceX(w / 2))
.force("y", d3.forceY(h / 2))
.force("collide", d3.forceCollide(function(d) {
return d.size
}))
.stop();

for (var i = 0; i < 100; ++i) simulation.tick();

var nodes = svg.selectAll(null)
.data(data.children)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x
})
.attr("cy", function(d) {
return d.y
})
.attr("r", function(d) {
return d.size
})
.style("fill", function(_, i) {
return color(i)
})
<script src="https://d3js.org/d3.v5.min.js"></script>


现在所有大小为 10 的圆圈:

var w = 500,
h = 400;
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);

var color = d3.scaleOrdinal(d3.schemeCategory10)

var data = {
name: "root",
children: [{
label: 'RAD',
size: 10,
color: '#c99700'
}, {
label: 'BIL',
size: 10,
color: '#008ce6'
}, {
label: 'EEN',
size: 10,
color: '#007377'
}, {
label: 'INO',
size: 10,
color: '#b4975a'
}, ]
};

var simulation = d3.forceSimulation(data.children)
.force("x", d3.forceX(w / 2))
.force("y", d3.forceY(h / 2))
.force("collide", d3.forceCollide(function(d) {
return d.size
}))
.stop();

for (var i = 0; i < 100; ++i) simulation.tick();

var nodes = svg.selectAll(null)
.data(data.children)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x
})
.attr("cy", function(d) {
return d.y
})
.attr("r", function(d) {
return d.size
})
.style("fill", function(_, i) {
return color(i)
})
<script src="https://d3js.org/d3.v5.min.js"></script>


最后,让我们将其中一个圆设为 5000。您将看到的唯一内容是整个 SVG 为单一颜色……但这正是您所要求的:圆的半径为 5000 像素。核实:

var w = 500,
h = 400;
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);

var color = d3.scaleOrdinal(d3.schemeCategory10)

var data = {
name: "root",
children: [{
label: 'RAD',
size: 5000,
color: '#c99700'
}, {
label: 'BIL',
size: 100,
color: '#008ce6'
}, {
label: 'EEN',
size: 100,
color: '#007377'
}, {
label: 'INO',
size: 100,
color: '#b4975a'
}, ]
};

var simulation = d3.forceSimulation(data.children)
.force("x", d3.forceX(w / 2))
.force("y", d3.forceY(h / 2))
.force("collide", d3.forceCollide(function(d) {
return d.size
}))
.stop();

for (var i = 0; i < 100; ++i) simulation.tick();

var nodes = svg.selectAll(null)
.data(data.children)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x
})
.attr("cy", function(d) {
return d.y
})
.attr("r", function(d) {
return d.size
})
.style("fill", function(_, i) {
return color(i)
})
<script src="https://d3js.org/d3.v5.min.js"></script>

关于javascript - 静态尺寸的圆形包装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49827367/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com