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, springConstant: 0.08, springLength: 100, 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: '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, keyboard: { enabled: true, speed: {x: 3, y: 3, zoom: 0.02}, bindToWindow: false }, multiselect: true, navigationButtons: false }, manipulation: { enabled: true, initiallyActive: true, addNode: function(nodeData, callback) { console.log('addNode', nodeData) //callback(nodeData) disabled }, editNode: function(nodeData, callback) { console.log('editNode', nodeData) //callback(nodeData) disabled }, deleteNode: function(nodeData, callback) { console.log('deleteNode', nodeData) //callback(nodeData) disabled }, addEdge: function(edgeData, callback) { if ( splitId(edgeData.from,'type') === 'person' && splitId(edgeData.to,'type') === 'person' ) { console.log('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('editEdge', edgeData) eventHub.emit('edit-relationship-modal', edgeData) callback(edgeData) } }, deleteEdge: function(edgeData, callback) { console.log('deleteEdge', edgeData) // array with edges id eventHub.emit('delete-relationship-modal', edgeData) callback(edgeData) }, controlNodeStyle: { /* shape:'dot', size: 6, color: { background: '#ff0000', border: '#3c3c3c', highlight: { background: '#07f968', border: '#3c3c3c' } }, borderWidth: 2, borderWidthSelected: 2 */ } }, 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', }, } } /** * Adapt entity to graph (id, label) * rename id in _id and add properties needed by vis * @param entity * @param options * @returns entity */ const adapt2vis = (entity, options = {}) => { entity.group = entity.type switch (entity.type) { case 'person': entity._id = entity.id entity.label = `*${entity.text}*\n_${getGender(entity.gender)} - ${getAge(entity.birthdate)}_` if (options.folded) { entity.title = visMessages.fr.visgraph.click_to_expand entity._label = entity.label // keep label entity.label = null } entity.id = `person_${entity.id}` break case 'household': entity._id = entity.id entity.label = `${visMessages.fr.visgraph.Household} n° ${entity.id}` entity.id = `household_${entity.id}` break case 'accompanying_period': entity._id = entity.id entity.label = `${visMessages.fr.visgraph.Course} n° ${entity.id}` entity.id = `accompanying_period_${entity.id}` break case 'relationship': entity._id = entity.id entity.id = `relationship_${entity.id}` break default: throw 'entity undefined' } return entity } /** * @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 label edge * @param relationship * @param reverse * @returns string */ const getRelationshipLabel = (relationship, reverse) => { return (!reverse) ? relationship.relation.title.fr : relationship.relation.reverseTitle.fr } /** * Return title edge * @param relationship * @returns string */ const getRelationshipTitle = (relationship) => { return relationship.relation.title.fr + ': ' + relationship.fromPerson.text + '\n' + relationship.relation.reverseTitle.fr + ': ' + relationship.toPerson.text } /** * Split string id and return type|id substring * @param id * @param position * @returns string */ const splitId = (id, position) => { switch (position) { case 'type': return /(.+)_/.exec(id)[1] // return 'accompanying_period' case 'id': return id.split("_").pop() // return '124' default: throw 'position undefined' } } export { adapt2vis, getHouseholdLabel, getHouseholdWidth, getRelationshipLabel, getRelationshipTitle, splitId }