D3 词云:如何自动调整字体大小,使文字不会 运行 出来,并将文字缩放到所有屏幕?
D3 word-cloud: how to auto size the font so words will not run out , and to scale words to all the screen?
我正在使用 Jason Davies d3-cloud.js 来实现我的词云,here
1.The 字是 运行 每当 initial window 尺寸太小。
所以为此我有计算单词大小所需像素的函数,但我使用的 if else 条件并不总是有效:
_.forEach(data, function (word) {
pixNeeded += that.wordService.calcFontSize(word.id) * word.text.length;
});
that.divideBy = pixNeeded < 7000 ? 2.5
: pixNeeded < 9000 ? 2
: pixNeeded < 12000 ? 1.7
: pixNeeded < 13000 ? 1.6
: pixNeeded < 15000 ? 1.5
: pixNeeded < 16000 ? 1.4
: pixNeeded < 17000 ? 1.3
: 1;
if (that.h<600 ||that.w<500) // little window handling
{
that.divideBy=1;
that.scale=0.8;
if(pixNeeded>15000) { //small window+lots of words handling by shrink font
that.wordService.fontMax = 24;
that.wordService.fontMin = 8;
}
我在此处使用 this.divideBy
布局大小:
this.layout = d3.layout.cloud().size([that.w / that.divideBy, that.h / that.divideBy])
有没有更聪明的算法?或使 g 元素适合外部 div?
的方法
- 调整字号后,文字不会运行出来,我希望文字能覆盖所有div,云在屏幕上后我可以做到,通过(SVG width)/(g width) = width scale 然后将宽度比例手动应用于 g 元素。但是如何在 javascript 中做到这一点?
如果您希望单词根据父元素的宽度调整大小,那么这可能会有所帮助
.style("font-size", function(d) { return Math.min(2 * r, (2 * r - 8) / this.getComputedTextLength() * 24) + "px"; });
r 依赖于父元素
不太确定,这是否是您要查找的内容
要计算 font-size,您必须创建此比例:
var fontSizeScale = d3.scale.pow().exponent(5).domain([0,1]).range([ minFont, maxFont]);
并在fontSize函数中调用:
var maxSize = d3.max(that.data, function (d) {return d.size;});
// on the d3.layout.cloud()
.fontSize(function (d) {
return fontSizeScale(d.size/maxSize);
})
为了适应您的 screen/div:
在.on("end",drawCloud)函数中,调用这个函数:
function zoomToFitBounds() {
var X0 = d3.min( words, function (d) {
return d.x - (d.width/2);
}),
X1 = d3.max( words, function (d) {
return d.x + (d.width/2);
});
var Y0 = d3.min( words, function (d) {
return d.y - (d.height/2);
}),
Y1 = d3.max( words, function (d) {
return d.y + (d.height/2);
});
var scaleX = (X1 - X0) / (width);
var scaleY = (Y1 - Y0) / (height);
var scale = 1 / Math.max(scaleX, scaleY);
var translateX = Math.abs(X0) * scale;
var translateY = Math.abs(Y0) * scale;
cloud.attr("transform", "translate(" +
translateX + "," + translateY + ")" +
" scale(" + scale + ")");
}
我正在使用 Jason Davies d3-cloud.js 来实现我的词云,here
1.The 字是 运行 每当 initial window 尺寸太小。 所以为此我有计算单词大小所需像素的函数,但我使用的 if else 条件并不总是有效:
_.forEach(data, function (word) {
pixNeeded += that.wordService.calcFontSize(word.id) * word.text.length;
});
that.divideBy = pixNeeded < 7000 ? 2.5
: pixNeeded < 9000 ? 2
: pixNeeded < 12000 ? 1.7
: pixNeeded < 13000 ? 1.6
: pixNeeded < 15000 ? 1.5
: pixNeeded < 16000 ? 1.4
: pixNeeded < 17000 ? 1.3
: 1;
if (that.h<600 ||that.w<500) // little window handling
{
that.divideBy=1;
that.scale=0.8;
if(pixNeeded>15000) { //small window+lots of words handling by shrink font
that.wordService.fontMax = 24;
that.wordService.fontMin = 8;
}
我在此处使用 this.divideBy
布局大小:
this.layout = d3.layout.cloud().size([that.w / that.divideBy, that.h / that.divideBy])
有没有更聪明的算法?或使 g 元素适合外部 div?
的方法- 调整字号后,文字不会运行出来,我希望文字能覆盖所有div,云在屏幕上后我可以做到,通过(SVG width)/(g width) = width scale 然后将宽度比例手动应用于 g 元素。但是如何在 javascript 中做到这一点?
如果您希望单词根据父元素的宽度调整大小,那么这可能会有所帮助
.style("font-size", function(d) { return Math.min(2 * r, (2 * r - 8) / this.getComputedTextLength() * 24) + "px"; });
r 依赖于父元素
不太确定,这是否是您要查找的内容
要计算 font-size,您必须创建此比例:
var fontSizeScale = d3.scale.pow().exponent(5).domain([0,1]).range([ minFont, maxFont]);
并在fontSize函数中调用:
var maxSize = d3.max(that.data, function (d) {return d.size;});
// on the d3.layout.cloud()
.fontSize(function (d) {
return fontSizeScale(d.size/maxSize);
})
为了适应您的 screen/div:
在.on("end",drawCloud)函数中,调用这个函数:
function zoomToFitBounds() {
var X0 = d3.min( words, function (d) {
return d.x - (d.width/2);
}),
X1 = d3.max( words, function (d) {
return d.x + (d.width/2);
});
var Y0 = d3.min( words, function (d) {
return d.y - (d.height/2);
}),
Y1 = d3.max( words, function (d) {
return d.y + (d.height/2);
});
var scaleX = (X1 - X0) / (width);
var scaleY = (Y1 - Y0) / (height);
var scale = 1 / Math.max(scaleX, scaleY);
var translateX = Math.abs(X0) * scale;
var translateY = Math.abs(Y0) * scale;
cloud.attr("transform", "translate(" +
translateX + "," + translateY + ")" +
" scale(" + scale + ")");
}