如何简化这个D3代码?

时间:2016-07-25 17:56:12

标签: javascript d3.js

我有一些看起来像这样的CSV数据,按年按组织显示通过率:

org,org_cat,2004_passed,2004_total,2005_passed,2005_total,2006_passed,2006_total
GSK,industry,35,100,45,100,55,100

我在D3工作,我想最终得到这样的组织词典:

data = {
 'GSK': {
     'org_cat': 'industry',
     'data': [
        { 'year': 2004, 'passed': 35, 'total': 100 },
        { 'year': 2005, 'passed': 45, 'total': 100 },
        { 'year': 2006, 'passed': 55, 'total': 100 }
     ]
  ]
}

大部分内容都是直截了当的,但我的年代专栏代码非常混乱:

var data = {};
allData.forEach(function(d) {
  data[d.org] = {
    'category': d.org_cat,
    'data': []
  };
  for (var k in d) {
    var temp = {};
    for (var k in d) {
      if (patt.test(k)) {
        var res = k.split("_");
        if (res[0] in temp) {
          temp[res[0]][res[1]] = +d[k];
        } else {
          temp[res[0]] = {};
          temp[res[0]][res[1]] = +d[k];
        }
      }
    }
    var tempArr = [];
    for (var y in temp) {
      var tempDict = {};
      tempDict.year = y;
      tempDict.passed = temp[y].passed;
      tempDict.total = temp[y].total;
      tempArr.push(tempDict);
    }
    // TODO: sort by year in case the keys got shuffled
    data[d.org].data = tempArr;
  }
});

有没有办法简化这个可怕的代码?

可以安全地假设每一行都是一个独特的组织。

1 个答案:

答案 0 :(得分:2)

我不明白为什么你需要D3来做这件事。你的代码也不使用它。这是我将如何做到这一点,我相信还有另一种更简单的方法,但它可以帮助你:

Jsfiddle:https://jsfiddle.net/thatOneGuy/dnvheznk/1/

我将数据转换为JSON以与JSFiddle一起使用,但您已经知道如何循环CSV以便只覆盖第14行:

for (var i = 0; i < data.length; i++) { //loop through data array (this is so you can use this on a bigger sized array) 

到你的循环:

allData.forEach(function(d, i) { //but add the 'i' to index

以下是带有转换后的JSON数据的完整注释代码:

var data = [{ //data set converted to JSON for easier use
  "org": "GSK",
  "org_cat": "industry",
  "2004_passed": 35,
  "2004_total": 100,
  "2005_passed": 45,
  "2005_total": 100,
  "2006_passed": 55,
  "2006_total": 100
}];

var newData = {}; //new data container

for (var i = 0; i < data.length; i++) { //loop through data array (this is so you can use this on a bigger sized array)
  var thisObj = {}; //create empty object
  thisObj.org_cat = data[i].org_cat; //set org_cat
  thisObj.data = []; //set data to empty array to populate later

  for (var key in data[i]) { //loop through data[i]
    if (key != 'org' && key != 'org_cat') { //check this key is not org or org_cat
      var thisData = {}; //create empty data object
      var thisYear = key.toString().substring(0, 4); //get year by using substring

      thisData.year = thisYear; //set year
      thisData.passed = data[i][thisYear + '_passed']; //set passed at this year
      thisData.total = data[i][thisYear + '_total']; //set total at this year

      thisObj.data.push(thisData); //push this data to data array
    }
  }
  var uniqueDates = []; //set empty array to use to remove duplicate items in data array
  for (var j = 0; j < thisObj.data.length; j++) { //loop through data array created earlier
    if (uniqueDates.indexOf(thisObj.data[j].year) < 0) { //if this year doesn't exist in unique array above, push it in
      uniqueDates.push(thisObj.data[j].year); //push it in
    } else {
      thisObj.data.splice(j--, 1); //remove duplicate data
    }
  }
  newData[data[i].org] = thisObj; //set data @ current org to be object created above
}
console.log('newData', newData) //log new data