Skip to content

Instantly share code, notes, and snippets.

@micahstubbs
Created August 9, 2017 20:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micahstubbs/876d8cfa60670254c938d75a984d4f71 to your computer and use it in GitHub Desktop.
Save micahstubbs/876d8cfa60670254c938d75a984d4f71 to your computer and use it in GitHub Desktop.
d3 example graph search - description query
height: 960
license: BSD-3-Clause
border: no

This iteration add an interaction that opens the block represented by a node when you click on that node

In this iteration, we load json data from a static file. This json data is produced by the REST API of a neo4j graph database that contains the d3 example README citation graph, in response to a query that we post to it.

This query finds all blocks that have the string map somewhere in the description (gist title) show those blocks and all blocks that they have a 1st degree link-in-the-README citation relationship with

MATCH(n)-[:LINKS_TO]-(m)
WHERE n.description =~  '.*map.*'
RETURN n, m

the cool thing about this is the related nodes may not have map anywhere in the description, but we can still use some known graph of d3 example relationships (in this case README citations) to infer that they are relevant to a map keyword search

a fork of the block d3 example graph search - user query from @micahstubbs

see also

the parent project for blockbuilder graph search ui prototypes
https://github.com/micahstubbs/bbgs-ui-prototypes

the blockbuilder graph search neo4j graph database source data & config backend project https://github.com/micahstubbs/blockbuilder-graph-search-index

/* global d3 */
function forceInABox(alpha) {
function index(d) {
return d.index;
}
var id = index,
nodes,
links, //needed for the force version
tree,
size = [100, 100],
nodeSize = 1, // The expected node size used for computing the cluster node
forceCharge = -2,
foci = {},
// oldStart = force.start,
linkStrengthIntraCluster = 0.1,
linkStrengthInterCluster = 0.01,
// oldGravity = force.gravity(),
templateNodes = [],
offset = [0, 0],
templateForce,
templateNodesSel,
groupBy = function(d) {
return d.cluster;
},
template = 'treemap',
enableGrouping = true,
strength = 0.1;
// showingTemplate = false;
function force(alpha) {
if (!enableGrouping) {
return force;
}
if (template === 'force') {
//Do the tick of the template force and get the new focis
templateForce.tick();
getFocisFromTemplate();
}
for (var i = 0, n = nodes.length, node, k = alpha * strength; i < n; ++i) {
node = nodes[i];
node.vx += (foci[groupBy(node)].x - node.x) * k;
node.vy += (foci[groupBy(node)].y - node.y) * k;
}
}
function initialize() {
if (!nodes) return;
// var i,
// n = nodes.length,
// m = links.length,
// nodeById = map(nodes, id),
// link;
if (template === 'treemap') {
initializeWithTreemap();
} else {
initializeWithForce();
}
}
force.initialize = function(_) {
nodes = _;
initialize();
};
function getLinkKey(l) {
var sourceID = groupBy(l.source), targetID = groupBy(l.target);
return sourceID <= targetID
? sourceID + '~' + targetID
: targetID + '~' + sourceID;
}
function computeClustersNodeCounts(nodes) {
var clustersCounts = d3.map();
nodes.forEach(function(d) {
if (!clustersCounts.has(groupBy(d))) {
clustersCounts.set(groupBy(d), 0);
}
});
nodes.forEach(function(d) {
// if (!d.show) { return; }
clustersCounts.set(groupBy(d), clustersCounts.get(groupBy(d)) + 1);
});
return clustersCounts;
}
//Returns
function computeClustersLinkCounts(links) {
var dClusterLinks = d3.map(), clusterLinks = [];
links.forEach(function(l) {
var key = getLinkKey(l), count;
if (dClusterLinks.has(key)) {
count = dClusterLinks.get(key);
} else {
count = 0;
}
count += 1;
dClusterLinks.set(key, count);
});
dClusterLinks.entries().forEach(function(d) {
var source, target;
source = d.key.split('~')[0];
target = d.key.split('~')[1];
clusterLinks.push({
source: source,
target: target,
count: d.value
});
});
return clusterLinks;
}
//Returns the metagraph of the clusters
function getGroupsGraph() {
var gnodes = [],
glinks = [],
// edges = [],
dNodes = d3.map(),
// totalSize = 0,
clustersList,
c,
i,
size,
clustersCounts,
clustersLinks;
clustersCounts = computeClustersNodeCounts(nodes);
clustersLinks = computeClustersLinkCounts(links);
//map.keys() is really slow, it's crucial to have it outside the loop
clustersList = clustersCounts.keys();
for (i = 0; i < clustersList.length; i += 1) {
c = clustersList[i];
size = clustersCounts.get(c);
gnodes.push({ id: c, size: size });
dNodes.set(c, i);
// totalSize += size;
}
clustersLinks.forEach(function(l) {
glinks.push({
source: dNodes.get(l.source),
target: dNodes.get(l.target),
count: l.count
});
});
return { nodes: gnodes, links: glinks };
}
function getGroupsTree() {
var children = [], totalSize = 0, clustersList, c, i, size, clustersCounts;
clustersCounts = computeClustersNodeCounts(force.nodes());
//map.keys() is really slow, it's crucial to have it outside the loop
clustersList = clustersCounts.keys();
for (i = 0; i < clustersList.length; i += 1) {
c = clustersList[i];
size = clustersCounts.get(c);
children.push({ id: c, size: size });
totalSize += size;
}
// return {id: "clustersTree", size: totalSize, children : children};
return { id: 'clustersTree', children: children };
}
function getFocisFromTemplate() {
//compute foci
foci.none = { x: 0, y: 0 };
templateNodes.forEach(function(d) {
if (template === 'treemap') {
foci[d.data.id] = {
x: d.x0 + (d.x1 - d.x0) / 2 - offset[0],
y: d.y0 + (d.y1 - d.y0) / 2 - offset[1]
};
} else {
foci[d.id] = { x: d.x - offset[0], y: d.y - offset[1] };
}
});
}
function initializeWithTreemap() {
var treemap = d3.treemap().size(force.size());
tree = d3
.hierarchy(getGroupsTree())
// .sort(function (p, q) { return d3.ascending(p.size, q.size); })
// .count()
.sum(function(d) {
return d.size;
})
.sort(function(a, b) {
return b.height - a.height || b.value - a.value;
});
templateNodes = treemap(tree).leaves();
getFocisFromTemplate();
}
function checkLinksAsObjects() {
// Check if links come in the format of indexes instead of objects
var linkCount = 0;
if (nodes.length === 0) return;
// console.log('nodes from forceInABox', nodes);
links.forEach(function(link) {
var source, target;
if (!nodes) return;
source = link.source;
target = link.target;
if (typeof link.source !== 'object') source = nodes[link.source];
if (typeof link.target !== 'object') target = nodes[link.target];
if (source === undefined || target === undefined) {
console.log('link from forceInABox', link);
throw Error(
"Error setting links, couldn't find nodes for a link (see it on the console)"
);
}
link.source = source;
link.target = target;
link.index = linkCount++;
});
}
function initializeWithForce() {
var net;
if (nodes && nodes.length > 0) {
if (groupBy(nodes[0]) === undefined) {
throw Error(
"Couldn't find the grouping attribute for the nodes. Make sure to set it up with forceInABox.groupBy('attr') before calling .links()"
);
}
}
checkLinksAsObjects();
net = getGroupsGraph();
templateForce = d3
.forceSimulation(net.nodes)
.force('x', d3.forceX(size[0] / 2).strength(0.5))
.force('y', d3.forceY(size[1] / 2).strength(0.5))
.force(
'collide',
d3.forceCollide(function(d) {
return d.size * nodeSize;
})
)
.force(
'charge',
d3.forceManyBody().strength(function(d) {
return forceCharge * d.size;
})
)
.force('links', d3.forceLink(!net.nodes ? net.links : []));
templateNodes = templateForce.nodes();
getFocisFromTemplate();
}
function drawTreemap(container) {
container.selectAll('.cell').remove();
container
.selectAll('cell')
.data(templateNodes)
.enter()
.append('svg:rect')
.attr('class', 'cell')
.attr('x', function(d) {
return d.x0;
})
.attr('y', function(d) {
return d.y0;
})
.attr('width', function(d) {
return d.x1 - d.x0;
})
.attr('height', function(d) {
return d.y1 - d.y0;
});
}
function drawGraph(container) {
container.selectAll('.cell').remove();
templateNodesSel = container.selectAll('cell').data(templateNodes);
templateNodesSel
.enter()
.append('svg:circle')
.attr('class', 'cell')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', function(d) {
return d.size * nodeSize;
});
}
force.drawTemplate = function(container) {
// showingTemplate = true;
if (template === 'treemap') {
drawTreemap(container);
} else {
drawGraph(container);
}
return force;
};
//Backwards compatibility
force.drawTreemap = force.drawTemplate;
force.deleteTemplate = function(container) {
// showingTemplate = false;
container.selectAll('.cell').remove();
return force;
};
force.template = function(x) {
if (!arguments.length) return template;
template = x;
initialize();
return force;
};
force.groupBy = function(x) {
if (!arguments.length) return groupBy;
if (typeof x === 'string') {
groupBy = function(d) {
return d[x];
};
return force;
}
groupBy = x;
return force;
};
force.enableGrouping = function(x) {
if (!arguments.length) return enableGrouping;
enableGrouping = x;
// update();
return force;
};
force.strength = function(x) {
if (!arguments.length) return strength;
strength = x;
return force;
};
force.getLinkStrength = function(e) {
if (enableGrouping) {
if (groupBy(e.source) === groupBy(e.target)) {
if (typeof linkStrengthIntraCluster === 'function') {
return linkStrengthIntraCluster(e);
} else {
return linkStrengthIntraCluster;
}
} else {
if (typeof linkStrengthInterCluster === 'function') {
return linkStrengthInterCluster(e);
} else {
return linkStrengthInterCluster;
}
}
} else {
// Not grouping return the intracluster
if (typeof linkStrengthIntraCluster === 'function') {
return linkStrengthIntraCluster(e);
} else {
return linkStrengthIntraCluster;
}
}
};
force.id = function(_) {
return arguments.length ? ((id = _), force) : id;
};
force.size = function(_) {
return arguments.length ? ((size = _), force) : size;
};
force.linkStrengthInterCluster = function(_) {
return arguments.length
? ((linkStrengthInterCluster = _), force)
: linkStrengthInterCluster;
};
force.linkStrengthIntraCluster = function(_) {
return arguments.length
? ((linkStrengthIntraCluster = _), force)
: linkStrengthIntraCluster;
};
force.nodes = function(_) {
return arguments.length ? ((nodes = _), force) : nodes;
};
force.links = function(_) {
if (!arguments.length) return links;
if (_ === null) links = [];
else links = _;
return force;
};
force.nodeSize = function(_) {
return arguments.length ? ((nodeSize = _), force) : nodeSize;
};
force.forceCharge = function(_) {
return arguments.length ? ((forceCharge = _), force) : forceCharge;
};
force.offset = function(_) {
return arguments.length ? ((offset = _), force) : offset;
};
return force;
}
<!DOCTYPE html>
<meta charset='utf-8'>
<style>
img {
max-width: 230px;
max-height: 120px;
}
#canvas-container {
width: 100%;
text-align: center;
}
canvas {
display: inline;
}
</style>
<a target='_blank' style='outline:none;'>
<div id='canvas-container'>
<canvas width='960' height='960'>Your browser does not support canvas</canvas>
</div>
</a>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.js'></script>
<script src="forceInABox.js"></script>
<script src='jsLouvain.js'></script>
<script src='vis.js'></script>
/*
Author: Corneliu S. (github.com/upphiminn)
This is a javascript implementation of the Louvain
community detection algorithm (http://arxiv.org/abs/0803.0476)
Based on https://bitbucket.org/taynaud/python-louvain/overview
*/
(function() {
jLouvain = function() {
//Constants
var __PASS_MAX = -1;
var __MIN = 0.0000001;
//Local vars
var original_graph_nodes;
var original_graph_edges;
var original_graph = {};
var partition_init;
//Helpers
function make_set(array) {
var set = {};
array.forEach(function(d, i) {
set[d] = true;
});
return Object.keys(set);
}
function obj_values(obj) {
var vals = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
vals.push(obj[key]);
}
}
return vals;
}
function get_degree_for_node(graph, node) {
var neighbours = graph._assoc_mat[node]
? Object.keys(graph._assoc_mat[node])
: [];
var weight = 0;
neighbours.forEach(function(neighbour, i) {
var value = graph._assoc_mat[node][neighbour] || 1;
if (node == neighbour) value *= 2;
weight += value;
});
return weight;
}
function get_neighbours_of_node(graph, node) {
if (typeof graph._assoc_mat[node] == 'undefined') return [];
var neighbours = Object.keys(graph._assoc_mat[node]);
return neighbours;
}
function get_edge_weight(graph, node1, node2) {
return graph._assoc_mat[node1]
? graph._assoc_mat[node1][node2]
: undefined;
}
function get_graph_size(graph) {
var size = 0;
graph.edges.forEach(function(edge) {
size += edge.weight;
});
return size;
}
function add_edge_to_graph(graph, edge) {
update_assoc_mat(graph, edge);
var edge_index = graph.edges
.map(function(d) {
return d.source + '_' + d.target;
})
.indexOf(edge.source + '_' + edge.target);
if (edge_index != -1) graph.edges[edge_index].weight = edge.weight;
else graph.edges.push(edge);
}
function make_assoc_mat(edge_list) {
var mat = {};
edge_list.forEach(function(edge, i) {
mat[edge.source] = mat[edge.source] || {};
mat[edge.source][edge.target] = edge.weight;
mat[edge.target] = mat[edge.target] || {};
mat[edge.target][edge.source] = edge.weight;
});
return mat;
}
function update_assoc_mat(graph, edge) {
graph._assoc_mat[edge.source] = graph._assoc_mat[edge.source] || {};
graph._assoc_mat[edge.source][edge.target] = edge.weight;
graph._assoc_mat[edge.target] = graph._assoc_mat[edge.target] || {};
graph._assoc_mat[edge.target][edge.source] = edge.weight;
}
function clone(obj) {
if (obj == null || typeof obj != 'object') return obj;
var temp = obj.constructor();
for (var key in obj)
temp[key] = clone(obj[key]);
return temp;
}
//Core-Algorithm Related
function init_status(graph, status, part) {
status['nodes_to_com'] = {};
status['total_weight'] = 0;
status['internals'] = {};
status['degrees'] = {};
status['gdegrees'] = {};
status['loops'] = {};
status['total_weight'] = get_graph_size(graph);
if (typeof part == 'undefined') {
graph.nodes.forEach(function(node, i) {
status.nodes_to_com[node] = i;
var deg = get_degree_for_node(graph, node);
if (deg < 0) throw 'Bad graph type, use positive weights!';
status.degrees[i] = deg;
status.gdegrees[node] = deg;
status.loops[node] = get_edge_weight(graph, node, node) || 0;
status.internals[i] = status.loops[node];
});
} else {
graph.nodes.forEach(function(node, i) {
var com = part[node];
status.nodes_to_com[node] = com;
var deg = get_degree_for_node(graph, node);
status.degrees[com] = (status.degrees[com] || 0) + deg;
status.gdegrees[node] = deg;
var inc = 0.0;
var neighbours = get_neighbours_of_node(graph, node);
neighbours.forEach(function(neighbour, i) {
var weight = graph._assoc_mat[node][neighbour];
if (weight <= 0) {
throw 'Bad graph type, use positive weights';
}
if (part[neighbour] == com) {
if (neighbour == node) {
inc += weight;
} else {
inc += weight / 2.0;
}
}
});
status.internals[com] = (status.internals[com] || 0) + inc;
});
}
}
function __modularity(status) {
var links = status.total_weight;
var result = 0.0;
var communities = make_set(obj_values(status.nodes_to_com));
communities.forEach(function(com, i) {
var in_degree = status.internals[com] || 0;
var degree = status.degrees[com] || 0;
if (links > 0) {
result =
result + in_degree / links - Math.pow(degree / (2.0 * links), 2);
}
});
return result;
}
function __neighcom(node, graph, status) {
// compute the communities in the neighb. of the node, with the graph given by
// node_to_com
var weights = {};
var neighboorhood = get_neighbours_of_node(graph, node); //make iterable;
neighboorhood.forEach(function(neighbour, i) {
if (neighbour != node) {
var weight = graph._assoc_mat[node][neighbour] || 1;
var neighbourcom = status.nodes_to_com[neighbour];
weights[neighbourcom] = (weights[neighbourcom] || 0) + weight;
}
});
return weights;
}
function __insert(node, com, weight, status) {
//insert node into com and modify status
status.nodes_to_com[node] = +com;
status.degrees[com] =
(status.degrees[com] || 0) + (status.gdegrees[node] || 0);
status.internals[com] =
(status.internals[com] || 0) + weight + (status.loops[node] || 0);
}
function __remove(node, com, weight, status) {
//remove node from com and modify status
status.degrees[com] =
(status.degrees[com] || 0) - (status.gdegrees[node] || 0);
status.internals[com] =
(status.internals[com] || 0) - weight - (status.loops[node] || 0);
status.nodes_to_com[node] = -1;
}
function __renumber(dict) {
var count = 0;
var ret = clone(dict); //deep copy :)
var new_values = {};
var dict_keys = Object.keys(dict);
dict_keys.forEach(function(key) {
var value = dict[key];
var new_value = typeof new_values[value] == 'undefined'
? -1
: new_values[value];
if (new_value == -1) {
new_values[value] = count;
new_value = count;
count = count + 1;
}
ret[key] = new_value;
});
return ret;
}
function __one_level(graph, status) {
//Compute one level of the Communities Dendogram.
var modif = true,
nb_pass_done = 0,
cur_mod = __modularity(status),
new_mod = cur_mod;
while (modif && nb_pass_done != __PASS_MAX) {
cur_mod = new_mod;
modif = false;
nb_pass_done += 1;
graph.nodes.forEach(function(node, i) {
var com_node = status.nodes_to_com[node];
var degc_totw =
(status.gdegrees[node] || 0) / (status.total_weight * 2.0);
var neigh_communities = __neighcom(node, graph, status);
__remove(node, com_node, neigh_communities[com_node] || 0.0, status);
var best_com = com_node;
var best_increase = 0;
var neigh_communities_entries = Object.keys(neigh_communities); //make iterable;
neigh_communities_entries.forEach(function(com, i) {
var incr =
neigh_communities[com] - (status.degrees[com] || 0.0) * degc_totw;
if (incr > best_increase) {
best_increase = incr;
best_com = com;
}
});
__insert(node, best_com, neigh_communities[best_com] || 0, status);
if (best_com != com_node) modif = true;
});
new_mod = __modularity(status);
if (new_mod - cur_mod < __MIN) break;
}
}
function induced_graph(partition, graph) {
var ret = { nodes: [], edges: [], _assoc_mat: {} };
var w_prec, weight;
//add nodes from partition values
var partition_values = obj_values(partition);
ret.nodes = ret.nodes.concat(make_set(partition_values)); //make set
graph.edges.forEach(function(edge, i) {
weight = edge.weight || 1;
var com1 = partition[edge.source];
var com2 = partition[edge.target];
w_prec = get_edge_weight(ret, com1, com2) || 0;
var new_weight = w_prec + weight;
add_edge_to_graph(ret, {
source: com1,
target: com2,
weight: new_weight
});
});
return ret;
}
function partition_at_level(dendogram, level) {
var partition = clone(dendogram[0]);
for (var i = 1; i < level + 1; i++)
Object.keys(partition).forEach(function(key, j) {
var node = key;
var com = partition[key];
partition[node] = dendogram[i][com];
});
return partition;
}
function generate_dendogram(graph, part_init) {
if (graph.edges.length == 0) {
var part = {};
graph.nodes.forEach(function(node, i) {
part[node] = node;
});
return part;
}
var status = {};
init_status(original_graph, status, part_init);
var mod = __modularity(status);
var status_list = [];
__one_level(original_graph, status);
var new_mod = __modularity(status);
var partition = __renumber(status.nodes_to_com);
status_list.push(partition);
mod = new_mod;
var current_graph = induced_graph(partition, original_graph);
init_status(current_graph, status);
while (true) {
__one_level(current_graph, status);
new_mod = __modularity(status);
if (new_mod - mod < __MIN) break;
partition = __renumber(status.nodes_to_com);
status_list.push(partition);
mod = new_mod;
current_graph = induced_graph(partition, current_graph);
init_status(current_graph, status);
}
return status_list;
}
var core = function() {
var status = {};
var dendogram = generate_dendogram(original_graph, partition_init);
return partition_at_level(dendogram, dendogram.length - 1);
};
core.nodes = function(nds) {
if (arguments.length > 0) {
original_graph_nodes = nds;
}
return core;
};
core.edges = function(edgs) {
if (typeof original_graph_nodes == 'undefined')
throw 'Please provide the graph nodes first!';
if (arguments.length > 0) {
original_graph_edges = edgs;
var assoc_mat = make_assoc_mat(edgs);
original_graph = {
nodes: original_graph_nodes,
edges: original_graph_edges,
_assoc_mat: assoc_mat
};
}
return core;
};
core.partition_init = function(prttn) {
if (arguments.length > 0) {
partition_init = prttn;
}
return core;
};
return core;
};
})();
{
"results": [
{
"columns": ["n", "m"],
"data": [
{
"row": [
{
"createdAt": "2013-07-22T10:16:34Z",
"description": "Self Organizing Map - Heatmap - D3",
"user": "nbremer",
"gistId": "6052814",
"updatedAt": "2015-12-20T01:59:10Z"
},
{
"createdAt": "2013-07-22T09:50:44Z",
"description": "Self Organizing Map - Hexagonal Heatmap - Lines",
"user": "nbremer",
"gistId": "6052681",
"updatedAt": "2015-12-20T01:59:03Z"
}
],
"meta": [
{
"id": 105,
"type": "node",
"deleted": false
},
{
"id": 106,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-07-22T10:16:34Z",
"description": "Self Organizing Map - Heatmap - D3",
"user": "nbremer",
"gistId": "6052814",
"updatedAt": "2015-12-20T01:59:10Z"
},
{
"createdAt": "2013-07-22T09:50:44Z",
"description": "Self Organizing Map - Hexagonal Heatmap - Lines",
"user": "nbremer",
"gistId": "6052681",
"updatedAt": "2015-12-20T01:59:03Z"
}
],
"meta": [
{
"id": 105,
"type": "node",
"deleted": false
},
{
"id": 106,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-07-22T09:50:44Z",
"description": "Self Organizing Map - Hexagonal Heatmap - Lines",
"user": "nbremer",
"gistId": "6052681",
"updatedAt": "2015-12-20T01:59:03Z"
},
{
"createdAt": "2013-07-22T10:16:34Z",
"description": "Self Organizing Map - Heatmap - D3",
"user": "nbremer",
"gistId": "6052814",
"updatedAt": "2015-12-20T01:59:10Z"
}
],
"meta": [
{
"id": 106,
"type": "node",
"deleted": false
},
{
"id": 105,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-07-22T09:50:44Z",
"description": "Self Organizing Map - Hexagonal Heatmap - Lines",
"user": "nbremer",
"gistId": "6052681",
"updatedAt": "2015-12-20T01:59:03Z"
},
{
"createdAt": "2013-07-22T10:16:34Z",
"description": "Self Organizing Map - Heatmap - D3",
"user": "nbremer",
"gistId": "6052814",
"updatedAt": "2015-12-20T01:59:10Z"
}
],
"meta": [
{
"id": 106,
"type": "node",
"deleted": false
},
{
"id": 105,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-08-20T10:51:34Z",
"description": "France_topographic_map.svg",
"user": "hugolpz",
"gistId": "6279966",
"updatedAt": "2015-12-21T08:39:11Z"
},
{
"createdAt": "null",
"description": "null",
"user": "null",
"gistId": "5691513",
"updatedAt": "null"
}
],
"meta": [
{
"id": 124,
"type": "node",
"deleted": false
},
{
"id": 98,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 218,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 218,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2013-12-18T22:48:11Z",
"description": "Fractal tree depth map (random, Gosper)",
"user": "nitaku",
"gistId": "8031205",
"updatedAt": "2015-12-31T19:08:58Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 210,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2013-11-15T23:43:20Z",
"description": "Graph editing",
"user": "nitaku",
"gistId": "7493693",
"updatedAt": "2015-12-28T11:29:11Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 185,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2012-11-23T17:56:09Z",
"description": "U.S. TopoJSON",
"user": "mbostock",
"gistId": "4136647",
"updatedAt": "2016-02-09T01:46:11Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 204,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2013-10-17T13:52:38Z",
"description": "Precomputed Gosper regions",
"user": "nitaku",
"gistId": "7025272",
"updatedAt": "2015-12-25T19:09:02Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 163,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2013-10-17T12:11:09Z",
"description": "Gosper regions",
"user": "nitaku",
"gistId": "7023794",
"updatedAt": "2015-12-25T18:49:35Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 161,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2013-10-17T13:52:38Z",
"description": "Precomputed Gosper regions",
"user": "nitaku",
"gistId": "7025272",
"updatedAt": "2015-12-25T19:09:02Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 163,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2013-10-16T21:27:57Z",
"description": "Gosper hex tiling (fancy)",
"user": "nitaku",
"gistId": "7015186",
"updatedAt": "2015-12-25T17:39:36Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 160,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "null",
"description": "null",
"user": "null",
"gistId": "7960622",
"updatedAt": "null"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 203,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2013-12-13T01:15:00Z",
"description": "Random tree II",
"user": "nitaku",
"gistId": "7938492",
"updatedAt": "2015-12-31T05:09:00Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 202,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "null",
"description": "null",
"user": "null",
"gistId": "7962295",
"updatedAt": "null"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 201,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
},
{
"createdAt": "2013-10-17T13:52:38Z",
"description": "Precomputed Gosper regions",
"user": "nitaku",
"gistId": "7025272",
"updatedAt": "2015-12-25T19:09:02Z"
}
],
"meta": [
{
"id": 205,
"type": "node",
"deleted": false
},
{
"id": 163,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T22:48:11Z",
"description": "Fractal tree depth map (random, Gosper)",
"user": "nitaku",
"gistId": "8031205",
"updatedAt": "2015-12-31T19:08:58Z"
},
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
}
],
"meta": [
{
"id": 210,
"type": "node",
"deleted": false
},
{
"id": 218,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T22:48:11Z",
"description": "Fractal tree depth map (random, Gosper)",
"user": "nitaku",
"gistId": "8031205",
"updatedAt": "2015-12-31T19:08:58Z"
},
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
}
],
"meta": [
{
"id": 210,
"type": "node",
"deleted": false
},
{
"id": 218,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-18T22:48:11Z",
"description": "Fractal tree depth map (random, Gosper)",
"user": "nitaku",
"gistId": "8031205",
"updatedAt": "2015-12-31T19:08:58Z"
},
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
}
],
"meta": [
{
"id": 210,
"type": "node",
"deleted": false
},
{
"id": 205,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-30T17:51:39Z",
"description": "Base map for Haiyan typhoon track",
"user": "rveciana",
"gistId": "8185373",
"updatedAt": "2016-01-01T18:39:13Z"
},
{
"createdAt": "2012-09-20T17:13:29Z",
"description": "Spherical Mercator",
"user": "mbostock",
"gistId": "3757132",
"updatedAt": "2016-02-09T01:37:10Z"
}
],
"meta": [
{
"id": 212,
"type": "node",
"deleted": false
},
{
"id": 208,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-12-30T17:51:39Z",
"description": "Base map for Haiyan typhoon track",
"user": "rveciana",
"gistId": "8185373",
"updatedAt": "2016-01-01T18:39:13Z"
},
{
"createdAt": "2012-09-20T17:13:29Z",
"description": "Spherical Mercator",
"user": "mbostock",
"gistId": "3757132",
"updatedAt": "2016-02-09T01:37:10Z"
}
],
"meta": [
{
"id": 212,
"type": "node",
"deleted": false
},
{
"id": 208,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "2013-12-18T22:48:11Z",
"description": "Fractal tree depth map (random, Gosper)",
"user": "nitaku",
"gistId": "8031205",
"updatedAt": "2015-12-31T19:08:58Z"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 210,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 205,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "null",
"description": "null",
"user": "null",
"gistId": "8272105",
"updatedAt": "null"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 217,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "2014-01-04T20:46:29Z",
"description": "Canonical representation of unordered rooted trees",
"user": "nitaku",
"gistId": "8260510",
"updatedAt": "2016-01-02T05:59:07Z"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 211,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "2015-06-17T12:09:03Z",
"description": "Node Gosper hex tiling",
"user": "nitaku",
"gistId": "0c991d6ed0e994e1c7ed",
"updatedAt": "2015-08-29T14:23:13Z"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 726,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "2014-02-02T17:54:42Z",
"description": "Space-flling curve layout (Gosper)",
"user": "nitaku",
"gistId": "8772179",
"updatedAt": "2015-08-29T13:55:55Z"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 227,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "2013-12-18T22:48:11Z",
"description": "Fractal tree depth map (random, Gosper)",
"user": "nitaku",
"gistId": "8031205",
"updatedAt": "2015-12-31T19:08:58Z"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 210,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "2013-12-18T19:27:21Z",
"description": "Fractal treemap (random, Gosper)",
"user": "nitaku",
"gistId": "8028264",
"updatedAt": "2015-12-31T18:39:11Z"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 205,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "null",
"description": "null",
"user": "null",
"gistId": "8272105",
"updatedAt": "null"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 217,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-01-05T19:32:04Z",
"description": "Fractal treemap of Konanopii (1,724 leaves)",
"user": "nitaku",
"gistId": "8272715",
"updatedAt": "2016-01-02T07:49:18Z"
},
{
"createdAt": "2014-01-04T20:46:29Z",
"description": "Canonical representation of unordered rooted trees",
"user": "nitaku",
"gistId": "8260510",
"updatedAt": "2016-01-02T05:59:07Z"
}
],
"meta": [
{
"id": 218,
"type": "node",
"deleted": false
},
{
"id": 211,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T13:58:25Z",
"description": "Jigsaw treemap (Gosper)",
"user": "nitaku",
"gistId": "8784278",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-02-03T17:18:56Z",
"description": "Gosper treemap with hierarchical edge bundling",
"user": "nitaku",
"gistId": "8788101",
"updatedAt": "2015-08-29T13:55:56Z"
}
],
"meta": [
{
"id": 228,
"type": "node",
"deleted": false
},
{
"id": 232,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T13:58:25Z",
"description": "Jigsaw treemap (Gosper)",
"user": "nitaku",
"gistId": "8784278",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-02-03T14:40:20Z",
"description": "Jigsaw treemap (Hilbert)",
"user": "nitaku",
"gistId": "8784942",
"updatedAt": "2015-08-29T13:55:56Z"
}
],
"meta": [
{
"id": 228,
"type": "node",
"deleted": false
},
{
"id": 229,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T13:58:25Z",
"description": "Jigsaw treemap (Gosper)",
"user": "nitaku",
"gistId": "8784278",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-02-02T17:54:42Z",
"description": "Space-flling curve layout (Gosper)",
"user": "nitaku",
"gistId": "8772179",
"updatedAt": "2015-08-29T13:55:55Z"
}
],
"meta": [
{
"id": 228,
"type": "node",
"deleted": false
},
{
"id": 227,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T14:40:20Z",
"description": "Jigsaw treemap (Hilbert)",
"user": "nitaku",
"gistId": "8784942",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-07-12T11:08:58Z",
"description": "Hilbert spiral (L-system)",
"user": "nitaku",
"gistId": "bffd66a05d5bf04aefa7",
"updatedAt": "2015-08-29T14:03:53Z"
}
],
"meta": [
{
"id": 229,
"type": "node",
"deleted": false
},
{
"id": 752,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T14:40:20Z",
"description": "Jigsaw treemap (Hilbert)",
"user": "nitaku",
"gistId": "8784942",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-02-12T00:38:14Z",
"description": "Unstable Hilbert curve",
"user": "nitaku",
"gistId": "8947565",
"updatedAt": "2015-08-29T13:56:17Z"
}
],
"meta": [
{
"id": 229,
"type": "node",
"deleted": false
},
{
"id": 239,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T14:40:20Z",
"description": "Jigsaw treemap (Hilbert)",
"user": "nitaku",
"gistId": "8784942",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-02-08T12:10:37Z",
"description": "Label placement for Hilbert treemaps",
"user": "nitaku",
"gistId": "8882722",
"updatedAt": "2015-08-29T13:56:10Z"
}
],
"meta": [
{
"id": 229,
"type": "node",
"deleted": false
},
{
"id": 236,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T14:40:20Z",
"description": "Jigsaw treemap (Hilbert)",
"user": "nitaku",
"gistId": "8784942",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-02-03T16:28:05Z",
"description": "Hilbert treemap (area encoding)",
"user": "nitaku",
"gistId": "8787102",
"updatedAt": "2015-08-29T13:55:56Z"
}
],
"meta": [
{
"id": 229,
"type": "node",
"deleted": false
},
{
"id": 230,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T14:40:20Z",
"description": "Jigsaw treemap (Hilbert)",
"user": "nitaku",
"gistId": "8784942",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-02-03T13:58:25Z",
"description": "Jigsaw treemap (Gosper)",
"user": "nitaku",
"gistId": "8784278",
"updatedAt": "2015-08-29T13:55:56Z"
}
],
"meta": [
{
"id": 229,
"type": "node",
"deleted": false
},
{
"id": 228,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T14:40:20Z",
"description": "Jigsaw treemap (Hilbert)",
"user": "nitaku",
"gistId": "8784942",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2013-09-10T20:15:19Z",
"description": "Hilbert curve (L-system)",
"user": "nitaku",
"gistId": "6514960",
"updatedAt": "2015-12-22T18:48:57Z"
}
],
"meta": [
{
"id": 229,
"type": "node",
"deleted": false
},
{
"id": 143,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T16:28:05Z",
"description": "Hilbert treemap (area encoding)",
"user": "nitaku",
"gistId": "8787102",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-02-03T14:40:20Z",
"description": "Jigsaw treemap (Hilbert)",
"user": "nitaku",
"gistId": "8784942",
"updatedAt": "2015-08-29T13:55:56Z"
}
],
"meta": [
{
"id": 230,
"type": "node",
"deleted": false
},
{
"id": 229,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T17:18:56Z",
"description": "Gosper treemap with hierarchical edge bundling",
"user": "nitaku",
"gistId": "8788101",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2012-12-19T22:31:13Z",
"description": "Hierarchical Edge Bundling",
"user": "mbostock",
"gistId": "4341134",
"updatedAt": "2016-04-11T03:04:09Z"
}
],
"meta": [
{
"id": 232,
"type": "node",
"deleted": false
},
{
"id": 231,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-03T17:18:56Z",
"description": "Gosper treemap with hierarchical edge bundling",
"user": "nitaku",
"gistId": "8788101",
"updatedAt": "2015-08-29T13:55:56Z"
},
{
"createdAt": "2014-02-03T13:58:25Z",
"description": "Jigsaw treemap (Gosper)",
"user": "nitaku",
"gistId": "8784278",
"updatedAt": "2015-08-29T13:55:56Z"
}
],
"meta": [
{
"id": 232,
"type": "node",
"deleted": false
},
{
"id": 228,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-08T12:10:37Z",
"description": "Label placement for Hilbert treemaps",
"user": "nitaku",
"gistId": "8882722",
"updatedAt": "2015-08-29T13:56:10Z"
},
{
"createdAt": "2014-02-12T00:38:14Z",
"description": "Unstable Hilbert curve",
"user": "nitaku",
"gistId": "8947565",
"updatedAt": "2015-08-29T13:56:17Z"
}
],
"meta": [
{
"id": 236,
"type": "node",
"deleted": false
},
{
"id": 239,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-02-08T12:10:37Z",
"description": "Label placement for Hilbert treemaps",
"user": "nitaku",
"gistId": "8882722",
"updatedAt": "2015-08-29T13:56:10Z"
},
{
"createdAt": "2014-02-03T14:40:20Z",
"description": "Jigsaw treemap (Hilbert)",
"user": "nitaku",
"gistId": "8784942",
"updatedAt": "2015-08-29T13:55:56Z"
}
],
"meta": [
{
"id": 236,
"type": "node",
"deleted": false
},
{
"id": 229,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-02-21T21:50:54Z",
"description": "Hexbin Heightmap Transitions",
"user": "syntagmatic",
"gistId": "c256fda4965d38e7c59b",
"updatedAt": "2015-08-29T14:15:53Z"
},
{
"createdAt": "2013-03-06T16:29:21Z",
"description": "Arc Tween",
"user": "mbostock",
"gistId": "5100636",
"updatedAt": "2016-04-30T20:28:27Z"
}
],
"meta": [
{
"id": 351,
"type": "node",
"deleted": false
},
{
"id": 118,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-02-21T21:50:54Z",
"description": "Hexbin Heightmap Transitions",
"user": "syntagmatic",
"gistId": "c256fda4965d38e7c59b",
"updatedAt": "2015-08-29T14:15:53Z"
},
{
"createdAt": "2015-01-25T10:36:49Z",
"description": "Hexbin Heightmap",
"user": "syntagmatic",
"gistId": "1092fe86860def004ea7",
"updatedAt": "2015-08-29T14:14:06Z"
}
],
"meta": [
{
"id": 351,
"type": "node",
"deleted": false
},
{
"id": 353,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-02-21T21:50:54Z",
"description": "Hexbin Heightmap Transitions",
"user": "syntagmatic",
"gistId": "c256fda4965d38e7c59b",
"updatedAt": "2015-08-29T14:15:53Z"
},
{
"createdAt": "2015-03-06T09:03:50Z",
"description": "Hexbin Canvas Transitions",
"user": "syntagmatic",
"gistId": "002ef2fb5c1dc2df5821",
"updatedAt": "2015-10-21T23:25:20Z"
}
],
"meta": [
{
"id": 351,
"type": "node",
"deleted": false
},
{
"id": 407,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-01-25T10:36:49Z",
"description": "Hexbin Heightmap",
"user": "syntagmatic",
"gistId": "1092fe86860def004ea7",
"updatedAt": "2015-08-29T14:14:06Z"
},
{
"createdAt": "2012-12-10T03:04:53Z",
"description": "Hexagonal Binning",
"user": "mbostock",
"gistId": "4248145",
"updatedAt": "2016-04-19T16:12:17Z"
}
],
"meta": [
{
"id": 353,
"type": "node",
"deleted": false
},
{
"id": 356,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-01-25T10:36:49Z",
"description": "Hexbin Heightmap",
"user": "syntagmatic",
"gistId": "1092fe86860def004ea7",
"updatedAt": "2015-08-29T14:14:06Z"
},
{
"createdAt": "2012-08-07T21:26:46Z",
"description": "Heightmap",
"user": "mbostock",
"gistId": "3289530",
"updatedAt": "2016-02-09T01:30:14Z"
}
],
"meta": [
{
"id": 353,
"type": "node",
"deleted": false
},
{
"id": 355,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-01-25T10:36:49Z",
"description": "Hexbin Heightmap",
"user": "syntagmatic",
"gistId": "1092fe86860def004ea7",
"updatedAt": "2015-08-29T14:14:06Z"
},
{
"createdAt": "2015-02-21T21:50:54Z",
"description": "Hexbin Heightmap Transitions",
"user": "syntagmatic",
"gistId": "c256fda4965d38e7c59b",
"updatedAt": "2015-08-29T14:15:53Z"
}
],
"meta": [
{
"id": 353,
"type": "node",
"deleted": false
},
{
"id": 351,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2012-08-07T21:26:46Z",
"description": "Heightmap",
"user": "mbostock",
"gistId": "3289530",
"updatedAt": "2016-02-09T01:30:14Z"
},
{
"createdAt": "2015-01-25T10:36:49Z",
"description": "Hexbin Heightmap",
"user": "syntagmatic",
"gistId": "1092fe86860def004ea7",
"updatedAt": "2015-08-29T14:14:06Z"
}
],
"meta": [
{
"id": 355,
"type": "node",
"deleted": false
},
{
"id": 353,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-08-26T16:04:24Z",
"description": "Modal Infoboxes - d3.carto.map",
"user": "emeeks",
"gistId": "433a9b04f82a1c78af4b",
"updatedAt": "2015-08-29T14:05:41Z"
},
{
"createdAt": "2014-08-26T21:50:55Z",
"description": "Custom Infobox Formatter - d3.carto.map",
"user": "emeeks",
"gistId": "905bb4f399e0855e08fe",
"updatedAt": "2015-08-29T14:05:45Z"
}
],
"meta": [
{
"id": 414,
"type": "node",
"deleted": false
},
{
"id": 655,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-08-26T16:04:24Z",
"description": "Modal Infoboxes - d3.carto.map",
"user": "emeeks",
"gistId": "433a9b04f82a1c78af4b",
"updatedAt": "2015-08-29T14:05:41Z"
},
{
"createdAt": "2014-08-26T21:50:55Z",
"description": "Custom Infobox Formatter - d3.carto.map",
"user": "emeeks",
"gistId": "905bb4f399e0855e08fe",
"updatedAt": "2015-08-29T14:05:45Z"
}
],
"meta": [
{
"id": 414,
"type": "node",
"deleted": false
},
{
"id": 655,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-09-10T17:38:03Z",
"description": "visualizing map distortion",
"user": "enjalot",
"gistId": "bd552e711b8325c64729",
"updatedAt": "2015-09-30T17:02:12Z"
},
{
"createdAt": "2014-07-07T03:35:48Z",
"description": "Map Pan & Zoom II",
"user": "mbostock",
"gistId": "eec4a6cda2f573574a11",
"updatedAt": "2016-02-09T01:53:20Z"
}
],
"meta": [
{
"id": 467,
"type": "node",
"deleted": false
},
{
"id": 615,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-09-10T17:38:03Z",
"description": "visualizing map distortion",
"user": "enjalot",
"gistId": "bd552e711b8325c64729",
"updatedAt": "2015-09-30T17:02:12Z"
},
{
"createdAt": "2015-08-16T03:37:26Z",
"description": "Comparing Map Projections",
"user": "syntagmatic",
"gistId": "ba569633d51ebec6ec6e",
"updatedAt": "2015-08-29T14:27:28Z"
}
],
"meta": [
{
"id": 467,
"type": "node",
"deleted": false
},
{
"id": 437,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-09-10T17:38:03Z",
"description": "visualizing map distortion",
"user": "enjalot",
"gistId": "bd552e711b8325c64729",
"updatedAt": "2015-09-30T17:02:12Z"
},
{
"createdAt": "null",
"description": "null",
"user": "null",
"gistId": "e2744ee563f7cab80350",
"updatedAt": "null"
}
],
"meta": [
{
"id": 467,
"type": "node",
"deleted": false
},
{
"id": 466,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-09-10T17:38:03Z",
"description": "visualizing map distortion",
"user": "enjalot",
"gistId": "bd552e711b8325c64729",
"updatedAt": "2015-09-30T17:02:12Z"
},
{
"createdAt": "2015-09-04T03:00:28Z",
"description": "Map & Globe",
"user": "curran",
"gistId": "01aa2685f083b6c1b9fb",
"updatedAt": "2015-09-23T21:36:19Z"
}
],
"meta": [
{
"id": 467,
"type": "node",
"deleted": false
},
{
"id": 614,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-09-10T17:38:03Z",
"description": "visualizing map distortion",
"user": "enjalot",
"gistId": "bd552e711b8325c64729",
"updatedAt": "2015-09-30T17:02:12Z"
},
{
"createdAt": "2015-09-30T17:02:24Z",
"description": "d3.geo.weichel",
"user": "enjalot",
"gistId": "27969219a945e2bd20dc",
"updatedAt": "2015-09-30T18:14:36Z"
}
],
"meta": [
{
"id": 467,
"type": "node",
"deleted": false
},
{
"id": 611,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-09-10T17:38:03Z",
"description": "visualizing map distortion",
"user": "enjalot",
"gistId": "bd552e711b8325c64729",
"updatedAt": "2015-09-30T17:02:12Z"
},
{
"createdAt": "2015-09-04T03:00:28Z",
"description": "Map & Globe",
"user": "curran",
"gistId": "01aa2685f083b6c1b9fb",
"updatedAt": "2015-09-23T21:36:19Z"
}
],
"meta": [
{
"id": 467,
"type": "node",
"deleted": false
},
{
"id": 614,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-08-07T15:35:00Z",
"description": "tmap with interactivity and pan/zoom",
"user": "timelyportfolio",
"gistId": "e2effb970b3cbe2f4e84",
"updatedAt": "2015-10-21T02:35:21Z"
},
{
"createdAt": "2015-08-07T15:35:00Z",
"description": "tmap with interactivity and pan/zoom",
"user": "timelyportfolio",
"gistId": "e2effb970b3cbe2f4e84",
"updatedAt": "2015-10-21T02:35:21Z"
}
],
"meta": [
{
"id": 515,
"type": "node",
"deleted": false
},
{
"id": 515,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-10-06T09:30:58Z",
"description": "Responsive map with Cartodb/Leaflet",
"user": "maartenzam",
"gistId": "7ef773bdf11999c9eebb",
"updatedAt": "2015-10-06T10:02:57Z"
},
{
"createdAt": "2015-11-19T15:02:16Z",
"description": "Responsive CartoDB choropleth linked to strip plot",
"user": "maartenzam",
"gistId": "8a7f9bed9715c0eb678a",
"updatedAt": "2015-11-19T15:27:50Z"
}
],
"meta": [
{
"id": 544,
"type": "node",
"deleted": false
},
{
"id": 941,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-10-06T09:30:58Z",
"description": "Responsive map with Cartodb/Leaflet",
"user": "maartenzam",
"gistId": "7ef773bdf11999c9eebb",
"updatedAt": "2015-10-06T10:02:57Z"
},
{
"createdAt": "2015-10-06T09:30:58Z",
"description": "Responsive map with Cartodb/Leaflet",
"user": "maartenzam",
"gistId": "7ef773bdf11999c9eebb",
"updatedAt": "2015-10-06T10:02:57Z"
}
],
"meta": [
{
"id": 544,
"type": "node",
"deleted": false
},
{
"id": 544,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-07-21T06:36:01Z",
"description": "Quadtree clustering - d3.carto.map",
"user": "emeeks",
"gistId": "7d5925cb7d9721c60360",
"updatedAt": "2015-08-29T14:04:17Z"
},
{
"createdAt": "2014-09-12T01:21:37Z",
"description": "Feature Clustering - d3.carto",
"user": "emeeks",
"gistId": "1a75ec54489368b514f8",
"updatedAt": "2015-08-29T14:06:21Z"
}
],
"meta": [
{
"id": 652,
"type": "node",
"deleted": false
},
{
"id": 654,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-08-26T21:50:55Z",
"description": "Custom Infobox Formatter - d3.carto.map",
"user": "emeeks",
"gistId": "905bb4f399e0855e08fe",
"updatedAt": "2015-08-29T14:05:45Z"
},
{
"createdAt": "2014-08-26T16:04:24Z",
"description": "Modal Infoboxes - d3.carto.map",
"user": "emeeks",
"gistId": "433a9b04f82a1c78af4b",
"updatedAt": "2015-08-29T14:05:41Z"
}
],
"meta": [
{
"id": 655,
"type": "node",
"deleted": false
},
{
"id": 414,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-08-26T21:50:55Z",
"description": "Custom Infobox Formatter - d3.carto.map",
"user": "emeeks",
"gistId": "905bb4f399e0855e08fe",
"updatedAt": "2015-08-29T14:05:45Z"
},
{
"createdAt": "2014-08-26T16:04:24Z",
"description": "Modal Infoboxes - d3.carto.map",
"user": "emeeks",
"gistId": "433a9b04f82a1c78af4b",
"updatedAt": "2015-08-29T14:05:41Z"
}
],
"meta": [
{
"id": 655,
"type": "node",
"deleted": false
},
{
"id": 414,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-08-26T21:50:55Z",
"description": "Custom Infobox Formatter - d3.carto.map",
"user": "emeeks",
"gistId": "905bb4f399e0855e08fe",
"updatedAt": "2015-08-29T14:05:45Z"
},
{
"createdAt": "2014-09-12T01:21:37Z",
"description": "Feature Clustering - d3.carto",
"user": "emeeks",
"gistId": "1a75ec54489368b514f8",
"updatedAt": "2015-08-29T14:06:21Z"
}
],
"meta": [
{
"id": 655,
"type": "node",
"deleted": false
},
{
"id": 654,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-02-24T23:27:41Z",
"description": "Printing map.svg file via D3js, Nodejs, Jsdom",
"user": "hugolpz",
"gistId": "1c34e14d8b7dd457f802",
"updatedAt": "2015-08-29T14:16:04Z"
},
{
"createdAt": "2015-02-24T23:27:41Z",
"description": "Printing map.svg file via D3js, Nodejs, Jsdom",
"user": "hugolpz",
"gistId": "1c34e14d8b7dd457f802",
"updatedAt": "2015-08-29T14:16:04Z"
}
],
"meta": [
{
"id": 681,
"type": "node",
"deleted": false
},
{
"id": 681,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-07-03T19:52:30Z",
"description": "Isometric treemap (flare)",
"user": "nitaku",
"gistId": "833632f23c308ae2d58b",
"updatedAt": "2015-08-29T14:24:13Z"
},
{
"createdAt": "2014-09-15T15:51:04Z",
"description": "Labeled treemap (flare)",
"user": "nitaku",
"gistId": "3424eed86f55550622ef",
"updatedAt": "2015-08-29T14:06:30Z"
}
],
"meta": [
{
"id": 716,
"type": "node",
"deleted": false
},
{
"id": 721,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-07-03T19:52:30Z",
"description": "Isometric treemap (flare)",
"user": "nitaku",
"gistId": "833632f23c308ae2d58b",
"updatedAt": "2015-08-29T14:24:13Z"
},
{
"createdAt": "2015-06-17T20:19:57Z",
"description": "Isometric projection",
"user": "nitaku",
"gistId": "8f96bf393b94caff688b",
"updatedAt": "2015-10-15T19:17:28Z"
}
],
"meta": [
{
"id": 716,
"type": "node",
"deleted": false
},
{
"id": 720,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-09-15T15:51:04Z",
"description": "Labeled treemap (flare)",
"user": "nitaku",
"gistId": "3424eed86f55550622ef",
"updatedAt": "2015-08-29T14:06:30Z"
},
{
"createdAt": "2014-09-15T13:44:56Z",
"description": "Basic treemap (flare)",
"user": "nitaku",
"gistId": "2d502924bad6152acbe5",
"updatedAt": "2015-08-29T14:06:30Z"
}
],
"meta": [
{
"id": 721,
"type": "node",
"deleted": false
},
{
"id": 737,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-09-15T15:51:04Z",
"description": "Labeled treemap (flare)",
"user": "nitaku",
"gistId": "3424eed86f55550622ef",
"updatedAt": "2015-08-29T14:06:30Z"
},
{
"createdAt": "2015-07-03T19:52:30Z",
"description": "Isometric treemap (flare)",
"user": "nitaku",
"gistId": "833632f23c308ae2d58b",
"updatedAt": "2015-08-29T14:24:13Z"
}
],
"meta": [
{
"id": 721,
"type": "node",
"deleted": false
},
{
"id": 716,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-06-18T18:58:03Z",
"description": "Isometric \"treemap\"",
"user": "nitaku",
"gistId": "e03a1a5c1a4a95f06c3b",
"updatedAt": "2016-03-08T03:54:52Z"
},
{
"createdAt": "2015-06-17T20:19:57Z",
"description": "Isometric projection",
"user": "nitaku",
"gistId": "8f96bf393b94caff688b",
"updatedAt": "2015-10-15T19:17:28Z"
}
],
"meta": [
{
"id": 724,
"type": "node",
"deleted": false
},
{
"id": 720,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-06-18T18:58:03Z",
"description": "Isometric \"treemap\"",
"user": "nitaku",
"gistId": "e03a1a5c1a4a95f06c3b",
"updatedAt": "2016-03-08T03:54:52Z"
},
{
"createdAt": "2015-06-17T20:19:57Z",
"description": "Isometric projection",
"user": "nitaku",
"gistId": "8f96bf393b94caff688b",
"updatedAt": "2015-10-15T19:17:28Z"
}
],
"meta": [
{
"id": 724,
"type": "node",
"deleted": false
},
{
"id": 720,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-06-18T18:58:03Z",
"description": "Isometric \"treemap\"",
"user": "nitaku",
"gistId": "e03a1a5c1a4a95f06c3b",
"updatedAt": "2016-03-08T03:54:52Z"
},
{
"createdAt": "2015-06-20T10:06:44Z",
"description": "Isometric word cloud",
"user": "nitaku",
"gistId": "6210bd80bdd20181e1f4",
"updatedAt": "2015-08-29T14:23:23Z"
}
],
"meta": [
{
"id": 724,
"type": "node",
"deleted": false
},
{
"id": 722,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-10-10T13:40:59Z",
"description": "Word cloud treemap (flare)",
"user": "nitaku",
"gistId": "79f16392f7e1bed77f07",
"updatedAt": "2015-08-29T14:07:27Z"
},
{
"createdAt": "2015-06-20T10:06:44Z",
"description": "Isometric word cloud",
"user": "nitaku",
"gistId": "6210bd80bdd20181e1f4",
"updatedAt": "2015-08-29T14:23:23Z"
}
],
"meta": [
{
"id": 725,
"type": "node",
"deleted": false
},
{
"id": 722,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-09-15T13:44:56Z",
"description": "Basic treemap (flare)",
"user": "nitaku",
"gistId": "2d502924bad6152acbe5",
"updatedAt": "2015-08-29T14:06:30Z"
},
{
"createdAt": "2014-09-15T15:51:04Z",
"description": "Labeled treemap (flare)",
"user": "nitaku",
"gistId": "3424eed86f55550622ef",
"updatedAt": "2015-08-29T14:06:30Z"
}
],
"meta": [
{
"id": 737,
"type": "node",
"deleted": false
},
{
"id": 721,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-11-07T05:12:48Z",
"description": "Treemap",
"user": "emeeks",
"gistId": "98f56f3e840143a4eccf",
"updatedAt": "2016-03-16T15:38:03Z"
},
{
"createdAt": "2015-11-08T06:19:51Z",
"description": "County Treemap I",
"user": "micahstubbs",
"gistId": "c5f71b45dbd87402e6f2",
"updatedAt": "2016-03-12T22:44:05Z"
}
],
"meta": [
{
"id": 792,
"type": "node",
"deleted": false
},
{
"id": 793,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-11-07T05:12:48Z",
"description": "Treemap",
"user": "emeeks",
"gistId": "98f56f3e840143a4eccf",
"updatedAt": "2016-03-16T15:38:03Z"
},
{
"createdAt": "2015-11-08T06:19:51Z",
"description": "County Treemap I",
"user": "micahstubbs",
"gistId": "c5f71b45dbd87402e6f2",
"updatedAt": "2016-03-12T22:44:05Z"
}
],
"meta": [
{
"id": 792,
"type": "node",
"deleted": false
},
{
"id": 793,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-11-08T06:19:51Z",
"description": "County Treemap I",
"user": "micahstubbs",
"gistId": "c5f71b45dbd87402e6f2",
"updatedAt": "2016-03-12T22:44:05Z"
},
{
"createdAt": "2015-11-07T05:12:48Z",
"description": "Treemap",
"user": "emeeks",
"gistId": "98f56f3e840143a4eccf",
"updatedAt": "2016-03-16T15:38:03Z"
}
],
"meta": [
{
"id": 793,
"type": "node",
"deleted": false
},
{
"id": 792,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-11-08T06:19:51Z",
"description": "County Treemap I",
"user": "micahstubbs",
"gistId": "c5f71b45dbd87402e6f2",
"updatedAt": "2016-03-12T22:44:05Z"
},
{
"createdAt": "2015-11-07T05:12:48Z",
"description": "Treemap",
"user": "emeeks",
"gistId": "98f56f3e840143a4eccf",
"updatedAt": "2016-03-16T15:38:03Z"
}
],
"meta": [
{
"id": 793,
"type": "node",
"deleted": false
},
{
"id": 792,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-12-01T04:40:58Z",
"description": "dots on a map: setup",
"user": "enjalot",
"gistId": "18cb7a77b2d9de597b86",
"updatedAt": "2016-04-29T10:08:29Z"
},
{
"createdAt": "2016-03-24T22:49:54Z",
"description": "topojson on a map: setup-gl",
"user": "enjalot",
"gistId": "676bfe2b6e67e61e0656",
"updatedAt": "2016-04-11T20:32:40Z"
}
],
"meta": [
{
"id": 1006,
"type": "node",
"deleted": false
},
{
"id": 1868,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-12-01T04:40:58Z",
"description": "dots on a map: setup",
"user": "enjalot",
"gistId": "18cb7a77b2d9de597b86",
"updatedAt": "2016-04-29T10:08:29Z"
},
{
"createdAt": "2015-12-01T06:10:27Z",
"description": "dots on a map: lasso",
"user": "enjalot",
"gistId": "b95748220bd4752fb33a",
"updatedAt": "2015-12-02T00:45:26Z"
}
],
"meta": [
{
"id": 1006,
"type": "node",
"deleted": false
},
{
"id": 1301,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-12-01T04:40:58Z",
"description": "dots on a map: setup",
"user": "enjalot",
"gistId": "18cb7a77b2d9de597b86",
"updatedAt": "2016-04-29T10:08:29Z"
},
{
"createdAt": "2015-12-03T18:17:59Z",
"description": "dots on a map: setup-gl",
"user": "enjalot",
"gistId": "dc1ce756527c072885dc",
"updatedAt": "2015-12-06T01:55:32Z"
}
],
"meta": [
{
"id": 1006,
"type": "node",
"deleted": false
},
{
"id": 1300,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-12-08T18:10:09Z",
"description": "d3 | reusable heatmap calendar",
"user": "eesur",
"gistId": "5fbda7f410d31da35e42",
"updatedAt": "2015-12-08T18:10:12Z"
},
{
"createdAt": "2012-11-13T01:33:21Z",
"description": "Calendar View",
"user": "mbostock",
"gistId": "4063318",
"updatedAt": "2016-03-28T13:27:52Z"
}
],
"meta": [
{
"id": 1010,
"type": "node",
"deleted": false
},
{
"id": 809,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2014-07-07T18:22:08Z",
"description": "D3 Trail Layout animated map",
"user": "rveciana",
"gistId": "2986e55a01c7008d4b5b",
"updatedAt": "2015-08-29T14:03:37Z"
},
{
"createdAt": "2014-04-15T16:02:03Z",
"description": "Hayan typhoon gradient colored track II",
"user": "rveciana",
"gistId": "10743959",
"updatedAt": "2015-08-29T13:59:32Z"
}
],
"meta": [
{
"id": 1283,
"type": "node",
"deleted": false
},
{
"id": 1284,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-08-09T11:55:29Z",
"description": "Flag map with D3js - SVG",
"user": "rveciana",
"gistId": "6193058",
"updatedAt": "2015-12-20T20:49:10Z"
},
{
"createdAt": "2015-12-13T16:18:54Z",
"description": "D3.js Boetti ",
"user": "espinielli",
"gistId": "9ea56e041f6847dbe944",
"updatedAt": "2015-12-20T15:03:50Z"
}
],
"meta": [
{
"id": 1285,
"type": "node",
"deleted": false
},
{
"id": 1280,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2013-06-01T09:26:01Z",
"description": "Cahill-Keyes map projection",
"user": "espinielli",
"gistId": "5689783",
"updatedAt": "2015-12-17T23:29:34Z"
},
{
"createdAt": "2012-12-01T05:12:55Z",
"description": "World Map",
"user": "mbostock",
"gistId": "4180634",
"updatedAt": "2016-04-20T13:59:18Z"
}
],
"meta": [
{
"id": 1286,
"type": "node",
"deleted": false
},
{
"id": 81,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-12-03T18:17:59Z",
"description": "dots on a map: setup-gl",
"user": "enjalot",
"gistId": "dc1ce756527c072885dc",
"updatedAt": "2015-12-06T01:55:32Z"
},
{
"createdAt": "2016-03-24T22:49:54Z",
"description": "topojson on a map: setup-gl",
"user": "enjalot",
"gistId": "676bfe2b6e67e61e0656",
"updatedAt": "2016-04-11T20:32:40Z"
}
],
"meta": [
{
"id": 1300,
"type": "node",
"deleted": false
},
{
"id": 1868,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-12-03T18:17:59Z",
"description": "dots on a map: setup-gl",
"user": "enjalot",
"gistId": "dc1ce756527c072885dc",
"updatedAt": "2015-12-06T01:55:32Z"
},
{
"createdAt": "2015-12-01T04:40:58Z",
"description": "dots on a map: setup",
"user": "enjalot",
"gistId": "18cb7a77b2d9de597b86",
"updatedAt": "2016-04-29T10:08:29Z"
}
],
"meta": [
{
"id": 1300,
"type": "node",
"deleted": false
},
{
"id": 1006,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-12-01T06:10:27Z",
"description": "dots on a map: lasso",
"user": "enjalot",
"gistId": "b95748220bd4752fb33a",
"updatedAt": "2015-12-02T00:45:26Z"
},
{
"createdAt": "2015-12-01T04:40:58Z",
"description": "dots on a map: setup",
"user": "enjalot",
"gistId": "18cb7a77b2d9de597b86",
"updatedAt": "2016-04-29T10:08:29Z"
}
],
"meta": [
{
"id": 1301,
"type": "node",
"deleted": false
},
{
"id": 1006,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-12-06T15:47:38Z",
"description": "Heatmap of Force-Directed Graph Node Positions",
"user": "rpgove",
"gistId": "3ad7359dc3d6f0d25734",
"updatedAt": "2015-12-06T20:34:09Z"
},
{
"createdAt": "2012-11-12T21:31:44Z",
"description": "Force-Directed Graph",
"user": "mbostock",
"gistId": "4062045",
"updatedAt": "2016-04-30T00:53:20Z"
}
],
"meta": [
{
"id": 1510,
"type": "node",
"deleted": false
},
{
"id": 1,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-03-01T16:18:25Z",
"description": "d3-heatmap",
"user": "fabid",
"gistId": "0c4cf357ab5ed3e90382",
"updatedAt": "2016-03-02T14:50:07Z"
},
{
"createdAt": "2015-12-05T21:03:01Z",
"description": "d3-hexbin demo",
"user": "xaranke",
"gistId": "b956ee7215b7b50bc78a",
"updatedAt": "2015-12-05T21:38:20Z"
}
],
"meta": [
{
"id": 1671,
"type": "node",
"deleted": false
},
{
"id": 1668,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-03-01T16:18:25Z",
"description": "d3-heatmap",
"user": "fabid",
"gistId": "0c4cf357ab5ed3e90382",
"updatedAt": "2016-03-02T14:50:07Z"
},
{
"createdAt": "2016-03-01T18:28:35Z",
"description": "d3-returntimemap",
"user": "fabid",
"gistId": "024452c42b94723b401d",
"updatedAt": "2016-03-02T15:09:41Z"
}
],
"meta": [
{
"id": 1671,
"type": "node",
"deleted": false
},
{
"id": 1672,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-03-01T16:18:25Z",
"description": "d3-heatmap",
"user": "fabid",
"gistId": "0c4cf357ab5ed3e90382",
"updatedAt": "2016-03-02T14:50:07Z"
},
{
"createdAt": "2015-12-05T21:03:01Z",
"description": "d3-hexbin demo",
"user": "xaranke",
"gistId": "b956ee7215b7b50bc78a",
"updatedAt": "2015-12-05T21:38:20Z"
}
],
"meta": [
{
"id": 1671,
"type": "node",
"deleted": false
},
{
"id": 1668,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-03-01T16:18:25Z",
"description": "d3-heatmap",
"user": "fabid",
"gistId": "0c4cf357ab5ed3e90382",
"updatedAt": "2016-03-02T14:50:07Z"
},
{
"createdAt": "2016-03-01T18:28:35Z",
"description": "d3-returntimemap",
"user": "fabid",
"gistId": "024452c42b94723b401d",
"updatedAt": "2016-03-02T15:09:41Z"
}
],
"meta": [
{
"id": 1671,
"type": "node",
"deleted": false
},
{
"id": 1672,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-03-01T18:28:35Z",
"description": "d3-returntimemap",
"user": "fabid",
"gistId": "024452c42b94723b401d",
"updatedAt": "2016-03-02T15:09:41Z"
},
{
"createdAt": "2016-03-01T16:18:25Z",
"description": "d3-heatmap",
"user": "fabid",
"gistId": "0c4cf357ab5ed3e90382",
"updatedAt": "2016-03-02T14:50:07Z"
}
],
"meta": [
{
"id": 1672,
"type": "node",
"deleted": false
},
{
"id": 1671,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-03-01T18:28:35Z",
"description": "d3-returntimemap",
"user": "fabid",
"gistId": "024452c42b94723b401d",
"updatedAt": "2016-03-02T15:09:41Z"
},
{
"createdAt": "2016-03-01T16:18:25Z",
"description": "d3-heatmap",
"user": "fabid",
"gistId": "0c4cf357ab5ed3e90382",
"updatedAt": "2016-03-02T14:50:07Z"
}
],
"meta": [
{
"id": 1672,
"type": "node",
"deleted": false
},
{
"id": 1671,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-11-20T00:54:18Z",
"description": "State Grid Minimap",
"user": "enjalot",
"gistId": "1919bd8c2f574caa17ba",
"updatedAt": "2015-11-24T00:22:39Z"
},
{
"createdAt": "2015-04-21T21:55:55Z",
"description": "State Grid",
"user": "mbostock",
"gistId": "29cc3cc4078091fd2115",
"updatedAt": "2016-02-09T01:51:31Z"
}
],
"meta": [
{
"id": 1864,
"type": "node",
"deleted": false
},
{
"id": 831,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-11-20T00:54:18Z",
"description": "State Grid Minimap",
"user": "enjalot",
"gistId": "1919bd8c2f574caa17ba",
"updatedAt": "2015-11-24T00:22:39Z"
},
{
"createdAt": "2012-03-26T17:16:19Z",
"description": "click-to-zoom via transform",
"user": "mbostock",
"gistId": "2206590",
"updatedAt": "2016-02-09T01:17:03Z"
}
],
"meta": [
{
"id": 1864,
"type": "node",
"deleted": false
},
{
"id": 136,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2015-11-20T00:54:18Z",
"description": "State Grid Minimap",
"user": "enjalot",
"gistId": "1919bd8c2f574caa17ba",
"updatedAt": "2015-11-24T00:22:39Z"
},
{
"createdAt": "2012-03-26T17:16:19Z",
"description": "click-to-zoom via transform",
"user": "mbostock",
"gistId": "2206590",
"updatedAt": "2016-02-09T01:17:03Z"
}
],
"meta": [
{
"id": 1864,
"type": "node",
"deleted": false
},
{
"id": 136,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-03-24T22:49:54Z",
"description": "topojson on a map: setup-gl",
"user": "enjalot",
"gistId": "676bfe2b6e67e61e0656",
"updatedAt": "2016-04-11T20:32:40Z"
},
{
"createdAt": "2015-12-03T18:17:59Z",
"description": "dots on a map: setup-gl",
"user": "enjalot",
"gistId": "dc1ce756527c072885dc",
"updatedAt": "2015-12-06T01:55:32Z"
}
],
"meta": [
{
"id": 1868,
"type": "node",
"deleted": false
},
{
"id": 1300,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-03-24T22:49:54Z",
"description": "topojson on a map: setup-gl",
"user": "enjalot",
"gistId": "676bfe2b6e67e61e0656",
"updatedAt": "2016-04-11T20:32:40Z"
},
{
"createdAt": "2015-12-01T04:40:58Z",
"description": "dots on a map: setup",
"user": "enjalot",
"gistId": "18cb7a77b2d9de597b86",
"updatedAt": "2016-04-29T10:08:29Z"
}
],
"meta": [
{
"id": 1868,
"type": "node",
"deleted": false
},
{
"id": 1006,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-05-03T20:39:59Z",
"description": "Linear SVG Gradient - A hexagonal SOM heatmap with color legend",
"user": "nbremer",
"gistId": "5cd07f2cb4ad202a9facfbd5d2bc842e",
"updatedAt": "2016-05-03T20:44:18Z"
},
{
"createdAt": "2016-04-03T10:50:59Z",
"description": "Linear SVG Gradient - Weather Radial",
"user": "nbremer",
"gistId": "a43dbd5690ccd5ac4c6cc392415140e7",
"updatedAt": "2016-05-03T20:43:26Z"
}
],
"meta": [
{
"id": 2011,
"type": "node",
"deleted": false
},
{
"id": 2009,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-05-03T20:39:59Z",
"description": "Linear SVG Gradient - A hexagonal SOM heatmap with color legend",
"user": "nbremer",
"gistId": "5cd07f2cb4ad202a9facfbd5d2bc842e",
"updatedAt": "2016-05-03T20:44:18Z"
},
{
"createdAt": "2016-04-03T11:23:11Z",
"description": "Linear SVG Gradient - Traffic accidents per Day & Hour combination",
"user": "nbremer",
"gistId": "62cf60e116ae821c06602793d265eaf6",
"updatedAt": "2016-05-03T20:41:49Z"
}
],
"meta": [
{
"id": 2011,
"type": "node",
"deleted": false
},
{
"id": 1910,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-05-03T20:39:59Z",
"description": "Linear SVG Gradient - A hexagonal SOM heatmap with color legend",
"user": "nbremer",
"gistId": "5cd07f2cb4ad202a9facfbd5d2bc842e",
"updatedAt": "2016-05-03T20:44:18Z"
},
{
"createdAt": "2016-04-03T10:50:59Z",
"description": "Linear SVG Gradient - Weather Radial",
"user": "nbremer",
"gistId": "a43dbd5690ccd5ac4c6cc392415140e7",
"updatedAt": "2016-05-03T20:43:26Z"
}
],
"meta": [
{
"id": 2011,
"type": "node",
"deleted": false
},
{
"id": 2009,
"type": "node",
"deleted": false
}
]
},
{
"row": [
{
"createdAt": "2016-05-03T20:39:59Z",
"description": "Linear SVG Gradient - A hexagonal SOM heatmap with color legend",
"user": "nbremer",
"gistId": "5cd07f2cb4ad202a9facfbd5d2bc842e",
"updatedAt": "2016-05-03T20:44:18Z"
},
{
"createdAt": "2016-04-03T11:23:11Z",
"description": "Linear SVG Gradient - Traffic accidents per Day & Hour combination",
"user": "nbremer",
"gistId": "62cf60e116ae821c06602793d265eaf6",
"updatedAt": "2016-05-03T20:41:49Z"
}
],
"meta": [
{
"id": 2011,
"type": "node",
"deleted": false
},
{
"id": 1910,
"type": "node",
"deleted": false
}
]
}
]
}
],
"errors": []
}
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
const searchRadius = 30;
const color = d3.scaleOrdinal().range(d3.schemeCategory20);
// Create the simulation with a small forceX and Y towards the center
var simulation = d3
.forceSimulation()
.force('charge', d3.forceManyBody())
.force('x', d3.forceX(0).strength(0.003))
.force('y', d3.forceY(0).strength(0.003));
//
// comment out for now, until we have a public neo4j instance running
// https://think-lab.github.io/d/216/#1
//
//
// make the request to neo4j for the data
//
// function fetchGraphSearchResults(queryString) {
// const url = 'http://localhost:7474/db/data/transaction/commit';
// const requestData = JSON.stringify({
// statements: [
// {
// statement: queryString
// }
// ]
// });
// const myHeaders = new Headers();
// myHeaders.append('Content-Type', 'application/json');
// myHeaders.append('Authorization', 'Basic bmVvNGo6YWRtaW4=');
// myHeaders.append('Accept', 'application/json; charset=UTF-8');
// const myInit = {
// method: 'POST',
// body: requestData,
// headers: myHeaders
// };
// const myRequest = new Request(url, myInit);
// fetch(myRequest)
// .then(response => response.json())
// .then(data => parseResponse(data))
// .catch(e => {
// console.log(e);
// });
// }
//
// run a defult query so the user has
// something nice to look at on load
//
// const mapQueryString =
// "MATCH(n)-[:LINKS_TO]-(m) WHERE n.description =~ '.*map.*'RETURN n, m";
// const enjalotQueryString =
// "MATCH(n)-[:LINKS_TO]-(m) WHERE n.user =~ '.*enjalot.*'RETURN n, m";
// fetchGraphSearchResults(enjalotQueryString);
//
// load static neo4j API response data from a file
//
d3.json('neo4j-api-response.json', (error, response) => {
if (error) {
console.error(error);
}
parseResponse(response);
});
//
// cache images
//
const imageCache = {};
//
// parse the response from neo4j
//
function parseResponse(responseData) {
const graph = {
nodes: [],
links: []
};
const nodeHash = {};
console.log('responseData from parseResponse', responseData);
const graphData = responseData.results[0].data;
graphData.forEach(inputLink => {
const source = inputLink.row[0].gistId;
const target = inputLink.row[1].gistId;
if (typeof source !== 'undefined' && typeof target !== 'undefined') {
// collect the nodes in a set
// which builds up a list of unique nodes
inputLink.row.forEach(inputNode => {
nodeHash[inputNode.gistId] = {
id: inputNode.gistId,
createdAt: inputNode.createdAt,
description: inputNode.description,
updatedAt: inputNode.updatedAt,
user: inputNode.user
};
});
// assume that the inputLink rows
// are in [source, target] format
// TODO: check the neo4j REST API docs
// to verify this
graph.links.push({
source,
target,
weight: 1 // for jsLouvain community detection
});
}
});
// add the unique nodes that we've collected
// onto our graph object
Object.keys(nodeHash).forEach(key => {
graph.nodes.push(nodeHash[key]);
});
// call the drawGraph function
// to plot the graph
drawGraph(graph);
}
//
// visualize the graph
//
function drawGraph(graph) {
console.log('graph from drawGraph', graph);
cacheImages(graph, imageCache);
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
//
// detect communities with jsLouvain
//
const nodeData = graph.nodes.map(function(d) {
return d.id;
});
const linkData = graph.links.map(function(d) {
return { source: d.source, target: d.target, weight: d.weight };
});
const community = jLouvain().nodes(nodeData).edges(linkData);
const result = community();
const nodeIndexHash = {};
graph.nodes.forEach(function(node, i) {
node.group = result[node.id];
nodeIndexHash[node.id] = i;
});
//
//
//
const users = d3
.nest()
.key(d => d.user)
.entries(graph.nodes)
.sort((a, b) => b.values.length - a.values.length);
color.domain(users.map(d => d.key));
//
// process links data to use simple node array index ids
// for source and target values
// to satisfy the assumption of the forceInABox layout
//
graph.links.forEach(link => {
// record the gistId
link.sourceGistId = link.source;
link.targetGistId = link.target;
// now use the node index
link.source = nodeIndexHash[link.source];
link.target = nodeIndexHash[link.target];
});
//
// Instantiate the forceInABox force
//
const groupingForce = forceInABox()
.strength(0.001) // Strength to foci
.template('force') // Either treemap or force
.groupBy('group') // Node attribute to group
.links(graph.links) // The graph links. Must be called after setting the grouping attribute
.size([width, height]); // Size of the chart
// Add your forceInABox to the simulation
simulation
.nodes(graph.nodes)
.force('group', groupingForce)
.force(
'link',
d3
.forceLink(graph.links)
.distance(50)
.strength(groupingForce.getLinkStrength) // default link force will try to join nodes in the same group stronger than if they are in different groups
)
.on('tick', ticked);
// simulation.force('link').links(graph.links);
d3
.select(canvas)
.on('mousemove', mousemoved)
.on('click', clicked)
.call(
d3
.drag()
.container(canvas)
.subject(dragsubject)
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended)
);
function ticked() {
context.clearRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
context.beginPath();
graph.links.forEach(drawLink);
context.strokeStyle = '#aaa';
context.stroke();
users.forEach(user => {
context.beginPath();
user.values.forEach(drawNode);
context.fillStyle = color(user.key);
context.fill();
});
context.restore();
}
function dragsubject() {
return simulation.find(
d3.event.x - width / 2,
d3.event.y - height / 2,
searchRadius
);
}
function mousemoved() {
//
// disable mouse move links for now
//
const a = this.parentNode;
const m = d3.mouse(this);
const d = simulation.find(
m[0] - width / 2,
m[1] - height / 2,
searchRadius
);
if (!d) return a.removeAttribute('href');
a.removeAttribute('title');
a.setAttribute(
'href',
`http://bl.ocks.org/${d.user ? `${d.user}/` : ''}${d.id}`
);
a.setAttribute(
'title',
`${d.id}${d.user ? ` by ${d.user}` : ''}${d.description
? `\n${d.description}`
: ''}`
);
}
function clicked() {
const m = d3.mouse(this);
const d = simulation.find(
m[0] - width / 2,
m[1] - height / 2,
searchRadius
);
const blockUrl = `http://bl.ocks.org/${d.user ? `${d.user}/` : ''}${d.id}`;
window.open(blockUrl);
}
}
function dragstarted() {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d3.event.subject.fx = d3.event.subject.x;
d3.event.subject.fy = d3.event.subject.y;
}
function dragged() {
d3.event.subject.fx = d3.event.x;
d3.event.subject.fy = d3.event.y;
}
function dragended() {
if (!d3.event.active) simulation.alphaTarget(0);
d3.event.subject.fx = null;
d3.event.subject.fy = null;
}
// a small function to ensure that
// points stay inside the canvas
function boundScalar(p) {
const halfEdge = 448;
const minP = Math.min(p, halfEdge);
return Math.max(-halfEdge, minP);
}
function drawLink(d) {
context.moveTo(boundScalar(d.source.x), boundScalar(d.source.y));
context.lineTo(boundScalar(d.target.x), boundScalar(d.target.y));
}
function drawNode(d) {
// old solid color nodes
// context.moveTo(d.x + 3, d.y);
// context.arc(d.x, d.y, 3, 0, 2 * Math.PI);
const image = imageCache[d.id];
const iconWidth = 92;
const iconHeight = 48;
const radius = 22;
// draw border to check intution
context.strokeStyle = 'darkgray';
context.strokeRect(-width / 2, -height / 2, width - 2, height - 2);
// const minX = Math.min(d.x, width - radius);
// const nX = Math.max(-width / 2 + radius, minX);
// const minY = Math.min(d.y, height - 2 * radius);
// const nY = Math.max(-height / 2 - radius, minY);
// const minX = Math.min(d.x, 448);
// const nX = Math.max(-448, minX);
// const minY = Math.min(d.y, 448);
// const nY = Math.max(-448, minY);
const nX = boundScalar(d.x);
const nY = boundScalar(d.y);
// if (d.x !== nX || d.y !== nY) {
// console.log('d.x', d.x);
// console.log('d.y', d.y);
// console.log('nX', nX);
// console.log('nY', nY);
// console.log('------------');
// }
// draw images with a circular clip mask
// so that rectangular thumbnail images become
// round node icons
if (typeof image !== 'undefined' && image.height > 0) {
context.save();
context.beginPath();
context.arc(nX, nY, radius, 0, Math.PI * 2, true);
context.closePath();
context.clip();
context.drawImage(
image,
0,
0,
230,
120,
nX - iconWidth / 2,
nY - iconHeight / 2,
iconWidth,
iconHeight
);
context.beginPath();
context.arc(0, 0, 2, 0, Math.PI * 2, true);
context.clip();
context.closePath();
context.restore();
} else {
// gray from the blockbuilder search results page
context.fillStyle = '#EEEEEE';
context.beginPath();
context.arc(nX, nY, radius, 0, Math.PI * 2, true);
context.closePath();
context.fill();
// teal from blockbuilder search results page
context.fillStyle = '#66B5B4';
context.font = '20px Georgia';
context.fillText('?', nX - 5, nY + 8);
}
}
function cacheImages(graph, imageCache) {
graph.nodes.forEach(d => {
const image = new Image();
image.src = `https://bl.ocks.org/${d.user
? `${d.user}/`
: ''}raw/${d.id}/thumbnail.png`;
// image.onload = function() {
// imageCache[d.id] = image;
// };
imageCache[d.id] = image;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment