forked from security_vision/semantic_graph
Fix filtering of links, and prepare for institution type filtering.
This commit is contained in:
parent
6eb67407d9
commit
a43c320af6
2 changed files with 153 additions and 15 deletions
|
@ -257,6 +257,46 @@ svg.zoomed.zoomed2 .node text.nodeTitle {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.node.Institution.Institution-company path{
|
||||||
|
fill: blue;
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-government path{
|
||||||
|
fill: orange;
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-local-government path{
|
||||||
|
fill: purple;
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-law-enforcement path{
|
||||||
|
fill: seagreen;
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-ngo path{
|
||||||
|
fill: yellow;
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-university path{
|
||||||
|
fill: pink;
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-research path{
|
||||||
|
fill: fuchsia;
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-project path{
|
||||||
|
fill: rgb(0, 255, 255);
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-watchdog path{
|
||||||
|
fill: rgb(145, 255, 0);
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-expert-group path{
|
||||||
|
fill: rgb(149, 87, 161);
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-foundation path{
|
||||||
|
fill: brown;
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-international-organization path{
|
||||||
|
fill: gray;
|
||||||
|
}
|
||||||
|
.node.Institution.Institution-art-project path{
|
||||||
|
/* fill: blue; */
|
||||||
|
}
|
||||||
|
|
||||||
/* .node.Person circle {
|
/* .node.Person circle {
|
||||||
fill: var(--color2)
|
fill: var(--color2)
|
||||||
}
|
}
|
||||||
|
|
128
www/graph.js
128
www/graph.js
|
@ -4,7 +4,7 @@ const CONFIG = {
|
||||||
'subtitle': "A survey of the European Union",
|
'subtitle': "A survey of the European Union",
|
||||||
// 'nodeSize': 8,
|
// 'nodeSize': 8,
|
||||||
'nodeRadius': 5,
|
'nodeRadius': 5,
|
||||||
'nodeRepositionPadding': 10,
|
'nodeRepositionPadding': 12,
|
||||||
'baseUrl': 'https://www.securityvision.io/wiki/index.php/',
|
'baseUrl': 'https://www.securityvision.io/wiki/index.php/',
|
||||||
'dataUrl': 'result2.json',
|
'dataUrl': 'result2.json',
|
||||||
'preSimulate': false, // run simulation before starting, so we don't start with lines jumping around
|
'preSimulate': false, // run simulation before starting, so we don't start with lines jumping around
|
||||||
|
@ -17,7 +17,74 @@ const CONFIG = {
|
||||||
'lonMax': 35,
|
'lonMax': 35,
|
||||||
'center': [11, 47],
|
'center': [11, 47],
|
||||||
},
|
},
|
||||||
"filters": ["Institution", "Deployments",/* "Technology", "Dataset"*/],
|
"filters": {
|
||||||
|
"Institution": {
|
||||||
|
"label": "Institution",
|
||||||
|
"type": "categories",
|
||||||
|
},
|
||||||
|
"Law Enforcement": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"NGO": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Government": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Regional Government": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Local Government": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Company": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Foundation": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"University": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Research": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Labour Union": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Watchdog": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Expert Group": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"International Organization": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Art Project": {
|
||||||
|
// "label": "Institution",
|
||||||
|
"type": "institution_types",
|
||||||
|
},
|
||||||
|
"Deployments": {
|
||||||
|
"label": "Deployment",
|
||||||
|
"type": "categories",
|
||||||
|
},
|
||||||
|
|
||||||
|
/* "Technology", "Dataset"*/
|
||||||
|
},
|
||||||
|
|
||||||
"link_properties": [
|
"link_properties": [
|
||||||
"Clients",
|
"Clients",
|
||||||
|
@ -46,7 +113,7 @@ const CONFIG = {
|
||||||
"Country": ["Country"],
|
"Country": ["Country"],
|
||||||
"City": ["City"],
|
"City": ["City"],
|
||||||
// ["Deployment type"], // TODO: select this
|
// ["Deployment type"], // TODO: select this
|
||||||
// ["Institution type"], // TODO: select this (local gov, etc.)
|
"Institution" : ["Institution Type"], // TODO: select this (local gov, etc.)
|
||||||
"Dataset": ["Datasets used"],
|
"Dataset": ["Datasets used"],
|
||||||
"Company": ["Managed by", "Provided by", "Developped by (institutions)"],
|
"Company": ["Managed by", "Provided by", "Developped by (institutions)"],
|
||||||
"Tech": ["Technologies Used", "Software Deployed"],
|
"Tech": ["Technologies Used", "Software Deployed"],
|
||||||
|
@ -196,7 +263,16 @@ function getTitle(obj) {
|
||||||
}
|
}
|
||||||
function getCategories(obj) {
|
function getCategories(obj) {
|
||||||
// console.log(obj);
|
// console.log(obj);
|
||||||
return obj.printouts['Category'].map(n => n.fulltext.split(':')[1]);
|
let cats = obj.printouts['Category'].map(n => n.fulltext.split(':')[1]);
|
||||||
|
if(obj.printouts.hasOwnProperty("Institution Type") && obj.printouts['Institution Type'].length) {
|
||||||
|
obj.printouts['Institution Type'].forEach(type => {
|
||||||
|
cats.push(getInstitutionClass(type.fulltext));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return cats;
|
||||||
|
}
|
||||||
|
function getInstitutionClass(name) {
|
||||||
|
return "Institution-"+ slugify(name);
|
||||||
}
|
}
|
||||||
function getClasses(obj) {
|
function getClasses(obj) {
|
||||||
const classes = getCategories(obj);
|
const classes = getCategories(obj);
|
||||||
|
@ -1444,6 +1520,7 @@ class Store {
|
||||||
|
|
||||||
this.filters = {
|
this.filters = {
|
||||||
'categories': [],
|
'categories': [],
|
||||||
|
'institution_types': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1503,10 +1580,18 @@ class Store {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isFiltered(node) {
|
||||||
|
if(this.filters.categories.includes(node.printouts['Category'][0].fulltext.split(':')[1]))
|
||||||
|
return true;
|
||||||
|
if(node.printouts['Institution Type'].length && this.filters.institution_types.includes(node.printouts['Institution Type'][0].fulltext))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
filter() {
|
filter() {
|
||||||
// add and remove nodes from data based on type filters
|
// add and remove nodes from data based on type filters
|
||||||
this.nodes.forEach((n) => {
|
this.nodes.forEach((n) => {
|
||||||
if (!this.filters.categories.includes(n.printouts['Category'][0].fulltext.split(':')[1])) {
|
if (!this.isFiltered(n)) {
|
||||||
if (n.filtered || typeof n.filtered === 'undefined') {
|
if (n.filtered || typeof n.filtered === 'undefined') {
|
||||||
n.filtered = false;
|
n.filtered = false;
|
||||||
this.graph.nodes.push(n);
|
this.graph.nodes.push(n);
|
||||||
|
@ -1524,14 +1609,16 @@ class Store {
|
||||||
|
|
||||||
// add and remove links from data based on availability of nodes
|
// add and remove links from data based on availability of nodes
|
||||||
this.links.forEach((l) => {
|
this.links.forEach((l) => {
|
||||||
if (this.graph.nodes.includes(l.source) && this.graph.nodes.includes(l.target)) {
|
// if (this.graph.nodes.includes(l.source) && this.graph.nodes.includes(l.target)) {
|
||||||
|
if (!l.source.filtered && !l.target.filtered) {
|
||||||
if (l.filtered || typeof l.filtered === 'undefined')
|
if (l.filtered || typeof l.filtered === 'undefined')
|
||||||
this.graph.links.push(l);
|
this.graph.links.push(l);
|
||||||
l.filtered = false;
|
l.filtered = false;
|
||||||
} else {
|
} else {
|
||||||
if (l.filtered === false) {
|
if (l.filtered === false) {
|
||||||
|
console.log('filter', l.id);
|
||||||
this.graph.links.forEach((d, i) => {
|
this.graph.links.forEach((d, i) => {
|
||||||
if (l.id === d.id) {
|
if (l.nr === d.nr) {
|
||||||
this.graph.links.splice(i, 1);
|
this.graph.links.splice(i, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1539,39 +1626,50 @@ class Store {
|
||||||
l.filtered = true;
|
l.filtered = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(this.graph.nodes.length, this.graph.links.length)
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
CONFIG.filters.forEach(f => {
|
Object.keys(CONFIG.filters).forEach(f => {
|
||||||
|
const settings = CONFIG.filters[f];
|
||||||
|
|
||||||
|
if(settings.type == 'institution_types')
|
||||||
|
// TODO; For now, skip
|
||||||
|
return;
|
||||||
|
|
||||||
|
let categories = [f];
|
||||||
|
if( settings.type == 'institution_types')
|
||||||
|
categories = ['Institution', getInstitutionClass(f)];
|
||||||
|
|
||||||
let labelEl = document.createElement('label')
|
let labelEl = document.createElement('label')
|
||||||
let inputEl = document.createElement('input')
|
let inputEl = document.createElement('input')
|
||||||
let textEl = document.createElement('span');
|
let textEl = document.createElement('span');
|
||||||
let svg = d3.select(labelEl).append('svg')
|
let svg = d3.select(labelEl).append('svg')
|
||||||
.attr("viewBox", [-12, -12, 24, 24]);
|
.attr("viewBox", [-12, -12, 24, 24]);
|
||||||
svg.append('g')
|
svg.append('g')
|
||||||
.attr("class", "node " + f)
|
.attr("class", "node " + categories.join(' '))
|
||||||
.append('path')
|
.append('path')
|
||||||
.attr('d', getSymbolForCategories(f)());
|
.attr('d', getSymbolForCategories(categories)());
|
||||||
inputEl.type = "checkbox";
|
inputEl.type = "checkbox";
|
||||||
textEl.innerText = f;
|
textEl.innerText = f;
|
||||||
labelEl.appendChild(inputEl);
|
labelEl.appendChild(inputEl);
|
||||||
labelEl.appendChild(textEl);
|
labelEl.appendChild(textEl);
|
||||||
|
|
||||||
if (!this.filters.categories.includes(f)) {
|
if (!this.filters[settings.type].includes(f)) {
|
||||||
inputEl.checked = true;
|
inputEl.checked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputEl.addEventListener('change', (e) => {
|
inputEl.addEventListener('change', (e) => {
|
||||||
if (e.target.checked) {
|
if (e.target.checked) {
|
||||||
this.filters.categories.forEach((d, i) => {
|
this.filters[settings.type].forEach((d, i) => {
|
||||||
if (d == f) {
|
if (d == f) {
|
||||||
this.filters.categories.splice(i, 1);
|
this.filters[settings.type].splice(i, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (!this.filters.categories.includes(f)) {
|
if (!this.filters[settings.type].includes(f)) {
|
||||||
this.filters.categories.push(f);
|
this.filters[settings.type].push(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.filter();
|
this.filter();
|
||||||
|
|
Loading…
Reference in a new issue