Skip to content

Instantly share code, notes, and snippets.

@bubnenkoff
Created March 6, 2020 10:03
Show Gist options
  • Select an option

  • Save bubnenkoff/60254cc52b6a84ee821a3bd438d67047 to your computer and use it in GitHub Desktop.

Select an option

Save bubnenkoff/60254cc52b6a84ee821a3bd438d67047 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: 350px;
}
</style>
</head>
<body>
<div id="app">
<div class="MainContainer">
<div class="LeftSide">
<div id="legende" style="padding-top: 20px;">
<div style="width: 85px; height: 35; margin: 5px; border: 2px solid black; background: #ffeda5">Компания</div>
<div style="width: 85px; height: 35; margin: 5px; border: 2px solid black; background: #cadbf9">Владелец</div>
<div style="width: 85px; height: 35; margin: 5px; border: 2px solid black; background: #f9caca">Учредитель</div>
</div>
<div class="MenuLeftSide">
<div>
<div class="input-group">
<label>ИНН:</label><input v-model="selected_inn" type="number" placeholder="ИНН" style="appearance:textfield;"> <button @click="add_inn" class="small">+</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>
<button @click="get_data">Получить данные</button>
<button @click="make_deps">Оставить связи</button>
<button @click="add_test">test</button>
</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>
<!-- {{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,
// inn_list: [{id: 1, inn: 6670373697}, {id: 2, inn: 6670479929} ], // который ищем
inn_list: [ ], // который ищем
not_found_inn_list: [], // который не нашли после проверки на сервере
nodes : [],
options: {
physics: {
enabled: true,
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});
},
make_deps()
{
function getPath(graph, from, to) {
let queue = [ from ];
let p = {};
p[from] = -1;
while (queue.length > 0) {
let v = queue.shift();
if (v == to) {
break;
}
graph[v].forEach(edge => {
if (!(edge in p)) {
p[edge] = v;
queue.push(edge);
}
});
}
let ans = [];
while (to != -1) {
ans.push(to);
to = p[to];
}
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, 6670373697, 6670479929);
this.nodes = this.nodes.filter(node => path.includes(node['id']));
this.edges = this.edges.filter(edge => path.includes(edge['from']) && path.includes(edge['to']));
this.nodes = new vis.DataSet(this.nodes);
this.edges = new vis.DataSet(this.edges);
window.mynetwork.setData({ nodes: this.nodes, edges: this.edges});
// у нод родителей нужно взять значения id_path которое ниже будет использовано в фильтре
// ноды родители берем из списка введенных inn_list
// из каждого уникального родетеля parent нужно собрать все id_path и потом для каждого из них найти пересечения. Пересечения и будут тем ИНН которое общее и там и тут
// id_path_list.push(...root_inn)
/*
const uniq_parent = [...new Set(this.nodes.map(item => item.parent))]; // получаем список уникальных родителей
let result = {}; // подготавливаем словарь\объект заполняя его INN родителя как ключами?
for (let value of uniq_parent) {
result[value] = [];
}
// теперь итерируемся по каждому чтобы собрать для него все id_path
for(item of this.nodes)
{
// collect[item.parent].push(...id_path);
result[item.parent].push(...item.id_path);
}
console.log(result)
// теперь удалим дубликаты, чтобы было проще
for([k,v] of Object.entries(result))
{
result[k] = [...new Set(v.map(item => item))]
// console.log('== ', v)
}
// теперь объединяем инн и ищем дубликаты
var total_inn_list = []
for([k,v] of Object.entries(result))
{
total_inn_list.push(...v) // полный список дочерних ИНН для каждого родителя объединяем в один список
}
var dublicates_inn = total_inn_list.filter((e, i, a) => a.indexOf(e) !== i)
console.log("total_inn_list: ", total_inn_list)
console.log("dublicates_inn: ", dublicates_inn)
// теперь из каждого node нужно выкинуть значения до него
// толко для теста!!!
// for(q of dublicates_inn)
// {
// for (el of this.nodes)
// {
// this.nodes = this.nodes.filter(item => item.id != q);
// }
// }
window.mynetwork.setData({ nodes: this.nodes, edges: this.edges});
console.log(result)
*/
/*
var id_path_list = [];
var root_inn = this.inn_list.map(a=>a.inn) // inn которые являются корневыми
//root_inn.push(...dublicates_inn) // добавим сюда узлы из тех что были выше
console.log("root_inn: ", root_inn)
console.log("this.nodes: ", this.nodes)
for(inn of this.nodes) // идем по всем нодам и ищем корневые (выделенные жирным инн компаний которые мы ищем)
{
// console.log(inn.id, " ", inn.label )
let isFounded = inn.id_path.some( ai => dublicates_inn.includes(ai) );
if(!isFounded)
{
console.log("!: ", inn)
// this.nodes = this.nodes.filter(item => item.id != inn.id);
}
else
{
console.log("!----------: ", inn)
// this.nodes = this.nodes.filter(item => item.id != inn.id);
}
}
console.log("2this.nodes: ", this.nodes)
window.mynetwork.setData({ nodes: this.nodes, edges: this.edges});
*/
// console.log("id_path_list: ", id_path_list);
// // var mylist = ["6671074509", "661216744697", "6670387322", "661202720696"]
// var mylist = ["662333903600", "667324212394", "6670373697"]
// for (el of mylist)
// {
// this.nodes = this.nodes.filter(item => item.id != el);
// // console.log(this.nodes)
// }
// window.mynetwork.setData({ nodes: this.nodes, edges: this.edges});
var id_path_list = [];
var root_inn = this.inn_list.map(a=>a.inn) // inn которые являются корневыми
console.log("root_inn: ", root_inn)
for(inn of this.nodes) // идем по всем нодам и ищем корневые (выделенные жирным инн компаний которые мы ищем)
{
console.log(inn.id, " ", inn.label )
if(root_inn.includes(inn.id.toString()))
{
id_path_list.push(...inn.id_path); // предотвращаем массив в массиве
}
}
console.log("id_path_list: ", id_path_list);
// var mylist = ["6671074509", "661216744697", "6670387322", "661202720696"]
var mylist = ["662333903600", "667324212394", "6670373697"]
for (el of mylist)
{
this.nodes = this.nodes.filter(item => item.id != el);
// console.log(this.nodes)
}
window.mynetwork.setData({ nodes: this.nodes, edges: this.edges});
},
get_data()
{
if(this.selected_inn && this.selected_inn.length >= 8) // небольшое удобство - поиск ИНН без его добавления кнопкой плюса в интерфейсе
{
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) => {
if ('data' in response.data)
{
this.nodes = response.data.data.nodes;
this.edges = response.data.data.edges;
window.mynetwork.setData({ nodes: app.$root._data.nodes, edges: app.$root._data.edges});
// в msg у нас лежит предупреждение о том что не всё было найдено в случае если такое произошло иначе msg отстутсвует
// not_found_inn_list список того что не было найдено
if ('msg' in response.data)
{
this.not_found_inn_list = response.data.not_found_inn_list;
}
}
if ('error' in response.data)
{
Notification.requestPermission().then(function(result) {
var notification = new Notification(response.data.error);
});
}
//var network = new vis.Network(container, { nodes: app.$root._data.nodes, edges: app.$root._data.edges }, options);
}).catch((error) => {
console.log(error);
});
},
add_test()
{
_nodes = [
{id: 1, label: 'Company 0', group: "company", borderWidth: 4, color: { border: '#077eb8' }, font: { size: 16}, },
{id: 2, label: 'Foo1', group: "owner"},
{id: 3, label: 'Foo2', group: "founder"},
{id: 4, label: 'Company 1', group: "company"},
{id: 5, label: 'Company 2', group: "company"},
{id: 6, label: 'Company 3', group: "company"},
{id: 8, label: 'Company 4', group: "company"},
{id: 9, label: 'Company 5', group: "company"},
{id: 10, label: 'Company 6', group: "company", borderWidth: 4, color: { border: '#077eb8' }, font: { size: 16},},
{id: 11, label: 'Company 7', group: "company"}
];
// create an array with edges
_edges = [
{from: 1, to: 2},
{from: 1, to: 3},
{from: 2, to: 11},
{from: 3, to: 4},
{from: 2, to: 8},
{from: 3, to: 6},
{from: 3, to: 5},
{from: 4, to: 9},
{from: 4, to: 10}
]
// 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment