パストランジションのサンプル。
左:パスの頂点数を調整していないもの。 右:パスの頂点数を揃えたもの。
Built with blockbuilder.org
| license: mit |
パストランジションのサンプル。
左:パスの頂点数を調整していないもの。 右:パスの頂点数を揃えたもの。
Built with blockbuilder.org
| if(!d3.geo2square) d3.geo2square = function(coordinates, width, height) { | |
| var centroid =d3.polygonCentroid(coordinates) | |
| width = (width) ? width : 0 ; | |
| height = (height) ? height : 0 ; | |
| var p = [] | |
| var i = 0 | |
| var length = coordinates.length | |
| var qtr = ~~(length/4) | |
| var nScale = d3.scaleLinear().domain([0, qtr]).range([0, width]) | |
| var sScale = d3.scaleLinear().domain([0, qtr]).range([width, 0]) | |
| var wScale = d3.scaleLinear().domain([0, qtr]).range([0, height]) | |
| var eScale = d3.scaleLinear().domain([0, qtr]).range([height, 0]) | |
| while (i < length) { | |
| if (i <= qtr){ | |
| p.push([ centroid[0]+nScale(i), centroid[1] ]) | |
| } | |
| else if (i <= qtr*2){ | |
| p.push([ centroid[0]+width, centroid[1] + wScale(i-qtr) ]) | |
| } | |
| else if (i <= qtr*3){ | |
| p.push([ centroid[0]+sScale(i-qtr*2), centroid[1]+height ]) | |
| } | |
| else if (i <= qtr*4){ | |
| p.push([ centroid[0], centroid[1]+eScale(i-qtr*3) ]) | |
| } | |
| i++ | |
| } | |
| return p | |
| }; |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"/> | |
| <title>Path トランジション</title> | |
| <style> | |
| html, body { | |
| width: 100%; | |
| height: 100%; | |
| padding:0px; | |
| margin:0px; | |
| } | |
| .wrapper { | |
| width: 49.75%; | |
| height: 100%; | |
| border: 1px solid black; | |
| float:left; | |
| } | |
| svg { | |
| width: 100%; | |
| height: 90%; | |
| } | |
| .button { | |
| background-color: #4CAF50; | |
| border: none; | |
| color: white; | |
| padding: 10px 32px; | |
| text-align: center; | |
| text-decoration: none; | |
| display: inline-block; | |
| font-size: 16px; | |
| border-top: 1px solid #ccc; | |
| border-right: 1px solid #999; | |
| border-bottom: 1px solid #999; | |
| border-left: 1px solid #ccc; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="wrapper"> | |
| <button id="run1" class="button">transiton >></button> | |
| <svg id="example1"></svg> | |
| </div> | |
| <div class="wrapper"> | |
| <button id="run2" class="button">transiton >></button> | |
| <svg id="example2"></svg> | |
| </div> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script> | |
| <script src="d3.geo2square.js"></script> | |
| <script> | |
| !(function(){ | |
| var svg = d3.select("#example1") | |
| var width = svg.node().clientWidth | |
| var height = svg.node().clientHeight | |
| var sqHeight = height -20 | |
| var sqHeight = height -20 | |
| var projection = d3.geoMercator() | |
| var geoPath = d3.geoPath().projection(projection) | |
| d3.json("gunma.geojson",main) | |
| function main(geo) { | |
| var linedata = [ | |
| {x:10, y:10}, | |
| {x:sqHeight, y:10}, | |
| {x:sqHeight, y:sqHeight}, | |
| {x:10, y:sqHeight}, | |
| {x:10, y:10}, | |
| ] | |
| var line = d3.line() | |
| .x(function(d) { return d.x }) | |
| .y(function(d) { return d.y }) | |
| projection.fitExtent([[0, 0], [width, height]], geo) | |
| var path = svg.append("path") | |
| .attr("fill", "none") | |
| .attr("fill-opacity", 0.8) | |
| .attr("stroke", "blue") | |
| .attr("stroke-width", 2) | |
| var data = {} | |
| geo.features.forEach(function(d){ | |
| data.geoPath = geoPath(d) | |
| data.squarePath = line(linedata) | |
| }) | |
| var drawMaps = function(data) { | |
| path | |
| .transition().duration(1000) | |
| .attr("d", data.geoPath) | |
| } | |
| var drawSquare = function(data) { | |
| path | |
| .transition().duration(1000) | |
| .attr("d", data.squarePath) | |
| } | |
| toggleFn = toggle(function(){ | |
| drawSquare(data) | |
| }, | |
| function(){ | |
| drawMaps(data) | |
| }) | |
| d3.select("#run1").on("click", toggleFn) | |
| drawMaps(data) | |
| } | |
| }()) | |
| !(function(){ | |
| var svg = d3.select("#example2") | |
| var width = svg.node().clientWidth | |
| var height = svg.node().clientHeight | |
| var sqHeight = height -20 | |
| var projection = d3.geoMercator() | |
| var geoPath = d3.geoPath().projection(projection) | |
| d3.json("gunma.geojson",main) | |
| function main(geo) { | |
| var line = d3.line() | |
| .x(function(d) { return d[0] }) | |
| .y(function(d) { return d[1] }) | |
| projection.fitExtent([[0, 0], [width, height]], geo) | |
| var path = svg.append("path") | |
| .attr("fill", "none") | |
| .attr("fill-opacity", 0.8) | |
| .attr("stroke", "blue") | |
| .attr("stroke-width", 2) | |
| var data = {} | |
| geo.features.forEach(function(d){ | |
| data.geoPath = geoPath(d) | |
| data.squarePath = line(d3.geo2square(d.geometry.coordinates[0].map(projection), sqHeight, sqHeight)) | |
| var center = geoPath.centroid(d.geometry); | |
| var x = center[0]; | |
| var y = center[1]; | |
| var nx = 10 | |
| var ny = 10 | |
| data.center = {x:x, y:y, nx:nx, ny:ny} | |
| }) | |
| var drawMaps = function(data) { | |
| path | |
| .transition().duration(1000) | |
| .attr("d", data.geoPath) | |
| .attr("transform", 'translate(0,0)') | |
| } | |
| var drawSquare = function(data) { | |
| path | |
| .transition().duration(1000) | |
| .attr("d", data.squarePath) | |
| .attr("transform", 'translate('+(0-data.center.x)+','+(0-data.center.y)+'),translate('+data.center.nx+','+data.center.ny+')') | |
| } | |
| toggleFn = toggle(function(){ | |
| drawSquare(data) | |
| }, | |
| function(){ | |
| drawMaps(data) | |
| }) | |
| d3.select("#run2").on("click", toggleFn) | |
| drawMaps(data) | |
| } | |
| }()) | |
| function toggle(){ | |
| var fn = arguments; | |
| var l = arguments.length; | |
| var i = 0; | |
| return function(){ | |
| if(l <= i) i=0; | |
| fn[i++](); | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> |