Simon Hunt

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
...@@ -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')
......