取引額の多い上位10家国を黒字、赤字ごとに取得してプロットしてます。
PCの場合は、左右の(←・→)アローキーでも年代を変更できます。
<!DOCTYPE html>
<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>
Years,Export,Import,Bop,Country
1979,7103,85834,-78731,GREENLD
1980,16063,64746,-48683,GREENLD
1981,60498,794422,-733924,GREENLD
1982,224232,261893,-37661,GREENLD
1983,254139,689390,-435251,GREENLD
1984,268405,3093513,-2825108,GREENLD
1985,47153,7082622,-7035469,GREENLD
1986,512164,10063492,-9551328,GREENLD
1987,346697,14968913,-14622216,GREENLD
1988,66889,16317182,-16250293,GREENLD
1989,179286,18110056,-17930770,GREENLD
1990,288161,19408247,-19120086,GREENLD
1991,274319,16352482,-16078163,GREENLD
1992,500121,12409277,-11909156,GREENLD
1993,392177,13879680,-13487503,GREENLD
1994,309275,10083431,-9774156,GREENLD
1995,89498,9727872,-9638374,GREENLD
1996,154276,12760797,-12606521,GREENLD
1997,111168,9741355,-9630187,GREENLD
1998,300997,9720653,-9419656,GREENLD
1999,111109,11443076,-11331967,GREENLD
2000,44567,10245602,-10201035,GREENLD
2001,52692,7564109,-7511417,GREENLD
2002,35610,7663974,-7628364,GREENLD
2003,40450,8177674,-8137224,GREENLD
2004,7654,7183051,-7175397,GREENLD
2005,27507,7660687,-7633180,GREENLD
2006,34266,7367167,-7332901,GREENLD
2007,86945,7585196,-7498251,GREENLD
2008,43999,8545503,-8501504,GREENLD
2009,58677,8293199,-8234522,GREENLD
2010,11700,6820418,-6808718,GREENLD
2011,17706,7171011,-7153305,GREENLD
2012,12200,8451755,-8439555,GREENLD
2013,300,8793797,-8793497,GREENLD
2014,700,8415772,-8415072,GREENLD
2015,1597,8945975,-8944378,GREENLD
2016,8740,5757540,-5748800,GREENLD
2017,600,8040126,-8039526,GREENLD
2018,250,7911056,-7910806,GREENLD
1979,379475502,896660633,-517185131,CANADA
1980,549836963,1073979568,-524142605,CANADA
1981,748812462,980174750,-231362288,CANADA
1982,708869686,1099931998,-391062312,CANADA
1983,861393305,1053032177,-191638872,CANADA
1984,1018420891,1171993985,-153573094,CANADA
1985,1078423402,1147356026,-68932624,CANADA
1986,933765739,829459981,104305758,CANADA
1987,816718076,882892704,-66174628,CANADA
1988,823346678,1065526155,-242179477,CANADA
1989,935227124,1186403748,-251176624,CANADA
1990,975698952,1219850903,-244151951,CANADA
1991,976883150,1039634402,-62751252,CANADA
1992,897801394,973213153,-75411759,CANADA
1993,704892598,901897063,-197004465,CANADA
1994,605360550,912193205,-306832655,CANADA
1995,545655923,1011685219,-466029296,CANADA
1996,557390687,1100532048,-543141361,CANADA
1997,738100635,1184589085,-446488450,CANADA
1998,828244369,1003008829,-174764460,CANADA
1999,788693107,900255100,-111561993,CANADA
2000,805938747,938485113,-132546366,CANADA
2001,797112940,941469374,-144356434,CANADA
2002,917851339,895043290,22808049,CANADA
2003,854629108,871094866,-16465758,CANADA
2004,826054298,909551154,-83496856,CANADA
2005,971764318,985141713,-13377395,CANADA
2006,1158402984,1118371580,40031404,CANADA
2007,1238409878,1174082205,64327673,CANADA
2008,1116153074,1322835477,-206682403,CANADA
2009,722761037,857526049,-134765012,CANADA
2010,816585314,958015402,-141430088,CANADA
2011,709362049,1031566579,-322204530,CANADA
2012,818899941,1012463942,-193564001,CANADA
2013,847805957,1169548983,-321743026,CANADA
2014,845763221,1189982085,-344218864,CANADA
2015,936052814,1109412720,-173359906,CANADA
2016,886417706,1002778259,-116360553,CANADA
2017,1075663145,1226249907,-150586762,CANADA
2018,1029417300,1294986738,-265569438,CANADA
1979,33690,48163,-14473,ST P MQ
1980,2980,67759,-64779,ST P MQ
1981,30743,798,29945,ST P MQ
1982,30313,249,30064,ST P MQ
1983,15672,5222,10450,ST P MQ
1984,12871,79800,-66929,ST P MQ
1985,8471,90662,-82191,ST P MQ
1986,2321,36501,-34180,ST P MQ
1987,35808,23526,12282,ST P MQ
1988,66914,5167,61747,ST P MQ
1989,69205,662904,-593699,ST P MQ
1990,140661,21074,119587,ST P MQ
1991,142949,101174,41775,ST P MQ
1992,29757,158607,-128850,ST P MQ
1993,8086,3162,4924,ST P MQ
1994,115834,3470,112364,ST P MQ
1995,2475,8883,-6408,ST P MQ
1996,3064,15265,-12201,ST P MQ
1997,4388,1252,3136,ST P MQ
1998,95550,1134,94416,ST P MQ
1999,137391,143308,-5917,ST P MQ
2000,589380,132095,457285,ST P MQ
2001,937830,1012485,-74655,ST P MQ
2002,0,1093,-1093,ST P MQ
2003,0,1310,-1310,ST P MQ
2004,211,0,211,ST P MQ
2005,8789,0,8789,ST P MQ
2006,0,203,-203,ST P MQ
2007,0,0,0,ST P MQ
2008,0,0,0,ST P MQ
2009,2294,927,1367,ST P MQ
2010,291,1029,-738,ST P MQ
2011,20315,1738,18577,ST P MQ
2012,0,0,0,ST P MQ
2013,0,291,-291,ST P MQ
2014,0,0,0,ST P MQ
2015,0,0,0,ST P MQ
2016,0,0,0,ST P MQ
2017,0,0,0,ST P MQ
2018,0,0,0,ST P MQ
1979,5772773271,4456875699,1315897572,USA
1980,7118068295,5558111850,1559956445,USA
1981,8518676573,5552194215,2966482358,USA
1982,9015157570,5990524240,3024633330,USA
1983,10178585470,5855339358,4323246112,USA
1984,14221243909,6363608010,7857635899,USA
1985,15582715376,6213379884,9369335492,USA
1986,13563656567,4917847616,8645808951,USA
1987,12148054659,4581959518,7566095141,USA
1988,11487389163,5388264370,6099124793,USA
1989,12815991081,6632440506,6183550575,USA
1990,13056597641,7585904339,5470693302,USA
1991,12323796106,7190513601,5133282505,USA
1992,12120949537,6622048083,5498901454,USA
1993,11735162688,6162617478,5572545210,USA
1994,12035826285,6424429712,5611396573,USA
1995,11332951630,7076404002,4256547628,USA
1996,12177119308,8630976064,3546143244,USA
1997,14168941406,9149282451,5019658955,USA
1998,15470005803,8778119003,6691886800,USA
1999,14605315039,7639509645,6965805394,USA
2000,15355867334,7778861082,7577006252,USA
2001,14711055296,7671481006,7039574290,USA
2002,14873325654,7237175644,7636150010,USA
2003,13412156816,6824958413,6587198403,USA
2004,13730742370,6763358820,6967383550,USA
2005,14805465279,7074269509,7731195770,USA
2006,16933589773,7911227113,9022362660,USA
2007,16896234816,8348695214,8547539602,USA
2008,14214320598,8039575771,6174744827,USA
2009,8733358862,5512349685,3221009177,USA
2010,10373979853,5911421399,4462558454,USA
2011,10017653282,5931422189,4086231093,USA
2012,11188354357,6082064277,5106290080,USA
2013,12928168375,6814818915,6113349460,USA
2014,13649256753,7542679072,6106577681,USA
2015,15224592157,8059780909,7164811248,USA
2016,14142872402,7322133759,6820738643,USA
2017,15113485105,8090251224,7023233881,USA
2018,15470237117,9014901931,6455335186,USA
Years,Exp-Total,Imp-Total
1979,22531538859,24245350997
1980,29382471938,31995325202
1981,33468984502,31464145741
1982,34432500947,32656302574
1983,34909268599,30014784056
1984,40325293701,32321126640
1985,41955659471,31084935207
1986,35289713887,21550717070
1987,33315191383,21736912673
1988,33939183158,24006319859
1989,37822534626,28978572581
1990,41456939674,33855207638
1991,42359892974,31900153522
1992,43012281444,29527419360
1993,40202448725,26826357239
1994,40497552697,28104327343
1995,41530895121,31548753881
1996,44731311206,37993421106
1997,50937991859,40956182573
1998,50645003938,36653647183
1999,47547556241,35268008063
2000,51654197760,40938422968
2001,48979244311,42415533002
2002,52108955735,42227505945
2003,54548350172,44362023352
2004,61169979094,49216636346
2005,65656544157,56949392181
2006,75246173392,67344293072
2007,83931437612,73135920427
2008,81018087607,78954749926
2009,54170614088,51499377779
2010,67399626696,60764956840
2011,65546474948,68111187178
2012,63747572215,70688631840
2013,69774192950,81242545171
2014,73093028311,85909112733
2015,75613928862,78405535793
2016,70035770383,66041973885
2017,78286457048,75379231107
2018,81478752674,82703304395
/**
* @module nChart/createHBarChart
* @desc 棒グラフ(横)を生成します。
* @example
*var instans = nChart.createHBarChart()
*
*
*var selector = d3.select(query)
* .datum(data)
* .call(instans)
*/
!(function() {
'use strict';
if (typeof module !== 'undefined' && module.exports) {
module.exports = createHBarChart;
} else {
window.createHBarChart = createHBarChart;
}
function createHBarChart() {
var _addSvgElement = true;
var _plotWidth, _plotHeight;
var _plotMargin = { top: 0, left: 0, bottom: 0, right: 0 };
var _x = function(d) {
return d;
},
_y = function(d) {
return d;
};
var _xScale = d3.scaleLinear(),
_yScale = d3.scaleBand();
var _xScaleDomain, _yScaleDomain, _xScaleRange, _yScaleRange;
var _forcedXScaleDomain, _forcedYScaleDomain;
var _scalePaddingInner = 0,
_scalePaddingOuter = 0;
var _valueLabelVisible = false;
var _responsive = true;
var _parentNode;
var _svg, _backgroundLayer, _chartLayer, _plotLayer, _axisLayer;
function instance(_selection) {
_selection.each(function(_data) {
var isHash = function(value) {
return value.toString() === '[object Object]';
};
var isArray =
Array.isArray ||
function(value) {
return value.toString() === '[object Array]';
};
setLayers(_selection);
main(_data);
if (_responsive) setReSizeEvent(_selection);
updateBindSelector(_selection);
function main(data) {
setSize();
if (isHash(data)) {
var tmp = [];
Object.keys(data).forEach(function(key) {
tmp.push(data[key]);
});
setScale(Array.prototype.concat.apply([], tmp));
} else if (isArray(data)) {
setScale(data);
}
renderBarChart(data);
if (_valueLabelVisible) renderValueLabels(data);
}
function setReSizeEvent(_selection) {
var resizeTimer;
var interval = Math.floor(1000 / 60 * 10);
window.addEventListener('resize', function(event) {
if (resizeTimer !== false) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(function() {
main(_data);
_selection.dispatch('resize');
}, interval);
});
}
function setLayers(_selection) {
//parent element
_parentNode = _selection.node();
//parent -> svg element
var target = _addSvgElement ? 'svg' : 'g';
var selectedSVG = _selection.selectAll(target).data([ null ]);
var newSVG = selectedSVG.enter().append(target).attr('class', 'createHBarChart');
_svg = selectedSVG.merge(newSVG);
//svg -> background layer
var newBackgroundLayer = _svg.selectAll('.backgroundLayer').data([ null ]);
_backgroundLayer = newBackgroundLayer
.enter()
.append('g')
.classed('backgroundLayer', true)
.merge(newBackgroundLayer);
newBackgroundLayer.append('rect').classed('bg', true);
//svg -> chart layer
var newChartLayer = _svg.selectAll('.chartLayer').data([ null ]);
_chartLayer = newChartLayer.enter().append('g').classed('chartLayer', true).merge(newChartLayer);
//chart layer -> plot layer
var newPlotLayer = _chartLayer.selectAll('.plotLayer').data([ null ]);
_plotLayer = newChartLayer.enter().append('g').classed('plotLayer', true).merge(newPlotLayer);
//chart layer -> axis layer
var newAxisLayer = _chartLayer.selectAll('.axisLayer').data([ null ]);
_axisLayer = newChartLayer.enter().append('g').classed('axisLayer', true).merge(newAxisLayer);
}
function setSize() {
var parentWidth = _parentNode.clientWidth || _parentNode.parentNode.clientWidth;
var parentHeight = _parentNode.clientHeight || _parentNode.parentNode.clientHeight;
_plotWidth = parentWidth - (_plotMargin.left + _plotMargin.right);
_plotHeight = parentHeight - (_plotMargin.top + _plotMargin.bottom);
_svg.attr('width', parentWidth).attr('height', parentHeight);
_backgroundLayer.select('.bg').attr('width', parentWidth).attr('height', parentHeight);
_plotLayer
.attr('width', _plotWidth)
.attr('height', _plotHeight)
.attr('transform', 'translate(' + [ _plotMargin.left, _plotMargin.top ] + ')');
}
function setScale(data) {
var yMap = data.map(function(d) {
return _y(d).toString();
});
var xMax = d3.max(data, function(d) {
return _x(d);
});
var xMin = d3.min(data, function(d) {
return _x(d);
});
var xExtent = [ xMin, xMax ];
if (xMin > 0) xExtent = [ 0, xMax ];
_xScaleDomain = _forcedXScaleDomain ? _forcedXScaleDomain : xExtent;
_yScaleDomain = _forcedYScaleDomain ? _forcedYScaleDomain : yMap;
_xScaleRange = [ 0, _plotWidth ];
_yScaleRange = [ _plotHeight, 0 ];
_xScale.domain(_xScaleDomain);
_yScale.domain(_yScaleDomain);
_xScale.range(_xScaleRange);
_yScale.rangeRound(_yScaleRange);
scaleBindSelector(_selection);
_yScale.paddingInner(_scalePaddingInner).paddingOuter(_scalePaddingOuter);
}
function renderBarChart(data) {
var bar = _plotLayer.selectAll('.bar').data(data, function(d) {
return _y(d);
});
bar.exit().remove();
var newBar = bar
.enter()
.append('rect')
.attr('class', function(d) {
return 'bar ' + _y(d);
})
.attr('transform', function(d) {
var x = _xScale(Math.min(0, _x(d)));
return 'translate(' + [ x, _yScale(_y(d)) ] + ')';
});
bar
.merge(newBar) //選択済みセレクションをenterで追加されるセレクションにマージする
.attr('height', _yScale.bandwidth())
.transition()
.attr('width', function(d) {
var width = Math.abs(_xScale(_x(d)) - _xScale(0));
return width;
})
.attr('transform', function(d) {
var x = _xScale(Math.min(0, _x(d)));
return 'translate(' + [ x, _yScale(_y(d)) ] + ')';
});
}
function renderValueLabels(data) {
var label = _plotLayer.selectAll('.label').data(data, function(d) {
return _y(d);
});
label.exit().remove();
var newLabel = label.enter().append('text').attr('class', function(d) {
return 'label ' + _y(d);
});
var formart = d3.format('.2f');
label
.merge(newLabel) //選択済みセレクションをenterで追加されるセレクションにマージする
.attr('text-anchor', function(d) {
if (d.Bop > 0) return 'start';
if (d.Bop < 0) return 'end';
})
.attr('dominant-baseline', 'middle')
.attr('x', function(d) {
if (_x(d) <= 0) return '-0.5em';
return '0.5em';
})
.attr('y', _yScale.bandwidth() / 2)
.html(function(d) {
var value = _x(d) * 1000;
var abs = Math.abs(value);
var str = null;
if (abs > 900000000000) {
str = formart(value / 1000000000000);
str = '<tspan>' + str + '</tspan>';
str += '<tspan> 兆</tspan>';
} else {
str = formart(value / 100000000000);
str = '<tspan>' + str + '</tspan>';
str += '<tspan> 千億</tspan>';
}
return str;
})
.transition()
.attr('transform', function(d) {
var x = _xScale(_x(d));
return 'translate(' + [ x, _yScale(_y(d)) ] + ')';
});
}
function scaleBindSelector(_selection) {
//セレクターにaxisがバインドできるか判別するためのフラグ
_selection._enableBindAxis = true;
//セレクターにスケールをバインドする
_selection._xScale = _xScale;
_selection._yScale = _yScale;
//セレクターにマージンをバインドする
_selection._plotMargin = _plotMargin;
//セレクターにアクセサをバインドする
_selection._x = _x;
_selection._y = _y;
_selection._addSvgElement = _addSvgElement;
}
function updateBindSelector(_selection) {
if (!_selection.updateFanctions) _selection.updateFanctions = [];
_selection.updateFanctions.push(main);
_selection.update = function(data) {
_selection.updateFanctions.forEach(function(f) {
f(data);
});
};
}
});
}
//getter
instance.getChartWidth = function(_arg) {
if (!arguments.length) return _plotWidth;
throw new Error('このメソッドは取得専用です');
};
instance.getChartHeight = function(_arg) {
if (!arguments.length) return _plotHeight;
throw new Error('このメソッドは取得専用です');
};
/**
* チャート描画エリアのマージンを設定する
* @alias module:nChart/createHBarChart.plotMargin
* @param {Object} options 四方のマージンサイズを渡す
* @param {Number} options.top 上辺のマージン
* @param {Number} options.left 左辺のマージン
* @param {Number} options.bottom 下辺のマージン
* @param {Number} options.right 右辺のマージン
*/
instance.plotMargin = function(_arg) {
if (!arguments.length) return _plotMargin;
Object.keys(_arg).forEach(function(key) {
_plotMargin[key] = _arg[key];
});
return this;
};
/**
* データセットからx軸に適応するデータ項目を設定する
* @alias module:nChart/createHBarChart.x
* @param {Function} accessor アクセサ関数を渡す
*/
instance.x = function(_arg) {
if (!arguments.length) return _x;
_x = _arg;
return this;
};
/**
* データセットからy軸に適応するデータ項目を設定する
* @alias module:nChart/createHBarChart.y
* @param {Function} accessor アクセサ関数を渡す
*/
instance.y = function(_arg) {
if (!arguments.length) return _y;
_y = _arg;
return this;
};
/**
* x軸のスケールを設定する
* @alias module:nChart/createHBarChart.xScale
* @param {Object} scale d3スケールオブジェクトを渡す
*/
instance.xScale = function(_arg) {
if (!arguments.length) return _xScale;
_xScale = _arg;
return this;
};
/**
* y軸のスケールを設定する
* @alias module:nChart/createHBarChart.yScale
* @param {Object} scale d3スケールオブジェクトを渡
*/
instance.yScale = function(_arg) {
if (!arguments.length) return _yScale;
_yScale = _arg;
return this;
};
/**
* x軸のドメイン範囲を設定する
* @alias module:nChart/createHBarChart.xScaleDomain
* @param {Number[]} domain 描画する最小値と最大値を渡す
*/
instance.xScaleDomain = function(_arg) {
if (!arguments.length) return _xScaleDomain;
_forcedXScaleDomain = _arg;
return this;
};
/**
* y軸のドメイン範囲を設定する
* @alias module:nChart/createHBarChart.yScaleDomain
* @param {Number[]} domain 描画する最小値と最大値を渡す
*/
instance.yScaleDomain = function(_arg) {
if (!arguments.length) return _yScaleDomain;
_forcedYScaleDomain = _arg;
return this;
};
/**
* x軸のバーチャート間のパディング(内側)を指定する
* @alias module:nChart/createHBarChart.scalePaddingInner
* @param {Number[]} padding 0〜1の間で、バーチャートのサイズに対する割合を渡す
*/
instance.scalePaddingInner = function(_arg) {
if (!arguments.length) return _scalePaddingInner;
_scalePaddingInner = _arg;
return this;
};
/**
* x軸のバーチャートのパディング(外側)を指定する
* @alias module:nChart/createHBarChart.scalePaddingOuter
* @param {Number[]} padding 0〜1の間で、バーチャートのサイズに対する割合を渡す
*/
instance.scalePaddingOuter = function(_arg) {
if (!arguments.length) return _scalePaddingOuter;
_scalePaddingOuter = _arg;
return this;
};
/**
* バーの先端に値ラベルを表示する
* @alias module:nChart/createAxis.xAxisDomainLineVisible
* @param {Boolean} flag 表示(true),非表示(false)を渡す
*/
instance.valueLabelVisible = function(_arg) {
if (!arguments.length) return _valueLabelVisible;
_valueLabelVisible = _arg;
return this;
};
/**
* レスポンシブ機能の有効・無効を設定する
* @alias module:nChart/createHBarChart.responsive
* @param {Boolean} flag 有効, 無効を渡す
*/
instance.responsive = function(_arg) {
if (!arguments.length) return _responsive;
_responsive = _arg;
return this;
};
/**
* svgエレメントを追加する・しないを設定する
* @alias module:nChart/createHBarChart.addSvgElement
* @param {Boolean} flag 有効, 無効を渡す
*/
instance.addSvgElement = function(_arg) {
if (!arguments.length) return _addSvgElement;
_addSvgElement = _arg;
return this;
};
return instance;
}
})();
/**
* @module nChart/swiper
* @desc チャートにテキストラベルを追加します
* @example
* var swiper = d3.select("#swiper");
* var swiperData = d3.range(1976, 2017).map(function(d, i) {
* return { index: i, value: d, label: d };
* });
*
* swiper.datum(swiperData).call(nChart.createSwiper());
*/
!(function() {
'use strict';
if (typeof module !== 'undefined' && module.exports) {
module.exports = createSwiper;
} else {
window.createSwiper = createSwiper;
}
function createSwiper() {
var _wrapper = null;
var _minIndex = null;
var _maxIndex = null;
var _currentIndex = 0;
var _slideDuration = 400;
var _autoAnimation = true;
var _dispatch = d3.dispatch('edgeClick', 'slideClick', 'slideChange');
function instance(_selection) {
_selection.on = function() {
return this.on.apply(_dispatch, arguments);
};
_selection.each(function(_data) {
_wrapper = d3.select(this).append('div').classed('swiper-wrapper', true);
main();
function main() {
getIndex(_data);
addSlide(_data);
addBlank();
//デフォルトのインデックス
selectedSlide(_currentIndex, _selection, 0);
setClickSlideEvent(_selection);
setClickEdgeEvent(_selection);
setKeyEvent(_selection);
}
_selection.minIndex = function(_arg) {
if (!arguments.length) return _minIndex;
_minIndex = _arg;
return this;
};
_selection.maxIndex = function(_arg) {
if (!arguments.length) return _maxIndex;
_maxIndex = _arg;
return this;
};
_selection.nextSlide = function() {
if (_maxIndex <= _currentIndex) return;
_currentIndex += 1;
selectedSlide(_currentIndex, _selection, _slideDuration);
return this;
};
_selection.prevSlide = function() {
if (_minIndex >= _currentIndex) return;
_currentIndex -= 1;
selectedSlide(_currentIndex, _selection, _slideDuration);
return this;
};
_selection.selectSlide = function(_arg) {
if (!arguments.length) return _currentIndex;
_currentIndex = _arg;
selectedSlide(_currentIndex, _selection, 0);
return this;
};
_selection.autoAnimation = function(_arg) {
if (!arguments.length) return _autoAnimation;
_autoAnimation = _arg;
return this;
};
});
}
function addSlide(_data) {
var selectSlide = _wrapper.selectAll('swiper-slide').data(_data);
var enterSlide = selectSlide.enter().append('div').classed('swiper-slide clickable', true);
selectSlide
.merge(enterSlide)
.attr('data-index', function(d, i) {
return i;
})
.attr('data-value', function(d) {
return d.value;
})
.text(function(d) {
return d.label;
});
}
function getIndex(_data) {
_minIndex = 0;
_maxIndex = _data.length - 1;
}
function addBlank() {
_wrapper.insert('div', ':first-child').classed('swiper-blank', true);
_wrapper.append('div').classed('swiper-blank', true);
}
//スライドがクリックされた際に発行されるイベントを設定
function setClickSlideEvent(_selection) {
_wrapper.selectAll('.swiper-slide').on('click.centerd', function(d, i) {
console.log('click', _selection.node());
selectedSlide(i, _selection, _slideDuration);
_dispatch.call('slideClick', this, d);
});
}
//端のスライドがクリックされた際に発行されるイベントを設定
function setClickEdgeEvent(_selection) {
var edge = d3.selectAll('.swiper-slide').filter(function(d, i, node) {
if (0 == i) d._edge = 'first';
if (node.length - 1 == i) d._edge = 'first';
return 0 == i || node.length - 1 == i;
});
edge.on('click.edgeclick', function(d) {
_dispatch.call('edgeClick', this, d);
});
}
function setKeyEvent(_selection) {
var KeyDownFunc = function(e) {
var keyCode = e.keyCode;
if (keyCode == 37) {
//←アローキー
_selection.prevSlide();
} else if (keyCode == 39) {
//→アローキー
_selection.nextSlide();
}
};
if (document.addEventListener) {
document.addEventListener('keydown', KeyDownFunc);
} else if (document.attachEvent) {
document.attachEvent('onkeydown', KeyDownFunc);
}
}
function selectedSlide(index, _selectin, duration) {
_selectin.selectAll('.swiper-slide').classed('swiper-slide-active', false);
var container = _selectin.select('.swiper-wrapper').node();
console.dir(container);
var slide = d3
.selectAll('.swiper-slide')
.filter(function(d, i, node) {
return i == index;
})
.classed('swiper-slide-active', true);
var start = container.scrollLeft;
var target = slide.node().offsetLeft - container.clientWidth / 2 + 32;
if (_autoAnimation) {
if (!duration) {
container.scrollLeft = target;
} else {
moveTween(start, target, duration, d3.easeCubicOut, function(d) {
container.scrollLeft = d;
});
}
}
_currentIndex = index;
_dispatch.call('slideChange', this, slide.datum());
}
function moveTween(start, target, duration, ease, callback) {
var scale = d3.scaleLinear().domain([ 0, duration ]).range([ 0, 1 ]); //.clamp(true);
var interpolateX = d3.interpolate(start, target);
var t = d3.timer(function(elapsed) {
var c = ease(scale(elapsed));
callback(interpolateX(c));
if (elapsed > duration) t.stop();
}, 100);
}
return instance;
}
})();