带搜索框的D3图表 [英] D3 chart with search box

查看:102
本文介绍了带搜索框的D3图表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在D3中创建了一个图表,其中节点显示特定个人创建文档的时间。该图表还提供了一个搜索框,根据搜索框输入是否与该文档关联的单词匹配,将节点变为红色(这些单词列在数据集的第5列中 - 请参阅下面的数据集)。

I have created a chart in D3 where nodes show the time at which particular individuals created a document. The chart also presents a search box, which turns nodes red depending on whether the search box input matches the words associated to that document (these words are listed in column 5 of the dataset - please see below for dataset).

我的问题:一旦搜索到了输入到框中(即'fish'),网站访问者必须点击'刷新'才能运行新的搜索(即'dog')。我希望相反,当启动新搜索时图表仍然可见,并且尝试按钮仅切换节点的颜色以反映新的搜索选择。这是我到目前为止所拥有的:

My problem: once a search has been input into the box (ie. 'fish'), the website visitor must hit 'refresh' in order to run a new search (ie. 'dog'). I would prefer that instead, the chart remains visible when a new search is initiated, and the 'try it' button merely switches the colours of the nodes to reflect the new search choice. Here's what I have so far:

html,
body {
  margin: 0;
  height: 100%;
}

g.hidden line,
g.hidden path {
  display: none;
}

path {
  stroke: navy;
  stroke-width: 2px;
  fill: none;
}

circle {
  fill: #FF00FF;
  stroke: navy;
  stroke-width: 2px;
}

g.tick text y {
  font-size: 30px;
  font: Garamond;
}

g.tick text x {
  font-size: 10px;
  font: Garamond;
}

g.tick line {
  display: none;

<!-- begin snippet: js hide: false console: true babel: false -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta chartset="utf-8">
  <title>Interactive scatterplot</title>
  <link rel="stylesheet" type="text/css" href="style.css">
  <script type="text/javascript" src="d3.v4.js"></script>

</head>

<body>

  <script>
    var txtName = 0;

    function sayHi() {
      var txtName = document.getElementById("txtName");
      console.log(txtName.value);



      var parseDate = d3.timeParse("%m/%d/%Y");

      d3.csv("doc.csv")
        .row(function(d) {
          return {
            creator: d.creator,
            date: parseDate(d.date),
            number: Number(d.number),
            doc: d.doc
          };
        })
        .get(function(error, data) {
          var height = 300;
          var width = 500;

          var minDate = new Date(2000, 1, 1);
          var maxDate = new Date(2011, 1, 1);

          var y = d3.scaleOrdinal()
            .domain(['', 'may', 'milly', 'maggie', 'molly', ''])
            .range([300, 225, 150, 75, 15, 0]);

          var x = d3.scaleTime()
            .domain([minDate, maxDate])
            .range([0, width]);

          var yAxis = d3.axisLeft(y);
          var xAxis = d3.axisBottom(x);

          var svg = d3.select("body").append("svg").attr("height", "100%").attr("width", "100%");

          margin = {
            top: 40,
            right: 50,
            bottom: 0,
            left: 50
          };

          var redBox = svg.append("rect")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .attr("y", 0)
            .attr("width", width)
            .attr("height", height)
            .attr("fill", "orange");

          var chartGroup = svg.append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

          svg.selectAll("circle")
            .data(data)
            .enter().append("circle")
            //.filter(function(d) {return d.doc = "milly";})
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .attr("cx", function(d) {
              return x(d.date);
            })
            .attr("cy", function(d) {
              return y(d.creator);
            })
            .attr("r", 4)
            .style("fill", function(d) {
              if (d.doc == txtName.value) {
                return "red"
              } else {
                return "black"
              }
            });
          console.log(txtName.value);

          chartGroup.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(d3.axisBottom(x).ticks(14));
          chartGroup.append("g").attr("class", "y axis").call(d3.axisLeft(y).ticks(5));

        });
    }
  </script>

  <textarea id="txtName" name="txt-Name" placeholder="Search for something.."></textarea>
  <button onclick="sayHi()">Try it</button>

  <!-- <div class="test-wrapper"> -->

  <!-- </div><!-- .test-wrapper -->
</body>

</html>

这是数据集:

date	number	creator		doc
6/16/2000	3	molly	3	rat
2/25/2002	4	may	2	cat
12/05/2004	3	molly	4	fish
07/06/2006	1	milly	1	dog
09/07/2003	4	may	4	fish
12/10/2001	4	may	3	rat
6/15/2005	2	maggie	3	rat
06/09/2004	1	milly	4	fish
10/05/2005	1	milly	3	rat
10/07/2003	4	may	1	dog
1/19/2009	4	may	2	cat
10/30/2007	1	milly	4	fish
8/13/2009	4	may	2	cat
9/30/2004	3	molly	1	dog
1/17/2006	4	may	3	rat
12/18/2009	3	molly	1	dog
11/02/2007	2	maggie	3	rat
4/17/2007	1	milly	4	fish

目前,创建图形和获取搜索框值的过程属于一个函数。我尝试将它们分开,但在创建图形之前结束函数意味着图形无法识别变量 txtName 。我还尝试将与圆圈颜色相关的块复制粘贴到 sayHi 函数,但这会使图形无响应。

Currently, the creation of the graph and the process of obtaining the search-box value fall under one function. I tried to make them separate, but ending the function before the creation of the graph meant that the graph did not recognize the variable txtName. I also tried copy-pasting the block relating to the colour of the circles to the sayHi function, but this makes the graph unresponsive.

感谢任何帮助。

推荐答案

现在你正在画画单击按钮后的图表。当用户点击按钮时,更改圆圈的颜色并不是一个好主意。

Right now you're drawing the chart after the button is clicked. That's not a good idea for changing the colours of the circles when the user clicks the button.

因此,删除内联函数调用和 sayHi 功能完全一样。然后,在 d3.tsv 回调(这是TSV,而不是CSV)内,获取文本区域的值:

So, remove that inline function call and the sayHi function altogether. Then, inside the d3.tsv callback (that's a TSV, not a CSV), get the value of the text area:

d3.select("button").on("click", function() {
  var txtName = d3.select("#txtName").node().value;
  circles.style("fill", function(d) {
    return d.doc === txtName ? "red" : "black";
  })
})

此处, circles 是你圈子的选择。请记住为您的选择命名。

Here, circles is your circles' selection. Remember to name your selections.

以下是使用您的代码的演示: https://jsfiddle.net/dhy4yt2z/1/

Here is a demo using your code: https://jsfiddle.net/dhy4yt2z/1/

PS:您的代码还有其他几个应该纠正的小问题,比如利润率的使用。

PS: your code have several other minor issues that should be corrected, like the use of margins.

这篇关于带搜索框的D3图表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆