Commit d3fa7e03 authored by Themousaillon's avatar Themousaillon

transfer of the project

parent 2f252f4b
node_modules
*.log
*.tmp
*._DS_Store
*_DS_Store
*.DS_Store
/.idea
/lib
/lib.old
/out
/static/config.json
/karma_html/
package-lock.json
.vscode
deploy
\ No newline at end of file
## TODO
TODO
## Features
TODO
## Change Log
Changes to the component will be documented in this file.
## [0.1.0] - yyyy-mm-dd
### New features
- None
### Bugs
- None.
### Enhancement
- None.
## Development Environment
The source code is hosted on GitLab.
Use npm to install the local dependencies. Some modules may be installed globally.
## Tools & Frameworks
- Node
https://nodejs.org
- WebStorm
https://www.jetbrains.com/webstorm/download/#
- Babel install module + presets
https://babeljs.io
- ESLint
http://eslint.org
https://github.com/babel/babel-eslint
Enable ESLint in WebStorm : Languages & Frameworks : Javascript : Code Quality Tools : ESLint.
- JSDoc
Built-in in WebStorm : type /** + Enter.
http://en.wikipedia.org/wiki/JSDoc
# Installing the component
- Type npm install to locally deploy the node modules
- To clear the cache : npm cache clean && npm prune && npm install
# Running the component
- NPM tasks facilitate the building and the debugging of the app.
- To start the app, type : npm run start
- Debugging the app in WebStorm is also supported ; add a Debug Configuration on http://localhost:3000.
## Contributors
TODO
## License
This project is released under the GNU General Public License v3.0.
## References
- Neo4J database
https://neo4j.com/community/
- ES2015
http://exploringjs.com/es6/
https://github.com/lukehoban/es6features
## Related Documents
- Add links to other documents here.
## Database Queries
CVCE modifications to apply (based on 05-2017 neo4j dataset)
- precompute entity degree:
MATCH (ent:entity) WITH ent, size((ent)-[:appears_in]->()) as df SET ent.df = df
- precompute collection degree:
MATCH (r:resource)-[:is_part_of*]->(c)
WHERE (c:subunit) OR (c:unit) OR (c:epublication) WITH c, collect(r) as resources
SET c.rf = size(resources)
- unify organization, social_group => institution:
MATCH (n:organization) SET n:institution
MATCH (n:organization:institution) REMOVE n:organization
MATCH (n:social_group) SET n:institution
MATCH (n:social_group:institution) REMOVE n:social_group
- add cull labels:
MATCH (n:entity) WHERE n.df>500 OR n.name = 'Europe' OR n.name = 'European Union' SET n:cull
- In Javascript queries, add "... AND NOT (n:cull)"
## User interaction
- Mouse
Left button to rotate (3D view), right button to pan around. Mouse wheel to zoom.
- Keyboard
s, r, t to switch controls on a plane
delete to remove a plane
## Update version after every commit
Create a file named `.git/hooks/pre-commit` containing :
```bash
#!/bin/sh
file="path/to/project/src/misc/version.js"
echo "module.exports = { version: '`git rev-list --all --count`' }" > $file
git add $file
```
\ No newline at end of file
// Source : https://github.com/abiee/es6-marionette/blob/master/karma.conf.js
//See https://jaredtong.com/2016/01/08/how-to-set-up-mocha-chai-sinon-karma-browserify-istanbul-codecov/
//See https://cafedev.org/article/2016/12/testing-with-wepack-2-inject-loader-karma-mocha-chai-and-sinon/
module.exports = function (config) {
'use strict';
config.set({
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// base path, that will be used to resolve files and exclude
basePath: '',
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['mocha','chai', 'chai-sinon'],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'tests/**/*.spec.js': ['webpack',"sourcemap"],
'tests/**/*_test.js': ['webpack',"sourcemap"],
},
// webpack configuration
webpack: {
devtool: 'inline-source-map'
},
webpackMiddleware: {
stats: {
colors: true
}
},
// list of files / patterns to load in the browser
files: [
{pattern: 'tests/**/*.spec.js', watched: true},
// {pattern: 'src/**/*.js', watched: true},
],
reporters: ['mocha', 'html'],
// report on console and growl if available
//progress spec
// More info about growl notifications on
// http://mattn.github.io/growl-for-linux/ //don't work on linux
// http://growl.info/
//desactivate html if not in a browser
/***********************************/
//spec reporter options
// specReporter: {
// maxLogLines: 5, // limit number of lines logged per test
// suppressErrorSummary: true, // do not print error summary
// suppressFailed: false, // do not print information about failed tests
// suppressPassed: false, // do not print information about passed tests
// suppressSkipped: true, // do not print information about skipped tests
// showSpecTiming: false // print the time elapsed for each spec
// },
// coverageReporter: {
// reporters: [
// {'type': 'text'},
// {'type': 'html', dir: 'coverage'},
// {'type': 'lcov'}
// ]
// },
htmlReporter: {
outputFile: 'tests/units.html'
},
/**********************************/
// list of files / patterns to exclude
exclude: [],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['Chrome'],
// Which plugins to enable not necessary done automatically by karma whith config.json
plugins: [
// 'karma-browserify',
require('karma-mocha'),
require('karma-chai-sinon'),
require('karma-spec-reporter'),
require('karma-html-reporter'),
require('karma-mocha-reporter'),
require('karma-sourcemap-loader'),
// 'karma-growl',
require('karma-chrome-launcher'),
require('karma-webpack'),
require('karma-chai'),
// 'karma-phantomjs-launcher',
// 'karma-source-map-support',
// 'karma-htmlfile-reporter'
],
// Uncomment the following lines if you are using grunt's server to run the tests
// proxies: {
// '/': 'http://localhost:9876/'
// },
// URL root prevent conflicts with the site root
urlRoot: '/'
});
};
{
"name": "blizaar-intergraph",
"version": "0.5.1",
"description": "Blizaar Intergraph",
"main": "deploy/lib/blizaar-COMPONENT-module.js",
"private": true,
"publishConfig": {
"registry": "http://my-internal-registry.local"
},
"preferGlobal": false,
"scripts": {
"start": "npm run deploy && webpack-dev-server --config webpack.config.js",
"blizaar-lab": "npm run deploy && webpack-dev-server --config webpack.config.js",
"deploy": "npm run clean && webpack --config webpack.config.js && npm run doc",
"module-prod": "npm run clean && NODE_ENV='production' node node_modules/webpack/bin/webpack.js --config webpack.config.js",
"clean": "rimraf deploy/*",
"unit": "mocha --compilers js:babel-register --full-trace --check-leaks tests/unit/**/*.spec.js",
"integration": "karma start",
"lint": "eslint ./src/**/**.js",
"doc": "rimraf deploy/src && mkdirp deploy && babel --no-babelrc src --out-dir deploy/src --presets es2016 --plugins=transform-flow-strip-types,transform-class-properties && rimraf deploy/jsdoc && mkdirp deploy/jsdoc && jsdoc -r deploy/src -d deploy/jsdoc && rimraf deploy/src"
},
"author": "Blizaar",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+ssh://git@gitlab.etude.eisti.fr/sre/blizaar-component-example.git#blizaar_component_latest"
},
"devDependencies": {
"ajv": "^5.5.2",
"babel-cli": "^6.24.0",
"babel-core": "6.26.3",
"babel-eslint": "^7.2.3",
"babel-loader": "^7.1.2",
"babel-plugin-module-resolver": "^2.2.0",
"babel-plugin-syntax-flow": "^6.18.0",
"babel-plugin-transform-builtin-extend": "^1.1.2",
"babel-plugin-transform-class-properties": "^6.23.0",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"babel-preset-env": "1.7.0",
"babel-preset-es2015": "^6.24.0",
"babel-preset-es2015-loose": "^8.0.0",
"babel-preset-es2016": "^6.22.0",
"babel-preset-stage-2": "^6.17.0",
"babel-standalone": "^6.17.0",
"chai": "^4.1.2",
"circular-dependency-plugin": "^2.0.0",
"compression-webpack-plugin": "^0.3.2",
"copy-webpack-plugin": "4.6.0",
"css-loader": "^0.27.3",
"eslint": "^4.14.0",
"eslint-plugin-babel": "^4.1.1",
"expose-loader": "^0.7.4",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.6",
"fs.realpath": "^1.0.0",
"html-loader": "^0.5.1",
"html-webpack-include-assets-plugin": "0.0.4",
"html-webpack-plugin": "^2.28.0",
"inline-manifest-webpack-plugin": "^3.0.1",
"jquery": "^3.2.1",
"jsdoc": "^3.5.5",
"json-loader": "^0.5.4",
"karma": "^1.5.0",
"karma-babel-preprocessor": "^6.0.1",
"karma-chai": "^0.1.0",
"karma-chai-sinon": "^0.1.5",
"karma-chrome-launcher": "^2.0.0",
"karma-coverage": "1.1.2",
"karma-growl": "^0.1.2",
"karma-growl-reporter": "^1.0.0",
"karma-html-reporter": "^0.2.7",
"karma-htmlfile-reporter": "0.3.7",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.5",
"karma-phantomjs-launcher": "^1.0.2",
"karma-sinon": "^1.0.5",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.26",
"karma-webpack": "^2.0.9",
"loader-utils": "^1.0.3",
"lodash": "4.17.11",
"mocha": "^5.0.1",
"neo4j-driver": "1.7.1",
"npm-install-webpack-plugin": "^4.0.4",
"raw-loader": "^0.5.1",
"readline": "^1.3.0",
"rimraf": "^2.6.1",
"shader-loader": "^1.3.0",
"sinon": "^4.1.3",
"sinon-chai": "^2.14.0",
"style-loader": "^0.19.1",
"tapable": "^1.0.0-beta.5",
"url-loader": "^0.6.2",
"webfontloader": "^1.6.27",
"webpack": "^3.10.0",
"webpack-dev-server": "2.9.1",
"webpack-externals-plugin": "^1.0.0",
"webpack-manifest-plugin": "^1.1.0",
"webpack-merge": "^4.1.1",
"webpack-node-externals": "^1.5.4"
},
"dependencies": {
"angular": "1.5.11",
"d3-force": "^1.0.6",
"gl-mat4": "^1.1.4",
"jquery-contextmenu": "^2.6.3",
"jsonfile": "^4.0.0",
"ml-regression-multivariate-linear": "1.2.0",
"popper.js": "1.12.6",
"sweetalert2": "8.0.7",
"three": "^0.84.0"
},
"browserify": {
"transform": [
"browserify-shader"
]
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
export default class DataHandler {
constructor() {
this.init();
}
init() {
let dateSlider = document.getElementById('slider-date');
// Create a string representation of the date.
function formatDate(date) {
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
return date.getDate() + " " + months[date.getMonth()] + " " + date.getFullYear();
}
// Create a new date from a string, return as a timestamp.
function timestamp(str) {
return new Date(str).getTime();
}
function toFormat(value) {
let d = new Date();
d.setTime(value);
return formatDate(d);
}
window.noUiSlider.create(dateSlider, {
// Create two timestamps to define a range.
range: {
min: timestamp('1875'),
max: timestamp('2020')
},
// Add a formatter to the slider
format: {to: toFormat, from: Number},
// Steps of one week
step: 6 * 4 * 7 * 24 * 60 * 60 * 1000,
// Two more timestmps indicate the handle starting positions.
start: [timestamp('1875'), timestamp('2020')],
tooltips: [true, true],
connect: [false, true, false],
behaviour: 'drag-tap',
});
let dateValues = [
document.getElementById('event-start'),
document.getElementById('event-end')
];
dateSlider.noUiSlider.on('update', function (values, handle) {
dateValues[handle].innerHTML = values[handle];
});
}
}
import jquery from 'jquery';
export default class MenuHandler{
constructor(app, settings){
this.init(app, settings);
}
init(app, settings){
let isItemDisabled = function(key, opt) {
let load = document.getElementById("load").style.visibility
return load == 'visible';
}
let props = {};
$("#type").on('DOMSubtreeModified', function () {
let value = $("#type").html();
// console.log("value DOMS= "+ value);
$.contextMenu('destroy');
$('#main-container').removeClass('context-menu-active');
let multi = value.split(':')[0] == 'multi';
let supernode = value.split(':')[0] == 'supernode';
let sub = (action) => {
let union = action + ':union';
let intersection = action + ':intersection';
let items = {};
items[union] = {name: 'Union'};
items[intersection] = {name: 'Intersection'};
return items;
};
if (value != "") {
let layerType = '';
if (multi || supernode) {
layerType = value.split(':')[1]
} else {
let nodeType = settings.nodeTypes.find(nt => nt.name == value);
if (!!nodeType) layerType = nodeType.layer;
}
if (layerType != '') {
props = {};
let layerData = settings.layerTypes.find(lt => lt.name == layerType);
if (!layerData) {
console.error("Settings error : layer referenced in nodeTypes not defined in layerTypes");
return;
}
let queries = layerData.queries;
let sourceQueries = layerData.sourceQueries;
if (!multi) {
props["header"] = {"type": "html", html: "<span><B>Node</B></span>"};
} else {
props["header"] = {"type": "html", html: "<span><B>Multiple Nodes</B></span>"};
}
queries.forEach(query => {
if (!multi) {
props[layerType + '|' + query.name] = {name: query.text, icon: query.icon, disabled: isItemDisabled};
} else {
props[layerType + '|' + query.name + ':multi'] = {name: query.text, icon: query.icon, items: sub(layerType + '|' + query.name), disabled: isItemDisabled};
}
});
if (!multi) {
props["sep1"] = "---------";
} else {
props["sep1"] = "---------";
}
Object.keys(sourceQueries).forEach((source) => {
if (!multi) {
props[source + "|doi"] = {name: "Inspect Resources (" + sourceQueries[source].name + ")", icon: "fa-eye"};
} else {
props[source + "|doi"] = {name: "Inspect Resources (" + sourceQueries[source].name + ")", items: sub(source + "|doi"), icon: "fa-eye"};
}
});
if (!multi) {
props[layerType +"|cull"] = {name: "Add to cull list", icon: "fa-ban"};
} else {
// props["supernodes"] = {name: "Create a groupnode", icon: "fa-object-group"};
props[layerType + "|cull:multi"] = {name: "Add to cull list", icon: "fa-ban"};
}
}
else if (value.startsWith("edge")) {
let layerType = value.split('|')[1];
let layerData = settings.layerTypes.find(lt => lt.name == layerType);
let sourceQueries = layerData.sourceQueries;
props = {
"header": {"type": "html", html: "<span><B>Edge</B></span>"},
}
Object.keys(sourceQueries).forEach((source) => {
props[source + "|doi"] = {name: "Inspect Resources (" + sourceQueries[source].name + ")", icon: "fa-eye"};
});
}
else if (value.startsWith("interedge")) {
let layerType = value.split('|')[1];
let layerData = settings.layerTypes.find(lt => lt.name == layerType);
let sourceQueries = layerData.sourceQueries;
props = {
"header": {"type": "html", html: "<span><B>Interedge</B></span>"},
}
Object.keys(sourceQueries).forEach((source) => {
props[source + "|doi"] = {name: "Inspect Resources (" + sourceQueries[source].name + ")", icon: "fa-eye"};
});
}
else if (value=="view") {
props = {
"header": {"type": "html", html: "<span><B>View</B></span>"},
"list": {name: "Table View", icon: "fa-list"},
"rename": {name: 'Rename', icon: "fa-pencil"},
"translate": {name: "Translate", icon: "fa-arrows"},
"rotate": {name: "Rotate", icon: "fa-repeat"},
"scale": {name: "Scale", icon: "fa-bullseye"},
"clone": {name: "Clone", icon: "fa-clone"},
"freeze": {name: "Freeze", icon: "fa-snowflake-o"},
"remove": {name: "Remove", icon: "fa-trash-o"},
// "hierarchy": {name: "ePublication hierarchy of this Resource", icon: "fa-sitemap"},
}
}
else if (value=="hoverView") {
props = {
"header": {"type": "html", html: "<span><B>View</B></span>"},
"list": {name: "Table View", icon: "fa-list"},
"rename": {name: 'Rename', icon: "fa-pencil"} ,
"clone": {name: "Clone", icon: "fa-clone"},
"freeze": {name: "Freeze", icon: "fa-snowflake-o"},
"remove": {name: "Remove", icon: "fa-trash-o"},
// "hierarchy": {name: "ePublication hierarchy of this Resource", icon: "fa-sitemap"},
}
}
else if (value=="fhoverView") {
props = {
"header": {"type": "html", html: "<span><B>View</B></span>"},
"list": {name: "Table View", icon: "fa-list"},
"rename": {name: 'Rename', icon: "fa-pen"} ,
"clone": {name: "Clone", icon: "fa-clone"},
"unfreeze": {name: "Unfreeze", icon: "fa-tint"},
"remove": {name: "Remove", icon: "fa-trash-o"},
// "hierarchy": {name: "ePublication hierarchy of this Resource", icon: "fa-sitemap"},
}
}
else if (value=="frozenview") {
props = {
"header": {"type": "html", html: "<span><B>View</B></span>"},
"list": {name: "Table View", icon: "fa-list"},
"rename": {name: 'Rename', icon: "fa-pen"} ,
"translate": {name: "Translate", icon: "fa-arrows"},
"rotate": {name: "Rotate", icon: "fa-repeat"},
"scale": {name: "Scale", icon: "fa-bullseye"},
"clone": {name: "Clone", icon: "fa-clone"},
"unfreeze": {name: "Unfreeze", icon: "fa-tint"},
"remove": {name: "Remove", icon: "fa-trash-o"},
// "hierarchy": {name: "ePublication hierarchy of this Resource", icon: "fa-sitemap"},
}
}
else if (value=="canvas") {
props = {
"header": {"type": "html", html: "<span><B>Canvas</B></span>"},
"resetCamera": {name: "Reset camera"},
"2d/3d": {name: app.frame.scenemanager.perspective3D ? "Switch to 2D" : "Switch to 3D"},
"interedges": {name: app.frame.scenemanager.showInteredges ? "Hide interedges" : "Show interedges"},
}
}
else {
props = {}
}
$(function() {
let value = $("#type").html();
if (Object.keys(props).length > 0) {
$.contextMenu({
selector: '#main-container',
callback: function (key) {
let m = "" + key;
$("#info").html(m);
},
items: props,
events: {
hide : function(e) {
$('#main-container').trigger('contextMenuHide');
return true;
},
},
});
}
});
}
});