|
<html> |
|
<head> |
|
<title>D3 in Action Chapter 6 - Example 1</title> |
|
<meta charset="utf-8" /> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> |
|
<script src="superformula.js" type="text/JavaScript"></script> |
|
<script src="chernoff.js" type="text/JavaScript"></script> |
|
</head> |
|
<style> |
|
svg { |
|
height: 850px; |
|
width: 900px; |
|
border: 1px solid gray; |
|
} |
|
g.am-axis text { |
|
font-size: 8px; |
|
} |
|
|
|
.domain { |
|
fill: none; |
|
} |
|
|
|
.tick > line{ |
|
stroke: black; |
|
stroke-width: 1px; |
|
stroke-opacity: .25; |
|
} |
|
|
|
g.face > path { |
|
fill: white; |
|
stroke: black; |
|
stroke-width: 1px; |
|
} |
|
|
|
</style> |
|
<body> |
|
|
|
<div id="viz"> |
|
<svg> |
|
</svg> |
|
</div> |
|
Shirt icon from Megan Mitchell via the Noun Project |
|
<div/> |
|
</body> |
|
<footer> |
|
|
|
<script> |
|
|
|
var face = d3.chernoff() |
|
.face(function(d) { return (Math.random() * 0.25) + 0.75 }) |
|
.hair(-1) |
|
.mouth(function(d) { return happinessScale(d.happiness) }) |
|
.nosew(function(d) { return (Math.random() * 0.25) + 0.75 }) |
|
.noseh(function(d) { return (Math.random() * 0.25) + 0.75 }) |
|
.eyew(function(d) { return (Math.random() * 0.25) + 0.75 }) |
|
.eyeh(function(d) { return (Math.random() * 0.25) + 0.75 }) |
|
.brow(function(d) { return (Math.random() * 0.25) - 0.5 }); |
|
|
|
dataset = [ |
|
{label: "Susie", happiness: 95, fashion: 20, salary: 95000, age: 22, city: "San Francisco", industry: "Tech", exercise: 90}, |
|
{label: "Randy", happiness: 75, fashion: 1, salary: 15000, age: 7, city: "San Francisco", industry: "Entertainment", exercise: 200}, |
|
{label: "Sheila", happiness: 15, fashion: 750, salary: 45000, age: 41, city: "Rio", industry: "Sales", exercise: 130}, |
|
{label: "Nathan", happiness: 50, fashion: 50, salary: 220000, age: 40, city: "Timbuktu", industry: "Crime", exercise: 300}, |
|
{label: "Porsche", happiness: 1, fashion: 150, salary: 70000, age: 53, city: "Mumbai", industry: "Space Exploration", exercise: 0}, |
|
{label: "Jafar", happiness: 60, fashion: 100, salary: 60000, age: 84, city: "Jakarta", industry: "Administration", exercise: 10}, |
|
{label: "Rigel", happiness: 20, fashion: 100, salary: 50000, age: 74, city: "Beijing", industry: "Education", exercise: 120}, |
|
{label: "Prim", happiness: 30, fashion: 800, salary: 20000, age: 24, city: "San Francisco", industry: "Tech", exercise: 300}, |
|
{label: "Roy", happiness: 50, fashion: 500, salary: 20000, age: 28, city: "Atlanta", industry: "Crime", exercise: 200}, |
|
{label: "Tim", happiness: 5, fashion: 10, salary: 200000, age: 54, city: "New York", industry: "Tech", exercise: 0}, |
|
{label: "Sully", happiness: 100, fashion: 50, salary: 50000, age: 39, city: "Alexandria", industry: "Entertainment", exercise: 400}, |
|
{label: "Hal", happiness: 40, fashion: 110, salary: 150000, age: 29, city: "Jakarta", industry: "Service", exercise: 40}, |
|
{label: "Pip", happiness: 66, fashion: 180, salary: 180000, age: 45, city: "New York", industry: "Sales", exercise: 60}, |
|
{label: "Cicero", happiness: 68, fashion: 660, salary: 90000, age: 80, city: "Mumbai", industry: "Space Exploration", exercise: 80}, |
|
{label: "Leonard", happiness: 43, fashion: 680, salary: 45000, age: 55, city: "Alexandria", industry: "Construction", exercise: 150}, |
|
{label: "Aditi", happiness: 22, fashion: 300, salary: 86000, age: 55, city: "Beijing", industry: "Art", exercise: 10}, |
|
{label: "Jie", happiness: 10, fashion: 25, salary: 110000, age: 18, city: "Atlanta", industry: "Art", exercise: 50}, |
|
]; |
|
|
|
cities = ["San Francisco", "New York", "Atlanta", "Rio", "Beijing", "Paris", "Mumbai", "Timbuktu", "Alexandria", "Jakarta"]; |
|
|
|
industries = ["Tech", "Service", "Entertainment", "Construction", "Administration", "Sales", "Education", "Art", "Crime", "Space Exploration"] |
|
|
|
exerciseValues = dataset.map(function (d) {return d.exercise}); |
|
happinessScale = d3.scale.linear().domain([1,100]).range([-1,1]); |
|
|
|
ageScale = d3.scale.linear().domain([1,100]).range([0,800]); |
|
fashionScaleN3 = d3.scale.linear().domain([20,200,1000]).range([2,-8,-8]).clamp(true); |
|
fashionScaleN2 = d3.scale.linear().domain([20,200,1000]).range([2,1,-1]).clamp(true); |
|
fashionScaleN1 = d3.scale.linear().domain([20,200,1000]).range([2,0.8,10]).clamp(true); |
|
fashionScaleM = d3.scale.linear().domain([20,200,1000]).range([4,1,8]).clamp(true); |
|
salaryScale = d3.scale.linear().domain([0,250000]).range([800,0]).clamp(true); |
|
cityScale = d3.scale.category20c().domain(cities); |
|
industryScale = d3.scale.category20b().domain(industries); |
|
exerciseScale = d3.scale.quantile().domain(exerciseValues) |
|
.range(["#d73027","#fc8d59","#fee08b","#ffffbf","#d9ef8b","#91cf60","#1a9850"]); |
|
|
|
xAxis = d3.svg.axis().scale(ageScale).orient("bottom").tickSize(800).ticks(4); |
|
d3.select("svg").append("g").attr("id", "xAxisG").call(xAxis); |
|
|
|
yAxis = d3.svg.axis().scale(salaryScale).orient("right").ticks(10).tickSize(800).tickSubdivide(10); |
|
|
|
d3.select("svg").append("g").attr("id", "yAxisG").call(yAxis); |
|
|
|
d3.select("svg").selectAll("g.people").data(dataset) |
|
.enter() |
|
.append("g") |
|
.attr("class", "people"); |
|
|
|
people = d3.selectAll("g.people"); |
|
|
|
people |
|
.attr("transform", function(d) {return "translate(" + (ageScale(d.age) - 21) + "," + (salaryScale(d.salary) - 60) + ")"}) |
|
|
|
people |
|
.append("path") |
|
.style("fill", function (d) {return cityScale(d.city)}) |
|
.attr("transform", "translate(20,48)") |
|
.attr("d", "m 34.356212,6.8922268 c -0.0033,-0.0074 -0.0056,-0.0122 -0.01064,-0.02037 -0.03993,-0.07659 -0.07171,-0.137708 -0.103488,-0.194748 0.01549,0.02771 0.02852,0.05296 0.044,0.08067 -0.740694,-1.410493 -1.482202,-2.820988 -2.231045,-4.2274097 -1.819547,-3.42071617 -3.626057,-6.8789144 -5.709614,-10.1513306 -3.13878,-4.9306225 -8.874469,-5.7348725 -13.974579,-3.6651695 -3.3107122,1.3428639 -9.0195112,7.5584964 -11.48278516,7.5584964 -2.46246014,0 -7.92680614,-6.2156325 -11.23833284,-7.5584964 -5.080555,-2.06237 -10.766538,-1.246711 -13.891465,3.6651695 -2.084372,3.2724162 -3.890067,6.73061443 -5.712874,10.1513306 -0.767584,1.4447197 -1.528647,2.8926977 -2.289713,4.3406767 -0.456312,0.870254 -1.009591,1.583241 -0.620911,2.596909 0.62417,1.6247992 2.178894,2.9318092 3.574722,3.8827322 1.656579,1.127745 3.678208,2.052594 5.722651,1.99148 0.357718,-0.01142 1.342049,-0.01393 1.575094,-0.330013 0.324308,-0.43594 0.589947,-0.924848 0.870253,-1.390123 1.193749,-1.980073 2.35979,-3.9772562 3.525017,-5.9752542 -1.35264,9.5866442 -2.526016,19.2001762 -3.527461,28.8291912 -0.440829,4.238005 -0.852326,8.4809 -1.131818,12.730312 -0.152384,2.310899 -0.214305,1.654949 -0.09534,2.506462 0.123861,0.875957 1.090262,1.17419 1.86192,1.375457 2.04363,0.532908 14.2980731,1.219822 21.47359184,1.219822 7.16492496,0 19.56441116,-0.686914 21.60804116,-1.219822 0.770028,-0.200452 1.655764,-0.514167 1.861918,-1.375457 0.148301,-0.624986 0.05622,-0.195563 -0.09534,-2.506462 -0.280306,-4.249412 -0.692618,-8.492307 -1.132633,-12.730312 -1.001444,-9.6282 -2.174821,-19.242547 -3.527462,-28.8291912 1.166858,1.997184 2.330456,3.9951812 3.525831,5.9752542 0.281122,0.465275 0.545132,0.953368 0.86781,1.390123 0.235489,0.31616 1.217378,0.318605 1.578353,0.330013 2.044445,0.06112 4.064443,-0.863735 5.721022,-1.99148 1.395829,-0.950923 2.952181,-2.257933 3.576352,-3.8827322 0.386236,-1.005519 -0.154825,-1.715249 -0.611134,-2.575723 z m -58.346109,6.9954382 c -0.361792,0.527204 -2.253045,-0.144232 -4.223338,-1.498498 -1.971108,-1.355087 -3.27486,-2.8796612 -2.913068,-3.4068642 0.363419,-0.52639 2.254674,0.144232 4.224152,1.4984982 1.971108,1.355085 3.274044,2.880474 2.912254,3.406864 z m 44.607836,37.555359 c 0,0.963146 -8.777503,1.556352 -19.64834116,1.554722 -10.87083754,0.0016 -19.64834084,-0.593207 -19.64834084,-1.554722 0,-0.963147 8.7775033,-0.903662 19.64834084,-0.902847 10.86920816,-0.0033 19.64834116,-0.06112 19.64834116,0.902847 z m 10.01688,-39.053857 c -1.970293,1.354271 -3.860732,2.025702 -4.224153,1.498498 -0.360975,-0.52639 0.940331,-2.052592 2.912254,-3.406864 1.970294,-1.3542712 3.860732,-2.0248882 4.223339,-1.4984982 0.362605,0.528019 -0.941147,2.0525922 -2.91144,3.4068642 z"); |
|
|
|
people |
|
.append("g") |
|
.attr("class", "pattern") |
|
.attr("transform", "translate(5,42)") |
|
.each(function (d) { |
|
var superPattern = d3.superformula() |
|
.param("m", fashionScaleM(d.fashion)) |
|
.param("n1", fashionScaleN1(d.fashion)) |
|
.param("n2", fashionScaleN2(d.fashion)) |
|
.param("n3", fashionScaleN3(d.fashion)) |
|
.param("b", 1) |
|
.param("a", 1) |
|
.size(25); |
|
d3.select(this).selectAll("path.superpattern").data(d3.range(20)) |
|
.enter() |
|
.append("path") |
|
.attr("transform", function (d, i) { |
|
var yPos = (Math.floor(i/5) * 15) + 3; |
|
var xPos = i%5; |
|
return "translate(" + (xPos * 8) + "," + (yPos) + ")"; }) |
|
.attr("d", superPattern) |
|
.style("fill", industryScale(d.industry)) |
|
.style("stroke", industryScale(d.industry)) |
|
.style("stroke-width", 0.5) |
|
.style("stroke-opacity", 0.5); |
|
}) |
|
|
|
people |
|
.append("g") |
|
.attr("class", "face") |
|
.attr("transform", "scale(.3)") |
|
.call(face); |
|
|
|
people.select("path.face") |
|
.style("fill", function (d) {console.log(d, d.exercise, exerciseScale, exerciseScale(d.exercise)); return exerciseScale(d.exercise)}) |
|
.style("stroke", "none"); |
|
|
|
people.append("text") |
|
.attr("y", 65) |
|
.attr("x", 20) |
|
.style("text-anchor", "middle") |
|
.text(function (d) {return d.label}) |
|
.style("stroke", "white") |
|
.style("stroke-width", "4px") |
|
.style("stroke-opacity", .85) |
|
|
|
people.append("text") |
|
.attr("y", 65) |
|
.attr("x", 20) |
|
.style("text-anchor", "middle") |
|
.text(function (d) {return d.label}) |
|
|
|
</script> |
|
</footer> |
|
|
|
</html> |