block by shimizu 16c32d0e045d4e87d47ff5d9574cedcf

地図変形・棒グラフ

Full Screen

クリックすると棒グラフに遷移します。

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>地図・棒グラフ遷移</title>

<style>
html, body {
    width: 100%;
    height: 100%;
}

#stage {
    width: 100%;
    height: 100%;
}
svg {
    width: 100%;
    height: 100%;
}
.hidden {
    display: none;
}
</style>
</head>

<body>
<div id="stage"></div>    
    
    
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.1.1/d3.min.js"></script>    
<script src="d3.geo2square.js"></script>


<script>
!(function(){
    "use strict"
    
    var margin = { top: 40, right: 20, bottom: 80, left: 50}
    
    var width = document.querySelector("#stage").clientWidth
    var height = document.querySelector("#stage").clientHeight
     
    var stageW = width - (margin.left + margin.right)
    var stageH = height - (margin.top + margin.bottom)
            
    var svg = d3.select("#stage").append("svg")
        
    var axisLayer = svg.append("g").attr("class", "axisLayer")
    
    
    var mapLayer = svg.append("g").attr("class", "mapLayer")
        .attr("width", stageW)
        .attr("height", stageH)
        .attr("transform", "translate("+[margin.left, margin.top]+")")
    
    var projection = d3.geoMercator()	
        .scale(stageW*1.4)
        .translate([stageW/2,stageH/1.5])
        .center([139.0032936, 36.3219088]); 
    
    
    var geoPath = d3.geoPath().projection(projection); 
    
    
    var xScale = d3.scaleBand().range([0, stageW])
    var yScale = d3.scaleLinear().domain([0, 100]).range([stageH, 0])
        
    d3.json('japan.geojson', main)
    
    
    function main(json){
    
        xScale.domain(json.features.map(function(d){ return d.properties.pref }))
    
        json.features.forEach(function(d){
            if(d.geometry.coordinates.length > 1) d.geometry.coordinates = [d.geometry.coordinates[1]]
            d.properties.value = ~~(Math.random()*100)
        })
    
        var data = convert(json)
        
        drawMaps(data)
        drawAxis()
            
        var toggleFn = toggle(
            changeSquare,
            changeMap
        )
          
        d3.select("body").on("click", toggleFn)  
        d3.select("body").on("touchend", toggleFn)
    }
    
    function drawMaps(data) {
        mapLayer.selectAll("path")
            .data(data)
            .enter()
            .append("path")
            .attr("class", "land")
            .attr("fill", function(d,i){ return d3.interpolateRainbow(i/100) })
            .attr("stroke", "black")
            .attr("d", function(d){ return d.geoPath })
        
    }
    
    function drawAxis() {
        axisLayer.append("g")
            .attr("transform", "translate("+[margin.left, margin.top]+")")
            .attr("class", "axis y")
            .call(d3.axisLeft(yScale))
    
        axisLayer.append("g")
            .attr("class", "axis x")
            .attr("transform", "translate("+[margin.left, stageH+margin.top]+")")
            .call(d3.axisBottom(xScale))
            .selectAll("text")
              .attr("y", 0)
              .attr("x", 9)
              .attr("dy", ".35em")
              .attr("transform", "rotate(90)")
              .style("text-anchor", "start");        
                
    }
    
    function changeMap() {
        mapLayer.selectAll(".land")
            .transition()
            .duration(500)
            .delay(function(d,i){ return i * 100 })
            .attr('transform', "translate(0, 0)")        
            .attr("d", function(d){ return d.geoPath})
    
    }
    
    function changeSquare() {
        mapLayer.selectAll(".land")
            .transition()
            .duration(500)
            .delay(function(d,i){ return i * 100 })
            .attr("d", function(d){ return d.squarePath})
            .attr('transform', function(d, i){
                return 'translate('+(0-d.center.x)+','+(0-d.center.y)+'),translate('+d.center.nx+','+d.center.ny+')';		    
            })
    }
    
    
    function convert(json) {
        
        var calcCoords = function(polygon, properties) {
            var geoCoords = polygon.map(projection);
            var geoPathString = 'M' + geoCoords.join('L') + 'Z';
    
            var squareCoords = d3.geo2square(geoCoords, xScale.bandwidth(), yScale(properties.value));
            var squarePathString = 'M' + squareCoords.join('L') + 'Z'
            return {squarePath: squarePathString, geoPath: geoPathString , properties:properties};
        };	
    
        var reslut  = [];
        for (var i = 0; i < json.features.length; i++) {
            var geometry = json.features[i].geometry;
            var properties =json.features[i].properties;
            properties.geometry = geometry;
            if (geometry.type == 'Polygon') {
                reslut.push(calcCoords(geometry.coordinates[0], properties));			
            } else if (geometry.type == 'MultiPolygon') {
                geometry.coordinates.forEach(function(coordinates){
                    reslut.push(calcCoords(coordinates[0], properties));
                });			
            }
        }
        
        reslut.forEach(function(d){
            var center = geoPath.centroid(d.properties.geometry);
            var x = center[0]; 
            var y = center[1];
            var nx = xScale(d.properties.pref)
            var ny = stageH - yScale(d.properties.value)  
            d.center = {x:x, y:y, nx:nx, ny:ny}
        })
        
        reslut.sort(function(a,b){ return a.properties["JIS-CODE"] - b.properties["JIS-CODE"]})
            .forEach(function(d){ d.order = d.properties["JIS-CODE"]})
            
        return reslut
    
    }
    
    function toggle(){
        var fn = arguments;
        var l = arguments.length;
        var i = 0;
        return function(that){
            if(l <= i) i=0;
            fn[i++](that);            
        }
    }
}());    

</script>

    
    
</body>
</html>

d3.geo2square.js

if(!d3.geo2square) d3.geo2square = function(coordinates, width, height) {
    console.log(width)
    var centroid =d3.polygonCentroid(coordinates)
        
    width = (width) ? width : 50 ;
    height = (height) ? height : 50 ;

    var pp = []
    var ii = 0
    var max = coordinates.length
    var f = ~~(max/4)

      
    var wScale = d3.scaleLinear().domain([0, f]).range([0, width])
    var RwScale = d3.scaleLinear().domain([0, f]).range([width, 0])
    var hScale = d3.scaleLinear().domain([0, f]).range([0, height])
    var RhScale = d3.scaleLinear().domain([0, f]).range([height, 0])
      
	while (ii < max) {
        if (ii <= f){
            pp.push([ centroid[0]+wScale(ii), centroid[1] ])
        }
        else if (ii <= f*2){
            pp.push([ centroid[0]+width, centroid[1] + hScale(ii-f) ])
        }
        else if (ii <= f*3){
            pp.push([ centroid[0]+RwScale(ii-f*2), centroid[1]+height ])
        }
        else if (ii <= f*4){
            pp.push([ centroid[0], centroid[1]+RhScale(ii-f*3) ])
        }
        ii++
    }
    
	return pp

};