Skip to content

Instantly share code, notes, and snippets.

@billdwhite
Last active March 7, 2016 20:42
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save billdwhite/6929178 to your computer and use it in GitHub Desktop.
Save billdwhite/6929178 to your computer and use it in GitHub Desktop.
d3 flow tree layout
d3.custom.chart.flow = function() {
// public variables with default settings
var margin = {top:10, right:10, bottom:10, left:10}, // defaults
padding = {top:20, right:10, bottom:10, left:10},
transitionDuration = 300,
chartGroup,
container,
svg,
width,
height,
root,
rootNode,
scrollbarAffordance;
var flow = d3.custom.layout.flow()
.margin(margin)
.padding(padding)
.nodeWidth(110)
.nodeHeight(30)
.containerHeight(20);
function chart(selection) {
rootNode = selection.node();
function debounce(fn, timeout) {
var timeoutID = -1;
return function() {
if (timeoutID > -1) {
window.clearTimeout(timeoutID);
}
timeoutID = window.setTimeout(fn, timeout);
}
}
function resize(selectedNode) {
var domContainerWidth = (parseInt(d3.select(rootNode).style("width"))),
domContainerHeight = (parseInt(d3.select(rootNode).style("height"))),
flowWidth = 0;
if (root.height > domContainerHeight) {
scrollbarAffordance = 0;
} else {
scrollbarAffordance = 0;
}
flowWidth = domContainerWidth - scrollbarAffordance;
flow.width(flowWidth);
chart.update(selectedNode);
svg.transition().duration(transitionDuration)
.attr("width", function(d) {
return domContainerWidth;
})
.attr("height", function(d) {
return d.height + margin.top + margin.bottom;
})
.select(".chartGroup")
.attr("width", function(d) {
return flowWidth;
})
.attr("height", function(d) {
return d.height + margin.top + margin.bottom;
})
.select(".background")
.attr("width", function(d) {
return flowWidth;
})
.attr("height", function(d) {
return d.height + margin.top + margin.bottom;
});
}
d3.select(window).on('resize', function() {
debounce(resize, 50)();
});
selection.each(function(arg) {
root = arg;
container = d3.select(this);
var i = 0;
if (!svg) {
svg = container.append("svg")
.attr("class", "svg chartSVG")
.attr("transform", "translate(0, 0)")
.style("shape-rendering", "auto") // shapeRendering options; [crispEdges|geometricPrecision|optimizeSpeed|auto]
.style("text-rendering", "auto"); // textRendering options; [auto|optimizeSpeed|optimizeLegibility|geometricPrecision]
chartGroup = svg.append("svg:g")
.attr("class", "chartGroup");
chartGroup.append("svg:rect")
.attr("class", "background");
}
chart.update = function(source) {
var nodes = flow(root);
function color(d) {
return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
resize(d);
}
// Update the nodes…
var node = chartGroup.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
var nodeEnter = node.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + source.x + "," + source.y + ")";
})
.style("opacity", 1e-6);
// Enter any new nodes at the parent's previous position.
nodeEnter.append("svg:rect")
.attr("class", "background")
.attr("height", function(d) { return d.height; })
.attr("width", function(d) { return d.width; })
.style("fill", color)
.on("click", click);
nodeEnter.each(function(d) {
if (d.children || d._children) {
d3.select(this)
.append("path")
.attr("class", "expander")
.attr("d", "M 0 0 L 6 6 L 0 6 z")
.attr("transform", function(d) {
return d._children ? "translate(8,14)rotate(225)" : "translate(5,8)rotate(315)";
});
d3.select(this).append("svg:text")
.attr("class", "label")
.attr("dy", 13)
.attr("dx", 17)
.text(function(d) { return d.name; });
} else {
d3.select(this).append("svg:text")
.attr("class", "label")
.attr("dy", 13)
.attr("dx", 4)
.text(function(d) { return d.name; });
}
});
// Transition nodes to their new position.
nodeEnter.transition()
.duration(transitionDuration)
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.style("opacity", 1);
var nodeUpdate = node.transition()
.duration(transitionDuration);
nodeUpdate.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.style("opacity", 1)
.select("rect")
.style("fill", color);
nodeUpdate.each(function(d) {
if (d.children || d._children) {
d3.select(this).select(".expander").transition()
.duration(transitionDuration)
.attr("transform", function(d) {
return d._children ? "translate(8,14)rotate(225)" : "translate(5,8)rotate(315)";
});
}
});
nodeUpdate.select(".background")
.attr("height", function(d) { return d.height; })
.attr("width", function(d) { return d.width; });
// Transition exiting nodes to the parent's new position.
node.exit().transition()
.duration(transitionDuration)
.attr("transform", function(d) { return "translate(" + source.x + "," + source.y + ")"; })
.style("opacity", 1e-6)
.remove();
};
resize(root);
chart.update(root);
});
}
chart.width = function(value) {
if (!arguments.length) return width;
width = parseInt(value);
return this;
};
chart.height = function(value) {
if (!arguments.length) return height;
height = parseInt(value);
return this;
};
chart.margin = function(_) {
if (!arguments.length) return margin;
margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
return chart;
};
return chart;
};
d3.custom = {};
d3.custom.chart = {};
d3.custom.layout = {};
{
"id" : 1,
"name" : "flare",
"children" : [{
"id" : 2,
"name" : "analytics",
"children" : [{
"id" : 3,
"name" : "cluster",
"children" : [{
"id" : 4,
"name" : "AgglomerativeCluster",
"value" : 3938
},
{
"id" : 5,
"name" : "CommunityStructure",
"value" : 3812
},
{
"id" : 6,
"name" : "HierarchicalCluster",
"value" : 6714
},
{
"id" : 7,
"name" : "MergeEdge",
"value" : 743
}]
},
{
"id" : 8,
"name" : "graph",
"children" : [{
"id" : 9,
"name" : "BetweennessCentrality",
"value" : 3534
},
{
"id" : 10,
"name" : "LinkDistance",
"value" : 5731
},
{
"id" : 11,
"name" : "MaxFlowMinCut",
"value" : 7840
},
{
"id" : 12,
"name" : "ShortestPaths",
"value" : 5914
},
{
"id" : 13,
"name" : "SpanningTree",
"value" : 3416
}]
},
{
"id" : 14,
"name" : "optimization",
"children" : [{
"id" : 15,
"name" : "AspectRatioBanker",
"value" : 7074
}]
}]
},
{
"id" : 16,
"name" : "animate",
"children" : [{
"id" : 17,
"name" : "Easing",
"value" : 17010
},
{
"id" : 18,
"name" : "FunctionSequence",
"value" : 5842
},
{
"id" : 19,
"name" : "interpolate",
"children" : [{
"id" : 20,
"name" : "ArrayInterpolator",
"value" : 1983
},
{
"id" : 21,
"name" : "ColorInterpolator",
"value" : 2047
},
{
"id" : 22,
"name" : "DateInterpolator",
"value" : 1375
},
{
"id" : 23,
"name" : "Interpolator",
"value" : 8746
},
{
"id" : 24,
"name" : "MatrixInterpolator",
"value" : 2202
},
{
"id" : 25,
"name" : "NumberInterpolator",
"value" : 1382
},
{
"id" : 26,
"name" : "ObjectInterpolator",
"value" : 1629
},
{
"id" : 27,
"name" : "PointInterpolator",
"value" : 1675
},
{
"id" : 28,
"name" : "RectangleInterpolator",
"value" : 2042
}]
},
{
"id" : 29,
"name" : "ISchedulable",
"value" : 1041
},
{
"id" : 30,
"name" : "Parallel",
"value" : 5176
},
{
"id" : 31,
"name" : "Pause",
"value" : 449
},
{
"id" : 32,
"name" : "Scheduler",
"value" : 5593
},
{
"id" : 33,
"name" : "Sequence",
"value" : 5534
},
{
"id" : 34,
"name" : "Transition",
"value" : 9201
},
{
"id" : 35,
"name" : "Transitioner",
"value" : 19975
},
{
"id" : 36,
"name" : "TransitionEvent",
"value" : 1116
},
{
"id" : 37,
"name" : "Tween",
"value" : 6006
}]
},
{
"id" : 38,
"name" : "data",
"children" : [{
"id" : 39,
"name" : "converters",
"children" : [{
"id" : 40,
"name" : "Converters",
"value" : 721
},
{
"id" : 41,
"name" : "DelimitedTextConverter",
"value" : 4294
},
{
"id" : 42,
"name" : "GraphMLConverter",
"value" : 9800
},
{
"id" : 43,
"name" : "IDataConverter",
"value" : 1314
},
{
"id" : 44,
"name" : "JSONConverter",
"value" : 2220
}]
},
{
"id" : 45,
"name" : "DataField",
"value" : 1759
},
{
"id" : 46,
"name" : "DataSchema",
"value" : 2165
},
{
"id" : 47,
"name" : "DataSet",
"value" : 586
},
{
"id" : 48,
"name" : "DataSource",
"value" : 3331
},
{
"id" : 49,
"name" : "DataTable",
"value" : 772
},
{
"id" : 50,
"name" : "DataUtil",
"value" : 3322
}]
},
{
"id" : 51,
"name" : "display",
"children" : [{
"id" : 52,
"name" : "DirtySprite",
"value" : 8833
},
{
"id" : 53,
"name" : "LineSprite",
"value" : 1732
},
{
"id" : 54,
"name" : "RectSprite",
"value" : 3623
},
{
"id" : 55,
"name" : "TextSprite",
"value" : 10066
}]
},
{
"id" : 56,
"name" : "flex",
"children" : [{
"id" : 57,
"name" : "FlareVis",
"value" : 4116
}]
},
{
"id" : 58,
"name" : "physics",
"children" : [{
"id" : 59,
"name" : "DragForce",
"value" : 1082
},
{
"id" : 60,
"name" : "GravityForce",
"value" : 1336
},
{
"id" : 61,
"name" : "IForce",
"value" : 319
},
{
"id" : 62,
"name" : "NBodyForce",
"value" : 10498
},
{
"id" : 63,
"name" : "Particle",
"value" : 2822
},
{
"id" : 64,
"name" : "Simulation",
"value" : 9983
},
{
"id" : 65,
"name" : "Spring",
"value" : 2213
},
{
"id" : 66,
"name" : "SpringForce",
"value" : 1681
}]
},
{
"id" : 67,
"name" : "query",
"children" : [{
"id" : 68,
"name" : "AggregateExpression",
"value" : 1616
},
{
"id" : 69,
"name" : "And",
"value" : 1027
},
{
"id" : 70,
"name" : "Arithmetic",
"value" : 3891
},
{
"id" : 71,
"name" : "Average",
"value" : 891
},
{
"id" : 72,
"name" : "BinaryExpression",
"value" : 2893
},
{
"id" : 73,
"name" : "Comparison",
"value" : 5103
},
{
"id" : 74,
"name" : "CompositeExpression",
"value" : 3677
},
{
"id" : 75,
"name" : "Count",
"value" : 781
},
{
"id" : 76,
"name" : "DateUtil",
"value" : 4141
},
{
"id" : 77,
"name" : "Distinct",
"value" : 933
},
{
"id" : 78,
"name" : "Expression",
"value" : 5130
},
{
"id" : 79,
"name" : "ExpressionIterator",
"value" : 3617
},
{
"id" : 80,
"name" : "Fn",
"value" : 3240
},
{
"id" : 81,
"name" : "If",
"value" : 2732
},
{
"id" : 82,
"name" : "IsA",
"value" : 2039
},
{
"id" : 83,
"name" : "Literal",
"value" : 1214
},
{
"id" : 84,
"name" : "Match",
"value" : 3748
},
{
"id" : 85,
"name" : "Maximum",
"value" : 843
},
{
"id" : 86,
"name" : "methods",
"children" : [{
"id" : 87,
"name" : "add",
"value" : 593
},
{
"id" : 88,
"name" : "and",
"value" : 330
},
{
"id" : 89,
"name" : "average",
"value" : 287
},
{
"id" : 90,
"name" : "count",
"value" : 277
},
{
"id" : 91,
"name" : "distinct",
"value" : 292
},
{
"id" : 92,
"name" : "div",
"value" : 595
},
{
"id" : 93,
"name" : "eq",
"value" : 594
},
{
"id" : 94,
"name" : "fn",
"value" : 460
},
{
"id" : 95,
"name" : "gt",
"value" : 603
},
{
"id" : 96,
"name" : "gte",
"value" : 625
},
{
"id" : 97,
"name" : "iff",
"value" : 748
},
{
"id" : 98,
"name" : "isa",
"value" : 461
},
{
"id" : 99,
"name" : "lt",
"value" : 597
},
{
"id" : 100,
"name" : "lte",
"value" : 619
},
{
"id" : 101,
"name" : "max",
"value" : 283
},
{
"id" : 102,
"name" : "min",
"value" : 283
},
{
"id" : 103,
"name" : "mod",
"value" : 591
},
{
"id" : 104,
"name" : "mul",
"value" : 603
},
{
"id" : 105,
"name" : "neq",
"value" : 599
},
{
"id" : 106,
"name" : "not",
"value" : 386
},
{
"id" : 107,
"name" : "or",
"value" : 323
},
{
"id" : 108,
"name" : "orderby",
"value" : 307
},
{
"id" : 109,
"name" : "range",
"value" : 772
},
{
"id" : 110,
"name" : "select",
"value" : 296
},
{
"id" : 111,
"name" : "stddev",
"value" : 363
},
{
"id" : 112,
"name" : "sub",
"value" : 600
},
{
"id" : 113,
"name" : "sum",
"value" : 280
},
{
"id" : 114,
"name" : "update",
"value" : 307
},
{
"id" : 115,
"name" : "variance",
"value" : 335
},
{
"id" : 116,
"name" : "where",
"value" : 299
},
{
"id" : 117,
"name" : "xor",
"value" : 354
},
{
"id" : 118,
"name" : "_",
"value" : 264
}]
},
{
"id" : 119,
"name" : "Minimum",
"value" : 843
},
{
"id" : 120,
"name" : "Not",
"value" : 1554
},
{
"id" : 121,
"name" : "Or",
"value" : 970
},
{
"id" : 122,
"name" : "Query",
"value" : 13896
},
{
"id" : 123,
"name" : "Range",
"value" : 1594
},
{
"id" : 124,
"name" : "StringUtil",
"value" : 4130
},
{
"id" : 125,
"name" : "Sum",
"value" : 791
},
{
"id" : 126,
"name" : "Variable",
"value" : 1124
},
{
"id" : 127,
"name" : "Variance",
"value" : 1876
},
{
"id" : 128,
"name" : "Xor",
"value" : 1101
}]
},
{
"id" : 129,
"name" : "scale",
"children" : [{
"id" : 130,
"name" : "IScaleMap",
"value" : 2105
},
{
"id" : 131,
"name" : "LinearScale",
"value" : 1316
},
{
"id" : 132,
"name" : "LogScale",
"value" : 3151
},
{
"id" : 133,
"name" : "OrdinalScale",
"value" : 3770
},
{
"id" : 134,
"name" : "QuantileScale",
"value" : 2435
},
{
"id" : 135,
"name" : "QuantitativeScale",
"value" : 4839
},
{
"id" : 136,
"name" : "RootScale",
"value" : 1756
},
{
"id" : 137,
"name" : "Scale",
"value" : 4268
},
{
"id" : 138,
"name" : "ScaleType",
"value" : 1821
},
{
"id" : 139,
"name" : "TimeScale",
"value" : 5833
}]
},
{
"id" : 140,
"name" : "util",
"children" : [{
"id" : 141,
"name" : "Arrays",
"value" : 8258
},
{
"id" : 142,
"name" : "Colors",
"value" : 10001
},
{
"id" : 143,
"name" : "Dates",
"value" : 8217
},
{
"id" : 144,
"name" : "Displays",
"value" : 12555
},
{
"id" : 145,
"name" : "Filter",
"value" : 2324
},
{
"id" : 146,
"name" : "Geometry",
"value" : 10993
},
{
"id" : 147,
"name" : "heap",
"children" : [{
"id" : 148,
"name" : "FibonacciHeap",
"value" : 9354
},
{
"id" : 149,
"name" : "HeapNode",
"value" : 1233
}]
},
{
"id" : 150,
"name" : "IEvaluable",
"value" : 335
},
{
"id" : 151,
"name" : "IPredicate",
"value" : 383
},
{
"id" : 152,
"name" : "IValueProxy",
"value" : 874
},
{
"id" : 153,
"name" : "math",
"children" : [{
"id" : 154,
"name" : "DenseMatrix",
"value" : 3165
},
{
"id" : 155,
"name" : "IMatrix",
"value" : 2815
},
{
"id" : 156,
"name" : "SparseMatrix",
"value" : 3366
}]
},
{
"id" : 157,
"name" : "Maths",
"value" : 17705
},
{
"id" : 158,
"name" : "Orientation",
"value" : 1486
},
{
"id" : 159,
"name" : "palette",
"children" : [{
"id" : 160,
"name" : "ColorPalette",
"value" : 6367
},
{
"id" : 161,
"name" : "Palette",
"value" : 1229
},
{
"id" : 162,
"name" : "ShapePalette",
"value" : 2059
},
{
"id" : 163,
"name" : "SizePalette",
"value" : 2291
}]
},
{
"id" : 164,
"name" : "Property",
"value" : 5559
},
{
"id" : 165,
"name" : "Shapes",
"value" : 19118
},
{
"id" : 166,
"name" : "Sort",
"value" : 6887
},
{
"id" : 167,
"name" : "Stats",
"value" : 6557
},
{
"id" : 168,
"name" : "Strings",
"value" : 22026
}]
},
{
"id" : 169,
"name" : "vis",
"children" : [{
"id" : 170,
"name" : "axis",
"children" : [{
"id" : 171,
"name" : "Axes",
"value" : 1302
},
{
"id" : 172,
"name" : "Axis",
"value" : 24593
},
{
"id" : 173,
"name" : "AxisGridLine",
"value" : 652
},
{
"id" : 174,
"name" : "AxisLabel",
"value" : 636
},
{
"id" : 175,
"name" : "CartesianAxes",
"value" : 6703
}]
},
{
"id" : 176,
"name" : "controls",
"children" : [{
"id" : 177,
"name" : "AnchorControl",
"value" : 2138
},
{
"id" : 178,
"name" : "ClickControl",
"value" : 3824
},
{
"id" : 179,
"name" : "Control",
"value" : 1353
},
{
"id" : 180,
"name" : "ControlList",
"value" : 4665
},
{
"id" : 181,
"name" : "DragControl",
"value" : 2649
},
{
"id" : 182,
"name" : "ExpandControl",
"value" : 2832
},
{
"id" : 183,
"name" : "HoverControl",
"value" : 4896
},
{
"id" : 184,
"name" : "IControl",
"value" : 763
},
{
"id" : 185,
"name" : "PanZoomControl",
"value" : 5222
},
{
"id" : 186,
"name" : "SelectionControl",
"value" : 7862
},
{
"id" : 187,
"name" : "TooltipControl",
"value" : 8435
}]
},
{
"id" : 188,
"name" : "otherdata",
"children" : [{
"id" : 189,
"name" : "Data",
"value" : 20544
},
{
"id" : 190,
"name" : "DataList",
"value" : 19788
},
{
"id" : 191,
"name" : "DataSprite",
"value" : 10349
},
{
"id" : 192,
"name" : "EdgeSprite",
"value" : 3301
},
{
"id" : 193,
"name" : "NodeSprite",
"value" : 19382
},
{
"id" : 194,
"name" : "render",
"children" : [{
"id" : 195,
"name" : "ArrowType",
"value" : 698
},
{
"id" : 196,
"name" : "EdgeRenderer",
"value" : 5569
},
{
"id" : 197,
"name" : "IRenderer",
"value" : 353
},
{
"id" : 198,
"name" : "ShapeRenderer",
"value" : 2247
}]
},
{
"id" : 199,
"name" : "ScaleBinding",
"value" : 11275
},
{
"id" : 200,
"name" : "Tree",
"value" : 7147
},
{
"id" : 201,
"name" : "TreeBuilder",
"value" : 9930
}]
},
{
"id" : 202,
"name" : "events",
"children" : [{
"id" : 203,
"name" : "DataEvent",
"value" : 2313
},
{
"id" : 204,
"name" : "SelectionEvent",
"value" : 1880
},
{
"id" : 205,
"name" : "TooltipEvent",
"value" : 1701
},
{
"id" : 206,
"name" : "VisualizationEvent",
"value" : 1117
}]
},
{
"id" : 207,
"name" : "legend",
"children" : [{
"id" : 208,
"name" : "Legend",
"value" : 20859
},
{
"id" : 209,
"name" : "LegendItem",
"value" : 4614
},
{
"id" : 210,
"name" : "LegendRange",
"value" : 10530
}]
},
{
"id" : 211,
"name" : "operator",
"children" : [{
"id" : 212,
"name" : "distortion",
"children" : [{
"id" : 213,
"name" : "BifocalDistortion",
"value" : 4461
},
{
"id" : 214,
"name" : "Distortion",
"value" : 6314
},
{
"id" : 215,
"name" : "FisheyeDistortion",
"value" : 3444
}]
},
{
"id" : 216,
"name" : "encoder",
"children" : [{
"id" : 217,
"name" : "ColorEncoder",
"value" : 3179
},
{
"id" : 218,
"name" : "Encoder",
"value" : 4060
},
{
"id" : 219,
"name" : "PropertyEncoder",
"value" : 4138
},
{
"id" : 220,
"name" : "ShapeEncoder",
"value" : 1690
},
{
"id" : 221,
"name" : "SizeEncoder",
"value" : 1830
}]
},
{
"id" : 222,
"name" : "filter",
"children" : [{
"id" : 223,
"name" : "FisheyeTreeFilter",
"value" : 5219
},
{
"id" : 224,
"name" : "GraphDistanceFilter",
"value" : 3165
},
{
"id" : 225,
"name" : "VisibilityFilter",
"value" : 3509
}]
},
{
"id" : 226,
"name" : "IOperator",
"value" : 1286
},
{
"id" : 227,
"name" : "label",
"children" : [{
"id" : 228,
"name" : "Labeler",
"value" : 9956
},
{
"id" : 229,
"name" : "RadialLabeler",
"value" : 3899
},
{
"id" : 230,
"name" : "StackedAreaLabeler",
"value" : 3202
}]
},
{
"id" : 231,
"name" : "layout",
"children" : [{
"id" : 232,
"name" : "AxisLayout",
"value" : 6725
},
{
"id" : 233,
"name" : "BundledEdgeRouter",
"value" : 3727
},
{
"id" : 234,
"name" : "CircleLayout",
"value" : 9317
},
{
"id" : 235,
"name" : "CirclePackingLayout",
"value" : 12003
},
{
"id" : 236,
"name" : "DendrogramLayout",
"value" : 4853
},
{
"id" : 237,
"name" : "ForceDirectedLayout",
"value" : 8411
},
{
"id" : 238,
"name" : "IcicleTreeLayout",
"value" : 4864
},
{
"id" : 239,
"name" : "IndentedTreeLayout",
"value" : 3174
},
{
"id" : 240,
"name" : "Layout",
"value" : 7881
},
{
"id" : 241,
"name" : "NodeLinkTreeLayout",
"value" : 12870
},
{
"id" : 242,
"name" : "PieLayout",
"value" : 2728
},
{
"id" : 243,
"name" : "RadialTreeLayout",
"value" : 12348
},
{
"id" : 244,
"name" : "RandomLayout",
"value" : 870
},
{
"id" : 245,
"name" : "StackedAreaLayout",
"value" : 9121
},
{
"id" : 246,
"name" : "TreeMapLayout",
"value" : 9191
}]
},
{
"id" : 247,
"name" : "Operator",
"value" : 2490
},
{
"id" : 248,
"name" : "OperatorList",
"value" : 5248
},
{
"id" : 249,
"name" : "OperatorSequence",
"value" : 4190
},
{
"id" : 250,
"name" : "OperatorSwitch",
"value" : 2581
},
{
"id" : 251,
"name" : "SortOperator",
"value" : 2023
}]
},
{
"id" : 252,
"name" : "Visualization",
"value" : 16540
}]
}]
}
<html>
<head>
<meta charset="utf-8">
<title>Flow Tree Example</title>
<style>
body {
width: 100%;
height: 100%;
margin: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.container {
background-color: #DDDDDD;
}
.flowtree {
background-color: #caddcc;
}
.chartGroup .background {
fill: #FFFFFF;
stroke-width: 0.5;
}
.node rect {
cursor: pointer;
fill: #FFFFFF;
fill-opacity: 0.5;
stroke: #333333;
stroke-width: 1px;
}
.node text {
font: 10px sans-serif;
pointer-events: none;
}
path.link {
fill: none;
stroke: #9ecae1;
stroke-width: 1.5px;
}
</style>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="core.js"></script>
<script src="chart.js"></script>
<script src="layout.js"></script>
</head>
<body>
<div id="container" class="container">
<div id="flowtree" class="flowtree"></div>
</div>
<script type="text/javascript">
d3.json("flare.json", function(data) {
var flowTree = d3.custom.chart.flow();
d3.select('#flowtree')
.datum(data)
.call(flowTree)
.on("mouseover.customHover", function() {
console.log("customHover");
})
.on("resize.custom", function() {
console.log("resize.custom");
})
});
</script>
</body>
</html>
d3.custom.layout.flow = function() {
var hierarchy = d3.layout.hierarchy().sort(null).value(null),
nodeWidth = 125,
nodeHeight = 50,
containerHeight = 20,
width = 900,
height = 0,
padding = {top:20, left:10, bottom:10, right:10},
margin = {top:10, left:10, bottom:10, right:10};
function flow(d, i) {
var nodes = hierarchy.call(this, d, i),
root = nodes[0];
function firstWalk(node) {
var children = node.children;
if (children && children.length > 0) {
var n = children.length,
i = -1,
child;
while (++i < n) {
child = children[i];
firstWalk(child);
}
gridLayout(node, children, node.depth);
} else {
node.width = node._children ? width - (node.depth * (padding.left + padding.right)) - (padding.left + padding.right) : nodeWidth;
node.height = node._children ? containerHeight : nodeHeight;
}
}
function secondWalk(node) {
var children = node.children;
if (children && children.length > 0) {
var i = -1,
n = children.length,
child;
while (++i < n) {
child = children[i];
child.x += node.x;
child.y += node.y;
secondWalk(child);
}
}
}
function gridLayout(node, children, depth) {
var paddingValue = node.parent ? padding.left + padding.right : margin.left + margin.right;
var availableWidth = width - (depth * (paddingValue)) - (paddingValue),
currentX = padding.left,
currentY = padding.top,
tallestChildHeight = 0;
children.forEach(function(child) {
if ((currentX + child.width + padding.right) >= availableWidth) {
currentX = padding.right;
currentY += tallestChildHeight;
tallestChildHeight = 0;
}
child.x = currentX;
child.y = currentY;
currentX += child.width + padding.right;
tallestChildHeight = Math.max(tallestChildHeight, child.height + padding.bottom);
});
node.width = availableWidth;
node.height = currentY + tallestChildHeight;
node.x = node.parent ? padding.left : margin.left;
node.y = node.parent ? padding.top : margin.top;
}
firstWalk(root);
secondWalk(root);
height = root.height;
return nodes;
}
flow.padding = function(_) {
if (!arguments.length) return padding;
padding.top = typeof _.top != 'undefined' ? _.top : padding.top;
padding.right = typeof _.right != 'undefined' ? _.right : padding.right;
padding.bottom = typeof _.bottom != 'undefined' ? _.bottom : padding.bottom;
padding.left = typeof _.left != 'undefined' ? _.left : padding.left;
return this;
};
flow.margin = function(_) {
if (!arguments.length) return margin;
flow.top = typeof _.top != 'undefined' ? _.top : flow.top;
flow.right = typeof _.right != 'undefined' ? _.right : flow.right;
flow.bottom = typeof _.bottom != 'undefined' ? _.bottom : flow.bottom;
flow.left = typeof _.left != 'undefined' ? _.left : flow.left;
return this;
};
flow.width = function(value) {
if (!arguments.length) return width;
width = parseInt(value);
return this;
};
flow.height = function(value) {
if (!arguments.length) return height;
height = parseInt(value);
return this;
};
flow.nodeWidth = function(value) {
if (!arguments.length) return nodeWidth;
nodeWidth = parseInt(value);
return this;
};
flow.nodeHeight = function(value) {
if (!arguments.length) return nodeHeight;
nodeHeight = parseInt(value);
return this;
};
flow.containerHeight = function(value) {
if (!arguments.length) return containerHeight;
containerHeight = parseInt(value);
return this;
};
return flow;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment