简体   繁体   English

从Elasticsearch创建Wordcloud d3.js

[英]Create wordcloud d3.js from elasticsearch

I am using the following example as base and want to make it dynamic word cloud https://github.com/jasondavies/d3-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; });
});

this is example code from elasticsearch website how to use with d3 这是来自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>

This is code from d3 jason davies about wordcloud 这是来自d3 jason davies的有关wordcloud的代码

How to make d3 wordcloud to listen data from elasticsearch ? 如何使d3 wordcloud侦听来自Elasticsearch的数据?

You'll need to get the elasticsearch response data into a format that's easy to pass into the wordcloud sample code, something like this: 您需要将elasticsearch响应数据转换成易于传递到wordcloud示例代码中的格式,如下所示:

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

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

The response you get back from your Elasticsearch aggregation will look something like this: 您从Elasticsearch聚合中获得的响应如下所示:

回应

You'll also see this in a console when the ES response is logged: 记录ES响应后,您还将在控制台中看到以下内容:

}).then(function (resp) {
  console.log(resp);
  ...

So to manipulate that data, add: 因此,要操作该数据,请添加:

var data = resp.aggregations.myaggregation.buckets.map(function(d) {
  return {
    text: d.key,
    size: d.doc_count
  };
});

Note that myaggregation is a name you will define. 请注意, myaggregation是您将定义的名称。 In your NFL example code above it's actually called touchdowns 在上面的NFL示例代码中,它实际上称为touchdowns

Pushing this data straight into the wordcloud will cause problems, however. 但是,将这些数据直接推送到wordcloud会引起问题。 In the wordcloud example, the font-size is determined directly from the size, but there's a good chance your doc_count s are much too high, and will need to be scaled down. 在wordcloud示例中, font-size是直接由font-size决定的,但是您的doc_count很有可能太大了,需要缩小比例。

For that, try D3 linear scale. 为此,请尝试D3线性刻度。 In this case, it will scale the range of input values down to a value between 15 and 100, which can be used for font size: 在这种情况下,它将把输入值的范围缩小到15到100之间的一个值,该值可用于字体大小:

var fontsize = d3.scale.linear()
  .domain(d3.extent(data, function (d) {return d.size}))
  .range([15, 100]);

Then, instead of 然后,代替

.style("font-size", function (d) {
  return d.size + "px";
})

use: 采用:

.style("font-size", function (d) {
  return fontsize(d.size) + "px";
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM