Created
May 28, 2020 10:09
-
-
Save bubnenkoff/ac040927a28833971222c60223cb75dd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>Network</title> | |
<meta charset="utf-8"> | |
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script> | |
<link rel="stylesheet" href="https://cdn.rawgit.com/Chalarangelo/mini.css/v3.0.1/dist/mini-default.min.css"> | |
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> | |
<style type="text/css"> | |
#mynetwork { | |
width: 1600px; | |
height: 1000px; | |
border: 1px solid lightgray; | |
} | |
#legende { | |
/*width: 190px;*/ | |
border: 1px solid lightgray; | |
background-color: #fffef8; | |
/*position: absolute;*/ | |
} | |
.MainContainer { | |
display: flex; | |
flex-direction: row; | |
} | |
.LeftSide { | |
width: 360px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"> | |
<div class="MainContainer"> | |
<div class="LeftSide"> | |
<div id="legende" style="padding-top: 20px;"> | |
<div>Меню</div> | |
</div> | |
<div class="MenuLeftSide"> | |
<div> | |
<div> | |
<div class="input-group"> | |
<input v-model="selected_inn" type="number" placeholder="ИНН" style="appearance:textfield;" width="75"> | |
<button @click=" add_inn " class="small ">+</button> | |
<br> | |
<button @click="get_data ">Построить граф</button> | |
<!-- <button @click="add_test ">test</button> --> | |
<div v-for="inn in inn_list " v-bind:value="inn.value " style="padding-left: 10px; "> | |
{{ inn.inn }} | |
<button @click="remove_inn(inn.id, inn.inn ) ">-</button> | |
</div> | |
</div> | |
</div> | |
<div> | |
<div v-if="not_found_inn_list && not_found_inn_list.length " style="padding-left: 10px;">Следующие ИНН не нафдены в базе ФНС:</div> | |
<div v-for="inn in not_found_inn_list " style="padding-left: 10px; ">{{inn}}</div> | |
</div> | |
<div> | |
<div v-if="not_found_in_to_for_graph_inn_list && not_found_in_to_for_graph_inn_list.length " style="padding-left: 10px; ">Связи со следующими ИНН не обнаружены:</div> | |
<div v-for="inn in not_found_in_to_for_graph_inn_list " style="padding-left: 10px; ">{{inn}}</div> | |
</div> | |
</div> | |
<!-- <div v-if="nodes.length> 0" style="padding-top: 30px;"> | |
<select v-model="selectedNodeIDStart"> | |
<option v-for="node in nodes" v-bind:value="node">{{node.id}} - {{node.label}} </option> | |
</select> | |
<select v-model="selectedNodeIDEnd"> | |
<option v-for="node in nodes" v-bind:value="node">{{node.id}} - {{node.label}} </option> | |
</select> | |
<button @click="make_deps" :disabled="!selectedNodeIDEnd">Оставить связи</button> | |
</div> --> | |
</div> | |
</div> | |
<!-- {{nodes}} --> | |
<!-- {{edges}} --> | |
<div id="mynetwork"> | |
</div> | |
</div> | |
</div> | |
<script type="text/javascript"> | |
window.base_url = "http://127.0.0.1:8000" | |
var app = new Vue({ | |
el: '#app', | |
data: { | |
nextINNId: 1, // для инкремента | |
network: {}, | |
selected_inn: null, | |
selectedNodeIDStart: null, // обычно должена быть компания которую мы ищем, но оставим возможность поменять ее | |
selectedNodeIDEnd: null, // ИНН ДО которого мы строим граф | |
inn_list: [{ | |
id: 1, | |
inn: 6670479929 | |
}, { | |
id: 2, | |
inn: 6671013577 | |
}, { | |
id: 3, | |
inn: 7733793770 | |
}], // который ищем | |
// inn_list: [], // список ИНН который ищем | |
not_found_inn_list: [], // который не нашли после проверки на сервере | |
not_found_in_to_for_graph_inn_list: [], // тех кого нет в значенеи в to у графа | |
nodes: [], | |
options: { | |
physics: { | |
enabled: false, | |
stabilization: { // Determines an initial layout; enabled by default | |
enabled: true, | |
iterations: 1000 | |
}, | |
barnesHut: { | |
// springLength: 140, | |
// springConstant: 1, | |
// avoidOverlap: 1 | |
}, | |
}, | |
autoResize: true, | |
edges: { | |
font: { | |
size: 12 | |
}, | |
widthConstraint: { | |
maximum: 90 | |
} | |
}, | |
nodes: { | |
shape: "box", | |
widthConstraint: { | |
maximum: 200 | |
} | |
} | |
}, | |
container: '', | |
edges: [] | |
}, | |
methods: { | |
add_inn() { | |
if (this.inn_list.some(a => a['inn'] === this.selected_inn)) // предотвращаем повторное добавление одного и того же ИНН | |
{ | |
console.log("inn is already added") | |
} else { | |
this.inn_list.push({ | |
id: this.nextINNId, | |
inn: this.selected_inn | |
}) | |
this.nextINNId++; | |
} | |
}, | |
remove_inn(id, inn) { | |
this.inn_list = this.inn_list.filter(item => item.id !== id) | |
// this.nodes = this.nodes.filter(item => item.parent != "5904988746") | |
this.nodes = this.nodes.filter(item => item.parent !== inn.toString()) | |
this.edges = this.edges.filter(item => item.parent !== inn.toString()) | |
this.not_found_inn_list = this.not_found_inn_list.filter(item => item !== inn) | |
// window.mynetwork.setData({ nodes: this.nodes, edges: this.edges}); | |
window.mynetwork.setData({ | |
nodes: this.nodes, | |
edges: this.edges | |
}); | |
}, | |
make_deps() { | |
/* | |
var founded = [] | |
var not_founded = [] | |
console.log(this.inn_list) | |
// список веденных ИНН в чистом виде (не как обект) | |
var inn_list_only = this.inn_list.map(a => a.inn).filter(i => i); // удаляем до кучи пустые | |
console.log(inn_list_only) | |
for (x of inn_list_only) { | |
//console.log(x) | |
if (this.edges.filter(a => a.to == x).length !== 0) { | |
founded.push(x) | |
} else { | |
// console.log("not founded ", x) | |
this.not_found_in_to_for_graph_inn_list.push(x) | |
} | |
} | |
*/ | |
function getPath(graph, from, to) { | |
if (!(from in graph)) { | |
return []; | |
} | |
let queue = [from]; | |
let p = {}; | |
p[from] = -1; | |
while (queue.length > 0) { | |
let v = queue.shift(); | |
graph[v].forEach(edge => { | |
if (!(edge in p)) { | |
p[edge] = v; | |
queue.push(edge); | |
} | |
}); | |
} | |
let ans = []; | |
to.forEach(vertex => { | |
if (!(vertex in graph)) { | |
return; | |
} | |
console.log(p[vertex]); | |
while (vertex != -1) { | |
ans.push(vertex); | |
vertex = p[vertex]; | |
} | |
}); | |
//ans = ans.filter((v, i, a) => a.indexOf(v) === i); | |
console.log(ans); | |
return ans; | |
} | |
let graph = {}; | |
console.log(graph); | |
this.edges.forEach(edge => { | |
if (!(edge['from'] in graph)) { | |
graph[edge['from']] = []; | |
} | |
if (!(edge['to'] in graph)) { | |
graph[edge['to']] = []; | |
} | |
graph[edge['from']].push(edge['to']); | |
graph[edge['to']].push(edge['from']); | |
}); | |
//var path = getPath(graph, this.selectedNodeIDStart.id, this.selectedNodeIDEnd.id); | |
// var path = getPath(graph, this.selectedNodeIDStart.id, [this.selectedNodeIDEnd.id]); | |
// var path = getPath(graph, "6670479929", ["661202720696", "667324212394"]); | |
// var path = getPath(graph, "6670479929", ["6671013577"]); // тут рабочая связка | |
// var path = getPath(graph, "6670479929", ["7733793770"]); // тут второй элемент не существующий | |
console.log("we are here") | |
var path = getPath(graph, "6670479929", ["7733793770"]); // тут второй элемент не существующий | |
console.log("path: ", path) | |
// если в path что-то есть, то значит связи для графа установлены, если нет ниже в ноды ничего не добавляем | |
console.log("path.length: ", path.length) | |
// if (path.length > 0) { | |
// path = Array.from(new Set(path)); | |
// this.nodes = this.nodes.filter(node => path.includes(node['id'])); | |
// this.edges = this.edges.filter(edge => path.includes(edge['from']) && path.includes(edge['to'])); | |
// window.mynetwork.setData({ | |
// nodes: this.nodes, | |
// edges: this.edges | |
// }); | |
// } else { | |
// console.log("Can't make graph between points") | |
// window.mynetwork.setData({ | |
// nodes: this.nodes, | |
// edges: this.edges | |
// }); | |
// } | |
}, | |
get_data() { | |
if (this.inn_list.some(a => a['inn'] === this.selected_inn)) // предотвращаем повторное добавление одного и того же ИНН | |
{ | |
console.log("inn is already added") | |
} else { | |
this.inn_list.push({ | |
id: this.nextINNId, | |
inn: this.selected_inn | |
}) | |
this.nextINNId++; | |
} | |
axios.post(base_url + '/graph', this.inn_list) | |
.then((response) => { | |
console.log(this.inn_list) | |
if ('data' in response.data) { | |
this.nodes = response.data.data.nodes; | |
this.edges = response.data.data.edges; | |
console.log(response.data) | |
// window.mynetwork.setData({ | |
// nodes: app.$root._data.nodes, | |
// edges: app.$root._data.edges | |
// }); | |
this.make_deps() | |
// в msg у нас лежит предупреждение о том что не всё было найдено в случае если такое произошло иначе msg отстутсвует | |
// not_found_inn_list список того что не было найдено | |
if ('msg' in response.data) { | |
this.not_found_inn_list = response.data.not_found_inn_list; | |
} | |
// теперь нужно установить значение поля построения графа. Выше не получится т.к. нам нужен именно объект и он есть только когда данные прилетели | |
for (node of this.nodes) { | |
// главный узел мы определяем по границе "borderWidth": 4 | |
// в перспективе можно как-то получше сделать | |
} | |
// теперь заполним первым ИНН поле для ввода значений для построения графа | |
this.selectedNodeIDStart = this.nodes.filter(node => node.id === this.inn_list[0].inn)[0]; | |
} | |
if ('error' in response.data) { | |
Notification.requestPermission().then(function(result) { | |
var notification = new Notification(response.data.error); | |
}); | |
console.log(response.data) | |
} | |
}).catch((error) => { | |
console.log(error); | |
}); | |
}, | |
add_test() { | |
_nodes = [{ | |
"borderWidth": 4, | |
"id": "6670479929", | |
"label": "ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ \"МСС-ИНВЕСТ\"", | |
"group": "ORG", | |
"id_path": ["6670479929", "662333903600"], | |
"parent": "6670479929" | |
}, { | |
"borderWidth": 1, | |
"id": "667027218065", | |
"label": "ВОСТРЕЦОВ АЛЕКСЕЙ ЛЕОНИДОВИЧ", | |
"group": "FOUNDER", | |
"id_path": ["6670479929", "662333903600", "6670026598", "667027218065", "6670479911"], | |
"parent": "6670479929" | |
}, { | |
"borderWidth": 1, | |
"id": "662333903600", | |
"label": "БРОВИН ЯН ЭДУАРДОВИЧ", | |
"group": "MAIN_PERSONS", | |
"id_path": ["6670479929", "667027218065", "6670026598", "662333903600", "6671092890"], | |
"parent": "6670479929" | |
}, { | |
"borderWidth": 1, | |
"id": "6679011652", | |
"label": "ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ \"МВ-УРАЛ\"", | |
"group": "ORG", | |
"id_path": ["6670479929", "667027218065", "6679011652", "667324212394"], | |
"parent": "6670479929" | |
}, { | |
"borderWidth": 1, | |
"id": "6670479911", | |
"label": "ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ \"НОВАТЕХ\"", | |
"group": "ORG", | |
"id_path": ["6670479929", "667027218065", "6670479911", "661202720696"], | |
"parent": "6670479929" | |
}, { | |
"borderWidth": 1, | |
"id": "6670026598", | |
"label": "ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ \"ТЕХПРОМСЕРВИС\"", | |
"group": "ORG", | |
"id_path": ["6670479929", "662333903600", "6670026598", "667027218065"], | |
"parent": "6670479929" | |
}, { | |
"borderWidth": 1, | |
"id": "6671092890", | |
"label": "ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ \"МОНОЛИТСПЕЦСТРОЙ\"", | |
"group": "ORG", | |
"id_path": ["6670479929", "662333903600", "6671092890", "661216744697"], | |
"parent": "6670479929" | |
}, { | |
"borderWidth": 1, | |
"id": "667324212394", | |
"label": "МИРОШНИКОВ ВАДИМ ИГОРЕВИЧ", | |
"group": "MAIN_PERSONS", | |
"id_path": ["6670479929", "667027218065", "6679011652", "667324212394", "6671013577"], | |
"parent": "6670479929" | |
}, { | |
"borderWidth": 1, | |
"id": "661202720696", | |
"label": "ЛЕПИХИН ПАВЕЛ СЕРГЕЕВИЧ", | |
"group": "MAIN_PERSONS", | |
"id_path": ["6670479929", "667027218065", "6670479911", "661202720696", "6670387322"], | |
"parent": "6670479929" | |
}, { | |
"borderWidth": 1, | |
"id": "661216744697", | |
"label": "КОСКОВ АЛЕКСЕЙ ЮРЬЕВИЧ", | |
"group": "MAIN_PERSONS", | |
"id_path": ["6670479929", "662333903600", "6671092890", "661216744697", "6671074509"], | |
"parent": "6670479929" | |
}]; | |
// create an array with edges | |
_edges = [{ | |
"from": "6670479929", | |
"to": "667027218065", | |
"parent": "6670479929", | |
"id": "6273cf24-01fd-49a8-8732-8f7dbc173e2d" | |
}, { | |
"from": "6670479929", | |
"to": "662333903600", | |
"parent": "6670479929", | |
"id": "36aa3fe0-465f-4000-a2eb-1aa3f6ceab2f" | |
}, { | |
"from": "667027218065", | |
"to": "6679011652", | |
"parent": "6670479929", | |
"id": "37a87d83-5c3f-4839-8c0f-06ad3ebac443" | |
}, { | |
"from": "667027218065", | |
"to": "6670479911", | |
"parent": "6670479929", | |
"id": "62071517-7340-4114-b219-b27433f0eff2" | |
}, { | |
"from": "667027218065", | |
"to": "6670026598", | |
"parent": "6670479929", | |
"id": "abdddf0f-c01b-40e4-a230-12a0a82727b8" | |
}, { | |
"from": "662333903600", | |
"to": "6670026598", | |
"parent": "6670479929", | |
"id": "bb80ad15-ba7d-4ea7-b3ac-f89512ebfa9f" | |
}, { | |
"from": "662333903600", | |
"to": "6671092890", | |
"parent": "6670479929", | |
"id": "2ea5ea02-aba7-45c9-9f0b-2caf35e379e7" | |
}, { | |
"from": "6679011652", | |
"to": "667324212394", | |
"parent": "6670479929", | |
"id": "2a1a9d1d-0ca0-40f7-aad2-f21e25e39be3" | |
}, { | |
"from": "6670479911", | |
"to": "661202720696", | |
"parent": "6670479929", | |
"id": "aff33b6f-afdc-4a21-b581-acaab05df415" | |
}, { | |
"from": "6670026598", | |
"to": "661216744697", | |
"parent": "6670479929", | |
"id": "0a94182c-cca5-41dc-bedf-8f58f403bd2e" | |
}, { | |
"from": "6670026598", | |
"to": "662333903600", | |
"parent": "6670479929", | |
"id": "39691b01-4070-4dcc-89c3-eeea6f69e3f5" | |
}, { | |
"from": "6670026598", | |
"to": "667027218065", | |
"parent": "6670479929", | |
"id": "ef6a3d9c-5bbf-44ae-b39e-31c56658259e" | |
}, { | |
"from": "6671092890", | |
"to": "661216744697", | |
"parent": "6670479929", | |
"id": "4bf74e4d-c8bb-418a-8433-7a8a800f8f78" | |
}, { | |
"from": "667324212394", | |
"to": "6670373697", | |
"parent": "6670479929", | |
"id": "05cd9b96-33b6-469c-9a0e-74f409e5f1b3" | |
}, { | |
"from": "667324212394", | |
"to": "6672345367", | |
"parent": "6670479929", | |
"id": "4db77db3-dccd-463d-8de9-9c6a4733262a" | |
}, { | |
"from": "667324212394", | |
"to": "6671013577", | |
"parent": "6670479929", | |
"id": "03bc4bda-7637-4f77-a97f-b54b20d35be9" | |
}, { | |
"from": "661202720696", | |
"to": "6670387322", | |
"parent": "6670479929", | |
"id": "e0c293b6-fb64-477c-8090-fbb630c1d183" | |
}, { | |
"from": "661216744697", | |
"to": "6670387322", | |
"parent": "6670479929", | |
"id": "e2ece1b5-72b5-472c-94b9-afe15fdd331b" | |
}, { | |
"from": "661216744697", | |
"to": "6671092890", | |
"parent": "6670479929", | |
"id": "a21b131a-5e3a-4662-8389-269aba15a563" | |
}, { | |
"from": "661216744697", | |
"to": "6671074509", | |
"parent": "6670479929", | |
"id": "73003348-5504-4d63-973e-7b98caa3b6fd" | |
}, { | |
"from": "661216744697", | |
"to": "6670026598", | |
"parent": "6670479929", | |
"id": "e76cda8b-b09a-4521-bd60-daee44332ab7" | |
}] | |
// console.log(this.nodes) | |
this.nodes.push(..._nodes) | |
this.edges.push(..._edges) | |
console.log(this.nodes) | |
window.mynetwork.setData({ | |
nodes: app.$root._data.nodes, | |
edges: app.$root._data.edges | |
}); | |
} | |
}, | |
mounted() { | |
this.container = document.getElementById('mynetwork'); | |
var data = { | |
nodes: this.nodes, | |
edges: this.edges | |
}; | |
window.mynetwork = new vis.Network(this.container, data, this.options); | |
} | |
}) | |
</script> | |
</body> | |
</html> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment