javascript - 带搜索框的 D3 图表

标签 javascript html css d3.js

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

enter image description here

我的问题:一旦将搜索输入框(即“鱼”),网站访问者必须点击“刷新”才能运行新搜索(即“狗”)。相反,我更喜欢这样,当开始新的搜索时,图表仍然可见,而“尝试”按钮只是切换节点的颜色以反射(reflect)新的搜索选择。这是我到目前为止所拥有的:

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。我还尝试将与圆圈颜色相关的 block 复制粘贴到 sayHi 函数,但这会使图形无响应。

感谢任何帮助。

最佳答案

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

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

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 是您选择的圈子。请记住为您的选择命名。

这是一个使用您的代码的演示:https://jsfiddle.net/dhy4yt2z/1/

PS:您的代码还有其他几个小问题需要更正,例如边距的使用。

关于javascript - 带搜索框的 D3 图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50361571/

相关文章:

javascript - 如何使用 native JavaScript Promise 执行延迟模式?

html - 我想给 fa 图标 HTML 上色

jquery - 如何更改选择标签的触发事件?

javascript - IE(移动)不显示触摸子元素

HTML:调整 br 元素之间的高度

javascript - 如何通过检查元素的子元素是否具有特定的类名来将 css 属性添加到元素的伪类

javascript - 动画光标不适用于 anchor

javascript - 检索用户添加到表中的数据

javascript - 用ajax检查下载时间?

javascript - AngularJS - 在第一个可见元素上应用 CSS 类(最好不要使用 JQuery)