d3轴标签更新

时间:2018-07-09 01:35:24

标签: javascript d3.js

我已经尝试过可以想到的所有排列,但是无法清除和重置轴标签。我正在创建一个通过下拉菜单更新的热图。随即显示该图,并且正确绘制了热图数据。我遇到的问题是,每次更新图表时,新数据的所有x轴标签都会在数据更新时附加(但是如果我返回到先前加载的数据集,则不会附加)它使用旧标签)。我尝试创建一个函数,当下拉菜单更改“清除”图形时调用该函数,然后调用另一个函数“重绘”它。我试图使标签成为变量,等等,以查看大量示例。

即使我运行.remove()-并通过g.class等在svg,g上执行此操作。即使运行remove会使DOM元素消失,轴标签也仍然会挂住。它似乎与.exit .remove模式有关,但我无法弄清楚顺序?任何帮助都会很棒。

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>

1 个答案:

答案 0 :(得分:0)

对于那些遇到这种情况的人,我终于自己弄清楚了。

该问题与数组的存储方式有关,而与d3无关。

一旦我将更新函数中的原始变量更新为:

bacteria.length = 0;

...一切都准备就绪。最初的阵列还在继续。重置后,更新功能就可以重建所有内容。