mirror of
https://github.com/grafana/grafana.git
synced 2024-11-24 09:50:29 -06:00
Merge pull request #167 from rashidkpc/master
Added bettermap panel and plugin status messages
This commit is contained in:
commit
1dbedff432
@ -22,6 +22,6 @@ var config = new Settings(
|
||||
kibana_index: "kibana-int",
|
||||
modules: ['histogram','map','pie','table','stringquery','sort',
|
||||
'timepicker','text','fields','hits','dashcontrol',
|
||||
'column','derivequeries','trends'],
|
||||
'column','derivequeries','trends','bettermap'],
|
||||
}
|
||||
);
|
||||
|
42
panels/bettermap/editor.html
Normal file
42
panels/bettermap/editor.html
Normal file
@ -0,0 +1,42 @@
|
||||
<div class="row-fluid">
|
||||
<div class="span11">
|
||||
This panel uses geoJSON points in a field to place markers on a map.
|
||||
Coordinates <strong>must be stored as an array in Elasticsearch</strong>.
|
||||
Also note that geoJSON is <strong>long,lat NOT lat,long</strong>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span11">
|
||||
<h6>Query</h6>
|
||||
<input type="text" style="width:100%" ng-model="panel.query">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span4">
|
||||
<form>
|
||||
<h6>Coordinate Field</h6>
|
||||
<input bs-typeahead="fields.list" type="text" class="input-small" ng-model="panel.field">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span4">
|
||||
<form>
|
||||
<h6>Tooltip Field</h6>
|
||||
<input bs-typeahead="fields.list" type="text" class="input-small" ng-model="panel.tooltip">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span2"><h6>Max Points</h6>
|
||||
<input type="number" class="input-small" ng-model="panel.size">
|
||||
</div>
|
||||
</div>
|
||||
<h5>Panel Spy</h5>
|
||||
<div class="row-fluid">
|
||||
<div class="span2">
|
||||
<label class="small"> Spyable </label><input type="checkbox" ng-model="panel.spyable" ng-checked="panel.spyable">
|
||||
</div>
|
||||
<div class="span9 small">
|
||||
The panel spy shows 'behind the scenes' information about a panel. It can
|
||||
be accessed by clicking the <i class='icon-eye-open'></i> in the top right
|
||||
of the panel.
|
||||
</div>
|
||||
</div>
|
BIN
panels/bettermap/lib/images/layers-2x.png
Normal file
BIN
panels/bettermap/lib/images/layers-2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
panels/bettermap/lib/images/layers.png
Normal file
BIN
panels/bettermap/lib/images/layers.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
panels/bettermap/lib/images/marker-icon-2x.png
Normal file
BIN
panels/bettermap/lib/images/marker-icon-2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
BIN
panels/bettermap/lib/images/marker-icon.png
Normal file
BIN
panels/bettermap/lib/images/marker-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
panels/bettermap/lib/images/marker-shadow.png
Normal file
BIN
panels/bettermap/lib/images/marker-shadow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 797 B |
8724
panels/bettermap/lib/leaflet-src.js
Normal file
8724
panels/bettermap/lib/leaflet-src.js
Normal file
File diff suppressed because it is too large
Load Diff
463
panels/bettermap/lib/leaflet.css
Normal file
463
panels/bettermap/lib/leaflet.css
Normal file
@ -0,0 +1,463 @@
|
||||
/* required styles */
|
||||
|
||||
.leaflet-map-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-pane,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-overlay-pane,
|
||||
.leaflet-shadow-pane,
|
||||
.leaflet-marker-pane,
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-overlay-pane svg,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
-ms-touch-action: none;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container img {
|
||||
max-width: none !important;
|
||||
}
|
||||
/* stupid Android 2 doesn't understand "max-width: none" properly */
|
||||
.leaflet-container img.leaflet-image-layer {
|
||||
max-width: 15000px !important;
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.leaflet-tile-pane { z-index: 2; }
|
||||
.leaflet-objects-pane { z-index: 3; }
|
||||
.leaflet-overlay-pane { z-index: 4; }
|
||||
.leaflet-shadow-pane { z-index: 5; }
|
||||
.leaflet-marker-pane { z-index: 6; }
|
||||
.leaflet-popup-pane { z-index: 7; }
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 7;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-tile,
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
-o-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-tile-loaded,
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile,
|
||||
.leaflet-touching .leaflet-zoom-animated {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
-o-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-container {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging,
|
||||
.leaflet-dragging .leaflet-clickable,
|
||||
.leaflet-dragging .leaflet-container {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
}
|
||||
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline: 0;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-container a.leaflet-active {
|
||||
outline: 2px solid orange;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #05f;
|
||||
background: white;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 7px rgba(0,0,0,0.65);
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
-webkit-border-top-left-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
-webkit-border-top-right-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
-webkit-border-bottom-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
-webkit-border-bottom-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar {
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
-webkit-border-top-left-radius: 7px;
|
||||
border-top-left-radius: 7px;
|
||||
-webkit-border-top-right-radius: 7px;
|
||||
border-top-right-radius: 7px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
-webkit-border-bottom-left-radius: 7px;
|
||||
border-bottom-left-radius: 7px;
|
||||
-webkit-border-bottom-right-radius: 7px;
|
||||
border-bottom-right-radius: 7px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
}
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 22px 'Lucida Console', Monaco, monospace;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in {
|
||||
font-size: 22px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 28px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 7px rgba(0,0,0,0.4);
|
||||
background: #f8f8f9;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
box-shadow: 0 0 5px #bbb;
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.leaflet-container .leaflet-control-attribution,
|
||||
.leaflet-container .leaflet-control-scale {
|
||||
font-size: 11px;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
color: black;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
text-shadow: 1px 1px 1px #fff;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.2);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-control-zoom {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-control-zoom {
|
||||
border: 4px solid rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
-webkit-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 19px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 18px 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
margin: 0 auto;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
|
||||
background: white;
|
||||
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 4px 4px 0 0;
|
||||
text-align: center;
|
||||
width: 18px;
|
||||
height: 14px;
|
||||
font: 16px/14px Tahoma, Verdana, sans-serif;
|
||||
color: #c3c3c3;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover {
|
||||
color: #999;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
.leaflet-editing-icon {
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
51
panels/bettermap/lib/leaflet.ie.css
Normal file
51
panels/bettermap/lib/leaflet.ie.css
Normal file
@ -0,0 +1,51 @@
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.leaflet-control {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.leaflet-popup-tip {
|
||||
width: 21px;
|
||||
_width: 27px;
|
||||
margin: 0 auto;
|
||||
_margin-top: -3px;
|
||||
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
margin-top: -1px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
.leaflet-control-zoom,
|
||||
.leaflet-control-layers {
|
||||
border: 3px solid #999;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-layers,
|
||||
.leaflet-control-scale-line {
|
||||
background: white;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
.leaflet-control-attribution {
|
||||
border-top: 1px solid #bbb;
|
||||
border-left: 1px solid #bbb;
|
||||
}
|
8
panels/bettermap/lib/leaflet.js
Normal file
8
panels/bettermap/lib/leaflet.js
Normal file
File diff suppressed because one or more lines are too long
75
panels/bettermap/lib/plugins.css
Normal file
75
panels/bettermap/lib/plugins.css
Normal file
@ -0,0 +1,75 @@
|
||||
.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
|
||||
-webkit-transition: -webkit-transform 0.2s ease-out, opacity 0.2s ease-in;
|
||||
-moz-transition: -moz-transform 0.2s ease-out, opacity 0.2s ease-in;
|
||||
-o-transition: -o-transform 0.2s ease-out, opacity 0.2s ease-in;
|
||||
transition: transform 0.2s ease-out, opacity 0.2s ease-in;
|
||||
}
|
||||
.marker-cluster-small {
|
||||
background-color: rgba(181, 226, 140, 0.6);
|
||||
}
|
||||
.marker-cluster-small div {
|
||||
background-color: rgba(110, 204, 57, 0.6);
|
||||
}
|
||||
|
||||
.marker-cluster-medium {
|
||||
background-color: rgba(241, 211, 87, 0.6);
|
||||
}
|
||||
.marker-cluster-medium div {
|
||||
background-color: rgba(240, 194, 12, 0.6);
|
||||
}
|
||||
|
||||
.marker-cluster-large {
|
||||
background-color: rgba(253, 156, 115, 0.6);
|
||||
}
|
||||
.marker-cluster-large div {
|
||||
background-color: rgba(241, 128, 23, 0.6);
|
||||
}
|
||||
|
||||
.marker-cluster {
|
||||
background-clip: padding-box;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.marker-cluster div {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-left: 5px;
|
||||
margin-top: 5px;
|
||||
|
||||
text-align: center;
|
||||
border-radius: 15px;
|
||||
font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.marker-cluster span {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.leaflet-label {
|
||||
background: #1f1f1f;
|
||||
background-clip: padding-box;
|
||||
border-radius: 4px;
|
||||
border-style: solid;
|
||||
border-width: 0px;
|
||||
display: block;
|
||||
font-weight: 200;
|
||||
font-size: 11pt;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
z-index: 99999 !important;
|
||||
}
|
||||
|
||||
.leaflet-label:before {
|
||||
border-right: 6px solid black;
|
||||
border-right-color: inherit;
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: -10px;
|
||||
display: none;
|
||||
}
|
16
panels/bettermap/lib/plugins.js
Normal file
16
panels/bettermap/lib/plugins.js
Normal file
File diff suppressed because one or more lines are too long
13
panels/bettermap/module.html
Normal file
13
panels/bettermap/module.html
Normal file
@ -0,0 +1,13 @@
|
||||
<kibana-panel ng-controller='bettermap' ng-init="init()">
|
||||
<!-- questionable if this is allowed in HTML5 -->
|
||||
<link rel="stylesheet" href="panels/bettermap/lib/leaflet.css" />
|
||||
<link rel="stylesheet" href="panels/bettermap/lib/plugins.css" />
|
||||
|
||||
<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>
|
||||
</span>
|
||||
<!-- This solution might work well for other panels that have trouble with heights -->
|
||||
<div style="padding-right:10px;padding-top:10px;height:{{panel.height|| row.height}};overflow:hidden">
|
||||
<div bettermap id='bettermap' params="{{panel}}" style="height:100%"></div>
|
||||
</div>
|
||||
</kibana-panel>
|
211
panels/bettermap/module.js
Normal file
211
panels/bettermap/module.js
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
|
||||
## Better maps
|
||||
|
||||
So the cavaet for this panel is that, for better or worse, it does NOT use the terms facet and it
|
||||
DOES query sequentially. This however means that
|
||||
|
||||
### Parameters
|
||||
* query :: A single query string, not and array. This panel can only handle one
|
||||
query at a time.
|
||||
* size :: How many results to show, more results = slower
|
||||
* field :: field containing a 2 element array in the format [lon,lat]
|
||||
* tooltip :: field to extract the tool tip value from
|
||||
* spyable :: Show the 'eye' icon that reveals the last ES query
|
||||
|
||||
### Group Events
|
||||
#### Sends
|
||||
* get_time :: On panel initialization get time range to query
|
||||
#### Receives
|
||||
* time :: An object containing the time range to use and the index(es) to query
|
||||
* query :: An Array of queries, this panel uses only the first one
|
||||
*/
|
||||
|
||||
angular.module('kibana.bettermap', [])
|
||||
.controller('bettermap', function($scope, eventBus) {
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Experimental",
|
||||
query : "*",
|
||||
size : 1000,
|
||||
spyable : true,
|
||||
tooltip : "_id",
|
||||
field : null,
|
||||
group : "default"
|
||||
}
|
||||
_.defaults($scope.panel,_d)
|
||||
|
||||
$scope.init = function() {
|
||||
eventBus.register($scope,'time', function(event,time){set_time(time)});
|
||||
eventBus.register($scope,'query', function(event, query) {
|
||||
$scope.panel.query = _.isArray(query) ? query[0] : query;
|
||||
$scope.get_data();
|
||||
});
|
||||
|
||||
// Now that we're all setup, request the time from our group
|
||||
eventBus.broadcast($scope.$id,$scope.panel.group,'get_time')
|
||||
}
|
||||
|
||||
$scope.get_data = function(segment,query_id) {
|
||||
$scope.panel.error = false;
|
||||
|
||||
// Make sure we have everything for the request to complete
|
||||
if(_.isUndefined($scope.index) || _.isUndefined($scope.time))
|
||||
return
|
||||
|
||||
if(_.isUndefined($scope.panel.field)) {
|
||||
$scope.panel.error = "Please select a field that contains geo point in [lon,lat] format"
|
||||
return
|
||||
}
|
||||
|
||||
//$scope.panel.loading = true;
|
||||
|
||||
var _segment = _.isUndefined(segment) ? 0 : segment
|
||||
$scope.segment = _segment;
|
||||
|
||||
var request = $scope.ejs.Request().indices($scope.index[_segment])
|
||||
.query(ejs.FilteredQuery(
|
||||
ejs.QueryStringQuery(($scope.panel.query || '*') + " AND _exists_:"+$scope.panel.field),
|
||||
ejs.RangeFilter($scope.time.field)
|
||||
.from($scope.time.from)
|
||||
.to($scope.time.to)
|
||||
)
|
||||
)
|
||||
.fields([$scope.panel.field,$scope.panel.tooltip])
|
||||
.size($scope.panel.size)
|
||||
.sort($scope.time.field,'desc');
|
||||
|
||||
$scope.populate_modal(request)
|
||||
|
||||
var results = request.doSearch()
|
||||
|
||||
// Populate scope when we have results
|
||||
results.then(function(results) {
|
||||
$scope.panel.loading = false;
|
||||
|
||||
if(_segment === 0) {
|
||||
$scope.hits = 0;
|
||||
$scope.data = [];
|
||||
query_id = $scope.query_id = new Date().getTime()
|
||||
}
|
||||
|
||||
// Check for error and abort if found
|
||||
if(!(_.isUndefined(results.error))) {
|
||||
$scope.panel.error = $scope.parse_error(results.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that we're still on the same query, if not stop
|
||||
if($scope.query_id === query_id) {
|
||||
|
||||
var scripts = $LAB.script("panels/bettermap/lib/leaflet.js").wait()
|
||||
|
||||
scripts.wait(function(){
|
||||
$scope.data = $scope.data.concat(_.map(results.hits.hits, function(hit) {
|
||||
return {
|
||||
coordinates : new L.LatLng(hit.fields[$scope.panel.field][1],hit.fields[$scope.panel.field][0]),
|
||||
tooltip : hit.fields[$scope.panel.tooltip]
|
||||
}
|
||||
}));
|
||||
});
|
||||
// Keep only what we need for the set
|
||||
$scope.data = $scope.data.slice(0,$scope.panel.size)
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.$emit('draw')
|
||||
|
||||
// Get $size results then stop querying
|
||||
if($scope.data.length < $scope.panel.size && _segment+1 < $scope.index.length)
|
||||
$scope.get_data(_segment+1,$scope.query_id)
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// I really don't like this function, too much dom manip. Break out into directive?
|
||||
$scope.populate_modal = function(request) {
|
||||
$scope.modal = {
|
||||
title: "Inspector",
|
||||
body : "<h5>Last Elasticsearch Query</h5><pre>"+
|
||||
'curl -XGET '+config.elasticsearch+'/'+$scope.index+"/_search?pretty -d'\n"+
|
||||
angular.toJson(JSON.parse(request.toString()),true)+
|
||||
"'</pre>",
|
||||
}
|
||||
}
|
||||
|
||||
function set_time(time) {
|
||||
$scope.time = time;
|
||||
$scope.index = _.isUndefined(time.index) ? $scope.index : time.index
|
||||
$scope.get_data();
|
||||
}
|
||||
|
||||
$scope.build_search = function(field,value) {
|
||||
$scope.panel.query = add_to_query($scope.panel.query,field,value,false)
|
||||
$scope.get_data();
|
||||
eventBus.broadcast($scope.$id,$scope.panel.group,'query',[$scope.panel.query]);
|
||||
}
|
||||
|
||||
})
|
||||
.directive('bettermap', function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, elem, attrs) {
|
||||
|
||||
elem.html('<center><img src="common/img/load_big.gif"></center>')
|
||||
|
||||
// Receive render events
|
||||
scope.$on('draw',function(){
|
||||
render_panel();
|
||||
});
|
||||
|
||||
scope.$on('render', function(){
|
||||
if(!_.isUndefined(map)) {
|
||||
map.invalidateSize();
|
||||
var panes = map.getPanes()
|
||||
}
|
||||
})
|
||||
|
||||
var map, markers, layerGroup, mcg;
|
||||
|
||||
function render_panel() {
|
||||
scope.panel.loading = false;
|
||||
|
||||
var scripts = $LAB.script("panels/bettermap/lib/leaflet.js").wait()
|
||||
.script("panels/bettermap/lib/plugins.js")
|
||||
|
||||
//add markers dynamically
|
||||
scripts.wait(function(){
|
||||
if(_.isUndefined(map)) {
|
||||
map = L.map(attrs.id, {
|
||||
scrollWheelZoom: false,
|
||||
center: [40, -86],
|
||||
zoom: 10
|
||||
});
|
||||
|
||||
L.tileLayer('http://{s}.tile.cloudmade.com/57cbb6ca8cac418dbb1a402586df4528/22677/256/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18,
|
||||
minZoom: 2
|
||||
}).addTo(map);
|
||||
layerGroup = new L.MarkerClusterGroup({maxClusterRadius:30});
|
||||
} else {
|
||||
layerGroup.clearLayers();
|
||||
}
|
||||
|
||||
_.each(scope.data, function(p) {
|
||||
if(!_.isUndefined(p.tooltip) && p.tooltip !== '')
|
||||
layerGroup.addLayer(L.marker(p.coordinates).bindLabel(p.tooltip))
|
||||
else
|
||||
layerGroup.addLayer(L.marker(p.coordinates))
|
||||
})
|
||||
|
||||
layerGroup.addTo(map)
|
||||
|
||||
map.fitBounds(_.pluck(scope.data,'coordinates'));
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
@ -19,6 +19,7 @@ angular.module('kibana.column', [])
|
||||
.controller('column', function($scope, $rootScope) {
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status: "Stable",
|
||||
panels : [
|
||||
]
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ angular.module('kibana.dashcontrol', [])
|
||||
$scope.panel = $scope.panel || {};
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Stable",
|
||||
group : "default",
|
||||
save : {
|
||||
gist: false,
|
||||
|
@ -21,6 +21,7 @@ angular.module('kibana.debug', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Experimental",
|
||||
group : "ALL",
|
||||
style : {'font-size':'9pt'},
|
||||
size : 20
|
||||
|
@ -26,6 +26,7 @@ angular.module('kibana.derivequeries', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Beta",
|
||||
label : "Search",
|
||||
query : "*",
|
||||
group : "default",
|
||||
|
@ -22,6 +22,7 @@ angular.module('kibana.fields', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Beta",
|
||||
group : "default",
|
||||
style : {},
|
||||
arrange : 'vertical',
|
||||
|
@ -46,6 +46,7 @@ angular.module('kibana.histogram', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Stable",
|
||||
group : "default",
|
||||
query : [ {query: "*", label:"Query"} ],
|
||||
mode : 'count',
|
||||
|
@ -26,6 +26,7 @@ angular.module('kibana.hits', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Beta",
|
||||
query : ["*"],
|
||||
group : "default",
|
||||
style : { "font-size": '10pt'},
|
||||
|
@ -32,6 +32,7 @@ angular.module('kibana.map', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Beta",
|
||||
query : "*",
|
||||
map : "world",
|
||||
colors : ['#A0E2E2', '#265656'],
|
||||
|
@ -3,6 +3,7 @@ angular.module('kibana.map2', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Broken",
|
||||
query: "*",
|
||||
map: "world",
|
||||
colors: ['#C8EEFF', '#0071A4'],
|
||||
|
@ -6,6 +6,7 @@ angular.module('kibana.parallelcoordinates', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Broken",
|
||||
query : "*",
|
||||
size : 100, // Per page
|
||||
pages : 5, // Pages available
|
||||
|
@ -37,6 +37,7 @@ angular.module('kibana.pie', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Deprecating Soon",
|
||||
query : { field:"_all", query:"*", goal: 1},
|
||||
size : 10,
|
||||
exclude : [],
|
||||
|
@ -25,6 +25,7 @@ angular.module('kibana.sort', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Stable",
|
||||
label : "Sort",
|
||||
sort : ['_score','desc'],
|
||||
group : "default"
|
||||
|
@ -24,6 +24,7 @@ angular.module('kibana.stringquery', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Stable",
|
||||
label : "Search",
|
||||
query : "*",
|
||||
group : "default",
|
||||
|
@ -33,6 +33,7 @@ angular.module('kibana.table', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Stable",
|
||||
query : "*",
|
||||
size : 100, // Per page
|
||||
pages : 5, // Pages available
|
||||
|
@ -16,6 +16,7 @@ angular.module('kibana.text', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Stable",
|
||||
group : "default",
|
||||
mode : "markdown",
|
||||
content : "",
|
||||
|
@ -32,6 +32,7 @@ angular.module('kibana.timepicker', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Stable",
|
||||
mode : "relative",
|
||||
time_options : ['5m','15m','1h','6h','12h','24h','2d','7d','30d'],
|
||||
timespan : '15m',
|
||||
|
@ -23,6 +23,7 @@ angular.module('kibana.trends', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
status : "Beta",
|
||||
query : ["*"],
|
||||
group : "default",
|
||||
style : { "font-size": '14pt'},
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div ng-include src="'partials/panelgeneral.html'"></div>
|
||||
|
||||
|
||||
<h4 style="text-transform: capitalize;">{{panel.type}} <small> panel settings</small></h4>
|
||||
<h4 style="text-transform: capitalize;">{{panel.type}} <small> panel settings. <strong ng-show="!_.isUndefined(panel.status)">({{panel.status}})</strong></small></h4>
|
||||
<div ng-include src="edit_path(panel.type)">No additional settings are available for this type of panel.</div>
|
||||
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user