Skip to content

Instantly share code, notes, and snippets.

@gordonwoodhull
Last active September 2, 2017 13:55
Show Gist options
  • Save gordonwoodhull/c3e03cab74e78d451c2dd276fca142fd to your computer and use it in GitHub Desktop.
Save gordonwoodhull/c3e03cab74e78d451c2dd276fca142fd to your computer and use it in GitHub Desktop.
dc.js megamix tall
license: mit
height: 1300

dc.js megamix

This block shows an imaginary virtual network running on imaginary server farms across North America. Brush the graph to see where the physical machines reside. Zoom the map with shift-drag to see the virtual nodes running in those farms and the health of those nodes.

Admittedly, the main purpose for this block is to put dc.js, dc.leaflet.js, and dc.graph.js all in one block.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>dc.js megamix</title>
<link rel="stylesheet" type="text/css" href="https://dc-js.github.io/dc.js/css/dc.css" />
<link rel="stylesheet" type="text/css" href="http://dc-js.github.io/dc.graph.js/css/dc.graph.css"/>
<link rel="stylesheet" type="text/css" href="http://dc-js.github.io/dc.leaflet.js/css/leaflet.css" />
<script src="https://dc-js.github.io/dc.js/js/d3.js"></script>
<script src="https://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script src="https://dc-js.github.io/dc.js/js/dc.js"></script>
<script src="http://dc-js.github.io/dc.graph.js/js/chart.registry.js"></script>
<script src="http://dc-js.github.io/dc.graph.js/js/dc.graph.js"></script>
<script src="http://dc-js.github.io/dc.graph.js/js/cola.js"></script>
<script src="http://dc-js.github.io/dc.leaflet.js/js/leaflet-src.js"></script>
<script src="http://dc-js.github.io/dc.leaflet.js/js/dc.leaflet.js"></script>
<style>
body { margin: 0 }
#scatter svg .axis { display: none; }
</style>
</head>
<body>
<div id="under-title" style="height: 215px"></div>
<div id="graph" style="float:left"></div>
<div id="pie"></div>
<div id="scatter"></div>
<div style="float: left">
<div id="bars"></div>
<div id="row" style="clear: both"></div>
</div>
<div id="map"></div>
<script>
let params = new URLSearchParams(document.location.search.substring(1));
var center = [39.8333333,-98.585522];
function normal(N) { // generate normal distribution of integers in [0,N)
var rand = d3.random.normal(N/2, N/6);
return function() {
var r = rand();
if(r < 0)
return 0;
else if(r > N-1)
return N-1;
else return Math.floor(r);
}
}
function remove_empty_bins(source_group, field) {
return {
all:function () {
return source_group.all().filter(function(d) {
//return Math.abs(d.value) > 0.00001; // if using floating-point numbers
return d.value[field] !== 0; // if integers only
});
}
};
}
var N = 5000, NW = 100, NE = 90, // number of data, number of (virtual) widgets, number of edges
rndVW = normal(NW);
var edges = d3.range(NE).map(function(i) {
return {key: i, value: {source: rndVW(), target: rndVW()}};
});
// data from http://www.geomidpoint.com/random/ - center 39.8333333,-98.585522, radius 1500mi
d3.csv('sites.csv', function(error, sites) {
var rndS = normal(sites.length), rndX = normal(5), rndY = normal(7), rndA = normal(100), rndB = normal(100);
sites = d3.shuffle(sites);
var data = [];
for(var i = 0; i < N; ++i) {
var s = rndS(),
site = sites[s];
data.push({
lat: +site.lat,
long: +site.long,
widget: rndVW(),
x: rndX(),
y: rndY(),
a: rndA(),
b: rndB(),
health: Math.random()
});
}
var cf = crossfilter(data);
var locDim = cf.dimension(function(d) { return d.lat + ',' + d.long; }),
locGroup = locDim.group();
var tiles=function(map) {
L.tileLayer('https://api.mapbox.com/styles/v1/mapbox/light-v9/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZm91cnRoYXJrIiwiYSI6ImNqNXNoMGNpODE3MDczMm11bGppejUydnYifQ.CbZ-bY4pwfUvkTncEoJWPA', {
attribution: '<a href=\"https://www.mapbox.com/about/maps/\" target=\"_blank\">&copy; Mapbox</a> <a href=\"https://openstreetmap.org/about/\" target=\"_blank\">&copy; OpenStreetMap</a>'
}).addTo(map);
};
var bubbles = dc_leaflet.bubbleChart('#map')
.width(600).height(500)
.center(center)
.zoom(4)
.tiles(tiles)
.dimension(locDim)
.group(locGroup)
.r(d3.scale.sqrt().domain([0,100]).range([5,15]))
.unselectedColor('#68e')
;
var widgetDim = cf.dimension(function(d) { return d.widget; }),
widgetGroup = widgetDim.group().reduce(
function(p, v) { // add
p.sumhealth += v.health;
++p.n;
return p;
},
function(p, v) { // remove
p.sumhealth -= v.health;
--p.n;
return p;
},
function() { // init
return {sumhealth: 0, n: 0};
}
),
nonemptyWidgets = remove_empty_bins(widgetGroup, 'n')
var edgeDim = {}, // static/unused
edgeGroup = {
all: function() {
return edges;
}
};
var healthColors = d3.scale.linear()
.domain([0.25, 0.5, 0.75]).clamp(true)
.range(["red", "white", "green"])
var engine = dc_graph.cola_layout()
.baseLength(15)
var diagram = dc_graph.diagram('#graph')
.width(700).height(600)
.nodeDimension(widgetDim).nodeGroup(nonemptyWidgets)
.edgeDimension(edgeDim).edgeGroup(edgeGroup)
.layoutEngine(engine)
.initLayoutOnRedraw(true)
.transitionDuration(2000)
.timeLimit(2000)
.nodeRadius(n => 2*Math.sqrt(n.value.n))
.nodeFill(n => n.value.sumhealth / n.value.n)
.nodeFillScale(healthColors)
.edgeKey(e => String(e.key))
.edgeSource(e => e.value.source)
.edgeTarget(e => e.value.target)
.nodeStrokeWidth(1)
.nodeOpacity(0.25)
.altKeyZoom(true)
.induceNodes(true);
var select_nodes = dc_graph.select_nodes({
nodeOpacity: 1
})
.noneIsAll(true)
.autoCropSelection(false);
diagram.child('select-nodes', select_nodes);
diagram.child('filter-selection', dc_graph.filter_selection());
var healthDim = cf.dimension(function(d) { return d.health; }),
healthGroup = healthDim.group(function(d) { return Math.floor(d*10)/10; })
var bars = dc.barChart('#bars')
.width(425).height(250)
.margins({top: 7, left: 30, right: 10, bottom: 20})
.dimension(healthDim)
.group(healthGroup)
.transitionDuration(2000)
.x(d3.scale.linear())
.xUnits(dc.units.fp.precision(0.1))
.colors(healthColors)
.colorAccessor(function(d) {
return d.key;
})
.elasticX(true).elasticY(true);
var xDim = cf.dimension(function(d) { return d.x; }),
xGroup = xDim.group();
var pie = dc.pieChart('#pie')
.width(300).height(300)
.dimension(xDim)
.group(xGroup)
.transitionDuration(2000)
.colors(d3.scale.ordinal().range(d3.shuffle(['#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00'])));
var yDim = cf.dimension(function(d) { return d.y; }),
yGroup = xDim.group();
var row = dc.rowChart('#row')
.width(425).height(250)
.margins({top: 0, left: 30, right: 10, bottom: 20})
.dimension(yDim)
.group(yGroup)
.transitionDuration(2000)
.colors(d3.scale.ordinal().range(d3.shuffle(['#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00','#ffff33','#a65628'])));
var abDim = cf.dimension(function(d) { return [d.a, d.b]; }),
abGroup = abDim.group();
var scatter = dc.scatterPlot('#scatter')
.width(300).height(290)
.margins({top: 0, left: 0, right: 0, bottom: 0})
.dimension(abDim)
.group(abGroup)
.transitionDuration(2000)
.x(d3.scale.linear())
.y(d3.scale.linear())
.elasticX(true)
.elasticY(true)
.ordinalColors(['#4daf4a'])
.symbolSize(2)
dc.renderAll();
var map = bubbles.map();
map.on('boxzoomend', function(e) {
console.log(e.boxZoomBounds);
});
if(!params.get('nozoom')) {
var corner1 = L.latLng(49.993615462541136, -69.87304687500001),
corner2 = L.latLng(37.35269280367274, -94.21875),
bounds = L.latLngBounds(corner1, corner2);
window.setTimeout(function() {
map.fitBounds(bounds)
.fire('boxzoomend', {boxZoomBounds: bounds});
}, 2500);
}
});
</script>
</body>
lattxt lat longtxt long unk1 unk2
34°40′27″N 34.67419491 108°14′35″W -108.24304369 639.263 239.135°
57°18′08″N 57.30231036 108°51′41″W -108.86151813 1292.2791 342.505°
51°40′20″N 51.67212866 84°51′22″W -84.85607489 1048.9754 34.209°
46°02′02″N 46.03377466 120°57′06″W -120.95158347 1205.2012 298.169°
38°08′06″N 38.13488762 125°35′32″W -125.59223701 1450.1625 274.052°
54°23′54″N 54.39829662 117°12′28″W -117.20769702 1326.0388 325.552°
41°37′12″N 41.61993123 85°20′42″W -85.34495914 703.6874 75.618°
36°51′46″N 36.8627758 120°33′30″W -120.55834028 1205.4247 267.209°
37°25′23″N 37.42312451 113°45′43″W -113.7620039 835.1136 263.33°
46°07′40″N 46.12776057 108°38′42″W -108.64510455 668.3914 313.892°
26°41′14″N 26.68726284 89°29′25″W -89.4903663 1048.2862 147.329°
34°42′53″N 34.71467456 87°46′35″W -87.77627249 691.0566 117.391°
36°13′38″N 36.22710472 125°16′31″W -125.27530453 1468.6105 268.76°
29°36′59″N 29.61640222 88°10′54″W -88.18158843 919.4387 136.977°
56°30′29″N 56.5079209 111°03′31″W -111.05860164 1283.3222 338.02°
56°32′48″N 56.54660877 97°54′24″W -97.90673664 1155.564 1.301°
30°21′17″N 30.35471607 108°53′59″W -108.89968668 875.8829 224.77°
42°10′12″N 42.1698764 82°51′34″W -82.85956509 834.7571 73.753°
45°09′36″N 45.15988602 76°12′55″W -76.2152493 1193.4234 64.706°
23°05′55″N 23.09872709 94°55′02″W -94.91711722 1176.3702 168.401°
49°33′37″N 49.56038954 123°14′33″W -123.24250226 1376.3449 307.393°
19°13′05″N 19.21800263 103°40′01″W -103.66687707 1456.5641 193.45°
48°15′28″N 48.25786092 116°53′20″W -116.88902288 1075.5466 308.795°
43°37′27″N 43.62402796 109°34′05″W -109.56795663 623.4769 298.412°
42°23′02″N 42.38385762 120°52′43″W -120.87856799 1170.7845 285.909°
42°07′56″N 42.13222988 91°08′31″W -91.14200168 419.4322 65.336°
43°16′36″N 43.27665598 100°16′12″W -100.26987565 253.4166 340.45°
22°41′34″N 22.6929083 87°25′28″W -87.4245775 1353.1512 147.796°
41°25′03″N 41.41743759 112°37′32″W -112.62563587 743.7583 282.998°
24°45′31″N 24.7587317 98°42′06″W -98.7015658 1041.9182 180.405°
31°05′14″N 31.08732493 87°32′30″W -87.54158251 865.8279 130.858°
41°54′44″N 41.91224585 90°16′21″W -90.27250552 457.3787 69.008°
31°58′28″N 31.97447094 77°20′02″W -77.3337651 1303.5421 107.979°
27°32′39″N 27.54411512 94°50′04″W -94.83453882 876.105 164.672°
25°53′07″N 25.88519926 117°49′54″W -117.83168614 1469.8659 234.847°
50°47′12″N 50.78657242 82°36′53″W -82.61475764 1079.9535 40.228°
37°50′02″N 37.83395523 78°51′55″W -78.86526979 1068.4652 91.122°
45°27′21″N 45.45579388 70°55′43″W -70.92860021 1450.7391 65.365°
55°00′10″N 55.00288991 119°26′52″W -119.44779776 1421.2941 324.445°
42°52′48″N 42.87996946 94°49′46″W -94.82952981 286.8349 41.553°
29°03′19″N 29.05517363 94°42′16″W -94.70443111 776.8672 162.329°
54°25′21″N 54.42261143 113°15′53″W -113.26483266 1216.6683 330.823°
47°41′24″N 47.69013763 87°25′41″W -87.42798879 776.3912 41.964°
52°46′01″N 52.7669039 90°09′06″W -90.15164781 978.8571 21.266°
44°58′20″N 44.97233824 101°39′09″W -101.6524348 388.0698 337.241°
46°04′45″N 46.07929067 73°32′19″W -73.53862977 1331.8821 62.853°
38°33′42″N 38.56170852 74°03′17″W -74.05466017 1312.7609 85.944°
49°59′19″N 49.9886045 77°25′09″W -77.41907289 1244.4936 48.679°
30°24′22″N 30.4060662 99°42′10″W -99.70290878 654.613 185.866°
29°52′06″N 29.86836316 121°36′05″W -121.60127468 1469.8335 249.195°
49°26′46″N 49.44617433 74°29′23″W -74.48980192 1349.9744 52.554°
28°39′36″N 28.65992888 77°28′06″W -77.46845019 1426.763 116.269°
47°27′18″N 47.45495592 89°40′02″W -89.66715236 689.3259 37.247°
34°31′03″N 34.51753153 107°39′56″W -107.66558876 619.9635 236.511°
32°07′53″N 32.13147976 74°33′14″W -74.55375703 1439.9984 104.159°
37°16′28″N 37.27443842 85°54′44″W -85.9122249 706.7719 100.459°
44°24′09″N 44.40246553 96°56′39″W -96.94422263 326.7983 14.374°
53°42′19″N 53.70515158 90°55′11″W -90.91976423 1023.7105 17.992°
46°23′49″N 46.3969959 120°31′15″W -120.52079668 1191.0995 299.589°
19°27′26″N 19.45730285 94°11′24″W -94.18993383 1432.3363 168.216°
33°02′14″N 33.03715901 106°44′58″W -106.74938393 652.6551 226.519°
46°00′01″N 46.00020338 78°24′49″W -78.4137048 1102.5155 60.647°
48°42′35″N 48.70985959 75°06′46″W -75.11279441 1306.2152 54.24°
52°59′57″N 52.99906071 109°12′34″W -109.20935285 1038.7632 334.667°
41°20′53″N 41.34793243 111°44′38″W -111.74375925 697.8004 282.874°
43°35′49″N 43.59695054 113°38′14″W -113.63718583 817.5735 293.444°
47°15′49″N 47.26356478 93°04′46″W -93.07944799 582.5696 26.374°
37°44′09″N 37.73596385 98°13′41″W -98.22794901 146.2359 172.318°
37°14′11″N 37.23644824 108°33′44″W -108.562271 568.0888 254.753°
30°25′28″N 30.42440473 91°39′52″W -91.66455679 758.3123 146.91°
45°27′00″N 45.45000504 107°03′41″W -107.06132055 579.4101 314.828°
21°06′22″N 21.10619757 88°42′54″W -88.71505204 1419.3423 152.878°
28°11′08″N 28.18551127 118°01′34″W -118.02600606 1369.2299 239.951°
32°32′57″N 32.54903794 117°19′58″W -117.33276272 1157.4739 250.086°
42°43′50″N 42.73048276 88°12′33″W -88.20906964 574.4575 66.242°
45°54′37″N 45.91021815 120°02′41″W -120.04464251 1160.8355 298.248°
26°01′38″N 26.02732569 113°21′43″W -113.36193336 1279.0811 226.223°
33°52′56″N 33.88213562 102°42′34″W -102.70939649 470.1732 210.266°
57°41′55″N 57.69869753 94°53′26″W -94.89049672 1245.747 6.39°
26°13′21″N 26.22263251 84°50′52″W -84.84768585 1229.2215 135.775°
30°07′26″N 30.12396236 90°36′49″W -90.61358301 807.9863 143.699°
42°12′25″N 42.20692493 111°13′40″W -111.22763982 678.6389 288.078°
35°06′16″N 35.10454019 110°28′10″W -110.46956616 728.4099 247.088°
54°46′27″N 54.77415233 115°58′01″W -115.96707919 1307.7408 327.901°
35°40′38″N 35.67711896 120°24′22″W -120.40608758 1223.1465 263.351°
24°59′31″N 24.99197692 89°34′37″W -89.57682458 1151.054 150.316°
38°57′23″N 38.95639036 73°31′38″W -73.52732003 1335.4085 84.523°
40°01′20″N 40.02209375 91°06′54″W -91.11491418 396.0555 85.716°
47°17′10″N 47.28619206 123°44′06″W -123.73507556 1353.3304 300.661°
26°30′07″N 26.50208162 114°21′44″W -114.36226081 1293.0323 229.341°
57°03′30″N 57.05840128 97°29′57″W -97.49926601 1191.5312 1.993°
42°02′37″N 42.04361451 114°01′36″W -114.02677239 819.3586 285.743°
50°44′42″N 50.74499319 79°58′12″W -79.96992124 1172.3525 43.818°
34°31′13″N 34.52015129 115°59′32″W -115.99217472 1024.3764 254.484°
31°59′57″N 31.99930155 115°09′59″W -115.16632277 1071.9308 244.832°
57°18′54″N 57.31490092 100°03′24″W -100.05672283 1210.0571 357.358°
56°23′38″N 56.39378769 86°57′50″W -86.96393744 1260.0116 20.88°
42°55′45″N 42.92910352 113°19′36″W -113.3265951 792.6576 290.442°
21°06′56″N 21.11556638 103°34′15″W -103.57095445 1326.7341 194.274°
58°41′02″N 58.68396317 98°54′24″W -98.90674675 1302.9573 359.483°
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment