简体   繁体   English

正确处理JSON数据以创建D3面积图?

[英]Proper manipulation of JSON data to create D3 area chart?

Where I struggle the most with D3 is proper data manipulation prior to plugging it into existing models. 我在D3上遇到的最大困难是在将数据插入现有模型之前进行了适当的数据处理。 I am trying to figure out the least amount of data manipulation required to create a basic D3 area chart with a time-based x-axis. 我试图找出创建具有基于时间的x轴的基本D3面积图所需的最少数据处理量。 I am starting with a JSON array of objects with a date key and Date object property, along with several other key-value pairs to populate the chart. 我从一个带有date键和Date对象属性的对象的JSON数组开始,以及其他几个用于填充图表的键值对。

For example: 例如:

[{date: Wed Jul 20 2016 00:00:00 GMT-1000 (HST), a: 5, b: 1, c: 9, nothankyou: 90},
{date: Wed Jul 21 2016 00:00:00 GMT-1000 (HST), a: 7, b: 2, c: 10, nothankyou: 70},
{date: Wed Jul 22 2016 00:00:00 GMT-1000 (HST), a: 6, b: 5, c: 3, nothankyou: 50},
...etc...]

The goal is to create an area chart with the values for a , b , and c along the y-axis and time ( date ) along the x-axis. 目标是创建一个面积图,其中y轴的abc以及x轴的时间( date )。 Need to filter out unwanted data points, such as nothankyou . 需要过滤掉不需要的数据点,例如nothankyou

I have previously used d3.nest to similarly manipulate data in another project, but isn't it overkill where the data is already organized by date? 我以前曾使用d3.nest类似地在另一个项目中处理数据,但是在按日期组织数据的情况下,这不是过分杀伤力吗?

The D3 area chart itself is fairly straightforward (it assumes the data has been d3.nest()-ed already): D3面积图本身非常简单(它假设数据已经被d3.nest()编辑):

var format = d3.time.format("%Y-%m-%d");

var margin = {top: 20, right: 30, bottom: 30, left: 40},
    width = 450 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom,
    delay = 500,
    duration = 750;

var x = d3.time.scale()
    .range([0, width]);

var y = d3.scale.linear()
    .range([height, 0]);

var z = d3.scale.category20c();

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .ticks(d3.time.months);

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

var stack = d3.layout.stack()
    .offset("zero")
    .values(function(d) { return d.values; })
    .x(function(d) { return d.date; })
    .y(function(d) { return d.value; });

var nest = d3.nest()
    .key(function(d) { return d.key; });

var area = d3.svg.area()
    .interpolate("cardinal")
    .x(function(d) { return x(d.date); })
    .y0(function(d) { return y(d.y0); })
    .y1(function(d) { return y(d.y0 + d.y); });

var svg = d3.select(".areaChart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  totalCrimeData.forEach(function(d) {
    d.date = format.parse(d.date);
    d.value = +d.value;
  });

  var layers = stack(nest.entries(data));
  console.log("layers",layers);

  x.domain(d3.extent(data, function(d) { return d.date; }));
  y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);

  svg.selectAll(".layer")
      .data(layers)
    .enter().append("path")
      .attr("class", "layer")
      .attr("d", function(d) { return area(d.values); })
      .style("fill", function(d, i) { return z(i); });

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);

Here is an interim solution (non D3) that I've come up with to structure the data the way that the D3 set up wants it. 这是我提出的一种临时解决方案(非D3),用于按照D3设置的方式构造数据。 Comments welcome. 欢迎发表评论。

var data = [ {}, {}, {}, ... ] // see above
var dataSets = ["a","b","c"]
var newArr = [];

data.map(function(a) {
  var prop;
  var _this = this;

  dataSets.map(function(k) {
    prop = a.date+"|"+k;
    if (!_this[prop]) {
      _this[prop] = {
        key: k,
        value: 0,
        date: a.date
      };
        newArr.push(_this[prop]);
      }
      if (prop === a.date+"|"+k) {
        _this[prop].value += parseInt(a[k]);
      }
    });
  }, Object.create(null));

console.log("reduced data", newArr);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM