简体   繁体   English

d3轴标签更新

[英]d3 Axis Label Update

I have tried every permutation of this I can think of, but can not get the axis labels to clear and reset. 我已经尝试过可以想到的所有排列方式,但是无法清除和重置轴标签。 I am creating a heatmap that updates via a dropdown menu. 我正在创建一个通过下拉菜单更新的热图。 The graph shows up and the heatmap data draws correctly. 随即显示该图,并且正确绘制了热图数据。 The issue I am having is that every time the chart gets updated, all of the x-axis labels for the new data get appended as the data updates (but if I go back to a previously loaded set of data, it doesn't append it uses the old labels). 我遇到的问题是,每次更新图表时,新数据的所有x轴标签都会在数据更新时附加(但是如果我返回到先前加载的数据集,则不会附加)它使用旧标签)。 I have tried to create a function that gets called when the dropdown changes that "clears" the graph and then calls another function to "redraw" it. 我尝试创建一个函数,当下拉菜单更改“清除”图形时调用该函数,然后调用另一个函数“重绘”它。 I've tried to make the labels variables, and so on looking at a bunch of examples. 我试图使标签变量化,以此类推。

Even if I run a .remove() - and I have done this on the svg, the g, by g.class, etc. The axis labels just hang on, even though running the remove makes that DOM element disappear. 即使我运行了.remove()-并已在svg,g上(通过g.class等)完成了此操作。即使运行remove会使DOM元素消失,轴标签也仍然挂着。 It seems to have to do with the .exit .remove pattern, but I can't figure out the sequence? 它似乎与.exit .remove模式有关,但我无法弄清楚顺序? Any help would be great. 任何帮助都会很棒。

var dates = [];
var bacteria = [];

var itemHeight = 30,
  itemWidth = 12,
  cellSize = itemHeight - 1,
  margin = {
    top: 120,
    right: 20,
    bottom: 20,
    left: 80
  };

var e = document.getElementById("level");
var value = e.options[e.selectedIndex].value;
var text = e.options[e.selectedIndex].text;

var title = text.charAt(0).toUpperCase() + text.slice(1);
var newtitle = document.getElementById("thelevel").innerHTML=title;

d3.json("./javascripts/biome/biome_new.json").then(function(response) {
  var data = response;

  data.forEach(e => e.ubiome = e.ubiome.filter(e => e.tax_rank === value));

  dates = data.map(function(d) {
    return d.sample_date;
  })

  for (i = 0; i < data.length; i++) {
    bacteria.push(data[i].ubiome.slice(0, data[i].ubiome.length));
  }
  var bacteriaList = d3.merge(bacteria).map(function(d) {
    return d.tax_name
  });

  bacteriaList = d3.set(bacteriaList).values();

  var width = bacteriaList.length*itemWidth,
    height = 500 - margin.top - margin.bottom;

  var y_elements = dates,
    x_elements = bacteriaList;

  var xScale = d3.scaleBand()
    .domain(x_elements)
    .range([0, x_elements.length * itemWidth]);

  var xAxis = d3.axisTop()
    .scale(xScale)
    .tickFormat(function(d) {
      return d;
    });

  var yScale = d3.scaleBand()
    .domain(y_elements)
    .range([0, y_elements.length * itemHeight]);

  var yAxis = d3.axisLeft()
    .scale(yScale)
    .tickFormat(function(d) {
      return  moment(d).format("YYYY-MM-DD");
    });

  var colorScale = d3.scaleSequential(d3.interpolateOrRd)
    .domain([0, 10000]);

  var svg = d3.select('#heatmap')
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  var parents = svg.selectAll('svg')
    .data(data)
    .enter().append('g')
    .attr("transform",function(d) { return "translate(0," + yScale(d.sample_date) + ")" });

  var children = parents.selectAll('rect')
    .data(function(d) { return d.ubiome; })
    .enter()
    .append('rect')
    .attr('class', 'cell')
    .attr('width', 15)
    .attr('height', cellSize)
    .attr('x', function(d) {  return xScale(d.tax_name); })
    .attr('fill', function(d) {
      return colorScale(d.count_norm);
    });

  svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .selectAll('text')
    .attr('font-weight', 'normal');

  svg.append("g")
    .attr("class", "x axis")
    .call(xAxis)
    .selectAll('text')
    .attr('font-weight', 'normal')
    .style("text-anchor", "start")
    .attr("dx", ".8em")
    .attr("dy", "1.2em")
    .attr("transform", function(d) {
      return "rotate(-90)";
    });

    // Remove old elements
  parents.exit().remove();
  children.exit().remove();

});

function clearData(){
  bacteriaList = [];
  dates = [];

  var somemap = d3.selectAll("#heatmap");
  somemap.select("svg").remove();
  d3.select('#heatmap').html("");
  updateData();
}

function updateData(option) {
  var e = document.getElementById("level");
  var value = e.options[e.selectedIndex].value;
  var text = e.options[e.selectedIndex].text;

  var title = text.charAt(0).toUpperCase() + text.slice(1);
  var newtitle = document.getElementById("thelevel").innerHTML=title;

  d3.json("./javascripts/biome/biome_new.json").then(function(response) {
    var data = response;

    data.forEach(e => e.ubiome = e.ubiome.filter(e => e.tax_rank === value));

    dates = data.map(function(d) {
      return d.sample_date;
    })

    for (i = 0; i < data.length; i++) {
      bacteria.push(data[i].ubiome.slice(0, data[i].ubiome.length));
    }
    var bacteriaList = d3.merge(bacteria).map(function(d) {
      return d.tax_name
    });

    bacteriaList = d3.set(bacteriaList).values();

    var width = bacteriaList.length*itemWidth,
      height = 500 - margin.top - margin.bottom;

    var y_elements = dates,
      x_elements = bacteriaList;

    var xScale = d3.scaleBand()
      .domain(x_elements)
      .range([0, x_elements.length * itemWidth]);

    var xAxis = d3.axisTop()
      .scale(xScale)
      .tickFormat(function(d) {
        return d;
      });

    var yScale = d3.scaleBand()
      .domain(y_elements)
      .range([0, y_elements.length * itemHeight]);

    var yAxis = d3.axisLeft()
      .scale(yScale)
      .tickFormat(function(d) {
        return  moment(d).format("YYYY-MM-DD");
      });

    var colorScale = d3.scaleSequential(d3.interpolateOrRd)
      .domain([0, 10000]);

    var svg = d3.select('#heatmap')
      .append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var parents = svg.selectAll('svg')
      .data(data)
      .enter().append('g')
      .attr("transform",function(d) { return "translate(0," + yScale(d.sample_date) + ")" });

    var children = parents.selectAll('rect')
      .data(function(d) { return d.ubiome; })
      .enter()
      .append('rect')
      .attr('class', 'cell')
      .attr('width', 15)
      .attr('height', cellSize)
      .attr('x', function(d) {  return xScale(d.tax_name); })
      .attr('fill', function(d) {
        return colorScale(d.count_norm);
      });

    var they = svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
      .selectAll('text')
      .attr('font-weight', 'normal');

    var thex = svg.append("g")
      .attr("class", "x axis")
      .call(xAxis)
      .selectAll('text')
      .attr('font-weight', 'normal')
      .style("text-anchor", "start")
      .attr("dx", ".8em")
      .attr("dy", "1.2em")
      .attr("transform", function(d) {
        return "rotate(-90)";
      });

      they.exit().remove();
      thex.exit().remove();

  });
}

 var data = [{ "sample_date": "2017-07-04T00:00:00.000Z", "ubiome": [ { "taxon": 1, "parent": 0, "count": 56085, "count_norm": 999999, "tax_name": "root", "tax_rank": "root" }, { "taxon": 2, "parent": 131567, "count": 56085, "count_norm": 999999, "tax_name": "Bacteria", "tax_rank": "superkingdom" }, { "taxon": 237, "parent": 49546, "count": 284, "count_norm": 5063, "tax_name": "Flavobacterium", "tax_rank": "genus" }, { "taxon": 543, "parent": 91347, "count": 21, "count_norm": 374, "tax_name": "Enterobacteriaceae", "tax_rank": "family" }, { "taxon": 579, "parent": 543, "count": 21, "count_norm": 374, "tax_name": "Kluyvera", "tax_rank": "genus" }, { "taxon": 712, "parent": 135625, "count": 2, "count_norm": 35, "tax_name": "Pasteurellaceae", "tax_rank": "family" }, { "taxon": 724, "parent": 712, "count": 2, "count_norm": 35, "tax_name": "Haemophilus", "tax_rank": "genus" }, { "taxon": 729, "parent": 724, "count": 2, "count_norm": 35, "tax_name": "Haemophilus parainfluenzae", "tax_rank": "species" }, { "taxon": 815, "parent": 171549, "count": 14662, "count_norm": 261424, "tax_name": "Bacteroidaceae", "tax_rank": "family" }, { "taxon": 816, "parent": 815, "count": 14625, "count_norm": 260764, "tax_name": "Bacteroides", "tax_rank": "class" } ] }, { "sample_date": "2017-07-10T00:00:00.000Z", "ubiome": [ { "taxon": 357276, "parent": 816, "count": 5150, "count_norm": 76679, "tax_name": "Bacteroides dorei", "tax_rank": "species" }, { "taxon": 360807, "parent": 841, "count": 60, "count_norm": 893, "tax_name": "Roseburia inulinivorans", "tax_rank": "species" }, { "taxon": 371599, "parent": 816, "count": 3, "count_norm": 44, "tax_name": "Bacteroides sp. XB12B", "tax_rank": "species" }, { "taxon": 375288, "parent": 171551, "count": 1357, "count_norm": 20204, "tax_name": "Parabacteroides", "tax_rank": "genus" }, { "taxon": 376806, "parent": 816, "count": 1050, "count_norm": 15633, "tax_name": "Bacteroides gallinarum", "tax_rank": "species" }, { "taxon": 387661, "parent": 375288, "count": 941, "count_norm": 14010, "tax_name": "Parabacteroides johnsonii", "tax_rank": "species" }, { "taxon": 397864, "parent": 171551, "count": 891, "count_norm": 13266, "tax_name": "Barnesiella", "tax_rank": "genus" }, { "taxon": 418240, "parent": 572511, "count": 801, "count_norm": 11926, "tax_name": "Blautia wexlerae", "tax_rank": "species" }, { "taxon": 420345, "parent": 31979, "count": 14, "count_norm": 208, "tax_name": "Lactonifactor", "tax_rank": "class" } ] } ]; var dates = []; var bacteria = []; var itemHeight = 30, itemWidth = 12, cellSize = itemHeight - 1, margin = { top: 120, right: 20, bottom: 20, left: 80 }; var e = document.getElementById("level"); var value = e.options[e.selectedIndex].value; var text = e.options[e.selectedIndex].text; var title = text.charAt(0).toUpperCase() + text.slice(1); var newtitle = document.getElementById("thelevel").innerHTML=title; //d3.json("./javascripts/biome/biome_new.json").then(function(response) { data.forEach(e => e.ubiome = e.ubiome.filter(e => e.tax_rank === value)); dates = data.map(function(d) { return d.sample_date; }); for (i = 0; i < data.length; i++) { bacteria.push(data[i].ubiome.slice(0, data[i].ubiome.length)); } var bacteriaList = d3.merge(bacteria).map(function(d) { return d.tax_name }); bacteriaList = d3.set(bacteriaList).values(); var width = bacteriaList.length*itemWidth, height = 500 - margin.top - margin.bottom; var y_elements = dates, x_elements = bacteriaList; var xScale = d3.scaleBand() .domain(x_elements) .range([0, x_elements.length * itemWidth]); var xAxis = d3.axisTop() .scale(xScale) .tickFormat(function(d) { return d; }); var yScale = d3.scaleBand() .domain(y_elements) .range([0, y_elements.length * itemHeight]); var yAxis = d3.axisLeft() .scale(yScale) .tickFormat(function(d) { return moment(d).format("YYYY-MM-DD"); }); var colorScale = d3.scaleSequential(d3.interpolateOrRd) .domain([0, 10000]); var svg = d3.select('#heatmap') .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var parents = svg.selectAll('svg') .data(data) .enter().append('g') .attr("transform",function(d) { return "translate(0," + yScale(d.sample_date) + ")" }); var children = parents.selectAll('rect') .data(function(d) { return d.ubiome; }) .enter() .append('rect') .attr('class', 'cell') .attr('width', 15) .attr('height', cellSize) .attr('x', function(d) { return xScale(d.tax_name); }) .attr('fill', function(d) { return colorScale(d.count_norm); }); svg.append("g") .attr("class", "y axis") .call(yAxis) .selectAll('text') .attr('font-weight', 'normal'); svg.append("g") .attr("class", "x axis") .call(xAxis) .selectAll('text') .attr('font-weight', 'normal') .style("text-anchor", "start") .attr("dx", ".8em") .attr("dy", "1.2em") .attr("transform", function(d) { return "rotate(-90)"; }); // Remove old elements parents.exit().remove(); children.exit().remove(); //}); function clearData(){ bacteriaList = []; dates = []; var somemap = d3.selectAll("#heatmap"); somemap.select("svg").remove(); d3.select('#heatmap').html(""); updateData(); } function updateData() { var data = [{ "sample_date": "2017-07-04T00:00:00.000Z", "ubiome": [ { "taxon": 1, "parent": 0, "count": 56085, "count_norm": 999999, "tax_name": "root", "tax_rank": "root" }, { "taxon": 2, "parent": 131567, "count": 56085, "count_norm": 999999, "tax_name": "Bacteria", "tax_rank": "superkingdom" }, { "taxon": 237, "parent": 49546, "count": 284, "count_norm": 5063, "tax_name": "Flavobacterium", "tax_rank": "genus" }, { "taxon": 543, "parent": 91347, "count": 21, "count_norm": 374, "tax_name": "Enterobacteriaceae", "tax_rank": "family" }, { "taxon": 579, "parent": 543, "count": 21, "count_norm": 374, "tax_name": "Kluyvera", "tax_rank": "genus" }, { "taxon": 712, "parent": 135625, "count": 2, "count_norm": 35, "tax_name": "Pasteurellaceae", "tax_rank": "family" }, { "taxon": 724, "parent": 712, "count": 2, "count_norm": 35, "tax_name": "Haemophilus", "tax_rank": "genus" }, { "taxon": 729, "parent": 724, "count": 2, "count_norm": 35, "tax_name": "Haemophilus parainfluenzae", "tax_rank": "species" }, { "taxon": 815, "parent": 171549, "count": 14662, "count_norm": 261424, "tax_name": "Bacteroidaceae", "tax_rank": "family" }, { "taxon": 816, "parent": 815, "count": 14625, "count_norm": 260764, "tax_name": "Bacteroides", "tax_rank": "class" } ] }, { "sample_date": "2017-07-10T00:00:00.000Z", "ubiome": [ { "taxon": 357276, "parent": 816, "count": 5150, "count_norm": 76679, "tax_name": "Bacteroides dorei", "tax_rank": "species" }, { "taxon": 360807, "parent": 841, "count": 60, "count_norm": 893, "tax_name": "Roseburia inulinivorans", "tax_rank": "species" }, { "taxon": 371599, "parent": 816, "count": 3, "count_norm": 44, "tax_name": "Bacteroides sp. XB12B", "tax_rank": "species" }, { "taxon": 375288, "parent": 171551, "count": 1357, "count_norm": 20204, "tax_name": "Parabacteroides", "tax_rank": "genus" }, { "taxon": 376806, "parent": 816, "count": 1050, "count_norm": 15633, "tax_name": "Bacteroides gallinarum", "tax_rank": "species" }, { "taxon": 387661, "parent": 375288, "count": 941, "count_norm": 14010, "tax_name": "Parabacteroides johnsonii", "tax_rank": "species" }, { "taxon": 397864, "parent": 171551, "count": 891, "count_norm": 13266, "tax_name": "Barnesiella", "tax_rank": "genus" }, { "taxon": 418240, "parent": 572511, "count": 801, "count_norm": 11926, "tax_name": "Blautia wexlerae", "tax_rank": "species" }, { "taxon": 420345, "parent": 31979, "count": 14, "count_norm": 208, "tax_name": "Lactonifactor", "tax_rank": "class" } ] } ]; var e = document.getElementById("level"); var value = e.options[e.selectedIndex].value; var text = e.options[e.selectedIndex].text; var title = text.charAt(0).toUpperCase() + text.slice(1); var newtitle = document.getElementById("thelevel").innerHTML=title; //d3.json("./javascripts/biome/biome_new.json").then(function(response) { //var data = response; data.forEach(e => e.ubiome = e.ubiome.filter(e => e.tax_rank === value)); dates = data.map(function(d) { return d.sample_date; }); for (i = 0; i < data.length; i++) { bacteria.push(data[i].ubiome.slice(0, data[i].ubiome.length)); } var bacteriaList = d3.merge(bacteria).map(function(d) { return d.tax_name }); bacteriaList = d3.set(bacteriaList).values(); var width = bacteriaList.length*itemWidth, height = 500 - margin.top - margin.bottom; var y_elements = dates, x_elements = bacteriaList; var xScale = d3.scaleBand() .domain(x_elements) .range([0, x_elements.length * itemWidth]); var xAxis = d3.axisTop() .scale(xScale) .tickFormat(function(d) { return d; }); var yScale = d3.scaleBand() .domain(y_elements) .range([0, y_elements.length * itemHeight]); var yAxis = d3.axisLeft() .scale(yScale) .tickFormat(function(d) { return moment(d).format("YYYY-MM-DD"); }); var colorScale = d3.scaleSequential(d3.interpolateOrRd) .domain([0, 10000]); var svg = d3.select('#heatmap') .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var parents = svg.selectAll('svg') .data(data) .enter().append('g') .attr("transform",function(d) { return "translate(0," + yScale(d.sample_date) + ")" }); var children = parents.selectAll('rect') .data(function(d) { return d.ubiome; }) .enter() .append('rect') .attr('class', 'cell') .attr('width', 15) .attr('height', cellSize) .attr('x', function(d) { return xScale(d.tax_name); }) .attr('fill', function(d) { return colorScale(d.count_norm); }); var they = svg.append("g") .attr("class", "y axis") .call(yAxis) .selectAll('text') .attr('font-weight', 'normal'); var thex = svg.append("g") .attr("class", "x axis") .call(xAxis) .selectAll('text') .attr('font-weight', 'normal') .style("text-anchor", "start") .attr("dx", ".8em") .attr("dy", "1.2em") .attr("transform", function(d) { return "rotate(-90)"; }); they.exit().remove(); thex.exit().remove(); //}); } 
 body { padding: 50px; font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .column { float: left; width: 20%; } /* Clear floats after the columns */ .row:after { content: ""; display: table; clear: both; } #heatmap { height: 400px; width: 1200px; border:2px solid #000; overflow: scroll; padding: 20px; } 
 <!DOCTYPE html> <html> <head> <title></title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta charset="utf-8"> <link rel="stylesheet" href="/stylesheets/style.css"> </head> <body> <content> <h1></h1> <h4>Sort by:</h4> <div class="row"> <div class="column"><select id="level" style="margin-bottom:20px;" onchange="clearData()"><option value="class">Class</option><option value="family">Family</option><option value="genus">Genus</option><option value="order">Order</option><option value="phylum">Phylum</option><option value="species">Species</option><option value="subclass">Subclass</option><option value="suborder">Suborder</option><option value="subphylum">Subphylum</option><option value="superphylum">Superphylum</option></select></div> <div class="column"> <div id="thelevel"></div> </div> </div> <div id="heatmap"></div> </content> </body> <script src="https://d3js.org/d3.v5.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script> </html> 

For those that come across this, I finally figured it out myself. 对于那些遇到这种情况的人,我终于自己弄清楚了。

The issue had to do with how the array was being stored, and may have nothing to do with d3. 这个问题与数组的存储方式有关,而与d3无关。

Once I updated the original variable in the update function to: 一旦我将更新函数中的原始变量更新为:

bacteria.length = 0;

...everything fell into place. ...一切都准备就绪 That initial array was just hanging on. 最初的阵列还在继续。 Once I reset it, the update function was able to rebuild everything just fine. 重置后,更新功能就可以重建所有内容。

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

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