我正在尝试创建两个热图,以显示在同一日期下拉列表中更新的不同数据。我使用heatmap with data update并创建两个单独的svg,以在下拉列表中选择新的日期字段时进行更新。我能够遵循一些SO答案在同一页面上创建两个图表,但是我完全不知道要删除哪一个位置同时更新两个图表。任何有关如何实现这一目标的指针将不胜感激。我已经包括了我一直在使用的代码和json数据。我现在有两个不同文件中的数据。如果它仅来自一个文件,甚至可以使其更易于读取位置下拉值,那就更好了。
var dataset;
var dataset2;
var days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
times = d3.range(24);
var margin = {top:40, right:50, bottom:70, left:50};
// calculate width and height based on window size
var w = Math.max(Math.min(window.innerWidth, 1000), 500) - margin.left - margin.right - 20,
gridSize = Math.floor(w / times.length),
h = gridSize * (days.length+2);
//reset the overall font size
var newFontSize = w * 62.5 / 900;
d3.select("html").style("font-size", newFontSize + "%");
// svg container
var svg = d3.select("#heatmap")
.append("svg")
.attr("width", w + margin.top + margin.bottom)
.attr("height", h + margin.left + margin.right)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// svg container
var svg2 = d3.select("#heatmap2")
.append("svg")
.attr("width", w + margin.top + margin.bottom)
.attr("height", h + margin.left + margin.right)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// linear colour scale
var colours = d3.scaleLinear()
.domain(d3.range(1, 11, 1))
.range(["#87cefa", "#86c6ef", "#85bde4", "#83b7d9", "#82afce", "#80a6c2", "#7e9fb8", "#7995aa", "#758b9e", "#708090"]);
var dayLabels = svg.selectAll(".dayLabel")
.data(days)
.enter()
.append("text")
.text(function(d) { return d; })
.attr("x", 0)
.attr("y", function(d, i) { return i * gridSize; })
.style("text-anchor", "end")
.attr("transform", "translate(-6," + gridSize / 1.5 + ")")
var dayLabels = svg2.selectAll(".dayLabel")
.data(days)
.enter()
.append("text")
.text(function(d) { return d; })
.attr("x", 0)
.attr("y", function(d, i) { return i * gridSize; })
.style("text-anchor", "end")
.attr("transform", "translate(-6," + gridSize / 1.5 + ")")
var timeLabels = svg.selectAll(".timeLabel")
.data(times)
.enter()
.append("text")
.text(function(d) { return d; })
.attr("x", function(d, i) { return i * gridSize; })
.attr("y", 0)
.style("text-anchor", "middle")
.attr("transform", "translate(" + gridSize / 2 + ", -6)");
var timeLabels = svg2.selectAll(".timeLabel")
.data(times)
.enter()
.append("text")
.text(function(d) { return d; })
.attr("x", function(d, i) { return i * gridSize; })
.attr("y", 0)
.style("text-anchor", "middle")
.attr("transform", "translate(" + gridSize / 2 + ", -6)");
// load data heatmap 1
d3.json("test.json", function(error, data) {
data.forEach(function(d) {
d.day = +d.day;
d.hour = +d.hour;
d.value = +d.value;
});
dataset = data;
// group data by location
var nest = d3.nest()
.key(function(d) { return d.location; })
.entries(dataset);
// array of locations in the data
var locations = nest.map(function(d) { return d.key; });
var currentLocationIndex = 0;
// create location dropdown menu
var locationMenu = d3.select("#locationDropdown1");
locationMenu
.append("select")
.attr("id", "locationMenu")
.selectAll("option")
.data(locations)
.enter()
.append("option")
.attr("value", function(d, i) { return i; })
.text(function(d) { return d; });
// function to create the initial heatmap
var drawHeatmap = function(location) {
// filter the data to return object of location of interest
var selectLocation = nest.find(function(d) {
return d.key == location;
});
var heatmap = svg.selectAll(".hour")
.data(selectLocation.values)
.enter()
.append("rect")
.attr("x", function(d) { return (d.hour-1) * gridSize; })
.attr("y", function(d) { return (d.day-1) * gridSize; })
.attr("class", "hour bordered")
.attr("width", gridSize)
.attr("height", gridSize)
.style("stroke", "white")
.style("stroke-opacity", 0.6)
.style("fill", function(d) { return colours(d.value); })
}
drawHeatmap(locations[currentLocationIndex]);
var updateHeatmap = function(location) {
// filter data to return object of location of interest
var selectLocation = nest.find(function(d) {
return d.key == location;
});
// update the data and redraw heatmap
var heatmap = svg.selectAll(".hour")
.data(selectLocation.values)
.transition()
.duration(500)
.style("fill", function(d) { return colours(d.value); })
}
// run update function when dropdown selection changes
locationMenu.on("change", function() {
// find which location was selected from the dropdown
var selectedLocation = d3.select(this)
.select("select")
.property("value");
currentLocationIndex = +selectedLocation;
// run update function with selected location
updateHeatmap(locations[currentLocationIndex]);
});
})
// load data heatmap 2
d3.json("test2.json", function(error, data2) {
data2.forEach(function(d2) {
d2.day = +d2.day;
d2.hour = +d2.hour;
d2.value = +d2.value;
});
dataset2 = data2;
// group data by location
var nest2 = d3.nest()
.key(function(d2) { return d2.location; })
.entries(dataset2);
// array of locations in the data
var locations2 = nest2.map(function(d2) { return d2.key; });
var currentLocationIndex2 = 0;
// create location dropdown menu
var locationMenu2 = d3.select("#locationDropdown2");
locationMenu2
.append("select")
.attr("id", "locationMenu")
.selectAll("option")
.data(locations2)
.enter()
.append("option")
.attr("value", function(d2, i2) { return i2; })
.text(function(d2) { return d2; });
// function to create the initial heatmap
var drawHeatmap2 = function(location2) {
// filter the data to return object of location of interest
var selectLocation2 = nest2.find(function(d2) {
return d2.key == location2;
});
var heatmap2 = svg2.selectAll(".hour")
.data(selectLocation2.values)
.enter()
.append("rect")
.attr("x", function(d2) { return (d2.hour-1) * gridSize; })
.attr("y", function(d2) { return (d2.day-1) * gridSize; })
.attr("class", "hour bordered")
.attr("width", gridSize)
.attr("height", gridSize)
.style("stroke", "white")
.style("stroke-opacity", 0.6)
.style("fill", function(d2) { return colours(d2.value); })
}
drawHeatmap2(locations2[currentLocationIndex2]);
var updateHeatmap2 = function(location2) {
console.log("currentLocationIndex: " + currentLocationIndex2)
// filter data to return object of location of interest
var selectLocation2 = nest2.find(function(d2) {
return d2.key == location2;
});
// update the data and redraw heatmap
var heatmap2 = svg2.selectAll(".hour")
.data(selectLocation2.values)
.transition()
.duration(500)
.style("fill", function(d2) { return colours(d2.value); })
}
// run update function when dropdown selection changes
locationMenu2.on("change", function() {
// find which location was selected from the dropdown
var selectedLocation2 = d3.select(this)
.select("select")
.property("value");
currentLocationIndex2 = +selectedLocation2;
// run update function with selected location
updateHeatmap2(locations2[currentLocationIndex2]);
});
})
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
html {
font-size: 62.5%;
}
body {
margin-top: 30px;
font-size: 1.4rem;
font-family: 'Source Sans Pro', sans-serif;
font-weight: 400;
fill: #696969;
text-align: center;
}
.timeLabel, .dayLabel {
font-size: 1.6rem;
fill: #AAAAAA;
font-weight: 300;
}
#nav-container {
display: flex;
justify-content: center;
cursor: pointer;
}
</style>
</head>
<body>
<div id="nav-container">
<div id="locationDropdown1"></div>
</div>
<div id="heatmap"></div>
<div id="nav-container">
<div id="locationDropdown2"></div>
</div>
<div id="heatmap2"></div>
JSON示例与上面的链接相同。只是修改了一些值以显示差异。 (不知道如何在此处包括大json文件)。再次感谢。