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 }