Built with blockbuilder.org
forked from anonymous's block: d3.v4 collapsible force zoomable draggable radial tree using svg
| license: mit |
Built with blockbuilder.org
forked from anonymous's block: d3.v4 collapsible force zoomable draggable radial tree using svg
| { | |
| "name": "name0", | |
| "children": [ | |
| { | |
| "name": "name1", | |
| "children": [ | |
| { | |
| "name": "name2", | |
| "children": [ | |
| { | |
| "children": [ | |
| { | |
| "name": "name4" | |
| }, | |
| { | |
| "name": "name5" | |
| }, | |
| { | |
| "name": "name6" | |
| }, | |
| { | |
| "name": "name7" | |
| }, | |
| { | |
| "name": "name8" | |
| }, | |
| { | |
| "name": "name9" | |
| }, | |
| { | |
| "name": "name10" | |
| }, | |
| { | |
| "name": "name11" | |
| }, | |
| { | |
| "name": "name12" | |
| }, | |
| { | |
| "name": "name13" | |
| }, | |
| { | |
| "name": "name14" | |
| }, | |
| { | |
| "name": "name15" | |
| }, | |
| { | |
| "name": "name16" | |
| }, | |
| { | |
| "name": "name17" | |
| }, | |
| { | |
| "name": "name18" | |
| }, | |
| { | |
| "name": "name19" | |
| }, | |
| { | |
| "name": "name20" | |
| }, | |
| { | |
| "name": "name21" | |
| }, | |
| { | |
| "name": "name22" | |
| }, | |
| { | |
| "name": "name23" | |
| }, | |
| { | |
| "name": "name24" | |
| }, | |
| { | |
| "name": "name25" | |
| }, | |
| { | |
| "name": "name26" | |
| }, | |
| { | |
| "name": "name27" | |
| }, | |
| { | |
| "name": "name28" | |
| }, | |
| { | |
| "name": "name29" | |
| }, | |
| { | |
| "name": "name30" | |
| }, | |
| { | |
| "name": "name31" | |
| }, | |
| { | |
| "name": "name32" | |
| }, | |
| { | |
| "name": "name33" | |
| }, | |
| { | |
| "name": "name34" | |
| }, | |
| { | |
| "name": "name35" | |
| }, | |
| { | |
| "name": "name36" | |
| }, | |
| { | |
| "name": "name37" | |
| }, | |
| { | |
| "name": "name38" | |
| }, | |
| { | |
| "name": "name39" | |
| }, | |
| { | |
| "name": "name40" | |
| }, | |
| { | |
| "name": "name41" | |
| }, | |
| { | |
| "name": "name42" | |
| }, | |
| { | |
| "name": "name43" | |
| }, | |
| { | |
| "name": "name44" | |
| }, | |
| { | |
| "name": "name45" | |
| }, | |
| { | |
| "name": "name46" | |
| }, | |
| { | |
| "name": "name47" | |
| }, | |
| { | |
| "name": "name48" | |
| }, | |
| { | |
| "name": "name49" | |
| }, | |
| { | |
| "name": "name50" | |
| }, | |
| { | |
| "name": "name51" | |
| }, | |
| { | |
| "name": "name52" | |
| }, | |
| { | |
| "name": "name53" | |
| }, | |
| { | |
| "name": "name54" | |
| }, | |
| { | |
| "name": "name55" | |
| }, | |
| { | |
| "name": "name56" | |
| }, | |
| { | |
| "name": "name57" | |
| }, | |
| { | |
| "name": "name58" | |
| }, | |
| { | |
| "name": "name59" | |
| }, | |
| { | |
| "name": "name60" | |
| }, | |
| { | |
| "name": "name61" | |
| }, | |
| { | |
| "name": "name62" | |
| }, | |
| { | |
| "name": "name63" | |
| }, | |
| { | |
| "name": "name64" | |
| }, | |
| { | |
| "name": "name65" | |
| }, | |
| { | |
| "name": "name66" | |
| }, | |
| { | |
| "name": "name67" | |
| }, | |
| { | |
| "name": "name68" | |
| }, | |
| { | |
| "name": "name69" | |
| }, | |
| { | |
| "name": "name70" | |
| }, | |
| { | |
| "name": "name71" | |
| }, | |
| { | |
| "name": "name72" | |
| }, | |
| { | |
| "name": "name73" | |
| }, | |
| { | |
| "name": "name74" | |
| }, | |
| { | |
| "name": "name75" | |
| }, | |
| { | |
| "name": "name76" | |
| }, | |
| { | |
| "name": "name77" | |
| }, | |
| { | |
| "name": "name78" | |
| }, | |
| { | |
| "name": "name79" | |
| }, | |
| { | |
| "name": "name80" | |
| }, | |
| { | |
| "name": "name81" | |
| }, | |
| { | |
| "name": "name82" | |
| }, | |
| { | |
| "name": "name83" | |
| }, | |
| { | |
| "name": "name84" | |
| }, | |
| { | |
| "name": "name85" | |
| }, | |
| { | |
| "name": "name86" | |
| }, | |
| { | |
| "name": "name87" | |
| }, | |
| { | |
| "name": "name88" | |
| }, | |
| { | |
| "name": "name89" | |
| }, | |
| { | |
| "name": "name90" | |
| }, | |
| { | |
| "name": "name91" | |
| }, | |
| { | |
| "name": "name92" | |
| }, | |
| { | |
| "name": "name93" | |
| }, | |
| { | |
| "name": "name94" | |
| }, | |
| { | |
| "name": "name95" | |
| }, | |
| { | |
| "name": "name96" | |
| }, | |
| { | |
| "name": "name97" | |
| }, | |
| { | |
| "name": "name98" | |
| }, | |
| { | |
| "name": "name99" | |
| }, | |
| { | |
| "name": "name100" | |
| }, | |
| { | |
| "name": "name101" | |
| }, | |
| { | |
| "name": "name102" | |
| } | |
| ], | |
| "name": "name3" | |
| }, | |
| { | |
| "children": [ | |
| { | |
| "name": "name104" | |
| }, | |
| { | |
| "name": "name105" | |
| }, | |
| { | |
| "name": "name106" | |
| }, | |
| { | |
| "name": "name107" | |
| }, | |
| { | |
| "name": "name108" | |
| }, | |
| { | |
| "name": "name109" | |
| }, | |
| { | |
| "name": "name110" | |
| }, | |
| { | |
| "name": "name111" | |
| }, | |
| { | |
| "name": "name112" | |
| }, | |
| { | |
| "name": "name113" | |
| }, | |
| { | |
| "name": "name114" | |
| }, | |
| { | |
| "name": "name115" | |
| }, | |
| { | |
| "name": "name116" | |
| }, | |
| { | |
| "name": "name117" | |
| }, | |
| { | |
| "name": "name118" | |
| }, | |
| { | |
| "name": "name119" | |
| }, | |
| { | |
| "name": "name120" | |
| }, | |
| { | |
| "name": "name121" | |
| }, | |
| { | |
| "name": "name122" | |
| }, | |
| { | |
| "name": "name123" | |
| }, | |
| { | |
| "name": "name124" | |
| }, | |
| { | |
| "name": "name125" | |
| }, | |
| { | |
| "name": "name126" | |
| }, | |
| { | |
| "name": "name127" | |
| }, | |
| { | |
| "name": "name128" | |
| }, | |
| { | |
| "name": "name129" | |
| }, | |
| { | |
| "name": "name130" | |
| }, | |
| { | |
| "name": "name131" | |
| }, | |
| { | |
| "name": "name132" | |
| }, | |
| { | |
| "name": "name133" | |
| }, | |
| { | |
| "name": "name134" | |
| }, | |
| { | |
| "name": "name135" | |
| }, | |
| { | |
| "name": "name136" | |
| }, | |
| { | |
| "name": "name137" | |
| }, | |
| { | |
| "name": "name138" | |
| }, | |
| { | |
| "name": "name139" | |
| }, | |
| { | |
| "name": "name140" | |
| }, | |
| { | |
| "name": "name141" | |
| }, | |
| { | |
| "name": "name142" | |
| }, | |
| { | |
| "name": "name143" | |
| }, | |
| { | |
| "name": "name144" | |
| }, | |
| { | |
| "name": "name145" | |
| }, | |
| { | |
| "name": "name146" | |
| }, | |
| { | |
| "name": "name147" | |
| }, | |
| { | |
| "name": "name148" | |
| }, | |
| { | |
| "name": "name149" | |
| }, | |
| { | |
| "name": "name150" | |
| }, | |
| { | |
| "name": "name151" | |
| }, | |
| { | |
| "name": "name152" | |
| }, | |
| { | |
| "name": "name153" | |
| }, | |
| { | |
| "name": "name154" | |
| }, | |
| { | |
| "name": "name155" | |
| }, | |
| { | |
| "name": "name156" | |
| }, | |
| { | |
| "name": "name157" | |
| }, | |
| { | |
| "name": "name158" | |
| }, | |
| { | |
| "name": "name159" | |
| }, | |
| { | |
| "name": "name160" | |
| }, | |
| { | |
| "name": "name161" | |
| }, | |
| { | |
| "name": "name162" | |
| }, | |
| { | |
| "name": "name163" | |
| }, | |
| { | |
| "name": "name164" | |
| }, | |
| { | |
| "name": "name165" | |
| }, | |
| { | |
| "name": "name166" | |
| }, | |
| { | |
| "name": "name167" | |
| }, | |
| { | |
| "name": "name168" | |
| }, | |
| { | |
| "name": "name169" | |
| }, | |
| { | |
| "name": "name170" | |
| }, | |
| { | |
| "name": "name171" | |
| }, | |
| { | |
| "name": "name172" | |
| }, | |
| { | |
| "name": "name173" | |
| }, | |
| { | |
| "name": "name174" | |
| }, | |
| { | |
| "name": "name175" | |
| }, | |
| { | |
| "name": "name176" | |
| }, | |
| { | |
| "name": "name177" | |
| }, | |
| { | |
| "name": "name178" | |
| }, | |
| { | |
| "name": "name179" | |
| }, | |
| { | |
| "name": "name180" | |
| }, | |
| { | |
| "name": "name181" | |
| }, | |
| { | |
| "name": "name182" | |
| }, | |
| { | |
| "name": "name183" | |
| }, | |
| { | |
| "name": "name184" | |
| }, | |
| { | |
| "name": "name185" | |
| }, | |
| { | |
| "name": "name186" | |
| }, | |
| { | |
| "name": "name187" | |
| }, | |
| { | |
| "name": "name188" | |
| }, | |
| { | |
| "name": "name189" | |
| }, | |
| { | |
| "name": "name190" | |
| }, | |
| { | |
| "name": "name191" | |
| }, | |
| { | |
| "name": "name192" | |
| }, | |
| { | |
| "name": "name193" | |
| }, | |
| { | |
| "name": "name194" | |
| }, | |
| { | |
| "name": "name195" | |
| }, | |
| { | |
| "name": "name196" | |
| }, | |
| { | |
| "name": "name197" | |
| }, | |
| { | |
| "name": "name198" | |
| }, | |
| { | |
| "name": "name199" | |
| }, | |
| { | |
| "name": "name200" | |
| }, | |
| { | |
| "name": "name201" | |
| }, | |
| { | |
| "name": "name202" | |
| } | |
| ], | |
| "name": "name103" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "name203", | |
| "children": [ | |
| { | |
| "children": [ | |
| { | |
| "name": "name205" | |
| }, | |
| { | |
| "name": "name206" | |
| }, | |
| { | |
| "name": "name207" | |
| }, | |
| { | |
| "name": "name208" | |
| }, | |
| { | |
| "name": "name209" | |
| }, | |
| { | |
| "name": "name210" | |
| }, | |
| { | |
| "name": "name211" | |
| }, | |
| { | |
| "name": "name212" | |
| }, | |
| { | |
| "name": "name213" | |
| }, | |
| { | |
| "name": "name214" | |
| }, | |
| { | |
| "name": "name215" | |
| }, | |
| { | |
| "name": "name216" | |
| }, | |
| { | |
| "name": "name217" | |
| }, | |
| { | |
| "name": "name218" | |
| }, | |
| { | |
| "name": "name219" | |
| }, | |
| { | |
| "name": "name220" | |
| }, | |
| { | |
| "name": "name221" | |
| }, | |
| { | |
| "name": "name222" | |
| }, | |
| { | |
| "name": "name223" | |
| }, | |
| { | |
| "name": "name224" | |
| }, | |
| { | |
| "name": "name225" | |
| }, | |
| { | |
| "name": "name226" | |
| }, | |
| { | |
| "name": "name227" | |
| }, | |
| { | |
| "name": "name228" | |
| }, | |
| { | |
| "name": "name229" | |
| }, | |
| { | |
| "name": "name230" | |
| }, | |
| { | |
| "name": "name231" | |
| }, | |
| { | |
| "name": "name232" | |
| }, | |
| { | |
| "name": "name233" | |
| }, | |
| { | |
| "name": "name234" | |
| }, | |
| { | |
| "name": "name235" | |
| }, | |
| { | |
| "name": "name236" | |
| }, | |
| { | |
| "name": "name237" | |
| }, | |
| { | |
| "name": "name238" | |
| }, | |
| { | |
| "name": "name239" | |
| }, | |
| { | |
| "name": "name240" | |
| }, | |
| { | |
| "name": "name241" | |
| }, | |
| { | |
| "name": "name242" | |
| }, | |
| { | |
| "name": "name243" | |
| }, | |
| { | |
| "name": "name244" | |
| }, | |
| { | |
| "name": "name245" | |
| }, | |
| { | |
| "name": "name246" | |
| }, | |
| { | |
| "name": "name247" | |
| }, | |
| { | |
| "name": "name248" | |
| }, | |
| { | |
| "name": "name249" | |
| }, | |
| { | |
| "name": "name250" | |
| }, | |
| { | |
| "name": "name251" | |
| }, | |
| { | |
| "name": "name252" | |
| }, | |
| { | |
| "name": "name253" | |
| }, | |
| { | |
| "name": "name254" | |
| }, | |
| { | |
| "name": "name255" | |
| }, | |
| { | |
| "name": "name256" | |
| }, | |
| { | |
| "name": "name257" | |
| }, | |
| { | |
| "name": "name258" | |
| }, | |
| { | |
| "name": "name259" | |
| }, | |
| { | |
| "name": "name260" | |
| }, | |
| { | |
| "name": "name261" | |
| }, | |
| { | |
| "name": "name262" | |
| }, | |
| { | |
| "name": "name263" | |
| }, | |
| { | |
| "name": "name264" | |
| }, | |
| { | |
| "name": "name265" | |
| }, | |
| { | |
| "name": "name266" | |
| }, | |
| { | |
| "name": "name267" | |
| }, | |
| { | |
| "name": "name268" | |
| }, | |
| { | |
| "name": "name269" | |
| }, | |
| { | |
| "name": "name270" | |
| }, | |
| { | |
| "name": "name271" | |
| }, | |
| { | |
| "name": "name272" | |
| }, | |
| { | |
| "name": "name273" | |
| }, | |
| { | |
| "name": "name274" | |
| }, | |
| { | |
| "name": "name275" | |
| }, | |
| { | |
| "name": "name276" | |
| }, | |
| { | |
| "name": "name277" | |
| }, | |
| { | |
| "name": "name278" | |
| }, | |
| { | |
| "name": "name279" | |
| }, | |
| { | |
| "name": "name280" | |
| }, | |
| { | |
| "name": "name281" | |
| }, | |
| { | |
| "name": "name282" | |
| }, | |
| { | |
| "name": "name283" | |
| }, | |
| { | |
| "name": "name284" | |
| }, | |
| { | |
| "name": "name285" | |
| }, | |
| { | |
| "name": "name286" | |
| }, | |
| { | |
| "name": "name287" | |
| }, | |
| { | |
| "name": "name288" | |
| }, | |
| { | |
| "name": "name289" | |
| }, | |
| { | |
| "name": "name290" | |
| }, | |
| { | |
| "name": "name291" | |
| }, | |
| { | |
| "name": "name292" | |
| }, | |
| { | |
| "name": "name293" | |
| }, | |
| { | |
| "name": "name294" | |
| }, | |
| { | |
| "name": "name295" | |
| }, | |
| { | |
| "name": "name296" | |
| }, | |
| { | |
| "name": "name297" | |
| }, | |
| { | |
| "name": "name298" | |
| }, | |
| { | |
| "name": "name299" | |
| }, | |
| { | |
| "name": "name300" | |
| }, | |
| { | |
| "name": "name301" | |
| }, | |
| { | |
| "name": "name302" | |
| }, | |
| { | |
| "name": "name303" | |
| } | |
| ], | |
| "name": "name204" | |
| }, | |
| { | |
| "children": [ | |
| { | |
| "name": "name305" | |
| }, | |
| { | |
| "name": "name306" | |
| }, | |
| { | |
| "name": "name307" | |
| }, | |
| { | |
| "name": "name308" | |
| }, | |
| { | |
| "name": "name309" | |
| }, | |
| { | |
| "name": "name310" | |
| }, | |
| { | |
| "name": "name311" | |
| }, | |
| { | |
| "name": "name312" | |
| }, | |
| { | |
| "name": "name313" | |
| }, | |
| { | |
| "name": "name314" | |
| }, | |
| { | |
| "name": "name315" | |
| }, | |
| { | |
| "name": "name316" | |
| }, | |
| { | |
| "name": "name317" | |
| }, | |
| { | |
| "name": "name318" | |
| }, | |
| { | |
| "name": "name319" | |
| }, | |
| { | |
| "name": "name320" | |
| }, | |
| { | |
| "name": "name321" | |
| }, | |
| { | |
| "name": "name322" | |
| }, | |
| { | |
| "name": "name323" | |
| }, | |
| { | |
| "name": "name324" | |
| }, | |
| { | |
| "name": "name325" | |
| }, | |
| { | |
| "name": "name326" | |
| }, | |
| { | |
| "name": "name327" | |
| }, | |
| { | |
| "name": "name328" | |
| }, | |
| { | |
| "name": "name329" | |
| }, | |
| { | |
| "name": "name330" | |
| }, | |
| { | |
| "name": "name331" | |
| }, | |
| { | |
| "name": "name332" | |
| }, | |
| { | |
| "name": "name333" | |
| }, | |
| { | |
| "name": "name334" | |
| }, | |
| { | |
| "name": "name335" | |
| }, | |
| { | |
| "name": "name336" | |
| }, | |
| { | |
| "name": "name337" | |
| }, | |
| { | |
| "name": "name338" | |
| }, | |
| { | |
| "name": "name339" | |
| }, | |
| { | |
| "name": "name340" | |
| }, | |
| { | |
| "name": "name341" | |
| }, | |
| { | |
| "name": "name342" | |
| }, | |
| { | |
| "name": "name343" | |
| }, | |
| { | |
| "name": "name344" | |
| }, | |
| { | |
| "name": "name345" | |
| }, | |
| { | |
| "name": "name346" | |
| }, | |
| { | |
| "name": "name347" | |
| }, | |
| { | |
| "name": "name348" | |
| }, | |
| { | |
| "name": "name349" | |
| }, | |
| { | |
| "name": "name350" | |
| }, | |
| { | |
| "name": "name351" | |
| }, | |
| { | |
| "name": "name352" | |
| }, | |
| { | |
| "name": "name353" | |
| }, | |
| { | |
| "name": "name354" | |
| }, | |
| { | |
| "name": "name355" | |
| }, | |
| { | |
| "name": "name356" | |
| }, | |
| { | |
| "name": "name357" | |
| }, | |
| { | |
| "name": "name358" | |
| }, | |
| { | |
| "name": "name359" | |
| }, | |
| { | |
| "name": "name360" | |
| }, | |
| { | |
| "name": "name361" | |
| }, | |
| { | |
| "name": "name362" | |
| }, | |
| { | |
| "name": "name363" | |
| }, | |
| { | |
| "name": "name364" | |
| }, | |
| { | |
| "name": "name365" | |
| }, | |
| { | |
| "name": "name366" | |
| }, | |
| { | |
| "name": "name367" | |
| }, | |
| { | |
| "name": "name368" | |
| }, | |
| { | |
| "name": "name369" | |
| }, | |
| { | |
| "name": "name370" | |
| }, | |
| { | |
| "name": "name371" | |
| }, | |
| { | |
| "name": "name372" | |
| }, | |
| { | |
| "name": "name373" | |
| }, | |
| { | |
| "name": "name374" | |
| }, | |
| { | |
| "name": "name375" | |
| }, | |
| { | |
| "name": "name376" | |
| }, | |
| { | |
| "name": "name377" | |
| }, | |
| { | |
| "name": "name378" | |
| }, | |
| { | |
| "name": "name379" | |
| }, | |
| { | |
| "name": "name380" | |
| }, | |
| { | |
| "name": "name381" | |
| }, | |
| { | |
| "name": "name382" | |
| }, | |
| { | |
| "name": "name383" | |
| }, | |
| { | |
| "name": "name384" | |
| }, | |
| { | |
| "name": "name385" | |
| }, | |
| { | |
| "name": "name386" | |
| }, | |
| { | |
| "name": "name387" | |
| }, | |
| { | |
| "name": "name388" | |
| }, | |
| { | |
| "name": "name389" | |
| }, | |
| { | |
| "name": "name390" | |
| }, | |
| { | |
| "name": "name391" | |
| }, | |
| { | |
| "name": "name392" | |
| }, | |
| { | |
| "name": "name393" | |
| }, | |
| { | |
| "name": "name394" | |
| }, | |
| { | |
| "name": "name395" | |
| }, | |
| { | |
| "name": "name396" | |
| }, | |
| { | |
| "name": "name397" | |
| }, | |
| { | |
| "name": "name398" | |
| }, | |
| { | |
| "name": "name399" | |
| }, | |
| { | |
| "name": "name400" | |
| }, | |
| { | |
| "name": "name401" | |
| }, | |
| { | |
| "name": "name402" | |
| }, | |
| { | |
| "name": "name403" | |
| } | |
| ], | |
| "name": "name304" | |
| } | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "name404", | |
| "children": [ | |
| { | |
| "name": "name405", | |
| "children": [ | |
| { | |
| "name": "name406", | |
| "children": [ | |
| { | |
| "name": "name407" | |
| }, | |
| { | |
| "name": "name408" | |
| }, | |
| { | |
| "name": "name409" | |
| }, | |
| { | |
| "name": "name410" | |
| }, | |
| { | |
| "name": "name411" | |
| }, | |
| { | |
| "name": "name412" | |
| }, | |
| { | |
| "name": "name413" | |
| }, | |
| { | |
| "name": "name414" | |
| }, | |
| { | |
| "name": "name415" | |
| }, | |
| { | |
| "name": "name416" | |
| }, | |
| { | |
| "name": "name417" | |
| }, | |
| { | |
| "name": "name418" | |
| }, | |
| { | |
| "name": "name419" | |
| }, | |
| { | |
| "name": "name420" | |
| }, | |
| { | |
| "name": "name421" | |
| }, | |
| { | |
| "name": "name422" | |
| }, | |
| { | |
| "name": "name423" | |
| }, | |
| { | |
| "name": "name424" | |
| }, | |
| { | |
| "name": "name425" | |
| }, | |
| { | |
| "name": "name426" | |
| }, | |
| { | |
| "name": "name427" | |
| }, | |
| { | |
| "name": "name428" | |
| }, | |
| { | |
| "name": "name429" | |
| }, | |
| { | |
| "name": "name430" | |
| }, | |
| { | |
| "name": "name431" | |
| }, | |
| { | |
| "name": "name432" | |
| }, | |
| { | |
| "name": "name433" | |
| }, | |
| { | |
| "name": "name434" | |
| }, | |
| { | |
| "name": "name435" | |
| }, | |
| { | |
| "name": "name436" | |
| }, | |
| { | |
| "name": "name437" | |
| }, | |
| { | |
| "name": "name438" | |
| }, | |
| { | |
| "name": "name439" | |
| }, | |
| { | |
| "name": "name440" | |
| }, | |
| { | |
| "name": "name441" | |
| }, | |
| { | |
| "name": "name442" | |
| }, | |
| { | |
| "name": "name443" | |
| }, | |
| { | |
| "name": "name444" | |
| }, | |
| { | |
| "name": "name445" | |
| }, | |
| { | |
| "name": "name446" | |
| }, | |
| { | |
| "name": "name447" | |
| }, | |
| { | |
| "name": "name448" | |
| }, | |
| { | |
| "name": "name449" | |
| }, | |
| { | |
| "name": "name450" | |
| }, | |
| { | |
| "name": "name451" | |
| }, | |
| { | |
| "name": "name452" | |
| }, | |
| { | |
| "name": "name453" | |
| }, | |
| { | |
| "name": "name454" | |
| }, | |
| { | |
| "name": "name455" | |
| }, | |
| { | |
| "name": "name456" | |
| }, | |
| { | |
| "name": "name457" | |
| }, | |
| { | |
| "name": "name458" | |
| }, | |
| { | |
| "name": "name459" | |
| }, | |
| { | |
| "name": "name460" | |
| }, | |
| { | |
| "name": "name461" | |
| }, | |
| { | |
| "name": "name462" | |
| }, | |
| { | |
| "name": "name463" | |
| }, | |
| { | |
| "name": "name464" | |
| }, | |
| { | |
| "name": "name465" | |
| }, | |
| { | |
| "name": "name466" | |
| }, | |
| { | |
| "name": "name467" | |
| }, | |
| { | |
| "name": "name468" | |
| }, | |
| { | |
| "name": "name469" | |
| }, | |
| { | |
| "name": "name470" | |
| }, | |
| { | |
| "name": "name471" | |
| }, | |
| { | |
| "name": "name472" | |
| }, | |
| { | |
| "name": "name473" | |
| }, | |
| { | |
| "name": "name474" | |
| }, | |
| { | |
| "name": "name475" | |
| }, | |
| { | |
| "name": "name476" | |
| }, | |
| { | |
| "name": "name477" | |
| }, | |
| { | |
| "name": "name478" | |
| }, | |
| { | |
| "name": "name479" | |
| }, | |
| { | |
| "name": "name480" | |
| }, | |
| { | |
| "name": "name481" | |
| }, | |
| { | |
| "name": "name482" | |
| }, | |
| { | |
| "name": "name483" | |
| }, | |
| { | |
| "name": "name484" | |
| }, | |
| { | |
| "name": "name485" | |
| }, | |
| { | |
| "name": "name486" | |
| }, | |
| { | |
| "name": "name487" | |
| }, | |
| { | |
| "name": "name488" | |
| }, | |
| { | |
| "name": "name489" | |
| }, | |
| { | |
| "name": "name490" | |
| }, | |
| { | |
| "name": "name491" | |
| }, | |
| { | |
| "name": "name492" | |
| }, | |
| { | |
| "name": "name493" | |
| }, | |
| { | |
| "name": "name494" | |
| }, | |
| { | |
| "name": "name495" | |
| }, | |
| { | |
| "name": "name496" | |
| }, | |
| { | |
| "name": "name497" | |
| }, | |
| { | |
| "name": "name498" | |
| }, | |
| { | |
| "name": "name499" | |
| }, | |
| { | |
| "name": "name500" | |
| }, | |
| { | |
| "name": "name501" | |
| }, | |
| { | |
| "name": "name502" | |
| }, | |
| { | |
| "name": "name503" | |
| }, | |
| { | |
| "name": "name504" | |
| }, | |
| { | |
| "name": "name505" | |
| } | |
| ] | |
| } | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "name506", | |
| "children": [ | |
| { | |
| "name": "name507" | |
| }, | |
| { | |
| "name": "name508" | |
| }, | |
| { | |
| "name": "name509" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "name510", | |
| "children": [ | |
| { | |
| "name": "name511" | |
| }, | |
| { | |
| "name": "name512" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "name513", | |
| "children": [ | |
| { | |
| "name": "name514" | |
| }, | |
| { | |
| "name": "name515" | |
| } | |
| ] | |
| } | |
| ] | |
| } |
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <style> | |
| body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class=""> | |
| <div id="myGraph"></div> | |
| </div> | |
| <script> | |
| d3.json('data.json', data => { | |
| networkChart = renderChartCollapsibleNetwork() | |
| .svgHeight(window.innerHeight - 30) | |
| .svgWidth(window.innerWidth - 30) | |
| .container('#myGraph') | |
| .data({ root: data }) | |
| .debug(true) | |
| .run() | |
| }) | |
| </script> | |
| <script> | |
| /* | |
| This code is based on following convention: | |
| https://github.com/bumbeishvili/d3-coding-conventions | |
| */ | |
| function renderChartCollapsibleNetwork(params) { | |
| // exposed variables | |
| var attrs = { | |
| id: 'id' + Math.floor(Math.random() * 1000000), | |
| svgWidth: 960, | |
| svgHeight: 600, | |
| marginTop: 0, | |
| marginBottom: 5, | |
| marginRight: 0, | |
| marginLeft: 30, | |
| nodeRadius: 18, | |
| container: 'body', | |
| distance: 100, | |
| hiddenChildLevel: 1, | |
| //hiddenChildLevel: 5, | |
| nodeStroke: '#41302D', | |
| nodeTextColor: '#E5E5E5', | |
| linkColor: '#303030', | |
| activeLinkColor: "blue", | |
| hoverOpacity: 0.2, | |
| maxTextDisplayZoomLevel: 1, | |
| textDisplayed: true, | |
| lineStrokeWidth: 1.5, | |
| data: null | |
| }; | |
| /*############### IF EXISTS OVERWRITE ATTRIBUTES FROM PASSED PARAM ####### */ | |
| var attrKeys = Object.keys(attrs); | |
| attrKeys.forEach(function (key) { | |
| if (params && params[key]) { | |
| attrs[key] = params[key]; | |
| } | |
| }) | |
| //innerFunctions which will update visuals | |
| var updateData; | |
| var filter; | |
| //main chart object | |
| var main = function (selection) { | |
| selection.each(function scope() { | |
| //calculated properties | |
| var calc = {} | |
| calc.chartLeftMargin = attrs.marginLeft; | |
| calc.chartTopMargin = attrs.marginTop; | |
| calc.chartWidth = attrs.svgWidth - attrs.marginRight - calc.chartLeftMargin; | |
| calc.chartHeight = attrs.svgHeight - attrs.marginBottom - calc.chartTopMargin; | |
| //########################## HIERARCHY STUFF ######################### | |
| var hierarchy = {}; | |
| hierarchy.root = d3.hierarchy(attrs.data.root); | |
| //########################### BEHAVIORS ######################### | |
| var behaviors = {}; | |
| behaviors.zoom = d3.zoom().scaleExtent([0.75, 100, 8]).on('zoom', zoomed); | |
| behaviors.drag = d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended); | |
| //########################### LAYOUTS ######################### | |
| var layouts = {}; | |
| // custom radial kayout | |
| layouts.radial = d3.radial(); | |
| //########################### FORCE STUFF ######################### | |
| var force = {}; | |
| force.link = d3.forceLink().id(d => d.id); | |
| force.charge = d3.forceManyBody() | |
| force.center = d3.forceCenter(calc.chartWidth / 2, calc.chartHeight / 2) | |
| // prevent collide | |
| force.collide = d3.forceCollide().radius(d => { | |
| // if parent has many children, reduce collide strength | |
| if (d.parent) { | |
| if (d.parent.children.length > 10) { | |
| // also slow down node movement | |
| slowDownNodes(); | |
| return 7; | |
| } | |
| } | |
| // increase collide strength | |
| if (d.children && d.depth > 2) { | |
| return attrs.nodeRadius; | |
| } | |
| return attrs.nodeRadius * 2; | |
| }); | |
| //manually set x positions (which is calculated using custom radial layout) | |
| force.x = d3.forceX() | |
| .strength(0.5) | |
| .x(function (d, i) { | |
| // if node does not have children and is channel (depth=2) , then position it on parent's coordinate | |
| if (!d.children && d.depth > 2) { | |
| if (d.parent) { | |
| d = d.parent | |
| } | |
| } | |
| // custom circle projection - radius will be - (d.depth - 1) * 150 | |
| return projectCircle(d.proportion, (d.depth - 1) * 150)[0]; | |
| }); | |
| //manually set y positions (which is calculated using d3.cluster) | |
| force.y = d3.forceY() | |
| .strength(0.5) | |
| .y(function (d, i) { | |
| // if node does not have children and is channel (depth=2) , then position it on parent's coordinate | |
| if (!d.children && d.depth > 2) { | |
| if (d.parent) { | |
| d = d.parent | |
| } | |
| } | |
| // custom circle projection - radius will be - (d.depth - 1) * 150 | |
| return projectCircle(d.proportion, (d.depth - 1) * 150)[1]; | |
| }) | |
| //--------------------------------- INITIALISE FORCE SIMULATION ---------------------------- | |
| // get based on top parameter simulation | |
| force.simulation = d3.forceSimulation() | |
| .force('link', force.link) | |
| .force('charge', force.charge) | |
| .force('center', force.center) | |
| .force("collide", force.collide) | |
| .force('x', force.x) | |
| .force('y', force.y) | |
| //########################### HIERARCHY STUFF ######################### | |
| // flatten root | |
| var arr = flatten(hierarchy.root); | |
| // hide members based on their depth | |
| arr.forEach(d => { | |
| if (d.depth > attrs.hiddenChildLevel) { | |
| d._children = d.children; | |
| d.children = null; | |
| } | |
| }) | |
| //#################################### DRAWINGS ####################### | |
| //drawing containers | |
| var container = d3.select(this); | |
| //add svg | |
| var svg = container.patternify({ tag: 'svg', selector: 'svg-chart-container' }) | |
| .attr('width', attrs.svgWidth) | |
| .attr('height', attrs.svgHeight) | |
| .call(behaviors.zoom) | |
| //add container g element | |
| var chart = svg.patternify({ tag: 'g', selector: 'chart' }) | |
| .attr('transform', 'translate(' + (calc.chartLeftMargin) + ',' + calc.chartTopMargin + ')'); | |
| //################################ Chart Content Drawing ################################## | |
| //link wrapper | |
| var linksWrapper = chart.patternify({ tag: 'g', selector: 'links-wrapper' }) | |
| //node wrapper | |
| var nodesWrapper = chart.patternify({ tag: 'g', selector: 'nodes-wrapper' }) | |
| var nodes, links, enteredNodes; | |
| // reusable function which updates visual based on data change | |
| update(); | |
| //update visual based on data change | |
| function update(clickedNode) { | |
| // set xy and proportion properties with custom radial layout | |
| layouts.radial(hierarchy.root); | |
| //nodes and links array | |
| var nodesArr = flatten(hierarchy.root, true) | |
| .orderBy(d => d.depth) | |
| .filter(d => !d.hidden); | |
| var linksArr = hierarchy.root.links() | |
| .filter(d => !d.source.hidden) | |
| .filter(d => !d.target.hidden) | |
| // make new nodes to appear near the parents | |
| nodesArr.forEach(function (d, i) { | |
| if (clickedNode && clickedNode.id == (d.parent && d.parent.id)) { | |
| d.x = d.parent.x; | |
| d.y = d.parent.y; | |
| } | |
| }); | |
| //links | |
| links = linksWrapper.selectAll('.link').data(linksArr, d => d.target.id); | |
| links.exit().remove(); | |
| links = links.enter() | |
| .append('line') | |
| .attr('class', 'link') | |
| .merge(links).attr('stroke', '#9ecae1'); | |
| links.attr('stroke', attrs.linkColor).attr('stroke-width', attrs.lineStrokeWidth) | |
| //node groups | |
| nodes = nodesWrapper.selectAll('.node').data(nodesArr, d => d.id); | |
| var exited = nodes.exit().remove(); | |
| var enteredNodes = nodes.enter() | |
| .append('g') | |
| .attr('class', 'node') | |
| //bind event handlers | |
| enteredNodes.on('click', nodeClick) | |
| .on('mouseenter', nodeMouseEnter) | |
| .on('mouseleave', nodeMouseLeave) | |
| .call(behaviors.drag) | |
| //node texts | |
| enteredNodes.append('text').attr('class', 'node-texts') | |
| .attr('x', 30).attr('fill', attrs.nodeTextColor) | |
| .text(d => d.data.name) | |
| .style('display', attrs.textDisplayed ? "initial" : "none") | |
| //channels grandchildren | |
| var channelsGrandchildren = enteredNodes | |
| .append("circle") | |
| .attr('r', 7) | |
| .attr('stroke-width', 5) | |
| .attr('stroke', attrs.nodeStroke) | |
| //merge node groups and style it | |
| nodes = enteredNodes.merge(nodes); | |
| nodes | |
| .attr('fill', d => { | |
| return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c"; | |
| }) | |
| .style('cursor', 'pointer') | |
| //force simulation | |
| force.simulation.nodes(nodesArr) | |
| .on('tick', ticked); | |
| // links simulation | |
| force.simulation.force("link").links(links).id(d => d.id).distance(100).strength(d => 1); | |
| } | |
| //####################################### EVENT HANDLERS ######################## | |
| // zoom handler | |
| function zoomed() { | |
| //get transform event | |
| var transform = d3.event.transform; | |
| attrs.lastTransform = transform; | |
| // apply transform event props to the wrapper | |
| chart.attr('transform', transform) | |
| svg.selectAll('.node').attr("transform", function (d) { return `translate(${d.x},${d.y}) scale(${1 / (attrs.lastTransform ? attrs.lastTransform.k : 1)})`; }); | |
| svg.selectAll('.link').attr("stroke-width", attrs.lineStrokeWidth / (attrs.lastTransform ? attrs.lastTransform.k : 1)); | |
| // hide texts if zooming is less than certain level | |
| if (transform.k < attrs.maxTextDisplayZoomLevel) { | |
| svg.selectAll('.node-texts').style('display', 'none'); | |
| attrs.textDisplayed = false; | |
| } else { | |
| svg.selectAll('.node-texts').style('display', 'initial'); | |
| attrs.textDisplayed = true; | |
| } | |
| } | |
| //tick handler | |
| function ticked() { | |
| // set links position | |
| links.attr("x1", function (d) { return d.source.x; }) | |
| .attr("y1", function (d) { return d.source.y; }) | |
| .attr("x2", function (d) { return d.target.x; }) | |
| .attr("y2", function (d) { return d.target.y; }); | |
| //set nodes position | |
| svg.selectAll('.node').attr("transform", function (d) { return `translate(${d.x},${d.y}) scale(${1 / (attrs.lastTransform ? attrs.lastTransform.k : 1)})`; }); | |
| } | |
| //handler drag start event | |
| function dragstarted(d) { | |
| //disable node fixing | |
| nodes.each(d => { d.fx = null; d.fy = null }) | |
| } | |
| // handle dragging event | |
| function dragged(d) { | |
| // make dragged node fixed | |
| d.fx = d3.event.x; | |
| d.fy = d3.event.y; | |
| } | |
| //-------------------- handle drag end event --------------- | |
| function dragended(d) { | |
| // we are doing nothing, here , aren't we? | |
| } | |
| //-------------------------- node mouse hover handler --------------- | |
| function nodeMouseEnter(d) { | |
| //get hovered node | |
| var node = d3.select(this); | |
| //get links | |
| var links = hierarchy.root.links(); | |
| //get hovered node connected links | |
| var connectedLinks = links.filter(l => l.source.id == d.id || l.target.id == d.id); | |
| //get hovered node linked nodes | |
| var linkedNodes = connectedLinks.map(s => s.source.id).concat(connectedLinks.map(d => d.target.id)) | |
| //reduce all other nodes opacity | |
| nodesWrapper.selectAll('.node') | |
| .filter(n => linkedNodes.indexOf(n.id) == -1) | |
| .attr('opacity', attrs.hoverOpacity); | |
| //reduce all other links opacity | |
| linksWrapper.selectAll('.link').attr('opacity', attrs.hoverOpacity); | |
| //highlight hovered nodes connections | |
| linksWrapper.selectAll('.link') | |
| .filter(l => l.source.id == d.id || l.target.id == d.id) | |
| .attr('opacity', 1) | |
| .attr('stroke', attrs.activeLinkColor) | |
| } | |
| // --------------- handle mouseleave event --------------- | |
| function nodeMouseLeave(d) { | |
| // return things back to normal | |
| nodesWrapper.selectAll('.node').attr('opacity', 1); | |
| linksWrapper.selectAll('.link').attr('opacity', 1).attr('stroke', attrs.linkColor) | |
| } | |
| // --------------- handle node click event --------------- | |
| function nodeClick(d) { | |
| //free fixed nodes | |
| nodes.each(d => { d.fx = null; d.fy = null }) | |
| // collapse or expand node | |
| if (d.children) { | |
| d._children = d.children; | |
| d.children = null; | |
| update(); | |
| force.simulation.restart(); | |
| force.simulation.alphaTarget(0.15); | |
| } else if (d._children) { | |
| d.children = d._children; | |
| d._children = null; | |
| update(d); | |
| force.simulation.restart(); | |
| force.simulation.alphaTarget(0.15); | |
| } else { | |
| //nothing is to collapse or expand | |
| } | |
| freeNodes(); | |
| } | |
| //######################################### UTIL FUNCS ################################## | |
| updateData = function () { | |
| main.run(); | |
| } | |
| function slowDownNodes() { | |
| force.simulation.alphaTarget(0.05); | |
| }; | |
| function speedUpNodes() { | |
| force.simulation.alphaTarget(0.45); | |
| } | |
| function freeNodes() { | |
| d3.selectAll('.node').each(n => { n.fx = null; n.fy = null; }) | |
| } | |
| function projectCircle(value, radius) { | |
| var r = radius || 0; | |
| var corner = value * 2 * Math.PI; | |
| return [Math.sin(corner) * r, -Math.cos(corner) * r] | |
| } | |
| //recursively loop on children and extract nodes as an array | |
| function flatten(root, clustered) { | |
| var nodesArray = []; | |
| var i = 0; | |
| function recurse(node, depth) { | |
| if (node.children) | |
| node.children.forEach(function (child) { | |
| recurse(child, depth + 1); | |
| }); | |
| if (!node.id) node.id = ++i; | |
| else ++i; | |
| node.depth = depth; | |
| if (clustered) { | |
| if (!node.cluster) { | |
| // if cluster coordinates are not set, set it | |
| node.cluster = { x: node.x, y: node.y } | |
| } | |
| } | |
| nodesArray.push(node); | |
| } | |
| recurse(root, 1); | |
| return nodesArray; | |
| } | |
| function debug() { | |
| if (attrs.isDebug) { | |
| //stringify func | |
| var stringified = scope + ""; | |
| // parse variable names | |
| var groupVariables = stringified | |
| //match var x-xx= {}; | |
| .match(/var\s+([\w])+\s*=\s*{\s*}/gi) | |
| //match xxx | |
| .map(d => d.match(/\s+\w*/gi).filter(s => s.trim())) | |
| //get xxx | |
| .map(v => v[0].trim()) | |
| //assign local variables to the scope | |
| groupVariables.forEach(v => { | |
| main['P_' + v] = eval(v) | |
| }) | |
| } | |
| } | |
| debug(); | |
| }); | |
| }; | |
| //----------- PROTOTYEPE FUNCTIONS ---------------------- | |
| d3.selection.prototype.patternify = function (params) { | |
| var container = this; | |
| var selector = params.selector; | |
| var elementTag = params.tag; | |
| var data = params.data || [selector]; | |
| // pattern in action | |
| var selection = container.selectAll('.' + selector).data(data) | |
| selection.exit().remove(); | |
| selection = selection.enter().append(elementTag).merge(selection) | |
| selection.attr('class', selector); | |
| return selection; | |
| } | |
| // custom radial layout | |
| d3.radial = function () { | |
| return function setProportions(root) { | |
| recurse(root, 0, 1); | |
| function recurse(node, min, max) { | |
| node.proportion = (max + min) / 2; | |
| if (!node.x) { | |
| // if node has parent, match entered node positions to it's parent | |
| if (node.parent) { | |
| node.x = node.parent.x; | |
| } else { | |
| node.x = 0; | |
| } | |
| } | |
| // if node had parent, match entered node positions to it's parent | |
| if (!node.y) { | |
| if (node.parent) { | |
| node.y = node.parent.y; | |
| } else { | |
| node.y = 0; | |
| } | |
| } | |
| //recursively do the same for children | |
| if (node.children) { | |
| var offset = (max - min) / node.children.length; | |
| node.children.forEach(function (child, i, arr) { | |
| var newMin = min + offset * i; | |
| var newMax = newMin + offset; | |
| recurse(child, newMin, newMax); | |
| }); | |
| } | |
| } | |
| } | |
| } | |
| //https://github.com/bumbeishvili/d3js-boilerplates#orderby | |
| Array.prototype.orderBy = function (func) { | |
| this.sort((a, b) => { | |
| var a = func(a); | |
| var b = func(b); | |
| if (typeof a === 'string' || a instanceof String) { | |
| return a.localeCompare(b); | |
| } | |
| return a - b; | |
| }); | |
| return this; | |
| } | |
| //########################## BOILEPLATE STUFF ################ | |
| //dinamic keys functions | |
| Object.keys(attrs).forEach(key => { | |
| // Attach variables to main function | |
| return main[key] = function (_) { | |
| var string = `attrs['${key}'] = _`; | |
| if (!arguments.length) { return eval(` attrs['${key}'];`); } | |
| eval(string); | |
| return main; | |
| }; | |
| }); | |
| //set attrs as property | |
| main.attrs = attrs; | |
| //debugging visuals | |
| main.debug = function (isDebug) { | |
| attrs.isDebug = isDebug; | |
| if (isDebug) { | |
| if (!window.charts) window.charts = []; | |
| window.charts.push(main); | |
| } | |
| return main; | |
| } | |
| //exposed update functions | |
| main.data = function (value) { | |
| if (!arguments.length) return attrs.data; | |
| attrs.data = value; | |
| if (typeof updateData === 'function') { | |
| updateData(); | |
| } | |
| return main; | |
| } | |
| // run visual | |
| main.run = function () { | |
| d3.selectAll(attrs.container).call(main); | |
| return main; | |
| } | |
| main.filter = function (filterParams) { | |
| if (!arguments.length) return attrs.filterParams; | |
| attrs.filterParams = filterParams; | |
| if (typeof filter === 'function') { | |
| filter(); | |
| } | |
| return main; | |
| } | |
| return main; | |
| } | |
| </script> | |
| </body> |