使用Javascript将数据导入表中

时间:2017-10-05 23:12:05

标签: javascript jquery mongoose datatables frameworks

我有大约5k的文档,我需要整理和整理,从mongodb,express,out到ejs模板。我已经能够成功地将文档提交到ejs模板,但是我在如何解决项目的第二部分方面遇到了困难 - 组织数据。

以下是我的数据外观的示例。我的目标是列出最左侧列中的所有缺陷位置(总共大约30个),并根据每年和每月计算缺陷位置发生的次数。我并不反对使用框架或jquery。我唯一能想到的是为每个单元分配一个函数,迭代数组以查看它是否与该单元格的要求相匹配。 (但这似乎违背了编程的意图)。最后,我想添加图表,但这一点似乎真的很牵强。有一点需要补充 - 这不是我将使用的唯一日期范围,它们可以追溯到2012年至2017年。

  [{
    "_id": "59cee5ce8ffdc0134854f0c1",
    "repairorder": 7192822,
    "month": 2,
    "year": 2015,
    "defectlocation": "MB"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c2",
    "repairorder": 7192822,
    "month": 5,
    "year": 2015,
    "defectlocation": "COVER/HOUSING"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c3",
    "repairorder": 7192822,
    "month": 2,
    "year": 2015,
    "defectlocation": "MB"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c5",
    "repairorder": 7192822,
    "month": 3,
    "year": 2015,
    "defectlocation": "TOUCH PAD"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c6",
    "repairorder": 7192822,
    "month": 4,
    "year": 2015,
    "defectlocation": "MB"
  }]

以下是我需要它显示的方式:

  -----------------------------------------------------------------------
  Defect Location | 01-2015 |  02-2015 |  03-2015 |  04-2015 |  05-2015 |
  -----------------------------------------------------------------------
  MB              |         |    2     |          |    1     |          |
  -----------------------------------------------------------------------
  Touch Pad       |         |          |     1    |          |          |
  -----------------------------------------------------------------------
  Cover/ Housing  |         |          |          |          |     1    |
  -----------------------------------------------------------------------
  TOTAL           |         |     2    |     1    |     1    |     1    |

2 个答案:

答案 0 :(得分:1)

主要思想是将您的数据重新构建为一个数据结构,您可以轻松地将其用于构建理想的表格。

让我们将对象数组更改为嵌套对象:

def dothisthing(mydict) # define the function with a dictionary a the only parameter
    keylist = [] # create an empty list
    for key in mydict: # iterate the input dictionary
        keylist.append(key) # add the key from the dictionary to a list
    keylist.sort(reverse = True) # sort the list  from highest to lowest numbers
    toptwokeys = 0 # create a variable
    toptwovals = 0 # create a variable
    count = 0 # create an integer variable
    for item in keylist: # iterate the list we created above
        if count <2: # this limits the iterations to the first 2 
            toptwokeys += item # add the key 
            toptwovals += (mydict[item]) # add the value
        count += 1
    finaldict = {(toptwokeys/2):(toptwovals/2)} # create a dictionary where the key and val are the average of the 2 from the input dict with the greatest keys
    return finaldict # return the output dictionary

dothisthing({0.9711533363722904: 0.008296776727415599, 0.97163564816067838: 0.008153794130319884, 0.99212783984967068: 0.0022392112909864364, 0.98955473263127025: 0.0029843621053514003})
#call the function with your dictionary as the parameter

var deflects = {
    'MB': {
        '02-2015': 2,
        '04-2015': 1
    },
    'TOUCH PAD':  {
        '03-2015': 1
    }
    'COVER/HOUSING': {
        '05-2015': 1
    },
    'TOTAL': {
        '02-2015': 2,
        '03-2015': 1,
        '04-2015': 1,
        '05-2015': 1
    }
};
var data = [{
    "_id": "59cee5ce8ffdc0134854f0c1",
    "repairorder": 7192822,
    "month": 2,
    "year": 2015,
    "defectlocation": "MB"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c2",
    "repairorder": 7192822,
    "month": 5,
    "year": 2015,
    "defectlocation": "COVER/HOUSING"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c3",
    "repairorder": 7192822,
    "month": 2,
    "year": 2015,
    "defectlocation": "MB"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c5",
    "repairorder": 7192822,
    "month": 3,
    "year": 2015,
    "defectlocation": "TOUCH PAD"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c6",
    "repairorder": 7192822,
    "month": 4,
    "year": 2015,
    "defectlocation": "MB"
}];

function pad(n, width, z) {
     z = z || '0';
    n = n + '';
    return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

// PART 1: create object i.e. dictionary

// create a dictionary where each key is the defectlocation
// and its value is another dictionary;

// each inner dictionary will have a key for each date found
// and its value as a counter
var defects = {};

// let's create another inner dictionary for tallying
defects.TOTAL = {};

data.forEach(function (d) {
    if (!defects.hasOwnProperty(d.defectlocation)) {
        defects[d.defectlocation] = {};
    }

    var date = pad(d.month, 2) + '-' + d.year;
    if (!defects[d.defectlocation].hasOwnProperty(date)) {
        defects[d.defectlocation][date] = 0;
    }
    defects[d.defectlocation][date]++;
  
    if (!defects.TOTAL.hasOwnProperty(date)) {
        defects.TOTAL[date] = 0;
    }
    defects.TOTAL[date]++;
});

var dates = Object.keys(defects.TOTAL).sort();

// you would pass deflects and dates into your view

// PART 2: build the table (view)

var html = '<table>';
html += '<tr>';
html += '<th>Defect Location</th>';
dates.forEach(function (date) {
     html += '<th>' + date + '</th>';
});
html += '</tr>';

['MB', 'TOUCH PAD', 'COVER/HOUSING', 'TOTAL'].forEach(function (location) {
    html += '<tr>';
    html += '<td>' + location + '</td>';
    dates.forEach(function (date) {
        html += '<td>' + (defects[location][date] || '') + '</td>';
    });
    html += '</tr>';
})

html += '</table>';

document.getElementById('preview').innerHTML = html;
table {
  border-collapse: collapse;
}
th, td {
  border: 1px solid #000;
}
th:first-child {
  text-align: left; 
}
td:not(:first-child) {
  text-align: center;
}

虽然第2部分中的HTML生成器不是EJS格式,但您可以按照相同的逻辑轻松构建它。第1部分是重要的部分。

此外,填充逻辑取自此answer

答案 1 :(得分:1)

听起来您的问题是如何组织数据以计算每个时段内每个缺陷位置的实例。这会奏效。你可以缩短这个,但我试着用易读的js。从结束点开始,您可以使用任何表库(如datatables.net)或手动创建html表,如Mikey的答案所示。希望这会有所帮助。

***更新:我最初忽略了TOTAL行。我已经更新了我的答案以包含它(以及作为数组中的最后一行)。我还逐年添加了对列的排序,然后按月添加(因为您希望的最终结果的示例以这种方式显示)并且我将代码分成两个函数,希望使它更具可读性。

var data = [{
    "_id": "59cee5ce8ffdc0134854f0c1",
    "repairorder": 7192822,
    "month": 2,
    "year": 2015,
    "defectlocation": "MB"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c2",
    "repairorder": 7192822,
    "month": 5,
    "year": 2015,
    "defectlocation": "COVER/HOUSING"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c3",
    "repairorder": 7192822,
    "month": 2,
    "year": 2015,
    "defectlocation": "MB"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c5",
    "repairorder": 7192822,
    "month": 3,
    "year": 2015,
    "defectlocation": "TOUCH PAD"
  }, {
    "_id": "59cee5ce8ffdc0134854f0c6",
    "repairorder": 7192822,
    "month": 4,
    "year": 2015,
    "defectlocation": "MB"
  }];

  var tableData = {};
  var totalRow = {};
  var allCols = [];
  var asArray = [];

  tallyInstances();
  prepForTable();

  function tallyInstances () {
    var i;
    var monthDate;
    for (i = 0; i < data.length; i++) {
      monthDate = data[i].month.toString() + '-' + data[i].year.toString();
      allCols.indexOf(monthDate) < 0 ? allCols.push(monthDate) : null;
      if (!tableData[data[i].defectlocation]) {
        tableData[data[i].defectlocation] = {}; // if our tableData object doesn't have a property for this defect location yet then add it and make it an object
      }
      if (tableData[data[i].defectlocation][monthDate]) {
        tableData[data[i].defectlocation][monthDate] ++; // if this defect location object has a property for this year/month combination already then increment it's value by one
      } else {
        tableData[data[i].defectlocation][monthDate] = 1; // if this defect location object does not have a property for this year/month combination yet then create the property and give it a value of 1
      }
      totalRow[monthDate] ? totalRow[monthDate] ++ : totalRow[monthDate] = 1; // ternary operator saying if the totalRow object already has a property for this year/month combination then increment it's value by one, otherwise create it and give it a value of 1
    }
  }

  function prepForTable () {
    allCols.sort(function(a, b) {
      var aParts = a.split("-");
      var bParts = b.split("-");
      var x = {
        month : aParts[0],
        year  : aParts[1]
      };
      var y = {
        month : bParts[0],
        year  : bParts[1]
      };
      var n = x.year - y.year;
      if (n !== 0) {
        return n;
      }
      return x.month - y.month;
    });
    var keys = Object.keys(tableData);
    var e;
    var rowObj;
    for (e = 0; e < keys.length; e++) {
      rowObj = {};
      rowObj["Defect Location"] = keys[e];
      var a;
      for (a = 0; a < allCols.length; a++) {
        rowObj[allCols[a]] = tableData[keys[e]][allCols[a]] ? tableData[keys[e]][allCols[a]] : '';
      }
      asArray.push(rowObj);
    }
    rowObj = {};
    rowObj["Defect Location"] = "TOTAL";
    var o;
    for (o = 0; o < allCols.length; o++) {
      rowObj[allCols[o]] = totalRow[allCols[o]] ? totalRow[allCols[o]] : '';
    }
    asArray.push(rowObj);
  }

  console.log("tableRows: ", JSON.stringify(asArray, null, 4));
  /*
 tableRows:  [
    {
        "Defect Location": "MB",
        "2-2015": 2,
        "3-2015": "",
        "4-2015": 1,
        "5-2015": ""
    },
    {
        "Defect Location": "COVER/HOUSING",
        "2-2015": "",
        "3-2015": "",
        "4-2015": "",
        "5-2015": 1
    },
    {
        "Defect Location": "TOUCH PAD",
        "2-2015": "",
        "3-2015": 1,
        "4-2015": "",
        "5-2015": ""
    },
    {
        "Defect Location": "TOTAL",
        "2-2015": 2,
        "3-2015": 1,
        "4-2015": 1,
        "5-2015": 1
    }
]

*/