Fix filtering of links, and prepare for institution type filtering.

This commit is contained in:
Ruben van de Ven 2021-05-06 10:55:14 +02:00
parent 6eb67407d9
commit a43c320af6
2 changed files with 153 additions and 15 deletions

View file

@ -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)
} }

View file

@ -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,10 +1626,21 @@ 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')
@ -1550,28 +1648,28 @@ class Store {
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();