I want to trigger to different tooltips on a single column chart, one on hover and another on bar select.
How can i solve it ?
I went through the following links but couldn't solve it.
Show multiple tooltips in Google Charts
Google charts to show multiple tooltip
How to show/hide google chart's tooltip programatically?
ToolTip only shows on "Click"- google charts
out of the box, google chart does not offer this functionality.
you will need to turn off the default tooltips,
tooltip: {
trigger: 'none'
}
and add your own custom tooltips.
you can use chart events to determine which tooltip to show.
('select', 'onmouseover', 'onmouseout')
to position your custom tooltip,
you can use chart method --> getChartLayoutInterface
the interface has a method for --> getBoundingBox
which returns the position of a chart element,
just pass the id of the element, such as a chart column.
chart column id's take the form as --> bar#0#0
where the first 0 is the series number,
and the second 0 is the row number.
something to think about is how to handle collisions.
meaning, what are you going to show when a column is selected, then hovered.
or a column is selected and another column is hovered, etc...
see following working snippet for an example of how to accomplish...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['City', '2010 Population',],
['New York City, NY', 8175000],
['Los Angeles, CA', 3792000],
['Chicago, IL', 2695000],
['Houston, TX', 2099000],
['Philadelphia, PA', 1526000]
]);
var options = {
title: 'Population of Largest U.S. Cities',
chartArea: {width: '50%'},
hAxis: {
title: 'Total Population',
minValue: 0
},
vAxis: {
title: 'City'
},
tooltip: {
trigger: 'none'
}
};
var chart = new google.visualization.ColumnChart($('#chart_div').get(0));
var chartLayout;
var selection;
google.visualization.events.addListener(chart, 'ready', function () {
chartLayout = chart.getChartLayoutInterface();
});
google.visualization.events.addListener(chart, 'select', function () {
selection = getSelection();
if (selection.row !== null) {
hideTooltip('tooltip-hover');
showTooltip(selection, 'tooltip-select');
} else {
hideTooltip('tooltip-select');
}
});
google.visualization.events.addListener(chart, 'onmouseover', function (sender) {
selection = getSelection();
if ((sender.row !== null) && (selection.row !== sender.row)) {
showTooltip(sender, 'tooltip-hover');
}
});
google.visualization.events.addListener(chart, 'onmouseout', function (sender) {
selection = getSelection();
if ((sender.row !== null) && (selection.row !== sender.row)) {
hideTooltip('tooltip-hover');
}
});
function showTooltip(sender, tooltip) {
// get position of bar
var tooltipBounds = chartLayout.getBoundingBox('bar#' + (sender.column - 1) + '#' + sender.row);
// set values
$('#' + tooltip + ' .series-name').html(data.getColumnLabel(sender.column));
$('#' + tooltip + ' .series-x').html(data.getFormattedValue(sender.row, 0));
$('#' + tooltip + ' .series-y').html(data.getFormattedValue(sender.row, sender.column));
// set position
$('#' + tooltip).css({
left: tooltipBounds.left + 'px',
top: (tooltipBounds.top - $('#' + tooltip).outerHeight(true)) + 'px'
});
// show
$('#' + tooltip).addClass('shown');
$('#' + tooltip).removeClass('hidden');
}
function hideTooltip(tooltip) {
// hide
$('#' + tooltip).addClass('hidden');
$('#' + tooltip).removeClass('shown');
}
function getSelection() {
selection = chart.getSelection();
if (selection.length > 0) {
return selection[0];
} else {
return {row: null, column: null};
}
}
chart.draw(data, options);
});
.ggl-tooltip {
background-color: #ffffff;
border: 1px solid #E0E0E0;
font-size: 10pt;
padding: 8px 8px 8px 8px;
position: absolute;
}
.ggl-tooltip div {
margin-top: 4px;
}
.bold {
font-weight: bold;
}
.hidden {
display: none;
visibility: hidden;
}
.shown {
display: inline-block;
}
#tooltip-hover {
color: blue;
}
#tooltip-select {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src='https://www.gstatic.com/charts/loader.js'></script>
<div id="chart_div"></div>
<div id="tooltip-hover" class="ggl-tooltip hidden">
<div><span class="series-name bold"></span></div>
<div>
<span class="series-x bold"></span>:
<span class="series-y"></span>
</div>
</div>
<div id="tooltip-select" class="ggl-tooltip hidden">
<div><span class="series-name bold"></span></div>
<div>
<span class="series-x bold"></span>:
<span class="series-y"></span>
</div>
</div>
Related
I have two overlapping (100% overlapped) select dropdowns, I want to be able to click on the one overlapping the openable select drop down while triggering the other select dropdown to open up with the list of options. I have seen references this is unsupported and if so I need a workaround to get the option to preserver the value of the overlayed select while only opening the first select box z-index is less than the first select box.
How do I accomplish this requirement?
Fiddle
https://jsfiddle.net/0rgthvub/
HTML
<select class="long-select" style="background-color:white; position: absolute !important; width: 200px; z-index: 10 !important;" onmousedown="(function(event){processOpen(event);})(event, this)">
<option value="Open - some description" selected></option>
</select>
JavaScript/jQuery
function processOpen(e) {
e.preventDefault();
$input = $("select.shortened-select");
var $this = $(this);
if ($input.is("select") && !$('.lfClon').length) {
var $clon = $input.clone();
var getRules = function(e){ return {
position: 'absolute',
left: e.offset().left,
top: e.offset().top,
width: e.outerWidth(),
height: e.outerHeight(),
opacity: 0,
margin: 0,
padding: 0
};};
var rules = getRules($this);
$clon.css(rules);
$clon.on("mousedown.lf", function(){
debugger;
$clon.css({
marginLeft: $input.offset().left - rules.left,
marginTop: $input.offset().top - rules.top,
});
$clon.on('change blur', function(){
$input.val($clon.val()).show();
$clon.remove();
});
$clon.off('.lf');
});
$clon.on("mouseout.lf", function(){
$(this).remove();
});
$clon.prop({id:'',className:'lfClon'});
$clon.appendTo('body');
}
value = document.querySelectorAll(".shortened-select option")[document.querySelector(".shortened-select").selectedIndex].value;
$input.value = "value";
$input.value.show();
}
function focus() {
[].forEach.call(this.options, function(o) {
if (o.val === ""){
o.setAttribute('data-descr', document.querySelectorAll(".shortened-select option")[document.querySelector(".shortened-select").selectedIndex].getAttribute("val"));
o.selected = 'selected';
}
else
{
o.textContent = o.getAttribute('val');
}
});
}
function blur(e) {
[].forEach.call(this.options, function(o) {
o.textContent = o.getAttribute('val') + ' - ' + o.getAttribute('data-descr');
});
this.blur();
}
function mouseup(e) {
[].forEach.call(this.options, function(o) {
o.textContent = o.getAttribute('val') + ' - ' + o.getAttribute('data-descr');
});
}
[].forEach.call(document.querySelectorAll('.shortened-select'), function(s) {
s.addEventListener('focus', focus);
s.addEventListener('change', blur);
blur.call(s);
});
I am looking to add a small label near each of the countries name that will show it's population (e.g. Brazil [200,0000] ). Is there a way to do this with Google maps JS api?
My current code for map initialization:
// Define options
var options = {
center: {
lat: 48.1250223,
lng: 4.1264001
},
zoom: 3
};
// Init map
map = new google.maps.Map( $container.get(0), options );
Any help would be appreciated!
Data for the population is not available in the Google Maps API v3.
You will need to import data from an external source.
You can check this example from Google API https://developers.google.com/maps/documentation/javascript/combining-data
Full code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>Mashups with google.maps.Data</title>
<style>
html, body, #map { height: 100%; margin: 0; padding: 0; overflow: hidden; }
.nicebox {
position: absolute;
text-align: center;
font-family: "Roboto", "Arial", sans-serif;
font-size: 13px;
z-index: 5;
box-shadow: 0 4px 6px -4px #333;
padding: 5px 10px;
background: rgb(255,255,255);
background: linear-gradient(to bottom,rgba(255,255,255,1) 0%,rgba(245,245,245,1) 100%);
border: rgb(229, 229, 229) 1px solid;
}
#controls {
top: 10px;
left: 110px;
width: 360px;
height: 45px;
}
#data-box {
top: 10px;
left: 500px;
height: 45px;
line-height: 45px;
display: none;
}
#census-variable {
width: 360px;
height: 20px;
}
#legend { display: flex; display: -webkit-box; padding-top: 7px }
.color-key {
background: linear-gradient(to right,
hsl(5, 69%, 54%) 0%,
hsl(29, 71%, 51%) 17%,
hsl(54, 74%, 47%) 33%,
hsl(78, 76%, 44%) 50%,
hsl(102, 78%, 41%) 67%,
hsl(127, 81%, 37%) 83%,
hsl(151, 83%, 34%) 100%);
flex: 1;
-webkit-box-flex: 1;
margin: 0 5px;
text-align: left;
font-size: 1.0em;
line-height: 1.0em;
}
#data-value { font-size: 2.0em; font-weight: bold }
#data-label { font-size: 2.0em; font-weight: normal; padding-right: 10px; }
#data-label:after { content: ':' }
#data-caret { margin-left: -5px; display: none; font-size: 14px; width: 14px}
</style>
</head>
<body>
<div id="controls" class="nicebox">
<div>
<select id="census-variable">
<option value="https://storage.googleapis.com/mapsdevsite/json/DP02_0066PE">Percent of population over 25 that completed high
school</option>
<option value="https://storage.googleapis.com/mapsdevsite/json/DP05_0017E">Median age</option>
<option value="https://storage.googleapis.com/mapsdevsite/json/DP05_0001E">Total population</option>
<option value="https://storage.googleapis.com/mapsdevsite/json/DP02_0016E">Average family size</option>
<option value="https://storage.googleapis.com/mapsdevsite/json/DP03_0088E">Per-capita income</option>
</select>
</div>
<div id="legend">
<div id="census-min">min</div>
<div class="color-key"><span id="data-caret">◆</span></div>
<div id="census-max">max</div>
</div>
</div>
<div id="data-box" class="nicebox">
<label id="data-label" for="data-value"></label>
<span id="data-value"></span>
</div>
<div id="map"></div>
<script>
var mapStyle = [{
'stylers': [{'visibility': 'off'}]
}, {
'featureType': 'landscape',
'elementType': 'geometry',
'stylers': [{'visibility': 'on'}, {'color': '#fcfcfc'}]
}, {
'featureType': 'water',
'elementType': 'geometry',
'stylers': [{'visibility': 'on'}, {'color': '#bfd4ff'}]
}];
var map;
var censusMin = Number.MAX_VALUE, censusMax = -Number.MAX_VALUE;
function initMap() {
// load the map
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 40, lng: -100},
zoom: 4,
styles: mapStyle
});
// set up the style rules and events for google.maps.Data
map.data.setStyle(styleFeature);
map.data.addListener('mouseover', mouseInToRegion);
map.data.addListener('mouseout', mouseOutOfRegion);
// wire up the button
var selectBox = document.getElementById('census-variable');
google.maps.event.addDomListener(selectBox, 'change', function() {
clearCensusData();
loadCensusData(selectBox.options[selectBox.selectedIndex].value);
});
// state polygons only need to be loaded once, do them now
loadMapShapes();
}
/** Loads the state boundary polygons from a GeoJSON source. */
function loadMapShapes() {
// load US state outline polygons from a GeoJson file
map.data.loadGeoJson('https://storage.googleapis.com/mapsdevsite/json/states.js', { idPropertyName: 'STATE' });
// wait for the request to complete by listening for the first feature to be
// added
google.maps.event.addListenerOnce(map.data, 'addfeature', function() {
google.maps.event.trigger(document.getElementById('census-variable'),
'change');
});
}
/**
* Loads the census data from a simulated API call to the US Census API.
*
* #param {string} variable
*/
function loadCensusData(variable) {
// load the requested variable from the census API (using local copies)
var xhr = new XMLHttpRequest();
xhr.open('GET', variable + '.json');
xhr.onload = function() {
var censusData = JSON.parse(xhr.responseText);
censusData.shift(); // the first row contains column names
censusData.forEach(function(row) {
var censusVariable = parseFloat(row[0]);
var stateId = row[1];
// keep track of min and max values
if (censusVariable < censusMin) {
censusMin = censusVariable;
}
if (censusVariable > censusMax) {
censusMax = censusVariable;
}
// update the existing row with the new data
map.data
.getFeatureById(stateId)
.setProperty('census_variable', censusVariable);
});
// update and display the legend
document.getElementById('census-min').textContent =
censusMin.toLocaleString();
document.getElementById('census-max').textContent =
censusMax.toLocaleString();
};
xhr.send();
}
/** Removes census data from each shape on the map and resets the UI. */
function clearCensusData() {
censusMin = Number.MAX_VALUE;
censusMax = -Number.MAX_VALUE;
map.data.forEach(function(row) {
row.setProperty('census_variable', undefined);
});
document.getElementById('data-box').style.display = 'none';
document.getElementById('data-caret').style.display = 'none';
}
/**
* Applies a gradient style based on the 'census_variable' column.
* This is the callback passed to data.setStyle() and is called for each row in
* the data set. Check out the docs for Data.StylingFunction.
*
* #param {google.maps.Data.Feature} feature
*/
function styleFeature(feature) {
var low = [5, 69, 54]; // color of smallest datum
var high = [151, 83, 34]; // color of largest datum
// delta represents where the value sits between the min and max
var delta = (feature.getProperty('census_variable') - censusMin) /
(censusMax - censusMin);
var color = [];
for (var i = 0; i < 3; i++) {
// calculate an integer color based on the delta
color[i] = (high[i] - low[i]) * delta + low[i];
}
// determine whether to show this shape or not
var showRow = true;
if (feature.getProperty('census_variable') == null ||
isNaN(feature.getProperty('census_variable'))) {
showRow = false;
}
var outlineWeight = 0.5, zIndex = 1;
if (feature.getProperty('state') === 'hover') {
outlineWeight = zIndex = 2;
}
return {
strokeWeight: outlineWeight,
strokeColor: '#fff',
zIndex: zIndex,
fillColor: 'hsl(' + color[0] + ',' + color[1] + '%,' + color[2] + '%)',
fillOpacity: 0.75,
visible: showRow
};
}
/**
* Responds to the mouse-in event on a map shape (state).
*
* #param {?google.maps.MouseEvent} e
*/
function mouseInToRegion(e) {
// set the hover state so the setStyle function can change the border
e.feature.setProperty('state', 'hover');
var percent = (e.feature.getProperty('census_variable') - censusMin) /
(censusMax - censusMin) * 100;
// update the label
document.getElementById('data-label').textContent =
e.feature.getProperty('NAME');
document.getElementById('data-value').textContent =
e.feature.getProperty('census_variable').toLocaleString();
document.getElementById('data-box').style.display = 'block';
document.getElementById('data-caret').style.display = 'block';
document.getElementById('data-caret').style.paddingLeft = percent + '%';
}
/**
* Responds to the mouse-out event on a map shape (state).
*
* #param {?google.maps.MouseEvent} e
*/
function mouseOutOfRegion(e) {
// reset the hover state, returning the border to normal
e.feature.setProperty('state', 'normal');
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?callback=initMap">
</script>
</body>
</html>
You could use the label of a marker without displaying the marker. Attached a short example. Mmmmh, or use the country flag as icon and show the label over it.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Marker with Label</title>
<style>
#map {height: 100%;}
html, body {height: 100%;}
</style>
</head>
<body>
<div id="map"></div>
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: {lat: 48.1, lng: 4.1},
mapTypeId: 'terrain'
});
//set the text as marker label without displayinge the marker
var m = new google.maps.Marker({
position: {lat: 48.1, lng: 4.1},
label: {
color: 'purple',
fontWeight: 'bold',
text: 'people: 67 Mio',
},
icon: {
url: 'none_marker.png',
anchor: new google.maps.Point(10, -25),
},
map: map
});
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
</body>
</html>
trying to compare two sensor readings - the data is coming from thingspeak. I've got the zoom part working, but for some reason I cant get the scroll to work.
<script type="text/javascript">
// variables for the first series
var series_1_channel_id = 43330;
var series_1_field_number = 4;
var series_1_read_api_key = '7ZPHNX2SXPM0CA1K';
var series_1_results = 480;
var series_1_color = '#d62020';
var series_1_name = 'Zims Sensor';
// variables for the second series
var series_2_channel_id = 45473;
var series_2_field_number = 2;
var series_2_read_api_key = 'N12T3CWQB5IWJAU9';
var series_2_results = 480;
var series_2_color = '#00aaff';
var series_2_name = 'UVM30a';
// chart title
var chart_title = 'UV Sensors Zim / UVM30A';
// y axis title
var y_axis_title = 'UV Index';
// user's timezone offset
var my_offset = new Date().getTimezoneOffset();
// chart variable
var my_chart;
// when the document is ready
$(document).on('ready', function() {
// add a blank chart
addChart();
// add the first series
addSeries(series_1_channel_id, series_1_field_number, series_1_read_api_key, series_1_results, series_1_color, series_1_name);
// add the second series
addSeries(series_2_channel_id, series_2_field_number, series_2_read_api_key, series_2_results, series_2_color, series_2_name);
});
// add the base chart
function addChart() {
// variable for the local date in milliseconds
var localDate;
// specify the chart options
var chartOptions = {
chart: {
renderTo: 'chart-container',
defaultSeriesType: 'line',
zoomType: 'x', // added here
backgroundColor: '#ffffff',
events: { }
},
title: { text: chart_title },
plotOptions: {
series: {
marker: { radius: 3 },
animation: true,
step: false,
borderWidth: 0,
turboThreshold: 0
}
},
tooltip: {
// reformat the tooltips so that local times are displayed
formatter: function() {
var d = new Date(this.x + (my_offset*60000));
var n = (this.point.name === undefined) ? '' : '<br>' + this.point.name;
return this.series.name + ':<b>' + this.y + '</b>' + n + '<br>' + d.toDateString() + '<br>' + d.toTimeString().replace(/\(.*\)/, "");
}
},
xAxis: {
type: 'datetime',
scrollbar: {
enabled: true,
barBackgroundColor: 'gray',
barBorderRadius: 7,
barBorderWidth: 0,
buttonBackgroundColor: 'gray',
buttonBorderWidth: 0,
buttonArrowColor: 'yellow',
buttonBorderRadius: 7,
rifleColor: 'yellow',
trackBackgroundColor: 'white',
trackBorderWidth: 1,
trackBorderColor: 'silver',
trackBorderRadius: 7
},
title: { text: 'Date' }
},
yAxis: { title: { text: y_axis_title } },
exporting: { enabled: true },
legend: { enabled: true },
credits: {
text: 'ThingSpeak.com',
href: 'https://thingspeak.com/',
style: { color: '#D62020' }
}
};
// draw the chart
my_chart = new Highcharts.Chart(chartOptions);
}
// add a series to the chart
function addSeries(channel_id, field_number, api_key, results, color, name) {
var field_name = 'field' + field_number;
// get the data with a webservice call
$.getJSON('https://api.thingspeak.com/channels/' + channel_id + '/fields/' + field_number + '.json?offset=0&round=2&results=' + results + '&api_key=' + api_key, function(data) {
// blank array for holding chart data
var chart_data = [];
// iterate through each feed
$.each(data.feeds, function() {
var point = new Highcharts.Point();
// set the proper values
var value = this[field_name];
point.x = getChartDate(this.created_at);
point.y = parseFloat(value);
// add location if possible
if (this.location) { point.name = this.location; }
// if a numerical value exists add it
if (!isNaN(parseInt(value))) { chart_data.push(point); }
});
// add the chart data
my_chart.addSeries({ data: chart_data, name: data.channel[field_name], color: color });
});
}
// converts date format from JSON
function getChartDate(d) {
// offset in minutes is converted to milliseconds and subtracted so that chart's x-axis is correct
return Date.parse(d) - (my_offset * 60000);
}
</script>
<style type="text/css">
body { background-color: white; height: 100%; margin: 0; padding: 0; }
#chart-container { width: 800px; height: 400px; display: block; position:absolute; bottom:0; top:0; left:0; right:0; margin: 5px 15px 15px 0; overflow: hidden; }
</style>
<!DOCTYPE html>
<html style="height: 100%;">
<head>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="//code.highcharts.com/stock/highstock.js"></script>
<script type="text/javascript" src="//thingspeak.com/exporting.js"></script>
</head>
<body>
<div id="chart-container">
// <img alt="Ajax loader" src="//thingspeak.com/assets/ajax-loader.gif" style="position: absolute; margin: auto; top: 0; left: 0; right: 0; bottom: 0;" />
</div>
</body>
</html>
I would also like to get the chart updating automatically, so any help on that score would also be appreciated. The final issue I am having is trying to get the legend to display the sensor names properly: UV Index (red) should read "Zims Sensor" and UV Index (blue) should read "UVM30A"
Unfortunately I am not a developer, so I am trying to figure out how it works. I have some knowledge about PHP, HTML and CSS but unfortunately none about JavaScript. Below is my current code of Google Charts Data, it's imported by a module and the javascript code is in places inside the PHP file. Here is my code:
$js = "
google.setOnLoadCallback({$funcChart});
function {$funcChart}() {
var data = google.visualization.arrayToDataTable(".json_encode($data).");
var options = ".json_encode($options).";
var chart = new google.visualization.{$chart}(document.getElementById('{$container}'));
chart.draw(data, options);
}";
if(strpos($width, '%') !== false) {
JHtml::_('JABehavior.jquery');
$js .= "
jQuery(document).ready(function () {
jQuery(window).resize(function(){
{$funcChart}();
});
});
";
}
$doc = JFactory::getDocument();
$doc->addScriptDeclaration($js);
require JModuleHelper::getLayoutPath($module->module, $params->get('layout', 'default'));
}
How do I add a responsive function into the above code? The current chart looks weird on my page; http://goo.gl/v1GVWk
If you open the page and scroll to the "Trekking Map" tab then you will see the chart, but it looks very bad.
Try Using Following Code
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(initChartExpertBottom);
$(window).on("resize", function (event) {
initChartExpertBottom();
});
function initChartExpertBottom() {
var options = {
legend:'none',
width: '100%',
height: '100%',
tooltip: { isHtml: true },
chartArea: {left: "3%",top: "3%",height: "94%",width: "94%"},
colors: ['#7CB5EC', '#5C5C61','#16c104'],
pieHole: 0.50,
pieStartAngle: -90,
is3D: false,
pieSliceText: 'none',
};
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 11],
['Eat', 2],
["Hide" , (11+2)] //addition of value of all elements
]);
drawChartExpertBottom(data, options);
}
function drawChartExpertBottom(data, options) {
var tooltip = [
Math.round((11/(11+2))*100) + "%",
Math.round((2/(11+2))*100)+ "%",
"Hiii3",
];
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
var sliceid = 0;
function eventHandler(e){
chart.setSelection([e]);
try {
selection = chart.getSelection();
sliceid = selection[0].row;
}
catch(err) {
;
}
$(".google-visualization-tooltip-item-list li:eq(0)").css("font-weight", "bold");
$(".google-visualization-tooltip-item-list li:eq(1)").html(tooltip[sliceid]).css("font-family", "Arial");
}
google.visualization.events.addListener(chart, 'onmousedown', eventHandler);
google.visualization.events.addListener(chart, 'onmouseover', eventHandler);
chart.draw(data, options);
}
</script>
HTML for above script
<div id="piechart"></div>
Css for above code snippet
<style>
#piechart {
top: 0;
left: 0;
width:100%;
height:100%;
}
.google-visualization-tooltip{
display:table;
}
g{
cursor:pointer;
}
</style>
I am attempting to add this example to a content management system. The mapping feature will then be modified to meet our needs once it works in all 4 browsers. No i cant give you any more info on the CMS as it is private. Please dont mention some of the code using the character entities. ex < is & lt;
Ie8 claims L is not defined.
Chrome claims uncaught reference error L is not defined.
However FF21 and Safari 5.1.7 have no issues displaying this example http://leafletjs.com/examples/choropleth.html
Why is it when the example is inside the CMS some browsers wont display the map. Is this poor coding from the demo? Is this a difference of how the scripts are loaded. What is the best way to go about troubleshooting this?
The doctype is frameset because of the CMS.
<html>
<head>
<title>Leaflet Layers Control Example</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="http://leafletjs.com/examples/dist/leaflet.ie.css" /></link><![endif]-->
<style>
#map {
width: 800px;
height: 500px;
}
.info {
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}
.info h4 {
margin: 0 0 5px;
color: #777;
}
.legend {
text-align: left;
line-height: 18px;
color: #555;
}
.legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.js"></script>
<script type="text/javascript" src="http://leafletjs.com/examples/us-states.js"></script>
<script type="text/javascript">
var map = L.map('map').setView([37.8, -96], 4);
var cloudmade = L.tileLayer('http://{s}.tile.cloudmade.com/{key}/{styleId}/256/{z}/{x}/{y}.png', {
attribution: 'Map data © 2011 OpenStreetMap contributors, Imagery © 2011 CloudMade',
key: 'BC9A493B41014CAABB98F0471D759707',
styleId: 22677
}).addTo(map);
// control that shows state info on hover
var info = L.control();
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function (props) {
this._div.innerHTML = '<h4>US Population Density</h4>' + (props ?
'<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>'
: 'Hover over a state');
};
info.addTo(map);
// get color depending on population density value
function getColor(d) {
return d > 1000 ? '#800026' :
d > 500 ? '#BD0026' :
d > 200 ? '#E31A1C' :
d > 100 ? '#FC4E2A' :
d > 50 ? '#FD8D3C' :
d > 20 ? '#FEB24C' :
d > 10 ? '#FED976' :
'#FFEDA0';
}
function style(feature) {
return {
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7,
fillColor: getColor(feature.properties.density)
};
}
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera) {
layer.bringToFront();
}
info.update(layer.feature.properties);
}
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
}
geojson = L.geoJson(statesData, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
map.attributionControl.addAttribution('Population data © US Census Bureau');
var legend = L.control({position: 'bottomright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
grades = [0, 10, 20, 50, 100, 200, 500, 1000],
labels = [],
from, to;
for (var i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
labels.push(
'<i style="background:' + getColor(from + 1) + '"></i> ' +
from + (to ? '–' + to : '+'));
}
div.innerHTML = labels.join('<br />');
return div;
};
legend.addTo(map);
</script>
</body>
</html>
The CMS is probably running in a secure zone (SSL / https://), then the unsecure Leaflet .js and .css resources (http://) won't be loaded in most browsers, and you get some 'L is undefined' error message. There are some browsers that do load unsecure elements.
Try to include the Leaflet resources from a https:// location.
Please dont mention some of the code using the character entities. ex < is & lt;
And yet your code works fine when I suppress them.
<html>
<head>
<title>Leaflet Layers Control Example</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="http://leafletjs.com/examples/dist/leaflet.ie.css" /></link><![endif]-->
<style>
#map {
width: 800px;
height: 500px;
}
.info {
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}
.info h4 {
margin: 0 0 5px;
color: #777;
}
.legend {
text-align: left;
line-height: 18px;
color: #555;
}
.legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.js"></script>
<script type="text/javascript" src="http://leafletjs.com/examples/us-states.js"></script>
<script type="text/javascript">
var map = L.map('map').setView([37.8, -96], 4);
var cloudmade = L.tileLayer('http://{s}.tile.cloudmade.com/{key}/{styleId}/256/{z}/{x}/{y}.png', {
attribution: 'Map data © 2011 OpenStreetMap contributors, Imagery © 2011 CloudMade',
key: 'BC9A493B41014CAABB98F0471D759707',
styleId: 22677
}).addTo(map);
// control that shows state info on hover
var info = L.control();
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function (props) {
this._div.innerHTML = '<h4>US Population Density</h4>' + (props ?
'<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>'
: 'Hover over a state');
};
info.addTo(map);
// get color depending on population density value
function getColor(d) {
return d > 1000 ? '#800026' :
d > 500 ? '#BD0026' :
d > 200 ? '#E31A1C' :
d > 100 ? '#FC4E2A' :
d > 50 ? '#FD8D3C' :
d > 20 ? '#FEB24C' :
d > 10 ? '#FED976' :
'#FFEDA0';
}
function style(feature) {
return {
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7,
fillColor: getColor(feature.properties.density)
};
}
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera) {
layer.bringToFront();
}
info.update(layer.feature.properties);
}
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
}
geojson = L.geoJson(statesData, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
map.attributionControl.addAttribution('Population data © US Census Bureau');
var legend = L.control({position: 'bottomright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
grades = [0, 10, 20, 50, 100, 200, 500, 1000],
labels = [],
from, to;
for (var i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
labels.push(
'<i style="background:' + getColor(from + 1) + '"></i> ' +
from + (to ? '–' + to : '+'));
}
div.innerHTML = labels.join('<br />');
return div;
};
legend.addTo(map);
</script>
</body>
</html>
Works fine on chrome. Try it yourself!