2021-11-09 20:06:54 +01:00

295 lines
7.7 KiB
JavaScript

import { visMessages } from './i18n'
import { TinyEmitter } from "tiny-emitter";
/**
* Vis-network initial data/configuration script
* Notes:
* Use window.network and window.options to avoid conflict between vue and vis
* cfr. https://github.com/almende/vis/issues/2524#issuecomment-307108271
*/
console.log('@@@ init eventHub App @@@')
window.eventHub = new TinyEmitter()
window.network = {}
window.options = {
locale: 'fr',
locales: visMessages,
/*
configure: {
enabled: true,
filter: 'nodes,edges',
//container: undefined,
showButton: true
},
*/
physics: {
enabled: true,
barnesHut: {
theta: 0.5,
gravitationalConstant: -2000,
centralGravity: 0.08, //// 0.3
springLength: 220, //// 95
springConstant: 0.04,
damping: 0.09,
avoidOverlap: 0
},
forceAtlas2Based: {
theta: 0.5,
gravitationalConstant: -50,
centralGravity: 0.01,
springLength: 100,
springConstant: 0.08,
damping: 0.4,
avoidOverlap: 0
},
repulsion: {
centralGravity: 0.2,
springLength: 200,
springConstant: 0.05,
nodeDistance: 100,
damping: 0.09
},
hierarchicalRepulsion: {
centralGravity: 0.0,
springLength: 100,
springConstant: 0.01,
nodeDistance: 120,
damping: 0.09,
avoidOverlap: 0
},
maxVelocity: 50,
minVelocity: 0.1,
solver: 'forceAtlas2Based', //'barnesHut', //
stabilization: {
enabled: true,
iterations: 1000,
updateInterval: 100,
onlyDynamicEdges: false,
fit: true
},
timestep: 0.5,
adaptiveTimestep: true,
wind: { x: 0, y: 0 }
},
interaction: {
hover: true,
multiselect: true,
navigationButtons: false,
},
manipulation: {
enabled: false,
initiallyActive: false,
addNode: false,
//editNode: function(nodeData, callback) { callback(nodeData) }, //disabled if undefined
deleteNode: false,
// TODO see alternative with 'Manipulation methods to use the manipulation system without GUI.'
addEdge: function(edgeData, callback) {
if (
splitId(edgeData.from,'type') === 'person'
&& splitId(edgeData.to,'type') === 'person'
) {
console.log('callback addEdge', edgeData)
eventHub.emit('add-relationship-modal', edgeData)
callback(edgeData)
}
},
editEdge: function(edgeData, callback) {
if (
splitId(edgeData.from,'type') === 'person'
&& splitId(edgeData.to,'type') === 'person'
) {
console.log('callback editEdge', edgeData)
eventHub.emit('edit-relationship-modal', edgeData)
callback(edgeData)
}
},
deleteEdge: function(edgeData, callback) {
console.log('callback deleteEdge', edgeData) // array with edges id
eventHub.emit('delete-relationship-modal', edgeData)
callback(edgeData)
}
// end TODO
},
nodes: {
borderWidth: 1,
borderWidthSelected: 3,
font: {
multi: 'md'
}
},
edges: {
font: {
color: '#b0b0b0',
size: 9,
face: 'arial',
background: 'none',
strokeWidth: 2, // px
strokeColor: '#ffffff',
align: 'middle',
multi: false,
vadjust: 0,
},
scaling:{
label: true,
},
smooth: true,
},
groups: {
person: {
shape: 'box',
shapeProperties: {
borderDashes: false,
borderRadius: 3,
},
color: {
border: '#b0b0b0',
background: 'rgb(193,229,222)',
highlight: {
border: '#89c9a9',
background: 'rgb(156,213,203)'
},
hover: {
border: '#89c9a9',
background: 'rgb(156,213,203)'
}
},
opacity: 0.85,
shadow:{
enabled: true,
color: 'rgba(0,0,0,0.5)',
size:10,
x:5,
y:5
},
},
household: {
color: 'pink'
},
accompanying_period: {
color: 'orange',
},
}
}
/**
* @param gender
* @returns {string}
*/
const getGender = (gender) => {
switch (gender) {
case 'both':
return visMessages.fr.visgraph.both
case 'woman':
return visMessages.fr.visgraph.woman
case 'man':
return visMessages.fr.visgraph.man
default:
throw 'gender undefined'
}
}
/**
* TODO Repeat getAge() in PersonRenderBox.vue
* @param birthdate
* @returns {string|null}
*/
const getAge = (birthdate) => {
if (null === birthdate) {
return null
}
const birthday = new Date(birthdate.datetime)
const now = new Date()
return (now.getFullYear() - birthday.getFullYear()) + ' '+ visMessages.fr.visgraph.years
}
/**
* Return member position in household
* @param member
* @returns string
*/
const getHouseholdLabel = (member) => {
let position = member.position.label.fr
let holder = member.holder ? ` ${visMessages.fr.visgraph.Holder}` : ''
return position + holder
}
/**
* Return edge width for member (depends of position in household)
* @param member
* @returns integer (width)
*/
const getHouseholdWidth = (member) => {
if (member.holder) {
return 5
}
if (member.shareHousehold) {
return 2
}
return 1
}
/**
* Return direction edge
* @param relationship
* @returns string
*/
const getRelationshipDirection = (relationship) => {
return (!relationship.reverse) ? 'to' : 'from'
}
/**
* Return label edge
* !! always set label in title direction (arrow is reversed, see in previous method) !!
* @param relationship
* @returns string
*/
const getRelationshipLabel = (relationship) => {
return relationship.relation.title.fr
}
/**
* Return title edge
* @param relationship
* @returns string
*/
const getRelationshipTitle = (relationship) => {
return (!relationship.reverse) ?
relationship.relation.title.fr + ': ' + relationship.fromPerson.text + '\n' + relationship.relation.reverseTitle.fr + ': ' + relationship.toPerson.text :
relationship.relation.title.fr + ': ' + relationship.toPerson.text + '\n' + relationship.relation.reverseTitle.fr + ': ' + relationship.fromPerson.text
}
/**
* Split string id and return type|id substring
* @param id
* @param position
* @returns string|integer
*/
const splitId = (id, position) => {
//console.log(id, position)
switch (position) {
case 'type': // return 'accompanying_period'
return /(.+)_/.exec(id)[1]
case 'id': // return 124
return parseInt(id.toString()
.split("_")
.pop())
case 'link':
return id.split("-")[0] // return first segment
default:
throw 'position undefined'
}
}
export {
getGender,
getAge,
getHouseholdLabel,
getHouseholdWidth,
getRelationshipDirection,
getRelationshipLabel,
getRelationshipTitle,
splitId
}