gpt4 book ai didi

javascript - 如何在 d3 中换行以适合屏幕?

转载 作者:行者123 更新时间:2023-11-30 15:36:42 25 4
gpt4 key购买 nike

我对使用 d3 作为可视化有点陌生。这是我的可视化文档集群的程序。 the document titles exceed the screen

文档的标题太长,屏幕无法显示全部标题,所以我想把每个成员的标题标签都包裹起来。

这是 d3 代码:

var CodeFlower = function(selector, w, h) {
this.w = w;
this.h = h;

d3.select(selector).selectAll("svg").remove();

this.svg = d3.select(selector).append("svg:svg")
.attr('width', w)
.attr('height', h);

this.svg.append("svg:rect")
.style("stroke", "#6BB6CF")
.style("fill", "#6BB6CF")
.attr('width', "615px")
.attr('height', h);

this.force = d3.layout.force()
.on("tick", this.tick.bind(this))
.charge(function(d) { return d._children ? -d.size / 100 : -40; })
.linkDistance(function(d) { return d.target._children ? 80 : 25; })
.size([h, w]);
};

CodeFlower.prototype.update = function(json) {
if (json) this.json = json;

this.json.fixed = true;
this.json.x = this.w / 2;
this.json.y = this.h / 2;

var nodes = this.flatten(this.json);
var links = d3.layout.tree().links(nodes);
var total = nodes.length || 1;

// remove existing text (will readd it afterwards to be sure it's on top)
this.svg.selectAll("text").remove();

// Restart the force layout
this.force
.gravity(Math.atan(total / 50) / Math.PI * 0.4)
.nodes(nodes)
.links(links)
.start();

// Update the links
this.link = this.svg.selectAll("line.link")
.data(links, function(d) { return d.target.name; });

// Enter any new links
this.link.enter().insert("svg:line", ".node")
.attr("class", "link")
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });

// Exit any old links.
this.link.exit().remove();

// Update the nodes
this.node = this.svg.selectAll("circle.node")
.data(nodes, function(d) { return d.name; })
.classed("collapsed", function(d) { return d._children ? 1 : 0; });

this.node.transition()
.attr("r", function(d) { return d.children ? 3.5 : Math.pow(d.size, 2/5) || 1; });

// Enter any new nodes
this.node.enter().append('svg:circle')
.attr("class", "node")
.classed('directory', function(d) { return (d._children || d.children) ? 1 : 0; })
.attr("r", function(d) { return d.children ? 3.5 : Math.pow(d.size, 2/5) || 1; })
.style("fill", function color(d) {
return "hsl(" + parseInt(360 / total * d.id, 10) + ",90%,70%)";
})
.call(this.force.drag)
.on("click", this.click.bind(this))
.on("mouseover", this.mouseover.bind(this))
.on("mouseout", this.mouseout.bind(this));

// Exit any old nodes
this.node.exit().remove();

this.text = this.svg.append('svg:text')
.attr('class', 'nodetext')
.attr('dy', 0)
.attr('dx', 0)
.attr('text-anchor', 'middle');

return this;
};

function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}

function type(d) {
d.value = +d.value;
return d;
}


CodeFlower.prototype.flatten = function(root) {
var nodes = [], i = 0;

function recurse(node) {
if (node.children) {
node.size = node.children.reduce(function(p, v) {
return p + recurse(v);
}, 0);
}
if (!node.id) node.id = ++i;
nodes.push(node);
return node.size;
}

root.size = recurse(root);
return nodes;
};

CodeFlower.prototype.click = function(d) {
// Toggle children on click.
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
this.update();
};

CodeFlower.prototype.mouseover = function(d) {
this.text.attr('transform', 'translate(' + d.x + ',' + (d.y - 5 - (d.children ? 3.5 : Math.sqrt(d.size) / 2)) + ')')
.text(d.name)
.style('display', null);
};

CodeFlower.prototype.mouseout = function(d) {
this.text.style('display', 'none');
};

CodeFlower.prototype.tick = function() {
var h = this.h;
var w = this.w;
this.link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });

this.node.attr("transform", function(d) {
return "translate(" + Math.max(5, Math.min(w - 5, d.x)) + "," + Math.max(5, Math.min(h - 5, d.y)) + ")";
});
};

CodeFlower.prototype.cleanup = function() {
this.update([]);
this.force.stop();
};

我试过在某些网站上使用环绕文字功能,但它不起作用。任何帮助将不胜感激,非常感谢:)

最佳答案

如果您想使用 Mike Bostock 的 wrap函数,你必须调用它:

var foo = svg.append("text")
.attr("y", someValue)
.attr("dy", 0)
.text("foo bar baz")
.call(wrap, textWidth);//some value here

您可以直接设置 y 位置,并使用“转换”设置 x 位置(除非您在 <tspan> 函数内更改 wrap 的“x”属性)。

这是一个演示:

var svg = d3.select("svg");
var text = svg.append("text")
.attr("y", 20)
.attr("dy", 0)
.attr("transform", "translate(10,0)")
.text("this pure SVG text element is a very long long long long long long long long long long long long long long long long long long long long long long long long text indeed.")
.call(wrap, 280);

function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg style="background-color:wheat"></svg>

关于javascript - 如何在 d3 中换行以适合屏幕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41429192/

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