/* -------------------- 初期の設定 -------------------- */ /* 描画エリアのサイズ */ const width = 900 const height = 600 /* 表示領域の用意 */ const svgContainer = d3.select('#main').append('svg') .attr({width, height}) .style({ border: 'solid 1px lightGray', background: 'rgba(255, 0, 0, 0.03)' }) const mapContainer = svgContainer.append('g').attr('class', 'mapBlock') const dataContainer = svgContainer.append('g').attr('class', 'dataBlock') const legendContainer = svgContainer.append('g').attr('id', 'legendBlock') .attr('transform', 'translate(800,60)') .attr('width', 300).attr('height', 60).style('fill', 'red') /* 地図投影法 */ const projection = d3.geo.mercator() .scale(1200) .center([140.467551, 37.750299]) /* 地形データを SVG に変換するときに呼び出す */ const path = d3.geo.path().projection(projection) const rScale = d3.scale.linear().domain([0, 14000]).range(['#fff', '#00f']) const cScale = d3.scale.linear().domain([0, 14000]).range([2, 30]) /* -------------------- 外部ファイルの読み込み -------------------- */ queue() .defer(d3.json, "japan.json") .defer(d3.tsv, "population.tsv") .defer(d3.tsv, "capital.tsv") .await(mainFunc); /* -------------------- ファイル読み込み後に実行するメインの処理 -------------------- */ function mainFunc(_error, _topojson, _population, _capital) { if (_error){ console.log(_error); } let menu let indexYear = -1 let yearArray = [] let selectedPopulation let _prev = [] let _cPrev = [] initMenu() // renderMap() changeYear() renderCircle() /* -------------------- 関数の定義 -------------------- */ function renderMap() { mapContainer.selectAll('path') .data(topojson.feature(_topojson, _topojson.objects.japan).features) .enter() .append('path') .attr('id', (d) => { return d.nam_ja }) .attr('d', path) .style({ 'stroke': '#333', 'stroke-width': '0.2px', 'fill': '#fff' }) mapContainer.selectAll('path') .style('fill', (d, i) => { return rScale( parseInt(_prev[i])) }) .transition() .duration(2000) .style('fill', (d, i) => { const _value = selectedPopulation[0][d.properties.nam_ja] _prev[i] = _value return rScale(parseInt(_value)) //return '#ccc' }) } function renderCircle() { dataContainer.selectAll('circle') .data(_capital) .enter() .append('circle') .attr('id', (d) => { return d.num_ja }) .attr('class', 'perf') .attr('cx', (d) => { return projection([d.lon, d.lat])[0] }) .attr('cy', (d) => { return projection([d.lon, d.lat])[1] }) .attr('r', 2) .style('fill', (d) => { return'rgba(0,0,250,0.5)' }) dataContainer.selectAll('circle') .transition() .duration(2000) .attr('r', (d, i) => { const _value = selectedPopulation[0][d.nam_ja] _cPrev[i] = _value return cScale(parseFloat(_value)) }) } function initMenu() { for (let i = 0; i < _population.length; i++) { yearArray[i] = _population[i].date } menu = d3.select('#menuBlock select').on('change', changeYear) menu.selectAll('option') .data(yearArray) .enter() .append('option') .attr('value', (d, i) => { return i }) .text((d) => { return d + '年' }) } function changeYear() { if(indexYear != -1) { indexYear = parseInt(menu.property('value')) } else { indexYear = 0 } selectedPopulation = _population.filter((d) => { return d.date == yearArray[indexYear]; }) renderMap() renderCircle() } };