data = {
var levels = [
[
{id: 'Entity', type: 'Concept'},
{id: 'Telic', type: 'Concept'},
{id: 'Agentive', type: 'Concept'},
{id: 'Constitutive', type: 'Concept'}
],
[
{id: 'Linguistic Entity', type: 'Concept', parents: ['Entity']}
],
[
{id: 'Relational Entity', type: 'Concept', parents: ['Linguistic Entity']},
{id: 'Concrete Element', type: 'Concept', parents: ['Linguistic Entity']},
{id: 'Mental Element', type: 'Concept', parents: ['Linguistic Entity']}
],
[
{id: 'SIGN', type: 'Concept Instance', parents: ['Relational Entity'], layers: ['1891-1892', '1899-1903', '1910-1911']},
{id: 'SIGNIFIER', type: 'Concept Instance', parents: ['Concrete Element'], layers: ['1891-1892', '1899-1903', '1910-1911']},
{id: 'SOUND', type: 'Concept Instance', parents: ['Concrete Element'], layers: ['1891-1892', '1899-1903', '1910-1911']},
{id: 'SIGNIFIED', type: 'Concept Instance', parents: ['Mental Element'], layers: ['1891-1892', '1899-1903', '1910-1911']},
{id: 'VALUE', type: 'Concept Instance', parents: ['Mental Element'], layers: ['1891-1892', '1910-1911']},
{id: 'USAGE', type: 'Concept Instance', parents: ['Mental Element'], layers: ['1891-1892']}
],
[
{id: 'sème', type: 'Term', parents: ['SIGN'], layers: ['1899-1903']},
{id: 'terme', type: 'Term', parents: ['SIGN'], layers: ['1910-1911']},
{id: 'mot', type: 'Term', parents: ['SIGN'], layers: ['1910-1911']},
{id: 'signe', type: 'Term', parents: ['SIGNIFIER','SIGN'], layers: ['1891-1892', '1899-1903','1910-1911']},
{id: 'signifiant ', type: 'Term', parents: ['SIGNIFIER'], layers: ['1910-1911']},
{id: 'image vocale ', type: 'Term', parents: ['SIGNIFIER'], layers: ['1910-1911']},
{id: 'image acoustique ', type: 'Term', parents: ['SIGNIFIER'], layers: ['1910-1911']},
{id: 'signe vocal ', type: 'Term', parents: ['SIGNIFIER'], layers: ['1910-1911']},
{id: 'signe acoustique ', type: 'Term', parents: ['SIGNIFIER'], layers: ['1910-1911']},
{id: 'figure acoustique ', type: 'Term', parents: ['SIGNIFIER'], layers: ['1910-1911']},
{id: 'sensation auditive ', type: 'Term', parents: ['SIGNIFIER'], layers: ['1910-1911']},
{id: 'son', type: 'Term', parents: ['SIGNIFIER'], layers: ['1891-1892']},
{id: 'forme', type: 'Term', parents: ['SIGNIFIER'], layers: ['1891-1892', '1899-1903']},
{id: 'sôme', type: 'Term', parents: ['SIGNIFIER'], layers: ['1899-1903']},
{id: 'côté vocal', type: 'Term', parents: ['SIGNIFIER'], layers: ['1899-1903']},
{id: 'aposème', type: 'Term', parents: ['SIGNIFIER','SOUND'], layers: ['1899-1903']},
{id: 'son ', type: 'Term', parents: ['SOUND'], layers: ['1910-1911']},
{id: 'son matériel', type: 'Term', parents: ['SOUND'], layers: ['1891-1892', '1910-1911']},
{id: 'figure vocale', type: 'Term', parents: ['SOUND'], layers: ['1891-1892', '1899-1903']},
{id: 'idée', type: 'Term', parents: ['SIGNIFIED'], layers: ['1891-1892', '1899-1903', '1910-1911']},
{id: 'sens', type: 'Term', parents: ['SIGNIFIED'], layers: ['1891-1892','1899-1903', '1910-1911']},
{id: 'signification', type: 'Term', parents: ['SIGNIFIED'], layers: ['1891-1892', '1899-1903', '1910-1911']},
{id: 'côte idéologique', type: 'Term', parents: ['SIGNIFIED'], layers: ['1899-1903']},
{id: 'concept', type: 'Term', parents: ['SIGNIFIED'], layers: ['1910-1911']},
{id: 'signifié', type: 'Term', parents: ['SIGNIFIED'], layers: ['1910-1911']},
{id: 'fonction', type: 'Term', parents: ['VALUE'], layers: ['1891-1892', '1910-1911']},
{id: 'valeur', type: 'Term', parents: ['VALUE'], layers: ['1891-1892', '1910-1911']},
{id: 'emploi', type: 'Term', parents: ['USAGE'], layers: ['1891-1892']}
],
[
{id: 'signe-idée', type: 'Term', parents: ['signe','idée','SIGN'], layers: ['1891-1892']},
{id: 'son-idée', type: 'Term', parents: ['son','idée','SIGN'], layers: ['1891-1892']},
{id: 'forme-sens', type: 'Term', parents: ['forme','sens','SIGN'], layers: ['1891-1892']}
]
]
// precompute level depth
levels.forEach((l,i) => l.forEach(n => n.level = i))
var nodes = levels.reduce( ((a,x) => a.concat(x)), [] )
var nodes_index = {}
nodes.forEach(d => nodes_index[d.id] = d)
// objectification
nodes.forEach(d => {
d.parents = (d.parents === undefined ? [] : d.parents).map(p => nodes_index[p])
})
// precompute bundles
levels.forEach((l, i) => {
var index = {}
l.forEach(n => {
if(n.parents.length == 0) {
return
}
var id = n.parents.map(d => d.id).sort().join('--')
if (id in index) {
index[id].parents = index[id].parents.concat(n.parents)
}
else {
index[id] = {id: id, parents: n.parents.slice(), level: i}
}
n.bundle = index[id]
})
l.bundles = Object.keys(index).map(k => index[k])
l.bundles.forEach((b, i) => b.i = i)
})
var links = []
nodes.forEach(d => {
d.parents.forEach(p => links.push({source: d, bundle: d.bundle, target: p}))
})
var bundles = levels.reduce( ((a,x) => a.concat(x.bundles)), [] )
// reverse pointer from parent to bundles
bundles.forEach(b => b.parents.forEach(p => {
if(p.bundles_index === undefined) {
p.bundles_index = {}
}
if(!(b.id in p.bundles_index)) {
p.bundles_index[b.id] = []
}
p.bundles_index[b.id].push(b)
}))
nodes.forEach(n => {
if(n.bundles_index !== undefined) {
n.bundles = Object.keys(n.bundles_index).map(k => n.bundles_index[k])
}
else {
n.bundles_index = {}
n.bundles = []
}
n.bundles.forEach((b, i) => b.i = i)
})
links.forEach(l => {
if(l.bundle.links === undefined) {
l.bundle.links = []
}
l.bundle.links.push(l)
})
// layout
const padding = 8
const node_height = 22
const node_width = 100
const bundle_width = 14
const level_y_padding = 16
const metro_d = 4
const c = 16
const min_family_height = 16
nodes.forEach(n => n.height = (Math.max(1, n.bundles.length)-1)*metro_d)
var x_offset = padding
var y_offset = padding
levels.forEach(l => {
x_offset += l.bundles.length*bundle_width
y_offset += level_y_padding
l.forEach((n, i) => {
n.x = n.level*node_width + x_offset
n.y = node_height + y_offset + n.height/2
y_offset += node_height + n.height
})
})
var i = 0
levels.forEach(l => {
l.bundles.forEach(b => {
b.x = b.parents[0].x + node_width + (l.bundles.length-1-b.i)*bundle_width
b.y = i*node_height
})
i += l.length
})
links.forEach(l => {
l.xt = l.target.x
l.yt = l.target.y + l.target.bundles_index[l.bundle.id].i*metro_d - l.target.bundles.length*metro_d/2 + metro_d/2
l.xb = l.bundle.x
l.xs = l.source.x
l.ys = l.source.y
})
// compress vertical space
var y_negative_offset = 0
levels.forEach(l => {
y_negative_offset += -min_family_height + d3.min(l.bundles, b => d3.min(b.links, link => (link.ys-c)-(link.yt+c))) || 0
l.forEach(n => n.y -= y_negative_offset)
})
// very ugly, I know
links.forEach(l => {
l.yt = l.target.y + l.target.bundles_index[l.bundle.id].i*metro_d - l.target.bundles.length*metro_d/2 + metro_d/2
l.ys = l.source.y
l.c1 = l.source.level-l.target.level > 1 ? node_width/2+c : c
l.c2 = c
})
var layout = {
height: d3.max(nodes, n => n.y) + node_height/2 + 2*padding,
node_height,
node_width,
bundle_width,
level_y_padding,
metro_d
}
return {levels, nodes, nodes_index, links, bundles, layout}
}