取引額の多い上位10家国を黒字、赤字ごとに取得してプロットしてます。
PCの場合は、左右の(←・→)アローキーでも年代を変更できます。
xxxxxxxxxx
<html lang='jp'>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Roboto+Condensed&display=swap" rel="stylesheet">
<style>
.bg {
display: none;
}
/* axis */
.axisLayer .axis {
}
.axisLayer .axis .domain {
stroke: #333333;
}
.axisLayer .tick line {
stroke: #333333;
stroke-width: 1px;
}
.axisLayer .tick text {
fill: #333333;
letter-spacing: .05em;
}
/* label */
.axisLayer .label {
font-weight: normal;
letter-spacing: .05em;
}
/* grid */
.backgroundLayer .grid line {
stroke: #cccccc;
stroke-dasharray: 3,3;
}
.backgroundLayer .grid.y .tick {
stroke-width:2px;
stroke: gray;
stroke-dasharray: 2,5;
}
.backgroundLayer .grid.y .tick:nth-child(even) {
stroke-width:1px;
stroke: gray;
stroke-dasharray: 5,2;
}
.plotLayer text.label tspan:nth-child(1){
font-family: Roboto Condensed,sans-serif;
font-size: 1.2em;
}
.plotLayer text.label tspan:nth-child(2){
font-size: 0.7em;
margin-right: 1em;
}
/* +grind のベースライン */
.backgroundLayer .grid .domain {
stroke: none;
}
html, body {
margin: 0px;
padding: 0px;
height:100%;
overflow: hidden;
}
#hBarChart {
width:100%;
max-width:980px;
height:90%;
margin-bottom: 64px;
}
#hBarChart input {
width:100%;
}
#swiper {
position: fixed;
bottom:0;
width:100%;
max-width:980px;
height: 64px;
background-color: white;
border-top: 1px solid black;
}
.swiper-wrapper{
display: flex;
overflow-x: scroll;
-webkit-overflow-scrolling: touch:
}
.swiper-slide {
display: flex;
align-items: center;
justify-content: center;
font-family: Roboto Condensed,sans-serif;
width: 48px;
height: 48px;
padding: 10px;
border-left: 1px solid black;
}
.swiper-slide-active {
color:white;
background-color:black;
}
#info {
text-align: right;
color:#666;
font-family: Roboto Condensed,sans-serif;
position: fixed;
top:60px;
left:100px;
width:120px;
height: 160px;
padding:8px;
border:1px solid #ccc;
background-color: rgba(255, 255, 255, 0.8);
transform: scale(1);
}
#Year {
font-size:62px;
}
#info .money span:nth-child(1){
width:36px;
text-align: right;
display: inline-block;
font-size:18px;
margin-right: 8px;
}
#info .money span:nth-child(2){
width:40px;
text-align: right;
display: inline-block;
font-size:20px;
margin-right: 8px;
}
#info .money span:nth-child(3){
width:28px;
text-align: left;
display: inline-block;
font-size:14px;
}
.plus{
color:blue;
}
.minus {
color:red;
}
@media(max-width: 375px) {
#info {
top:40px;
left:68px;
transform: scale(0.75);
}
}
</style>
</head>
<body>
<div id="swiper"></div>
<div id="info">
<div id="Year"></div>
<div id="Exp" class="money"></div>
<div id="Imp" class="money"></div>
<div id="Bop" class="money"></div>
</div>
<div id="hBarChart"></div>
<div></div>
<script src='//unpkg.com/d3@5.0.0/dist/d3.min.js'></script>
<script src='./createAxis.js'></script>
<script src='./createHBarChart.js'></script>
<script src='./swiper.js'></script>
<script>
var max = 10;
var fmt = d3.format(".2f");
var info = d3.select("#info")
var total_Exp_Imp = null;
var current_data = null;
var swiper = d3.select("#swiper");
var swiperData = d3.range(1979, 2019).map(function (d, i) {
return { index: i, value: d, label: d };
});
swiper.datum(swiperData).call(createSwiper());
var cast = function(d){
Object.keys(d).forEach(function(key){
if(!isNaN(+d[key])) d[key] = +d[key];
})
return d
}
var p = [];
p.push(d3.csv("./Asia.csv", cast));
p.push(d3.csv("./Africa.csv", cast));
p.push(d3.csv("./LAmerica.csv", cast));
p.push(d3.csv("./NAmerica.csv", cast));
p.push(d3.csv("./EEurope.csv", cast));
p.push(d3.csv("./WEurope.csv", cast));
p.push(d3.csv("./MEast.csv", cast));
p.push(d3.csv("./Oceania.csv", cast));
p.push(d3.csv("./all.csv", cast));
Promise.all(p).then(function(data){
total_Exp_Imp = d3.nest()
.rollup(function(d){ return d[0] })
.key(function (d) { return d["Years"] })
.map(data.pop())
var dataset = data.reduce(function(acr, crr){
var tmp = acr.concat(crr)
return tmp;
}, []);
var yearsNested = d3.nest()
.key(function(d){ return d["Years"]})
.map(dataset)
current_data = filtering(yearsNested.get("1979"));
var selector = initChart(current_data.con)
changeColor(selector, current_data)
total_Exp_Imp_info(1979)
swiper.on("slideChange", function (d) {
var year = d.value;
current_data = filtering(yearsNested.get(year))
selector.update(current_data.con)
changeColor(selector, current_data)
total_Exp_Imp_info(year)
});
selector.on("resize", function(){
changeColor(selector, current_data)
});
});
function total_Exp_Imp_info(year){
var value = total_Exp_Imp.get(year);
var exp = (value["Exp-Total"]*1000) ;
var imp = value["Imp-Total"]*1000;
var bop = exp - imp;
info.selectAll("span").remove()
info.select("#Year").text(year);
info.select("#Exp").append("span").text("輸出")
info.select("#Exp").append("span").text(fmt(exp / 1000000000000));
info.select("#Exp").append("span").text("兆円")
info.select("#Imp").append("span").text("輸入")
info.select("#Imp").append("span").text(fmt(imp / 1000000000000));
info.select("#Imp").append("span").text("兆円")
info.select("#Bop").append("span").text("収支");
info.select("#Bop").append("span").text(fmt(bop / 1000000000000))
.attr("class", (bop > 0) ? "plus" : "minus")
info.select("#Bop").append("span").text("兆円")
info.selectAll(".value").append("span").text("兆円")
}
function changeColor(selector, filterd){
selector.selectAll(".bar")
.each(function (d) {
if (d.Bop > 0) {
d3.select(this).attr("fill", "blue")
} else {
d3.select(this).attr("fill", "red")
}
})
var lowCountry = d3.nest()
.key(function(d){ return d.Country})
.map(filterd.low)
var topCountry = d3.nest()
.key(function (d) { return d.Country })
.map(filterd.top)
selector.select(".axisLayer > g").selectAll(".tick text").each(function (d) {
if(lowCountry.get(d)) d3.select(this).attr("stroke", "red")
if (topCountry.get(d)) d3.select(this).attr("stroke", "blue")
});
}
function filtering(data){
data.sort(function (a, b) { return a["Bop"] - b["Bop"] })
var low = data.slice(0, max);
var top = data.reverse().slice(0, max);
var con = low.reverse().concat(top)
return {low:low, top:top, con:con}
}
function initChart(data){
var chart = createHBarChart()
.plotMargin({ top: 30, left: 80, bottom: 30, right: 40 })
.x(function (d) { return d["Bop"] })
.y(function (d) { return d["Country"] })
.xScaleDomain([-9000000000, 9000000000])
.scalePaddingInner(0.1)
.scalePaddingOuter(0.5)
.valueLabelVisible(true)
var axis = createAxis()
.topAxis(true)
.xAxisGridVisible(true)
.yAxisGridVisible(true)
.yTickPadding(0)
.xTickSize(4)
.yTickSize(4)
.xTickSizeOuter(0)
.yTickSizeOuter(0)
.xAxisDomainLineVisible(true)
.yAxisDomainLineVisible(false)
.xTickFormat(function(d){
return (d*1000)/1000000000000
})
var selector = d3.selectAll("#hBarChart")
.datum(data)
.call(chart)
.call(axis)
return selector;
}
</script>
</body>
</html>
https://unpkg.com/d3@5.0.0/dist/d3.min.js