// Generated by CoffeeScript 2.0.0 (function() { /* LAYOUT SETTING */ var draw, height, margin, sankey, svg, vis, width, _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; width = document.body.getBoundingClientRect().width; height = document.body.getBoundingClientRect().height; margin = 40; svg = d3.select('svg'); vis = svg.append('g').attrs({ width: width, height: 25000, transform: `translate(10, ${margin}) rotate(-90) translate(0, ${margin}) scale(-1,1)` }); // Sankey layout setting sankey = d3.sankey().nodeId(function(d) { return d.id; }).nodePadding(5).nodeAlign(function(d) { return d3.sankeyCenter(d); }).size([height - margin * 2, width - margin * 2]); /* DATA TRANSFORMATION */ // Data loading draw = async function(path) { var data, en_links, en_nodes, graph, label_coords, labels, links, nodes, s, x_factor; data = (await fetch(path).then(function(response) { return response.json(); })); // Filter EMPTY data data = data.filter(function(d) { return d.partitions != null; }); // Compute nodes nodes = data.map(function(d, i) { return d.partitions.map(function(p, j) { return _extends({}, p, { id: `${i}_${j}`, row: i, cell: j }); }); }).reduce(function(acc, cur) { return acc.concat(cur); }); // Compute links links = data.slice(0, -1).map(function(d, i) { return d.partitions.map(function(p, j) { return p.flows.map(function(f, k) { return { source: `${i}_${j}`, target: `${i + 1}_${k}`, self: j === k, value: f }; }).filter(function(f) { return f.value > 0; }); }).reduce(function(acc, cur) { return acc.concat(cur); }); }).reduce(function(acc, cur) { return acc.concat(cur); }); // Create graph structure graph = { nodes: nodes, links: links }; // Compute sankey layout s = sankey(graph); // Fix node positions x_factor = 0; s.nodes.forEach(function(n, i) { if (n.cell === 0) { return; } else if (n.cell === 1) { x_factor = s.nodes[i].y0 - 9; } s.nodes[i].y0 -= x_factor; return s.nodes[i].y1 -= x_factor; }); // Update links position sankey.update(s); /* VISUALIZATION */ // links links = vis.selectAll('.link').data(graph.links.filter(function(d) { return !d.self; })); en_links = links.enter().append('path').attrs({ class: 'link', d: d3.sankeyLinkHorizontal() }).styles({ 'stroke-width': function(d) { return Math.max(1, d.width); } }).append('title').text(function(d) { return `group${+d.source.id.slice(-1) + 1} -> group${+d.target.id.slice(-1) + 1}: ${d.value}`; }); // nodes nodes = vis.selectAll('.node').data(graph.nodes); en_nodes = nodes.enter().append('rect').attrs({ class: 'node', x: function(d) { return d.x0; }, y: function(d) { return d.y0; }, height: function(d) { return d.y1 - d.y0; }, width: function(d) { return d.x1 - d.x0; } }).append('title').text(function(d) { return `group${+d.id.slice(-1) + 1}\n${d.as_n} ASes`; }); // Date labels label_coords = graph.nodes.filter(function(d) { return d.cell === 0; }); labels = svg.selectAll('.label').data(data.map(function(d) { var date; date = new Date(d.date.replace(/_/g, ' ')); return date.toLocaleDateString('en-en', { month: "short" }) + date.getDate(); })); return labels.enter().append('text').attrs({ class: 'label', x: 4, y: function(d, i) { if (i < label_coords.length) { return label_coords[i].x0 + 52; } }, dy: '0.35em' }).text(function(d) { return d.toUpperCase(); }); }; draw('./data.json'); d3.select(self.frameElement).transition().duration(500).style('height', "25000px"); }).call(this);