使用嵌套json数据的d3热图:如何创建网格 [英] d3 heatmap using nested json data: how to create grids

查看:84
本文介绍了使用嵌套json数据的d3热图:如何创建网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参阅此示例: http://bl.ocks.org/tjdecke/5558084

我想创建一个52行和7列的热图。 52行代表一年中的52周,7列代表一周中的7天。

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.

使用如下数据集:(在下面发布缩写版本)。
天表示一周中的7天,里面的数字表示一天内的活动数量。 总数表示一周内的活动总数。 周似乎是各种各样的时间戳。

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.

但是,我很难弄清楚如何创建网格,因为示例数据集使用带有7个值的d.day和带有24个值的d.hour来创建网格。具体来说,我应该如何处理days数组?

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?

我不知道如何处理json值,因为我应该如何定义我的用于处理此数据集的变量。

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");

推荐答案

使用嵌套数据,您可以先为每个元素追加组元素对象在每个星期的网格中创建一个行,根据它们的索引得到它们的y坐标。

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.

然后对于每一行,根据日期追加rects对象中的数组。

Then for each row, append rects based on the days array within object.

诀窍是做两个data()连接,第二个连接从已经连接的数据中访问days数组。

The trick is to do two data() joins, with the second join accessing the days array from within the already joined data.

例如:

     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>

这篇关于使用嵌套json数据的d3热图:如何创建网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆