Zachary Tong 12 лет назад
Родитель
Сommit
f18b90a94e

+ 18 - 0
panels/map2/editor.html

@@ -184,6 +184,24 @@
     </div>
 </div>
 
+<div class="row-fluid tabDetails" ng-show="isActive('choropleth')">
+    <div class="span8 offset1">
+        <table>
+            <tbody  >
+            <tr>
+                <td>Choropleth</td>
+                <td>
+                    <button type="button" class="btn" bs-button
+                            ng-change="$emit('render')"
+                            ng-class="{'btn-success': panel.display.choropleth.enabled}"
+                            ng-model="panel.display.choropleth.enabled">{{panel.display.choropleth.enabled|enabledText}}</button>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+
 <div class="row-fluid tabDetails" ng-show="isActive('data')">
     <div class="span8 offset1">
         <table>

+ 1 - 0
panels/map2/lib/queue.v1.min.js

@@ -0,0 +1 @@
+(function(){function n(n){function t(){for(;f=a<c.length&&n>p;){var u=a++,t=c[u],r=l.call(t,1);r.push(e(u)),++p,t[0].apply(null,r)}}function e(n){return function(u,l){--p,null==d&&(null!=u?(d=u,a=s=0/0,r()):(c[n]=l,--s?f||t():r()))}}function r(){null!=d?v(d):i?v(d,c):v.apply(null,[d].concat(c))}var o,f,i,c=[],a=0,p=0,s=0,d=null,v=u;return n||(n=1/0),o={defer:function(){return d||(c.push(arguments),++s,t()),o},await:function(n){return v=n,i=!1,s||r(),o},awaitAll:function(n){return v=n,i=!0,s||r(),o}}}function u(){}"undefined"==typeof module?self.queue=n:module.exports=n,n.version="1.0.4";var l=[].slice})();

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
panels/map2/lib/topojson.v0.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
panels/map2/lib/topojson.v1.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
panels/map2/lib/world-110m.json


+ 251 - 0
panels/map2/lib/world-country-names.tsv

@@ -0,0 +1,251 @@
+id	short	name
+4	AF	Afghanistan
+8	AL	Albania
+10	AQ	Antarctica
+12	DZ	Algeria
+16	AS	American Samoa
+20	AD	Andorra
+24	AO	Angola
+28	AG	Antigua and Barbuda
+31	AZ	Azerbaijan
+32	AR	Argentina
+36	AU	Australia
+40	AT	Austria
+44	BS	Bahamas
+48	BH	Bahrain
+50	BD	Bangladesh
+51	AM	Armenia
+52	BB	Barbados
+56	BE	Belgium
+60	BM	Bermuda
+64	BT	Bhutan
+68	BO	Bolivia, Plurinational State of
+70	BA	Bosnia and Herzegovina
+72	BW	Botswana
+74	BV	Bouvet Island
+76	BR	Brazil
+84	BZ	Belize
+86	IO	British Indian Ocean Territory
+90	SB	Solomon Islands
+92	VG	Virgin Islands, British
+96	BN	Brunei Darussalam
+100	BG	Bulgaria
+104	MM	Myanmar
+108	BI	Burundi
+112	BY	Belarus
+116	KH	Cambodia
+120	CM	Cameroon
+124	CA	Canada
+132	CV	Cape Verde
+136	KY	Cayman Islands
+140	CF	Central African Republic
+144	LK	Sri Lanka
+148	TD	Chad
+152	CL	Chile
+156	CN	China
+158	TW	Taiwan, Province of China
+162	CX	Christmas Island
+166	CC	Cocos (Keeling) Islands
+170	CO	Colombia
+174	KM	Comoros
+175	YT	Mayotte
+178	CG	Congo
+180	CD	Congo, the Democratic Republic of the
+184	CK	Cook Islands
+188	CR	Costa Rica
+191	HR	Croatia
+192	CU	Cuba
+196	CY	Cyprus
+203	CZ	Czech Republic
+204	BJ	Benin
+208	DK	Denmark
+212	DM	Dominica
+214	DO	Dominican Republic
+218	EC	Ecuador
+222	SV	El Salvador
+226	GQ	Equatorial Guinea
+231	ET	Ethiopia
+232	ER	Eritrea
+233	EE	Estonia
+234	FO	Faroe Islands
+238	FK	Falkland Islands (Malvinas)
+239	GS	South Georgia and the South Sandwich Islands
+242	FJ	Fiji
+246	FI	Finland
+248	AX	Åland Islands
+250	FR	France
+254	GF	French Guiana
+258	PF	French Polynesia
+260	TF	French Southern Territories
+262	DJ	Djibouti
+266	GA	Gabon
+268	GE	Georgia
+270	GM	Gambia
+275		Palestinian Territory, Occupied
+276	DE	Germany
+288	GH	Ghana
+292	GI	Gibraltar
+296	KI	Kiribati
+300	GR	Greece
+304	GL	Greenland
+308	GD	Grenada
+312	GP	Guadeloupe
+316	GU	Guam
+320	GT	Guatemala
+324	GN	Guinea
+328	GY	Guyana
+332	HT	Haiti
+334	HM	Heard Island and McDonald Islands
+336	VA	Holy See (Vatican City State)
+340	HN	Honduras
+344	HK	Hong Kong
+348	HU	Hungary
+352	IS	Iceland
+356	IN	India
+360	ID	Indonesia
+364	IR	Iran, Islamic Republic of
+368	IQ	Iraq
+372	IE	Ireland
+376	IL	Israel
+380	IT	Italy
+384		Côte d'Ivoire
+388	JM	Jamaica
+392	JP	Japan
+398	KZ	Kazakhstan
+400	JO	Jordan
+404	KE	Kenya
+408	KP	Korea, Democratic People's Republic of
+410	KR	Korea, Republic of
+414	KW	Kuwait
+417	KG	Kyrgyzstan
+418	LA	Lao People's Democratic Republic
+422	LB	Lebanon
+426	LS	Lesotho
+428	LV	Latvia
+430	LR	Liberia
+434	LY	Libya
+438	LI	Liechtenstein
+440	LT	Lithuania
+442	LU	Luxembourg
+446	MO	Macao
+450	MG	Madagascar
+454	MW	Malawi
+458	MY	Malaysia
+462	MV	Maldives
+466	ML	Mali
+470	MT	Malta
+474	MQ	Martinique
+478	MR	Mauritania
+480	MU	Mauritius
+484	MX	Mexico
+492	MC	Monaco
+496	MN	Mongolia
+498	MD	Moldova, Republic of
+499	ME	Montenegro
+500	MS	Montserrat
+504	MA	Morocco
+508	MZ	Mozambique
+512	OM	Oman
+516	NA	Namibia
+520	NR	Nauru
+524	NP	Nepal
+528	NL	Netherlands
+531		Curaçao
+533	AW	Aruba
+534	SX	Sint Maarten (Dutch part)
+535	BQ	Bonaire, Sint Eustatius and Saba
+540	NC	New Caledonia
+548	VU	Vanuatu
+554	NZ	New Zealand
+558	NI	Nicaragua
+562	NE	Niger
+566	NG	Nigeria
+570	NU	Niue
+574	NF	Norfolk Island
+578	NO	Norway
+580	MP	Northern Mariana Islands
+581	UM	United States Minor Outlying Islands
+583	FM	Micronesia, Federated States of
+584	MH	Marshall Islands
+585	PW	Palau
+586	PK	Pakistan
+591	PA	Panama
+598	PG	Papua New Guinea
+600	PY	Paraguay
+604	PE	Peru
+608	PH	Philippines
+612	PN	Pitcairn
+616	PL	Poland
+620	PT	Portugal
+624	GW	Guinea-Bissau
+626	TL	Timor-Leste
+630	PR	Puerto Rico
+634	QA	Qatar
+638		Réunion
+642	RO	Romania
+643	RU	Russian Federation
+646	RW	Rwanda
+652		Saint Barthélemy
+654	SH	Saint Helena, Ascension and Tristan da Cunha
+659	KN	Saint Kitts and Nevis
+660	AI	Anguilla
+662	LC	Saint Lucia
+663	MF	Saint Martin (French part)
+666	PM	Saint Pierre and Miquelon
+670	VC	Saint Vincent and the Grenadines
+674	SM	San Marino
+678	ST	Sao Tome and Principe
+682	SA	Saudi Arabia
+686	SN	Senegal
+688	RS	Serbia
+690	SC	Seychelles
+694	SL	Sierra Leone
+702	SG	Singapore
+703	SK	Slovakia
+704	VN	Viet Nam
+705	SI	Slovenia
+706	SO	Somalia
+710	ZA	South Africa
+716	ZW	Zimbabwe
+724	ES	Spain
+728	SS	South Sudan
+729	SD	Sudan
+732	EH	Western Sahara
+740	SR	Suriname
+744	SJ	Svalbard and Jan Mayen
+748	SZ	Swaziland
+752	SE	Sweden
+756	CH	Switzerland
+760	SY	Syrian Arab Republic
+762	TJ	Tajikistan
+764	TH	Thailand
+768	TG	Togo
+772	TK	Tokelau
+776	TO	Tonga
+780	TT	Trinidad and Tobago
+784	AE	United Arab Emirates
+788	TN	Tunisia
+792	TR	Turkey
+795	TM	Turkmenistan
+796	TC	Turks and Caicos Islands
+798	TV	Tuvalu
+800	UG	Uganda
+804	UA	Ukraine
+807	MK	Macedonia, the former Yugoslav Republic of
+818	EG	Egypt
+826	GB	United Kingdom
+831	GG	Guernsey
+832	JE	Jersey
+833	IM	Isle of Man
+834	TZ	Tanzania, United Republic of
+840	US	United States
+850	VI	Virgin Islands, U.S.
+854	BF	Burkina Faso
+858	UY	Uruguay
+860	UZ	Uzbekistan
+862	VE	Venezuela, Bolivarian Republic of
+876	WF	Wallis and Futuna
+882	WS	Samoa
+887	YE	Yemen
+894	ZM	Zambia
+		

+ 10 - 0
panels/map2/module.html

@@ -22,6 +22,16 @@
             stroke-width: .1px;
         }
 
+        .q1 { fill:rgb(247,251,255); }
+        .q2 { fill:rgb(222,235,247); }
+        .q3 { fill:rgb(198,219,239); }
+        .q4 { fill:rgb(158,202,225); }
+        .q5 { fill:rgb(107,174,214); }
+        .q6 { fill:rgb(66,146,198); }
+        .q7 { fill:rgb(33,113,181); }
+        .q8 { fill:rgb(8,81,156); }
+        .q9 { fill:rgb(8,48,107); }
+
     </style>
   <span ng-show="panel.spyable" style="position:absolute;right:0px;top:0px" class='panelextra pointer'>
     <i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>

+ 207 - 138
panels/map2/module.js

@@ -31,9 +31,12 @@ angular.module('kibana.map2', [])
                     areaEncodingField: "primary",
                     colorEncoding: true,
                     colorEncodingField: "primary"
+                },
+                choropleth: {
+                    enabled: false
                 }
             },
-            displayTabs: ["Geopoints", "Binning", "Data"],
+            displayTabs: ["Geopoints", "Binning", "Choropleth", "Data"],
             activeDisplayTab:"Geopoints"
         };
 
@@ -187,6 +190,9 @@ angular.module('kibana.map2', [])
 
                 elem.html('<center><img src="common/img/load_big.gif"></center>')
 
+                var worldData = null,
+                    worldNames = null;
+
                 // Receive render events
                 scope.$on('render', function () {
                     console.log("render");
@@ -200,191 +206,254 @@ angular.module('kibana.map2', [])
                 });
 
                 function render_panel() {
-                    //console.log("render_panel");
-                    //console.log(scope.panel);
-                    //console.log(elem);
+ 
 
                     // Using LABjs, wait until all scripts are loaded before rendering panel
                     var scripts = $LAB.script("panels/map2/lib/d3.v3.min.js")
-                        .script("panels/map2/lib/topojson.v0.min.js")
+                        .script("panels/map2/lib/topojson.v1.min.js")
                         .script("panels/map2/lib/node-geohash.js")
-                        .script("panels/map2/lib/d3.hexbin.v0.min.js");
+                        .script("panels/map2/lib/d3.hexbin.v0.min.js")
+                        .script("panels/map2/lib/queue.v1.min.js");
 
                     // Populate element. Note that jvectormap appends, does not replace.
                     scripts.wait(function () {
                         elem.text('');
 
-                        //Better way to get these values?  Seems kludgy to use jQuery on the div...
-                        var width = $(elem[0]).width(),
-                            height = $(elem[0]).height();
+                        if (worldData === null || worldNames === null) {
+                            queue()
+                                .defer(d3.json, "panels/map2/lib/world-110m.json")
+                                .defer(d3.tsv, "panels/map2/lib/world-country-names.tsv")
+                                .await(function(error, world, names) {
+                                    worldData = world;
+                                    worldNames = names;
+                                    ready();
+                                });
+                        } else {
+                            ready();
+                        }
+
+
+                    });
+                }
+
+                function ready() {
+
+                    var world = worldData,
+                        names = worldNames;
+
+                    //Better way to get these values?  Seems kludgy to use jQuery on the div...
+                    var width = $(elem[0]).width(),
+                        height = $(elem[0]).height();
+
+                    console.log("draw map", width, height);
+
+
+                    var scale = (width > height) ? (height / 2 / Math.PI) : (width / 2 / Math.PI);
 
-                        console.log("draw map", width, height);
+                    var projection = d3.geo.mercator()
+                        .translate([0,0])
+                        .scale(scale);
 
+                    var zoom = d3.behavior.zoom()
+                        .scaleExtent([1, 8])
+                        .on("zoom", move);
 
-                        var scale = (width > height) ? (height / 2 / Math.PI) : (width / 2 / Math.PI);
+                    var path = d3.geo.path()
+                        .projection(projection);
 
-                        var projection = d3.geo.mercator()
-                            .translate([0,0])
-                            .scale(scale);
+                    var svg = d3.select(elem[0]).append("svg")
+                        .attr("width", width)
+                        .attr("height", height)
+                        .append("g")
+                        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
+                        .call(zoom);
 
-                        var zoom = d3.behavior.zoom()
-                            .scaleExtent([1, 8])
-                            .on("zoom", move);
+                    var g = svg.append("g");
 
-                        var path = d3.geo.path()
-                            .projection(projection);
+                    svg.append("rect")
+                        .attr("class", "overlay")
+                        .attr("x", -width / 2)
+                        .attr("y", -height / 2)
+                        .attr("width", width)
+                        .attr("height", height);
 
-                        var svg = d3.select(elem[0]).append("svg")
-                            .attr("width", width)
-                            .attr("height", height)
-                            .append("g")
-                            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
-                            .call(zoom);
+                    /*
+                    d3.json("panels/map2/lib/world-50m.json", function (error, world) {
+                        g.append("path")
+                            .datum(topojson.object(world, world.objects.countries))
+                            .attr("class", "land")
+                            .attr("d", path);
 
-                        var g = svg.append("g");
+                     g.append("path")
+                     .datum(topojson.mesh(world, world.objects.countries, function (a, b) {
+                     return a !== b;
+                     }))
+                     .attr("class", "boundary")
+                     .attr("d", path);
+                    */
+
+
+                    console.log(world);
+                    console.log("feature", topojson.feature(world, world.objects.countries));
+
+                    var countries = topojson.feature(world, world.objects.countries).features;
+
+                    countries = countries.filter(function(d) {
+                        return names.some(function(n) {
+                            if (d.id == n.id) {
+                                d.name = n.name;
+                                return d.short = n.short;
+                            }
+                        });
+                    }).sort(function(a, b) {
+                        return a.name.localeCompare(b.name);
+                    });
+
+
+                    var quantize = d3.scale.quantize()
+                        .domain([0, 1000])
+                        .range(d3.range(9).map(function(i) { return "q" + (i+1); }));
+
+
+                    g.selectAll("path")
+                        .data(countries)
+                        .enter().append("path")
+                        .attr("class", function(d) {
+                            if (scope.panel.display.choropleth.enabled) {
+                                return 'land ' + quantize(scope.data[d.short]);
+                            } else {
+                                return 'land';
+                            }
+                        })
+                        .attr("d", path);
 
-                        svg.append("rect")
-                            .attr("class", "overlay")
-                            .attr("x", -width / 2)
-                            .attr("y", -height / 2)
-                            .attr("width", width)
-                            .attr("height", height);
+                    g.append("path")
+                        .datum(topojson.mesh(world, world.objects.land, function(a, b) { return a !== b; }))
+                        .attr("class", "land boundary")
+                        .attr("d", path);
 
-                        d3.json("panels/map2/lib/world-50m.json", function (error, world) {
-                            g.append("path")
-                                .datum(topojson.object(world, world.objects.countries))
-                                .attr("class", "land")
-                                .attr("d", path);
 
-                            g.append("path")
-                                .datum(topojson.mesh(world, world.objects.countries, function (a, b) {
-                                    return a !== b;
-                                }))
-                                .attr("class", "boundary")
-                                .attr("d", path);
 
+                    //Geocoded points are decoded into lat/lon, then projected onto x/y
+                    points = _.map(scope.data, function (k, v) {
+                        var decoded = geohash.decode(v);
+                        return projection([decoded.longitude, decoded.latitude]);
+                    });
 
 
+                    //hexagonal binning
+                    if (scope.panel.display.binning.enabled) {
 
+                        var binPoints = [];
 
-                            //Geocoded points are decoded into lat/lon, then projected onto x/y
-                            points = _.map(scope.data, function (k, v) {
+                        //primary field is just binning raw counts
+                        //secondary field is binning some metric like mean/median/total.  Hexbins doesn't support that,
+                        //so we cheat a little and just add more points to compensate.
+                        //However, we don't want to add a million points, so normalize against the largest value
+                        if (scope.panel.display.binning.areaEncodingField === 'secondary') {
+                            var max = Math.max.apply(Math, _.map(scope.data, function(k,v){return k;})),
+                                scale = 10/max;
+
+                            _.map(scope.data, function (k, v) {
                                 var decoded = geohash.decode(v);
-                                return projection([decoded.longitude, decoded.latitude]);
+                                return _.map(_.range(0, k*scale), function(a,b) {
+                                    binPoints.push(projection([decoded.longitude, decoded.latitude]));
+                                })
                             });
 
+                        } else {
+                            binPoints = points;
+                        }
+
+
+                        var hexbin = d3.hexbin()
+                            .size([width, height])
+                            .radius(scope.panel.display.binning.hexagonSize);
+
+                        //bin and sort the points, so we can set the various ranges appropriately
+                        var binnedPoints = hexbin(binPoints).sort(function(a, b) { return b.length - a.length; });;
+console.log("binnedpoints",binnedPoints);
+                        //clean up some memory
+                        binPoints = [];
 
-                            //hexagonal binning
-                            if (scope.panel.display.binning.enabled) {
 
-                                var binPoints = [];
+                        var radius = d3.scale.sqrt()
+                            .domain([0, binnedPoints[0].length])
+                            .range([0, scope.panel.display.binning.hexagonSize]);
 
-                                //primary field is just binning raw counts
-                                //secondary field is binning some metric like mean/median/total.  Hexbins doesn't support that,
-                                //so we cheat a little and just add more points to compensate.
-                                //However, we don't want to add a million points, so normalize against the largest value
-                                if (scope.panel.display.binning.areaEncodingField === 'secondary') {
-                                    var max = Math.max.apply(Math, _.map(scope.data, function(k,v){return k;})),
-                                        scale = 10/max;
 
-                                    _.map(scope.data, function (k, v) {
-                                        var decoded = geohash.decode(v);
-                                        return _.map(_.range(0, k*scale), function(a,b) {
-                                            binPoints.push(projection([decoded.longitude, decoded.latitude]));
-                                        })
-                                    });
+                        var color = d3.scale.linear()
+                            .domain([0,binnedPoints[0].length])
+                            .range(["white", "steelblue"])
+                            .interpolate(d3.interpolateLab);
 
+                        g.selectAll(".hexagon")
+                            .data(binnedPoints)
+                            .enter().append("path")
+                            .attr("d", function (d) {
+                                if (scope.panel.display.binning.areaEncoding === false) {
+                                    return hexbin.hexagon();
                                 } else {
-                                    binPoints = points;
+                                    return hexbin.hexagon(radius(d.length));
                                 }
+                            })
+                            .attr("class", "hexagon")
+                            .attr("transform", function (d) {
+                                return "translate(" + d.x + "," + d.y + ")";
+                            })
+                            .style("fill", function (d) {
+                                if (scope.panel.display.binning.colorEncoding === false) {
+                                    return color(binnedPoints[0].length / 2);
+                                } else {
+                                    return color(d.length);
+                                }
+                            })
+                            .attr("opacity", scope.panel.display.binning.hexagonAlpha);
+                    }
 
 
-                                var hexbin = d3.hexbin()
-                                    .size([width, height])
-                                    .radius(scope.panel.display.binning.hexagonSize);
+                    //Raw geopoints
+                    if (scope.panel.display.geopoints.enabled) {
+                        g.selectAll("circles.points")
+                            .data(points)
+                            .enter()
+                            .append("circle")
+                            .attr("r", scope.panel.display.geopoints.pointSize)
+                            .attr("opacity", scope.panel.display.geopoints.pointAlpha)
+                            .attr("transform", function (d) {
+                                return "translate(" + d[0] + "," + d[1] + ")";
+                            });
+                    }
+
 
-                                //bin and sort the points, so we can set the various ranges appropriately
-                                var binnedPoints = hexbin(binPoints).sort(function(a, b) { return b.length - a.length; });;
-console.log("binnedpoints",binnedPoints);
-                                //clean up some memory
-                                binPoints = [];
-
-
-                                var radius = d3.scale.sqrt()
-                                    .domain([0, binnedPoints[0].length])
-                                    .range([0, scope.panel.display.binning.hexagonSize]);
-
-
-                                var color = d3.scale.linear()
-                                    .domain([0,binnedPoints[0].length])
-                                    .range(["white", "steelblue"])
-                                    .interpolate(d3.interpolateLab);
-
-                                g.selectAll(".hexagon")
-                                    .data(binnedPoints)
-                                    .enter().append("path")
-                                    .attr("d", function (d) {
-                                        if (scope.panel.display.binning.areaEncoding === false) {
-                                            return hexbin.hexagon();
-                                        } else {
-                                            return hexbin.hexagon(radius(d.length));
-                                        }
-                                    })
-                                    .attr("class", "hexagon")
-                                    .attr("transform", function (d) {
-                                        return "translate(" + d.x + "," + d.y + ")";
-                                    })
-                                    .style("fill", function (d) {
-                                        if (scope.panel.display.binning.colorEncoding === false) {
-                                            return color(binnedPoints[0].length / 2);
-                                        } else {
-                                            return color(d.length);
-                                        }
-                                    })
-                                    .attr("opacity", scope.panel.display.binning.hexagonAlpha);
-                            }
+                    console.log("initial", scope.panel.display.scale, scope.panel.display.translate);
 
+                    if (scope.panel.display.scale != -1) {
+                        zoom.scale(scope.panel.display.scale).translate(scope.panel.display.translate);
+                        g.style("stroke-width", 1 / scope.panel.display.scale).attr("transform", "translate(" + scope.panel.display.translate + ") scale(" + scope.panel.display.scale + ")");
+                        //svg.redraw();
+                    }
 
-                            //Raw geopoints
-                            if (scope.panel.display.geopoints.enabled) {
-                                g.selectAll("circles.points")
-                                    .data(points)
-                                    .enter()
-                                    .append("circle")
-                                    .attr("r", scope.panel.display.geopoints.pointSize)
-                                    .attr("opacity", scope.panel.display.geopoints.pointAlpha)
-                                    .attr("transform", function (d) {
-                                        return "translate(" + d[0] + "," + d[1] + ")";
-                                    });
-                            }
+                    function move() {
+                        var t = d3.event.translate,
+                            s = d3.event.scale;
+                        t[0] = Math.min(width / 2 * (s - 1), Math.max(width / 2 * (1 - s), t[0]));
+                        t[1] = Math.min(height / 2 * (s - 1) + 230 * s, Math.max(height / 2 * (1 - s) - 230 * s, t[1]));
+                        zoom.translate(t);
 
+                        scope.panel.display.translate = t;
+                        scope.panel.display.scale = s;
+                        g.style("stroke-width", 1 / s).attr("transform", "translate(" + t + ")scale(" + s + ")");
 
-                            console.log("initial", scope.panel.display.scale, scope.panel.display.translate);
+                        //console.log("move", scope.panel.display.scale, scope.panel.display.translate);
+                    }
 
-                            if (scope.panel.display.scale != -1) {
-                                zoom.scale(scope.panel.display.scale).translate(scope.panel.display.translate);
-                                g.style("stroke-width", 1 / scope.panel.display.scale).attr("transform", "translate(" + scope.panel.display.translate + ") scale(" + scope.panel.display.scale + ")");
-                                //svg.redraw();
-                            }
+                        }
 
-                        });
 
-                        function move() {
-                            var t = d3.event.translate,
-                                s = d3.event.scale;
-                            t[0] = Math.min(width / 2 * (s - 1), Math.max(width / 2 * (1 - s), t[0]));
-                            t[1] = Math.min(height / 2 * (s - 1) + 230 * s, Math.max(height / 2 * (1 - s) - 230 * s, t[1]));
-                            zoom.translate(t);
 
-                            scope.panel.display.translate = t;
-                            scope.panel.display.scale = s;
-                            g.style("stroke-width", 1 / s).attr("transform", "translate(" + t + ")scale(" + s + ")");
 
-                            console.log("move", scope.panel.display.scale, scope.panel.display.translate);
-                        }
 
-                    })
-                }
 
             }
         };

Некоторые файлы не были показаны из-за большого количества измененных файлов