prepareData.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. "use strict";
  2. const fs = require('fs');
  3. const path = require('path');
  4. const config = require('../build.json');
  5. // Change current directory to script location so that
  6. // the relative paths of the resources can be resolved
  7. process.chdir(path.dirname(process.argv[1]));
  8. function createDirectory(dir) {
  9. fs.mkdirSync(
  10. dir,
  11. { recursive: true },
  12. (error) => {
  13. if (error !== null) {
  14. console.error('Error while creating directory', error);
  15. }
  16. }
  17. );
  18. }
  19. function transformData() {
  20. // TSV laden und parsen
  21. var matrix = fs.readFileSync(path.join('../', config.path.data, 'crime.tsv'), 'utf8');
  22. matrix = matrix.split('\n').map(l => l.split('\t'));
  23. var rowCount = matrix.length - 1; // trailing new line
  24. var colCount = matrix[0].length - 1; // treat dark figures separately
  25. var result = {entries:[]};
  26. var nodes = new Map();
  27. // Die einzelnen Zeilen (je Straftat) in einen Tree einsortieren
  28. for (var r = 2; r < rowCount; r++) {
  29. var parentid = matrix[r][1].trim();
  30. var node = {};
  31. if (parentid === '') {
  32. result.tree = node;
  33. } else {
  34. var parent = nodes.get(parentid);
  35. if (!parent) throw Error('"'+parentid+'" not found');
  36. if (!parent.children) parent.children = [];
  37. parent.children.push(node);
  38. }
  39. nodes.set(matrix[r][0].trim(), node);
  40. node.id = matrix[r][0].trim();
  41. node.title = matrix[r][2].trim();
  42. // node.dark = matrix[r][colcount].trim();
  43. // node.dark = Math.random() * 0.8 + 0.1; fake dark figure
  44. }
  45. // Jeden Wert den Straftaten, Geschlecht und Alter zuordnen
  46. for (var c = 3; c < colCount; c++) {
  47. // Zuordnung zum Alter
  48. var alter = matrix[0][c];
  49. switch (alter) {
  50. case 'alle': alter = ''; break;
  51. case 'bis unter 6': alter = '0-5'; break;
  52. case '6 bis unter 14': alter = '6-13'; break;
  53. case '14 bis unter 18': alter = '14-17'; break;
  54. case '18 bis unter 21': alter = '18-20'; break;
  55. case '21 bis unter 60': alter = '21-59'; break;
  56. case '60 und älter': alter = '60+'; break;
  57. default: throw Error(alter);
  58. }
  59. // Zuordnung zum Geschlecht
  60. var geschlecht = matrix[1][c];
  61. switch (geschlecht) {
  62. case 'insges.': geschlecht = ''; break;
  63. case 'männlich': geschlecht = 'm'; break;
  64. case 'weiblich': geschlecht = 'w'; break;
  65. default: throw Error(geschlecht);
  66. }
  67. var entry = {alter:alter, geschlecht:geschlecht, values:{}};
  68. result.entries.push(entry);
  69. // Zuordnung zur Straftat
  70. for (var r = 2; r < rowCount; r++) {
  71. var crimeId = matrix[r][0].trim();
  72. var value = parseFloat(matrix[r][c].replace(/,/g, '.')) || 0;
  73. entry.values[crimeId] = round(value);
  74. }
  75. }
  76. // Validierung, ob die Summen aufgehen
  77. result.entries.forEach((entry) => {
  78. var values = entry.values;
  79. validate(result.tree);
  80. function validate(node) {
  81. if (!node.children) return;
  82. var sum = 0;
  83. node.children.forEach(child => {
  84. validate(child);
  85. sum += values[child.id];
  86. });
  87. // if (Math.abs(sum - values[node.id]) > 1e-3) {
  88. // var msg = [
  89. // 'Für Alter "'+entry.alter+'" und Geschlecht "'+entry.geschlecht+'"',
  90. // 'ist die Differenz von "'+node.id+'" minus der Summe der Kinder gleich',
  91. // (sum - values[node.id]).toFixed(3)
  92. // ].join(' ');
  93. // console.log(msg);
  94. // }
  95. values[node.id] = round(sum);
  96. }
  97. });
  98. // Resultat als JSON speichern
  99. fs.writeFileSync(path.join('../', config.path.build, 'data.json'), JSON.stringify(result, null, '\t'), 'utf8');
  100. // Runde alle Zahlen auf 4 Nachkommastellen
  101. function round(v) {
  102. return Math.round(v*1e4)/1e4;
  103. }
  104. }
  105. createDirectory(path.join('../', config.path.build));
  106. createDirectory(path.join('../', config.path.output));
  107. transformData();