Graph changes
parent
67f1da03a3
commit
e8cfd8040c
2
main.js
2
main.js
|
@ -10,7 +10,7 @@ let mainWindow
|
||||||
|
|
||||||
function createWindow () {
|
function createWindow () {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
mainWindow = new BrowserWindow({width: 1440, height: 900, icon:__dirname + '/src/img/favicon.ico'})
|
mainWindow = new BrowserWindow({width: 1280, height: 800, icon:__dirname + '/src/img/favicon.ico'})
|
||||||
|
|
||||||
// and load the index.html of the app.
|
// and load the index.html of the app.
|
||||||
mainWindow.loadURL(`file://${__dirname}/index.html`)
|
mainWindow.loadURL(`file://${__dirname}/index.html`)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "set ENV=development & electron .",
|
"start": "set ENV=development & electron .",
|
||||||
"server": "babel-node server.js",
|
"dev": "concurrently -k \"babel-node server.js\" \"npm start\"",
|
||||||
"build": "webpack --config webpack.config.production.js && electron-packager . Bloodhound --platform=all --arch=all --overwrite --prune",
|
"build": "webpack --config webpack.config.production.js && electron-packager . Bloodhound --platform=all --arch=all --overwrite --prune",
|
||||||
"winbuild": "webpack --config webpack.config.production.js && electron-packager . Bloodhound --platform=win32 --arch=all --overwrite --prune"
|
"winbuild": "webpack --config webpack.config.production.js && electron-packager . Bloodhound --platform=win32 --arch=all --overwrite --prune"
|
||||||
},
|
},
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
"babel-preset-es2015": "^6.9.0",
|
"babel-preset-es2015": "^6.9.0",
|
||||||
"babel-preset-react": "^6.11.1",
|
"babel-preset-react": "^6.11.1",
|
||||||
"babel-preset-stage-0": "^6.5.0",
|
"babel-preset-stage-0": "^6.5.0",
|
||||||
|
"concurrently": "^2.2.0",
|
||||||
"electron-prebuilt": "^1.2.8",
|
"electron-prebuilt": "^1.2.8",
|
||||||
"express": "^4.14.0",
|
"express": "^4.14.0",
|
||||||
"webpack": "^1.13.1",
|
"webpack": "^1.13.1",
|
||||||
|
|
|
@ -6,8 +6,8 @@ import LogoutModal from './components/Modals/logoutmodal';
|
||||||
import ClearWarnModal from './components/Modals/clearwarnmodal'
|
import ClearWarnModal from './components/Modals/clearwarnmodal'
|
||||||
import ClearConfirmModal from './components/Modals/clearconfirmmodal'
|
import ClearConfirmModal from './components/Modals/clearconfirmmodal'
|
||||||
import ClearingModal from './components/Modals/clearingmodal'
|
import ClearingModal from './components/Modals/clearingmodal'
|
||||||
import LoadingContainer from './components/loadingcontainer';
|
import LoadingContainer from './components/Float/loadingcontainer';
|
||||||
import GenericAlert from './components/alert';
|
import GenericAlert from './components/Float/alert';
|
||||||
import RawQuery from './components/rawquery';
|
import RawQuery from './components/rawquery';
|
||||||
import MenuContainer from './components/Menu/menucontainer';
|
import MenuContainer from './components/Menu/menucontainer';
|
||||||
import ExportContainer from './components/Float/exportcontainer';
|
import ExportContainer from './components/Float/exportcontainer';
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
export class QueryNodeSelect extends Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
export default class QueryNodeSelectItem extends Component {
|
||||||
|
_handleClick(){
|
||||||
|
var qstring = 'MATCH (n),(m:Group {name:"{}"}),p=allShortestPaths((n)-[*1..]->(m)) RETURN p'
|
||||||
|
|
||||||
|
emitter.emit('query', qstring.format(this.props.text), this.props.text)
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button onClick={this._handleClick.bind(this)} class="list-group-item">{this.props.text}</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -67,6 +67,31 @@ export default class GraphContainer extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadFromChildProcess(graph){
|
||||||
|
if (graph.nodes.length === 0){
|
||||||
|
emitter.emit('showAlert', "No data returned from query")
|
||||||
|
}else{
|
||||||
|
$.each(graph.nodes, function(i, node){
|
||||||
|
node.glyphs = $.map(node.glyphs, function(value, index) {
|
||||||
|
return [value];
|
||||||
|
});
|
||||||
|
})
|
||||||
|
appStore.queryStack.push({
|
||||||
|
nodes: this.state.sigmaInstance.graph.nodes(),
|
||||||
|
edges: this.state.sigmaInstance.graph.edges(),
|
||||||
|
spotlight: appStore.spotlightData,
|
||||||
|
startNode: appStore.startNode,
|
||||||
|
endNode: appStore.endNode
|
||||||
|
})
|
||||||
|
|
||||||
|
appStore.spotlightData = graph.spotlightData;
|
||||||
|
this.state.sigmaInstance.graph.clear();
|
||||||
|
this.state.sigmaInstance.graph.read(graph);
|
||||||
|
this.state.sigmaInstance.refresh()
|
||||||
|
emitter.emit('spotlightUpdate');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
import(payload){
|
import(payload){
|
||||||
fs.readFile(payload, 'utf8', function(err, data){
|
fs.readFile(payload, 'utf8', function(err, data){
|
||||||
var graph;
|
var graph;
|
||||||
|
@ -317,11 +342,17 @@ export default class GraphContainer extends Component {
|
||||||
|
|
||||||
// child.on('message', function(m) {
|
// child.on('message', function(m) {
|
||||||
// // Receive results from child process
|
// // Receive results from child process
|
||||||
// console.log(m)
|
// this.loadFromChildProcess(m)
|
||||||
// });
|
// }.bind(this));
|
||||||
|
|
||||||
// // Send child process some work
|
// // Send child process some work
|
||||||
// child.send(sigmaInstance);
|
// child.send(JSON.stringify({nodes:sigmaInstance.graph.nodes(),
|
||||||
|
// edges: sigmaInstance.graph.edges(),
|
||||||
|
// edge: params.allowCollapse ? appStore.performance.edge : 0 ,
|
||||||
|
// sibling: params.allowCollapse ? appStore.performance.sibling : 0,
|
||||||
|
// start: appStore.startNode,
|
||||||
|
// end: appStore.endNode
|
||||||
|
// }))
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
if (this.state.firstDraw){
|
if (this.state.firstDraw){
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
|
@ -427,7 +458,8 @@ export default class GraphContainer extends Component {
|
||||||
glyphFillColor: 'black',
|
glyphFillColor: 'black',
|
||||||
glyphTextColor: 'white',
|
glyphTextColor: 'white',
|
||||||
glyphTextThreshold: 1,
|
glyphTextThreshold: 1,
|
||||||
zoomingRatio: 1.4
|
zoomingRatio: 1.4,
|
||||||
|
scalingMode: 'inside'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -560,7 +592,8 @@ export default class GraphContainer extends Component {
|
||||||
var dagreListener = sigma.layouts.dagre.configure(sigmaInstance, {
|
var dagreListener = sigma.layouts.dagre.configure(sigmaInstance, {
|
||||||
easing: 'cubicInOut',
|
easing: 'cubicInOut',
|
||||||
boundingBox: true,
|
boundingBox: true,
|
||||||
background: true
|
background: true,
|
||||||
|
rankDir: 'LR'
|
||||||
});
|
});
|
||||||
|
|
||||||
dagreListener.bind('stop', function(event){
|
dagreListener.bind('stop', function(event){
|
||||||
|
@ -573,12 +606,16 @@ export default class GraphContainer extends Component {
|
||||||
emitter.emit('showLoadingIndicator', true)
|
emitter.emit('showLoadingIndicator', true)
|
||||||
})
|
})
|
||||||
|
|
||||||
var noverlapListener = sigmaInstance.configNoverlap({
|
// var noverlapListener = sigmaInstance.configNoverlap({
|
||||||
nodeMargin: 20.0,
|
// nodeMargin: 5.0,
|
||||||
easing: 'cubicInOut',
|
// easing: 'cubicInOut',
|
||||||
gridSize: 20,
|
// gridSize: 20,
|
||||||
permittedExpansion: 1.3
|
// permittedExpansion: 1.3
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
|
|
||||||
|
var noverlapListener = sigmaInstance.configNoverlap({})
|
||||||
|
|
||||||
noverlapListener.bind('stop', function(event) {
|
noverlapListener.bind('stop', function(event) {
|
||||||
emitter.emit('updateLoadingText', 'Done!');
|
emitter.emit('updateLoadingText', 'Done!');
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Login from '../login'
|
import Login from '../Float/login'
|
||||||
|
|
||||||
var Modal = require('react-bootstrap').Modal;
|
var Modal = require('react-bootstrap').Modal;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import AppContainer from './appcontainer';
|
import AppContainer from './appcontainer';
|
||||||
import Login from './components/login'
|
import Login from './components/Float/login'
|
||||||
import { getStorageData, storageHasKey, storageSetKey } from './js/utils.js';
|
import { getStorageData, storageHasKey, storageSetKey } from './js/utils.js';
|
||||||
|
|
||||||
const ConfigStore = require('configstore');
|
const ConfigStore = require('configstore');
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
var indexes,
|
||||||
|
edge,
|
||||||
|
sibling,
|
||||||
|
spotlightData,
|
||||||
|
adjacentNodes,
|
||||||
|
adjacentEdges,
|
||||||
|
idMap;
|
||||||
|
|
||||||
|
process.on('message', function(m){
|
||||||
|
adjacentNodes = {}
|
||||||
|
adjacentEdges = {}
|
||||||
|
idMap = {}
|
||||||
|
spotlightData = {}
|
||||||
|
|
||||||
|
var data = JSON.parse(m)
|
||||||
|
|
||||||
|
buildIndexes(data)
|
||||||
|
edge = data.edge;
|
||||||
|
sibling = data.sibling
|
||||||
|
|
||||||
|
data = processEdgeNodes(data)
|
||||||
|
data.spotlightData = spotlightData
|
||||||
|
|
||||||
|
data.nodes.forEach(function(node){
|
||||||
|
if (!spotlightData.hasOwnProperty(node.id)){
|
||||||
|
spotlightData[node.id] = [node.neo4j_data.name, 0, ""]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
process.send(data)
|
||||||
|
})
|
||||||
|
|
||||||
|
function buildIndexes(graph){
|
||||||
|
graph.nodes.forEach(function(node){
|
||||||
|
idMap[node.id] = node
|
||||||
|
adjacentNodes[node.id] = []
|
||||||
|
adjacentEdges[node.id] = []
|
||||||
|
})
|
||||||
|
|
||||||
|
graph.edges.forEach(function(edge){
|
||||||
|
adjacentNodes[edge.target].push(idMap[edge.source])
|
||||||
|
adjacentNodes[edge.source].push(idMap[edge.target])
|
||||||
|
adjacentEdges[edge.source].push(edge)
|
||||||
|
adjacentEdges[edge.target].push(edge)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function processEdgeNodes(graph){
|
||||||
|
if (edge === 0){
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(idMap).forEach(function(id){
|
||||||
|
var node = idMap[id]
|
||||||
|
|
||||||
|
adjacentNodes[node.id].forEach(function(anode){
|
||||||
|
if (anode.neo4j_data.name === graph.endNode || anode.neo4j_data.name === graph.startNode){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var edges = adjacentEdges[anode.id]
|
||||||
|
|
||||||
|
if ((edges.length > 1 || edges.length === 0) || (anode.folded.nodes.length > 0)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var edge = edges[0]
|
||||||
|
|
||||||
|
if ((anode.type_user && (edge.label === 'MemberOf' || edge.label === 'AdminTo'))
|
||||||
|
|| (anode.type_computer && (edge.label === 'AdminTo' || edge.label === 'MemberOf'))
|
||||||
|
|| (anode.type_group && edge.label === 'AdminTo')){
|
||||||
|
node.isGrouped = true
|
||||||
|
node.folded.nodes.push(anode)
|
||||||
|
node.folded.edges.push(edge)
|
||||||
|
spotlightData[anode.id] = [anode.neo4j_data.name, node.id, node.neo4j_data.name];
|
||||||
|
|
||||||
|
graph.nodes = graph.nodes.filter(function(index) {
|
||||||
|
return index.id !== anode.id
|
||||||
|
});
|
||||||
|
|
||||||
|
graph.edges = graph.edges.filter(function(index) {
|
||||||
|
return index.id !== edge.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (node.folded.nodes.length > 0){
|
||||||
|
node.glyphs.push({
|
||||||
|
'position': 'bottom-left',
|
||||||
|
'content': node.folded.nodes.length
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return graph
|
||||||
|
}
|
Loading…
Reference in New Issue