Skip to content

Instantly share code, notes, and snippets.

@jacekd
Created November 16, 2016 18:52
Show Gist options
  • Save jacekd/3075ba78a299b581e3a2c9baa4f57473 to your computer and use it in GitHub Desktop.
Save jacekd/3075ba78a299b581e3a2c9baa4f57473 to your computer and use it in GitHub Desktop.
threats catalogue
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>threat catalogue</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.3.1/lodash.min.js"></script>
<style>
.link {
stroke-width: 1px;
stroke: #ddd;
fill: none;
}
.text {
font-family: "Lucida Grande", "Helvetica Nueue", Arial, sans-serif;
font-size: 10px;
}
.hover {
stroke: #2c3e50;
}
.root {
visibility: hidden;
}
.chart {
width: 100%;
height: 100%;
}
div.tooltip {
position: absolute;
text-align: center;
max-width: 160px;
padding: 7px 10px;
font: 12px sans-serif;
color: white;
background: #111;
border: 0px;
border-radius: 2px;
pointer-events: none;
margin-top: 2px;
}
div.tooltip:before {
content: '';
position: absolute;
top: 0%;
left: 50%;
margin-left: -8px;
margin-top: -8px;
width: 0; height: 0;
border-bottom: 8px solid #111;
border-right: 8px solid transparent;
border-left: 8px solid transparent;
}
</style>
</head>
<body>
<div class="chart">
</div>
<script>
var data = {
"id": "root",
"name": "threats",
"children": [
{
"id": "T1",
"name": "T1",
"children": [
{
"id": "IA-1",
"name": "IA-1"
},
{
"id": "IA-2",
"name": "IA-2"
},
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "IA-8",
"name": "IA-8"
},
{
"id": "IA-9",
"name": "IA-9"
}
]
},
{
"id": "T2",
"name": "T2",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "SC-28",
"name": "SC-28"
},
{
"id": "PE-2",
"name": "PE-2"
}
]
},
{
"id": "T3",
"name": "T3",
"children": [
{
"id": "IA-3",
"name": "IA-3"
},
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "PE-2",
"name": "PE-2"
}
]
},
{
"id": "T4",
"name": "T4",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "SC-28",
"name": "SC-28"
}
]
},
{
"id": "T5",
"name": "T5",
"children": [
{
"id": "AT-2",
"name": "AT-2"
},
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "CM-7",
"name": "CM-7"
}
]
},
{
"id": "T6",
"name": "T6",
"children": [
{
"id": "IA-1",
"name": "IA-1"
}
]
},
{
"id": "T7",
"name": "T7",
"children": [
{
"id": "SC-8",
"name": "SC-8"
},
{
"id": "SC-23",
"name": "SC-23"
},
{
"id": "AT-2",
"name": "AT-2"
}
]
},
{
"id": "T8",
"name": "T8",
"children": [
{
"id": "AC-1",
"name": "AC-1"
},
{
"id": "AC-6",
"name": "AC-6"
},
{
"id": "AC-8",
"name": "AC-8"
}
]
},
{
"id": "T9",
"name": "T9",
"children": [
{
"id": "IA-1",
"name": "IA-1"
}
]
},
{
"id": "T10",
"name": "T10",
"children": [
{
"id": "IA-1",
"name": "IA-1"
}
]
},
{
"id": "T11",
"name": "T11",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "SC-28",
"name": "SC-28"
},
{
"id": "AC-23",
"name": "AC-23"
}
]
},
{
"id": "T12",
"name": "T12",
"children": [
{
"id": "AC-7",
"name": "AC-7"
},
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T13",
"name": "T13",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "IA-9",
"name": "IA-9"
},
{
"id": "IA-11",
"name": "IA-11"
},
{
"id": "SC-8",
"name": "SC-8"
}
]
},
{
"id": "T14",
"name": "T14",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "SC-28",
"name": "SC-28"
},
{
"id": "AC-23",
"name": "AC-23"
}
]
},
{
"id": "T15",
"name": "T15",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "IA-9.SC-8",
"name": "IA-9.SC-8"
}
]
},
{
"id": "T16",
"name": "T16",
"children": [
{
"id": "IA-9",
"name": "IA-9"
}
]
},
{
"id": "T17",
"name": "T17",
"children": [
{
"id": "SC-8",
"name": "SC-8"
},
{
"id": "IA-9",
"name": "IA-9"
}
]
},
{
"id": "T18",
"name": "T18",
"children": [
{
"id": "SC-8",
"name": "SC-8"
},
{
"id": "IA-9",
"name": "IA-9"
}
]
},
{
"id": "T19",
"name": "T19",
"children": [
{
"id": "IA-1",
"name": "IA-1"
}
]
},
{
"id": "T20",
"name": "T20",
"children": [
{
"id": "IA-1",
"name": "IA-1"
},
{
"id": "AT-2",
"name": "AT-2"
}
]
},
{
"id": "T21",
"name": "T21",
"children": []
},
{
"id": "T22",
"name": "T22",
"children": [
{
"id": "IA-2",
"name": "IA-2"
},
{
"id": "IA-2(9)",
"name": "IA-2(9)"
},
{
"id": "IA-2(13)",
"name": "IA-2(13)"
},
{
"id": "AC-2",
"name": "AC-2"
}
]
},
{
"id": "T23",
"name": "T23",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "AC-10",
"name": "AC-10"
},
{
"id": "SC-5",
"name": "SC-5"
}
]
},
{
"id": "T24",
"name": "T24",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "IA-9",
"name": "IA-9"
},
{
"id": "AC-10",
"name": "AC-10"
},
{
"id": "SC-5",
"name": "SC-5"
}
]
},
{
"id": "T25",
"name": "T25",
"children": [
{
"id": "IA-8",
"name": "IA-8"
},
{
"id": "IA-8(4)",
"name": "IA-8(4)"
},
{
"id": "IA-9",
"name": "IA-9"
}
]
},
{
"id": "T26",
"name": "T26",
"children": [
{
"id": "SC-8",
"name": "SC-8"
}
]
},
{
"id": "T27",
"name": "T27",
"children": [
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T28",
"name": "T28",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "IA-9",
"name": "IA-9"
}
]
},
{
"id": "T29",
"name": "T29",
"children": [
{
"id": "AT-2",
"name": "AT-2"
},
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T30",
"name": "T30",
"children": [
{
"id": "IA-8",
"name": "IA-8"
},
{
"id": "IA-8(4)",
"name": "IA-8(4)"
}
]
},
{
"id": "T31",
"name": "T31",
"children": [
{
"id": "AC-2",
"name": "AC-2"
}
]
},
{
"id": "T32",
"name": "T32",
"children": [
{
"id": "AC-2",
"name": "AC-2"
}
]
},
{
"id": "T33",
"name": "T33",
"children": [
{
"id": "SC-8",
"name": "SC-8"
}
]
},
{
"id": "T34",
"name": "T34",
"children": [
{
"id": "SC-28",
"name": "SC-28"
},
{
"id": "AC-23",
"name": "AC-23"
}
]
},
{
"id": "T35",
"name": "T35",
"children": [
{
"id": "IA-2",
"name": "IA-2"
},
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "IA-8",
"name": "IA-8"
},
{
"id": "AC-11",
"name": "AC-11"
}
]
},
{
"id": "T36",
"name": "T36",
"children": [
{
"id": "SC-8",
"name": "SC-8"
}
]
},
{
"id": "T37",
"name": "T37",
"children": [
{
"id": "SC-28",
"name": "SC-28"
},
{
"id": "AC-23",
"name": "AC-23"
}
]
},
{
"id": "T38",
"name": "T38",
"children": [
{
"id": "IA-9",
"name": "IA-9"
}
]
},
{
"id": "T39",
"name": "T39",
"children": [
{
"id": "IA-9",
"name": "IA-9"
}
]
},
{
"id": "T40",
"name": "T40",
"children": [
{
"id": "SC-8",
"name": "SC-8"
},
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T41",
"name": "T41",
"children": [
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T42",
"name": "T42",
"children": [
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T43",
"name": "T43",
"children": [
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T44",
"name": "T44",
"children": [
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T45",
"name": "T45",
"children": [
{
"id": "IA-1",
"name": "IA-1"
},
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T46",
"name": "T46",
"children": [
{
"id": "SC-28",
"name": "SC-28"
},
{
"id": "AC-23",
"name": "AC-23"
},
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T47",
"name": "T47",
"children": [
{
"id": "SC-8",
"name": "SC-8"
}
]
},
{
"id": "T48",
"name": "T48",
"children": [
{
"id": "SC-28",
"name": "SC-28"
},
{
"id": " AC-23",
"name": " AC-23"
}
]
},
{
"id": "T49",
"name": "T49",
"children": [
{
"id": "SC-8",
"name": "SC-8"
}
]
},
{
"id": "T50",
"name": "T50",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "IA-6",
"name": "IA-6"
}
]
},
{
"id": "T51",
"name": "T51",
"children": [
{
"id": "AC-7",
"name": "AC-7"
},
{
"id": "AC-9",
"name": "AC-9"
},
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T52",
"name": "T52",
"children": [
{
"id": "SC-8",
"name": "SC-8"
}
]
},
{
"id": "T53",
"name": "T53",
"children": [
{
"id": "IA-5",
"name": "IA-5"
}
]
},
{
"id": "T54",
"name": "T54",
"children": [
{
"id": "AC-2",
"name": "AC-2"
},
{
"id": " AC-2(12)",
"name": " AC-2(12)"
},
{
"id": "AC-3",
"name": "AC-3"
},
{
"id": "AC-7",
"name": "AC-7"
},
{
"id": "AC-9",
"name": "AC-9"
},
{
"id": "AC-17",
"name": "AC-17"
},
{
"id": "AC-23",
"name": "AC-23"
}
]
},
{
"id": "T55",
"name": "T55",
"children": [
{
"id": "CA-7",
"name": "CA-7"
},
{
"id": "CA-8",
"name": "CA-8"
},
{
"id": "RA-5",
"name": "RA-5"
},
{
"id": "SA-12(5)",
"name": "SA-12(5)"
},
{
"id": "SC-30(3)",
"name": "SC-30(3)"
},
{
"id": "SI-14",
"name": "SI-14"
},
{
"id": "AC-6(9)",
"name": "AC-6(9)"
}
]
},
{
"id": "T56",
"name": "T56",
"children": [
{
"id": "IA-1",
"name": "IA-1"
},
{
"id": "AC-1",
"name": "AC-1"
},
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": "SC-28",
"name": "SC-28"
},
{
"id": "AC-23",
"name": "AC-23"
}
]
},
{
"id": "T57",
"name": "T57",
"children": [
{
"id": "SI-4",
"name": "SI-4"
},
{
"id": "SI-10",
"name": "SI-10"
}
]
},
{
"id": "T58",
"name": "T58",
"children": [
{
"id": "SI-10",
"name": "SI-10"
},
{
"id": "RA-5",
"name": "RA-5"
}
]
},
{
"id": "T59",
"name": "T59",
"children": [
{
"id": "SC-8",
"name": "SC-8"
},
{
"id": "SC-28",
"name": "SC-28"
},
{
"id": "IR-1",
"name": "IR-1"
},
{
"id": "IR-4",
"name": "IR-4"
},
{
"id": "IR-5",
"name": "IR-5"
},
{
"id": "IR-6",
"name": "IR-6"
},
{
"id": "IR-9",
"name": "IR-9"
}
]
},
{
"id": "T60",
"name": "T60",
"children": [
{
"id": "SC-5",
"name": "SC-5"
},
{
"id": "SC-5(3)",
"name": "SC-5(3)"
}
]
},
{
"id": "T61",
"name": "T61",
"children": [
{
"id": "SI-10",
"name": "SI-10"
},
{
"id": "SI-15",
"name": "SI-15"
}
]
},
{
"id": "T62",
"name": "T62",
"children": [
{
"id": "AC-1",
"name": "AC-1"
}
]
},
{
"id": "T63",
"name": "T63",
"children": [
{
"id": "SC-23",
"name": "SC-23"
},
{
"id": "IA-2(13)",
"name": "IA-2(13)"
}
]
},
{
"id": "T64",
"name": "T64",
"children": [
{
"id": "AC-6",
"name": "AC-6"
},
{
"id": "AC-6(1)",
"name": "AC-6(1)"
},
{
"id": "AC-3",
"name": "AC-3"
}
]
},
{
"id": "T65",
"name": "T65",
"children": [
{
"id": "AC-6",
"name": "AC-6"
},
{
"id": " AC-6(1)",
"name": " AC-6(1)"
},
{
"id": "AC-3",
"name": "AC-3"
}
]
},
{
"id": "T66",
"name": "T66",
"children": [
{
"id": "SC-8",
"name": "SC-8"
},
{
"id": "SC-23",
"name": "SC-23"
}
]
},
{
"id": "T67",
"name": "T67",
"children": [
{
"id": "AC-6",
"name": "AC-6"
},
{
"id": "AC-6(1)",
"name": "AC-6(1)"
},
{
"id": "AC-6(3)",
"name": "AC-6(3)"
},
{
"id": "AC-6(5)",
"name": "AC-6(5)"
}
]
},
{
"id": "T68",
"name": "T68",
"children": [
{
"id": "AC-4",
"name": "AC-4"
}
]
},
{
"id": "T69",
"name": "T69",
"children": [
{
"id": "IA-5",
"name": "IA-5"
},
{
"id": " IA-5(1)",
"name": " IA-5(1)"
},
{
"id": "IA-5(2)",
"name": "IA-5(2)"
},
{
"id": "IA-5(4)",
"name": "IA-5(4)"
},
{
"id": "IA-5(6)",
"name": "IA-5(6)"
},
{
"id": "IA-5(7)",
"name": "IA-5(7)"
},
{
"id": "IA-5(11)",
"name": "IA-5(11)"
},
{
"id": "IA-5(12)",
"name": "IA-5(12)"
},
{
"id": "IA-5(13)",
"name": "IA-5(13)"
}
]
},
{
"id": "T70",
"name": "T70",
"children": [
{
"id": "SC-8",
"name": "SC-8"
},
{
"id": "SC-28",
"name": "SC-28"
}
]
},
{
"id": "T71",
"name": "T71",
"children": [
{
"id": "SC-4",
"name": "SC-4"
}
]
},
{
"id": "T72",
"name": "T72",
"children": [
{
"id": "SC-4",
"name": "SC-4"
},
{
"id": "MP-6",
"name": "MP-6"
}
]
},
{
"id": "T73",
"name": "T73",
"children": [
{
"id": "SC-4",
"name": "SC-4"
},
{
"id": "SI-16",
"name": "SI-16"
}
]
},
{
"id": "T74",
"name": "T74",
"children": [
{
"id": "AC-4",
"name": "AC-4"
}
]
},
{
"id": "T75",
"name": "T75",
"children": [
{
"id": "SA-10(1)",
"name": "SA-10(1)"
},
{
"id": "SA-10(3)",
"name": "SA-10(3)"
},
{
"id": "SA-10(4)",
"name": "SA-10(4)"
}
]
},
{
"id": "T76",
"name": "T76",
"children": [
{
"id": "SA-10(1)",
"name": "SA-10(1)"
},
{
"id": "SA-10(3)",
"name": "SA-10(3)"
},
{
"id": "SA-10(4)",
"name": "SA-10(4)"
}
]
},
{
"id": "T77",
"name": "T77",
"children": [
{
"id": "SC-5",
"name": "SC-5"
},
{
"id": "SC-5(3)",
"name": "SC-5(3)"
}
]
},
{
"id": "T78",
"name": "T78",
"children": [
{
"id": "SC-5",
"name": "SC-5"
},
{
"id": "SC-5(3)",
"name": "SC-5(3)"
}
]
},
{
"id": "T79",
"name": "T79",
"children": [
{
"id": "SC-5",
"name": "SC-5"
},
{
"id": "SC-5(3)",
"name": "SC-5(3)"
}
]
},
{
"id": "T80",
"name": "T80",
"children": [
{
"id": "CP-9",
"name": "CP-9"
},
{
"id": "CP-9(5)",
"name": "CP-9(5)"
},
{
"id": "CP-9(6)",
"name": "CP-9(6)"
}
]
},
{
"id": "T81",
"name": "T81",
"children": [
{
"id": "IA-3",
"name": "IA-3"
}
]
},
{
"id": "T82",
"name": "T82",
"children": [
{
"id": "SC-5",
"name": "SC-5"
},
{
"id": "SC-5(3)",
"name": "SC-5(3)"
}
]
},
{
"id": "T83",
"name": "T83",
"children": [
{
"id": "PE-9",
"name": "PE-9"
},
{
"id": " PE-9(1)",
"name": " PE-9(1)"
},
{
"id": "PE-9(2)",
"name": "PE-9(2)"
},
{
"id": "PE-11",
"name": "PE-11"
},
{
"id": "CP-2(6)",
"name": "CP-2(6)"
}
]
},
{
"id": "T84",
"name": "T84",
"children": [
{
"id": "CP-8",
"name": "CP-8"
}
]
},
{
"id": "T85",
"name": "T85",
"children": [
{
"id": "PE-3",
"name": "PE-3"
}
]
},
{
"id": "T86",
"name": "T86",
"children": [
{
"id": "MP-6",
"name": "MP-6"
}
]
},
{
"id": "T87",
"name": "T87",
"children": [
{
"id": "PE-2",
"name": "PE-2"
},
{
"id": "PE-3",
"name": "PE-3"
},
{
"id": "CP-6",
"name": "CP-6"
},
{
"id": "CP-9(6)",
"name": "CP-9(6)"
}
]
},
{
"id": "T88",
"name": "T88",
"children": [
{
"id": "SA-18",
"name": "SA-18"
},
{
"id": "SA-19",
"name": "SA-19"
},
{
"id": "SI-3",
"name": "SI-3"
}
]
},
{
"id": "T89",
"name": "T89",
"children": [
{
"id": "RA-5",
"name": "RA-5"
},
{
"id": "RA-5(1)",
"name": "RA-5(1)"
},
{
"id": "RA-5(2)",
"name": "RA-5(2)"
},
{
"id": "RA-5(3)",
"name": "RA-5(3)"
}
]
},
{
"id": "T90",
"name": "T90",
"children": [
{
"id": "SA-13",
"name": "SA-13"
}
]
},
{
"id": "T91",
"name": "T91",
"children": [
{
"id": "SI-16",
"name": "SI-16"
}
]
},
{
"id": "T92",
"name": "T92",
"children": [
{
"id": "SI-10",
"name": "SI-10"
}
]
},
{
"id": "T93",
"name": "T93",
"children": [
{
"id": "SC-23",
"name": "SC-23"
}
]
}
]
};
var graph = {
width: 1600,
height: 3000
};
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
};
var svg = d3.select('.chart').append('svg:svg')
.attr("width", graph.width)
.attr("height", graph.height)
.append('svg:g')
.attr('transform', 'translate(-' + graph.width * 0.1 + ', 0)')
function elbow(d, i) {
return "M" + d.source.y + "," + d.source.x + "H" + d.target.y
+ "V" + d.target.x + "H" + d.target.y
}
var diagonal = d3.svg.diagonal()
.projection(function(d)
{
return [d.y, d.x];
});
var tree = d3.layout.tree()
.size([graph.height,graph.width]);
var nodes = tree.nodes(data);
nodes = _.uniq(nodes, 'id');
_.each(nodes, function (o , i) {
var itemsOfTheSameDepth = _.where(nodes, {depth: o.depth});
var indexOfCurrent = _.indexOf(itemsOfTheSameDepth, o);
var interval = graph.height / itemsOfTheSameDepth.length;
nodes[i].x = interval / 2 + (interval * indexOfCurrent);
});
//tooltip
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var links = tree.links(nodes);
_.each(links, function (o, i) {
links[i].target = _.find(nodes, {id: o.target.id});
});
var link = svg.selectAll("path")
.data(links)
.enter().append("svg:path")
.attr('class', function (d) {
return (!!d.source) ? d.source.id : "root";
})
.classed('link', true)
.attr('d', diagonal);
var node = svg.selectAll('g.node')
.data(nodes)
.enter().append("svg:g")
.attr("transform", function (d) {
return "translate(" + d.y + "," + d.x + ")";
})
.on('mouseup', function (d) {
// remove all the colour paths
d3.selectAll('path.link').classed('hover', false);
// draw new colour paths
d3.selectAll("." + d.id)
.classed("hover", true)
.moveToFront();
_.pluck(d.children, 'id').forEach(function (id) {
d3.selectAll('.' + id)
.classed('hover', true)
.moveToFront();
});
})
.on('mouseover', function (d) {
if (!!d.description) {
tooltip.transition()
.duration(200)
.style('opacity',.9);
tooltip.html(d.description)
.style('left', (d3.event.pageX) + 'px')
.style('top', ((d3.event.pageY) + 8) + "px")
}
})
.on('mouseout', function (d) {
tooltip.transition()
.duration(500)
.style('opacity', 0);
});
var colors = d3.scale.category20();
node.append("svg:circle")
.attr("r", 4)
.attr('fill', function (d, i) {
return colors(d.id.split('-')[0]);
})
.attr('stroke', "#333333")
.attr('stroke-width', '1.5px');
node.append("svg:text")
.attr("dx", function (d) {
return d.children ? -8: 8;
})
.attr("dy", 3)
.classed("text", true)
.attr("text-anchor", function (d) {
return d.children ? "end" : "start";
})
.text(function (d) {
return d.name;
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment