问题
Referring to this example here: http://bl.ocks.org/tjdecke/5558084
I would like to create a heatmap of 52 rows, and 7 columns. 52 rows represents the 52 weeks of a year, and 7 column represents 7 days of a week.
With a dataset like this: (posting abbreviated version below). "days" signify the 7 days of a week, the numbers inside signify number of activity within a day. "total" signifies total number of activity in a week. "week" seems to be a timestamp of sorts.
However, I am having difficulty figuring out how to create the grids, as the example dataset uses d.day with 7 values and d.hour with 24 values to create the grid. Specifically, what should i be doing with the days array?
I am not sure on how to process the json values as well, as in, how should i be defining my variables to work with this dataset.
[
{
"days": [
0,
0,
0,
0,
0,
1,
0
],
"total": 1,
"week": 1457827200
},
{
"days": [
0,
0,
0,
1,
0,
3,
1
],
"total": 5,
"week": 1458432000
},
{
"days": [
1,
0,
0,
1,
5,
0,
1
],
"total": 8,
"week": 1459036800
},
{
"days": [
0,
0,
0,
2,
0,
1,
1
],
"total": 4,
"week": 1459641600
},
{
"days": [
0,
1,
3,
0,
2,
0,
0
],
"total": 6,
"week": 1460246400
},
{
"days": [
0,
1,
1,
2,
2,
0,
0
],
"total": 6,
"week": 1460851200
},
{
"days": [
1,
0,
3,
0,
2,
1,
0
],
"total": 7,
"week": 1461456000
},
{
"days": [
0,
0,
0,
0,
0,
0,
0
],
"total": 0,
"week": 1462060800
}
]
d3.json("/data/frequency.json", function (error, data) {
// NOT SURE, PROBABLY WRONG
data.forEach(function(d) {
ddays = +d.days;
total = +d.total;
week = +d.week;
});
// define range!!!
var x = d3.scaleLinear().domain([0, data.length]).range([0, width]);
//52 weeks
var y = d3.scaleLinear()
.domain([0, 52])
.rangeRound([height, 0]);
// Generate rectangle for each json object
var rectangles = svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr("x", function(d, index) {
return x(index); }) //WRONG!!
.attr("y", function(d, index) {
return y; }) // WRONG!!
.attr("width", gridSize)
.attr("height", gridSize)
.style("fill", 'black')
.attr("class", "bordered");
回答1:
with your nested data, you could first append group elements per object to create a "row" in your grid for each week, which get their y coordinate based on their index.
Then for each row, append rects based on the days array within object.
The trick is to do two data() joins, with the second join accessing the days array from within the already joined data.
For example:
let data = [
{
"days": [
0,
0,
0,
0,
0,
1,
0
],
"total": 1,
"week": 1457827200
},
{
"days": [
0,
0,
0,
1,
0,
3,
1
],
"total": 5,
"week": 1458432000
},
{
"days": [
1,
0,
0,
1,
5,
0,
1
],
"total": 8,
"week": 1459036800
},
{
"days": [
0,
0,
0,
2,
0,
1,
1
],
"total": 4,
"week": 1459641600
},
{
"days": [
0,
1,
3,
0,
2,
0,
0
],
"total": 6,
"week": 1460246400
},
{
"days": [
0,
1,
1,
2,
2,
0,
0
],
"total": 6,
"week": 1460851200
},
{
"days": [
1,
0,
3,
0,
2,
1,
0
],
"total": 7,
"week": 1461456000
},
{
"days": [
0,
0,
0,
0,
0,
0,
0
],
"total": 0,
"week": 1462060800
}
]
let gridSize = 20;
let width = (gridSize + 1) * 7;
let height = (gridSize + 1) * data.length;
// define range!!!
var x = d3.scaleLinear()
.domain([0, 7])
.range([0, width]);
//52 weeks
var y = d3.scaleLinear()
.domain([0, data.length])
.rangeRound([height, 0]);
let svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
// Generate rows for each json object
var rows = svg.selectAll('.row')
.data(data)
.enter()
.append('g')
.attr("transform", function(d, i){
return "translate(0," + y(i) + ")"
})
// Generate rects for the array of days per object
let box = rows.selectAll("rect")
.data(function(d){ return d.days })
.enter()
.append("rect")
.attr("x", function(d, i) { return x(i); })
.attr("width", gridSize)
.attr("height", gridSize)
.style("fill", 'black')
.attr("class", "bordered");
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
</body>
来源:https://stackoverflow.com/questions/46916634/d3-heatmap-using-nested-json-data-how-to-create-grids