1- ( function ( ) { var w = containerDim ( '#vis' , 'width' ) , h = w / 1.3 , format = d3 . format ( ',d' ) , lscale = d3 . scale . sqrt ( ) . range ( [ 1 , 1.6 ] ) , platforms , maxval ; var fill = d3 . scale . threshold ( ) . domain ( [ 1 , 50 , 100 , 250 , 500 , 1000 , 4000 , 8000 , 20000 ] ) . range ( [ 'rgb(255,247,236)' , 'rgb(254,232,200)' , 'rgb(253,212,158)' , 'rgb(253,187,132)' , 'rgb(252,141,89)' , 'rgb(239,101,72)' , 'rgb(215,48,31)' , 'rgb(179,0,0)' , 'rgb(127,0,0)' ] ) ; var spiral = d3 . layout . pack ( ) . size ( [ w , h ] ) . padding ( 6.6 ) ; var vis = d3 . select ( '#vis' ) . append ( 'svg' ) . attr ( 'width' , w ) . attr ( 'height' , h ) . attr ( 'class' , 'spiral' ) . append ( 'svg:g' ) . call ( d3 . behavior . zoom ( ) . on ( 'zoom' , rescale ) ) ; d3 . json ( '/json/exploit-db-platforms.json' , function ( error , json ) { d3 . select ( '#platformcount' ) . text ( json . length ) ; d3 . select ( '#exploitcount' ) . text ( format ( d3 . sum ( json , function ( d ) { return d . value } ) ) ) ; platforms = spiral . nodes ( nodes ( json ) ) . filter ( function ( d ) { return ! d . children } ) ; var node = vis . selectAll ( 'g.node' ) . data ( platforms ) . enter ( ) . append ( 'g' ) . attr ( 'class' , 'node' ) . attr ( 'transform' , function ( d ) { return 'translate(' + d . x + ',' + d . y + ')' } ) ; node . append ( 'title' ) . text ( function ( d ) { return d . name + ': ' + format ( d . value ) } ) ; node . append ( 'circle' ) . attr ( 'r' , function ( d ) { return d . r } ) . style ( 'fill' , function ( d ) { return fill ( d . value ) } ) . call ( events ) ; node . append ( 'text' ) . attr ( 'text-anchor' , 'middle' ) . attr ( 'dy' , '.3em' ) . attr ( 'style' , function ( d ) { return 'font-size:' + lscale ( d . value ) + 'px' } ) . text ( function ( d ) { return d . name } ) . call ( events ) ; bar ( '#platforms' , platforms . slice ( - 15 ) . reverse ( ) ) ; hashchange ( ) } ) ; d3 . select ( '#close-help' ) . on ( 'click' , function ( ) { d3 . select ( '#legend' ) . style ( 'display' , 'none' ) } ) ; var obtn = d3 . select ( '#overview' ) ; obtn . on ( 'click' , function ( ) { location . replace ( '#' , '' ) ; obtn . style ( 'display' , 'none' ) ; d3 . selectAll ( '.nodeinfo' ) . style ( 'display' , 'none' ) ; d3 . select ( '#expplatforms' ) . style ( 'display' , 'block' ) } ) ; d3 . select ( window ) . on ( 'hashchange' , hashchange ) ; function nodes ( data ) { return { children :data } } function hashchange ( ) { var name = decodeURIComponent ( location . hash . substring ( 1 ) ) . trim ( ) ; if ( ! name ) return ; d3 . select ( '#overview' ) . style ( 'display' , 'block' ) ; for ( i in platforms ) { p = platforms [ i ] ; if ( p . name == name ) { shownode ( p ) ; break } } } function bar ( selector , data ) { maxval = d3 . max ( data , function ( d ) { return d . value } ) ; var loff = 130 , barw = containerDim ( selector , 'width' ) - loff , barh = 20 * data . length , xoff = 10 , yoff = 15 , y = 20 , wscale = d3 . scale . linear ( ) . domain ( [ 0 , maxval ] ) . range ( [ '0px' , barw + 'px' ] ) , xticks = wscale . ticks ( 4 ) ; var bar = d3 . select ( selector ) ; bar . selectAll ( 'svg' ) . remove ( ) ; var svg = bar . append ( 'svg' ) . attr ( 'class' , 'bar' ) . attr ( 'width' , barw + 130 ) . attr ( 'height' , barh + yoff ) . append ( 'g' ) . attr ( 'transform' , 'translate(' + xoff + ',' + xoff + ')' ) ; svg . selectAll ( 'text' ) . data ( data ) . enter ( ) . append ( 'text' ) . attr ( 'x' , barw + xoff ) . attr ( 'y' , function ( d , i ) { return i * y + yoff } ) . text ( function ( d ) { return d . name + ': ' + format ( d . value ) } ) ; svg . selectAll ( 'line' ) . data ( xticks ) . enter ( ) . append ( 'line' ) . attr ( 'x1' , wscale ) . attr ( 'x2' , wscale ) . attr ( 'y1' , 0 ) . attr ( 'y2' , barh ) . style ( 'stroke' , '#ccc' ) . style ( 'stroke-dasharray' , '5,2' ) ; svg . selectAll ( 'rect' ) . data ( data ) . enter ( ) . append ( 'rect' ) . attr ( 'y' , function ( d , i ) { return i * y } ) . attr ( 'width' , function ( d ) { return wscale ( d . value ) } ) . attr ( 'height' , y - 1 ) ; svg . selectAll ( '.rule' ) . data ( xticks ) . enter ( ) . append ( 'text' ) . attr ( 'class' , 'rule' ) . attr ( 'x' , wscale ) . attr ( 'y' , 0 ) . attr ( 'dy' , - 2 ) . attr ( 'text-anchor' , 'middle' ) . text ( String ) } function nodecolor ( elt , color ) { if ( 'text' == elt . nodeName ) d3 . select ( elt . previousSibling ) . style ( 'fill' , color ) ; else d3 . select ( elt ) . style ( 'fill' , color ) } function shownode ( d ) { location . replace ( '#' + encodeURIComponent ( d . name ) ) ; d3 . select ( '#expplatforms' ) . style ( 'display' , 'none' ) ; d3 . selectAll ( '.nodeinfo' ) . style ( 'display' , 'block' ) ; d3 . select ( '#platform' ) . text ( d . name + ' ' + format ( d . value ) + ' exploits' ) ; bar ( '#exptypes' , d . types ) ; bar ( '#expcode' , d . code ) } function events ( d ) { d . on ( 'click' , function ( d ) { shownode ( d ) } ) ; d . on ( 'mouseover' , function ( d ) { nodecolor ( this , '#ddd' ) } ) ; d . on ( 'mouseout' , function ( d ) { nodecolor ( this , fill ( d . value ) ) } ) } function rescale ( ) { vis . attr ( 'transform' , 'translate(' + d3 . event . translate + ')' + ' scale(' + d3 . event . scale + ')' ) } } ) ( ) ;
1+ ( function ( ) {
2+
3+ var w = containerDim ( '#vis' , 'width' ) ,
4+ h = w / 1.3 ,
5+ format = d3 . format ( ',d' ) ,
6+ lscale = d3 . scale . sqrt ( ) . range ( [ 1 , 1.6 ] ) ,
7+ platforms ,
8+ maxval ;
9+
10+ var fill = d3 . scale . threshold ( ) . domain ( [ 1 , 50 , 100 , 250 , 500 , 1000 , 4000 , 8000 , 20000 ] ) . range ( [ 'rgb(255,247,236)' , 'rgb(254,232,200)' , 'rgb(253,212,158)' , 'rgb(253,187,132)' , 'rgb(252,141,89)' , 'rgb(239,101,72)' , 'rgb(215,48,31)' , 'rgb(179,0,0)' , 'rgb(127,0,0)' ] ) ;
11+
12+ var spiral = d3 . layout . pack ( ) . size ( [ w , h ] ) . padding ( 6.6 ) ;
13+
14+ var vis = d3 . select ( '#vis' ) . append ( 'svg' ) . attr ( 'width' , w ) . attr ( 'height' , h ) . attr ( 'class' , 'spiral' ) . append ( 'svg:g' ) . call ( d3 . behavior . zoom ( ) . on ( 'zoom' , rescale ) ) ;
15+
16+ d3 . json ( '/json/exploit-db-platforms.json' , function ( error , json ) {
17+ d3 . select ( '#platformcount' ) . text ( json . length ) ;
18+ d3 . select ( '#exploitcount' ) . text ( format ( d3 . sum ( json , function ( d ) {
19+ return d . value ;
20+ } ) ) ) ;
21+
22+ platforms = spiral . nodes ( nodes ( json ) ) . filter ( function ( d ) {
23+ return ! d . children ;
24+ } ) ;
25+ var node = vis . selectAll ( 'g.node' ) . data ( platforms ) . enter ( ) . append ( 'g' ) . attr ( 'class' , 'node' ) . attr ( 'transform' , function ( d ) {
26+ return 'translate(' + d . x + ',' + d . y + ')' ;
27+ } ) ;
28+
29+ node . append ( 'title' ) . text ( function ( d ) {
30+ return d . name + ': ' + format ( d . value ) ;
31+ } ) ;
32+
33+ node . append ( 'circle' ) . attr ( 'r' , function ( d ) {
34+ return d . r ;
35+ } ) . style ( 'fill' , function ( d ) {
36+ return fill ( d . value ) ;
37+ } ) . call ( events ) ;
38+
39+ node . append ( 'text' ) . attr ( 'text-anchor' , 'middle' ) . attr ( 'dy' , '.3em' ) . attr ( 'style' , function ( d ) {
40+ return 'font-size:' + lscale ( d . value ) + 'px' ;
41+ } ) . text ( function ( d ) {
42+ return d . name ;
43+ } ) . call ( events ) ;
44+
45+ bar ( '#platforms' , platforms . slice ( - 15 ) . reverse ( ) ) ;
46+
47+ hashchange ( ) ;
48+ } ) ;
49+
50+ d3 . select ( '#close-help' ) . on ( 'click' , function ( ) {
51+ d3 . select ( '#legend' ) . style ( 'display' , 'none' ) ;
52+ } ) ;
53+
54+ var obtn = d3 . select ( '#overview' ) ;
55+ obtn . on ( 'click' , function ( ) {
56+ location . replace ( '#' , '' ) ;
57+ obtn . style ( 'display' , 'none' ) ;
58+ d3 . selectAll ( '.nodeinfo' ) . style ( 'display' , 'none' ) ;
59+ d3 . select ( '#expplatforms' ) . style ( 'display' , 'block' ) ;
60+ } ) ;
61+
62+ d3 . select ( window ) . on ( 'hashchange' , hashchange ) ;
63+
64+ function nodes ( data ) {
65+ return { children : data } ;
66+ }
67+
68+ function hashchange ( ) {
69+ var name = decodeURIComponent ( location . hash . substring ( 1 ) ) . trim ( ) ;
70+ if ( ! name ) return ;
71+ d3 . select ( '#overview' ) . style ( 'display' , 'block' ) ;
72+ for ( i in platforms ) {
73+ p = platforms [ i ] ;
74+ if ( p . name == name ) {
75+ shownode ( p ) ;
76+ break ;
77+ }
78+ }
79+ }
80+
81+ function bar ( selector , data ) {
82+ maxval = d3 . max ( data , function ( d ) {
83+ return d . value ;
84+ } ) ;
85+ var loff = 130 ,
86+ barw = containerDim ( selector , 'width' ) - loff ,
87+ barh = 20 * data . length ,
88+ xoff = 10 ,
89+ yoff = 15 ,
90+ y = 20 ,
91+ wscale = d3 . scale . linear ( ) . domain ( [ 0 , maxval ] ) . range ( [ '0px' , barw + 'px' ] ) ,
92+ xticks = wscale . ticks ( 4 ) ;
93+
94+ var bar = d3 . select ( selector ) ;
95+ bar . selectAll ( 'svg' ) . remove ( ) ;
96+ var svg = bar . append ( 'svg' ) . attr ( 'class' , 'bar' ) . attr ( 'width' , barw + 130 ) . attr ( 'height' , barh + yoff ) . append ( 'g' ) . attr ( 'transform' , 'translate(' + xoff + ',' + xoff + ')' ) ;
97+
98+ svg . selectAll ( 'text' ) . data ( data ) . enter ( ) . append ( 'text' ) . attr ( 'x' , barw + xoff ) . attr ( 'y' , function ( d , i ) {
99+ return i * y + yoff ;
100+ } ) . text ( function ( d ) {
101+ return d . name + ': ' + format ( d . value ) ;
102+ } ) ;
103+
104+ svg . selectAll ( 'line' ) . data ( xticks ) . enter ( ) . append ( 'line' ) . attr ( 'x1' , wscale ) . attr ( 'x2' , wscale ) . attr ( 'y1' , 0 ) . attr ( 'y2' , barh ) . style ( 'stroke' , '#ccc' ) . style ( 'stroke-dasharray' , '5,2' ) ;
105+
106+ svg . selectAll ( 'rect' ) . data ( data ) . enter ( ) . append ( 'rect' ) . attr ( 'y' , function ( d , i ) {
107+ return i * y ;
108+ } ) . attr ( 'width' , function ( d ) {
109+ return wscale ( d . value ) ;
110+ } ) . attr ( 'height' , y - 1 ) ;
111+
112+ svg . selectAll ( '.rule' ) . data ( xticks ) . enter ( ) . append ( 'text' ) . attr ( 'class' , 'rule' ) . attr ( 'x' , wscale ) . attr ( 'y' , 0 ) . attr ( 'dy' , - 2 ) . attr ( 'text-anchor' , 'middle' ) . text ( String ) ;
113+ }
114+
115+ function nodecolor ( elt , color ) {
116+ if ( 'text' == elt . nodeName ) d3 . select ( elt . previousSibling ) . style ( 'fill' , color ) ; else d3 . select ( elt ) . style ( 'fill' , color ) ;
117+ }
118+
119+ function shownode ( d ) {
120+ location . replace ( '#' + encodeURIComponent ( d . name ) ) ;
121+ d3 . select ( '#expplatforms' ) . style ( 'display' , 'none' ) ;
122+ d3 . selectAll ( '.nodeinfo' ) . style ( 'display' , 'block' ) ;
123+ d3 . select ( '#platform' ) . text ( d . name + ' ' + format ( d . value ) + ' exploits' ) ;
124+ bar ( '#exptypes' , d . types ) ;
125+ bar ( '#expcode' , d . code ) ;
126+ }
127+
128+ function events ( d ) {
129+ d . on ( 'click' , function ( d ) {
130+ shownode ( d ) ;
131+ } ) ;
132+ d . on ( 'mouseover' , function ( d ) {
133+ nodecolor ( this , '#ddd' ) ;
134+ } ) ;
135+ d . on ( 'mouseout' , function ( d ) {
136+ nodecolor ( this , fill ( d . value ) ) ;
137+ } ) ;
138+ }
139+
140+ function rescale ( ) {
141+ vis . attr ( 'transform' , 'translate(' + d3 . event . translate + ')' + ' scale(' + d3 . event . scale + ')' ) ;
142+ }
143+ } ) ( ) ;
0 commit comments