我使用以下示例作为基础,并希望将其设为动态词云https://github.com/jasondavies/d3-cloud
define(['scripts/d3.v3', 'scripts/elasticsearch'], function (d3, elasticsearch) {
"use strict";
var client = new elasticsearch.Client();
client.search({
index: 'nfl',
size: 5,
body: {
// Begin query.
query: {
// Boolean query for matching and excluding items.
bool: {
must: { match: { "description": "TOUCHDOWN" }},
must_not: { match: { "qtr": 5 }}
}
},
// Aggregate on the results
aggs: {
touchdowns: {
terms: {
field: "qtr",
order: { "_term" : "asc" }
}
}
}
// End query.
}
}).then(function (resp) {
console.log(resp);
// D3 code goes here.
var touchdowns = resp.aggregations.touchdowns.buckets;
// d3 donut chart
var width = 600,
height = 300,
radius = Math.min(width, height) / 2;
var color = ['#ff7f0e', '#d62728', '#2ca02c', '#1f77b4'];
var arc = d3.svg.arc()
.outerRadius(radius - 60)
.innerRadius(120);
var pie = d3.layout.pie()
.sort(null)
.value(function (d) { return d.doc_count; });
var svg = d3.select("#donut-chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/1.4 + "," + height/2 + ")");
var g = svg.selectAll(".arc")
.data(pie(touchdowns))
.enter()
.append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function (d, i) {
return color[i];
});
g.append("text")
.attr("transform", function (d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.style("fill", "white")
.text(function (d) { return d.data.key; });
});
这是来自elasticsearch网站的示例代码,如何与d3一起使用
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="../lib/d3/d3.js"></script>
<script src="../d3.layout.cloud.js"></script>
<script>
var fill = d3.scale.category20();
d3.layout.cloud().size([300, 300])
.words([
"Hello", "world", "normally", "you", "want", "more", "words",
"than", "this"].map(function(d) {
return {text: d, size: 10 + Math.random() * 90};
}))
.padding(5)
.rotate(function() { return ~~(Math.random() * 2) * 90; })
.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.text; });
}
</script>
这是d3 jason davies关于wordcloud的代码
如何让d3 wordcloud收听来自elasticsearch的数据?
答案 0 :(得分:4)
您需要将elasticsearch响应数据转换为易于传递到wordcloud示例代码的格式,如下所示:
var data = [{
"text": "How",
"size": 20
}, {
"text": "to",
"size": 30
}, ... ]
请参阅:http://jsfiddle.net/henbox/RUTpJ/659/
您从Elasticsearch聚合中获得的响应将如下所示:
当记录ES响应时,您还会在控制台中看到这一点:
}).then(function (resp) {
console.log(resp);
...
因此,要操纵该数据,请添加:
var data = resp.aggregations.myaggregation.buckets.map(function(d) {
return {
text: d.key,
size: d.doc_count
};
});
请注意,myaggregation
是您要定义的名称。在上面的NFL示例代码中,它实际上称为touchdowns
将这些数据直接输入wordcloud会导致问题。在wordcloud示例中,font-size
是直接根据大小确定的,但是doc_count
s很可能太高,需要按比例缩小。
为此,尝试D3线性刻度。在这种情况下,它会将输入值的范围缩小到15到100之间的值,可以用于字体大小:
var fontsize = d3.scale.linear()
.domain(d3.extent(data, function (d) {return d.size}))
.range([15, 100]);
然后,而不是
.style("font-size", function (d) {
return d.size + "px";
})
使用:
.style("font-size", function (d) {
return fontsize(d.size) + "px";
})