Javascript D3WordCloud中的重叠

Javascript D3WordCloud中的重叠,javascript,d3.js,overlap,word-cloud,Javascript,D3.js,Overlap,Word Cloud,我在d3()中使用Jason Davies的wordcloud库,我的问题是云中的单词重叠 我知道在堆栈溢出(和其他站点)上已经有关于这个问题的问题,但在我的案例中,这些问题都没有帮助 在下面的示例中,我使用了Jason Davies网站上的示例云,并仅更改了一些内容: 我从外部文件中读取单词及其大小 我将旋转设置为0。旋转角度似乎并没有什么不同 我注释掉了“Impact”字体,以排除加载字体时出现的任何问题。(不过这也没什么区别。) 这是我的密码: <!DOCTYPE html>

我在d3()中使用Jason Davies的wordcloud库,我的问题是云中的单词重叠

我知道在堆栈溢出(和其他站点)上已经有关于这个问题的问题,但在我的案例中,这些问题都没有帮助

在下面的示例中,我使用了Jason Davies网站上的示例云,并仅更改了一些内容:

  • 我从外部文件中读取单词及其大小
  • 我将旋转设置为0。旋转角度似乎并没有什么不同
  • 我注释掉了“Impact”字体,以排除加载字体时出现的任何问题。(不过这也没什么区别。)
这是我的密码:

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="d3.js"></script>
<script src="d3.layout.cloud.js"></script>
<script>
   d3.tsv("testdata.txt", 
  function(error, data) {

  var fill = d3.scale.category20();



  d3.layout.cloud().size([300, 300])
      .words(data)
      .padding(1)
      .rotate(function(d) { return 0; })
  //    .font("Impact")
      .fontSize(function(d) { return d.size; })
      .on("end", draw)
      .start();

  function draw(words) {
    d3.select("body").append("svg")
        .attr("width", 300)
        .attr("height", 300)
      .append("g")
        .attr("transform", "translate(150,150)")
      .selectAll("text")
        .data(words)
      .enter().append("text")
        .style("font-size", function(d) { return d.size + "px"; })
    //    .style("font-family", "Impact")
        .style("fill", function(d, i) { return fill(i); })
        .attr("text-anchor", "middle")
        .attr("transform", function(d) {
          return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
        })
        .text(function(d) { return d.word; });
  }
  }
  )

</script>
如果我用测试数据运行js脚本,我的word cloud就会出现重叠。有时,它只发生在几次重新加载之后,但这是相当频繁的

其他人报告了同样的问题,发现这与使用web字体或跳过rotate参数有关。这不适用于我的示例

我怀疑这可能与画布大小有很多单词这一事实有关,然而,我也做了一些测试,在测试中我显著地增加了画布大小,但这种情况仍然发生(虽然不太频繁,因为单词的随机放置使其不太可能发生)。除此之外,您还可以看到,由于画布尺寸较小,一些单词根本没有显示。为什么要遗漏一些内容,而为其他内容创建重叠?因此,我认为问题在别处

有什么想法吗


谢谢

我最后问了Jason Davies自己,这实际上是一个非常简单的错误:必须在第一条语句中指定文本访问器函数(而不仅仅是“draw”函数)。如果您添加一行如下所示,则它会起作用:

d3.layout.cloud().size([300, 300])
  .words(data)
  .padding(1)
  .rotate(function(d) { return 0; })
//    .font("Impact")
  .text(function(d) { return d.word; }) // THE SOLUTION
  .fontSize(function(d) { return d.size; })
  .on("end", draw)
  .start();

我试过一个样品供你摆弄, 请看一看。

基本上:

<div id="cloud"></div> 

// First define your cloud data, using `text` and `size` properties:


var fill = d3.scale.category20();
var words = {
"Battery Related": "52382",
"Billing": "52412",
"Break Related": "52490",
"Chain Related": "52471",
"Clutch Related": "52468",
"Dealer attitude": "52488",
"Electrical Related": "52352",
"Engine Related": "52446",
"Handle Bar Related": "52486",
"Happy": "52472",
"Jerking": "52325",
"Jerking Problem": "52325",
"Low Mileage": "52489",
"Noise": "52462",
"Poor Pickup": "52406",
"Running Off": "52242",
"Service Quality": "52488",
"Silencer Problem": "52468",
"Starting Trouble": "52490",
"Suspension Related": "52365",
"Vehicle Noise": "52467",
"Vibration": "52463",
"Washing": "52488"
};
var max_freq = 52490;
var cloudwords = ["Battery Related", "Billing", "Break Related", "Chain Related", "Clutch Related", "Dealer attitude", "Electrical Related", "Engine Related", "Handle Bar Related", "Happy", "Jerking", "Jerking Problem", "Low Mileage", "Noise", "Poor Pickup", "Running Off", "Service Quality", "Silencer Problem", "Starting Trouble", "Suspension Related", "Vehicle Noise", "Vibration", "Washing"];
var url = 'http://xxx.yyyy.zz.ww/?q=abc/';
var width = 800,
height = 800;

var leaders = cloudwords
.map(function(d) {

return {
  text: d,
  size: 5 + (words[d] / max_freq) * 0.9 * 30 // *the size of the "box" occupied by each word. has no relation to text size.
};
})
 .sort(function(a, b) {
 return d3.descending(a.size, b.size)
});

var leaderScale = d3.scale.linear().range([1, 20]); // *scale range to plot the relative sizes of the words.

leaderScale.domain([d3.min(leaders, function(d) {
return d.size;
}),
d3.max(leaders, function(d) {
return d.size;
})
]);

 // Next you need to use the layout script to calculate the placement, rotation and size of each word:

 d3.layout.cloud().size([width, height])
.words(leaders)
.padding(0) //fiddle with padding here, does not really have any effect    on overlap.
.rotate(function() {
 return ~~0; //to keep the words horizontal 
 })
 .font("Impact")
 .fontSize(function(d) {
 return d.size;
 })
 .on("end", drawCloud)
 .start();

 function drawCloud(words) {
 d3.select("#cloud").append("svg")
 .attr("width", width)
 .attr("height", height)
 .attr("text-align", "center")
 .append("g")
 .attr("transform", "translate(" + [width >> 1, height >> 1] + ")")    //for transalting words to their different postions.
 .selectAll("text")
 .data(words)
 .enter().append("text")
 .style("font-size", function(d) {
  return leaderScale(d.size) + "px"; //used scale to resize words to a linear scale.
 })
 .style("font-family", "Impact")
 .style("fill", function(d, i) {
  return fill(i);
 })
 .attr("text-anchor", "middle")
 .attr("transform", function(d) {
  return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
 })
 .text(function(d) {
  return d.text;
 })
 .on("click", function(d, i) {
  window.open(url + d.text);
 });
 }

 // set the viewbox to content bounding box (zooming in on the content, effectively trimming whitespace)

 var svg = document.getElementsByTagName("svg")[0];
 var bbox = svg.getBBox();
 var viewBox = [bbox.x, bbox.y, bbox.width, bbox.height].join(" ");
 svg.setAttribute("viewBox", viewBox);

//首先使用“text”和“size”属性定义云数据:
var fill=d3.scale.category20();
变量字={
“电池相关”:“52382”,
“账单”:“52412”,
“中断相关”:“52490”,
“链相关”:“52471”,
“离合器相关”:“52468”,
“经销商态度”:“52488”,
“电气相关”:“52352”,
“发动机相关”:“52446”,
“把手相关”:“52486”,
“快乐”:“52472”,
“抽搐”:“52325”,
“抖动问题”:“52325”,
“低里程”:“52489”,
“噪音”:“52462”,
“捡拾不良”:“52406”,
“流失”:“52242”,
“服务质量”:“52488”,
“消声器问题”:“52468”,
“起动故障”:“52490”,
“暂停相关”:“52365”,
“车辆噪音”:“52467”,
“振动”:“52463”,
“清洗”:“52488”
};
var max_freq=52490;
var cloudwords=[“与电池相关”、“计费”、“与断开相关”、“与链条相关”、“与离合器相关”、“经销商态度”、“与电气相关”、“与发动机相关”、“与把手相关”、“开心”、“抖动”、“抖动问题”、“低里程数”、“噪音”、“拾音不良”、“跑偏”、“服务质量”、“消声器问题”、“起动故障”,“悬架相关”、“车辆噪音”、“振动”、“清洗”];
var url='1〕http://xxx.yyyy.zz.ww/?q=abc/';
可变宽度=800,
高度=800;
var leaders=cloudwords
.地图(功能(d){
返回{
案文:d,
大小:5+(单词[d]/max_freq)*0.9*30//*每个单词所占“框”的大小。与文本大小无关。
};
})
.排序(功能(a、b){
返回d3.递减(a.大小,b.大小)
});
var leaderScale=d3.scale.linear().range([1,20]);//*scale range以绘制单词的相对大小。
leaderScale.domain([d3.min(leaders,function(d)){
返回d.size;
}),
d3.最大值(引线、功能(d){
返回d.size;
})
]);
//接下来,您需要使用布局脚本计算每个单词的位置、旋转和大小:
d3.layout.cloud().size([宽度,高度])
.文字(领导人)
.padding(0)//在此处使用填充,实际上对重叠没有任何影响。
.旋转(函数(){
return~~0;//保持单词水平
})
.font(“影响”)
.fontSize(函数(d){
返回d.size;
})
.on(“结束”,drawCloud)
.start();
函数drawCloud(字){
d3.选择(“#云”)。追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度)
.attr(“文本对齐”、“居中”)
.附加(“g”)
.attr(“transform”、“translate”(“+[width>>1,height>>1]+”)/),用于将单词转换到不同的位置。
.selectAll(“文本”)
.数据(字)
.enter().append(“文本”)
.样式(“字体大小”,功能(d){
返回leaderScale(d.size)+“px”;//用于将单词大小调整为线性刻度的刻度。
})
.style(“字体系列”、“影响”)
.样式(“填充”,功能(d,i){
返回填充(i);
})
.attr(“文本锚定”、“中间”)
.attr(“转换”,函数(d){
返回“translate(“+[d.x,d.y]+”)rotate(“+d.rotate+”)”;
})
.文本(功能(d){
返回d.text;
})
.on(“点击”),功能(d,i){
打开(url+d.text);
});
}
//将viewbox设置为内容边界框(放大内容,有效地修剪空白)
var svg=document.getElementsByTagName(“svg”)[0];
var bbox=svg.getBBox();
var viewBox=[bbox.x,bbox.y,bbox.width,bbox.height]。连接(“”);
setAttribute(“viewBox”,viewBox);

作者的修复对我不起作用。有效的方法是指定
.font()
在云布局设置中
并在绘图代码中声明相同的字体系列-具有讽刺意味的是,上面作者注释掉了该位。这为代码提供了计算尺寸的字体。如果没有它,则需要进行最佳猜测

d3.layout.cloud().size([800, 400])
  .words(words)
  .font('Impact') // <-- what mattered
  .fontSize(d => d.size)
  .on('end', draw)
  .start()

同意存在一些困难。但是,在使用维度(布局和svg)和字体系列时,可能会偶尔出现相对轻微的重叠(但这些重叠的可接受程度可能有点主观).无论如何,这是我为玩它而创建的一个。至少,我相信这些维度在排除单词的基础上有所改进…看起来它们中的大多数都在那里(尽管它们都需要在那里)。是的,谢谢。就我所见,你更改了维度和字体?这对我来说确实很好用
d3.layout.cloud().size([800, 400])
  .words(words)
  .font('Impact') // <-- what mattered
  .fontSize(d => d.size)
  .on('end', draw)
  .start()
.attr('font-family', 'Impact')