block by timelyportfolio de7de158d68ea3bf51ad

de7de158d68ea3bf51ad

Full Screen

Radial Tree

Collapsible/expandible, can change root, and full user interface.

See the gist in action at http://bl.ocks.org/wmleler/raw/a734fb2bb3319a2cb386/.

There is also a help file.

The source is at https://bl.ocks.org/wmleler/a734fb2bb3319a2cb386/.

I didn’t need drag and drop, but it could be added with not too much trouble.

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Radial Tree</title>
  <script src="d3.min.js" charset="utf-8"></script>
  <link rel="stylesheet" type="text/css" href="radial-tree.css">
</head>
<body>

<div id="tree-container"></div>

<div id="toolbar">
  <div class="tool">
    <div id="help" title="click for help"><a href="help.html" target="_blank">HELP</a></div>
  </div>
  <div class="tool">
    <div class="tlabel">zoom</div>
    <div class="tbuttons">
      <div class="button" data-key="187" title="Zoom In (+ OR scrollwheel)">+</div>
      <div class="button" data-key="189" title="Zoom Out (&minus; OR scrollwheel)">&minus;</div>
    </div>
  </div>
  <div class="tool">
    <div class="tlabel">rotate</div>
    <div class="tbuttons">
      <div class="button" data-key="33" title="Rotate CCW (Page Up OR &#8679;scrollwheel)" style="font-size:0.9em">&#8634;</div>
      <div class="button" data-key="34" title="Rotate CW (Page Down OR &#8679;scrollwheel)" style="font-size:0.9em">&#8635;</div>
    </div>
  </div>
  <div class="tool">
    <div class="tlabel">select</div>
    <div class="tbuttons">
      <div class="button" data-key="-38" title="Select Previous (&#8679;&uarr;)" style="font-size:0.9em">&#8613;</div>
      <div class="button" data-key="-40" title="Select Next (&#8679;&darr;)" style="font-size:0.9em">&#8615;</div>
    </div>
  </div>
  <div class="tool">
    <div class="tlabel">view</div>
    <div class="tbuttons">
      <div class="button" data-key="36" title="Center Root (Home)">&#8962;</div>
      <div class="button" data-key="35" title="Center Selected (End)" style="font-size:0.8em">&#9673;</div>
    </div>
  </div>
  <div class="tool">
    <div class="tlabel">toggle</div>
    <div class="tbuttons">
      <div class="button" data-key="32" title="Toggle Node (Space OR double-click)">1</div>
      <div class="button" data-key="13" title="Toggle Level (Return OR &#8679;double-click)">&oplus;</div>
      <div class="button" data-key="191" title="Toggle Root (/)">/</div>
    </div>
  </div>
  <div class="tool">
    <div class="tlabel" style="text-align:left" title="Change Root">&nbsp;selection</div>
    <div id="selection" class="tlabel"></div>
  </div>
</div>

<div id="contextmenu">
  <div data-key="32"><span class="expcol">Expand</span> Node</div>
  <div data-key="13">Expand 1 Level</div>
  <div data-key="-13">Expand Full Tree</div>
  <div data-key="35">Center This Node</div>
  <div data-key="36">Center Root</div>
  <div data-key="191">Set Root</div>
</div>

<script type="text/javascript" src="radial-tree.js"></script>

</body>
</html>

data-flare.json

{
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
     "children": [
      {"name": "AgglomerativeCluster", "size": 3938},
      {"name": "CommunityStructure", "size": 3812},
      {"name": "HierarchicalCluster", "size": 6714},
      {"name": "MergeEdge", "size": 743}
     ]
    },
    {
     "name": "graph",
     "children": [
      {"name": "BetweennessCentrality", "size": 3534},
      {"name": "LinkDistance", "size": 5731},
      {"name": "MaxFlowMinCut", "size": 7840},
      {"name": "ShortestPaths", "size": 5914},
      {"name": "SpanningTree", "size": 3416}
     ]
    },
    {
     "name": "optimization",
     "children": [
      {"name": "AspectRatioBanker", "size": 7074}
     ]
    }
   ]
  },
  {
   "name": "animate",
   "children": [
    {"name": "Easing", "size": 17010},
    {"name": "FunctionSequence", "size": 5842},
    {
     "name": "interpolate",
     "children": [
      {"name": "ArrayInterpolator", "size": 1983},
      {"name": "ColorInterpolator", "size": 2047},
      {"name": "DateInterpolator", "size": 1375},
      {"name": "Interpolator", "size": 8746},
      {"name": "MatrixInterpolator", "size": 2202},
      {"name": "NumberInterpolator", "size": 1382},
      {"name": "ObjectInterpolator", "size": 1629},
      {"name": "PointInterpolator", "size": 1675},
      {"name": "RectangleInterpolator", "size": 2042}
     ]
    },
    {"name": "ISchedulable", "size": 1041},
    {"name": "Parallel", "size": 5176},
    {"name": "Pause", "size": 449},
    {"name": "Scheduler", "size": 5593},
    {"name": "Sequence", "size": 5534},
    {"name": "Transition", "size": 9201},
    {"name": "Transitioner", "size": 19975},
    {"name": "TransitionEvent", "size": 1116},
    {"name": "Tween", "size": 6006}
   ]
  },
  {
   "name": "data",
   "children": [
    {
     "name": "converters",
     "children": [
      {"name": "Converters", "size": 721},
      {"name": "DelimitedTextConverter", "size": 4294},
      {"name": "GraphMLConverter", "size": 9800},
      {"name": "IDataConverter", "size": 1314},
      {"name": "JSONConverter", "size": 2220}
     ]
    },
    {"name": "DataField", "size": 1759},
    {"name": "DataSchema", "size": 2165},
    {"name": "DataSet", "size": 586},
    {"name": "DataSource", "size": 3331},
    {"name": "DataTable", "size": 772},
    {"name": "DataUtil", "size": 3322}
   ]
  },
  {
   "name": "display",
   "children": [
    {"name": "DirtySprite", "size": 8833},
    {"name": "LineSprite", "size": 1732},
    {"name": "RectSprite", "size": 3623},
    {"name": "TextSprite", "size": 10066}
   ]
  },
  {
   "name": "flex",
   "children": [
    {"name": "FlareVis", "size": 4116}
   ]
  },
  {
   "name": "physics",
   "children": [
    {"name": "DragForce", "size": 1082},
    {"name": "GravityForce", "size": 1336},
    {"name": "IForce", "size": 319},
    {"name": "NBodyForce", "size": 10498},
    {"name": "Particle", "size": 2822},
    {"name": "Simulation", "size": 9983},
    {"name": "Spring", "size": 2213},
    {"name": "SpringForce", "size": 1681}
   ]
  },
  {
   "name": "query",
   "children": [
    {"name": "AggregateExpression", "size": 1616},
    {"name": "And", "size": 1027},
    {"name": "Arithmetic", "size": 3891},
    {"name": "Average", "size": 891},
    {"name": "BinaryExpression", "size": 2893},
    {"name": "Comparison", "size": 5103},
    {"name": "CompositeExpression", "size": 3677},
    {"name": "Count", "size": 781},
    {"name": "DateUtil", "size": 4141},
    {"name": "Distinct", "size": 933},
    {"name": "Expression", "size": 5130},
    {"name": "ExpressionIterator", "size": 3617},
    {"name": "Fn", "size": 3240},
    {"name": "If", "size": 2732},
    {"name": "IsA", "size": 2039},
    {"name": "Literal", "size": 1214},
    {"name": "Match", "size": 3748},
    {"name": "Maximum", "size": 843},
    {
     "name": "methods",
     "children": [
      {"name": "add", "size": 593},
      {"name": "and", "size": 330},
      {"name": "average", "size": 287},
      {"name": "count", "size": 277},
      {"name": "distinct", "size": 292},
      {"name": "div", "size": 595},
      {"name": "eq", "size": 594},
      {"name": "fn", "size": 460},
      {"name": "gt", "size": 603},
      {"name": "gte", "size": 625},
      {"name": "iff", "size": 748},
      {"name": "isa", "size": 461},
      {"name": "lt", "size": 597},
      {"name": "lte", "size": 619},
      {"name": "max", "size": 283},
      {"name": "min", "size": 283},
      {"name": "mod", "size": 591},
      {"name": "mul", "size": 603},
      {"name": "neq", "size": 599},
      {"name": "not", "size": 386},
      {"name": "or", "size": 323},
      {"name": "orderby", "size": 307},
      {"name": "range", "size": 772},
      {"name": "select", "size": 296},
      {"name": "stddev", "size": 363},
      {"name": "sub", "size": 600},
      {"name": "sum", "size": 280},
      {"name": "update", "size": 307},
      {"name": "variance", "size": 335},
      {"name": "where", "size": 299},
      {"name": "xor", "size": 354},
      {"name": "_", "size": 264}
     ]
    },
    {"name": "Minimum", "size": 843},
    {"name": "Not", "size": 1554},
    {"name": "Or", "size": 970},
    {"name": "Query", "size": 13896},
    {"name": "Range", "size": 1594},
    {"name": "StringUtil", "size": 4130},
    {"name": "Sum", "size": 791},
    {"name": "Variable", "size": 1124},
    {"name": "Variance", "size": 1876},
    {"name": "Xor", "size": 1101}
   ]
  },
  {
   "name": "scale",
   "children": [
    {"name": "IScaleMap", "size": 2105},
    {"name": "LinearScale", "size": 1316},
    {"name": "LogScale", "size": 3151},
    {"name": "OrdinalScale", "size": 3770},
    {"name": "QuantileScale", "size": 2435},
    {"name": "QuantitativeScale", "size": 4839},
    {"name": "RootScale", "size": 1756},
    {"name": "Scale", "size": 4268},
    {"name": "ScaleType", "size": 1821},
    {"name": "TimeScale", "size": 5833}
   ]
  },
  {
   "name": "util",
   "children": [
    {"name": "Arrays", "size": 8258},
    {"name": "Colors", "size": 10001},
    {"name": "Dates", "size": 8217},
    {"name": "Displays", "size": 12555},
    {"name": "Filter", "size": 2324},
    {"name": "Geometry", "size": 10993},
    {
     "name": "heap",
     "children": [
      {"name": "FibonacciHeap", "size": 9354},
      {"name": "HeapNode", "size": 1233}
     ]
    },
    {"name": "IEvaluable", "size": 335},
    {"name": "IPredicate", "size": 383},
    {"name": "IValueProxy", "size": 874},
    {
     "name": "math",
     "children": [
      {"name": "DenseMatrix", "size": 3165},
      {"name": "IMatrix", "size": 2815},
      {"name": "SparseMatrix", "size": 3366}
     ]
    },
    {"name": "Maths", "size": 17705},
    {"name": "Orientation", "size": 1486},
    {
     "name": "palette",
     "children": [
      {"name": "ColorPalette", "size": 6367},
      {"name": "Palette", "size": 1229},
      {"name": "ShapePalette", "size": 2059},
      {"name": "SizePalette", "size": 2291}
     ]
    },
    {"name": "Property", "size": 5559},
    {"name": "Shapes", "size": 19118},
    {"name": "Sort", "size": 6887},
    {"name": "Stats", "size": 6557},
    {"name": "Strings", "size": 22026}
   ]
  },
  {
   "name": "vis",
   "children": [
    {
     "name": "axis",
     "children": [
      {"name": "Axes", "size": 1302},
      {"name": "Axis", "size": 24593},
      {"name": "AxisGridLine", "size": 652},
      {"name": "AxisLabel", "size": 636},
      {"name": "CartesianAxes", "size": 6703}
     ]
    },
    {
     "name": "controls",
     "children": [
      {"name": "AnchorControl", "size": 2138},
      {"name": "ClickControl", "size": 3824},
      {"name": "Control", "size": 1353},
      {"name": "ControlList", "size": 4665},
      {"name": "DragControl", "size": 2649},
      {"name": "ExpandControl", "size": 2832},
      {"name": "HoverControl", "size": 4896},
      {"name": "IControl", "size": 763},
      {"name": "PanZoomControl", "size": 5222},
      {"name": "SelectionControl", "size": 7862},
      {"name": "TooltipControl", "size": 8435}
     ]
    },
    {
     "name": "data",
     "children": [
      {"name": "Data", "size": 20544},
      {"name": "DataList", "size": 19788},
      {"name": "DataSprite", "size": 10349},
      {"name": "EdgeSprite", "size": 3301},
      {"name": "NodeSprite", "size": 19382},
      {
       "name": "render",
       "children": [
        {"name": "ArrowType", "size": 698},
        {"name": "EdgeRenderer", "size": 5569},
        {"name": "IRenderer", "size": 353},
        {"name": "ShapeRenderer", "size": 2247}
       ]
      },
      {"name": "ScaleBinding", "size": 11275},
      {"name": "Tree", "size": 7147},
      {"name": "TreeBuilder", "size": 9930}
     ]
    },
    {
     "name": "events",
     "children": [
      {"name": "DataEvent", "size": 2313},
      {"name": "SelectionEvent", "size": 1880},
      {"name": "TooltipEvent", "size": 1701},
      {"name": "VisualizationEvent", "size": 1117}
     ]
    },
    {
     "name": "legend",
     "children": [
      {"name": "Legend", "size": 20859},
      {"name": "LegendItem", "size": 4614},
      {"name": "LegendRange", "size": 10530}
     ]
    },
    {
     "name": "operator",
     "children": [
      {
       "name": "distortion",
       "children": [
        {"name": "BifocalDistortion", "size": 4461},
        {"name": "Distortion", "size": 6314},
        {"name": "FisheyeDistortion", "size": 3444}
       ]
      },
      {
       "name": "encoder",
       "children": [
        {"name": "ColorEncoder", "size": 3179},
        {"name": "Encoder", "size": 4060},
        {"name": "PropertyEncoder", "size": 4138},
        {"name": "ShapeEncoder", "size": 1690},
        {"name": "SizeEncoder", "size": 1830}
       ]
      },
      {
       "name": "filter",
       "children": [
        {"name": "FisheyeTreeFilter", "size": 5219},
        {"name": "GraphDistanceFilter", "size": 3165},
        {"name": "VisibilityFilter", "size": 3509}
       ]
      },
      {"name": "IOperator", "size": 1286},
      {
       "name": "label",
       "children": [
        {"name": "Labeler", "size": 9956},
        {"name": "RadialLabeler", "size": 3899},
        {"name": "StackedAreaLabeler", "size": 3202}
       ]
      },
      {
       "name": "layout",
       "children": [
        {"name": "AxisLayout", "size": 6725},
        {"name": "BundledEdgeRouter", "size": 3727},
        {"name": "CircleLayout", "size": 9317},
        {"name": "CirclePackingLayout", "size": 12003},
        {"name": "DendrogramLayout", "size": 4853},
        {"name": "ForceDirectedLayout", "size": 8411},
        {"name": "IcicleTreeLayout", "size": 4864},
        {"name": "IndentedTreeLayout", "size": 3174},
        {"name": "Layout", "size": 7881},
        {"name": "NodeLinkTreeLayout", "size": 12870},
        {"name": "PieLayout", "size": 2728},
        {"name": "RadialTreeLayout", "size": 12348},
        {"name": "RandomLayout", "size": 870},
        {"name": "StackedAreaLayout", "size": 9121},
        {"name": "TreeMapLayout", "size": 9191}
       ]
      },
      {"name": "Operator", "size": 2490},
      {"name": "OperatorList", "size": 5248},
      {"name": "OperatorSequence", "size": 4190},
      {"name": "OperatorSwitch", "size": 2581},
      {"name": "SortOperator", "size": 2023}
     ]
    },
    {"name": "Visualization", "size": 16540}
   ]
  }
 ]
}

help.html

<!DOCTYPE html>
<html>
<head>
  <title>Radial Tree Help</title>
  <style>
body {
  font-family: Roboto, Helvetica, sans-serif;
}
table {
  border: solid black 1px;
}
td {
  text-align: center;
  padding: 2px 3px;
}
li {
  line-height: 1.3em;
}
  </style>
</head>
<body>
<h1>Radial Tree</h1>

<p>
This animated radial tree is collapsible and expandible, and you can change the root of the tree.
It has a full user interface, including mouse, mousewheel (if you have one), and keyboard shortcuts.
It may also work on touch screens, although that has not been tested.
The tree automatically resizes to fit the window.
</p>
<p>
See the gist in action at <a href="//bl.ocks.org/wmleler/raw/a734fb2bb3319a2cb386/"
target="_blank">//bl.ocks.org/wmleler/raw/a734fb2bb3319a2cb386/</a>

The source is on github at <a href="https://gist.github.com/wmleler/a734fb2bb3319a2cb386"
target="_blank">https://gist.github.com/wmleler/a734fb2bb3319a2cb386</a>
</p>
<h2>User Interface</h2>
<p>
Initially, the root node of the tree is selected.
Click on any node in the tree to select it; node is then highlighted and
path to it is displayed in toolbar.
Click on any name in path to change the root. The current root is shown in bold.
</p>
<p>
If the center of a node is colored in, then it has (hidden) children:
<ul>
<li>Double-click on the node to expand its immediate children (or if they are showing, to collapse them).</li>
<li>Hold down the shift key and double click a node to expand/collapse all descendent children.</li>
<li>Press the "/" key to set the root of the tree to the currently selected node.
  Press again to reset it back to the original root.</li>
</ul>
</p>
<p>Right-click on a node to bring up a context menu that gives you shortcuts for
  expanding and collapsing nodes, changing the root, and recentering the view.</p>
<table>
  <thead style="font-weight:bold">
    <tr><td>Function</td><td>Tool</td><td>Keyboard shortcut</td><td>Context menu</td><td>Other</td><td>Description</td></tr>
  </thead>
  <tr><td>Zoom In</td><td>+</td><td>+</td><td></td><td>scrollwheel</td></tr>
  <tr><td>Zoom Out</td><td>&minus;</td><td>&minus;</td><td></td><td>scrollwheel</td></tr>
  <tr><td>Rotate CCW</td><td>&#8634;</td><td>"Page Up"</td><td></td><td>shift + scrollwheel</td></tr>
  <tr><td>Rotate CW</td><td>&#8635;</td><td>"Page Down"</td><td></td><td>shift + scrollwheel</td></tr>
  <tr><td>Select Up</td><td>&#8613;</td><td>shift + &uarr;</td><td></td><td></td><td>move selection to previous child</tr>
  <tr><td>Select Down</td><td>&#8615;</td><td>shift + &darr;</td><td></td><td></td><td>move selection to next child</tr>
  <tr><td>Select Parent</td><td></td><td>shift + &larr;</td><td></td><td></td><td>move selection to parent</tr>
  <tr><td>Select Child</td><td></td><td>shift + &rarr;</td><td></td><td></td><td>move selection to first child</tr>
  <tr><td>View Home</td><td>&#8962;</td><td>"Home"</td><td>Center Root</td><td></td><td>reset rotate and zoom</td></tr>
  <tr><td>View Selected</td><td>&#9673;</td><td>"End"</td><td>Center This Node</td><td></td><td>center selection</tr>
  <tr><td>Toggle 1</td><td>1</td><td>space bar</td><td>Node</td><td>double-click</td><td>expand/collapse immediate children</tr>
  <tr><td>Expand Level</td><td>&oplus;</td><td>"Return"</td><td>Expand 1 Level</td><td>shift + double-click</td><td>expand/collapse all children</tr>
  <tr><td>Toggle Root</td><td>/</td><td>/</td><td>Set Root</td><td></td><td>change root to selection (and back)</tr>
</table>
<p>Hover over any tool button to see a popup tooltip containing keyboard shortcuts.</p>
<p>Note that there is no toolbar button for Select Parent or Select Child;
use the keyboard shortcut (shift + arrow key), or the mouse to select any node.</p>
<p>Hold down the alt/option key to slow down the transition animations or the rate of zooming and rotation.</p>
<p>Hold down shift key and press the &oplus; tool to force expand entire tree from selection. This is also available in the context menu as "Expand Full Tree".</p>
<p>Hold down shift key and press the &#8962; tool to reset root.</p>
<img src="thumbnail.png" />
</body>
</html>

radial-tree.css

#toolbar {
  display: flex;
  display: -webkit-box;
  display: moz-box-flex;
  display: -ms-flexbox;
  display: -webkit-flex;
  flex-wrap: wrap;
  position: fixed;
  top: 10px;
  left: 10px;
  font-family: Roboto, Helvetica, sans-serif;
  box-shadow: 1px 1px 3px;
  background-color: #ECEFF1;
}
.tool {
  display: flex;
  flex-direction: column;
  border: solid black 1px;
  padding: 1px;
}
.tlabel {
  text-align: center;
  padding: 3px 2px 1px 2px;
}
.tbuttons {
  display: flex;
  display: -webkit-box;
  display: moz-box-flex;
  display: -ms-flexbox;
  display: -webkit-flex;
  flex-wrap: wrap;
  flex-direction: row;
}
.button {
  border: outset gray 2px;
	border-radius: 4px;
	cursor: pointer;
  padding: 1px 3px;
  min-width: 12px;
  text-align: center;
  margin: 2px;
  font-family: "Courier New", Courier, monospace;
  background-color: white;
}
.button:hover {
  background-color: yellow;
}
.button:active {
  border: inset gray 2px;
}
#selection {
  margin: 2px 5px;
  vertical-align: middle;
  font-family: "Courier New", Courier, monospace;
  color: black;
  background-color: white;
}
#selection span.nodepath:hover {
  background-color: rgba(0, 0, 25, 0.1);
  cursor: pointer;
}
#selection span.nodepath.highlight {
  font-weight: bold;
}
#contextmenu {
  display: none;
  position: absolute;
  border: solid black 1px;
  box-shadow: 2px 2px 3px gray;
  padding: 2px;
  background-color: white;
  font-family: Roboto, Helvetica, sans-serif;
  font-size: 0.9em;
}
#contextmenu div {
  padding: 4px 10px;
  cursor: pointer;
}
#contextmenu div:hover {
  background-color: rgba(0, 0, 25, 0.1);
}
#contextmenu span.expcol {
  pointer-events: none;
}
#help {
  position: relative;
  bottom: -1.8em;
  transform: rotate(270deg);
  -webkit-transform: rotate(270deg);
  -moz-transform: rotate(270deg);
  -o-transform: rotate(270deg);
  width: 1.2em;
}
#help a {
  color: black;
  text-decoration: none;
  background-color: white;
}
#help:hover a {
  background-color: yellow;
}

#tree-container, svg {
  overflow: hidden;
}
.node {
  cursor: pointer;
}
.node circle {
  fill: #fff;
}
.node text {
  font-size: 12px;
  font-family: Roboto, sans-serif;
  text-shadow: 4px 4px 3px white, -4px -4px 3px white;
}
.node text:hover {
  font-size: 1.2em;
  transition: font-size 0.1s;
}
.node text:not(:hover) {
  transition: font-size 1s;
  transition-delay: 0.5s;
}
.link {
  fill: none;
  stroke: #ccc;
  stroke-width: 1.5px;
}