Commit 37161ba3 by Zachary Tong

Fix bug with duplicate svgs being appended

parent 4f3f29b8
function displayBinning() { function displayBinning(scope, dimensions, projection) {
/** /**
* Hexbin-specific setup * Hexbin-specific setup
*/ */
var hexbin = d3.hexbin() var hexbin = d3.hexbin()
.size([width, height]) .size(dimensions)
.radius(scope.panel.display.binning.hexagonSize); .radius(scope.panel.display.binning.hexagonSize);
...@@ -16,7 +16,7 @@ function displayBinning() { ...@@ -16,7 +16,7 @@ function displayBinning() {
//However, we don't want to add a million points, so normalize against the largest value //However, we don't want to add a million points, so normalize against the largest value
if (scope.panel.display.binning.areaEncodingField === 'secondary') { if (scope.panel.display.binning.areaEncodingField === 'secondary') {
var max = Math.max.apply(Math, _.map(scope.data, function(k,v){return k;})), var max = Math.max.apply(Math, _.map(scope.data, function(k,v){return k;})),
scale = 10/max; scale = 50/max;
_.map(scope.data, function (k, v) { _.map(scope.data, function (k, v) {
var decoded = geohash.decode(v); var decoded = geohash.decode(v);
...@@ -50,7 +50,7 @@ function displayBinning() { ...@@ -50,7 +50,7 @@ function displayBinning() {
*/ */
g.selectAll(".hexagon") scope.g.selectAll(".hexagon")
.data(binnedPoints) .data(binnedPoints)
.enter().append("path") .enter().append("path")
.attr("d", function (d) { .attr("d", function (d) {
......
function displayGeopoints() { function displayGeopoints(scope) {
g.selectAll("circles.points") scope.g.selectAll("circles.points")
.data(points) .data(points)
.enter() .enter()
.append("circle") .append("circle")
......
...@@ -8,17 +8,18 @@ ...@@ -8,17 +8,18 @@
padding-bottom:10px; padding-bottom:10px;
} }
</style> </style>
<div class="row-fluid" ng-controller="map2"> <div ng-controller="map2">
<div class="row-fluid" >
<div class="span11"> <div class="span11">
The map panel uses 2 letter country or US state codes to plot concentrations The map panel uses 2 letter country or US state codes to plot concentrations
on a map. Darker terroritories mean more records matched that area. If on a map. Darker terroritories mean more records matched that area. If
multiple queries are sent from a single panel the <strong>first query will be multiple queries are sent from a single panel the <strong>first query will be
displayed</strong> displayed</strong>
</div> </div>
</div> </div>
<div class="row-fluid"> <div class="row-fluid">
<div class="span10"> <div class="span10">
<form class="form-horizontal"> <form class="form-horizontal">
<div class="control-group"> <div class="control-group">
...@@ -48,8 +49,8 @@ ...@@ -48,8 +49,8 @@
</div> </div>
</form> </form>
</div> </div>
</div> </div>
<div class="row-fluid"> <div class="row-fluid">
<div class="span11"> <div class="span11">
<h4>Display Options</h4> <h4>Display Options</h4>
</div> </div>
...@@ -65,9 +66,9 @@ ...@@ -65,9 +66,9 @@
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<div class="row-fluid tabDetails" ng-show="isActive('geopoints')"> <div class="row-fluid tabDetails" ng-show="isActive('geopoints')">
<div class="span8 offset1"> <div class="span8 offset1">
<table> <table>
<tbody > <tbody >
...@@ -108,15 +109,16 @@ ...@@ -108,15 +109,16 @@
<input type="checkbox" <input type="checkbox"
ng-change="$emit('render')" ng-change="$emit('render')"
data-placement="right" data-placement="right"
ng-model="panel.display.geopoints.autosize"
bs-tooltip="'Allows point sizes to scale as you zoom in and out of the map.'" /> bs-tooltip="'Allows point sizes to scale as you zoom in and out of the map.'" />
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<div class="row-fluid tabDetails" ng-show="isActive('binning')"> <div class="row-fluid tabDetails" ng-show="isActive('binning')">
<div class="span8 offset1"> <div class="span8 offset1">
<table> <table>
<tbody > <tbody >
...@@ -182,9 +184,9 @@ ...@@ -182,9 +184,9 @@
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<div class="row-fluid tabDetails" ng-show="isActive('choropleth')"> <div class="row-fluid tabDetails" ng-show="isActive('choropleth')">
<div class="span8 offset1"> <div class="span8 offset1">
<table> <table>
<tbody > <tbody >
...@@ -192,6 +194,8 @@ ...@@ -192,6 +194,8 @@
<td>Choropleth</td> <td>Choropleth</td>
<td> <td>
<button type="button" class="btn" bs-button <button type="button" class="btn" bs-button
data-placement="right"
bs-tooltip="'Choropleths color country regions according to your selected field. Only compatible with Country-Coded fields'"
ng-change="$emit('render')" ng-change="$emit('render')"
ng-class="{'btn-success': panel.display.choropleth.enabled}" ng-class="{'btn-success': panel.display.choropleth.enabled}"
ng-model="panel.display.choropleth.enabled">{{panel.display.choropleth.enabled|enabledText}}</button> ng-model="panel.display.choropleth.enabled">{{panel.display.choropleth.enabled|enabledText}}</button>
...@@ -200,9 +204,47 @@ ...@@ -200,9 +204,47 @@
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<div class="row-fluid tabDetails" ng-show="isActive('data')"> <div class="row-fluid tabDetails" ng-show="isActive('bullseye')">
<div class="span8 offset1">
<table>
<tbody >
<tr>
<td>Bullseye</td>
<td>
<button type="button" class="btn" bs-button
ng-change="$emit('render')"
ng-class="{'btn-success': panel.display.bullseye.enabled}"
ng-model="panel.display.bullseye.enabled">{{panel.display.choropleth.enabled|enabledText}}</button>
</td>
</tr>
<tr>
<td>Bullseye Coordinates</td>
<td>
<input type="text" style="width:100px"
ng-change="$emit('render')"
placeholder="Latitude"
data-placement="right"
bs-tooltip="'Latitude of Bullseye'"
ng-model="panel.display.bullseye.coord.lat"
value="{{panel.display.bullseye.coord.lat}}" />
<input type="text" style="width:100px"
placeholder="Longitude"
ng-change="$emit('render')"
data-placement="right"
bs-tooltip="'Longitude of Bullseye'"
ng-model="panel.display.bullseye.coord.lon"
value="{{panel.display.bullseye.coord.lon}}" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row-fluid tabDetails" ng-show="isActive('data')">
<div class="span8 offset1"> <div class="span8 offset1">
<table> <table>
<tbody > <tbody >
...@@ -220,11 +262,11 @@ ...@@ -220,11 +262,11 @@
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<h5>Panel Spy</h5> <h5>Panel Spy</h5>
<div class="row-fluid"> <div class="row-fluid">
<div class="span2"> <div class="span2">
<label class="small">Spyable</label> <input type="checkbox" ng-model= <label class="small">Spyable</label> <input type="checkbox" ng-model=
"panel.spyable" ng-checked="panel.spyable"> "panel.spyable" ng-checked="panel.spyable">
...@@ -234,4 +276,5 @@ ...@@ -234,4 +276,5 @@
The panel spy shows 'behind the scenes' information about a panel. It can be The panel spy shows 'behind the scenes' information about a panel. It can be
accessed by clicking the in the top right of the panel. accessed by clicking the in the top right of the panel.
</div> </div>
</div>
</div> </div>
\ No newline at end of file
...@@ -34,9 +34,12 @@ angular.module('kibana.map2', []) ...@@ -34,9 +34,12 @@ angular.module('kibana.map2', [])
}, },
choropleth: { choropleth: {
enabled: false enabled: false
},
bullseye: {
enabled: false
} }
}, },
displayTabs: ["Geopoints", "Binning", "Choropleth", "Data"], displayTabs: ["Geopoints", "Binning", "Choropleth", "Bullseye", "Data"],
activeDisplayTab:"Geopoints" activeDisplayTab:"Geopoints"
}; };
...@@ -138,7 +141,7 @@ angular.module('kibana.map2', []) ...@@ -138,7 +141,7 @@ angular.module('kibana.map2', [])
$scope.populate_modal = function (request) { $scope.populate_modal = function (request) {
$scope.modal = { $scope.modal = {
title: "Inspector", title: "Inspector",
body: "<h5>Last Elasticsearch Query</h5><pre>" + 'curl -XGET ' + config.elasticsearch + '/' + $scope.panel.index + "/_search?pretty -d'\n" + angular.toJson(JSON.parse(request.toString()), true) + "'</pre>", body: "<h5>Last Elasticsearch Query</h5><pre>" + 'curl -XGET ' + config.elasticsearch + '/' + $scope.panel.index + "/_search?pretty -d'\n" + angular.toJson(JSON.parse(request.toString()), true) + "'</pre>"
} }
}; };
...@@ -179,8 +182,10 @@ angular.module('kibana.map2', []) ...@@ -179,8 +182,10 @@ angular.module('kibana.map2', [])
elem.html('<center><img src="common/img/load_big.gif"></center>') elem.html('<center><img src="common/img/load_big.gif"></center>')
var worldData = null, scope.worldData = null;
worldNames = null; scope.worldNames = null;
scope.svg = null;
scope.g = null;
// Receive render events // Receive render events
scope.$on('render', function () { scope.$on('render', function () {
...@@ -209,13 +214,13 @@ angular.module('kibana.map2', []) ...@@ -209,13 +214,13 @@ angular.module('kibana.map2', [])
//these files can take a bit of time to process, so save them in a variable //these files can take a bit of time to process, so save them in a variable
//and use those on redraw //and use those on redraw
if (worldData === null || worldNames === null) { if (scope.worldData === null || scope.worldNames === null) {
queue() queue()
.defer(d3.json, "panels/map2/lib/world-110m.json") .defer(d3.json, "panels/map2/lib/world-110m.json")
.defer(d3.tsv, "panels/map2/lib/world-country-names.tsv") .defer(d3.tsv, "panels/map2/lib/world-country-names.tsv")
.await(function(error, world, names) { .await(function(error, world, names) {
worldData = world; scope.worldData = world;
worldNames = names; scope.worldNames = names;
ready(); ready();
}); });
} else { } else {
...@@ -229,8 +234,10 @@ angular.module('kibana.map2', []) ...@@ -229,8 +234,10 @@ angular.module('kibana.map2', [])
*/ */
function ready() { function ready() {
var world = worldData,
names = worldNames;
var world = scope.worldData,
names = scope.worldNames;
//Better way to get these values? Seems kludgy to use jQuery on the div... //Better way to get these values? Seems kludgy to use jQuery on the div...
var width = $(elem[0]).width(), var width = $(elem[0]).width(),
...@@ -287,18 +294,21 @@ angular.module('kibana.map2', []) ...@@ -287,18 +294,21 @@ angular.module('kibana.map2', [])
* D3 SVG Setup * D3 SVG Setup
*/ */
var svg = d3.select(elem[0]).append("svg") //remove our old svg...is there a better way to update than remove/append?
d3.select(elem[0]).select("svg").remove();
//create the new svg
scope.svg = d3.select(elem[0]).append("svg")
.attr("width", width) .attr("width", width)
.attr("height", height) .attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.call(zoom); .call(zoom);
var g = svg.append("g"); scope.g = scope.svg.append("g");
//Overlay is used so that the entire map is draggable, not just the locations //Overlay is used so that the entire map is draggable, not just the locations
//where countries are //where countries are
svg.append("rect") scope.svg.append("rect")
.attr("class", "overlay") .attr("class", "overlay")
.attr("x", -width / 2) .attr("x", -width / 2)
.attr("y", -height / 2) .attr("y", -height / 2)
...@@ -306,7 +316,7 @@ angular.module('kibana.map2', []) ...@@ -306,7 +316,7 @@ angular.module('kibana.map2', [])
.attr("height", height); .attr("height", height);
//Draw the countries, if this is a choropleth, draw with fancy colors //Draw the countries, if this is a choropleth, draw with fancy colors
g.selectAll("path") scope.g.selectAll("path")
.data(countries) .data(countries)
.enter().append("path") .enter().append("path")
.attr("class", function(d) { .attr("class", function(d) {
...@@ -319,7 +329,7 @@ angular.module('kibana.map2', []) ...@@ -319,7 +329,7 @@ angular.module('kibana.map2', [])
.attr("d", path); .attr("d", path);
//draw boundaries //draw boundaries
g.append("path") scope.g.selectAll("land").append("path")
.datum(topojson.mesh(world, world.objects.land, function(a, b) { return a !== b; })) .datum(topojson.mesh(world, world.objects.land, function(a, b) { return a !== b; }))
.attr("class", "land boundary") .attr("class", "land boundary")
.attr("d", path); .attr("d", path);
...@@ -332,12 +342,13 @@ angular.module('kibana.map2', []) ...@@ -332,12 +342,13 @@ angular.module('kibana.map2', [])
//Hexagonal Binning //Hexagonal Binning
if (scope.panel.display.binning.enabled) { if (scope.panel.display.binning.enabled) {
displayBinning(); var dimensions = [width, height];
displayBinning(scope, dimensions, projection);
} }
//Raw geopoints //Raw geopoints
if (scope.panel.display.geopoints.enabled) { if (scope.panel.display.geopoints.enabled) {
displayGeopoints(); displayGeopoints(scope);
} }
...@@ -346,7 +357,7 @@ angular.module('kibana.map2', []) ...@@ -346,7 +357,7 @@ angular.module('kibana.map2', [])
*/ */
if (scope.panel.display.scale != -1) { if (scope.panel.display.scale != -1) {
zoom.scale(scope.panel.display.scale).translate(scope.panel.display.translate); 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 + ")"); scope.g.style("stroke-width", 1 / scope.panel.display.scale).attr("transform", "translate(" + scope.panel.display.translate + ") scale(" + scope.panel.display.scale + ")");
} }
...@@ -359,7 +370,7 @@ angular.module('kibana.map2', []) ...@@ -359,7 +370,7 @@ angular.module('kibana.map2', [])
scope.panel.display.translate = t; scope.panel.display.translate = t;
scope.panel.display.scale = s; scope.panel.display.scale = s;
g.style("stroke-width", 1 / s).attr("transform", "translate(" + t + ")scale(" + s + ")"); scope.g.style("stroke-width", 1 / s).attr("transform", "translate(" + t + ")scale(" + s + ")");
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment