GUI -- Clarified math used for computing scaling and translation of US map.
- Increased zoom bounds to be able to zoom out further, and zoom in further. Change-Id: I4ad3dca8edd1986034dec57cad6d19f80753daea
Showing
1 changed file
with
35 additions
and
31 deletions
... | @@ -108,12 +108,6 @@ | ... | @@ -108,12 +108,6 @@ |
108 | charge: { | 108 | charge: { |
109 | device: -8000, | 109 | device: -8000, |
110 | host: -5000 | 110 | host: -5000 |
111 | - }, | ||
112 | - pad: 20, | ||
113 | - translate: function() { | ||
114 | - return 'translate(' + | ||
115 | - config.force.pad + ',' + | ||
116 | - config.force.pad + ')'; | ||
117 | } | 111 | } |
118 | }, | 112 | }, |
119 | // see below in creation of viewBox on main svg | 113 | // see below in creation of viewBox on main svg |
... | @@ -231,7 +225,7 @@ | ... | @@ -231,7 +225,7 @@ |
231 | mask; | 225 | mask; |
232 | 226 | ||
233 | // the projection for the map background | 227 | // the projection for the map background |
234 | - var geoMapProjection; | 228 | + var geoMapProj; |
235 | 229 | ||
236 | // the zoom function | 230 | // the zoom function |
237 | var zoom; | 231 | var zoom; |
... | @@ -1614,7 +1608,7 @@ | ... | @@ -1614,7 +1608,7 @@ |
1614 | 1608 | ||
1615 | var location = node.location; | 1609 | var location = node.location; |
1616 | if (location && location.type === 'latlng') { | 1610 | if (location && location.type === 'latlng') { |
1617 | - var coord = geoMapProjection([location.lng, location.lat]); | 1611 | + var coord = geoMapProj([location.lng, location.lat]); |
1618 | node.fixed = true; | 1612 | node.fixed = true; |
1619 | node.px = node.x = coord[0]; | 1613 | node.px = node.x = coord[0]; |
1620 | node.py = node.y = coord[1]; | 1614 | node.py = node.y = coord[1]; |
... | @@ -2578,7 +2572,7 @@ | ... | @@ -2578,7 +2572,7 @@ |
2578 | zoom = d3.behavior.zoom() | 2572 | zoom = d3.behavior.zoom() |
2579 | .translate([0, 0]) | 2573 | .translate([0, 0]) |
2580 | .scale(1) | 2574 | .scale(1) |
2581 | - .scaleExtent([1, 8]) | 2575 | + .scaleExtent([0.25, 10]) |
2582 | .on("zoom", zoomed); | 2576 | .on("zoom", zoomed); |
2583 | 2577 | ||
2584 | svg.call(zoom); | 2578 | svg.call(zoom); |
... | @@ -2631,7 +2625,7 @@ | ... | @@ -2631,7 +2625,7 @@ |
2631 | ll; | 2625 | ll; |
2632 | 2626 | ||
2633 | if (store) { | 2627 | if (store) { |
2634 | - ll = geoMapProjection.invert([d.x, d.y]); | 2628 | + ll = geoMapProj.invert([d.x, d.y]); |
2635 | metaUi = { | 2629 | metaUi = { |
2636 | x: d.x, | 2630 | x: d.x, |
2637 | y: d.y, | 2631 | y: d.y, |
... | @@ -2653,9 +2647,7 @@ | ... | @@ -2653,9 +2647,7 @@ |
2653 | function preload(view, ctx, flags) { | 2647 | function preload(view, ctx, flags) { |
2654 | var w = view.width(), | 2648 | var w = view.width(), |
2655 | h = view.height(), | 2649 | h = view.height(), |
2656 | - fcfg = config.force, | 2650 | + fcfg = config.force; |
2657 | - fpad = fcfg.pad, | ||
2658 | - forceDim = [w - 2*fpad, h - 2*fpad]; | ||
2659 | 2651 | ||
2660 | // NOTE: view.$div is a D3 selection of the view's div | 2652 | // NOTE: view.$div is a D3 selection of the view's div |
2661 | var viewBox = '0 0 ' + config.logicalSize + ' ' + config.logicalSize; | 2653 | var viewBox = '0 0 ' + config.logicalSize + ' ' + config.logicalSize; |
... | @@ -2671,8 +2663,7 @@ | ... | @@ -2671,8 +2663,7 @@ |
2671 | 2663 | ||
2672 | // group for the topology | 2664 | // group for the topology |
2673 | topoG = panZoomContainer.append('g') | 2665 | topoG = panZoomContainer.append('g') |
2674 | - .attr('id', 'topo-G') | 2666 | + .attr('id', 'topo-G'); |
2675 | - .attr('transform', fcfg.translate()); | ||
2676 | 2667 | ||
2677 | // subgroups for links, link labels, and nodes | 2668 | // subgroups for links, link labels, and nodes |
2678 | linkG = topoG.append('g').attr('id', 'links'); | 2669 | linkG = topoG.append('g').attr('id', 'links'); |
... | @@ -2720,7 +2711,7 @@ | ... | @@ -2720,7 +2711,7 @@ |
2720 | 2711 | ||
2721 | // set up the force layout | 2712 | // set up the force layout |
2722 | network.force = d3.layout.force() | 2713 | network.force = d3.layout.force() |
2723 | - .size(forceDim) | 2714 | + .size([w, h]) |
2724 | .nodes(network.nodes) | 2715 | .nodes(network.nodes) |
2725 | .links(network.links) | 2716 | .links(network.links) |
2726 | .gravity(0.4) | 2717 | .gravity(0.4) |
... | @@ -2856,6 +2847,31 @@ | ... | @@ -2856,6 +2847,31 @@ |
2856 | }); | 2847 | }); |
2857 | } | 2848 | } |
2858 | 2849 | ||
2850 | + function setProjForView(path, topoData) { | ||
2851 | + var dim = config.logicalSize; | ||
2852 | + | ||
2853 | + // start with unit scale, no translation.. | ||
2854 | + geoMapProj.scale(1).translate([0, 0]); | ||
2855 | + | ||
2856 | + // figure out dimensions of map data.. | ||
2857 | + var b = path.bounds(topoData), | ||
2858 | + x1 = b[0][0], | ||
2859 | + y1 = b[0][1], | ||
2860 | + x2 = b[1][0], | ||
2861 | + y2 = b[1][1], | ||
2862 | + dx = x2 - x1, | ||
2863 | + dy = y2 - y1, | ||
2864 | + x = (x1 + x2) / 2, | ||
2865 | + y = (y1 + y2) / 2; | ||
2866 | + | ||
2867 | + // size map to 95% of minimum dimension to fill space.. | ||
2868 | + var s = .95 / Math.min(dx / dim, dy / dim); | ||
2869 | + var t = [dim / 2 - s * x, dim / 2 - s * y]; | ||
2870 | + | ||
2871 | + // set new scale, translation on the projection.. | ||
2872 | + geoMapProj.scale(s).translate(t); | ||
2873 | + } | ||
2874 | + | ||
2859 | function loadGeoMap() { | 2875 | function loadGeoMap() { |
2860 | fnTrace('loadGeoMap', geoJsonUrl); | 2876 | fnTrace('loadGeoMap', geoJsonUrl); |
2861 | 2877 | ||
... | @@ -2863,22 +2879,10 @@ | ... | @@ -2863,22 +2879,10 @@ |
2863 | var topoData = topojson.feature(geoJson, geoJson.objects.states); | 2879 | var topoData = topojson.feature(geoJson, geoJson.objects.states); |
2864 | 2880 | ||
2865 | // see: http://bl.ocks.org/mbostock/4707858 | 2881 | // see: http://bl.ocks.org/mbostock/4707858 |
2866 | - geoMapProjection = d3.geo.mercator(); | 2882 | + geoMapProj = d3.geo.mercator(); |
2867 | - var path = d3.geo.path().projection(geoMapProjection); | 2883 | + var path = d3.geo.path().projection(geoMapProj); |
2868 | - | ||
2869 | - geoMapProjection | ||
2870 | - .scale(1) | ||
2871 | - .translate([0, 0]); | ||
2872 | - | ||
2873 | - // [[x1,y1],[x2,y2]] | ||
2874 | - var b = path.bounds(topoData); | ||
2875 | - // size map to 95% of minimum dimension to fill space | ||
2876 | - var s = .95 / Math.min((b[1][0] - b[0][0]) / config.logicalSize, (b[1][1] - b[0][1]) / config.logicalSize); | ||
2877 | - var t = [(config.logicalSize - s * (b[1][0] + b[0][0])) / 2, (config.logicalSize - s * (b[1][1] + b[0][1])) / 2]; | ||
2878 | 2884 | ||
2879 | - geoMapProjection | 2885 | + setProjForView(path, topoData); |
2880 | - .scale(s) | ||
2881 | - .translate(t); | ||
2882 | 2886 | ||
2883 | bgImg = panZoomContainer.insert("g", '#topo-G'); | 2887 | bgImg = panZoomContainer.insert("g", '#topo-G'); |
2884 | bgImg.attr('id', 'map').selectAll('path') | 2888 | bgImg.attr('id', 'map').selectAll('path') | ... | ... |
-
Please register or login to post a comment