A comparison of two forums analysed in the Cassandra project (Bluelight on the left, and Drugsforum on the right). Two hierarchies are visualized in a single treemap having a "fake" root (and two "fake children" used to create a padding between the two hierarchies).
| id | name | forum_parent_id | size | |
|---|---|---|---|---|
| 0 | Bluelight | null | 0 | |
| 11 | Closed: Bluelight Discussion | 0 | 25000 | |
| 13 | Announcements | 0 | 1899 | |
| 15 | Electronic Music Discussion | 0 | 24111 | |
| 16 | Basic Drug Discussion | 0 | 4224 | |
| 18 | General Archives | 0 | 8439 | |
| 19 | European & African Drug Discussion | 0 | 150938 | |
| 20 | Archive - Australian Drug Discussion | 45 | 159287 | |
| 21 | Archive - Words | 62 | 70342 | |
| 22 | MDMA & Empathogenic Drugs | 0 | 4898 | |
| 24 | Pillreports Discussion | 0 | 1183 | |
| 27 | Drugs in the Media | 0 | 119002 | |
| 29 | Archive - OD | 58 | 190701 | |
| 31 | North & South American Events | 0 | 12 | |
| 33 | Midwest USA | 31 | 9453 | |
| 37 | European & African Events | 0 | 1552 | |
| 39 | Australian Social & Events | 0 | 33728 | |
| 40 | Trip Reports | 0 | 46735 | |
| 41 | Philosophy and Spirituality | 0 | 40951 | |
| 42 | Drug FAQs | 0 | 188 | |
| 45 | Australian Drug Discussion | 0 | 98215 | |
| 47 | The Dark Side | 0 | 5867 | |
| 48 | Psychedelic Drugs | 0 | 20023 | |
| 50 | Current Events and Politics | 0 | 75119 | |
| 51 | Sex, Love and Relationships | 0 | 117591 | |
| 52 | Legal Discussion Archive | 0 | 8986 | |
| 57 | Second Opinion | 0 | 44034 | |
| 58 | Other Drugs | 0 | 34170 | |
| 59 | Archive - Australian Social | 39 | 113469 | |
| 60 | Archive - EMD | 15 | 22616 | |
| 61 | Archive - DC | 76 | 145245 | |
| 62 | Words | 0 | 27483 | |
| 64 | Archive - Healthy Living | 161 | 14855 | |
| 65 | Archive - ED | 22 | 93514 | |
| 68 | Archive - SLR | 51 | 27385 | |
| 70 | Cannabis Discussion | 0 | 6096 | |
| 71 | Archive - DITM | 27 | 36755 | |
| 72 | Archive - TDS | 47 | 101591 | |
| 73 | Archive - EADD | 19 | 498465 | |
| 76 | Drug Culture | 0 | 24460 | |
| 89 | Bluelight Shrine | 0 | 9587 | |
| 111 | Support | 0 | 12673 | |
| 119 | Best of Bluelight | 0 | 22113 | |
| 126 | Testing Grounds | 0 | 1609 | |
| 127 | Film & Television | 0 | 98276 | |
| 128 | Archive - P&S | 41 | 22993 | |
| 130 | Archive - NAE | 31 | 38282 | |
| 131 | Archive - CEP | 50 | 50194 | |
| 133 | Archive - BDD | 16 | 45139 | |
| 138 | North & South American Social & Drug Discussion | 0 | 55344 | |
| 143 | New Member Introductions | 0 | 1593 | |
| 144 | Harm Reduction | 0 | 625 | |
| 145 | Archive - SO | 57 | 65440 | |
| 146 | Archive - CD | 70 | 29338 | |
| 148 | Steroid Discussion | 0 | 27103 | |
| 149 | Archive - F&T | 127 | 11667 | |
| 150 | Education & Careers | 0 | 13288 | |
| 152 | Homeless Threads | 0 | 2199 | |
| 153 | Anonymous Posting | 0 | 991 | |
| 154 | Non-Electronic Music Discussion | 0 | 41829 | |
| 155 | Neuroscience and Pharmacology Discussion | 0 | 74829 | |
| 156 | Drug Testing Q&A | 16 | 1819 | |
| 159 | Pill Testing Q&A | 0 | 14508 | |
| 161 | Healthy Living | 0 | 57292 | |
| 162 | Archive - NEMD | 154 | 3089 | |
| 166 | Pill ID Archive | 156 | 2076 | |
| 167 | Archive - TR | 40 | 50465 | |
| 171 | Wiki | 0 | 855 | |
| 172 | Northeast USA | 31 | 3757 | |
| 173 | Other North and South American Regions | 31 | 2000 | |
| 176 | Global HR Workshop | 0 | 127 | |
| 178 | Science & Technology | 0 | 14332 | |
| 179 | Sports & Gaming | 0 | 41356 | |
| 180 | Drug Studies | 0 | 4128 | |
| 181 | Archive - NMI | 143 | 19109 | |
| 183 | Archive - Aus Events | 39 | 26132 | |
| 190 | Archive - E&C | 150 | 4912 | |
| 191 | Archive - S&T | 178 | 4856 | |
| 193 | Archive - NAS | 138 | 25841 | |
| 194 | Archive - NADD | 138 | 46523 | |
| 195 | Archive - S&G | 179 | 16330 | |
| 196 | Archive - SD | 148 | 3110 | |
| 215 | Reference Materials | 171 | 3183 | |
| 216 | Australian Pill Info Requests | 45 | 2096 | |
| 228 | Archive - PD | 48 | 99251 | |
| 262 | Archive - ADD | 155 | 28357 | |
| 263 | Drug Studies Archive | 180 | 0 | |
| 267 | Support Archive | 111 | 3853 | |
| 269 | Sober Living | 0 | 3269 | |
| 270 | Mental Health | 0 | 5100 | |
| 271 | Archive- Global HR Workshop | 176 | 232 | |
| 272 | Archive- Mental Health | 270 | 7446 | |
| 273 | Archives- Sober Living | 269 | 7572 | |
| 276 | MAPS Discussion | 0 | 279 | |
| 277 | Clinical Psychedelic Research & Medicine | 0 | 336 | |
| 278 | Psychedelic Harm Reduction | 0 | 960 | |
| 282 | Archive - MAPS Discussion | 276 | 0 | |
| 283 | Archive - Clinical Psychedelic Research & Medicine | 277 | 0 | |
| 284 | Archive - Psychedelic Harm Reduction | 278 | 0 |
| id | name | forum_parent_id | size | |
|---|---|---|---|---|
| 0 | Drugsforum | null | 0 | |
| 7 | Cannabis | 0 | 29411 | |
| 8 | Magic Mushrooms (Psilocybe & Amanita) | 0 | 650 | |
| 17 | Drug chemistry | 0 | 0 | |
| 18 | Alcohol | 0 | 18808 | |
| 19 | Amphetamine | 0 | 14365 | |
| 20 | Benzodiazepines | 50 | 22943 | |
| 21 | Research Chemicals | 0 | 14014 | |
| 22 | Cocaine & Crack | 0 | 33426 | |
| 23 | Herbal Ecstasy | 0 | 5324 | |
| 24 | Dissociatives | 0 | 995 | |
| 25 | LSD | 0 | 27596 | |
| 26 | Cannabis Experiences | 7 | 2438 | |
| 27 | Cannabis growing | 330 | 8334 | |
| 28 | Magic Mushroom use | 8 | 10949 | |
| 29 | Mushroom growing | 330 | 9607 | |
| 30 | Ecstasy & MDMA | 0 | 33775 | |
| 32 | Peyote & San Pedro | 40 | 5194 | |
| 33 | Opiates & Opioids | 0 | 24636 | |
| 35 | Salvia divinorum | 40 | 10050 | |
| 36 | GHB | 0 | 5523 | |
| 37 | Various drugs not covered by other forums | 0 | 7424 | |
| 38 | Other Drugs Chemistry | 17 | 0 | |
| 39 | Insights & Mystical | 70 | 12584 | |
| 40 | Ethnobotanicals | 0 | 11298 | |
| 41 | Law and order | 0 | 23154 | |
| 42 | Drug combinations | 71 | 12156 | |
| 43 | About Drugs-Forum.com | 0 | 1690 | |
| 45 | Sex and Drugs | 71 | 8479 | |
| 47 | Drogen-forum | 0 | 6 | |
| 49 | Some for all | 70 | 12681 | |
| 50 | Downers and sleeping pills | 0 | 9654 | |
| 51 | Funny shit | 70 | 8071 | |
| 52 | DMT and Ayahuasca | 40 | 8474 | |
| 53 | Miscellaneous News | 351 | 19792 | |
| 58 | Nieuws over drugs | 148 | 2490 | |
| 60 | Drug testing discussion | 71 | 8494 | |
| 61 | Kruiden & cactus | 149 | 372 | |
| 62 | Coffeeshops | 7 | 1034 | |
| 64 | Phenethylamine Chem | 17 | 0 | |
| 65 | Setup & precursors | 17 | 0 | |
| 66 | Opiate & Opioid Chem | 17 | 0 | |
| 67 | Tryptamine Chemistry | 17 | 0 | |
| 70 | Social Forums | 0 | 13161 | |
| 71 | The euphoric body | 0 | 10440 | |
| 74 | Drug culture | 70 | 12629 | |
| 75 | Drug Policy Reform & Narco Politics | 41 | 13070 | |
| 76 | Kratom | 40 | 19853 | |
| 79 | Amanita | 8 | 1196 | |
| 80 | DXM | 24 | 25936 | |
| 82 | Wiet & Hash | 149 | 303 | |
| 84 | DMT Extraction | 434 | 3782 | |
| 85 | Computers | 70 | 4201 | |
| 86 | GHB | 149 | 806 | |
| 87 | XTC | 149 | 589 | |
| 88 | Methamphetamine | 19 | 53051 | |
| 89 | Phenethylamines | 21 | 9669 | |
| 90 | Tryptamines | 21 | 4456 | |
| 91 | Piperazines | 21 | 984 | |
| 92 | Ketamine | 24 | 7143 | |
| 93 | LSA seeds | 40 | 6003 | |
| 106 | Cannabis paraphernalia | 7 | 5770 | |
| 107 | Antidepressants | 37 | 8526 | |
| 108 | LSD | 149 | 190 | |
| 109 | Research Chemicals | 149 | 934 | |
| 110 | Wiet kweken | 346 | 106 | |
| 111 | Cocaïne | 149 | 361 | |
| 112 | Speed | 149 | 491 | |
| 114 | Opiaten | 149 | 334 | |
| 115 | Diverse drugs | 149 | 1267 | |
| 117 | Nightshades | 40 | 1192 | |
| 118 | Kava-Kava | 40 | 2470 | |
| 119 | Nitrous Oxide | 24 | 3040 | |
| 123 | Heroin | 33 | 44567 | |
| 124 | Morphine | 33 | 4675 | |
| 125 | Coffeeshop reviews | 62 | 0 | |
| 132 | Antipsychotics | 37 | 2901 | |
| 133 | Tobacco | 37 | 6012 | |
| 134 | Deliriant antihistamines | 37 | 5778 | |
| 135 | Concerta & Ritalin | 19 | 7786 | |
| 136 | Adderall | 19 | 18621 | |
| 138 | Pharmacology | 71 | 4593 | |
| 142 | Book reviews | 74 | 0 | |
| 147 | Over Drugs-Forum | 148 | 266 | |
| 148 | Diverse drugs gerelateerde forums | 0 | 0 | |
| 149 | Forums over drugs | 0 | 0 | |
| 150 | Diverse zaken | 148 | 668 | |
| 157 | Smartdrugs | 149 | 164 | |
| 158 | Paddo's | 149 | 676 | |
| 159 | Chemie & extractie | 346 | 910 | |
| 161 | Codeine | 33 | 10107 | |
| 162 | Opium & Poppy | 33 | 11332 | |
| 172 | Nootropics | 37 | 6384 | |
| 173 | Announcements | 43 | 3003 | |
| 174 | Wiki Testing Grounds | 426 | 0 | |
| 175 | Coca | 40 | 1023 | |
| 176 | Wiki Articles | 426 | 0 | |
| 184 | Site use | 43 | 9991 | |
| 185 | MDMA Chemistry | 64 | 0 | |
| 186 | Meth Chemistry | 64 | 0 | |
| 187 | GHB Chemistry | 17 | 0 | |
| 188 | Multimedia | 74 | 1931 | |
| 195 | About DF members | 70 | 51866 | |
| 196 | International rehab index | 463 | 0 | |
| 197 | Kokain | 47 | 30 | |
| 198 | LSD | 47 | 16 | |
| 199 | Zauberpilze | 47 | 105 | |
| 200 | Amphetamin | 47 | 426 | |
| 201 | XTC | 47 | 25 | |
| 202 | GHB | 47 | 33 | |
| 203 | Ethnobotanik | 47 | 140 | |
| 204 | Cannabis | 47 | 182 | |
| 205 | Herbal XTC | 47 | 1 | |
| 206 | Downers | 47 | 71 | |
| 207 | Dissoziativa | 47 | 60 | |
| 208 | Verschiedenes | 0 | 218 | |
| 210 | Über Drogen-Forum | 208 | 173 | |
| 211 | USA | 278 | 0 | |
| 212 | Alabama | 211 | 0 | |
| 213 | Alaska | 211 | 0 | |
| 214 | Arizona | 211 | 0 | |
| 215 | Arkansas | 211 | 0 | |
| 216 | Spain | 277 | 0 | |
| 217 | Netherlands | 277 | 0 | |
| 218 | UK | 277 | 0 | |
| 219 | Canada | 278 | 0 | |
| 220 | Australia | 196 | 0 | |
| 221 | Hong Kong | 279 | 0 | |
| 222 | Ireland | 277 | 0 | |
| 223 | Israel | 279 | 0 | |
| 224 | Nepal | 279 | 0 | |
| 225 | Portugal | 277 | 0 | |
| 226 | South Africa | 196 | 0 | |
| 227 | Colorado | 211 | 0 | |
| 228 | California | 211 | 0 | |
| 229 | Florida | 211 | 0 | |
| 230 | Hawaii | 211 | 0 | |
| 231 | Illinois | 211 | 0 | |
| 232 | Kentucky | 211 | 0 | |
| 233 | Texas | 211 | 0 | |
| 234 | Utah | 211 | 0 | |
| 235 | Washington | 211 | 0 | |
| 236 | Pennsylvania | 211 | 0 | |
| 237 | Connecticut | 211 | 0 | |
| 238 | Delaware | 211 | 0 | |
| 239 | Georgia | 211 | 0 | |
| 240 | Idaho | 211 | 0 | |
| 241 | Indiana | 211 | 0 | |
| 242 | Iowa | 211 | 0 | |
| 243 | Kansas | 211 | 0 | |
| 244 | Louisiana | 211 | 0 | |
| 245 | Maine | 211 | 0 | |
| 246 | Maryland | 211 | 0 | |
| 247 | Massachusetts | 211 | 0 | |
| 248 | Michigan | 211 | 0 | |
| 249 | Minnesota | 211 | 0 | |
| 250 | Mississippi | 211 | 0 | |
| 251 | Missouri | 211 | 0 | |
| 252 | Montana | 211 | 0 | |
| 253 | Nebraska | 211 | 0 | |
| 254 | Nevada | 211 | 0 | |
| 255 | New Hampshire | 211 | 0 | |
| 256 | New Jersey | 211 | 0 | |
| 257 | New Mexico | 211 | 0 | |
| 258 | New York | 211 | 0 | |
| 259 | North Carolina | 211 | 0 | |
| 260 | North Dakota | 211 | 0 | |
| 261 | Ohio | 211 | 0 | |
| 262 | Oklahoma | 211 | 0 | |
| 263 | Oregon | 211 | 0 | |
| 264 | Rhode Island | 211 | 0 | |
| 265 | South Carolina | 211 | 0 | |
| 266 | South Dakota | 211 | 0 | |
| 267 | Tennessee | 211 | 0 | |
| 268 | Vermont | 211 | 0 | |
| 269 | Virginia | 211 | 0 | |
| 270 | West Virginia | 211 | 0 | |
| 271 | Wisconsin | 211 | 0 | |
| 272 | Wyoming | 211 | 0 | |
| 273 | Mexico | 278 | 0 | |
| 277 | Europe | 196 | 0 | |
| 278 | North America | 196 | 0 | |
| 279 | Asia | 196 | 0 | |
| 280 | Cocaine addiction | 424 | 3718 | |
| 281 | Opiate addiction | 424 | 53338 | |
| 282 | Amphetamines addiction | 424 | 6461 | |
| 283 | Cocaine addiction | 22 | 0 | |
| 284 | Alcohol addiction | 424 | 3993 | |
| 285 | Alcohol addiction | 18 | 0 | |
| 286 | Amphetamine addiction | 19 | 0 | |
| 287 | Opiate addiction | 33 | 0 | |
| 288 | Downers addiction | 424 | 4621 | |
| 289 | Downers addiction | 50 | 0 | |
| 290 | South America | 196 | 0 | |
| 291 | Peru | 290 | 0 | |
| 292 | Brazil | 290 | 0 | |
| 293 | Denmark | 277 | 0 | |
| 294 | Germany | 277 | 0 | |
| 295 | Italy | 277 | 0 | |
| 296 | France | 277 | 0 | |
| 297 | Belgium | 277 | 0 | |
| 306 | Justice & Law (News) | 351 | 19494 | |
| 307 | Politics (News) | 351 | 6670 | |
| 308 | Health (News) | 351 | 13445 | |
| 309 | Culture (News) | 351 | 8255 | |
| 310 | Weird News | 351 | 5287 | |
| 312 | Bug tracker | 43 | 279 | |
| 315 | Cultuur (Nieuws) | 58 | 6 | |
| 316 | Gezondheid (Nieuws) | 58 | 58 | |
| 317 | Politiek (Nieuws) | 58 | 68 | |
| 318 | Justitie (Nieuws) | 58 | 189 | |
| 319 | Cactus Extraction | 434 | 923 | |
| 320 | Mescaline extraction | 32 | 0 | |
| 321 | DMT Extraction | 52 | 0 | |
| 322 | GHB Chemistry | 36 | 0 | |
| 323 | PEA Chem | 89 | 0 | |
| 324 | MDMA Chemistry | 30 | 0 | |
| 325 | Phenethylamine Chem | 19 | 0 | |
| 326 | Meth Chemistry | 88 | 0 | |
| 327 | Tryptamine Chem | 90 | 0 | |
| 328 | LSD Synthesis | 67 | 0 | |
| 330 | Psychoactive Plant Cultivation | 0 | 548 | |
| 331 | Cannabis growing | 7 | 0 | |
| 332 | Mushroom growing | 8 | 0 | |
| 333 | Poppy growing | 330 | 4344 | |
| 334 | Poppy growing | 162 | 0 | |
| 336 | Cannabinoids | 21 | 15404 | |
| 342 | Drug News Portal | 351 | 0 | |
| 343 | Drugsbeleid | 148 | 17 | |
| 344 | Justitie & Recht | 148 | 17 | |
| 345 | Verslaving | 148 | 36 | |
| 346 | DRUG CREATIE | 0 | 1 | |
| 347 | Recht & Gesetz | 208 | 217 | |
| 348 | Research Chemicals | 47 | 222 | |
| 349 | Opiate | 47 | 180 | |
| 350 | Verschiedene Drogen | 47 | 192 | |
| 351 | Drug News | 0 | 1 | |
| 352 | Cactus Growing | 330 | 1108 | |
| 353 | Cactus Growing | 32 | 0 | |
| 354 | Bulgaria | 277 | 0 | |
| 355 | Croatia | 277 | 0 | |
| 356 | Finland | 277 | 0 | |
| 357 | Latvia | 277 | 0 | |
| 358 | Macedonia | 277 | 0 | |
| 359 | Norway | 277 | 0 | |
| 360 | Slovakia | 277 | 0 | |
| 361 | Sweden | 277 | 0 | |
| 362 | Switzerland | 277 | 0 | |
| 363 | Ukraine | 277 | 0 | |
| 375 | New Zealand | 196 | 0 | |
| 377 | Beta-Ketones | 21 | 15550 | |
| 379 | GrowFAQ | 27 | 0 | |
| 380 | Rhodium | 17 | 0 | |
| 381 | Medical Marijuana News | 351 | 3071 | |
| 389 | Drogen-Wiki | 208 | 0 | |
| 391 | Wiki Discussions | 426 | 275 | |
| 392 | Unidentified Products | 21 | 2176 | |
| 393 | Unidentified blends | 21 | 699 | |
| 394 | Events | 74 | 857 | |
| 395 | Fentanyl | 33 | 3713 | |
| 396 | Hydrocodone | 33 | 6072 | |
| 397 | Methadone | 33 | 5510 | |
| 398 | Oxycodone | 33 | 14247 | |
| 399 | Tramadol | 33 | 5867 | |
| 400 | Strains & Breeding | 27 | 580 | |
| 401 | Outdoor Cannabis | 27 | 778 | |
| 402 | Indoor Cannabis | 27 | 923 | |
| 403 | Hydromorphone | 33 | 2509 | |
| 404 | Oxymorphone | 33 | 684 | |
| 405 | Medical Marijuana News | 413 | 0 | |
| 406 | Buprenorphine | 33 | 5808 | |
| 407 | Salvia Growing | 330 | 528 | |
| 408 | Salvia Growing | 35 | 0 | |
| 413 | Medical Marijuana | 414 | 527 | |
| 414 | Cannabis & Health | 7 | 5407 | |
| 415 | Hashish & BHO | 7 | 2591 | |
| 416 | Cooking with Cannabis | 7 | 2095 | |
| 417 | Cannabis addiction | 424 | 3951 | |
| 418 | Cannabis addiction | 414 | 0 | |
| 420 | GHB addiction | 424 | 1060 | |
| 421 | GHB addiction | 36 | 0 | |
| 422 | Ecstasy addiction | 30 | 0 | |
| 423 | Amphetamine addiction | 89 | 0 | |
| 424 | Drug Addiction & Recovery | 0 | 0 | |
| 425 | Other drug addiction | 424 | 1871 | |
| 426 | Drugs-Wiki | 0 | 0 | |
| 428 | Wiki Books | 426 | 0 | |
| 429 | Wiki Categories | 426 | 0 | |
| 430 | Wiki Templates | 426 | 0 | |
| 431 | Opiate Extraction | 434 | 5354 | |
| 432 | Opiate Extraction, CWE | 33 | 0 | |
| 433 | Access Applications | 17 | 466 | |
| 434 | Extraction | 0 | 1932 | |
| 435 | Chemistry Basics | 17 | 2385 | |
| 437 | DXM Extraction | 434 | 1022 | |
| 438 | Surveys | 71 | 1551 | |
| 440 | Family & friends | 424 | 3956 | |
| 441 | Psychological & social | 424 | 3026 | |
| 442 | Nachrichten | 208 | 567 | |
| 443 | Caffeine & Coffee | 40 | 1229 | |
| 445 | Dissociative RC's | 21 | 1365 | |
| 446 | Dissociative RC's | 24 | 0 | |
| 463 | Drug Addiction Tools | 0 | 0 | |
| 464 | Recovery Articles | 463 | 0 | |
| 465 | Assess your addiction | 463 | 0 | |
| 467 | Recovery Journals | 0 | 0 | |
| 468 | Alcohol R&A Journals | 467 | 614 | |
| 469 | Amphetamines R&A Journals | 467 | 562 | |
| 470 | Cannabinoids R&A Journals | 467 | 572 | |
| 471 | Downers R&A Journals | 467 | 378 | |
| 472 | Opiate R&A Journals | 467 | 15033 | |
| 473 | Drug Law Articles | 41 | 0 | |
| 476 | Music Groups | 74 | 0 | |
| 477 | Off-Topic Groups | 70 | 0 | |
| 478 | Social Blogs | 70 | 0 | |
| 479 | Medical Marijuana Dispensaries | 414 | 0 | |
| 480 | Helpdesk | 43 | 0 | |
| 485 | Magic Mushroom hunting | 8 | 1310 | |
| 493 | Cannabis Paraphernalia Reviews | 106 | 253 | |
| 494 | Reputation bounties | 43 | 48 | |
| 500 | LSD Questions | 25 | 8 | |
| 501 | LSD Experiences | 25 | 0 | |
| 502 | LSD Discussions | 25 | 211 | |
| 503 | Drug testing Questions | 71 | 1896 | |
| 504 | Resolved bugs | 312 | 3087 | |
| 505 | Future fix | 312 | 559 | |
| 506 | General Addiction discussion | 424 | 9175 | |
| 507 | Other Drug R&A Journals | 467 | 522 |
| svg = d3.select('svg') | |
| width = svg.node().getBoundingClientRect().width | |
| height = svg.node().getBoundingClientRect().height | |
| # append a group for zoomable content | |
| zoomable_layer = svg.append('g') | |
| # define a zoom behavior | |
| zoom = d3.behavior.zoom() | |
| .scaleExtent([1,1000]) # min-max zoom | |
| .on 'zoom', () -> | |
| # GEOMETRIC ZOOM | |
| zoomable_layer | |
| .attr | |
| transform: "translate(#{zoom.translate()})scale(#{zoom.scale()})" | |
| # bind the zoom behavior to the main SVG | |
| svg.call(zoom) | |
| vis = zoomable_layer.append('g') | |
| .attr | |
| class: 'vis' | |
| transform: "translate(#{width/2-400},#{height/2-200})" | |
| # define the treemap layout | |
| PAD = 6 | |
| treemap = d3.layout.treemap() | |
| .size([800, 400]) | |
| .value((d) -> d.size) | |
| .sort(null) | |
| .padding((d) -> | |
| # WARNING special padding depends on ordering (bluelight first, drugsforum next) | |
| switch d.id | |
| when 'root_fake' then 0 | |
| when 'bluelight_fake' then [0,2*PAD,0,0] | |
| when 'drugsforum_fake' then [0,0,0,2*PAD] | |
| else PAD | |
| ) | |
| .ratio(1) | |
| .round(false) # bugfix: d3 wrong ordering | |
| # define a categorical color scale | |
| color = d3.scale.category20c() | |
| # correction scales for labels | |
| correct_x = d3.scale.linear() | |
| .domain([0, width]) | |
| .range([0, width*1.2]) | |
| correct_y = d3.scale.linear() | |
| .domain([0, height]) | |
| .range([0, height*1.1]) | |
| # fetch data | |
| d3.csv 'drugsforum.csv', (data1) -> | |
| # prepare table 1 for merging into a single tree | |
| data1.forEach (d) -> | |
| d.size = +d.size | |
| d.id = 'drugsforum_' + d.id | |
| d.forum_parent_id = if d.forum_parent_id is "null" then 'drugsforum_fake' else 'drugsforum_' + d.forum_parent_id | |
| d3.csv 'bluelight_forum.csv', (data2) -> | |
| # prepare table 2 for merging into a single tree | |
| data2.forEach (d) -> | |
| d.size = +d.size | |
| d.id = 'bluelight_' + d.id | |
| d.forum_parent_id = if d.forum_parent_id is "null" then 'bluelight_fake' else 'bluelight_' + d.forum_parent_id | |
| # merge tables | |
| data = data1.concat(data2) | |
| # add fake nodes: a single root for both hierarchies and two more internal nodes to hack d3 treemap padding | |
| data.push { | |
| id: 'drugsforum_fake', | |
| size: 0, | |
| forum_parent_id: 'root_fake', | |
| name: '', | |
| fake: true | |
| } | |
| data.push { | |
| id: 'bluelight_fake', | |
| size: 0, | |
| forum_parent_id: 'root_fake', | |
| name: '', | |
| fake: true | |
| } | |
| data.push { | |
| id: 'root_fake', | |
| size: 0, | |
| forum_parent_id: null, | |
| name: '', | |
| fake: true | |
| } | |
| # create the tree structure | |
| index = {} | |
| data.forEach (d) -> | |
| index[d.id] = d | |
| d.children = [] | |
| data.forEach (d) -> if d.forum_parent_id isnt null | |
| index[d.forum_parent_id].children.push d | |
| tree = index['root_fake'] | |
| # split the names for displaying multiline labels | |
| data.forEach (d) -> | |
| d.splitted_name = d.name.split(' ') | |
| walk = (n, depth) -> | |
| # no children array -> empty children array | |
| if not n.children? | |
| n.children = [] | |
| if n.children.length > 0 | |
| for child in n.children | |
| walk(child, depth+1) | |
| # sort children | |
| n.children.sort (a,b) -> a.size - b.size | |
| # save original size for later | |
| size = n.size | |
| # compute aggregated node sizes | |
| n.size += d3.sum n.children, (d) -> d.size | |
| # add the node representing leaves | |
| n.children.unshift { | |
| name: n.name, | |
| splitted_name: n.splitted_name, | |
| size: size, | |
| leaves: true | |
| } | |
| walk(tree, 0) | |
| # depth-first enumeration | |
| i = 0 | |
| walk_i = (n) -> | |
| if n.children? | |
| for child in n.children | |
| walk_i(child) | |
| n.i = i | |
| i += 1 | |
| walk_i(tree) | |
| # compute the treemap layout | |
| data = treemap.nodes(tree) | |
| # draw the treemap | |
| boxes = vis.selectAll('.box') | |
| .data(data) | |
| enter_boxes = boxes.enter().append('g') | |
| .attr | |
| class: 'box' | |
| transform: (d) -> "translate(#{d.x},#{d.y})" | |
| .classed('hidden', (d) -> d.fake? and d.fake) | |
| .classed('leaves', (d) -> d.leaves? and d.leaves) | |
| enter_boxes.append('rect') | |
| .attr | |
| width: (d) -> d.dx | |
| height: (d) -> d.dy | |
| fill: (d) -> | |
| if d.leaves? and d.leaves | |
| return color(d.parent.i) | |
| else | |
| return color(d.i) | |
| enter_labels_g = enter_boxes.append('g') | |
| .classed('hidden', (d) -> d.children?) | |
| enter_labels = enter_labels_g.append('svg') | |
| .attr | |
| class: 'label' | |
| enter_texts = enter_labels.append('text') | |
| tspans = enter_texts.selectAll('tspan') | |
| .data((d) -> d.splitted_name) | |
| tspans.enter().append('tspan') | |
| .text((d) -> d.toUpperCase()) | |
| .attr | |
| x: 0 | |
| y: (d, i) -> | |
| l = d3.select(this.parentNode).datum().splitted_name.length | |
| return (i-l/2) + 'em' | |
| enter_texts | |
| .each (node) -> | |
| bbox = this.getBBox() | |
| bbox_aspect = bbox.width / bbox.height | |
| node_bbox = {width: node.dx, height: node.dy} | |
| node_bbox_aspect = node_bbox.width / node_bbox.height | |
| rotate = bbox_aspect >= 1 and node_bbox_aspect < 1 or bbox_aspect < 1 and node_bbox_aspect >= 1 | |
| node.label_bbox = { | |
| x: bbox.x+(bbox.width-correct_x(bbox.width))/2, | |
| y: bbox.y+(bbox.height-correct_y(bbox.height))/2, | |
| width: correct_x(bbox.width), | |
| height: correct_y(bbox.height) | |
| } | |
| if rotate | |
| node.label_bbox = { | |
| x: node.label_bbox.y, | |
| y: node.label_bbox.x, | |
| width: node.label_bbox.height, | |
| height: node.label_bbox.width | |
| } | |
| d3.select(this).attr('transform', 'rotate(90) translate(0,28)') | |
| enter_labels | |
| .attr | |
| width: (d) -> d.dx | |
| height: (d) -> d.dy | |
| viewBox: (d) -> "#{d.label_bbox.x} #{d.label_bbox.y} #{d.label_bbox.width} #{d.label_bbox.height}" | |
| preserveAspectRatio: 'none' | |
| fill: (d) -> | |
| if d.leaves? and d.leaves | |
| c = d3.hcl(color(d.parent.i)) | |
| else | |
| c = d3.hcl(color(d.i)) | |
| c.l -= 20 | |
| return c | |
| enter_boxes.append('title') | |
| .text (d) -> | |
| "#{d.name}\n#{d3.format(',')(d.size)} posts" + if d.leaves? and d.leaves then '\n(subforums excluded)' else '' | |
| <!doctype html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>Bluelight and Drugsforum treemaps (Cassandra)</title> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <link rel="stylesheet" href="index.css"> | |
| </head> | |
| <body> | |
| <svg width="960px" height="500px"></svg> | |
| <script src="index.js"></script> | |
| </body> | |
| </html> |
| // Generated by CoffeeScript 1.4.0 | |
| (function() { | |
| var PAD, color, correct_x, correct_y, height, svg, treemap, vis, width, zoom, zoomable_layer; | |
| svg = d3.select('svg'); | |
| width = svg.node().getBoundingClientRect().width; | |
| height = svg.node().getBoundingClientRect().height; | |
| zoomable_layer = svg.append('g'); | |
| zoom = d3.behavior.zoom().scaleExtent([1, 1000]).on('zoom', function() { | |
| return zoomable_layer.attr({ | |
| transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")" | |
| }); | |
| }); | |
| svg.call(zoom); | |
| vis = zoomable_layer.append('g').attr({ | |
| "class": 'vis', | |
| transform: "translate(" + (width / 2 - 400) + "," + (height / 2 - 200) + ")" | |
| }); | |
| PAD = 6; | |
| treemap = d3.layout.treemap().size([800, 400]).value(function(d) { | |
| return d.size; | |
| }).sort(null).padding(function(d) { | |
| switch (d.id) { | |
| case 'root_fake': | |
| return 0; | |
| case 'bluelight_fake': | |
| return [0, 2 * PAD, 0, 0]; | |
| case 'drugsforum_fake': | |
| return [0, 0, 0, 2 * PAD]; | |
| default: | |
| return PAD; | |
| } | |
| }).ratio(1).round(false); | |
| color = d3.scale.category20c(); | |
| correct_x = d3.scale.linear().domain([0, width]).range([0, width * 1.2]); | |
| correct_y = d3.scale.linear().domain([0, height]).range([0, height * 1.1]); | |
| d3.csv('drugsforum.csv', function(data1) { | |
| data1.forEach(function(d) { | |
| d.size = +d.size; | |
| d.id = 'drugsforum_' + d.id; | |
| return d.forum_parent_id = d.forum_parent_id === "null" ? 'drugsforum_fake' : 'drugsforum_' + d.forum_parent_id; | |
| }); | |
| return d3.csv('bluelight_forum.csv', function(data2) { | |
| var boxes, data, enter_boxes, enter_labels, enter_labels_g, enter_texts, i, index, tree, tspans, walk, walk_i; | |
| data2.forEach(function(d) { | |
| d.size = +d.size; | |
| d.id = 'bluelight_' + d.id; | |
| return d.forum_parent_id = d.forum_parent_id === "null" ? 'bluelight_fake' : 'bluelight_' + d.forum_parent_id; | |
| }); | |
| data = data1.concat(data2); | |
| data.push({ | |
| id: 'drugsforum_fake', | |
| size: 0, | |
| forum_parent_id: 'root_fake', | |
| name: '', | |
| fake: true | |
| }); | |
| data.push({ | |
| id: 'bluelight_fake', | |
| size: 0, | |
| forum_parent_id: 'root_fake', | |
| name: '', | |
| fake: true | |
| }); | |
| data.push({ | |
| id: 'root_fake', | |
| size: 0, | |
| forum_parent_id: null, | |
| name: '', | |
| fake: true | |
| }); | |
| index = {}; | |
| data.forEach(function(d) { | |
| index[d.id] = d; | |
| return d.children = []; | |
| }); | |
| data.forEach(function(d) { | |
| if (d.forum_parent_id !== null) { | |
| return index[d.forum_parent_id].children.push(d); | |
| } | |
| }); | |
| tree = index['root_fake']; | |
| data.forEach(function(d) { | |
| return d.splitted_name = d.name.split(' '); | |
| }); | |
| walk = function(n, depth) { | |
| var child, size, _i, _len, _ref; | |
| if (!(n.children != null)) { | |
| n.children = []; | |
| } | |
| if (n.children.length > 0) { | |
| _ref = n.children; | |
| for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
| child = _ref[_i]; | |
| walk(child, depth + 1); | |
| } | |
| n.children.sort(function(a, b) { | |
| return a.size - b.size; | |
| }); | |
| size = n.size; | |
| n.size += d3.sum(n.children, function(d) { | |
| return d.size; | |
| }); | |
| return n.children.unshift({ | |
| name: n.name, | |
| splitted_name: n.splitted_name, | |
| size: size, | |
| leaves: true | |
| }); | |
| } | |
| }; | |
| walk(tree, 0); | |
| i = 0; | |
| walk_i = function(n) { | |
| var child, _i, _len, _ref; | |
| if (n.children != null) { | |
| _ref = n.children; | |
| for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
| child = _ref[_i]; | |
| walk_i(child); | |
| } | |
| } | |
| n.i = i; | |
| return i += 1; | |
| }; | |
| walk_i(tree); | |
| data = treemap.nodes(tree); | |
| boxes = vis.selectAll('.box').data(data); | |
| enter_boxes = boxes.enter().append('g').attr({ | |
| "class": 'box', | |
| transform: function(d) { | |
| return "translate(" + d.x + "," + d.y + ")"; | |
| } | |
| }).classed('hidden', function(d) { | |
| return (d.fake != null) && d.fake; | |
| }).classed('leaves', function(d) { | |
| return (d.leaves != null) && d.leaves; | |
| }); | |
| enter_boxes.append('rect').attr({ | |
| width: function(d) { | |
| return d.dx; | |
| }, | |
| height: function(d) { | |
| return d.dy; | |
| }, | |
| fill: function(d) { | |
| if ((d.leaves != null) && d.leaves) { | |
| return color(d.parent.i); | |
| } else { | |
| return color(d.i); | |
| } | |
| } | |
| }); | |
| enter_labels_g = enter_boxes.append('g').classed('hidden', function(d) { | |
| return d.children != null; | |
| }); | |
| enter_labels = enter_labels_g.append('svg').attr({ | |
| "class": 'label' | |
| }); | |
| enter_texts = enter_labels.append('text'); | |
| tspans = enter_texts.selectAll('tspan').data(function(d) { | |
| return d.splitted_name; | |
| }); | |
| tspans.enter().append('tspan').text(function(d) { | |
| return d.toUpperCase(); | |
| }).attr({ | |
| x: 0, | |
| y: function(d, i) { | |
| var l; | |
| l = d3.select(this.parentNode).datum().splitted_name.length; | |
| return (i - l / 2) + 'em'; | |
| } | |
| }); | |
| enter_texts.each(function(node) { | |
| var bbox, bbox_aspect, node_bbox, node_bbox_aspect, rotate; | |
| bbox = this.getBBox(); | |
| bbox_aspect = bbox.width / bbox.height; | |
| node_bbox = { | |
| width: node.dx, | |
| height: node.dy | |
| }; | |
| node_bbox_aspect = node_bbox.width / node_bbox.height; | |
| rotate = bbox_aspect >= 1 && node_bbox_aspect < 1 || bbox_aspect < 1 && node_bbox_aspect >= 1; | |
| node.label_bbox = { | |
| x: bbox.x + (bbox.width - correct_x(bbox.width)) / 2, | |
| y: bbox.y + (bbox.height - correct_y(bbox.height)) / 2, | |
| width: correct_x(bbox.width), | |
| height: correct_y(bbox.height) | |
| }; | |
| if (rotate) { | |
| node.label_bbox = { | |
| x: node.label_bbox.y, | |
| y: node.label_bbox.x, | |
| width: node.label_bbox.height, | |
| height: node.label_bbox.width | |
| }; | |
| return d3.select(this).attr('transform', 'rotate(90) translate(0,28)'); | |
| } | |
| }); | |
| enter_labels.attr({ | |
| width: function(d) { | |
| return d.dx; | |
| }, | |
| height: function(d) { | |
| return d.dy; | |
| }, | |
| viewBox: function(d) { | |
| return "" + d.label_bbox.x + " " + d.label_bbox.y + " " + d.label_bbox.width + " " + d.label_bbox.height; | |
| }, | |
| preserveAspectRatio: 'none', | |
| fill: function(d) { | |
| var c; | |
| if ((d.leaves != null) && d.leaves) { | |
| c = d3.hcl(color(d.parent.i)); | |
| } else { | |
| c = d3.hcl(color(d.i)); | |
| } | |
| c.l -= 20; | |
| return c; | |
| } | |
| }); | |
| return enter_boxes.append('title').text(function(d) { | |
| return ("" + d.name + "\n" + (d3.format(',')(d.size)) + " posts") + ((d.leaves != null) && d.leaves ? '\n(subforums excluded)' : ''); | |
| }); | |
| }); | |
| }); | |
| }).call(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment