Last active
September 14, 2017 19:27
-
-
Save birm/c429d6d120e15e0cc3bb0ccd2661f97d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"data":[[457,"0",1,"Millet, Mr. Francis Davis","male",65,0,0,"13509",26.55,"E38","S",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[7,"0",1,"McCarthy, Mr. Timothy J","male",54,0,0,"17463",51.8625,"E46","S",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[22,"1",2,"Beesley, Mr. Lawrence","male",34,0,0,"248698",13,"D56","S",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[873,"0",1,"Carlsson, Mr. Frans Olof","male",33,0,0,"695",5,"B51 B53 B55","S",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[24,"1",1,"Sloper, Mr. William Thompson","male",28,0,0,"113788",35.5,"A6","S",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[868,"0",1,"Roebling, Mr. Washington Augustus II","male",31,0,0,"PC 17590",50.4958,"A24","S",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[28,"0",1,"Fortune, Mr. Charles Alexander","male",19,3,2,"19950",263,"C23 C25 C27","S",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[858,"1",1,"Daly, Mr. Peter Denis ","male",51,0,0,"113055",26.55,"E17","S",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[55,"0",1,"Ostby, Mr. Engelhart Cornelius","male",65,0,1,"113509",61.9792,"B30","C",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],[63,"0",1,"Harris, Mr. Henry Birkhardt","male",45,1,0,"36973",83.475,"C83","S",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]],"active":0,"state":1,"draw":"1","recordsTotal":183,"recordsFiltered":183} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
font-family: sans-serif; | |
font-size: 12px; | |
background: #f9f9f9; | |
color: #777; | |
margin-top: 40px; | |
} | |
body.dark { | |
background: #090909; | |
color: #ccc; | |
} | |
#wrap { | |
width: 960px; | |
margin: 0 auto; | |
position: relative; | |
} | |
svg { | |
font: 10px sans-serif; | |
} | |
canvas, svg { | |
position: absolute; | |
top: 0; | |
left: 0; | |
} | |
#chart { | |
position: relative; | |
} | |
.brush .extent { | |
fill: rgba(0,0,0,0.12); | |
stroke: rgba(255,255,255,0.6); | |
shape-rendering: crisp-edges; | |
} | |
.axis line, .axis path { | |
fill: none; | |
stroke: #222; | |
shape-rendering: crispEdges; | |
} | |
.axis text { | |
fill: #222; | |
text-shadow: 1px 1px 1px #fff, -1px -1px 1px #fff; | |
} | |
.axis text.label { | |
fill: #444; | |
font-size: 14px; | |
} | |
.axis g, | |
.axis path { | |
display: none; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> | |
<title>Parallel Coords DataScope Test</title> | |
<link rel="stylesheet" type="text/css" href="pc.css"> | |
</head> | |
<body> | |
<div id="wrap"> | |
<div id="chart"> | |
<canvas id="foreground"></canvas> | |
<svg></svg> | |
</div> | |
<p> | |
Rendered: <strong id="rendered-count"></strong><br/> | |
Selected: <strong id="selected-count"></strong><br/> | |
</p> | |
</div> | |
<script src="http://d3js.org/d3.v2.js"></script> | |
<script src="pc.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var all_data = []; | |
pagnated_json = function(url_generator, callback, finalizer) { | |
// url_generator can be either a generator (recommended) or an iterator | |
try { | |
var xhr = new XMLHttpRequest(); | |
xhr.open("GET", url_generator.next().value, true); | |
xhr.onload = function(e) { | |
if (xhr.readyState === 4 && xhr.responseText) { | |
// if it's not blank, process records and recurse | |
var records = JSON.parse(xhr.responseText); | |
if (records['data'].length > 0) { | |
callback(records); | |
// recurse and add new request | |
//xhr.open("GET", url_generator.next().value, true); | |
pagnated_json(url_generator, callback); | |
} | |
} | |
} | |
xhr.send(); | |
} catch (e) { | |
console.log(e); | |
} | |
// if the url geneator is done, or response is empty, terminate | |
} | |
window.requestAnimFrame = window.requestAnimationFrame || | |
window.webkitRequestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
window.oRequestAnimationFrame || | |
window.msRequestAnimationFrame || | |
function(callback) { | |
window.setTimeout(callback, 1000 / 60); | |
}; | |
var m = [60, 10, 10, 0], | |
w = 960 - m[1] - m[3], | |
h = 290 - m[0] - m[2]; | |
var xscale = d3.scale.ordinal().rangePoints([0, w], 1), | |
yscale = {}; | |
var line = d3.svg.line(), | |
axis = d3.svg.axis().orient("left"), | |
foreground, | |
dimensions; | |
d3.select("#chart") | |
.style("width", (w + m[1] + m[3]) + "px") | |
.style("height", (h + m[0] + m[2]) + "px") | |
d3.selectAll("canvas") | |
.attr("width", w) | |
.attr("height", h) | |
.style("padding", m.join("px ") + "px"); | |
foreground = document.getElementById('foreground').getContext('2d'); | |
foreground.strokeStyle = "rgba(0,100,160,0.1)"; | |
foreground.lineWidth = 1.3; // avoid weird subpixel effects | |
function* ds_url_generator() { | |
var page = 0; | |
while (true) { | |
yield "http://localhost:3001/dataTable/next?dataSourceName=main&draw=1&start=" + 10 * page + "&length=10&search"; | |
page += 1; | |
} | |
} | |
var ds_urls = ds_url_generator(); | |
var draw_record = function(data) { | |
var svg = d3.select("svg") | |
.attr("width", w + m[1] + m[3]) | |
.attr("height", h + m[0] + m[2]) | |
.append("svg:g") | |
.attr("transform", "translate(" + m[3] + "," + m[0] + ")"); | |
var brush_count = 0; | |
// convert datascopr data to a more standard format | |
names = ["a", "b", "c"]; // TODO make work with actual variable names | |
data = data['data']; // get the list of lists | |
function ll_to_obj(data, names) { | |
res = []; | |
for (i in data) { | |
item = {}; | |
for (j in names) { | |
item[names[j]] = data[i][j]; | |
} | |
res = res.concat(item); | |
} | |
return res | |
} | |
data = ll_to_obj(data, names); | |
data = all_data.concat(data); | |
all_data = data; | |
// Convert quantitative scales to floats | |
data = data.map(function(d) { | |
for (var k in d) { | |
if (k != "name" && k != "group" && k != "id") | |
d[k] = parseFloat(d[k]) || 0; | |
}; | |
return d; | |
}); | |
// Extract the list of dimensions and create a scale for each. | |
xscale.domain(dimensions = d3.keys(data[0]).filter(function(d) { | |
return d != "name" && d != "group" && d != "id" && (yscale[d] = d3.scale.linear() | |
.domain(d3.extent(data, function(p) { | |
return +p[d]; | |
})) | |
.range([h, 0])); | |
})); | |
// Render full foreground | |
paths(data, foreground, brush_count); | |
// Add a group element for each dimension. | |
var g = svg.selectAll(".dimension") | |
.data(dimensions) | |
.enter().append("svg:g") | |
.attr("class", "dimension") | |
.attr("transform", function(d) { | |
return "translate(" + xscale(d) + ")"; | |
}); | |
// Add an axis and title. | |
g.append("svg:g") | |
.attr("class", "axis") | |
.each(function(d) { | |
d3.select(this).call(axis.scale(yscale[d])); | |
}) | |
.append("svg:text") | |
.attr("text-anchor", "left") | |
.attr("y", -8) | |
.attr("x", -4) | |
.attr("transform", "rotate(-19)") | |
.attr("class", "label") | |
.text(String); | |
// Add and store a brush for each axis. | |
g.append("svg:g") | |
.attr("class", "brush") | |
.each(function(d) { | |
d3.select(this).call(yscale[d].brush = d3.svg.brush().y(yscale[d]).on("brush", brush)); | |
}) | |
.selectAll("rect") | |
.attr("x", -16) | |
.attr("width", 32) | |
.attr("rx", 3) | |
.attr("ry", 3); | |
// Handles a brush event, toggling the display of foreground lines. | |
function brush() { | |
brush_count++; | |
console.log(dimensions); | |
var actives = dimensions.filter(function(p) { | |
console.log(yscale[p]); | |
return !yscale[p].brush.empty(); | |
}), | |
extents = actives.map(function(p) { | |
return yscale[p].brush.extent(); | |
}); | |
// Get lines within extents | |
var selected = []; | |
data.map(function(d) { | |
return actives.every(function(p, i) { | |
return extents[i][0] <= d[p] && d[p] <= extents[i][1]; | |
}) ? selected.push(d) : null; | |
}); | |
// Render selected lines | |
paths(selected, foreground, brush_count); | |
} | |
function paths(data, ctx, count) { | |
var n = data.length, | |
i = 0, | |
opacity = d3.min([2 / Math.pow(n, 0.37), 1]); | |
d3.select("#selected-count").text(n); | |
data = shuffle(data); | |
ctx.clearRect(0, 0, w + 1, h + 1); | |
function render() { | |
var max = d3.min([i + 12, n]); | |
data.slice(i, max).forEach(function(d) { | |
path(d, foreground, color(d.group, opacity)); | |
}); | |
i = max; | |
d3.select("#rendered-count").text(i); | |
}; | |
// render all lines until finished or a new brush event | |
(function animloop() { | |
if (i >= n || count < brush_count) return; | |
requestAnimFrame(animloop); | |
render(); | |
})(); | |
}; | |
} | |
pagnated_json(ds_urls, draw_record); | |
function path(d, ctx, color) { | |
if (color) ctx.strokeStyle = color; | |
ctx.beginPath(); | |
var x0 = 0, | |
y0 = 0; | |
dimensions.map(function(p, i) { | |
var x = xscale(p), | |
y = yscale[p](d[p]); | |
if (i == 0) { | |
ctx.moveTo(x, y); | |
} else { | |
var cp1x = x - 0.85 * (x - x0); | |
var cp1y = y0; | |
var cp2x = x - 0.15 * (x - x0); | |
var cp2y = y; | |
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); | |
} | |
x0 = x; | |
y0 = y; | |
}); | |
ctx.stroke(); | |
}; | |
function random255() { | |
return Math.floor(Math.random() * 255); | |
} | |
// random probably visible color (0-60) | |
// except really just return black | |
function randomVis() { | |
//return Math.floor(Math.random()*60); | |
return 0; | |
} | |
function color(d, a) { | |
//return ["hsla(",randomVis(),",",randomVis(),"%,",randomVis(),"%,",a,")"].join(""); | |
return ["hsla(", randomVis(), ",", randomVis(), "%,", randomVis(), "%,", a, ")"].join(""); | |
}; | |
// Fisher-Yates shuffle | |
function shuffle(array) { | |
var m = array.length, | |
t, i; | |
// While there remain elements to shuffle… | |
while (m) { | |
// Pick a remaining element… | |
i = Math.floor(Math.random() * m--); | |
// And swap it with the current element. | |
t = array[m]; | |
array[m] = array[i]; | |
array[i] = t; | |
} | |
return array; | |
} | |
window.setTimeout(function() { | |
d3.selectAll(".axis g").style("display", "block"); | |
d3.selectAll(".axis path").style("display", "block"); | |
}, 200); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment