D3JS 中强制定向图像和标签布局中的不同图像大小
Different Image Sizes in Force-Directed Images and Labels Layout in d3js
我有一个简单的问题,我无法解决。所以我在 d3js 中实现了力导向布局,如下所示。但是,现在我想包含在图表中的图像具有不同的大小。所以我写了一个函数 imagesize 来确定这些图像的尺寸。但是,问题是在布局的第一个开始时,图像不会显示。如果我重新加载它,那么它可以完美运行。我想问题是加载功能,但我不知道我还能如何获得尺寸。
你可以在这里找到jsfiddle。所以我写的你可以在第 62 - 67 行找到。
.attr("width", function(d) {
return imagesize("https://github.com/favicon.ico")[0];
})
.attr("height", function(d) {
return imagesize("https://github.com/favicon.ico")[1];
});
和图像大小
function imagesize(link) {
var img = new Image();
img.src = link;
return [img.width, img.width];
}
谢谢。
编辑
将宽度和高度存储在每个节点的基准中,然后在绘制直线时使用它。 请参阅下面的代码更新:
您没有处理映像的异步加载。 此外,您可以使用.each
来简化这一点:
appended.append("image")
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("x", "-8px")
.attr("y", "-8px")
.each(imagesize); //<-- call this for each image
function imagesize(d) {
var self = d3.select(this); //<-- this is the svg image
function loaded() { //<-- when your img is finished loading set width/height
d.width = img.width; //<-- stash width/height in each node
d.height = img.height;
self.attr('width', d.width);
self.attr('height', d.height);
}
var img = new Image();
img.src = self.attr('href'); //<-- you can get this from the svg image
if (img.complete) {
loaded(); //<-- is to already done
} else {
img.addEventListener('load', loaded); //<-- callback after loading
img.addEventListener('error', function() {
alert('error');
})
}
}
绘制线条时:
force.on("tick", function() {
link.attr("x1", function(d) {
// draw line with width of node
// since width is set async, protect against null values
return d.source.x + (d.source.width ? d.source.width/2 : 0);
})
完整代码:
var width = 300, height = 300;
var radius = 5;
var svg = d3.select('#main')
.append("svg")
.attr("height", height)
.attr("width", width);
var nodes = [], links = [];
var force = d3.layout.force()
.charge(-350)
.linkDistance(50)
.nodes(nodes)
.links(links)
.size([height, width]);
var node = svg.selectAll(".node"),
link = svg.selectAll('.link');
var drag = force.drag().on("dragstart", dragstart);
nodes.push({id: 0, name:"zero"});
nodes.push({id: 1, name:"one"});
links.push({source: 0, target: 1});
update();
function update() {
// add reference to index of nodes
var edges = [];
links.forEach(function(e){
var sourcenode = nodes.filter(function(n) {
return n.id === e.source;
})[0];
var targetnode = nodes.filter(function(n) {
return n.id === e.target;
})[0];
edges.push({source: sourcenode, target: targetnode});
});
links = edges;
var link = svg.selectAll("line.link")
.data(links, function(d) {
return d.source.id + '-' + d.target.id;
});
link.enter().insert("line").attr("class", "link").style("stroke","black");
link.exit().remove();
node = node.data(force.nodes(), function(d) {return d.id;});
node.exit().remove();
var appended = node.enter().append("g").call(drag);
appended.append("image")
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("x", "-8px")
.attr("y", "-8px")
.each(imagesize);
appended
//.on("dblclick", dblclick)
.on("contextmenu", dragend);
appended.append("text")
.attr("dx", "12")
.attr("dy", ".35em")
.text(function(d) { return d.name; });
force.on("tick", function() {
link.attr("x1", function(d) {
return d.source.x + (d.source.width ? d.source.width/2 : 0);
})
.attr("y1", function(d) {
return d.source.y + (d.source.height ? d.source.height/2 : 0);
})
.attr("x2", function(d) {
return d.target.x + (d.target.width ? d.target.width/2 : 0);
})
.attr("y2", function(d) {
return d.target.y + (d.target.height ? d.target.height/2 : 0);
});
node.attr("transform", function(d) {
var x = Math.max(radius,
Math.min($('svg').attr('width') - radius, d.x));
var y = Math.max(radius,
Math.min($('svg').attr('height') - radius, d.y));
return "translate(" + d.x + "," + d.y + ")";
});
});
force.start();
}
function dragstart(d) {
d3.select(this).classed("fixed", d.fixed = true);
}
function dragend(d) {
d3.select(this).classed("fixed", d.fixed = false);
}
function imagesize(d) {
var self = d3.select(this);
function loaded() {
d.width = img.width;
d.height = img.height;
self.attr('width', d.width);
self.attr('height', d.height);
}
var img = new Image();
img.src = self.attr('href');
if (img.complete) {
loaded();
} else {
img.addEventListener('load', loaded)
img.addEventListener('error', function() {
alert('error');
})
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body>
<div id="main"></div>
</body>
相关文章:
- 在HTML/JavaScript中,有没有一种方法可以在图像开始加载时知道图像的最终布局尺寸
- 无法在cakepp布局中显示图像
- 使用javascript根据图像的布局方向为图像添加不同的类名
- 网格化图像,如画布上的Pinterest布局
- HTML图像布局使用PHP变量,该变量是用JavaScript动态设置的〔o r…〕
- 如何在钛(合金)图像视图中使用后置布局
- 砖石事件:在图像加载和布局完成后调用事件
- 使用 d3.js 在强制布局中淡入淡出某些图像
- 具有排序问题的流体动态图像布局
- D3JS 中强制定向图像和标签布局中的不同图像大小
- 调整随机图像放置代码以实现灵活的布局
- JQuery图像库-所选图像临时更改布局
- 如何在图库页面中布局不同大小的图像
- 图像在放入表格单元格布局时不再有响应
- 使用angularjs和ui-bootstrap进行谷歌图像布局
- 自适应布局上的垂直自适应图像对齐
- 响应式图像布局
- D3.js:强制布局-节点不渲染图像
- 中心砌体布局,有不同大小的图像
- 3d -js的强制布局是否支持图像作为节点?