| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <title>Magical waves in numbers</title> |
| <script type="text/javascript" src="d3/d3.v3.js"></script> |
| <style type="text/css"> |
| |
| .axis path, |
| .axis line { |
| fill: none; |
| stroke: black; |
| shape-rendering: crispEdges; |
| } |
| |
| .axis text { |
| font-family: sans-serif; |
| font-size: 11px; |
| } |
| |
| </style> |
| </head> |
| |
| <body> |
| |
| <script type="text/javascript"> |
| |
| var debug = true; |
| function log(o) { |
| if (debug) { |
| console.log(o); |
| } |
| } |
| |
| // TODO(katepek): Find better values; currently for 13" screen. |
| var width = 1350; |
| var height = 650; |
| var padding = 20; |
| |
| var dataset; |
| var seqScale; |
| var rateScale; |
| var pcapSecsScale; |
| |
| d3.csv('imaginary.data', function(error, data) { |
| if (error) { |
| console.log(error); |
| } else { |
| console.log(data); |
| dataset = data; |
| init(); |
| visualize(); |
| } |
| }); |
| |
| function init() { |
| pcapSecsScale = d3.scale |
| .linear() |
| .domain([ |
| d3.min(dataset, |
| function(d) { return parseFloat(d['pcap_secs']); }), |
| d3.max(dataset, |
| function(d) { return parseFloat(d['pcap_secs']); }) |
| ]) |
| .range([2 * padding, width - 2 * padding]); |
| |
| seqScale = d3.scale |
| .linear() |
| .domain([ |
| d3.min(dataset, |
| function(d) { return Number(d['seq']); }), |
| d3.max(dataset, |
| function(d) { return Number(d['seq']); }) |
| ]) |
| .range([height - padding, padding]); |
| |
| rateScale = d3.scale |
| .linear() |
| .domain([ |
| d3.min(dataset, |
| function(d) { return Number(d['rate']); }), |
| d3.max(dataset, |
| function(d) { return Number(d['rate']); }) |
| ]) |
| .range([height - padding, padding]); |
| } |
| |
| function seq(d) { |
| var seq = seqScale(Number(d['seq'])); |
| log('seq = ' + seq); |
| return seq; |
| } |
| |
| function rate(d) { |
| var rate = rateScale(Number(d['rate'])); |
| log('rate = ' + rate); |
| return rate; |
| } |
| |
| function pcapSecs(d) { |
| var pcapSecs = pcapSecsScale(parseFloat(d['pcap_secs'])); |
| log('pcapSecs = ' + pcapSecs); |
| return pcapSecs; |
| } |
| |
| function visualize() { |
| var svg = d3 |
| .select('body') |
| .append('svg') |
| .attr('width', width) |
| .attr('height', height); |
| // .style("border", "1px solid black") |
| ; |
| |
| // Plot pcapSecs vs. rate |
| svg |
| .selectAll('pcap_vs_rate') |
| .data(dataset) |
| .enter() |
| .append('circle') |
| .attr('cx', pcapSecs) |
| .attr('cy', rate) |
| .attr('r', 1) |
| .append('title') |
| .text( |
| function(d) { |
| return d['typestr'] |
| + ': pcapSecs=' |
| + d['pcap_secs'] |
| + '; rate=' |
| + d['rate']; |
| }); |
| ; |
| |
| // Plot pcapSecs vs. seq |
| svg |
| .selectAll('pcap_vs_seq') |
| .data(dataset) |
| .enter() |
| .append('circle') |
| .attr('cx', pcapSecs) |
| .attr('cy', seq) |
| .attr('r', 1) |
| .attr('fill', 'red') |
| .append('title') |
| .text( |
| function(d) { |
| return d['typestr'] |
| + ': pcapSecs=' |
| + d['pcap_secs'] |
| + '; seq=' |
| + d['seq']; |
| }); |
| ; |
| |
| var pcapSecsAxis = d3.svg.axis() |
| .scale(pcapSecsScale) |
| .orient('bottom') |
| .ticks(5); |
| var rateAxis = d3.svg.axis() |
| .scale(rateScale) |
| .orient('left') |
| .ticks(5); |
| var seqAxis = d3.svg.axis() |
| .scale(seqScale) |
| .orient('right') |
| .ticks(5); |
| |
| svg.append('g') |
| .attr('class', 'axis') |
| .attr('transform', 'translate(0,' + (height - padding) + ')') |
| .call(pcapSecsAxis); |
| svg.append('g') |
| .attr('class', 'axis') |
| .attr('transform', 'translate(' + 2 * padding + ',0)') |
| .call(rateAxis); |
| svg.append('g') |
| .attr('class', 'axis') |
| .attr('fill', 'red') |
| .attr('transform', 'translate(' + (width - 2 * padding) + ',0)') |
| .call(seqAxis); |
| } |
| |
| </script> |
| |
| </body> |
| </html> |