【问题标题】:Create wordcloud d3.js from elasticsearch从 elasticsearch 创建 wordcloud d3.js
【发布时间】:2015-04-08 16:27:06
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    您需要将 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_counts 太高了,需要按比例缩小。

    为此,请尝试 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";
    })
    

    【讨论】:

    • 现在我按照您的要求完成了它的工作:),但为什么会出现这张图片,s4.postimg.org/no5jzve59/rere.png
    • 这很奇怪。看起来您要显示的文本实际上是一个对象。如果您更改:.text(function(d) { return d.text; });.text(function(d) { console.log(d.text); return d.text; });,您将能够在浏览器控制台中看到该对象是什么。他们应该能够弄清楚如何访问所需的文本位。如果这不起作用,您可以发布您的代码吗?
    • 我点了错误的数据,现在它可以运行了:)......谢谢亨利,非常感谢你的回答
    • Henry 的尺寸不起作用,这是示例,plnkr.co/edit/7UKIN3tPOgIrGFuJJzRr?p=preview 如何根据频率进行排列...抱歉我使用的英语不好,希望您能理解
    • 在那个 plunk 中,有些词没有显示,因为它们超过了 SVG 元素可以容纳的最大字长(font-size 和字长)。如果你增加宽度 (var w = 400) 和高度,你会得到这些词。但是,您应该按照上述比例缩小尺寸。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    相关资源
    最近更新 更多