我已经尝试过可以想到的所有排列,但是无法清除和重置轴标签。我正在创建一个通过下拉菜单更新的热图。随即显示该图,并且正确绘制了热图数据。我遇到的问题是,每次更新图表时,新数据的所有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>
答案 0 :(得分:0)
对于那些遇到这种情况的人,我终于自己弄清楚了。
该问题与数组的存储方式有关,而与d3无关。
一旦我将更新函数中的原始变量更新为:
bacteria.length = 0;
...一切都准备就绪。最初的阵列还在继续。重置后,更新功能就可以重建所有内容。