|
<!DOCTYPE html> |
|
|
|
<head> |
|
<meta charset="utf-8"> |
|
<title>Global Corporate Tax Rates Map from 2006 to 2016</title> |
|
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script> |
|
<script src="https://d3js.org/topojson.v1.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.10.0/d3-legend.min.js"></script> |
|
<style> |
|
.country path { |
|
fill: #ECECEC; |
|
} |
|
|
|
.country path:hover { |
|
/*stroke: #FFFFFF;*/ |
|
stroke-width: 1px; |
|
fill-opacity: 0.7; |
|
} |
|
|
|
.country text { |
|
fill: black; |
|
font-size: 8px; |
|
} |
|
|
|
div { |
|
font-family: 'Open Sans', sans-serif; |
|
} |
|
|
|
div#tooltip { |
|
position: absolute; |
|
z-index: 10; |
|
width: 100px; |
|
border: 1px solid #cccccc; |
|
border-radius: 5px; |
|
padding: 0px 10px 0px 10px; |
|
background: #F7F7F7; |
|
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3); |
|
} |
|
|
|
div#tooltip p { |
|
line-height: 1.2em; |
|
text-align: center |
|
} |
|
|
|
div#tooltip hr { |
|
border: 0; |
|
height: 0; |
|
border-top: 1px solid rgba(0, 0, 0, 0.1); |
|
border-bottom: 1px solid rgba(255, 255, 255, 0.3); |
|
} |
|
|
|
p#tooltip-country-name { |
|
color: #666666; |
|
font-size: 14px; |
|
font-weight: 600; |
|
} |
|
|
|
p#tooltip-tax { |
|
font-size: 10px; |
|
font-weight: 800; |
|
color: #666666; |
|
font-weight: 300; |
|
} |
|
|
|
span#tooltip-legend-icon { |
|
font-size: 16px; |
|
text-shadow: 0px 0px 3px rgba(0, 0, 0, 0.7); |
|
} |
|
|
|
span#tooltip-value { |
|
vertical-align: 0.1em; |
|
} |
|
|
|
.horizontalLegend { |
|
font-size: 10px; |
|
font-weight: 600; |
|
} |
|
|
|
.horizontalLegend .legendTitle { |
|
transform: translate(0, 15px); |
|
font-size: 12px; |
|
font-weight: 800; |
|
} |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<div id="menu"> |
|
Year Selection: |
|
<select> |
|
<option>2016</option> |
|
<option>2015</option> |
|
<option>2014</option> |
|
<option>2013</option> |
|
<option>2012</option> |
|
<option>2011</option> |
|
<option>2010</option> |
|
<option>2009</option> |
|
<option>2008</option> |
|
<option>2007</option> |
|
<option>2006</option> |
|
</select> |
|
</div> |
|
<div id="chart"></div> |
|
<script> |
|
var width = 960, |
|
height = 600; |
|
|
|
var data; |
|
|
|
var svg = d3.select("div#chart").append("svg") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
// 新增 d3-legend |
|
svg.append("g") |
|
.attr("class", "horizontalLegend") |
|
.attr("transform", "translate(400,520)"); |
|
|
|
var projection = d3.geo.mercator() |
|
.center([0, 0]) |
|
.scale(150) |
|
.translate([470, 400]); |
|
|
|
// 顏色尺度 |
|
var color = d3.scale.linear() |
|
.range(["#FFE4B5", "#F64403"]); |
|
|
|
var path = d3.geo.path() |
|
.projection(projection); |
|
|
|
var menu = d3.select("div#menu select") |
|
.on("change", change); |
|
|
|
var tooltip = d3.select("div#chart") |
|
.append("div") |
|
.attr("id", "tooltip") |
|
.style("visibility", "hidden"); |
|
|
|
d3.json("world.json", function(error, world) { |
|
if (error) return console.error(error); |
|
|
|
data = topojson.feature(world, world.objects.countries).features |
|
|
|
menu.property("value", "2016"); |
|
|
|
redraw() |
|
|
|
}); |
|
|
|
function change() { |
|
d3.transition() |
|
.duration(0) |
|
.each(redraw); |
|
} |
|
|
|
function redraw() { |
|
var selectedYear = menu.property("value"); // 用這個方法來擷取下拉式選單裡被選中的年份 |
|
|
|
var sortedData = data.sort(function(a, b) { |
|
return b["properties"][selectedYear] - a["properties"][selectedYear]; |
|
}); |
|
|
|
// 幫顏色尺度指定資料範圍 |
|
// 在這邊,sortedData[0]["properties"][selectedYear]] 剛好會是最大值 |
|
color.domain([0, sortedData[0]["properties"][selectedYear]]); |
|
|
|
// Data Join |
|
var country = svg.selectAll(".country") |
|
.data(data, function(d) { |
|
return d["properties"]["NAME"]; |
|
}) |
|
|
|
// Enter |
|
var countryEnter = country.enter().insert("g", ".horizontalLegend") |
|
.attr("class", "country") |
|
.style("fill-opacity", 0); |
|
|
|
// Enter - Country Path |
|
countryEnter.append("path") |
|
.attr("id", function(d) { |
|
return d.id; |
|
}) |
|
.attr("d", path); |
|
|
|
// // Enter - Country Name |
|
// countryEnter.append("text") |
|
// .attr("class", "label") |
|
// .attr("transform", function(d) { |
|
// var centroid = path.centroid(d), |
|
// x = centroid[0], |
|
// y = centroid[1]; |
|
// return "translate(" + x + "," + y + ")"; |
|
// }).attr("dy", ".35em") |
|
// .attr("text-anchor", "start"); |
|
|
|
// Mouse Events |
|
country.select("path") |
|
.on("mouseover", function() { |
|
return tooltip.style("visibility", "visible"); |
|
}).on("mousemove", function(d) { |
|
return tooltip |
|
.style("top", (d3.event.pageY - 10) + "px") |
|
.style("left", (d3.event.pageX + 10) + "px") |
|
.html(tooltipHtml(d["properties"]["NAME"], d["properties"][selectedYear])); |
|
}).on("mouseout", function() { |
|
return tooltip.style("visibility", "hidden"); |
|
}); |
|
|
|
// Legend (With D3-Legend) |
|
var legend = d3.select(".horizontalLegend") |
|
|
|
var legendLinear = d3.legend.color() |
|
.shapeWidth(30) |
|
.cells(11) |
|
.orient("horizontal") |
|
.scale(color) |
|
.title("Corporation Tax Rate (%)"); |
|
|
|
legend.call(legendLinear); |
|
|
|
// Update |
|
var countryUpdate = d3.transition(country) |
|
.style("fill-opacity", 1); |
|
|
|
// Update - Country Path |
|
countryUpdate.select("path") |
|
.style("fill", function(d) { |
|
return d["properties"][selectedYear] == undefined ? "" : color(d["properties"][selectedYear]); |
|
}); |
|
|
|
// // Update - Country Name |
|
// countryUpdate.select(".label") |
|
// .text(function(d) { |
|
// return d["properties"]["NAME"]; |
|
// }); |
|
|
|
|
|
// Exit |
|
var countryExit = d3.transition(country.exit()) |
|
.style("fill-opacity", 0) |
|
.remove(); |
|
|
|
// Exit - Country Path |
|
countryExit.select("path") |
|
.style("fill", function(d) { |
|
return color(d["properties"][selectedYear]); |
|
}); |
|
|
|
// Exit - Country Name |
|
countryExit.select(".label") |
|
.text(function(d) { |
|
return d["properties"]["NAME"]; |
|
}); |
|
|
|
} |
|
|
|
function tooltipHtml(country, taxrate) { |
|
var code = '<p id="tooltip-country-name">' + country + '</p><hr>' + '<p id="tooltip-tax"><span id="tooltip-legend-icon" style="color: ' + (taxrate == undefined ? "#ECECEC" : color(taxrate)) + '; ">●</span><span id="tooltip-value"> ' + (taxrate == undefined ? "No Data." : taxrate + "%") + '</span></p>' |
|
return code; |
|
} |
|
</script> |
|
</body> |