diff --git a/www/graph.css b/www/graph.css
index 3c110ad..2d7ef76 100644
--- a/www/graph.css
+++ b/www/graph.css
@@ -6,7 +6,7 @@
}
:root {
- --color1: #f94144;
+ --color1: #9741f9;
--color2: #f3722c;
--color3: #f8961e;
/* --color4: #f9844a; */
@@ -40,8 +40,17 @@ svg.dragging {
cursor: grabbing;
}
+#arrowHead {
+ fill: #9df32c;
+}
+
+#arrowHeadSelected {
+ fill: var(--hover-color);;
+}
+
svg .links line, svg .links path {
stroke: #f3722c;
+ stroke: #9df32c;
stroke-width: 6;
fill: none;
transition: stroke-width 1s;
@@ -51,6 +60,7 @@ svg .links line, svg .links path {
svg .links line.hover, svg .links path.hover {
stroke: var(--hover-color);
stroke-width: 12;
+ marker-end: url(#arrowHeadSelected);
}
svg.zoomed .links line, svg.zoomed .links path {
@@ -70,11 +80,12 @@ svg .subtitle {
font-size: 100;
}
-svg #countries .country{
- fill:rgba(200,200,200,0.7);
+svg #countries .country {
+ fill: rgba(200, 200, 200, 0.7);
}
-svg #countries .country.eu_country{
- fill:black;
+
+svg #countries .country.eu_country {
+ fill: black;
}
svg #header #titlePath, svg #header #subtitlePath {
@@ -117,7 +128,8 @@ svg #header text#subtitle {
text-anchor: start;
dominant-baseline: hanging;
/*achieves a 'text-anchor: top'*/
- /* font-size: 16pt; */ /*Set this in JS*/
+ /* font-size: 16pt; */
+ /*Set this in JS*/
transition: font-size .4s, opacity 1s;
fill: white;
opacity: 1;
@@ -137,13 +149,14 @@ svg.zoomed.zoomed2 .node text.nodeTitle {
font-size: 3pt;
}
-.node circle {
- fill: white;
+.node circle, .node path {
+ fill: lightgray;
}
/* Whenever a connected link is hovered */
-.node.linkHover circle {
+.node.linkHover circle, .node.linkHover path, label:hover .node path {
+ fill: var(--hover-color) !important;
stroke: var(--hover-color);
stroke-width: 5px;
}
@@ -152,7 +165,8 @@ svg.zoomed.zoomed2 .node text.nodeTitle {
transition: opacity 0s;
}
-.node:hover circle {
+.node:hover circle, .node:hover path {
+ fill: var(--hover-color) !important;
stroke: var(--hover-color);
stroke-width: 5px;
}
@@ -162,12 +176,13 @@ svg.zoomed.zoomed2 .node text.nodeTitle {
fill: var(--hover-color);
}
-.node.selected circle {
+.node.selected circle, .node.selected path {
+ fill: var(--selected-color) !important;
stroke: var(--selected-color);
stroke-width: 5px;
}
-.node.City circle {
+.node.City circle, .node.City path {
display: none;
}
@@ -178,24 +193,24 @@ svg.zoomed.zoomed2 .node text.nodeTitle {
font-size: 20px;
}
-.node.Person circle {
+.node.Person circle, .node.Person path {
fill: lightgreen
}
-.node.Technology circle {
- fill: lightcoral;
+.node.Technology circle, .node.Technology path {
+ fill: plum;
}
-.node.Deployment circle {
+.node.Deployments circle, .node.Deployments path {
fill: lightblue;
}
-.node.Institution circle {
- fill: lightgoldenrodyellow
+.node.Institution circle, .node.Institution path {
+ fill: lightcoral
}
-.node.Dataset circle {
- fill: plum
+.node.Dataset circle, .node.Dataset path {
+ fill: lightgoldenrodyellow
}
.labels .label text {
@@ -284,29 +299,37 @@ p.subtitle {
display: none;
}
-#filters h3{
- text-align: center;;
+#filters h3 {
+ text-align: center;
+ ;
}
+
#filters label {
cursor: pointer;
display: block;
padding: 10px;
}
+#filters label svg {
+ display: inline;
+ width: 30px;
+ height: 30px;
+ vertical-align: middle;
+}
+
#filters span:hover {
color: var(--hover-color);
}
#filters input {
- /* display: none; */
+ display: none;
}
#filters input+span {
display: inline-block;
padding-left: 10px;
-
/* background: var(--color9); */
- text-decoration:line-through;
+ text-decoration: line-through;
}
#filters input:checked+span {
diff --git a/www/graph.js b/www/graph.js
index 62743d1..7254319 100644
--- a/www/graph.js
+++ b/www/graph.js
@@ -4,7 +4,7 @@ const CONFIG = {
'subtitle': "Connections in the European Union & beyond",
// 'nodeSize': 8,
'nodeRadius': 5,
- 'nodeRepositionPadding': 3,
+ 'nodeRepositionPadding': 8,
'baseUrl': 'https://www.securityvision.io/wiki/index.php/',
'dataUrl': 'result.json',
'preSimulate': false, // run simulation before starting, so we don't start with lines jumping around
@@ -58,6 +58,27 @@ const CONFIG = {
// let height = window.innerHeight;
+function getSymbolForCategories(classes) {
+ if(!Array.isArray(classes)) {
+ classes = [classes];
+ }
+ if (classes.includes('Institution')) {
+ return d3.symbol()
+ .type(d3.symbolTriangle)
+ .size(CONFIG.nodeRadius * 16);
+ }
+
+ return d3.symbol()
+ .type(d3.symbolCircle)
+ .size(CONFIG.nodeRadius * 16);
+}
+
+// returns a symbol function
+function getSymbolForNode(n) {
+ const classes = getCategories(n);
+ return getSymbolForCategories(classes);
+}
+
// Slugify a string, by https://lucidar.me/en/web-dev/how-to-slugify-a-string-in-javascript/
function slugify(str) {
str = str.replace(/^\s+|\s+$/g, '');
@@ -226,7 +247,7 @@ class NodeMap {
render() {
this.svg = this.root.append('svg')
- this.svg.append('defs').html(`
+ this.svg.append('defs').html(`
@@ -302,7 +323,7 @@ class NodeMap {
this.container.attr("transform", transform);
const oldZoom = this.svg.classed('zoomed');
const newZoom = transform.k > 2.0;
- if(zoomTimeout) {
+ if (zoomTimeout) {
clearTimeout(zoomTimeout)
}
zoomTimeout = setTimeout(() => {
@@ -522,7 +543,11 @@ class NodeMap {
let group = enter.append("g").attr("class", getClasses);
// group.call(drag(simulation));
group.on("click", (evt, n) => selectNode(evt, n, node));
- group.append('circle').attr("r", 5 /*this.nodeSize*/);
+ // group.append('circle').attr("r", 5 /*this.nodeSize*/);
+ group.append('path')
+ .attr('d', (n) => {
+ return getSymbolForNode(n)(n);
+ })
var nodeTitle = group.append('text').attr("class", "nodeTitle").attr("y", "3").attr('x', 5);
nodeTitle
.each(function (node, i, nodes) {
@@ -1288,9 +1313,16 @@ class Store {
render() {
CONFIG.filters.forEach(f => {
+
let labelEl = document.createElement('label')
let inputEl = document.createElement('input')
let textEl = document.createElement('span');
+ let svg = d3.select(labelEl).append('svg')
+ .attr("viewBox", [-12,-12,24,24]);
+ svg.append('g')
+ .attr("class", "node "+ f)
+ .append('path')
+ .attr('d', getSymbolForCategories(f)());
inputEl.type = "checkbox";
textEl.innerText = f;
labelEl.appendChild(inputEl);