gedcom-d3 2.0.7 → 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +129 -7
  2. package/d3ize.js +553 -556
  3. package/package.json +35 -35
package/d3ize.js CHANGED
@@ -1,625 +1,622 @@
1
- const d3ize = tree => {
2
- const notes = tree.filter(hasTag('NOTE'));
3
- let surnameList = []
4
- const peopleNodes = tree
5
- .filter(hasTag('INDI'))
6
- .map(p => ( toNode(p, notes, surnameList )));
7
- const families = tree.filter(hasTag('FAM'));
8
- const links = families.reduce((memo, family) => {
9
- return memo.concat(familyLinks(family, peopleNodes));
10
- }, []);
11
- assignFy(peopleNodes, links);
12
- return {
13
- nodes: peopleNodes,
14
- links: links,
15
- families: families,
16
- surnameList: surnameList
17
- };
1
+ const d3ize = (tree) => {
2
+ const notes = tree.filter(hasTag('NOTE'))
3
+ let surnameList = []
4
+ const peopleNodes = tree
5
+ .filter(hasTag('INDI'))
6
+ .map((p) => toNode(p, notes, surnameList))
7
+ const families = tree.filter(hasTag('FAM'))
8
+ const links = families.reduce((memo, family) => {
9
+ return memo.concat(familyLinks(family, peopleNodes))
10
+ }, [])
11
+ assignFy(peopleNodes, links)
12
+ return {
13
+ nodes: peopleNodes,
14
+ links: links,
15
+ families: families,
16
+ surnameList: surnameList,
17
+ }
18
18
  }
19
19
 
20
20
  // Tag search function
21
- const hasTag = val => {
22
- return node => {
23
- return node.tag === val;
24
- };
21
+ const hasTag = (val) => {
22
+ return (node) => {
23
+ return node.tag === val
24
+ }
25
25
  }
26
26
 
27
27
  // Data search function
28
- const hasData = val => {
29
- return node => {
30
- return node.data === val;
31
- };
28
+ const hasData = (val) => {
29
+ return (node) => {
30
+ return node.data === val
31
+ }
32
32
  }
33
33
 
34
34
  // ID search function
35
- const hasID = val => {
36
- return node => {
37
- return node.id === val;
38
- };
35
+ const hasID = (val) => {
36
+ return (node) => {
37
+ return node.id === val
38
+ }
39
39
  }
40
40
 
41
41
  const assignFy = (peopleNodes, links) => {
42
-
43
- // YOB known
44
- let yesyob = peopleNodes.filter(p => {
45
- return p.yob !== '?' && !isNaN(+p.yob);
46
- })
47
-
48
- yesyob.forEach(p => p.fy = +(p.yob));
49
-
50
- // YOB unknown
51
- let noyob = peopleNodes.filter(p => {
52
- return p.yob === '?';
53
- });
54
-
55
- let count = 10;
56
-
57
- // Cycle through list, adding fy until all complete
58
- while (noyob.length > 0 && count > 0) {
59
-
60
- let tempnoyob = noyob.slice();
61
-
62
- tempnoyob.forEach((p, index) => {
63
-
64
- // Build array of family
65
- let tpFamily = [];
66
-
67
- links.forEach(link => {
68
- if (link.source == p.id) {
69
- tpFamily.push({pRole: 'source', pType: link.sourceType, other: link.target, oType: link.targetType});
70
- } else if (link.target == p.id) {
71
- tpFamily.push({pRole: 'target', pType: link.targetType, other: link.source, oType: link.sourceType});
72
- };
73
- });
74
-
75
- // Check family for YOB
76
- tpFamily.forEach(member => { // USE SOME() INSTEAD OF FOREACH!!!
77
- peopleNodes.forEach(person => { // USE SOME() INSTEAD OF FOREACH!!!
78
- if (person.id == member.other && person.fy !== undefined) {
79
-
80
- // Person is source
81
- if (member.pRole === 'source') {
82
-
83
- // Person is husband
84
- if (member.pType === 'HUSB' && member.oType === 'WIFE') {
85
- p.fy = +person.fy - 3;
86
-
87
- // Person is father
88
- } else if (member.pType === 'HUSB' && member.oType === 'CHIL') {
89
- p.fy = +person.fy - 30;
90
-
91
- // Person is mother
92
- } else if (member.pType === 'WIFE') {
93
- p.fy = +person.fy - 27;
94
- }
95
-
96
- // Person is target
97
- } else if (member.pRole === 'target') {
98
-
99
- // Person is wife
100
- if (member.pType === 'WIFE' && member.oType === 'HUSB') {
101
- p.fy = +person.fy + 3;
102
-
103
- // Person is child of father
104
- } else if (member.pType === 'CHIL' && member.oType === 'HUSB') {
105
- p.fy = +person.fy + 30;
106
-
107
- // Person is child of mother
108
- } else if (member.pType === 'CHIL' && member.oType === 'WIFE') {
109
- p.fy = +person.fy + 27;
110
- }
111
- }
112
- }
113
- });
114
- });
115
- if (p.fy !== undefined) {
116
- noyob.splice(index,index +1);
117
- }
118
- })
119
- count -= 1;
120
- }
121
-
122
- const convertFy = (peopleNodes) => {
123
- const fyRatio = peopleNodes => {
124
- if (peopleNodes.length <= 50) {
125
- return 3;
126
- } else if (peopleNodes.length > 50 && peopleNodes.length <= 150) {
127
- return 4;
128
- } else if (peopleNodes.length > 150 && peopleNodes.length <= 250) {
129
- return 5;
130
- } else if (peopleNodes.length > 250){
131
- return 6;
132
- }
133
- };
134
- let allFy = [];
135
- peopleNodes.forEach(p => {
136
- if (p.fy !== undefined) {
137
- p.fy = p.fy * fyRatio(peopleNodes);
138
- allFy.push(p.fy);
139
- }
140
- })
141
-
142
- let total = 0;
143
- allFy.forEach(fy => total += fy);
144
- let average = total/allFy.length;
145
-
146
- peopleNodes.forEach(p => {
147
- if (p.fy !== undefined) {
148
- p.fy = -(p.fy - average);
149
- }
150
- });
151
- }
152
- convertFy(peopleNodes);
42
+ // YOB known
43
+ let yesyob = peopleNodes.filter((p) => {
44
+ return p.yob !== '?' && !isNaN(+p.yob)
45
+ })
46
+
47
+ yesyob.forEach((p) => (p.fy = +p.yob))
48
+
49
+ // YOB unknown
50
+ let noyob = peopleNodes.filter((p) => {
51
+ return p.yob === '?'
52
+ })
53
+
54
+ let count = 10
55
+
56
+ // Cycle through list, adding fy until all complete
57
+ while (noyob.length > 0 && count > 0) {
58
+ let tempnoyob = noyob.slice()
59
+
60
+ tempnoyob.forEach((p, index) => {
61
+ // Build array of family
62
+ let tpFamily = []
63
+
64
+ links.forEach((link) => {
65
+ if (link.source == p.id) {
66
+ tpFamily.push({
67
+ pRole: 'source',
68
+ pType: link.sourceType,
69
+ other: link.target,
70
+ oType: link.targetType,
71
+ })
72
+ } else if (link.target == p.id) {
73
+ tpFamily.push({
74
+ pRole: 'target',
75
+ pType: link.targetType,
76
+ other: link.source,
77
+ oType: link.sourceType,
78
+ })
79
+ }
80
+ })
81
+
82
+ // Check family for YOB
83
+ tpFamily.forEach((member) => {
84
+ // USE SOME() INSTEAD OF FOREACH!!!
85
+ peopleNodes.forEach((person) => {
86
+ // USE SOME() INSTEAD OF FOREACH!!!
87
+ if (person.id == member.other && person.fy !== undefined) {
88
+ // Person is source
89
+ if (member.pRole === 'source') {
90
+ // Person is husband
91
+ if (member.pType === 'HUSB' && member.oType === 'WIFE') {
92
+ p.fy = +person.fy - 3
93
+
94
+ // Person is father
95
+ } else if (member.pType === 'HUSB' && member.oType === 'CHIL') {
96
+ p.fy = +person.fy - 30
97
+
98
+ // Person is mother
99
+ } else if (member.pType === 'WIFE') {
100
+ p.fy = +person.fy - 27
101
+ }
102
+
103
+ // Person is target
104
+ } else if (member.pRole === 'target') {
105
+ // Person is wife
106
+ if (member.pType === 'WIFE' && member.oType === 'HUSB') {
107
+ p.fy = +person.fy + 3
108
+
109
+ // Person is child of father
110
+ } else if (member.pType === 'CHIL' && member.oType === 'HUSB') {
111
+ p.fy = +person.fy + 30
112
+
113
+ // Person is child of mother
114
+ } else if (member.pType === 'CHIL' && member.oType === 'WIFE') {
115
+ p.fy = +person.fy + 27
116
+ }
117
+ }
118
+ }
119
+ })
120
+ })
121
+ if (p.fy !== undefined) {
122
+ noyob.splice(index, index + 1)
123
+ }
124
+ })
125
+ count -= 1
126
+ }
127
+
128
+ const convertFy = (peopleNodes) => {
129
+ const fyRatio = (peopleNodes) => {
130
+ if (peopleNodes.length <= 50) {
131
+ return 3
132
+ } else if (peopleNodes.length > 50 && peopleNodes.length <= 150) {
133
+ return 4
134
+ } else if (peopleNodes.length > 150 && peopleNodes.length <= 250) {
135
+ return 5
136
+ } else if (peopleNodes.length > 250) {
137
+ return 6
138
+ }
139
+ }
140
+ let allFy = []
141
+ peopleNodes.forEach((p) => {
142
+ if (p.fy !== undefined) {
143
+ p.fy = p.fy * fyRatio(peopleNodes)
144
+ allFy.push(p.fy)
145
+ }
146
+ })
147
+
148
+ let total = 0
149
+ allFy.forEach((fy) => (total += fy))
150
+ let average = total / allFy.length
151
+
152
+ peopleNodes.forEach((p) => {
153
+ if (p.fy !== undefined) {
154
+ p.fy = -(p.fy - average)
155
+ }
156
+ })
157
+ }
158
+ convertFy(peopleNodes)
153
159
  }
154
160
 
155
161
  // Get title
156
- const getTitle = p => {
157
- const title = (p.tree.filter(hasTag('TITL')) || []);
158
- if (title.length > 0) {
159
- return title[title.length -1].data;
160
- }
162
+ const getTitle = (p) => {
163
+ const title = p.tree.filter(hasTag('TITL')) || []
164
+ if (title.length > 0) {
165
+ return title[title.length - 1].data
166
+ }
161
167
  }
162
168
 
163
169
  // Get full name
164
- const getName = p => {
165
- let nameNode = (p.tree.filter(hasTag('NAME')) || [])[0];
166
- if (nameNode) {
167
- return nameNode.data.replace(/\//g, '');
168
- } else {
169
- return '?';
170
- }
170
+ const getName = (p) => {
171
+ let nameNode = (p.tree.filter(hasTag('NAME')) || [])[0]
172
+ if (nameNode) {
173
+ return nameNode.data.replace(/\//g, '')
174
+ } else {
175
+ return '?'
176
+ }
171
177
  }
172
178
 
173
179
  // Get first name
174
- const getFirstName = p => {
175
-
176
- // Find 'NAME' tag
177
- const nameNode = (p.tree.filter(hasTag('NAME')) || [])[0];
178
- if (nameNode) {
179
-
180
- // Find 'GIVN' tag
181
- let firstNameNode = (nameNode.tree.filter(hasTag('GIVN')) || [])[0];
182
- if (firstNameNode) {
183
-
184
- // Remove middle name
185
- if (firstNameNode.data.search(' ') !== -1) {
186
- return firstNameNode.data.slice(0, firstNameNode.data.search(' '));
187
- } else {
188
- return firstNameNode.data;
189
- }
190
- } else {
191
- return '?';
192
- }
193
- } else {
194
- return '?';
195
- }
180
+ const getFirstName = (p) => {
181
+ // Find 'NAME' tag
182
+ const nameNode = (p.tree.filter(hasTag('NAME')) || [])[0]
183
+ if (nameNode) {
184
+ // Find 'GIVN' tag
185
+ let firstNameNode = (nameNode.tree.filter(hasTag('GIVN')) || [])[0]
186
+ if (firstNameNode) {
187
+ // Remove middle name
188
+ if (firstNameNode.data.search(' ') !== -1) {
189
+ return firstNameNode.data.slice(0, firstNameNode.data.search(' '))
190
+ } else {
191
+ return firstNameNode.data
192
+ }
193
+ } else {
194
+ return '?'
195
+ }
196
+ } else {
197
+ return '?'
198
+ }
196
199
  }
197
200
 
198
201
  // Get surname
199
- const getSurname = p => {
200
-
201
- // Find 'NAME' tag
202
- const nameNode = (p.tree.filter(hasTag('NAME')) || [])[0];
203
- if (nameNode) {
204
-
205
- // Find 'SURN' tag
206
- const surnameNode = (nameNode.tree.filter(hasTag('SURN')) || [])[0];
207
-
208
- // If surname listed
209
- if (surnameNode) {
210
-
211
- // Remove alternate surnames
212
- if (surnameNode.data.search(',') !== -1) {
213
- return surnameNode.data.slice(0, surnameNode.data.search(','));
214
- } else {
215
- return surnameNode.data;
216
- }
217
-
218
- // Derive surname from name
219
- } else {
220
- nameArr = nameNode.data.split(' ');
221
-
222
- // Look for forward slashes
223
- let isSlashes = nameArr.some(str => str[0] === "/");
224
- if (isSlashes) {
225
- return nameArr.find(str => str[0] === "/").replace(/\//g, '');
226
-
227
- // no slashes, use final item in array
228
- } else {
229
- nameArr[nameArr.length -1] = nameArr[nameArr.length -1].replace(/\//g, '')
230
- return nameArr.length > 1 ? nameArr[nameArr.length -1] : "Hrm"
231
- }
232
- }
233
- } else {
234
- return '?';
235
- }
202
+ const getSurname = (p) => {
203
+ // Find 'NAME' tag
204
+ const nameNode = (p.tree.filter(hasTag('NAME')) || [])[0]
205
+ if (nameNode) {
206
+ // Find 'SURN' tag
207
+ const surnameNode = (nameNode.tree.filter(hasTag('SURN')) || [])[0]
208
+
209
+ // If surname listed
210
+ if (surnameNode) {
211
+ // Remove alternate surnames
212
+ if (surnameNode.data.search(',') !== -1) {
213
+ return surnameNode.data.slice(0, surnameNode.data.search(','))
214
+ } else {
215
+ return surnameNode.data
216
+ }
217
+
218
+ // Derive surname from name
219
+ } else {
220
+ nameArr = nameNode.data.split(' ')
221
+
222
+ // Look for forward slashes
223
+ let isSlashes = nameArr.some((str) => str[0] === '/')
224
+ if (isSlashes) {
225
+ return nameArr.find((str) => str[0] === '/').replace(/\//g, '')
226
+
227
+ // no slashes, use final item in array
228
+ } else {
229
+ nameArr[nameArr.length - 1] = nameArr[nameArr.length - 1].replace(
230
+ /\//g,
231
+ ''
232
+ )
233
+ return nameArr.length > 1 ? nameArr[nameArr.length - 1] : 'Hrm'
234
+ }
235
+ }
236
+ } else {
237
+ return '?'
238
+ }
236
239
  }
237
240
 
238
241
  // Get gender
239
- const getGender = p => {
240
-
241
- // Find 'SEX' tag
242
- let genderNode = (p.tree.filter(hasTag('SEX')) || [])[0];
243
- if (genderNode) {
244
- return genderNode.data;
245
- } else {
246
- return 'Unknown';
247
- }
242
+ const getGender = (p) => {
243
+ // Find 'SEX' tag
244
+ let genderNode = (p.tree.filter(hasTag('SEX')) || [])[0]
245
+ if (genderNode) {
246
+ return genderNode.data
247
+ } else {
248
+ return 'Unknown'
249
+ }
248
250
  }
249
251
 
250
252
  // Get date of birth
251
- const getDOB = p => {
252
-
253
- // Find 'BIRT' tag
254
- let dobNode = (p.tree.filter(hasTag('BIRT')) || [])[0];
255
- if (dobNode) {
256
-
257
- // Find 'DATE' tag
258
- let dateNode = (dobNode.tree.filter(hasTag('DATE')) || [])[0];
259
- if (dateNode) {
260
- return dateNode.data;
261
- } else {
262
- return '?';
263
- }
264
- } else {
265
- return '?';
266
- }
253
+ const getDOB = (p) => {
254
+ // Find 'BIRT' tag
255
+ let dobNode = (p.tree.filter(hasTag('BIRT')) || [])[0]
256
+ if (dobNode) {
257
+ // Find 'DATE' tag
258
+ let dateNode = (dobNode.tree.filter(hasTag('DATE')) || [])[0]
259
+ if (dateNode) {
260
+ return dateNode.data
261
+ } else {
262
+ return '?'
263
+ }
264
+ } else {
265
+ return '?'
266
+ }
267
267
  }
268
268
 
269
269
  // Get year of birth
270
- const getYOB = p => {
271
-
272
- // Find 'BIRT' tag
273
- let dobNode = (p.tree.filter(hasTag('BIRT')) || [])[0];
274
- if (dobNode) {
275
-
276
- // Find 'DATE' tag
277
- let dateNode = (dobNode.tree.filter(hasTag('DATE')) || [])[0];
278
- if (dateNode) {
279
- return dateNode.data.slice(-4);
280
- } else {
281
- return '?';
282
- }
283
- } else {
284
- return '?';
285
- }
270
+ const getYOB = (p) => {
271
+ // Find 'BIRT' tag
272
+ let dobNode = (p.tree.filter(hasTag('BIRT')) || [])[0]
273
+ if (dobNode) {
274
+ // Find 'DATE' tag
275
+ let dateNode = (dobNode.tree.filter(hasTag('DATE')) || [])[0]
276
+ if (dateNode) {
277
+ return dateNode.data.slice(-4)
278
+ } else {
279
+ return '?'
280
+ }
281
+ } else {
282
+ return '?'
283
+ }
286
284
  }
287
285
 
288
286
  // Get place of birth
289
- const getPOB = p => {
290
-
291
- // Find 'BIRT' tag
292
- let pobNode = (p.tree.filter(hasTag('BIRT')) || [])[0];
293
- if (pobNode) {
294
-
295
- // Find 'DATE' tag
296
- let placeNode = (pobNode.tree.filter(hasTag('PLAC')) || [])[0];
297
- if (placeNode) {
298
- return placeNode.data;
299
- } else {
300
- return '';
301
- }
302
- } else {
303
- return '';
304
- }
287
+ const getPOB = (p) => {
288
+ // Find 'BIRT' tag
289
+ let pobNode = (p.tree.filter(hasTag('BIRT')) || [])[0]
290
+ if (pobNode) {
291
+ // Find 'DATE' tag
292
+ let placeNode = (pobNode.tree.filter(hasTag('PLAC')) || [])[0]
293
+ if (placeNode) {
294
+ return placeNode.data
295
+ } else {
296
+ return ''
297
+ }
298
+ } else {
299
+ return ''
300
+ }
305
301
  }
306
302
 
307
303
  // Get date of death
308
- const getDOD = p => {
309
-
310
- // Find 'DEAT' tag
311
- let dobNode = (p.tree.filter(hasTag('BIRT')) || [])[0];
312
- let dodNode = (p.tree.filter(hasTag('DEAT')) || [])[0];
313
- if (dodNode) {
314
-
315
- // Find 'DATE' tag
316
- let dateNode = (dodNode.tree.filter(hasTag('DATE')) || [])[0];
317
- if (dateNode) {
318
- return dateNode.data;
319
- } else {
320
- return '?';
321
- }
322
- } else if (dobNode) {
323
- let dateNode = (dobNode.tree.filter(hasTag('DATE')) || [])[0];
324
- if (dateNode) {
325
- return dateNode.data.slice(-4) + 100;
326
- } else {
327
- return '?';
328
- }
329
- } else {
330
- return 'Present';
331
- }
304
+ const getDOD = (p) => {
305
+ // Find 'DEAT' tag
306
+ let dobNode = (p.tree.filter(hasTag('BIRT')) || [])[0]
307
+ let dodNode = (p.tree.filter(hasTag('DEAT')) || [])[0]
308
+ if (dodNode) {
309
+ // Find 'DATE' tag
310
+ let dateNode = (dodNode.tree.filter(hasTag('DATE')) || [])[0]
311
+ if (dateNode) {
312
+ return dateNode.data
313
+ } else {
314
+ return '?'
315
+ }
316
+ } else if (dobNode) {
317
+ let dateNode = (dobNode.tree.filter(hasTag('DATE')) || [])[0]
318
+ if (dateNode) {
319
+ return dateNode.data.slice(-4) + 100
320
+ } else {
321
+ return '?'
322
+ }
323
+ } else {
324
+ return 'Present'
325
+ }
332
326
  }
333
327
 
334
328
  // Get year of death
335
- const getYOD = p => {
336
- let thisYear = new Date().getFullYear();
337
-
338
- // Find 'DEAT' tag
339
- let dobNode = (p.tree.filter(hasTag('BIRT')) || [])[0];
340
- let dodNode = (p.tree.filter(hasTag('DEAT')) || [])[0];
341
-
342
- // If DEATH tag
343
- if (dodNode) {
344
-
345
- // Find 'DATE' tag
346
- let dateNode = (dodNode.tree.filter(hasTag('DATE')) || [])[0];
347
-
348
- // If death date listed
349
- if (dateNode) {
350
- return dateNode.data.slice(-4);
351
- } else {
352
- return '?';
353
- }
354
-
355
- // BIRT tag, but no DEAT tag
356
- } else if (dobNode && !dodNode) {
357
- let dateNode = (dobNode.tree.filter(hasTag('DATE')) || [])[0];
358
-
359
- // If DOB listed
360
- if (dateNode) {
361
-
362
- // If born > 100 yrs ago, call dead
363
- if (dateNode.data.slice(-4) < (thisYear - 100)) {
364
- return '?';
365
- } else {
366
- return 'Present';
367
- }
368
- } else {
369
- return '?';
370
- }
371
-
372
- // no DEAT or BIRT tag
373
- } else {
374
- return '?';
375
- }
329
+ const getYOD = (p) => {
330
+ let thisYear = new Date().getFullYear()
331
+
332
+ // Find 'DEAT' tag
333
+ let dobNode = (p.tree.filter(hasTag('BIRT')) || [])[0]
334
+ let dodNode = (p.tree.filter(hasTag('DEAT')) || [])[0]
335
+
336
+ // If DEATH tag
337
+ if (dodNode) {
338
+ // Find 'DATE' tag
339
+ let dateNode = (dodNode.tree.filter(hasTag('DATE')) || [])[0]
340
+
341
+ // If death date listed
342
+ if (dateNode) {
343
+ return dateNode.data.slice(-4)
344
+ } else {
345
+ return '?'
346
+ }
347
+
348
+ // BIRT tag, but no DEAT tag
349
+ } else if (dobNode && !dodNode) {
350
+ let dateNode = (dobNode.tree.filter(hasTag('DATE')) || [])[0]
351
+
352
+ // If DOB listed
353
+ if (dateNode) {
354
+ // If born > 100 yrs ago, call dead
355
+ if (dateNode.data.slice(-4) < thisYear - 100) {
356
+ return '?'
357
+ } else {
358
+ return 'Present'
359
+ }
360
+ } else {
361
+ return '?'
362
+ }
363
+
364
+ // no DEAT or BIRT tag
365
+ } else {
366
+ return '?'
367
+ }
376
368
  }
377
369
 
378
370
  // Get place of birth
379
- const getPOD = p => {
380
-
381
- // Find 'BIRT' tag
382
- let podNode = (p.tree.filter(hasTag('DEAT')) || [])[0];
383
- if (podNode) {
384
-
385
- // Find 'DATE' tag
386
- let placeNode = (podNode.tree.filter(hasTag('PLAC')) || [])[0];
387
- if (placeNode) {
388
- return placeNode.data;
389
- } else {
390
- return '';
391
- }
392
- } else {
393
- return '';
394
- }
371
+ const getPOD = (p) => {
372
+ // Find 'BIRT' tag
373
+ let podNode = (p.tree.filter(hasTag('DEAT')) || [])[0]
374
+ if (podNode) {
375
+ // Find 'DATE' tag
376
+ let placeNode = (podNode.tree.filter(hasTag('PLAC')) || [])[0]
377
+ if (placeNode) {
378
+ return placeNode.data
379
+ } else {
380
+ return ''
381
+ }
382
+ } else {
383
+ return ''
384
+ }
395
385
  }
396
386
 
397
387
  // Get relatives
398
- const getFamilies = p => {
399
- let families = [];
400
- let pediInfo;
401
- // If child
402
- let familyNode1 = (p.tree.filter(hasTag('FAMC')) || []);
403
- if (familyNode1) {
404
- for (let i = 0; i < familyNode1.length; i++) {
405
- if (familyNode1[i].tree.length > 0) {
406
- // Get pedigree info
407
- if (familyNode1[i].tree[0].tag == 'PEDI') {
408
- pediInfo = {frel: familyNode1[i].tree[0].data, mrel: familyNode1[i].tree[0].data}
409
- } else if (familyNode1[i].tree[0].tag == '_FREL') {
410
- pediInfo = {frel: familyNode1[i].tree[0].data, mrel: familyNode1[i].tree[1].data}
411
- }
412
- }
413
-
414
- families.push({id: familyNode1[i].data, pedi: pediInfo});
415
- }
416
- }
417
- let familyNode2 = (p.tree.filter(hasTag('FAMS')) || []);
418
- if (familyNode2) {
419
- for (let i = 0; i < familyNode2.length; i++) {
420
- families.push({id:familyNode2[i].data});
421
- }
422
- }
423
- return families;
388
+ const getFamilies = (p) => {
389
+ let families = []
390
+ let pediInfo
391
+ // If child
392
+ let familyNode1 = p.tree.filter(hasTag('FAMC')) || []
393
+ if (familyNode1) {
394
+ for (let i = 0; i < familyNode1.length; i++) {
395
+ if (familyNode1[i].tree.length > 0) {
396
+ // Get pedigree info
397
+ if (familyNode1[i].tree[0].tag == 'PEDI') {
398
+ pediInfo = {
399
+ frel: familyNode1[i].tree[0].data,
400
+ mrel: familyNode1[i].tree[0].data,
401
+ }
402
+ } else if (familyNode1[i].tree[0].tag == '_FREL') {
403
+ pediInfo = {
404
+ frel: familyNode1[i].tree[0].data,
405
+ mrel: familyNode1[i].tree[1].data,
406
+ }
407
+ }
408
+ }
409
+
410
+ families.push({ id: familyNode1[i].data, pedi: pediInfo })
411
+ }
412
+ }
413
+ let familyNode2 = p.tree.filter(hasTag('FAMS')) || []
414
+ if (familyNode2) {
415
+ for (let i = 0; i < familyNode2.length; i++) {
416
+ families.push({ id: familyNode2[i].data })
417
+ }
418
+ }
419
+ return families
424
420
  }
425
421
 
426
422
  // Get color
427
423
  const getColor = (p, surnameList) => {
428
- const colorList = [
429
- '#ff7f50', // coral
430
- '#00b4ff', // sky blue
431
- '#fac641', // mexican egg yolk
432
- '#8a9b0f', // olive
433
- '#a7dbd8', // sea foam
434
- '#a37e58', // light brown
435
- '#ec4913', // burnt orange
436
- '#a27dbd', // soft royal purple
437
- '#11644d', // forest
438
- '#b3347c', // magenta
439
- '#359668', // grass & sage
440
- '#fab8b4', // soft pink
441
- '#6de627', // neon green
442
- '#ecd078', // tangerine
443
- '#bfcff7', // ligt purple blue
444
- '#e08e79', // blush
445
- '#c44d58', // rouge
446
- '#c4ffeb', // light sea foam
447
- '#a6b890', // olive sage
448
- '#aaaaaa', // light blue grey
449
- '#ffd3b5', // peach
450
- '#826942', // chocolate
451
- '#d4ee5e', // lime
452
- '#ecfc85', // light yellow
453
- '#666666', // off white
454
- '#ffa1c3', // newborn pink
455
- '#6541a3', // royal purple
456
- '#75616b', // dry wine
457
- '#71cfde', // baby foam
458
- '#e0e0e0', // light grey
459
- ];
460
-
461
- // If color description listed in GEDCOM
462
- const dscr = (p.tree.filter(hasTag('DSCR')) || [])[0];
463
-
464
- const foundName = surnameList.find(sName => sName.surname === p.surname);
465
-
466
- // If surname already in list
467
- if (foundName) {
468
- foundName.count = foundName.count +1;
469
- } else {
470
- surnameList.push({
471
- surname: p.surname,
472
- count: 1,
473
- color: colorList[surnameList.length % colorList.length]
474
- })
475
- }
476
-
477
- // surnameList.color = surnameList.length % colorList.length});
478
-
479
- // If color listed assign that
480
- if (dscr) {
481
- return dscr.data;
482
-
483
- // else assign color from colorList
484
- } else {
485
- return surnameList.find(sName => sName.surname === p.surname).color;
486
- }
424
+ const colorList = [
425
+ '#ff7f50', // coral
426
+ '#00b4ff', // sky blue
427
+ '#fac641', // mexican egg yolk
428
+ '#8a9b0f', // olive
429
+ '#70ccc7', // sea foam
430
+ '#a37e58', // light brown
431
+ '#ec4913', // burnt orange
432
+ '#a27dbd', // soft royal purple
433
+ '#11644d', // forest
434
+ '#b3347c', // magenta
435
+ '#359668', // grass & sage
436
+ '#e87c76', // soft pink
437
+ '#80d152', // neon green
438
+ '#ecd078', // tangerine
439
+ '#6e90e6', // ligt purple blue
440
+ '#e08e79', // blush
441
+ '#c44d58', // rouge
442
+ '#7ff0ca', // light sea foam
443
+ '#a6b890', // olive sage
444
+ '#a5c2cc', // light blue grey
445
+ '#e8b28e', // peach
446
+ '#826942', // chocolate
447
+ '#d4ee5e', // lime
448
+ '#cad96a', // light yellow
449
+ '#e887aa', // newborn pink
450
+ '#6541a3', // royal purple
451
+ '#75616b', // dry wine
452
+ '#71cfde', // baby foam
453
+ '#7a7a7a', // light grey
454
+ ]
455
+
456
+ // If color description listed in GEDCOM
457
+ const dscr = (p.tree.filter(hasTag('DSCR')) || [])[0]
458
+
459
+ const foundName = surnameList.find((sName) => sName.surname === p.surname)
460
+
461
+ // If surname already in list
462
+ if (foundName) {
463
+ foundName.count = foundName.count + 1
464
+ } else {
465
+ surnameList.push({
466
+ surname: p.surname,
467
+ count: 1,
468
+ color: colorList[surnameList.length % colorList.length],
469
+ })
470
+ }
471
+
472
+ // surnameList.color = surnameList.length % colorList.length});
473
+
474
+ // If color listed assign that
475
+ if (dscr) {
476
+ return dscr.data
477
+
478
+ // else assign color from colorList
479
+ } else {
480
+ return surnameList.find((sName) => sName.surname === p.surname).color
481
+ }
487
482
  }
488
483
 
489
484
  // Get person notes
490
- const getNotes = p => {
491
- return p.tree.filter(hasTag('NOTE'));
485
+ const getNotes = (p) => {
486
+ return p.tree.filter(hasTag('NOTE'))
492
487
  }
493
488
 
494
489
  // Get Bio
495
490
  const getBio = (p, notes) => {
496
-
497
- if (p.notes.length != 0) {
498
- let bio = '';
499
-
500
- // Notes for person
501
- p.notes.forEach(personNote => {
502
-
503
- // personNote.data points to NOTE object
504
- if (notes.length > 0) {
505
- notes.forEach(note => {
506
- if (personNote.data === note.pointer) {
507
- bio += note.data;
508
-
509
- // Concat broken up note
510
- if (note.tree.length > 0) { note.tree.forEach(fragment => bio += fragment.data) }
511
-
512
- }
513
- });
514
-
515
- // personNote.data is actual note
516
- } else {
517
- bio += personNote.data;
518
- }
519
- });
520
- return bio;
521
- }
491
+ if (p.notes.length != 0) {
492
+ let bio = ''
493
+
494
+ // Notes for person
495
+ p.notes.forEach((personNote) => {
496
+ // personNote.data points to NOTE object
497
+ if (notes.length > 0) {
498
+ notes.forEach((note) => {
499
+ if (personNote.data === note.pointer) {
500
+ bio += note.data
501
+
502
+ // Concat broken up note
503
+ if (note.tree.length > 0) {
504
+ note.tree.forEach((fragment) => (bio += fragment.data))
505
+ }
506
+ }
507
+ })
508
+
509
+ // personNote.data is actual note
510
+ } else {
511
+ bio += personNote.data
512
+ }
513
+ })
514
+ return bio
515
+ }
522
516
  }
523
517
 
524
- const getFy = p => {
525
- if(p.yob === '?') {
526
- return 0;
527
- } else {
528
- return +(-p.yob * 3 + 6000);
529
- }
518
+ const getFy = (p) => {
519
+ if (p.yob === '?') {
520
+ return 0
521
+ } else {
522
+ return +(-p.yob * 3 + 6000)
523
+ }
530
524
  }
531
525
 
532
526
  const toNode = (p, notes, surnameList) => {
533
- p.id = p.pointer;
534
- p.title = getTitle(p);
535
- p.name = getName(p);
536
- p.firstName = getFirstName(p);
537
- p.surname = getSurname(p);
538
- p.gender = getGender(p);
539
- p.dob = getDOB(p);
540
- p.yob = getYOB(p);
541
- p.pob = getPOB(p);
542
- p.dod = getDOD(p);
543
- p.yod = getYOD(p);
544
- p.pod = getPOD(p);
545
- p.families = getFamilies(p);
546
- p.color = getColor(p, surnameList);
547
- p.notes = getNotes(p);
548
- p.bio = getBio(p, notes);
549
- return p;
527
+ p.id = p.pointer
528
+ p.title = getTitle(p)
529
+ p.name = getName(p)
530
+ p.firstName = getFirstName(p)
531
+ p.surname = getSurname(p)
532
+ p.gender = getGender(p)
533
+ p.dob = getDOB(p)
534
+ p.yob = getYOB(p)
535
+ p.pob = getPOB(p)
536
+ p.dod = getDOD(p)
537
+ p.yod = getYOD(p)
538
+ p.pod = getPOD(p)
539
+ p.families = getFamilies(p)
540
+ p.color = getColor(p, surnameList)
541
+ p.notes = getNotes(p)
542
+ p.bio = getBio(p, notes)
543
+ return p
550
544
  }
551
545
 
552
546
  const familyLinks = (family, peopleNodes) => {
553
-
554
- let memberLinks = [];
555
- let maritalStatus = null;
556
- let pedigree;
557
-
558
- // Filter only individual objects from family tree
559
- let memberSet = family.tree.filter(function(member) {
560
- return member.tag && (member.tag === 'HUSB' || member.tag === 'WIFE' || member.tag === 'CHIL');
561
- })
562
-
563
- // Filter marital status events
564
- family.tree.filter(event => {
565
- if (event.tag === 'DIV' || event.tag === 'MARR') {
566
- if (maritalStatus !== 'DIV') {
567
- maritalStatus = event.tag;
568
- }
569
- }
570
- })
571
-
572
- // Iterate over each member of set to connect with other members
573
- while (memberSet.length > 1) {
574
- for (let i = 1; i < memberSet.length; i++) {
575
-
576
- // Exclude sibling relationships
577
- if (memberSet[0].tag != 'CHIL') {
578
-
579
- // If marital status listed
580
- if (memberSet[0].tag == 'HUSB' && memberSet[i].tag == 'WIFE') {
581
- memberLinks.push({
582
- "source": memberSet[0].data,
583
- "target": memberSet[i].data,
584
- "sourceType": memberSet[0].tag,
585
- "targetType": memberSet[i].tag,
586
- "type": maritalStatus
587
- })
588
- } else {
589
-
590
- // Filter pedigree info
591
- function getPedigree(personID, parentType, relInfo) {
592
- // GRAMPS
593
- let person = peopleNodes.filter(hasID(personID));
594
- let personFamily = person[0].families.filter(hasID(family.pointer));
595
- if (parentType == 'HUSB') {
596
- if (personFamily[0].pedi) {
597
- return personFamily[0].pedi.frel;
598
- } else if (relInfo.some(parent => parent.tag === "_FREL")) {
599
- return relInfo.find(parent => parent.tag === "_FREL").data;
600
- }
601
- } else {
602
- if (personFamily[0].pedi) {
603
- return personFamily[0].pedi.mrel;
604
- } else if (relInfo.some(parent => parent.tag === "_MREL")) {
605
- return relInfo.find(parent => parent.tag === "_MREL").data;
606
- }
607
- }
608
- }
609
-
610
- memberLinks.push({
611
- "source": memberSet[0].data,
612
- "target": memberSet[i].data,
613
- "sourceType": memberSet[0].tag,
614
- "targetType": memberSet[i].tag,
615
- "type": getPedigree(memberSet[i].data, memberSet[0].tag, memberSet[i].tree)
616
- })
617
- }
618
- }
619
- }
620
- memberSet.splice(0,1);
621
- }
622
- return memberLinks;
547
+ let memberLinks = []
548
+ let maritalStatus = null
549
+ let pedigree
550
+
551
+ // Filter only individual objects from family tree
552
+ let memberSet = family.tree.filter(function (member) {
553
+ return (
554
+ member.tag &&
555
+ (member.tag === 'HUSB' || member.tag === 'WIFE' || member.tag === 'CHIL')
556
+ )
557
+ })
558
+
559
+ // Filter marital status events
560
+ family.tree.filter((event) => {
561
+ if (event.tag === 'DIV' || event.tag === 'MARR') {
562
+ if (maritalStatus !== 'DIV') {
563
+ maritalStatus = event.tag
564
+ }
565
+ }
566
+ })
567
+
568
+ // Iterate over each member of set to connect with other members
569
+ while (memberSet.length > 1) {
570
+ for (let i = 1; i < memberSet.length; i++) {
571
+ // Exclude sibling relationships
572
+ if (memberSet[0].tag != 'CHIL') {
573
+ // If marital status listed
574
+ if (memberSet[0].tag == 'HUSB' && memberSet[i].tag == 'WIFE') {
575
+ memberLinks.push({
576
+ source: memberSet[0].data,
577
+ target: memberSet[i].data,
578
+ sourceType: memberSet[0].tag,
579
+ targetType: memberSet[i].tag,
580
+ type: maritalStatus,
581
+ })
582
+ } else {
583
+ // Filter pedigree info
584
+ function getPedigree(personID, parentType, relInfo) {
585
+ // GRAMPS
586
+ let person = peopleNodes.filter(hasID(personID))
587
+ let personFamily = person[0].families.filter(hasID(family.pointer))
588
+ if (parentType == 'HUSB') {
589
+ if (personFamily[0].pedi) {
590
+ return personFamily[0].pedi.frel
591
+ } else if (relInfo.some((parent) => parent.tag === '_FREL')) {
592
+ return relInfo.find((parent) => parent.tag === '_FREL').data
593
+ }
594
+ } else {
595
+ if (personFamily[0].pedi) {
596
+ return personFamily[0].pedi.mrel
597
+ } else if (relInfo.some((parent) => parent.tag === '_MREL')) {
598
+ return relInfo.find((parent) => parent.tag === '_MREL').data
599
+ }
600
+ }
601
+ }
602
+
603
+ memberLinks.push({
604
+ source: memberSet[0].data,
605
+ target: memberSet[i].data,
606
+ sourceType: memberSet[0].tag,
607
+ targetType: memberSet[i].tag,
608
+ type: getPedigree(
609
+ memberSet[i].data,
610
+ memberSet[0].tag,
611
+ memberSet[i].tree
612
+ ),
613
+ })
614
+ }
615
+ }
616
+ }
617
+ memberSet.splice(0, 1)
618
+ }
619
+ return memberLinks
623
620
  }
624
621
 
625
- module.exports = d3ize;
622
+ module.exports = d3ize