Skip to content

Instantly share code, notes, and snippets.

@bubnenkoff
Created May 28, 2020 10:09
Show Gist options
  • Save bubnenkoff/ac040927a28833971222c60223cb75dd to your computer and use it in GitHub Desktop.
Save bubnenkoff/ac040927a28833971222c60223cb75dd to your computer and use it in GitHub Desktop.
<!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