javascript - d3.js:使用新数据集刷新图表

标签 javascript d3.js

我已经创建了 d3 PCP 图表,这是我的代码:

 var m = [60, 10, 10, 60],
      w = 1000 - m[1] - m[3],
      h = 270 - m[0] - m[2];

 var  x=d3.scaleOrdinal()
    .range([0, w]),
      y = {},
      dragging = {};

    var line = d3.line(),
      background,
      foreground;

 var svg = d3.select("#test").append("svg:svg")
      .attr("width", w + m[1] + m[3])
      .attr("height", h + m[0] + m[2])
      .append("svg:g")
      .attr("transform", "translate(" + m[3] + "," + m[0] + ")");   

    //let dimensions
    // Extract the list of dimensions and create a scale for each.
     x.domain(this.dimensions = d3.keys(data[0]).filter(function(d) {
      if (d === "name") return false;
      if (d === "Plant" || d === "Chemical" || d === "Pathway" || d === "Gene" || d === "Disease") {
        y[d] = d3.scaleOrdinal()
          .domain(data.map(function(p) {
            return p[d];
          }))
          .range([h, 0]);
      } else {
       y[d] = d3.scaleLinear().domain([0, d3.max(data.map(function(p) { return p[d]; }))]).range([h, 0]);
      }
      return true;
    }));

    //alert(this.dimensions)

    // Add grey background lines for context.  
    background = svg.append("svg:g")
      .attr("class", "background")
      .selectAll("path")
      .data(data)
      .enter().append("svg:path")
       .style('fill', 'none')
       .attr("d", path.bind(this));


    // Add blue foreground lines for focus.
    foreground = svg.append("svg:g")
      .attr("class", "foreground")
      .selectAll("path")
      .data(data)
      .enter().append("svg:path")
       .style('fill', 'none')
       .style('stroke', 'steelblue')
      .attr("d", path.bind(this));

    // Add a group element for each dimension.
    let g = svg.selectAll(".dimension")
      .data(this.dimensions)
   .enter().append("svg:g")
      .attr("class", "dimension")
      .attr("transform", function(d) {
        return "translate(" + x(d) + ")";
      })


    // Add an axis and title.
    g.append("svg:g")
      .attr("class", "axis")
      .each(function(d) {
        d3.select(this).call(d3.axisLeft(y[d]));
      })
      .append("svg:text")
      .attr("text-anchor", "middle")
      .attr("y", -50)
      .attr("x",-10)
      .style("fill", "black")
       .text(function(d) {return d });   


    var firstAxis = d3.selectAll('g.dimension g.axis');

    firstAxis
      .append("svg:image")
      .attr('x',-20)
      .attr('y',-60)
      .attr('width', 40)
      .attr('height', 60)
      .attr("xlink:href", function(s) {
        return "images/" + s+'.png';
      });

    function position(d) {
      var v = dragging[d];
      return v == null ? x(d) : v;
    }

    function transition(g) {
      return g.transition().duration(500);
    }

    // Returns the path for a given data point.
    function path(d) {
           return line(this.dimensions.map(function(p) {
          return [position(p), y[p](d[p])];
      }));

    }

我的网页上有一个简单的输入,其中显示一些输入下拉列表,并根据每次将新数据集传递到脚本时传递的选定值。每次用户更改表单上的值时,都会发送一个新数据集到我的脚本。我正在努力弄清楚如何使用新数据集更新(刷新)图表,我尝试使用 exitremove 函数,但没有取得太大成功。

svg.exit().remove();

最佳答案

退出方法:

Returns the exit selection: existing DOM elements in the selection for which no new datum was found. (The exit selection is empty for selections not returned by selection.data.) (API documentation).

虽然您已为选区g前景背景指定了数据,但尚未为选区指定任何数据>svg,因此退出选择将为空。因此,.remove() 无法删除任何内容。

<小时/>

要使用退出选择,请注意退出选择不会删除选择中的元素。它是选择中不再具有相应绑定(bind)数据的元素子集的选择。

如果一个选择包含 10 个 DOM 元素,并且该选择的数据数组设置为包含 9 个元素的数组,则退出选择将包含一个元素:多余的元素。

我们可以使用 .exit().remove() 删除这个子集。退出是我们不再需要哪些元素,remove() 会删除它们。 Exit 不会删除元素,因为我们可能仍想对它们执行某些操作,例如转换它们或隐藏它们等。

如上面引用中所述,要填充退出选择,您必须使用 Selection.data():

var selection = svg.selectAll("path")
  .data(data);

现在我们可以访问进入选择、退出选择和更新选择。

除非指定一个键,否则只有进入或退出选择之一可以包含元素:如果我们需要更多元素,我们不需要退出任何元素,如果我们有多余的元素,我们不需要任何新元素。

要删除多余的元素,我们现在可以使用:

var selection = svg.selectAll("path")
  .data(data);    

selection.exit().remove();

假设您正在为其他选择指定数据,例如 foregroundbackgroundg,这些是您应该使用的选择。 exit() 开启,作为完整的进入/更新/退出循环的一部分。请记住,在 d3v4 中,您需要合并更新并输入选择,以便对选择中预先存在的元素和新元素执行操作。

<小时/>

但是,如果您只是想删除 svg 并重新开始(这就是您想要做的 - 当您尝试删除 svg 时),您可以简单地删除 svg:

d3.select("#test")
  .select("svg")
  .remove();

但是,这不允许您在图表之间很好地转换或利用进入/更新/退出循环。

为什么要注意使用 svg.remove()?因为选择 svg 包含一个 g 元素:

 var svg = d3.select("#test") // returns a selection with #test
      .append("svg:svg")      // returns a selection with the new svg
      .attr(...)              // returns the selection with the newly created svg again
      .append("svg:g")        // returns a selection with the new g
      .attr(...);             // returns the selection with the newly created g again

svg 因此是 g 的选择,删除它不会删除 svg 元素。事实上,在 svg.remove() 之后运行上述代码块会向 DOM 添加一个新的 svg 元素,同时不会删除旧的元素。

关于javascript - d3.js:使用新数据集刷新图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47462098/

相关文章:

javascript - 达到div高度后jquery从右到左滑动文本

javascript - 创建可点击的视频缩略图,在上方同一页面上加载视频

javascript - 如何打破 JavaScript 中的闭包

javascript - 创建 Microsoft.Maps.Search.Address 的实例

svg - 如何根据数据创建 SVG 形状?

javascript - 如何确保树形图单元格中的文本不会溢出?

javascript - 在 Opera 中发出 iframe 的重定向父级问题

javascript - 使用D3生成SVG饼图如何垂直对齐文本

javascript - 处理元素时 d3 与 svg

javascript - D3.js 过渡多个弧路径