我使用的是d3.js版本5和circle-pack和d3圆弧生成器。圆圈打包和缩放代码是标准的,并在许多地方使用。当我尝试沿圆形放置弧形文本时,它工作得很好,加载也很好,但当我尝试放大或缩小时,文本/标签不会相应地与圆形边框一起放置。下面是我的代码:https://codepen.io/dmd7/pen/BvMwbr
我尝试了在'd3-circle-text' on zoomable circle-pack中使用这里提到的' d3 -circle-text‘插件,但不起作用,因为它使用的是旧版本的d3,而且放大功能有所不同。
此外,我还想尝试一下在这里实现的功能:http://nbremer.github.io/occupations/,但没有工作,因为从旧的d3版本转换到新的d3版本会使它变得更加困难。
下面是我的代码:https://codepen.io/dmd7/pen/BvMwbr
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
text {
font-size: 11px;
}
text.parent {
fill: #1f77b4;
}
text {
font: 10px sans-serif;
}
/*.text {
cursor: pointer;
}*/
text:hover {
/*color: #FF0000; */
font-weight: bold;
stroke: #000;
stroke-width: 0.5px;
text-decoration: underline;
}
circle {
fill: #ccc;
stroke: #999;
pointer-events: all;
cursor: pointer;
opacity: 0.55;
}
circle.parent {
fill: #1f77b4;
fill-opacity: .1;
stroke: steelblue;
}
circle.parent:hover {
stroke: #ff7f0e;
stroke-width: .5px;
}
/*circle.child {
pointer-events: none;
}*/
/*Node hover*/
/*.node {
cursor: pointer;
}
.node:hover {
stroke: #000;
stroke-width: 1.5px;
}
.node--leaf {
fill: white;
}
*/
/*Circle text*/
.label {
font: 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
text-anchor: middle;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff;
}
.label,
.node--root,
.node--leaf {
pointer-events: none;
}
.arc-path {
visibility: hidden;
}
</style>
</head>
<body>
<div id="container">
<svg width="700" height="700" id="cir_svg"></svg>
</div>
</body>
</html>下面是javaScript代码:
var svg, margin, diameter, g, pack, focus, view, circle, node;
var maxNumLevels = 3;
document.addEventListener("DOMContentLoaded", function (e) {
svg = d3.select("svg"),
margin = 20,
diameter = +svg.attr("width");
g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
pack = d3.pack()
.size([diameter - margin, diameter - margin])
.padding(2);
initialSpecialCase();
});
function generateLevels(pivotLevel) {
pivNum = parseInt(pivotLevel.match(/VirusL(\d+)_s/)[1]);
var r = '';
for (var n = 0; n <= maxNumLevels; ++n) {
if(n!=0) {
r += ",";
}
r += "VirusL" + (pivNum + n) + "_s";
}
curLevelsStr = r;
return r;
}
function extractTaxIdFromName(nameTaxId) {
var idx = nameTaxId.lastIndexOf(", taxid:");
if(idx != -1) {
return nameTaxId.substring(idx + 8);
}
return '';
}
function initialSpecialCase() {
var data1 = {};
d3.json("https://api.myjson.com/bins/1h5co8").then(function(dta) {
console.info("Data from ajax: ", dta);
data1 = {
'name' : 'root',
'field' : '',
'value' : dta.response.numFound,
'pivot' : dta['facet_counts']['facet_pivot'][generateLevels('VirusL0_s')]
};
createCircles(data1);
});
}
function mapData(d) {
if (!d.hasOwnProperty('pivot'))
return;
d.hasChildren = true;
var maxPivName = "VirusL" + (pivNum + maxNumLevels - 1).toString() + "_s";
if (d.field === maxPivName)
return;
var cnodes = d.pivot;
for (c in cnodes) {
if (!cnodes[c].hasOwnProperty('name')) {
cnodes[c].name = cnodes[c].value;
cnodes[c].value = cnodes[c].count;
}
}
return cnodes;
}
function arcSVG(mx0, my0, r, larc, sweep, mx1, my1) {
return 'M'+mx0+','+my0+' A'+r+','+r+' 0 '+larc+','+sweep+' '+mx1+','+my1;
}
function createCircles(data) {
var root = d3.hierarchy(data, mapData)
.sort(function(a, b) { return b.value - a.value; });
console.info(root);
focus = root;
var nodes = pack(root).descendants();
var nodeg = g.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", function(d) {
return d.children ? "node" : "leaf node";
})
;
nodeg.append("circle")
.attr("class", function(d) { return d.children ? "parent" : "child"; })
.attr("id", function(d) { return 'c' + extractTaxIdFromName(d.data.name); })
.on("click", function(d) {
selectedVirus = d.data.name;
if (!d.children && d.parent) {
zoom(d); d3.event.stopPropagation();
}
else if (focus !== d) {
zoom(d);
d3.event.stopPropagation();
}
});
nodeg.append("title")
.text(function(d) {
return d.data.name;
});
nodeg.each(function(d, i) {
var gg = d3.select(this);
if(d.depth === 3) {
// gg.append('text')
// .style('font-size', d3.min([3 * d.r / d.data.name.length, 16]))
// .attr('dy', '0.3em')
// .text(d.data.name);
}
else if(d.depth > 0) {
var rr = d.r - 5;
gg.append('path')
.attr('d', arcSVG(-rr, 0, rr, 1, 1, rr, 0))
.attr('id', 'label-path-' + i)
.style('fill', 'none')
.style('stroke', 'none');
gg.append('text')
.append('textPath')
.attr('xlink:href', '#label-path-' + i)
.attr('startOffset', '50%')
.style("text-anchor","middle")
.style('font-size', '10px')
.style('fill', 'black')
.text(d.data.name);
}
});
node = nodeg.selectAll("circle,text");
circle = nodeg.selectAll("circle");
svg
.on("click", function() {
zoom(root);
});
zoomTo([root.x, root.y, root.r * 2 + margin]);
}
function zoom(d) {
var focus0 = focus; focus = d;
var transition = d3.transition()
.duration(d3.event.altKey ? 7500 : 750)
.tween("zoom", function(d) {
var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
return function(t) { zoomTo(i(t)); };
});
transition.selectAll("text")
.filter(function(d) { return d.parent === focus || this.style.display === "inline"; })
.style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
.on("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })
.on("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });
}
function zoomTo(v) {
var k = diameter / v[2]; view = v;
node.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
circle.attr("r", function(d) { return d.r * k; });
}感谢你的帮助。
谢谢。
发布于 2019-01-15 09:10:02
您没有在缩放功能中为<textPath>选择路径。可以这样做:
svg.selectAll("path")
.attr('d', function(d){
return arcSVG(-(d.r - 5) * k, 0, (d.r - 5) * k, 1, 1, (d.r - 5) * k, 0)
});当然,更好的方法是命名您的选择,并改进新的d属性。此外,注意创建全局变量(如circle和node),仅用于在缩放功能中使用。最后,设置textpaths的display属性的逻辑不能正常工作。
https://stackoverflow.com/questions/54191307
复制相似问题