summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bubble.html1
-rw-r--r--bubble.js74
-rw-r--r--preprocess.js74
3 files changed, 79 insertions, 70 deletions
diff --git a/bubble.html b/bubble.html
index c0ed167..c6305d4 100644
--- a/bubble.html
+++ b/bubble.html
@@ -134,6 +134,7 @@ html, body {
<script src="d3.js"></script>
<script src="collision.js"></script>
+<script src="preprocess.js"></script>
<script src="bubble.js"></script>
</body>
</html>
diff --git a/bubble.js b/bubble.js
index fd59b32..9724886 100644
--- a/bubble.js
+++ b/bubble.js
@@ -1,5 +1,5 @@
/* jshint devel:true, browser:true */
-/* global d3, collisionTick */
+/* global d3, collisionTick, preprocess */
'use strict';
/* settings */
@@ -34,74 +34,6 @@ function getEdgesNodes(nodesCsv, edgesCsv, completeCallback) {
edgesCsv.get(checker('edges'));
}
-function preprocess(data) {
- // map userID to nodes
- var users = {};
- data.nodes.forEach(function (user, i) {
- users[user.group] = user;
- });
- console.log('Initial nodes count:', data.nodes.length);
- console.log('Initial edges count:', data.edges.length);
-
- var ratelimit_count = 0, ratelimit_max = 10;
- function ratelimit() {
- return ratelimit_count <= ratelimit_max;
- }
- // filter away invalid edges
- data.edges = data.edges.filter(function (link, i) {
- var invalid = false;
- if (!(link.source in users)) {
- if (ratelimit()) console.warn('Dropping invalid source user',
- link.source, 'at line', (i + 1), link);
- invalid = true;
- }
- if (!(link.target in users)) {
- if (ratelimit()) console.warn('Dropping invalid target user',
- link.target, 'at line', (i + 1), link);
- invalid = true;
- }
- if (link.source === link.target) {
- if (ratelimit()) console.warn('Dropping self-referencing user',
- link.target, 'at line', (i + 1), link);
- invalid = true;
- }
- return !invalid;
- });
- if (ratelimit_count > ratelimit_max) {
- console.log('Supressed', ratelimit_count, 'messages');
- }
- console.log('Valid edges count:', data.edges.length);
-
- // find all related users by userID
- var hasRelations = {};
- data.edges.forEach(function (link) {
- hasRelations[link.target] = 1;
- hasRelations[link.source] = 1;
- });
-
- if (KILL_LONERS) {
- var hasRelated = {};
- data.nodes = data.nodes.filter(function (d) {
- return d.group in hasRelations;
- });
- console.log('Nodes count (after dropping loners):', data.nodes.length);
- }
-
- // prepare data for force layout: map user IDs to indices
- var userIds_indices = {};
- data.nodes.forEach(function (user, i) {
- users[user.group] = user;
- userIds_indices[user.group] = i;
- });
- console.log('UserID to index map:', userIds_indices);
-
- // change userID of relation edges to indices
- data.edges.map(function (link) {
- link.source = userIds_indices[link.source];
- link.target = userIds_indices[link.target];
- });
-}
-
function initForce(width, height) {
console.log('Initing force with dimensions', width, height);
var force = d3.layout.force()
@@ -205,7 +137,9 @@ function initSvg() {
function processData(data) {
var infoPane = d3.select('#infobox');
- preprocess(data);
+ preprocess(data, {
+ kill_loners: KILL_LONERS
+ });
infoPane.select('.node-count').text(data.nodes.length);
infoPane.select('.edge-count').text(data.edges.length);
force.nodes(data.nodes)
diff --git a/preprocess.js b/preprocess.js
new file mode 100644
index 0000000..03af077
--- /dev/null
+++ b/preprocess.js
@@ -0,0 +1,74 @@
+/* "Optimizes" nodes and edges by dropping uninteresting ones. (for example,
+ * nodes with no edges).
+ */
+/* jshint devel:true */
+
+'use strict';
+
+function preprocess(data, options) {
+ // map userID to nodes
+ var users = {};
+ data.nodes.forEach(function (user, i) {
+ users[user.group] = user;
+ });
+ console.log('Initial nodes count:', data.nodes.length);
+ console.log('Initial edges count:', data.edges.length);
+
+ var ratelimit_count = 0, ratelimit_max = 10;
+ function ratelimit() {
+ return ratelimit_count <= ratelimit_max;
+ }
+ // filter away invalid edges
+ data.edges = data.edges.filter(function (link, i) {
+ var invalid = false;
+ if (!(link.source in users)) {
+ if (ratelimit()) console.warn('Dropping invalid source user',
+ link.source, 'at line', (i + 1), link);
+ invalid = true;
+ }
+ if (!(link.target in users)) {
+ if (ratelimit()) console.warn('Dropping invalid target user',
+ link.target, 'at line', (i + 1), link);
+ invalid = true;
+ }
+ if (link.source === link.target) {
+ if (ratelimit()) console.warn('Dropping self-referencing user',
+ link.target, 'at line', (i + 1), link);
+ invalid = true;
+ }
+ return !invalid;
+ });
+ if (ratelimit_count > ratelimit_max) {
+ console.log('Supressed', ratelimit_count, 'messages');
+ }
+ console.log('Valid edges count:', data.edges.length);
+
+ // find all related users by userID
+ var hasRelations = {};
+ data.edges.forEach(function (link) {
+ hasRelations[link.target] = 1;
+ hasRelations[link.source] = 1;
+ });
+
+ if (options.kill_loners) {
+ var hasRelated = {};
+ data.nodes = data.nodes.filter(function (d) {
+ return d.group in hasRelations;
+ });
+ console.log('Nodes count (after dropping loners):', data.nodes.length);
+ }
+
+ // prepare data for force layout: map user IDs to indices
+ var userIds_indices = {};
+ data.nodes.forEach(function (user, i) {
+ users[user.group] = user;
+ userIds_indices[user.group] = i;
+ });
+ console.log('UserID to index map:', userIds_indices);
+
+ // change userID of relation edges to indices
+ data.edges.map(function (link) {
+ link.source = userIds_indices[link.source];
+ link.target = userIds_indices[link.target];
+ });
+}