[英]d3 Axis Label Update
我已经尝试过可以想到的所有排列方式,但是无法清除和重置轴标签。 我正在创建一个通过下拉菜单更新的热图。 随即显示该图,并且正确绘制了热图数据。 我遇到的问题是,每次更新图表时,新数据的所有x轴标签都会在数据更新时附加(但是如果我返回到先前加载的数据集,则不会附加)它使用旧标签)。 我尝试创建一个函数,当下拉菜单更改“清除”图形时调用该函数,然后调用另一个函数“重绘”它。 我试图使标签变量化,以此类推。
即使我运行了.remove()-并已在svg,g上(通过g.class等)完成了此操作。即使运行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>
对于那些遇到这种情况的人,我终于自己弄清楚了。
这个问题与数组的存储方式有关,而与d3无关。
一旦我将更新函数中的原始变量更新为:
bacteria.length = 0;
...一切都准备就绪 最初的阵列还在继续。 重置后,更新功能就可以重建所有内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.