diff --git a/GMapComponentAsyncLoader.js b/GMapComponentAsyncLoader.js
index b58c934..2eee728 100644
--- a/GMapComponentAsyncLoader.js
+++ b/GMapComponentAsyncLoader.js
@@ -1,10 +1,34 @@
-/*
-This Source Code Form is subject to the
-terms of the Mozilla Public License, v. 2.0.
-If a copy of the MPL was not distributed
-with this file, You can obtain one at
-http://mozilla.org/MPL/2.0/.
+/*!
+* JavaScript - loadGoogleMaps( version, apiKey, language )
+*
+* - Load Google Maps API using jQuery Deferred.
+* Useful if you want to only load the Google Maps API on-demand.
+* - Requires jQuery 1.5
+*
+* Copyright (c) 2011 Glenn Baker
+* Dual licensed under the MIT and GPL licenses.
+*
+* The MIT License (MIT)
+* Copyright (c) 2011 Glenn Baker
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
*/
+
var loadGoogleMapsOverlay = (function($) {
var now = $.now(), promise;
@@ -85,7 +109,7 @@ var loadGoogleMapsOverlay = (function($) {
$.ajax({
dataType: 'script',
data: params,
- url: 'http://maps.googleapis.com/maps/api/js'
+ url: "http://maps.googleapis.com/maps/api/js"
});
}
@@ -96,4 +120,4 @@ var loadGoogleMapsOverlay = (function($) {
};
-} (jQuery));
\ No newline at end of file
+} (jQuery));
diff --git a/README.md b/README.md
index 63742dc..6ce742b 100644
--- a/README.md
+++ b/README.md
@@ -11,13 +11,123 @@ GMaps Version 1.x tested on Pentaho 4.5 / 4.8
Sample
-https://sourceforge.net/projects/pentahogmapsoverlay/files/
+[How to use this plugin](https://sourceforge.net/projects/pentahogmapsoverlay/files/ "How to use this plugin")
Usage
See the video for GMapsOverlay Version 1.0.0
-http://youtu.be/oyppms5fGhc
+
+ [Plugin video usage](http://youtu.be/oyppms5fGhc "Plugin video usage")
Adding New Maps
For new maps just create a new definition map and save it in the pentaho-solutions/cde/components/gmapsoverlay/map-def folder.
+
+ New plugin features
+
+- **DoubleClickAction**
+ - You can specify a function with two parameters for you to call another action based on the value of the shape that received double click
+
+ function(obj,e){
+ if(regiao_mapa !== '[Municipio].[MunicipioX]'){
+ Dashboards.fireChange('regiao_selecionada_mapa', obj.infowindow.dataPayload.name);
+ }
+ }
+
+- **DisableDoubleClickZoom**: true | false
+ Option to disable the zoom in the double click because it interferes if you will use the DoubleClickAction
+
+- **LabelsIcons**: On | Off
+ Show icons on the map
+
+- **AdministrativeLocality**: On | Off
+ Show location information
+
+- **MapColorConditional**
+ You can define a function that receives a parameter and based on the value of this parameter returns a color in the format #000000.
+ Obs: The isColorDefinedInDS property must be false for use of this function.
+
+ function(value){
+ if(value > 20){
+ return '#00FF00'
+ }
+ }
+
+- **MapNameConditional**
+ Here you define a function that returns the file name of the shape that will be drawn on the map depending on a certain condition
+
+
+ function(){
+
+ if (regiao_mapa == '[MunicipioResidencia].[MunicipioX]') {
+ return 'goias-municipios';
+ } else if (regiao_mapa == '[RegiaoSaude].[RegiaoSaudeX]') {
+ return 'goias-regiao-saude';
+ } else if (regiao_mapa == '[MacroRegiao].[MacroRegiaoX]') {
+ return 'goias-macro';
+ } else if (regiao_mapa == '[RideRegiao].[RIDEX]') {
+ return 'goias-ride';
+
+ }
+ }
+
+- **ScrollWhell**
+ Enables or disables scroll zoom
+- **ShapeFillOpacity**
+ Here you define the transparency of shape
+- **shapeStrokeWeight**
+ Define a shape line thickness
+- **ValueFormat**
+ Here you define a function that receives a value parameter where you will format the value and return the formatted value.
+
+ function(value){
+ return accounting.toFixed(value, 2)+"%";
+
+ }
+
+- **ZoomControl**
+ Enable / disable zoom control
+- **isColorDefinedInDS**: true | false
+ If this option is ** true ** it is mandatory to bring the color (in the format: # 00FF00) in the third column of your datasource
+- **LegendItemLabelDescConditional**
+ Here you define a function that returns an array with the description of the legend item
+
+ function (){
+ if ( MENU_SELECIONADO == PRE_NATAL) {
+ return ['≥75.01%','≥ 50.01% e ≤75%','≤ 50%','0%'];
+ }else if(MENU_SELECIONADO == MAES_ADOLESCENTES){
+ return ['≥0.01% e ≤15%','≥ 15.01% e ≤25%','≥ 25.01%','0%'];
+ }
+ }
+
+ - **LegendItemLabelDescFonteColor**
+ Color description of the item in the legend. Here you write the color ex: 'white'
+ - **LegendItemLabelDescFonteSize**
+ Legend item font size
+ - **LegendOpacity**
+ Legend Transparency
+ - **LegendPosition**
+ Position Legend
+ - **LegendItemCountVisible**
+ Show a counter of the legend colors that are in shape
+ - **ExportToCSVFileVisible**
+ Enable / disable option in subtitle to export map data to csv
+
+ #### Sample: ####
+
+- **Dashboards that use this plugin**
+
+ - [Dashbord SINASC](https://extranet.saude.go.gov.br/public/genesis.html "Dashbord SINASC")
+ - [Dashbord SIM](https://extranet.saude.go.gov.br/public/sim.html "Dashbord SIM")
+ - [Dashbord DENGUE](https://extranet.saude.go.gov.br/public/dengue.html "Dashbord DENGUE")
+
+- **Map by municipality**
+
+ 
+
+
+- **Map by Health Region**
+
+ 
+
+
diff --git a/component.xml b/component.xml
index 08524e7..7cfddf2 100644
--- a/component.xml
+++ b/component.xml
@@ -1,203 +1,716 @@
+
-
- Google Maps Overlay Component
- gMapsOverlayComponent
- Google Maps Overlay Component (By Kleyson Rios)
- COMMUNITYCOMPONENTS
- Community Contributions
- PalleteEntry
- 2.0
-
-
-
- width
- height
- executeAtStart
- htmlObject
- listeners
- postFetch
- preExecution
- postExecution
- xActionArrayParameter
-
- dataSource
-
- mapName
- mapWidth
- mapHeight
- centerLatitude
- centerLongitude
- defaultColor
- defaultZoomLevel
- legend
- legendText
- sourceText
- search
-
-
-
-
- GMapComponentAsyncLoader
-
-
-
-
-
-
-
- mapName
- BaseProperty
-
- Map Name
- This is the region descriptor file name that must be placed at cde/components/gmapsoverlay/map-def
- false
- String
- String
- 40
- 1.0
-
-
-
-
- mapHeight
- BaseProperty
-
- Map Height
-
- false
- Integer
- Number
- 40
- 1.0
-
-
-
-
- mapWidth
- BaseProperty
-
- Map Width
-
- false
- Integer
- Number
- 40
- 1.0
-
-
-
-
- centerLatitude
- BaseProperty
-
- Center Latitude
- Center latitude for map
- false
- Float
- Number
- 40
- 1.0
-
-
-
-
- centerLongitude
- BaseProperty
-
- Center Longitude
- Center Longitude for Map
- false
- Float
- Number
- 40
- 1.0
-
-
-
-
- defaultColor
- BaseProperty
-
- Default Color
- Default color for the map
- false
- String
- String
- 40
- 1.0
-
-
-
-
- defaultZoomLevel
- BaseProperty
- 6
- Default zoom Level
-
- Integer
- Number
- 40
- false
- 1.0
-
-
-
-
- legend
- BaseProperty
- "[]"
- Range for Lengend
-
- false
- ValuesArray
- Array
- 40
- 1.0
-
-
-
-
- legendText
- BaseProperty
- Legend
- Legend Text
-
- false
- String
- String
- 40
- 1.0
-
-
-
-
- sourceText
- BaseProperty
-
- Source Text
-
- false
- String
- String
- 40
- 1.0
-
-
-
-
- search
- BaseProperty
- "true"
- Search
- Enable Search Box
- false
- Boolean
- Boolean
- 40
- 1.0
-
-
-
-
-
+
+ Google Maps Overlay Component
+ gMapsOverlayComponent
+ Google Maps Overlay Component (By Kleyson Rios / Josemar Rincon)
+ COMMUNITYCOMPONENTS
+ Community Contributions
+ PalleteEntry
+ 2.0
+
+
+
+ executeAtStart
+ htmlObject
+ listeners
+ postFetch
+ preExecution
+ postExecution
+ xActionArrayParameter
+
+ dataSource
+
+ mapName
+ mapNameConditional
+ mapColorConditional
+ legendLabelDescConditional
+ doubleClickAction
+ valueFormat
+ width
+ height
+ centerLatitude
+ centerLongitude
+ defaultColor
+ defaultZoomLevel
+ disableDoubleClickZoom
+ zoomControl
+ panControl
+ scrollwheel
+ exportToCSVFileVisible
+ exportToCSVFileLocaly
+ mapTypeId
+ mapTypeControl
+ legend
+ legendLabelDesc
+ legendLabelDescFonteColor
+ legendLabelDescOrderColor
+ legendLabelDescOrderColorConditional
+ legendLabelDescFonteSize
+ legendCountVisible
+ legendCountFonteSize
+ legendOpacity
+ legendTitle
+ legendPosition
+ legendWidth
+ legendVisible
+ icons
+ locality
+ shapeFillOpacity
+ shapeStrokeWeight
+ legendText
+ legendTextFonteSize
+ sourceText
+ search
+ isColorDefinedInDS
+ isContinuousMapColor
+
+
+
+
+ GMapComponentAsyncLoader
+
+
+
+
+
+
+
+ mapName
+ BaseProperty
+
+ MapName
+ This is the region descriptor file name that must be placed at cde/components/gmapsoverlay/map-def
+ false
+ String
+ String
+ 1
+ 1.0
+
+
+
+
+
+ mapNameConditional
+ BaseProperty
+
+ MapNameConditional
+ Function to return the name in the json/MapName file depending on a condition
+ false
+ JavaScript
+ Function
+ 1
+ 1.0
+
+
+
+
+ mapColorConditional
+ BaseProperty
+
+ MapColorConditional
+ Conditional function that returns a color format (#FFFFFF) to color the map should be declared receiving ex parameter: function (value) {}
+ false
+ JavaScript
+ Function
+ 1
+ 1.0
+
+
+
+
+ height
+ BaseProperty
+ 800
+ MapHeight
+ if the value blank map assumes 100% of the Height
+ false
+ Integer
+ Number
+ 1
+ 1.0
+
+
+
+
+ width
+ BaseProperty
+
+ MapWidth
+ if the value blank map assumes 100% of the width
+ false
+ Integer
+ Number
+ 1
+ 1.0
+
+
+
+
+ centerLatitude
+ BaseProperty
+
+ CenterLatitude
+ Center latitude for map
+ false
+ Float
+ Number
+ 1
+ 1.0
+
+
+
+
+ centerLongitude
+ BaseProperty
+
+ CenterLongitude
+ Center Longitude for Map
+ false
+ Float
+ Number
+ 1
+ 1.0
+
+
+
+
+ defaultColor
+ BaseProperty
+ #EAEAEA
+ DefaultColor
+ Default color for the map
+ false
+ String
+ String
+ 1
+ 1.0
+
+
+
+
+ defaultZoomLevel
+ BaseProperty
+ 7
+ ZoomLevel
+ level of zoom to load the map
+ Integer
+ Number
+ 1
+ false
+ 1.0
+
+
+
+
+
+ zoomControl
+ BaseProperty
+ true
+ ZoomControl
+ The enabled/disabled state of the Zoom control.
+ true
+ Boolean
+ Boolean
+ 1
+ false
+ 1.0
+
+
+
+
+ panControl
+ BaseProperty
+ true
+ PanControl
+ The enabled/disabled state of the Pan control.
+ true
+ Boolean
+ Boolean
+ 1
+ false
+ 1.0
+
+
+
+
+ scrollwheel
+ BaseProperty
+ true
+ Scrollwheel
+ If false, disables scrollwheel zooming on the map. The scrollwheel is enabled by default.
+ true
+ Boolean
+ Boolean
+ 1
+ false
+ 1.0
+
+
+
+
+ mapTypeId
+ BaseProperty
+ terrain
+ MapTypeId
+ Identifiers for common MapTypes.(hybrid,roadmap,satellite,terrain)
+ true
+
+ String
+ 1
+ 1.0
+
+
+ terrain
+ hybrid
+ roadmap
+ satellite
+
+
+
+
+ mapTypeControl
+ BaseProperty
+ false
+ MapTypeControl
+ The initial enabled/disabled state of the Map type control..
+ true
+ Boolean
+ Boolean
+ 1
+ 1.0
+
+
+
+
+ legend
+ BaseProperty
+ "[]"
+ RangeForLengend
+
+ false
+ ValuesArray
+ Array
+ 1
+ 1.0
+
+
+
+
+ icons
+ BaseProperty
+ on
+ LabelsIcons
+ show icons
+ true
+
+ String
+ 1
+ 1.0
+
+
+ on
+ off
+
+
+
+
+ locality
+ BaseProperty
+ on
+ AdministrativeLocality
+ Show info Locality
+ true
+
+ String
+ 1
+ 1.0
+
+
+ on
+ off
+
+
+
+
+ legendVisible
+ BaseProperty
+ false
+ LegendVisible
+ Disable/Enable legend info
+ false
+ Boolean
+ Boolean
+ 1
+ 1.0
+
+
+
+
+ legendText
+ BaseProperty
+ Legend
+ LegendText
+ Description for legend
+ false
+ String
+ String
+ 1
+ 1.0
+
+
+
+
+ legendTextFonteSize
+ BaseProperty
+ 12
+ LegendTextFonteSize
+ Fonte Size for description legend
+ false
+ Integer
+ String
+ 1
+ 1.0
+
+
+
+
+ shapeFillOpacity
+ BaseProperty
+ 0.6
+ ShapeFillOpacity
+ changes the opacity map
+ true
+ Float
+ Number
+ 1
+ 1.0
+
+
+
+
+ shapeStrokeWeight
+ BaseProperty
+ 0.5
+ ShapeStrokeWeight
+ changing the thickness of the lines on the map
+ true
+ Float
+ Number
+ 1
+ 1.0
+
+
+
+
+ sourceText
+ BaseProperty
+
+ Legend source Text
+
+ false
+ String
+ String
+ 1
+ 1.0
+
+
+
+
+ search
+ BaseProperty
+ "true"
+ SearchVisible
+ Enable/Disable Search Box
+ false
+ Boolean
+ Boolean
+ 1
+ 1.0
+
+
+
+
+ disableDoubleClickZoom
+ BaseProperty
+ true
+ DisableDoubleClickZoom
+ Enables/disables zoom and center on double click. Enabled by default.
+ true
+ Boolean
+ Boolean
+ 1
+ false
+ 1.0
+
+
+
+
+ doubleClickAction
+ BaseProperty
+
+ DoubleClickAction
+ Adds option to double click to regions on the map.It requires two parameters in input function (obj, event)
+ the first is clicked object and the second is the event
+ false
+ JavaScript
+ Function
+ 1
+ 1.0
+
+
+
+
+ valueFormat
+ BaseProperty
+
+ ValueFormat
+ A function that return formats the non-null values of numeric dimensions.ex: function(value) {return valueFormated}
+ true
+ JavaScript
+ Function
+ 1
+ 1.0
+
+
+
+
+ isColorDefinedInDS
+ BaseProperty
+ true
+ IsColorDefinedInDS
+ Map color defined in the datasource. datasource return default is {cities or regions etc., value, color to the map pattern(#FFFFFF)}
+ true
+ Boolean
+ Boolean
+ 1
+ 1.0
+
+
+
+
+
+
+ isContinuousMapColor
+ BaseProperty
+ false
+ IsContinuousMapColor
+ Color map continues. Necessary disable color in the datasource
+ true
+ Boolean
+ Boolean
+ 1
+ 1.0
+
+
+
+
+
+ exportToCSVFileVisible
+ BaseProperty
+ false
+ ExportToCSVFileVisible
+ Export data to CSV file
+ true
+ Boolean
+ Boolean
+ 1
+ 1.0
+
+
+
+
+ exportToCSVFileLocaly
+ BaseProperty
+ LEGEND
+ ExportToCSVFileLocaly
+ Export CSV file locality
+ true
+
+ String
+ 1
+ 1.0
+
+
+ LEGEND
+ MAP
+
+
+
+
+ legendLabelDescFonteColor
+ BaseProperty
+ '["black"]'
+ LegendItemLabelDescFonteColor
+
+ false
+ Array
+ Array
+ 1
+ 1.0
+
+
+
+
+ legendLabelDesc
+ BaseProperty
+ '[""]'
+ LegendItemLabelDesc
+
+ false
+ Array
+ Array
+ 1
+ 1.0
+
+
+
+
+ legendLabelDescConditional
+ BaseProperty
+
+ LegendItemLabelDescConditional
+ Conditional function that must return an array with the description of the legend item
+ true
+ JavaScript
+ Function
+ 1
+ 1.0
+
+
+
+
+ legendLabelDescFonteSize
+ BaseProperty
+ 12
+ LegendItemLabelDescFonteSize
+ Font size the description of the legend item
+ true
+ Integer
+ String
+ 1
+ 1.0
+
+
+
+
+ legendCountVisible
+ BaseProperty
+ false
+ LegendItemCountVisible
+ Enable / disable The Legend colors counter
+ true
+ Boolean
+ Boolean
+ 1
+ 1.0
+
+
+
+
+ legendCountFonteSize
+ BaseProperty
+ 12
+ LegendItemCountFonteSize
+ Font size of the Legend colors counter
+ true
+ Integer
+ String
+ 1
+ 1.0
+
+
+
+
+ legendOpacity
+ BaseProperty
+ 0.8
+ LegendOpacity
+
+ true
+ String
+ String
+ 1
+ 1.0
+
+
+
+
+ legendWidth
+ BaseProperty
+ auto
+ LegendWidth
+
+ true
+ String
+ String
+ 1
+ 1.0
+
+
+
+
+ legendTitle
+ BaseProperty
+ Lengend
+ LegendTitle
+
+ true
+ String
+ String
+ 1
+ 1.0
+
+
+
+
+ legendPosition
+ BaseProperty
+ BOTTOM_CENTER
+ LegendPosition
+ changes the position of the legend
+ true
+
+ String
+ 1
+ 1.0
+
+
+ BOTTOM_CENTER
+ BOTTOM_LEFT
+ RIGHT_BOTTOM
+
+
+
+
+ legendLabelDescOrderColor
+ BaseProperty
+ '[]'
+ LegendItemLabelDescOrderColor
+ orders the position of the colors in the legend
+ true
+ Array
+ Array
+ 1
+ 1.0
+
+
+
+
+ legendLabelDescOrderColorConditional
+ BaseProperty
+
+ LegendItemLabelDescOrderColorConditional
+ Conditional function that must return an array with orders position of the colors in the legend item
+ true
+ JavaScript
+ Function
+ 1
+ 1.0
+
+
+
+
+
+
diff --git a/gmapsoverlay-implementation.js b/gmapsoverlay-implementation.js
index 8b167be..0e4fc36 100644
--- a/gmapsoverlay-implementation.js
+++ b/gmapsoverlay-implementation.js
@@ -5,7 +5,6 @@
with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
-
/*
Contributions by Carlos Russo from Webdetails.pt
@@ -16,19 +15,21 @@ Contributions by Carlos Russo from Webdetails.pt
*/
-
function submitGeocode(input) {
return function(e) {
var keyCode;
if (window.event) {
keyCode = window.event.keyCode;
- } /*else if (variable) {
- keyCode = e.which;
- }*/
+ }
+ /*else if (variable) {
+ keyCode = e.which;
+ }*/
if (keyCode == 13) {
- geocoder.geocode( { address: input.value }, function(results, status) {
+ geocoder.geocode({
+ address: input.value
+ }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.fitBounds(results[0].geometry.viewport);
} else {
@@ -42,223 +43,448 @@ function submitGeocode(input) {
var gMapsOverlayComponent = UnmanagedComponent.extend({
mapEngineOpts: undefined, //override this in preExec
- colormap: [[0, 102, 0, 255], [255, 255 ,0,255], [255, 0,0, 255]], //RGBA
-
- // Get color based on a Range
- getColorLegend: function (value, legendRanges) {
- var qtd = Object.keys(legendRanges.ranges).length;
- for (var j = 0; j < qtd; j++) {
- if ((isNaN(legendRanges.ranges[j].min) && value <= legendRanges.ranges[j].max) ||
- (isNaN(legendRanges.ranges[j].max) && value >= legendRanges.ranges[j].min) ||
- (value >= legendRanges.ranges[j].min && value <= legendRanges.ranges[j].max)) {
- return legendRanges.ranges[j].color;
- }
- }
- },
-
- // Get color based on Continuous Color Map
+ colormap: [
+ [0, 102, 0, 255],
+ [255, 255, 0, 255],
+ [255, 0, 0, 255]
+ ], //RGBA
+
+ // Get color based on a Range
+ getColorLegend: function(value, legendRanges) {
+ var qtd = Object.keys(legendRanges.ranges).length;
+ for (var j = 0; j < qtd; j++) {
+ if ((isNaN(legendRanges.ranges[j].min) && value <= legendRanges.ranges[j].max) ||
+ (isNaN(legendRanges.ranges[j].max) && value >= legendRanges.ranges[j].min) ||
+ (value >= legendRanges.ranges[j].min && value <= legendRanges.ranges[j].max)) {
+ return legendRanges.ranges[j].color;
+ }
+ }
+ },
+
+
+
+ // Get color based on Continuous Color Map
getColorMap: function() {
- var interpolate = function(a, b, n){
- var c = [], d=[];
+ var interpolate = function(a, b, n) {
+ var c = [],
+ d = [];
var k, kk, step;
- for (k=0; k 2){
- myself.queryResult[item[0]].payload = item.slice(2);
- }
- }
-
- myself._parseLegend(myself.isContinuousMapColor);
-
+ //myself.isContinuousMapColor = this.legendVisible ? $.isEmptyObject(myself.legend) : false;
+ var nrCols = values.metadata.length;
+
+ var listColor = [];
+ var countColor;
+ dataResult = {};
+ dataResult.resultset = [];
+ dataResult.metadata = values.metadata;
+
+ for (i in values.resultset) {
+ var item = values.resultset[i];
+
+ var value;
+
+
+
+ if (typeof this.valueFormat == 'function') {
+ value = this.valueFormat(item[1]);
+ }else{
+ value = item[1];
+ }
+
+ dataResult.resultset.push([item[0],value]);
+
+
+ //if (nrCols < 3) // DataSet onde a legenda é baseada no valor
+ // {
+ //value = parseFloat(item[1]);
+ // color = "";
+ // myself.isColorDefinedInDS = false;
+ // } else // DataSet com a 3a coluna informando qual cor utilizar, nao utilizar Legenda nem Mapa de Cor continuo para definir cor da regiao.
+ // {
+ //value = item[1];
+ // color = item[2];
+ // myself.isColorDefinedInDS = true;
+ // }
+ color = "";
+ if(myself.isColorDefinedInDS && typeof myself.mapColorConditional != 'function'){
+ if(nrCols < 3){
+
+ Dashboards.error("GMaps - Color not defined in the third column of the datasource.");
+ return
+ }
+ color = item[2];
+ // por padrao do DS as cores tem que vir na 3 coluna
+ listColor.push(values.resultset[i][2]);
+ }
+
+ if( typeof myself.mapColorConditional == 'function'){
+ // passa o valor por parametro para calculo da cor condicional
+ color = myself.mapColorConditional(item[1]);
+ listColor.push(color);
+ }
+
+
+ myself.queryResult[item[0]] = {
+ 'value': value,
+ 'color': color
+ };
+
+
+
+
+ if (item.length > 2) {
+ myself.queryResult[item[0]].payload = item.slice(2);
+ }
+ }
+
+ listUniqColor = _.uniq(listColor);
+
+ myself._parseLegend(myself.isContinuousMapColor);
+
+
// patch queryResult with color information
- if (myself.isContinuousMapColor)
- {
- var colormap = myself.getColorMap();
- var qvalues = _.map(myself.queryResult, function (q) { return q.value; });
- var minValue = _.min(qvalues), maxValue = _.max(qvalues);
- var n = colormap.length;
- _.each(myself.queryResult, function (v, key) {
- var level = (v.value-minValue) / (maxValue - minValue);
- myself.queryResult[key] = _.extend({
- level: level,
- fillColor: colormap[Math.floor( level * (n-1)) ],
- fillOpacity: defaultFillOpacity,
- strokeWeight: defaultStrokeWeight
- }, myself.queryResult[key]);
- });
- }
- else
- {
- _.each(myself.queryResult, function (v, key) {
-
- var color;
- if (myself.isColorDefinedInDS) {
- color = v.color;
- }
- else
- {
- color = myself.getColorLegend(v.value, myself.legendRanges);
- }
-
- myself.queryResult[key] = _.extend({
- fillColor: color,
- fillOpacity: defaultFillOpacity,
- strokeWeight: defaultStrokeWeight
- }, myself.queryResult[key]);
- });
- }
+ if (myself.isContinuousMapColor) {
+ var colormap = myself.getColorMap();
+ var qvalues = _.map(myself.queryResult, function(q) {
+ return q.value;
+ });
+ var minValue = _.min(qvalues),
+ maxValue = _.max(qvalues);
+ var n = colormap.length;
+ _.each(myself.queryResult, function(v, key) {
+ var level = (v.value - minValue) / (maxValue - minValue);
+ myself.queryResult[key] = _.extend({
+ level: level,
+ fillColor: colormap[Math.floor(level * (n - 1))],
+ fillOpacity: defaultFillOpacity,
+ strokeWeight: defaultStrokeWeight
+ }, myself.queryResult[key]);
+ });
+ } else {
+ listCountColor=[];
+ _.each(myself.queryResult, function(v, key) {
+
+ var color;
+
+ if (myself.isColorDefinedInDS || (typeof myself.mapColorConditional == 'function')) {
+ color = v.color;
+ for(i=0;i" + (shapeValue ? shapeValue : '-');
+
+ tooltipMessage: function(shapeName, shapeValue) {
+ var message = shapeName + "" + (shapeValue ? shapeValue : '-');
return '' + message + '
';
},
-
- // Apenas para debug de codigo
- clickCallback : function (shape, event){
+
+ // Apenas para debug de codigo
+ clickCallback: function(shape, event) {
//Override this
- Dashboards.log(shape.dataPayload.name + ':' + shape.dataPayload.value + ':' + shape.dataPayload.level*100 + '%');
+ Dashboards.log(shape.dataPayload.name + ':' + shape.dataPayload.value + ':' + shape.dataPayload.level * 100 + '%');
},
-
- // Apenas para debug, mostra Lat/Lng no console
- displayCoordinates: function(pnt) {
- var lat = pnt.lat();
- lat = lat.toFixed(4);
- var lng = pnt.lng();
- lng = lng.toFixed(4);
- Dashboards.log("Lat: " + lat + " Lng: " + lng);
- },
-
- showInfo: function (event, mapEngine, infowindow) {
- mapEngine.opened_info.close();
- //if (mapEngine.opened_info.name != infowindow.name) {
- infowindow.setPosition(event.latLng);
- infowindow.open(mapEngine.map);
- mapEngine.opened_info = infowindow;
- //}
+
+ // Apenas para debug, mostra Lat/Lng no console
+ displayCoordinates: function(pnt) {
+ var lat = pnt.lat();
+ lat = lat.toFixed(4);
+ var lng = pnt.lng();
+ lng = lng.toFixed(4);
+ Dashboards.log("Lat: " + lat + " Lng: " + lng);
},
- resetButton: function (id, zoom, centerLongitude, centerLatitude) {
+ showInfo: function(event, mapEngine, infowindow) {
+ mapEngine.opened_info.close();
+ //if (mapEngine.opened_info.name != infowindow.name) {
+ infowindow.setPosition(event.latLng);
+ infowindow.open(mapEngine.map);
+ mapEngine.opened_info = infowindow;
+ //}
+ },
+
+ resetButton: function(id, zoom, centerLongitude, centerLatitude) {
- var myself = this;
+ var myself = this;
- var controlReset = document.createElement('div');
- var linkReset = document.createElement('a');
- controlReset.appendChild(linkReset);
- controlReset.setAttribute('id', 'controlReset_' + id);
- linkReset.setAttribute('id', 'linkReset_' + id);
- linkReset.href = "javascript:void(0)";
- linkReset.className = 'gmapsoverlay-button';
- linkReset.onclick = (function () { myself.map.setZoom(zoom);
- myself.map.setCenter(new google.maps.LatLng(centerLatitude, centerLongitude));
- });
- linkReset.innerHTML = 'Reset';
+ var controlReset = document.createElement('div');
+ var linkReset = document.createElement('a');
+ controlReset.appendChild(linkReset);
+ controlReset.setAttribute('id', 'controlReset_' + id);
+ linkReset.setAttribute('id', 'linkReset_' + id);
+ linkReset.href = "javascript:void(0)";
+ linkReset.className = 'gmapsoverlay-button';
+ linkReset.onclick = (function() {
+ myself.map.setZoom(zoom);
+ myself.map.setCenter(new google.maps.LatLng(centerLatitude, centerLongitude));
+ });
+ linkReset.innerHTML = 'Reset';
- myself.map.controls[google.maps.ControlPosition.TOP_LEFT].push(controlReset);
+ myself.map.controls[google.maps.ControlPosition.TOP_LEFT].push(controlReset);
},
- searchBox: function (id) {
-
- var myself = this;
-
- var control = document.createElement('div');
- var input = document.createElement('input');
- control.appendChild(input);
- control.setAttribute('id', 'locationField_' + id);
- input.style.width = '250px';
- input.style.height = '100%';
- input.style.margin = '0px';
- input.style.border = '1px solid #A9BBDF';
- input.style.borderRadius = '2px';
- input.setAttribute('id', 'locationInput_' + id);
- myself.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(control);
-
- var ac = new google.maps.places.Autocomplete(input, { types: ['geocode'] });
- google.maps.event.addListener(ac, 'place_changed', function() {
- var place = ac.getPlace();
- if (place.geometry.viewport) {
- myself.map.fitBounds(place.geometry.viewport);
- } else {
- myself.map.setCenter(place.geometry.location);
- myself.map.setZoom(17);
- }
- });
-
- google.maps.event.addListener(myself.map, 'bounds_changed', function() {
- input.blur();
- input.value = '';
- });
-
- input.onkeyup = submitGeocode(input);
+ exportCSVButton: function(obj) {
+
+ var myself = this;
+ var id = obj.ph[0].id;
+
+ var controlDiv = document.createElement('div');
+ controlDiv.className = 'pull-left';
+ var button = document.createElement('button');
+ controlDiv.appendChild(button);
+ controlDiv.setAttribute('id', 'exportCSV_' +id);
+ button.setAttribute('id', 'CSVButton_' + id);
+ button.setAttribute('data-placement', 'bottom');
+ button.style.opacity ='0.6';
+ // button.href = "javascript:void(0)";
+ button.title='Export to file csv.';
+ button.className = 'btn btn-default btn-xs';
+
+ button.onmouseover = (function(){
+ button.style.opacity ='1';
+ $(this).tooltip();
+
+ });
+ button.onmouseout = (function(){
+ button.style.opacity ='0.6';
+
+ });
+ button.onclick = (function() {
+ obj.downloadCSV();
+ });
+ button.innerHTML = 'CSV';
+
+ myself.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(controlDiv);
},
-
- renderLegend: function (id, mapDefinition, queryResult, colormap, ticks, legendRanges, isContinuousMapColor, isColorDefinedInDS) {
- /*
- var engNotation = function(d) {
- var Log1000 = Math.log(1000);
- var engLabels = ['', ' k' , ' M', ' G' , ' T', ' P'];
- var exponent3 = ( d == 0 ? 0 :
- Math.floor(Math.round( 100 * Math.log(d)/Log1000 )/100) );
- var mantissa = Math.round( 100* d / Math.pow(1000, exponent3))/100;
- return mantissa + engLabels[exponent3];
- };
- */
-
- if (isContinuousMapColor)
- {
- var sigFigs = function (num, sig) {
- if (num == 0)
- return 0;
- if (Math.round(num) == num)
- return num;
- var digits = Math.round((-Math.log(Math.abs(num)) / Math.LN10) + (sig || 2));
- //round to significant digits (sig)
- if (digits < 0)
- digits = 0;
- return num.toFixed(digits);
- };
-
-
- if (queryResult && mapDefinition ) {
- var values = _.map(queryResult, function (q) { return q.value; });
- var minValue = _.min(values),
- maxValue = _.max(values);
- var n = colormap.length;
- var rounding=1;
- if (maxValue < -5){
- rounding = ((maxValue -minValue)/5).toString().split('.');
- rounding = rounding.length > 1 ? Math.pow(10, Math.max(rounding[1].length, 3)): 1;
- }
- var legend = _.map(ticks, function (level) {
- var value = (minValue + level * (maxValue - minValue)*rounding)/rounding;
- return {
- value: sigFigs(value,1),
- level: level,
- fillColor: colormap[Math.floor( level* n -1)]
- };
- });
- }
-
- this.legend = legend;
- }
-
- // Set CSS styles for the DIV containing the control
- // Setting padding to 5 px will offset the control
- // from the edge of the map
- var controlDiv = document.createElement('DIV');
- controlDiv.style.padding = '5px';
- controlDiv.setAttribute('id', 'legendDiv_' + id);
-
- // Set CSS for the control border
- var controlUI = document.createElement('DIV');
- controlUI.setAttribute('id', 'legendUI_' + id);
- //controlUI.style.backgroundColor = 'white';
- //controlUI.style.borderStyle = 'solid';
- //controlUI.style.borderWidth = '1px';
- controlUI.title = 'Legend';
- controlDiv.appendChild(controlUI);
-
- // Set CSS for the control text
- var controlText = document.createElement('DIV');
- controlText.setAttribute('id', 'legendText_' + id);
- controlText.style.fontFamily = 'Arial,sans-serif';
- controlText.style.fontSize = '12px';
- controlText.style.paddingLeft = '4px';
- controlText.style.paddingRight = '4px';
-
- if (isContinuousMapColor)
- {
- var legendTable = '';
- _.each(legend, function(el){
- var left = (el.level != 0) ? el.level*100 + '%' : '-1px';
- legendTable += "";
- });
-
- // Add the text
- controlText.innerHTML = "" +
- "" +
- "
" + legendRanges.text + "
" +
- "
" +
- "
" +
- legendTable +
- "
" +
- "
" +
- "
" + legendRanges.source + "
" +
- "
";
-
- }
- else
- {
- var legendTable = "";
- var qtd = Object.keys(legendRanges.ranges).length;
- for (var j = 0; j < qtd; j++) {
-
- if (isColorDefinedInDS)
- {
- legendTable += "" + legendRanges.ranges[j].desc + "";
- }
- else if (isNaN(legendRanges.ranges[j].min))
- {
- legendTable += "<= " + legendRanges.ranges[j].max + "" + legendRanges.ranges[j].desc + "";
- }
- else if (isNaN(legendRanges.ranges[j].max))
- {
- legendTable += ">= " + legendRanges.ranges[j].min + "" + legendRanges.ranges[j].desc + "";
- }
- else
- {
- //legendTable += "" + legendRanges.ranges[j].min + "-" + legendRanges.ranges[j].max + "" + legendRanges.ranges[j].desc + "";
- legendTable += "" + legendRanges.ranges[j].max + "" + legendRanges.ranges[j].desc + "";
- }
- }
-
- // Add the text
- controlText.innerHTML = "" +
- "" +
- "
" + legendRanges.text + "
" +
- "
" +
- "
" + legendRanges.source + "
" +
- "
";
-
- }
-
- controlUI.appendChild(controlText);
- this.map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(controlDiv);
-
+
+ searchBox: function(id) {
+
+ var myself = this;
+
+ var control = document.createElement('div');
+ var input = document.createElement('input');
+ control.appendChild(input);
+ control.setAttribute('id', 'locationField_' + id);
+ input.style.width = '250px';
+ input.style.height = '100%';
+ input.style.margin = '0px';
+ input.style.border = '1px solid #A9BBDF';
+ input.style.borderRadius = '2px';
+ input.setAttribute('id', 'locationInput_' + id);
+ myself.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(control);
+
+ var ac = new google.maps.places.Autocomplete(input, {
+ types: ['geocode']
+ });
+ google.maps.event.addListener(ac, 'place_changed', function() {
+ var place = ac.getPlace();
+ if (place.geometry.viewport) {
+ myself.map.fitBounds(place.geometry.viewport);
+ } else {
+ myself.map.setCenter(place.geometry.location);
+ myself.map.setZoom(17);
+ }
+ });
+
+ google.maps.event.addListener(myself.map, 'bounds_changed', function() {
+ input.blur();
+ input.value = '';
+ });
+
+ input.onkeyup = submitGeocode(input);
+ },
+
+
+
+ renderLegend: function(id, mapDefinition, queryResult, colormap, ticks, legendRanges, myself,obj) {
+
+
+ if (myself.isContinuousMapColor) {
+ var sigFigs = function(num, sig) {
+ if (num == 0)
+ return 0;
+ if (Math.round(num) == num)
+ return num;
+ var digits = Math.round((-Math.log(Math.abs(num)) / Math.LN10) + (sig || 2));
+ //round to significant digits (sig)
+ if (digits < 0)
+ digits = 0;
+ return num.toFixed(digits);
+ };
+
+
+ if (queryResult && mapDefinition) {
+ var values = _.map(queryResult, function(q) {
+ return q.value;
+ });
+ var minValue = _.min(values),
+ maxValue = _.max(values);
+ var n = colormap.length;
+ var rounding = 1;
+ if (maxValue < -5) {
+ rounding = ((maxValue - minValue) / 5).toString().split('.');
+ rounding = rounding.length > 1 ? Math.pow(10, Math.max(rounding[1].length, 3)) : 1;
+ }
+ var legend = _.map(ticks, function(level) {
+ var value = (minValue + level * (maxValue - minValue) * rounding) / rounding;
+ return {
+ value: sigFigs(value, 1),
+ level: level,
+ fillColor: colormap[Math.floor(level * n - 1)]
+ };
+ });
+ }
+
+ this.legend = legend;
+ }
+
+ // Set CSS styles for the DIV containing the control
+ // Setting padding to 5 px will offset the control
+ // from the edge of the map
+ var controlDiv = document.createElement('DIV');
+ controlDiv.style.padding = '5px';
+ controlDiv.style.width = 'auto';
+ controlDiv.setAttribute('id', 'legendDiv_' + id);
+
+ // Set CSS for the control border
+ var controlUI = document.createElement('DIV');
+ controlUI.setAttribute('id', 'legendUI_' + id);
+ //controlUI.style.backgroundColor = 'white';
+ //controlUI.style.borderStyle = 'solid';
+ //controlUI.style.borderWidth = '1px';
+ //controlUI.title = 'Legend';
+ controlDiv.appendChild(controlUI);
+
+ // Set CSS for the control text
+ var controlText = document.createElement('DIV');
+ controlText.setAttribute('id', 'legendText_' + id);
+ controlText.style.fontFamily = 'Arial,sans-serif';
+ controlText.style.fontSize = '12px';
+ controlText.style.paddingLeft = '4px';
+ controlText.style.paddingRight = '4px';
+ // cria constante
+ var LEGEND_POSITION = {'BOTTOM_CENTER':11,
+ 'BOTTOM_LEFT':10,
+ 'RIGHT_BOTTOM':9};
+
+ if (myself.isContinuousMapColor) {
+ var legendTable = '';
+ _.each(legend, function(el) {
+ var left = (el.level != 0) ? el.level * 100 + '%' : '-1px';
+ legendTable += "";
+ });
+
+ // Add the text
+ controlText.innerHTML = "" +
+ "" +
+ "
" + legendRanges.text + "
" +
+ "
" +
+ "
" +
+ legendTable +
+ "
" +
+ "
" +
+ "
" + legendRanges.source + "
" +
+ "
";
+
+ } else {
+ var legendTable = "";
+ if(!myself.isColorDefinedInDS){
+ var qtd = Object.keys(legendRanges.ranges).length;
+
+
+ for (var j = 0; j < qtd; j++) {
+
+ if (myself.isColorDefinedInDS) {
+ legendTable += "" + legendRanges.ranges[j].desc + "";
+ } else if (isNaN(legendRanges.ranges[j].min)) {
+ legendTable += "<= " + legendRanges.ranges[j].max + "" + legendRanges.ranges[j].desc + "";
+ } else if (isNaN(legendRanges.ranges[j].max)) {
+ legendTable += ">= " + legendRanges.ranges[j].min + "" + legendRanges.ranges[j].desc + "";
+ } else {
+ //legendTable += "" + legendRanges.ranges[j].min + "-" + legendRanges.ranges[j].max + "" + legendRanges.ranges[j].desc + "";
+ legendTable += "" + legendRanges.ranges[j].max + "" + legendRanges.ranges[j].desc + "";
+ }
+ }
+
+ }
+
+
+
+
+ if(myself.isColorDefinedInDS || typeof obj.mapColorConditional == 'function'){
+
+
+
+ var listColorOrdened = [];
+ var colorIgualDs = false;
+ var listCloneObj = [];
+ var contem = function(arry,obj) {
+ var i = arry.length;
+ while (i--) {
+ if (arry[i] === obj) {
+ return true;
+ }
+ }
+ return false;
+ };
+ // faz a ordenção por cores
+ listUniqColor = _.sortBy(listUniqColor,'color');
+ //obj.legendLabelDescOrderColor = obj.legendLabelDescOrderColor.reverse();
+ // Sobrescreve a ordenação das colres na legenda pelo retorna da ordenação condicional
+ if(typeof obj.legendLabelDescOrderColorConditional == 'function'){
+ obj.legendLabelDescOrderColor = obj.legendLabelDescOrderColorConditional();
+ }
+
+ if(obj.legendLabelDescOrderColor.length > 0){
+ qtdLegend = obj.legendLabelDescOrderColor.length;
+ for(var i = 0; i < qtdLegend;i++){
+ listColorOrdened[i] = {'countColor':(function(j){
+ return function(){
+ var qtdeTemp = listUniqColor.length;
+ for(var i = 0; i < qtdeTemp;i++){
+ if(!contem(obj.legendLabelDescOrderColor,listUniqColor[i].color)){
+ listCloneObj.push(listUniqColor[i]);
+ // remove istem
+ listUniqColor.splice(i,1);
+ i--;
+ qtdeTemp--
+ }
+
+ }
+ for(var item in listUniqColor){
+ colorIgualDs = false;
+ var valorRetorno = 0;
+
+
+ if(listUniqColor[item].color == obj.legendLabelDescOrderColor[j]){
+ colorIgualDs = true;
+ valorRetorno= listUniqColor[item].countColor;
+ // remove istem
+ listUniqColor.splice(item,1);
+ }
+
+ if(colorIgualDs){
+ return valorRetorno;
+ }
+
+ }
+ if(!colorIgualDs){
+ return 0;
+ }
+ }()
+ }(i))
+ , 'color':obj.legendLabelDescOrderColor[i]};
+
+ listUniqColor.push(listColorOrdened[i]);
+ }
+ if(listCloneObj.length > 0){
+ for(var j in listCloneObj){
+ listUniqColor.push(listCloneObj[j]);
+ }
+ }
+ }else{
+ qtdLegend = Object.keys(listUniqColor).length;
+ }
+
+ var fontColor ;
+ var legendLabelDescInfo;
+ var legendCountHtml = '';
+ var legendLabelConditional = false;
+
+ // retorna um array com as labels condicionais
+ if(typeof obj.legendLabelDescConditional == 'function'){
+ legendLabelDescInfo = obj.legendLabelDescConditional() ;
+ legendLabelConditional = true;
+ }
+ for (var j = 0; j < listUniqColor.length; j++) {
+ fontColor = obj.legendLabelDescFonteColor[j] != undefined ? obj.legendLabelDescFonteColor[j] : 'black';
+ if(typeof obj.legendLabelDescConditional != 'function'){
+ legendLabelDescInfo = obj.legendLabelDesc[j] != undefined ? obj.legendLabelDesc[j] : '';
+ }
+
+ obj.legendCountVisible ? legendCountHtml = ""+ listUniqColor[j].countColor +"" : legendCountHtml ;
+ legendTable += ""+
+ "" +(legendLabelConditional ? legendLabelDescInfo[j] : legendLabelDescInfo)+ legendCountHtml+" ";
+ }
+ // Add the text
+ controlText.innerHTML =
+
+ "" +
+ (obj.legendTitle != undefined ? "
" + obj.legendTitle +"
" : "") +
+ "
" +
+ "
" + legendRanges.text + "
" +
+ "
"+
+
+ "
" +
+ "" +
+ "
";
+
+ }else{
+
+ // Add the text
+ controlText.innerHTML = "" +
+ "" +
+ "
" + legendRanges.text + "
" +
+ "
" +
+ "
" +
+
+ legendTable +
+
+ "
" +
+ "
" +
+ "
" + legendRanges.source + "
" +
+ "
";
+
+ }
+
+
+ }
+
+ controlUI.appendChild(controlText);
+ this.map.controls[( LEGEND_POSITION[obj.legendPosition] != undefined ? LEGEND_POSITION[obj.legendPosition] :google.maps.ControlPosition.BOTTOM_CENTER)].push(controlDiv);
},
showPopup: function(data, mapElement, popupHeight, popupWidth, contents, popupContentDiv, borderColor) {
var overlay = new OurMapOverlay(mapElement.getPosition(), popupWidth, popupHeight, contents, popupContentDiv, this.map, borderColor);
- $(this.overlays).each(function (i, elt) {elt.setMap(null);});
+ $(this.overlays).each(function(i, elt) {
+ elt.setMap(null);
+ });
this.overlays.push(overlay);
}
diff --git a/gmapsoverlay.css b/gmapsoverlay.css
index 312d1fb..ca38eb0 100644
--- a/gmapsoverlay.css
+++ b/gmapsoverlay.css
@@ -1,4 +1,3 @@
-
/* @media print { */
/* html, body { */
/* height: auto; */
@@ -172,4 +171,111 @@ ul.gmapsoverlay-legend-labels-range li span {
a.gmapsoverlay-button {
color: #FFFFFF;
-}
\ No newline at end of file
+}
+
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ margin: 3px 7px;
+ font-size: 12px;
+ font-weight: 700;
+ line-height: 1;
+ color: #000;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: #fff;
+ border-radius: 10px;
+
+}
+
+
+
+
+.panel {
+ margin-bottom: 20px;
+ background-color: #fff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+}
+.panel-body {
+ padding: 15px;
+}
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+
+}
+
+
+
+
+.col-md-1 {
+ width: 8.33333333%;
+ position: relative;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px;
+}
+
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+}
+.nav {
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+
+}
+
+.nav > li {
+ position: relative;
+ display: block;
+}
+
+.nav:before,
+.nav:after,
+.panel-body:before,
+.panel-body:after
+ {
+ display: table;
+ content: " ";
+}
+
+
+