學習 treemap
遇到的問題:我改不動 mouseover 使區塊變色,mouseover 後 d3.select(this).style("background", anotherColor) 沒作用?
學習 treemap
遇到的問題:我改不動 mouseover 使區塊變色,mouseover 後 d3.select(this).style("background", anotherColor) 沒作用?
Group | Group description | Type | Type description | Percentage | |
---|---|---|---|---|---|
A | The Rich | A1 | Privileged | 3 | |
A | The Rich | A2 | Entrepaneurs | 7 | |
A | The Rich | A3 | Empty Nesters | 10 | |
B | Upper Class Families | B4 | Well-established Volvo | 23 | |
B | Upper Class Families | B5 | Optimist | 7 | |
C | Suburban | C6 | Small Business | 5 | |
C | Suburban | C7 | Never Left Home | 15 | |
E | Students | D8 | Students | 12 | |
F | Troubled | E9 | Borderline Beneficiaries | 8 | |
F | Welfare | F10 | Families on Benefits | 10 |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<body> | |
<style> | |
form { | |
position: absolute; | |
left: 20px; | |
top: 10px; | |
} | |
.node { | |
border: solid 2px white; | |
position: absolute; | |
overflow: hidden; | |
text-align: center; | |
} | |
#tooltip { | |
position: absolute; | |
width: 220px; | |
height: auto; | |
padding: 10px; | |
background-color: white; | |
-webkit-border-radius: 10px; | |
-moz-border-radius: 10px; | |
border-radius: 10px; | |
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); | |
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); | |
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); | |
pointer-events: none; | |
} | |
#tooltip.hidden { | |
display: none; | |
} | |
#tooltip p { | |
margin: 0; | |
font-family: sans-serif; | |
font-size: 16px; | |
line-height: 20px; | |
} | |
</style> | |
<form> | |
<label><input type="radio" name="mode" value="population" checked> Population distribution</label> | |
<label><input type="radio" name="mode" value="revenue"> Revenue</label> | |
</form> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
var margin = { top: 40, right: 10, bottom: 10, left: 10 }, | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var percentage = function(d) { return d["percentage"]; }; | |
var revenue = function(d) { return d["revenue"]; }; | |
var colorScale = d3.scale.category20c(); | |
var colorScale2 = d3.scale.category20(); | |
var color = function(d) { return d.children ? colorScale(d["Group"]) : null; } | |
var anotherColor = function(d) { return d.children ? colorScale2(d["Group"]) : null; } | |
var treemap = d3.layout.treemap() | |
.size([width, height]) | |
.sticky(true) | |
.value(percentage); | |
var div = d3.select("body").append("div") | |
.style("position", "relative") | |
.style("width", (width + margin.left + margin.right) + "px") | |
.style("height", (height + margin.top + margin.bottom) + "px") | |
.style("left", margin.left + "px") | |
.style("top", margin.top + "px"); | |
var mousemove = function(d) { | |
var xPosition = d3.event.pageX + 5; | |
var yPosition = d3.event.pageY + 5; | |
d3.select("#tooltip") | |
.style("left", xPosition + "px") | |
.style("top", yPosition + "px"); | |
d3.select("#tooltip #heading") | |
.text(d["demographics"]["Group"] + " - " + d["demographics"]["Group description"]); | |
d3.select("#tooltip #percentage") | |
.text(d["demographics"]["Type description"] + "\n" + d["percentage"] + "%"); | |
d3.select("#tooltip #revenue") | |
.text("£" + d["revenue"].toFixed(0)); | |
d3.select("#tooltip").classed("hidden", false); | |
d3.select(this).style("background", anotherColor); | |
}; | |
var mouseout = function() { | |
d3.select("#tooltip").classed("hidden", true); | |
d3.select(this).style("background", color); | |
}; | |
var randomRevenue = function(data) { | |
var rows = []; | |
data.forEach(function(d){ | |
if (Math.random() < 0.75) { | |
rows.push({"Group": d["Group"], | |
"Type": d["Type"], | |
"Revenue": Math.random() * 100}); | |
} | |
}); | |
return rows; | |
} | |
var groupData = function(groupings, data, key){ | |
data.forEach(function(d){ | |
if(!groupings[d["Group"]]) { | |
groupings[d["Group"]] = {}; | |
} | |
if(!groupings[d["Group"]][d["Type"]]) { | |
groupings[d["Group"]][d["Type"]] = {}; | |
} | |
groupings[d["Group"]][d["Type"]][key] = d; | |
}); | |
} | |
d3.csv("demographics.csv", function(error, data) { | |
var revenueData = randomRevenue(data); | |
var groupings = {} | |
groupData(groupings, data, "demographics"); | |
groupData(groupings, revenueData, "revenue"); | |
var trees = []; | |
for(group in groupings){ | |
var children = []; | |
for(type in groupings[group]){ | |
var elm = groupings[group][type]; | |
elm["percentage"] = elm["demographics"]["Percentage"]; | |
elm["revenue"] = elm["revenue"] | |
? parseFloat(elm["revenue"]["Revenue"]) | |
: 2.0; | |
children.push(elm); | |
} | |
trees.push({"children": children, | |
"Group": group}); | |
} | |
var root = {"children": trees}; | |
var node = div.datum(root).selectAll(".node") | |
.data(treemap.nodes) | |
.enter().append("div") | |
.attr("class", "node") | |
.call(position) | |
.style("background", color) | |
.on("mousemove", mousemove) | |
.on("mouseout", mouseout) | |
.text(function(d) { return d.children ? "": d["demographics"]["Type description"]; }); | |
d3.selectAll("input").on("change", function change() { | |
var value = this.value === "population" ? percentage : revenue; | |
node | |
.data(treemap.value(value).nodes) | |
.transition() | |
.duration(1500) | |
.call(position); | |
}); | |
}); | |
function position() { | |
this.style("left", function(d) { return d.x + "px"; }) | |
.style("top", function(d) { return d.y + "px"; }) | |
.style("width", function(d) { return Math.max(0, d.dx - 2) + "px"; }) | |
.style("height", function(d) { return Math.max(0, d.dy - 2) + "px"; }) | |
.style("line-height", function(d) { return Math.max(0, d.dy - 2) + "px"; }); | |
} | |
</script> | |
<div id="tooltip" class="hidden"> | |
<p><strong id="heading"></strong></p> | |
<p><span id="percentage"></span></p> | |
<p><span id="revenue"></span></p> | |
</div> | |
</body> |