Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active August 29, 2015 13:55
Show Gist options
  • Save nitaku/8784942 to your computer and use it in GitHub Desktop.
Save nitaku/8784942 to your computer and use it in GitHub Desktop.
Jigsaw treemap (Hilbert)
[{
"name": "flare.analytics.cluster.AgglomerativeCluster",
"size": 3938,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.DataList",
"flare.util.math.IMatrix",
"flare.analytics.cluster.MergeEdge",
"flare.analytics.cluster.HierarchicalCluster",
"flare.vis.data.Data"]
},
{
"name": "flare.analytics.cluster.CommunityStructure",
"size": 3812,
"imports": ["flare.analytics.cluster.HierarchicalCluster",
"flare.animate.Transitioner",
"flare.vis.data.DataList",
"flare.analytics.cluster.MergeEdge",
"flare.util.math.IMatrix"]
},
{
"name": "flare.analytics.cluster.HierarchicalCluster",
"size": 6714,
"imports": ["flare.vis.data.EdgeSprite",
"flare.vis.data.NodeSprite",
"flare.vis.data.DataList",
"flare.vis.data.Tree",
"flare.util.Arrays",
"flare.analytics.cluster.MergeEdge",
"flare.util.Sort",
"flare.vis.operator.Operator",
"flare.util.Property",
"flare.vis.data.Data"]
},
{
"name": "flare.analytics.cluster.MergeEdge",
"size": 743,
"imports": []
},
{
"name": "flare.analytics.graph.BetweennessCentrality",
"size": 3534,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.vis.data.DataList",
"flare.util.Arrays",
"flare.vis.data.Data",
"flare.util.Property",
"flare.vis.operator.Operator"]
},
{
"name": "flare.analytics.graph.LinkDistance",
"size": 5731,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.vis.data.EdgeSprite",
"flare.analytics.graph.ShortestPaths",
"flare.vis.data.Data",
"flare.util.Property",
"flare.vis.operator.Operator"]
},
{
"name": "flare.analytics.graph.MaxFlowMinCut",
"size": 7840,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.vis.data.EdgeSprite",
"flare.vis.data.Data",
"flare.util.Property",
"flare.vis.operator.Operator"]
},
{
"name": "flare.analytics.graph.ShortestPaths",
"size": 5914,
"imports": ["flare.vis.data.EdgeSprite",
"flare.vis.data.NodeSprite",
"flare.animate.Transitioner",
"flare.vis.operator.Operator",
"flare.util.heap.HeapNode",
"flare.util.heap.FibonacciHeap",
"flare.util.Property",
"flare.vis.data.Data"]
},
{
"name": "flare.analytics.graph.SpanningTree",
"size": 3416,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.vis.operator.IOperator",
"flare.vis.Visualization",
"flare.vis.data.TreeBuilder",
"flare.vis.operator.Operator"]
},
{
"name": "flare.analytics.optimization.AspectRatioBanker",
"size": 7074,
"imports": ["flare.animate.Transitioner",
"flare.util.Arrays",
"flare.vis.data.DataSprite",
"flare.scale.Scale",
"flare.vis.axis.CartesianAxes",
"flare.vis.Visualization",
"flare.util.Property",
"flare.vis.operator.Operator"]
},
{
"name": "flare.animate.Easing",
"size": 17010,
"imports": ["flare.animate.Transition"]
},
{
"name": "flare.animate.FunctionSequence",
"size": 5842,
"imports": ["flare.util.Maths",
"flare.animate.Transition",
"flare.util.Arrays",
"flare.animate.Sequence",
"flare.animate.Transitioner"]
},
{
"name": "flare.animate.interpolate.ArrayInterpolator",
"size": 1983,
"imports": ["flare.util.Arrays",
"flare.animate.interpolate.Interpolator"]
},
{
"name": "flare.animate.interpolate.ColorInterpolator",
"size": 2047,
"imports": ["flare.animate.interpolate.Interpolator"]
},
{
"name": "flare.animate.interpolate.DateInterpolator",
"size": 1375,
"imports": ["flare.animate.interpolate.Interpolator"]
},
{
"name": "flare.animate.interpolate.Interpolator",
"size": 8746,
"imports": ["flare.animate.interpolate.NumberInterpolator",
"flare.animate.interpolate.ColorInterpolator",
"flare.animate.interpolate.PointInterpolator",
"flare.animate.interpolate.ObjectInterpolator",
"flare.animate.interpolate.MatrixInterpolator",
"flare.animate.interpolate.RectangleInterpolator",
"flare.animate.interpolate.DateInterpolator",
"flare.util.Property",
"flare.animate.interpolate.ArrayInterpolator"]
},
{
"name": "flare.animate.interpolate.MatrixInterpolator",
"size": 2202,
"imports": ["flare.animate.interpolate.Interpolator"]
},
{
"name": "flare.animate.interpolate.NumberInterpolator",
"size": 1382,
"imports": ["flare.animate.interpolate.Interpolator"]
},
{
"name": "flare.animate.interpolate.ObjectInterpolator",
"size": 1629,
"imports": ["flare.animate.interpolate.Interpolator"]
},
{
"name": "flare.animate.interpolate.PointInterpolator",
"size": 1675,
"imports": ["flare.animate.interpolate.Interpolator"]
},
{
"name": "flare.animate.interpolate.RectangleInterpolator",
"size": 2042,
"imports": ["flare.animate.interpolate.Interpolator"]
},
{
"name": "flare.animate.ISchedulable",
"size": 1041,
"imports": ["flare.animate.Scheduler"]
},
{
"name": "flare.animate.Parallel",
"size": 5176,
"imports": ["flare.animate.Easing",
"flare.animate.Transition",
"flare.util.Arrays"]
},
{
"name": "flare.animate.Pause",
"size": 449,
"imports": ["flare.animate.Transition"]
},
{
"name": "flare.animate.Scheduler",
"size": 5593,
"imports": ["flare.animate.ISchedulable",
"flare.animate.Pause",
"flare.animate.Transition"]
},
{
"name": "flare.animate.Sequence",
"size": 5534,
"imports": ["flare.animate.Easing",
"flare.util.Maths",
"flare.animate.Transition",
"flare.util.Arrays"]
},
{
"name": "flare.animate.Transition",
"size": 9201,
"imports": ["flare.animate.Transitioner",
"flare.animate.TransitionEvent",
"flare.animate.Scheduler",
"flare.animate.Pause",
"flare.animate.Parallel",
"flare.animate.Easing",
"flare.animate.Sequence",
"flare.animate.ISchedulable",
"flare.util.Maths",
"flare.animate.Tween"]
},
{
"name": "flare.animate.Transitioner",
"size": 19975,
"imports": ["flare.util.IValueProxy",
"flare.animate.Parallel",
"flare.animate.Easing",
"flare.animate.Sequence",
"flare.animate.Transition",
"flare.animate.Tween",
"flare.util.Property"]
},
{
"name": "flare.animate.TransitionEvent",
"size": 1116,
"imports": ["flare.animate.Transition"]
},
{
"name": "flare.animate.Tween",
"size": 6006,
"imports": ["flare.animate.Transitioner",
"flare.animate.Transition",
"flare.animate.interpolate.Interpolator",
"flare.util.Property"]
},
{
"name": "flare.data.converters.Converters",
"size": 721,
"imports": ["flare.data.converters.IDataConverter",
"flare.data.converters.GraphMLConverter",
"flare.data.converters.JSONConverter",
"flare.data.converters.DelimitedTextConverter"]
},
{
"name": "flare.data.converters.DelimitedTextConverter",
"size": 4294,
"imports": ["flare.data.DataSet",
"flare.data.DataUtil",
"flare.data.DataTable",
"flare.data.converters.IDataConverter",
"flare.data.DataSchema",
"flare.data.DataField"]
},
{
"name": "flare.data.converters.GraphMLConverter",
"size": 9800,
"imports": ["flare.data.DataSet",
"flare.data.DataUtil",
"flare.data.DataTable",
"flare.data.converters.IDataConverter",
"flare.data.DataSchema",
"flare.data.DataField"]
},
{
"name": "flare.data.converters.IDataConverter",
"size": 1314,
"imports": ["flare.data.DataSet",
"flare.data.DataSchema"]
},
{
"name": "flare.data.converters.JSONConverter",
"size": 2220,
"imports": ["flare.data.DataSet",
"flare.data.DataUtil",
"flare.data.DataTable",
"flare.data.converters.IDataConverter",
"flare.data.DataSchema",
"flare.data.DataField",
"flare.util.Property"]
},
{
"name": "flare.data.DataField",
"size": 1759,
"imports": ["flare.data.DataUtil"]
},
{
"name": "flare.data.DataSchema",
"size": 2165,
"imports": ["flare.data.DataField",
"flare.util.Arrays"]
},
{
"name": "flare.data.DataSet",
"size": 586,
"imports": ["flare.data.DataTable"]
},
{
"name": "flare.data.DataSource",
"size": 3331,
"imports": ["flare.data.converters.IDataConverter",
"flare.data.converters.Converters",
"flare.data.DataSchema"]
},
{
"name": "flare.data.DataTable",
"size": 772,
"imports": ["flare.data.DataSchema"]
},
{
"name": "flare.data.DataUtil",
"size": 3322,
"imports": ["flare.data.DataField",
"flare.data.DataSchema"]
},
{
"name": "flare.display.DirtySprite",
"size": 8833,
"imports": []
},
{
"name": "flare.display.LineSprite",
"size": 1732,
"imports": ["flare.display.DirtySprite"]
},
{
"name": "flare.display.RectSprite",
"size": 3623,
"imports": ["flare.util.Colors",
"flare.display.DirtySprite"]
},
{
"name": "flare.display.TextSprite",
"size": 10066,
"imports": ["flare.display.DirtySprite"]
},
{
"name": "flare.flex.FlareVis",
"size": 4116,
"imports": ["flare.display.DirtySprite",
"flare.data.DataSet",
"flare.vis.Visualization",
"flare.vis.axis.CartesianAxes",
"flare.vis.axis.Axes",
"flare.vis.data.Data"]
},
{
"name": "flare.physics.DragForce",
"size": 1082,
"imports": ["flare.physics.Simulation",
"flare.physics.Particle",
"flare.physics.IForce"]
},
{
"name": "flare.physics.GravityForce",
"size": 1336,
"imports": ["flare.physics.Simulation",
"flare.physics.Particle",
"flare.physics.IForce"]
},
{
"name": "flare.physics.IForce",
"size": 319,
"imports": ["flare.physics.Simulation"]
},
{
"name": "flare.physics.NBodyForce",
"size": 10498,
"imports": ["flare.physics.Simulation",
"flare.physics.Particle",
"flare.physics.IForce"]
},
{
"name": "flare.physics.Particle",
"size": 2822,
"imports": []
},
{
"name": "flare.physics.Simulation",
"size": 9983,
"imports": ["flare.physics.Particle",
"flare.physics.NBodyForce",
"flare.physics.DragForce",
"flare.physics.GravityForce",
"flare.physics.Spring",
"flare.physics.SpringForce",
"flare.physics.IForce"]
},
{
"name": "flare.physics.Spring",
"size": 2213,
"imports": ["flare.physics.Particle"]
},
{
"name": "flare.physics.SpringForce",
"size": 1681,
"imports": ["flare.physics.Simulation",
"flare.physics.Particle",
"flare.physics.Spring",
"flare.physics.IForce"]
},
{
"name": "flare.query.AggregateExpression",
"size": 1616,
"imports": ["flare.query.Expression"]
},
{
"name": "flare.query.And",
"size": 1027,
"imports": ["flare.query.CompositeExpression",
"flare.query.Expression"]
},
{
"name": "flare.query.Arithmetic",
"size": 3891,
"imports": ["flare.query.BinaryExpression",
"flare.query.Expression"]
},
{
"name": "flare.query.Average",
"size": 891,
"imports": ["flare.query.Expression",
"flare.query.AggregateExpression"]
},
{
"name": "flare.query.BinaryExpression",
"size": 2893,
"imports": ["flare.query.Expression"]
},
{
"name": "flare.query.Comparison",
"size": 5103,
"imports": ["flare.query.Not",
"flare.query.BinaryExpression",
"flare.query.Expression",
"flare.query.Or"]
},
{
"name": "flare.query.CompositeExpression",
"size": 3677,
"imports": ["flare.query.Expression",
"flare.query.If"]
},
{
"name": "flare.query.Count",
"size": 781,
"imports": ["flare.query.Expression",
"flare.query.AggregateExpression"]
},
{
"name": "flare.query.DateUtil",
"size": 4141,
"imports": ["flare.query.Fn"]
},
{
"name": "flare.query.Distinct",
"size": 933,
"imports": ["flare.query.Expression",
"flare.query.AggregateExpression"]
},
{
"name": "flare.query.Expression",
"size": 5130,
"imports": ["flare.query.Variable",
"flare.query.IsA",
"flare.query.ExpressionIterator",
"flare.util.IPredicate",
"flare.query.Literal",
"flare.util.IEvaluable",
"flare.query.If"]
},
{
"name": "flare.query.ExpressionIterator",
"size": 3617,
"imports": ["flare.query.Expression"]
},
{
"name": "flare.query.Fn",
"size": 3240,
"imports": ["flare.query.DateUtil",
"flare.query.CompositeExpression",
"flare.query.Expression",
"flare.query.StringUtil"]
},
{
"name": "flare.query.If",
"size": 2732,
"imports": ["flare.query.Expression"]
},
{
"name": "flare.query.IsA",
"size": 2039,
"imports": ["flare.query.Expression",
"flare.query.If"]
},
{
"name": "flare.query.Literal",
"size": 1214,
"imports": ["flare.query.Expression"]
},
{
"name": "flare.query.Match",
"size": 3748,
"imports": ["flare.query.BinaryExpression",
"flare.query.Expression",
"flare.query.StringUtil"]
},
{
"name": "flare.query.Maximum",
"size": 843,
"imports": ["flare.query.Expression",
"flare.query.AggregateExpression"]
},
{
"name": "flare.query.methods.add",
"size": 593,
"imports": ["flare.query.methods.or",
"flare.query.Arithmetic"]
},
{
"name": "flare.query.methods.and",
"size": 330,
"imports": ["flare.query.And",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.average",
"size": 287,
"imports": ["flare.query.Average",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.count",
"size": 277,
"imports": ["flare.query.Count",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.distinct",
"size": 292,
"imports": ["flare.query.Distinct",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.div",
"size": 595,
"imports": ["flare.query.methods.or",
"flare.query.Arithmetic"]
},
{
"name": "flare.query.methods.eq",
"size": 594,
"imports": ["flare.query.Comparison",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.fn",
"size": 460,
"imports": ["flare.query.methods.or",
"flare.query.Fn"]
},
{
"name": "flare.query.methods.gt",
"size": 603,
"imports": ["flare.query.Comparison",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.gte",
"size": 625,
"imports": ["flare.query.Comparison",
"flare.query.methods.gt",
"flare.query.methods.eq",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.iff",
"size": 748,
"imports": ["flare.query.methods.or",
"flare.query.If"]
},
{
"name": "flare.query.methods.isa",
"size": 461,
"imports": ["flare.query.IsA",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.lt",
"size": 597,
"imports": ["flare.query.Comparison",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.lte",
"size": 619,
"imports": ["flare.query.Comparison",
"flare.query.methods.lt",
"flare.query.methods.eq",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.max",
"size": 283,
"imports": ["flare.query.Maximum",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.min",
"size": 283,
"imports": ["flare.query.Minimum",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.mod",
"size": 591,
"imports": ["flare.query.methods.or",
"flare.query.Arithmetic"]
},
{
"name": "flare.query.methods.mul",
"size": 603,
"imports": ["flare.query.methods.lt",
"flare.query.methods.or",
"flare.query.Arithmetic"]
},
{
"name": "flare.query.methods.neq",
"size": 599,
"imports": ["flare.query.Comparison",
"flare.query.methods.eq",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.not",
"size": 386,
"imports": ["flare.query.Not",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.or",
"size": 323,
"imports": ["flare.query.Or"]
},
{
"name": "flare.query.methods.orderby",
"size": 307,
"imports": ["flare.query.Query",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.range",
"size": 772,
"imports": ["flare.query.methods.max",
"flare.query.Range",
"flare.query.methods.or",
"flare.query.methods.min"]
},
{
"name": "flare.query.methods.select",
"size": 296,
"imports": ["flare.query.Query"]
},
{
"name": "flare.query.methods.stddev",
"size": 363,
"imports": ["flare.query.methods.and",
"flare.query.Variance",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.sub",
"size": 600,
"imports": ["flare.query.methods.or",
"flare.query.Arithmetic"]
},
{
"name": "flare.query.methods.sum",
"size": 280,
"imports": ["flare.query.Sum",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.update",
"size": 307,
"imports": ["flare.query.Query"]
},
{
"name": "flare.query.methods.variance",
"size": 335,
"imports": ["flare.query.Variance",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods.where",
"size": 299,
"imports": ["flare.query.Query",
"flare.query.methods.lt",
"flare.query.methods.lte"]
},
{
"name": "flare.query.methods.xor",
"size": 354,
"imports": ["flare.query.Xor",
"flare.query.methods.or"]
},
{
"name": "flare.query.methods._",
"size": 264,
"imports": ["flare.query.Literal",
"flare.query.methods.or"]
},
{
"name": "flare.query.Minimum",
"size": 843,
"imports": ["flare.query.Expression",
"flare.query.AggregateExpression"]
},
{
"name": "flare.query.Not",
"size": 1554,
"imports": ["flare.query.Expression"]
},
{
"name": "flare.query.Or",
"size": 970,
"imports": ["flare.query.CompositeExpression",
"flare.query.Expression"]
},
{
"name": "flare.query.Query",
"size": 13896,
"imports": ["flare.query.Variable",
"flare.query.Sum",
"flare.query.Expression",
"flare.util.Sort",
"flare.query.Not",
"flare.query.AggregateExpression",
"flare.query.Literal",
"flare.util.Filter",
"flare.util.Property",
"flare.query.If"]
},
{
"name": "flare.query.Range",
"size": 1594,
"imports": ["flare.query.And",
"flare.query.Comparison",
"flare.query.Expression"]
},
{
"name": "flare.query.StringUtil",
"size": 4130,
"imports": ["flare.query.Fn"]
},
{
"name": "flare.query.Sum",
"size": 791,
"imports": ["flare.query.Expression",
"flare.query.AggregateExpression"]
},
{
"name": "flare.query.Variable",
"size": 1124,
"imports": ["flare.query.Expression",
"flare.util.Property"]
},
{
"name": "flare.query.Variance",
"size": 1876,
"imports": ["flare.query.Expression",
"flare.query.AggregateExpression"]
},
{
"name": "flare.query.Xor",
"size": 1101,
"imports": ["flare.query.CompositeExpression",
"flare.query.Expression"]
},
{
"name": "flare.scale.IScaleMap",
"size": 2105,
"imports": ["flare.scale.Scale"]
},
{
"name": "flare.scale.LinearScale",
"size": 1316,
"imports": ["flare.util.Maths",
"flare.util.Strings",
"flare.scale.Scale",
"flare.scale.QuantitativeScale",
"flare.scale.ScaleType"]
},
{
"name": "flare.scale.LogScale",
"size": 3151,
"imports": ["flare.util.Maths",
"flare.util.Strings",
"flare.scale.Scale",
"flare.scale.QuantitativeScale",
"flare.scale.ScaleType"]
},
{
"name": "flare.scale.OrdinalScale",
"size": 3770,
"imports": ["flare.scale.ScaleType",
"flare.util.Arrays",
"flare.scale.Scale"]
},
{
"name": "flare.scale.QuantileScale",
"size": 2435,
"imports": ["flare.util.Maths",
"flare.util.Strings",
"flare.scale.Scale",
"flare.scale.ScaleType"]
},
{
"name": "flare.scale.QuantitativeScale",
"size": 4839,
"imports": ["flare.util.Maths",
"flare.util.Strings",
"flare.scale.Scale"]
},
{
"name": "flare.scale.RootScale",
"size": 1756,
"imports": ["flare.util.Maths",
"flare.util.Strings",
"flare.scale.Scale",
"flare.scale.QuantitativeScale",
"flare.scale.ScaleType"]
},
{
"name": "flare.scale.Scale",
"size": 4268,
"imports": ["flare.scale.ScaleType",
"flare.util.Strings"]
},
{
"name": "flare.scale.ScaleType",
"size": 1821,
"imports": ["flare.scale.Scale"]
},
{
"name": "flare.scale.TimeScale",
"size": 5833,
"imports": ["flare.util.Maths",
"flare.util.Dates",
"flare.scale.Scale",
"flare.scale.ScaleType"]
},
{
"name": "flare.util.Arrays",
"size": 8258,
"imports": ["flare.util.IValueProxy",
"flare.util.Property",
"flare.util.IEvaluable"]
},
{
"name": "flare.util.Colors",
"size": 10001,
"imports": ["flare.util.Filter"]
},
{
"name": "flare.util.Dates",
"size": 8217,
"imports": ["flare.util.Maths"]
},
{
"name": "flare.util.Displays",
"size": 12555,
"imports": ["flare.util.IValueProxy",
"flare.util.Filter",
"flare.util.Property",
"flare.util.IEvaluable",
"flare.util.Sort"]
},
{
"name": "flare.util.Filter",
"size": 2324,
"imports": ["flare.util.IPredicate",
"flare.util.Property"]
},
{
"name": "flare.util.Geometry",
"size": 10993,
"imports": []
},
{
"name": "flare.util.heap.FibonacciHeap",
"size": 9354,
"imports": ["flare.util.heap.HeapNode"]
},
{
"name": "flare.util.heap.HeapNode",
"size": 1233,
"imports": ["flare.util.heap.FibonacciHeap"]
},
{
"name": "flare.util.IEvaluable",
"size": 335,
"imports": []
},
{
"name": "flare.util.IPredicate",
"size": 383,
"imports": []
},
{
"name": "flare.util.IValueProxy",
"size": 874,
"imports": []
},
{
"name": "flare.util.math.DenseMatrix",
"size": 3165,
"imports": ["flare.util.math.IMatrix"]
},
{
"name": "flare.util.math.IMatrix",
"size": 2815,
"imports": []
},
{
"name": "flare.util.math.SparseMatrix",
"size": 3366,
"imports": ["flare.util.math.IMatrix"]
},
{
"name": "flare.util.Maths",
"size": 17705,
"imports": ["flare.util.Arrays"]
},
{
"name": "flare.util.Orientation",
"size": 1486,
"imports": []
},
{
"name": "flare.util.palette.ColorPalette",
"size": 6367,
"imports": ["flare.util.palette.Palette",
"flare.util.Colors"]
},
{
"name": "flare.util.palette.Palette",
"size": 1229,
"imports": []
},
{
"name": "flare.util.palette.ShapePalette",
"size": 2059,
"imports": ["flare.util.palette.Palette",
"flare.util.Shapes"]
},
{
"name": "flare.util.palette.SizePalette",
"size": 2291,
"imports": ["flare.util.palette.Palette"]
},
{
"name": "flare.util.Property",
"size": 5559,
"imports": ["flare.util.IPredicate",
"flare.util.IValueProxy",
"flare.util.IEvaluable"]
},
{
"name": "flare.util.Shapes",
"size": 19118,
"imports": ["flare.util.Arrays"]
},
{
"name": "flare.util.Sort",
"size": 6887,
"imports": ["flare.util.Arrays",
"flare.util.Property"]
},
{
"name": "flare.util.Stats",
"size": 6557,
"imports": ["flare.util.Arrays",
"flare.util.Property"]
},
{
"name": "flare.util.Strings",
"size": 22026,
"imports": ["flare.util.Dates",
"flare.util.Property"]
},
{
"name": "flare.vis.axis.Axes",
"size": 1302,
"imports": ["flare.animate.Transitioner",
"flare.vis.Visualization"]
},
{
"name": "flare.vis.axis.Axis",
"size": 24593,
"imports": ["flare.animate.Transitioner",
"flare.scale.LinearScale",
"flare.util.Arrays",
"flare.scale.ScaleType",
"flare.util.Strings",
"flare.display.TextSprite",
"flare.scale.Scale",
"flare.util.Stats",
"flare.scale.IScaleMap",
"flare.vis.axis.AxisLabel",
"flare.vis.axis.AxisGridLine"]
},
{
"name": "flare.vis.axis.AxisGridLine",
"size": 652,
"imports": ["flare.vis.axis.Axis",
"flare.display.LineSprite"]
},
{
"name": "flare.vis.axis.AxisLabel",
"size": 636,
"imports": ["flare.vis.axis.Axis",
"flare.display.TextSprite"]
},
{
"name": "flare.vis.axis.CartesianAxes",
"size": 6703,
"imports": ["flare.animate.Transitioner",
"flare.display.RectSprite",
"flare.vis.axis.Axis",
"flare.display.TextSprite",
"flare.vis.axis.Axes",
"flare.vis.Visualization",
"flare.vis.axis.AxisGridLine"]
},
{
"name": "flare.vis.controls.AnchorControl",
"size": 2138,
"imports": ["flare.vis.controls.Control",
"flare.vis.Visualization",
"flare.vis.operator.layout.Layout"]
},
{
"name": "flare.vis.controls.ClickControl",
"size": 3824,
"imports": ["flare.vis.events.SelectionEvent",
"flare.vis.controls.Control"]
},
{
"name": "flare.vis.controls.Control",
"size": 1353,
"imports": ["flare.vis.controls.IControl",
"flare.util.Filter"]
},
{
"name": "flare.vis.controls.ControlList",
"size": 4665,
"imports": ["flare.vis.controls.IControl",
"flare.util.Arrays",
"flare.vis.Visualization",
"flare.vis.controls.Control"]
},
{
"name": "flare.vis.controls.DragControl",
"size": 2649,
"imports": ["flare.vis.controls.Control",
"flare.vis.data.DataSprite"]
},
{
"name": "flare.vis.controls.ExpandControl",
"size": 2832,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.vis.controls.Control",
"flare.vis.Visualization"]
},
{
"name": "flare.vis.controls.HoverControl",
"size": 4896,
"imports": ["flare.vis.events.SelectionEvent",
"flare.vis.controls.Control"]
},
{
"name": "flare.vis.controls.IControl",
"size": 763,
"imports": ["flare.vis.controls.Control"]
},
{
"name": "flare.vis.controls.PanZoomControl",
"size": 5222,
"imports": ["flare.util.Displays",
"flare.vis.controls.Control"]
},
{
"name": "flare.vis.controls.SelectionControl",
"size": 7862,
"imports": ["flare.vis.events.SelectionEvent",
"flare.vis.controls.Control"]
},
{
"name": "flare.vis.controls.TooltipControl",
"size": 8435,
"imports": ["flare.animate.Tween",
"flare.display.TextSprite",
"flare.vis.controls.Control",
"flare.vis.events.TooltipEvent"]
},
{
"name": "flare.vis.data.Data",
"size": 20544,
"imports": ["flare.vis.data.EdgeSprite",
"flare.vis.data.NodeSprite",
"flare.util.Arrays",
"flare.vis.data.DataSprite",
"flare.vis.data.Tree",
"flare.vis.events.DataEvent",
"flare.data.DataSet",
"flare.vis.data.TreeBuilder",
"flare.vis.data.DataList",
"flare.data.DataSchema",
"flare.util.Sort",
"flare.data.DataField",
"flare.util.Property"]
},
{
"name": "flare.vis.data.DataList",
"size": 19788,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.util.Arrays",
"flare.util.math.DenseMatrix",
"flare.vis.data.DataSprite",
"flare.vis.data.EdgeSprite",
"flare.vis.events.DataEvent",
"flare.util.Stats",
"flare.util.math.IMatrix",
"flare.util.Sort",
"flare.util.Filter",
"flare.util.Property",
"flare.util.IEvaluable",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.data.DataSprite",
"size": 10349,
"imports": ["flare.util.Colors",
"flare.vis.data.Data",
"flare.display.DirtySprite",
"flare.vis.data.render.IRenderer",
"flare.vis.data.render.ShapeRenderer"]
},
{
"name": "flare.vis.data.EdgeSprite",
"size": 3301,
"imports": ["flare.vis.data.render.EdgeRenderer",
"flare.vis.data.DataSprite",
"flare.vis.data.NodeSprite",
"flare.vis.data.render.ArrowType",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.data.NodeSprite",
"size": 19382,
"imports": ["flare.animate.Transitioner",
"flare.util.Arrays",
"flare.vis.data.DataSprite",
"flare.vis.data.EdgeSprite",
"flare.vis.data.Tree",
"flare.util.Sort",
"flare.util.Filter",
"flare.util.IEvaluable",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.data.render.ArrowType",
"size": 698,
"imports": []
},
{
"name": "flare.vis.data.render.EdgeRenderer",
"size": 5569,
"imports": ["flare.vis.data.EdgeSprite",
"flare.vis.data.NodeSprite",
"flare.vis.data.DataSprite",
"flare.vis.data.render.IRenderer",
"flare.util.Shapes",
"flare.util.Geometry",
"flare.vis.data.render.ArrowType"]
},
{
"name": "flare.vis.data.render.IRenderer",
"size": 353,
"imports": ["flare.vis.data.DataSprite"]
},
{
"name": "flare.vis.data.render.ShapeRenderer",
"size": 2247,
"imports": ["flare.util.Shapes",
"flare.vis.data.render.IRenderer",
"flare.vis.data.DataSprite"]
},
{
"name": "flare.vis.data.ScaleBinding",
"size": 11275,
"imports": ["flare.scale.TimeScale",
"flare.scale.ScaleType",
"flare.scale.LinearScale",
"flare.scale.LogScale",
"flare.scale.OrdinalScale",
"flare.scale.RootScale",
"flare.scale.Scale",
"flare.scale.QuantileScale",
"flare.util.Stats",
"flare.scale.QuantitativeScale",
"flare.vis.events.DataEvent",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.data.Tree",
"size": 7147,
"imports": ["flare.vis.data.EdgeSprite",
"flare.vis.events.DataEvent",
"flare.vis.data.NodeSprite",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.data.TreeBuilder",
"size": 9930,
"imports": ["flare.vis.data.EdgeSprite",
"flare.vis.data.NodeSprite",
"flare.vis.data.Tree",
"flare.util.heap.HeapNode",
"flare.util.heap.FibonacciHeap",
"flare.util.Property",
"flare.util.IEvaluable",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.events.DataEvent",
"size": 2313,
"imports": ["flare.vis.data.EdgeSprite",
"flare.vis.data.NodeSprite",
"flare.vis.data.DataList",
"flare.vis.data.DataSprite"]
},
{
"name": "flare.vis.events.SelectionEvent",
"size": 1880,
"imports": ["flare.vis.events.DataEvent"]
},
{
"name": "flare.vis.events.TooltipEvent",
"size": 1701,
"imports": ["flare.vis.data.EdgeSprite",
"flare.vis.data.NodeSprite"]
},
{
"name": "flare.vis.events.VisualizationEvent",
"size": 1117,
"imports": ["flare.animate.Transitioner"]
},
{
"name": "flare.vis.legend.Legend",
"size": 20859,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.ScaleBinding",
"flare.util.palette.SizePalette",
"flare.scale.ScaleType",
"flare.vis.legend.LegendItem",
"flare.display.RectSprite",
"flare.display.TextSprite",
"flare.scale.Scale",
"flare.vis.legend.LegendRange",
"flare.util.Displays",
"flare.util.Orientation",
"flare.util.palette.ShapePalette",
"flare.util.palette.Palette",
"flare.util.palette.ColorPalette"]
},
{
"name": "flare.vis.legend.LegendItem",
"size": 4614,
"imports": ["flare.util.Shapes",
"flare.display.TextSprite",
"flare.vis.legend.Legend",
"flare.display.RectSprite"]
},
{
"name": "flare.vis.legend.LegendRange",
"size": 10530,
"imports": ["flare.util.Colors",
"flare.vis.legend.Legend",
"flare.display.RectSprite",
"flare.display.TextSprite",
"flare.scale.Scale",
"flare.util.Stats",
"flare.scale.IScaleMap",
"flare.util.Orientation",
"flare.util.palette.ColorPalette"]
},
{
"name": "flare.vis.operator.distortion.BifocalDistortion",
"size": 4461,
"imports": ["flare.vis.operator.distortion.Distortion"]
},
{
"name": "flare.vis.operator.distortion.Distortion",
"size": 6314,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.DataSprite",
"flare.vis.events.VisualizationEvent",
"flare.vis.axis.Axis",
"flare.vis.axis.CartesianAxes",
"flare.vis.operator.layout.Layout",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.distortion.FisheyeDistortion",
"size": 3444,
"imports": ["flare.vis.operator.distortion.Distortion"]
},
{
"name": "flare.vis.operator.encoder.ColorEncoder",
"size": 3179,
"imports": ["flare.animate.Transitioner",
"flare.scale.ScaleType",
"flare.vis.operator.encoder.Encoder",
"flare.util.palette.Palette",
"flare.util.palette.ColorPalette",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.encoder.Encoder",
"size": 4060,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.DataSprite",
"flare.vis.operator.Operator",
"flare.vis.data.ScaleBinding",
"flare.util.palette.Palette",
"flare.util.Filter",
"flare.util.Property",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.encoder.PropertyEncoder",
"size": 4138,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.DataList",
"flare.vis.data.Data",
"flare.vis.operator.encoder.Encoder",
"flare.util.Filter",
"flare.vis.operator.Operator"]
},
{
"name": "flare.vis.operator.encoder.ShapeEncoder",
"size": 1690,
"imports": ["flare.util.palette.Palette",
"flare.scale.ScaleType",
"flare.util.palette.ShapePalette",
"flare.vis.operator.encoder.Encoder",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.encoder.SizeEncoder",
"size": 1830,
"imports": ["flare.util.palette.Palette",
"flare.scale.ScaleType",
"flare.vis.operator.encoder.Encoder",
"flare.util.palette.SizePalette",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.filter.FisheyeTreeFilter",
"size": 5219,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.vis.data.DataSprite",
"flare.vis.data.EdgeSprite",
"flare.vis.data.Tree",
"flare.vis.operator.Operator",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.filter.GraphDistanceFilter",
"size": 3165,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.vis.operator.Operator",
"flare.vis.data.DataSprite",
"flare.vis.data.EdgeSprite"]
},
{
"name": "flare.vis.operator.filter.VisibilityFilter",
"size": 3509,
"imports": ["flare.vis.operator.Operator",
"flare.animate.Transitioner",
"flare.util.Filter",
"flare.vis.data.DataSprite",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.IOperator",
"size": 1286,
"imports": ["flare.animate.Transitioner",
"flare.vis.Visualization",
"flare.vis.operator.Operator"]
},
{
"name": "flare.vis.operator.label.Labeler",
"size": 9956,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.DataSprite",
"flare.display.TextSprite",
"flare.vis.operator.Operator",
"flare.util.Shapes",
"flare.util.Filter",
"flare.util.Property",
"flare.util.IEvaluable",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.label.RadialLabeler",
"size": 3899,
"imports": ["flare.vis.operator.label.Labeler",
"flare.util.Shapes",
"flare.display.TextSprite",
"flare.vis.data.DataSprite",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.label.StackedAreaLabeler",
"size": 3202,
"imports": ["flare.vis.operator.label.Labeler",
"flare.display.TextSprite",
"flare.vis.data.DataSprite",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.layout.AxisLayout",
"size": 6725,
"imports": ["flare.scale.ScaleType",
"flare.vis.data.DataSprite",
"flare.vis.axis.CartesianAxes",
"flare.vis.data.ScaleBinding",
"flare.util.Property",
"flare.vis.operator.layout.Layout",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.layout.BundledEdgeRouter",
"size": 3727,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.util.Arrays",
"flare.vis.data.DataSprite",
"flare.vis.data.EdgeSprite",
"flare.util.Shapes",
"flare.vis.operator.layout.Layout",
"flare.vis.operator.Operator"]
},
{
"name": "flare.vis.operator.layout.CircleLayout",
"size": 9317,
"imports": ["flare.vis.data.NodeSprite",
"flare.vis.data.DataList",
"flare.vis.data.ScaleBinding",
"flare.util.Property",
"flare.vis.operator.layout.Layout",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.layout.CirclePackingLayout",
"size": 12003,
"imports": ["flare.vis.data.NodeSprite",
"flare.vis.data.render.ShapeRenderer",
"flare.util.Shapes",
"flare.util.Sort",
"flare.vis.operator.layout.Layout",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.layout.DendrogramLayout",
"size": 4853,
"imports": ["flare.util.Property",
"flare.vis.data.NodeSprite",
"flare.util.Orientation",
"flare.vis.operator.layout.Layout",
"flare.vis.data.EdgeSprite"]
},
{
"name": "flare.vis.operator.layout.ForceDirectedLayout",
"size": 8411,
"imports": ["flare.physics.Simulation",
"flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.vis.data.DataSprite",
"flare.physics.Particle",
"flare.physics.Spring",
"flare.vis.operator.layout.Layout",
"flare.vis.data.EdgeSprite",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.layout.IcicleTreeLayout",
"size": 4864,
"imports": ["flare.vis.data.NodeSprite",
"flare.util.Orientation",
"flare.vis.operator.layout.Layout"]
},
{
"name": "flare.vis.operator.layout.IndentedTreeLayout",
"size": 3174,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.util.Arrays",
"flare.vis.operator.layout.Layout",
"flare.vis.data.EdgeSprite"]
},
{
"name": "flare.vis.operator.layout.Layout",
"size": 7881,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.vis.data.DataList",
"flare.vis.data.DataSprite",
"flare.vis.data.EdgeSprite",
"flare.vis.Visualization",
"flare.vis.axis.CartesianAxes",
"flare.vis.axis.Axes",
"flare.animate.TransitionEvent",
"flare.vis.operator.Operator"]
},
{
"name": "flare.vis.operator.layout.NodeLinkTreeLayout",
"size": 12870,
"imports": ["flare.vis.data.NodeSprite",
"flare.util.Arrays",
"flare.util.Orientation",
"flare.vis.operator.layout.Layout"]
},
{
"name": "flare.vis.operator.layout.PieLayout",
"size": 2728,
"imports": ["flare.vis.data.DataList",
"flare.vis.data.DataSprite",
"flare.util.Shapes",
"flare.util.Property",
"flare.vis.operator.layout.Layout",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.layout.RadialTreeLayout",
"size": 12348,
"imports": ["flare.vis.data.NodeSprite",
"flare.util.Arrays",
"flare.vis.operator.layout.Layout"]
},
{
"name": "flare.vis.operator.layout.RandomLayout",
"size": 870,
"imports": ["flare.vis.operator.layout.Layout",
"flare.vis.data.DataSprite",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.operator.layout.StackedAreaLayout",
"size": 9121,
"imports": ["flare.scale.TimeScale",
"flare.scale.LinearScale",
"flare.util.Arrays",
"flare.scale.OrdinalScale",
"flare.vis.data.NodeSprite",
"flare.scale.Scale",
"flare.vis.axis.CartesianAxes",
"flare.util.Stats",
"flare.util.Orientation",
"flare.scale.QuantitativeScale",
"flare.util.Maths",
"flare.vis.operator.layout.Layout"]
},
{
"name": "flare.vis.operator.layout.TreeMapLayout",
"size": 9191,
"imports": ["flare.animate.Transitioner",
"flare.vis.data.NodeSprite",
"flare.util.Property",
"flare.vis.operator.layout.Layout"]
},
{
"name": "flare.vis.operator.Operator",
"size": 2490,
"imports": ["flare.animate.Transitioner",
"flare.vis.operator.IOperator",
"flare.util.Property",
"flare.util.IEvaluable",
"flare.vis.Visualization"]
},
{
"name": "flare.vis.operator.OperatorList",
"size": 5248,
"imports": ["flare.animate.Transitioner",
"flare.util.Arrays",
"flare.vis.operator.IOperator",
"flare.vis.Visualization",
"flare.vis.operator.Operator"]
},
{
"name": "flare.vis.operator.OperatorSequence",
"size": 4190,
"imports": ["flare.animate.Transitioner",
"flare.util.Arrays",
"flare.vis.operator.IOperator",
"flare.vis.operator.OperatorList",
"flare.animate.FunctionSequence",
"flare.vis.operator.Operator"]
},
{
"name": "flare.vis.operator.OperatorSwitch",
"size": 2581,
"imports": ["flare.animate.Transitioner",
"flare.vis.operator.OperatorList",
"flare.vis.operator.IOperator",
"flare.vis.operator.Operator"]
},
{
"name": "flare.vis.operator.SortOperator",
"size": 2023,
"imports": ["flare.vis.operator.Operator",
"flare.animate.Transitioner",
"flare.util.Arrays",
"flare.vis.data.Data"]
},
{
"name": "flare.vis.Visualization",
"size": 16540,
"imports": ["flare.animate.Transitioner",
"flare.vis.operator.IOperator",
"flare.animate.Scheduler",
"flare.vis.events.VisualizationEvent",
"flare.vis.data.Tree",
"flare.vis.events.DataEvent",
"flare.vis.axis.Axes",
"flare.vis.axis.CartesianAxes",
"flare.util.Displays",
"flare.vis.operator.OperatorList",
"flare.vis.controls.ControlList",
"flare.animate.ISchedulable",
"flare.vis.data.Data"]
}]
### read flare-imports data and provide it in form of tree (for the package hierarchy) and links (for the imports) ###
### code adapted from http://bl.ocks.org/mbostock/4341134 ###
`
window.flare_reader = {
// Lazily construct the package hierarchy from class names.
tree: function(classes) {
var map = {};
function find(name, data) {
var node = map[name], i;
if (!node) {
node = map[name] = data || {name: name, children: []};
if (name.length) {
node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
node.parent.children.push(node);
node.key = name.substring(i + 1);
}
}
return node;
}
classes.forEach(function(d) {
find(d.name, d);
});
var flare = map['flare'];
delete flare.parent; // CHANGED root node is not ""
return flare;
},
// Return a list of imports for the given array of nodes.
imports: function(nodes) {
var map = {},
imports = [];
// Compute a map from name to node.
nodes.forEach(function(d) {
map[d.name] = d;
});
// For each import, construct a link from the source to target node.
nodes.forEach(function(d) {
if (d.imports) d.imports.forEach(function(i) {
imports.push({source: map[d.name], target: map[i]});
});
});
return imports;
}
};
`
/* read flare-imports data and provide it in form of tree (for the package hierarchy) and links (for the imports)
*/
/* code adapted from http://bl.ocks.org/mbostock/4341134
*/
(function() {
window.flare_reader = {
// Lazily construct the package hierarchy from class names.
tree: function(classes) {
var map = {};
function find(name, data) {
var node = map[name], i;
if (!node) {
node = map[name] = data || {name: name, children: []};
if (name.length) {
node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
node.parent.children.push(node);
node.key = name.substring(i + 1);
}
}
return node;
}
classes.forEach(function(d) {
find(d.name, d);
});
var flare = map['flare'];
delete flare.parent; // CHANGED root node is not ""
return flare;
},
// Return a list of imports for the given array of nodes.
imports: function(nodes) {
var map = {},
imports = [];
// Compute a map from name to node.
nodes.forEach(function(d) {
map[d.name] = d;
});
// For each import, construct a link from the source to target node.
nodes.forEach(function(d) {
if (d.imports) d.imports.forEach(function(i) {
imports.push({source: map[d.name], target: map[i]});
});
});
return imports;
}
};
;
}).call(this);
width = 960
height = 500
### create the SVG ###
svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height)
vis = svg.append('g')
map = vis.append('g')
.attr('transform', "translate(#{width/2},#{height/2})")
### define a zoom behavior ###
zoom = d3.behavior.zoom()
.scaleExtent([1,10]) # min-max zoom
.on 'zoom', () ->
### whenever the user zooms, ###
### modify translation and scale of the zoom group accordingly ###
vis.attr('transform', "translate(#{zoom.translate()})scale(#{zoom.scale()})")
### bind the zoom behavior to the main SVG ###
svg.call(zoom)
### read flare data ###
d3.json 'flare-imports.json', (data) ->
### package tree ###
tree = flare_reader.tree(data)
hierarchy = d3.layout.hierarchy()
nodes = hierarchy(tree)
### imports links ###
# graph_links = flare_reader.imports(nodes)
### this tree is unordered, we need a canonical ordering for it ###
tree_utils.canonical_sort(tree)
### obtain the sequence of leaves ###
leaves = tree_utils.get_leaves(tree)
### VISUALIZATION ###
### compute the space-filling curve layout ###
scale = 26
sfc_layout.displace(leaves, sfc_layout.HILBERT, scale, 0)
### compute also the position of internal nodes ###
sfc_layout.displace_tree(tree)
### define a bundle layout ###
# bundle = d3.layout.bundle()
# bundles = bundle(graph_links)
# link_generator = d3.svg.line()
# .interpolate('bundle')
# .tension(0.99)
# .x((d) -> d.x)
# .y((d) -> d.y)
### define a color scale for leaf depth ###
depth_color = d3.scale.linear()
.domain([1, d3.max(leaves,(d)->d.depth)])
.range(['#FFF7DB', '#F0A848'])
.interpolate(d3.interpolateHcl)
### define a thickness scale for region depth ###
# depth_thickness = d3.scale.sqrt()
# .domain([0, d3.max(leaves,(d)->d.depth)-1])
# .range([4, 0.1])
### translate size to cell scale ###
# size2cellscale = d3.scale.sqrt()
# .domain([0, d3.max(nodes,(d)->d.size)])
# .range([0,scale])
### translate cells to label font size ###
cells2fontsize = d3.scale.pow()
.exponent(0.3)
.domain([1, leaves.length])
.range([4,80])
### compute all the internal nodes regions ###
jigsaw.treemap(tree, scale, jigsaw.SQUARE_CELL)
### define the level zero region (the land) ###
defs = svg.append('defs')
defs.append('path')
.attr('id', 'land')
.attr('d', jigsaw.get_svg_path tree.region)
### faux land glow (using filters takes too much resources) ###
map.append('use')
.attr('class', 'land-glow-outer')
.attr('xlink:href', '#land')
map.append('use')
.attr('class', 'land-glow-inner')
.attr('xlink:href', '#land')
### draw the cells ###
# map.selectAll('.cell')
# .data(leaves)
# .enter().append('path')
# .attr('class', 'cell')
## .attr('d', (d) -> jigsaw.square_generate_svg_path size2cellscale(d.size) )
# .attr('d', jigsaw.square_generate_svg_path scale )
# .attr('transform', (d) -> "translate(#{d.x},#{d.y})")
# .attr('fill', (d) -> depth_color(d.depth))
# .attr('fill', 'white')
# .attr('stroke', (d) -> depth_color(d.depth))
# .attr('stroke', 'white')
### draw the land border (above cells) ###
map.append('use')
.attr('class', 'land-fill')
.attr('xlink:href', '#land')
### draw the level one region boundaries ###
map.selectAll('.region')
.data(nodes.filter((d)->d.depth is 1))
.enter().append('path')
.attr('class', 'region')
.attr('d', (d) -> jigsaw.get_svg_path d.region)
# .attr('stroke-width', (d) -> depth_thickness(d.depth))
.attr('stroke-width', '0.2px')
### draw the graph links ###
# map.selectAll('.graph_link')
# .data(bundles)
# .enter().append('path')
# .attr('class', 'graph_link')
# .attr('d', link_generator)
### draw labels ###
map.selectAll('.label')
.data(nodes.filter((d)->d.depth is 1))
.enter().append('text')
.attr('class', 'label')
.attr('font-size', (d) -> cells2fontsize(d.leaf_descendants.length))
.attr('dy', '0.35em')
.attr('transform', (d) -> "translate(#{d.x},#{d.y})")
.text((d) -> d.name.split('.').reverse()[0])
### draw the leaf labels ###
# map.selectAll('.label')
# .data(leaves)
# .enter().append('text')
# .attr('class', 'label')
# .attr('font-size', '4px')
# .attr('dy', '0.35em')
# .attr('transform', (d) -> "translate(#{d.x},#{d.y})")
# .text((d) -> d.name.split('.').reverse()[0])
.land-glow-outer {
fill: none;
stroke: #eeeeee;
stroke-width: 16px;
}
.land-glow-inner {
fill: none;
stroke: #dddddd;
stroke-width: 8px;
}
.land-fill {
fill: white;
stroke: #444444;
stroke-width: 0.5px;
}
.cell {
stroke-width: 1px;
}
.region {
fill: none;
stroke: #444444;
}
@font-face {
font-family: "Lacuna";
src: url("lacuna.ttf");
}
.label {
fill: #333333;
text-anchor: middle;
pointer-events: none;
font-family: "Lacuna";
}
.graph_link {
stroke: teal;
stroke-width: 0.05;
fill: none;
pointer-events: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Jigsaw treemap (Hilbert)</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://jsclipper.sourceforge.net/6.1.3.1/clipper.js"></script>
<script src="zip.js"></script>
<script src="flare_reader.js"></script>
<script src="tree_utils.js"></script>
<script src="sfc_layout.js"></script>
<script src="jigsaw.js"></script>
</head>
<body>
</body>
<script src="index.js"></script>
</html>
(function() {
var height, map, svg, vis, width, zoom;
width = 960;
height = 500;
/* create the SVG
*/
svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
vis = svg.append('g');
map = vis.append('g').attr('transform', "translate(" + (width / 2) + "," + (height / 2) + ")");
/* define a zoom behavior
*/
zoom = d3.behavior.zoom().scaleExtent([1, 10]).on('zoom', function() {
/* whenever the user zooms,
*/
/* modify translation and scale of the zoom group accordingly
*/ return vis.attr('transform', "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")");
});
/* bind the zoom behavior to the main SVG
*/
svg.call(zoom);
/* read flare data
*/
d3.json('flare-imports.json', function(data) {
/* package tree
*/
var cells2fontsize, defs, depth_color, hierarchy, leaves, nodes, scale, tree;
tree = flare_reader.tree(data);
hierarchy = d3.layout.hierarchy();
nodes = hierarchy(tree);
/* imports links
*/
/* this tree is unordered, we need a canonical ordering for it
*/
tree_utils.canonical_sort(tree);
/* obtain the sequence of leaves
*/
leaves = tree_utils.get_leaves(tree);
/* VISUALIZATION
*/
/* compute the space-filling curve layout
*/
scale = 26;
sfc_layout.displace(leaves, sfc_layout.HILBERT, scale, 0);
/* compute also the position of internal nodes
*/
sfc_layout.displace_tree(tree);
/* define a bundle layout
*/
/* define a color scale for leaf depth
*/
depth_color = d3.scale.linear().domain([
1, d3.max(leaves, function(d) {
return d.depth;
})
]).range(['#FFF7DB', '#F0A848']).interpolate(d3.interpolateHcl);
/* define a thickness scale for region depth
*/
/* translate size to cell scale
*/
/* translate cells to label font size
*/
cells2fontsize = d3.scale.pow().exponent(0.3).domain([1, leaves.length]).range([4, 80]);
/* compute all the internal nodes regions
*/
jigsaw.treemap(tree, scale, jigsaw.SQUARE_CELL);
/* define the level zero region (the land)
*/
defs = svg.append('defs');
defs.append('path').attr('id', 'land').attr('d', jigsaw.get_svg_path(tree.region));
/* faux land glow (using filters takes too much resources)
*/
map.append('use').attr('class', 'land-glow-outer').attr('xlink:href', '#land');
map.append('use').attr('class', 'land-glow-inner').attr('xlink:href', '#land');
/* draw the cells
*/
/* draw the land border (above cells)
*/
map.append('use').attr('class', 'land-fill').attr('xlink:href', '#land');
/* draw the level one region boundaries
*/
map.selectAll('.region').data(nodes.filter(function(d) {
return d.depth === 1;
})).enter().append('path').attr('class', 'region').attr('d', function(d) {
return jigsaw.get_svg_path(d.region);
}).attr('stroke-width', '0.2px');
/* draw the graph links
*/
/* draw labels
*/
return map.selectAll('.label').data(nodes.filter(function(d) {
return d.depth === 1;
})).enter().append('text').attr('class', 'label').attr('font-size', function(d) {
return cells2fontsize(d.leaf_descendants.length);
}).attr('dy', '0.35em').attr('transform', function(d) {
return "translate(" + d.x + "," + d.y + ")";
}).text(function(d) {
return d.name.split('.').reverse()[0];
});
/* draw the leaf labels
*/
});
}).call(this);
.land-glow-outer
fill: none
stroke: #EEE
stroke-width: 16px
.land-glow-inner
fill: none
stroke: #DDD
stroke-width: 8px
.land-fill
fill: white
stroke: #444
stroke-width: 0.5px
.cell
stroke-width: 1px
.region
fill: none
stroke: #444
@font-face
font-family: "Lacuna"
src: url("lacuna.ttf")
.label
fill: #333
text-anchor: middle
pointer-events: none
font-family: "Lacuna"
.graph_link
stroke: teal
stroke-width: 0.05
fill: none
pointer-events: none
window.jigsaw = {
hex_generate_svg_path: (scale) ->
a = scale/2
r = a / Math.sin(Math.PI/3)
return "M#{r} 0 L#{r/2} #{a} L#{-r/2} #{a} L#{-r} 0 L#{-r/2} #{-a} L#{r/2} #{-a} Z"
square_generate_svg_path: (scale) ->
a = scale/2
return "M#{-a} #{-a} L#{-a} #{a} L#{a} #{a} L#{a} #{-a} Z"
HEX_CELL: (node, scale) ->
a = scale/2
r = a / Math.sin(Math.PI/3)
region = [[{X:node.x+r, Y:node.y}, {X:node.x+r/2, Y:node.y+a}, {X:node.x-r/2, Y:node.y+a}, {X:node.x-r, Y:node.y}, {X:node.x-r/2, Y:node.y-a}, {X:node.x+r/2, Y:node.y-a}]]
return region
SQUARE_CELL: (node, scale) ->
a = scale/2
region = [[{X:node.x-a, Y:node.y-a}, {X:node.x-a, Y:node.y+a}, {X:node.x+a, Y:node.y+a}, {X:node.x+a, Y:node.y-a}]]
return region
treemap: (node, scale, base) ->
if not node.children?
node.region = base(node, scale)
return node.region
children_paths = (jigsaw.treemap(child, scale, base) for child in node.children).reduce((a, d) -> a.concat(d))
upscale = 100
ClipperLib.JS.ScaleUpPaths(children_paths, upscale)
cpr = new ClipperLib.Clipper()
cpr.AddPaths(children_paths, ClipperLib.PolyType.ptSubject, true)
node.region = new ClipperLib.Paths()
cpr.Execute(ClipperLib.ClipType.ctUnion, node.region, ClipperLib.PolyFillType.pftNonZero, ClipperLib.PolyFillType.pftNonZero)
ClipperLib.JS.ScaleDownPaths(children_paths, upscale)
ClipperLib.JS.ScaleDownPaths(node.region, upscale)
return node.region
### Converts Paths to SVG path string ###
### and scales down the coordinates ###
### from http://jsclipper.sourceforge.net/6.1.3.1/index.html?p=starter_boolean.html ###
get_svg_path: (paths, scale) ->
svgpath = ''
if not scale?
scale = 1
for path in paths
for p, i in path
if i is 0
svgpath += 'M'
else
svgpath += 'L'
svgpath += p.X/scale + ", " + p.Y/scale
svgpath += 'Z'
if svgpath is ''
svgpath = 'M0,0'
return svgpath
}
(function() {
window.jigsaw = {
hex_generate_svg_path: function(scale) {
var a, r;
a = scale / 2;
r = a / Math.sin(Math.PI / 3);
return "M" + r + " 0 L" + (r / 2) + " " + a + " L" + (-r / 2) + " " + a + " L" + (-r) + " 0 L" + (-r / 2) + " " + (-a) + " L" + (r / 2) + " " + (-a) + " Z";
},
square_generate_svg_path: function(scale) {
var a;
a = scale / 2;
return "M" + (-a) + " " + (-a) + " L" + (-a) + " " + a + " L" + a + " " + a + " L" + a + " " + (-a) + " Z";
},
HEX_CELL: function(node, scale) {
var a, r, region;
a = scale / 2;
r = a / Math.sin(Math.PI / 3);
region = [
[
{
X: node.x + r,
Y: node.y
}, {
X: node.x + r / 2,
Y: node.y + a
}, {
X: node.x - r / 2,
Y: node.y + a
}, {
X: node.x - r,
Y: node.y
}, {
X: node.x - r / 2,
Y: node.y - a
}, {
X: node.x + r / 2,
Y: node.y - a
}
]
];
return region;
},
SQUARE_CELL: function(node, scale) {
var a, region;
a = scale / 2;
region = [
[
{
X: node.x - a,
Y: node.y - a
}, {
X: node.x - a,
Y: node.y + a
}, {
X: node.x + a,
Y: node.y + a
}, {
X: node.x + a,
Y: node.y - a
}
]
];
return region;
},
treemap: function(node, scale, base) {
var child, children_paths, cpr, upscale;
if (!(node.children != null)) {
node.region = base(node, scale);
return node.region;
}
children_paths = ((function() {
var _i, _len, _ref, _results;
_ref = node.children;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
child = _ref[_i];
_results.push(jigsaw.treemap(child, scale, base));
}
return _results;
})()).reduce(function(a, d) {
return a.concat(d);
});
upscale = 100;
ClipperLib.JS.ScaleUpPaths(children_paths, upscale);
cpr = new ClipperLib.Clipper();
cpr.AddPaths(children_paths, ClipperLib.PolyType.ptSubject, true);
node.region = new ClipperLib.Paths();
cpr.Execute(ClipperLib.ClipType.ctUnion, node.region, ClipperLib.PolyFillType.pftNonZero, ClipperLib.PolyFillType.pftNonZero);
ClipperLib.JS.ScaleDownPaths(children_paths, upscale);
ClipperLib.JS.ScaleDownPaths(node.region, upscale);
return node.region;
},
/* Converts Paths to SVG path string
*/
/* and scales down the coordinates
*/
/* from http://jsclipper.sourceforge.net/6.1.3.1/index.html?p=starter_boolean.html
*/
get_svg_path: function(paths, scale) {
var i, p, path, svgpath, _i, _len, _len2;
svgpath = '';
if (!(scale != null)) scale = 1;
for (_i = 0, _len = paths.length; _i < _len; _i++) {
path = paths[_i];
for (i = 0, _len2 = path.length; i < _len2; i++) {
p = path[i];
if (i === 0) {
svgpath += 'M';
} else {
svgpath += 'L';
}
svgpath += p.X / scale + ", " + p.Y / scale;
}
svgpath += 'Z';
}
if (svgpath === '') svgpath = 'M0,0';
return svgpath;
}
};
}).call(this);
### FIXME update this code to the optimized version ###
### compute a Lindenmayer system given an axiom, a number of steps and rules ###
fractalize = (config) ->
input = config.axiom
for i in [0...config.steps]
output = ''
for char in input
if char of config.rules
output += config.rules[char]
else
output += char
input = output
return output
### execute a curve string and return all the generated points ###
execute = (curve_string, angle, scale, orientation) ->
points = [{x: 0, y: 0}]
for char in curve_string
if char == '+'
orientation += angle
else if char == '-'
orientation -= angle
else if char == 'F'
last_point = points[points.length-1]
points.push {
x: last_point.x + scale * Math.cos(orientation),
y: last_point.y + scale * Math.sin(orientation)
}
return points
### custom base for logarithm (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log) ###
base_log = (x, base) -> Math.log(x) / Math.log(base)
window.sfc_layout = {
GOSPER: {
base: 7
angle: Math.PI/3
axiom: 'A'
rules:
A: 'A+BF++BF-FA--FAFA-BF+'
B: '-FA+BFBF++BF+FA--FA-B'
}
HILBERT: {
base: 4
angle: Math.PI/2
axiom: 'A'
rules:
A: '-BF+AFA+FB-'
B: '+AF-BFB-FA+'
}
displace: (seq, curve_cfg, scale, orientation) ->
scale = if scale? then scale else 10
orientation = if orientation? then orientation else 0
### create the minimal curve that can accommodate the whole sequence ###
steps = Math.ceil(base_log(seq.length, curve_cfg.base))
### generate the Lindenmayer system string for the requested curve ###
curve_string = fractalize
steps: steps
axiom: curve_cfg.axiom
rules: curve_cfg.rules
### execute the string, producing the actual points of the curve ###
curve = execute(curve_string, curve_cfg.angle, scale, orientation)
### stores the coordinates in the given sequence ###
for [d,point] in zip(seq, curve)
d.x = point.x
d.y = point.y
### center the layout coordinates in the center of its bounding box ###
max_x = d3.max(seq, (d)->d.x)
max_y = d3.max(seq, (d)->d.y)
min_x = d3.min(seq, (d)->d.x)
min_y = d3.min(seq, (d)->d.y)
for d in seq
d.x -= (max_x+min_x)/2
d.y -= (max_y+min_y)/2
### recursively assign positions to internal nodes too. also compute leaf descendants ###
displace_tree: (node) ->
if not node.children?
### this is a leaf ###
node.leaf_descendants = [node]
return node.leaf_descendants
### an internal node's position is the centroid of its leaf descendants ###
node.leaf_descendants = (sfc_layout.displace_tree(c) for c in node.children).reduce((a, d) -> a.concat(d))
node.x = d3.mean(node.leaf_descendants, (d)->d.x)
node.y = d3.mean(node.leaf_descendants, (d)->d.y)
### pass descendants up to the hierarchy ###
return node.leaf_descendants
}
/* FIXME update this code to the optimized version
*/
/* compute a Lindenmayer system given an axiom, a number of steps and rules
*/
(function() {
var base_log, execute, fractalize;
fractalize = function(config) {
var char, i, input, output, _i, _len, _ref;
input = config.axiom;
for (i = 0, _ref = config.steps; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
output = '';
for (_i = 0, _len = input.length; _i < _len; _i++) {
char = input[_i];
if (char in config.rules) {
output += config.rules[char];
} else {
output += char;
}
}
input = output;
}
return output;
};
/* execute a curve string and return all the generated points
*/
execute = function(curve_string, angle, scale, orientation) {
var char, last_point, points, _i, _len;
points = [
{
x: 0,
y: 0
}
];
for (_i = 0, _len = curve_string.length; _i < _len; _i++) {
char = curve_string[_i];
if (char === '+') {
orientation += angle;
} else if (char === '-') {
orientation -= angle;
} else if (char === 'F') {
last_point = points[points.length - 1];
points.push({
x: last_point.x + scale * Math.cos(orientation),
y: last_point.y + scale * Math.sin(orientation)
});
}
}
return points;
};
/* custom base for logarithm (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log)
*/
base_log = function(x, base) {
return Math.log(x) / Math.log(base);
};
window.sfc_layout = {
GOSPER: {
base: 7,
angle: Math.PI / 3,
axiom: 'A',
rules: {
A: 'A+BF++BF-FA--FAFA-BF+',
B: '-FA+BFBF++BF+FA--FA-B'
}
},
HILBERT: {
base: 4,
angle: Math.PI / 2,
axiom: 'A',
rules: {
A: '-BF+AFA+FB-',
B: '+AF-BFB-FA+'
}
},
displace: function(seq, curve_cfg, scale, orientation) {
var curve, curve_string, d, max_x, max_y, min_x, min_y, point, steps, _i, _j, _len, _len2, _ref, _ref2, _results;
scale = scale != null ? scale : 10;
orientation = orientation != null ? orientation : 0;
/* create the minimal curve that can accommodate the whole sequence
*/
steps = Math.ceil(base_log(seq.length, curve_cfg.base));
/* generate the Lindenmayer system string for the requested curve
*/
curve_string = fractalize({
steps: steps,
axiom: curve_cfg.axiom,
rules: curve_cfg.rules
});
/* execute the string, producing the actual points of the curve
*/
curve = execute(curve_string, curve_cfg.angle, scale, orientation);
/* stores the coordinates in the given sequence
*/
_ref = zip(seq, curve);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
_ref2 = _ref[_i], d = _ref2[0], point = _ref2[1];
d.x = point.x;
d.y = point.y;
}
/* center the layout coordinates in the center of its bounding box
*/
max_x = d3.max(seq, function(d) {
return d.x;
});
max_y = d3.max(seq, function(d) {
return d.y;
});
min_x = d3.min(seq, function(d) {
return d.x;
});
min_y = d3.min(seq, function(d) {
return d.y;
});
_results = [];
for (_j = 0, _len2 = seq.length; _j < _len2; _j++) {
d = seq[_j];
d.x -= (max_x + min_x) / 2;
_results.push(d.y -= (max_y + min_y) / 2);
}
return _results;
},
/* recursively assign positions to internal nodes too. also compute leaf descendants
*/
displace_tree: function(node) {
var c;
if (!(node.children != null)) {
/* this is a leaf
*/
node.leaf_descendants = [node];
return node.leaf_descendants;
}
/* an internal node's position is the centroid of its leaf descendants
*/
node.leaf_descendants = ((function() {
var _i, _len, _ref, _results;
_ref = node.children;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
c = _ref[_i];
_results.push(sfc_layout.displace_tree(c));
}
return _results;
})()).reduce(function(a, d) {
return a.concat(d);
});
node.x = d3.mean(node.leaf_descendants, function(d) {
return d.x;
});
node.y = d3.mean(node.leaf_descendants, function(d) {
return d.y;
});
/* pass descendants up to the hierarchy
*/
return node.leaf_descendants;
}
};
}).call(this);
tcmp = (a,b) ->
children_a = (if a.children? then a.children else [])
children_b = (if b.children? then b.children else [])
for [ai, bi] in zip(children_a,children_b)
ci = tcmp(ai,bi)
if ci isnt 0
return ci
return children_b.length-children_a.length
rsort = (t) ->
children = (if t.children? then t.children else [])
for c in children
rsort(c)
children.sort(tcmp)
window.tree_utils = {
### sort the given unordered tree using a canonical ordering ###
### see Constant time generation of free trees - Wright et al. 1986 ###
canonical_sort: (tree) ->
rsort(tree)
### return the ordered sequence of leaves of a given tree ###
get_leaves: (tree) ->
seq = []
parse_leaves = (node) ->
if not node.children?
seq.push node
else
for c in node.children
parse_leaves(c)
parse_leaves(tree)
return seq
}
(function() {
var rsort, tcmp;
tcmp = function(a, b) {
var ai, bi, children_a, children_b, ci, _i, _len, _ref, _ref2;
children_a = (a.children != null ? a.children : []);
children_b = (b.children != null ? b.children : []);
_ref = zip(children_a, children_b);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
_ref2 = _ref[_i], ai = _ref2[0], bi = _ref2[1];
ci = tcmp(ai, bi);
if (ci !== 0) return ci;
}
return children_b.length - children_a.length;
};
rsort = function(t) {
var c, children, _i, _len;
children = (t.children != null ? t.children : []);
for (_i = 0, _len = children.length; _i < _len; _i++) {
c = children[_i];
rsort(c);
}
return children.sort(tcmp);
};
window.tree_utils = {
/* sort the given unordered tree using a canonical ordering
*/
/* see Constant time generation of free trees - Wright et al. 1986
*/
canonical_sort: function(tree) {
return rsort(tree);
},
/* return the ordered sequence of leaves of a given tree
*/
get_leaves: function(tree) {
var parse_leaves, seq;
seq = [];
parse_leaves = function(node) {
var c, _i, _len, _ref, _results;
if (!(node.children != null)) {
return seq.push(node);
} else {
_ref = node.children;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
c = _ref[_i];
_results.push(parse_leaves(c));
}
return _results;
}
};
parse_leaves(tree);
return seq;
}
};
}).call(this);
### python-like zip ###
window.zip = () ->
args = [].slice.call(arguments)
shortest = if args.length == 0 then [] else args.reduce(((a,b) ->
if a.length < b.length then a else b
))
return shortest.map(((_,i) ->
args.map((array) -> array[i])
))
/* python-like zip
*/
(function() {
window.zip = function() {
var args, shortest;
args = [].slice.call(arguments);
shortest = args.length === 0 ? [] : args.reduce((function(a, b) {
if (a.length < b.length) {
return a;
} else {
return b;
}
}));
return shortest.map((function(_, i) {
return args.map(function(array) {
return array[i];
});
}));
};
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment