从elasticsearch创建wordcloud d3.js

时间:2015-02-09 00:40:37

标签: javascript json d3.js elasticsearch word-cloud

我使用以下示例作为基础,并希望将其设为动态词云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的数据?

1 个答案:

答案 0 :(得分:4)

您需要将elasticsearch响应数据转换为易于传递到wordcloud示例代码的格式,如下所示:

var data = [{
    "text": "How",
    "size": 20
}, {
    "text": "to",
    "size": 30
}, ... ]

请参阅:http://jsfiddle.net/henbox/RUTpJ/659/

您从Elasticsearch聚合中获得的响应将如下所示:

es response

当记录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";
})