How can I overlap geojson collection with an other one with leaflet? - javascript

I create this with leaflet with 2 geojson collection.
My issue is I want blue to be above orange.
And is it possible to don't see the orange when blue is above ? and how to do it ?
This is my code (I have the same code for both geojson)
var fc2 = {
"type": "FeatureCollection",
"features": [unionA2]
}
L.geoJson(fc2, { // initialize layer with data
style: function (feature) {
return {
color: "#ea6621"
};
}
}).addTo(map);

Related

Passing data to leaflet from ag-grid programmitically

I am a total javascript/leaflet/ag-grid newbie, so please bear with me.
I am creating a website that allows users to query (add/remove) spatial points on a leaflet map based on selecting rows from ag-grid. I have no understanding/experience with React or Angular, so I am using vanilla javascript. Leaflet is used to display the data spatially.
I have spatial data that has GPS coordinates that are parent records. Each parent they have multiple children.
Spatial data
The spatial data is an external file I read into my HTML file. It looks like this:
var spatial_data = {
"type": "FeatureCollection",
"features": [
{ "type": "Feature",
"properties": { "Name": "Boulder 1", "SpatialID": "Lower Blair_0" },
"geometry": { "type": "Point", "coordinates": [ -105.39079766, 41.19044516, 2510.159912109375 ] } },
{ "type": "Feature",
"properties": { "Name": "Boulder 2", "SpatialID": "Upper Blair_1" },
"geometry": { "type": "Point", "coordinates": [ -105.39058423, 41.19655902, 2534.4599609375 ] } }
]};
Children records
There are children records for each parent spatial ID. The data is within the .js code.
The functionality I am hoping for is someone could filter the ag-grid for a route called 'Slam Dunk' and that would provide the "SpatialID":"Lower Blair_0". If they filter for 'Test two' it provides the same SpatialID. This would be available to play around within the HTML file.
myownscript.js
var rowData = [{"Route Name":"Slam Dunk","SpatialID":"Lower Blair_0"},
{"Route Name":"Test two","SpatialID":"Lower Blair_0"},
{"Route Name":"Test three","SpatialID":"Upper Blair_1"}];
var columnDefs= [
{field: 'Route Name', minWidth:10, sortable:true, filter:true},
{field: 'Sub-Area', minWidth:5, sortable:true, filter:true},
];
const gridOptions = {
columnDefs: columnDefs,
rowData: rowData,
defaultColDef:{
flex:1,
minWidth:100
},
rowSelection: 'multiple',
pagination:true
};
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
};
function grabFilteredData(){
let rowData = [];
gridOptions.api.forEachNodeAfterFilter(node => {
rowData.push(node.data.SpatialID);
});
var uniqueID = rowData.filter(onlyUnique);
return uniqueID;
}
document.addEventListener('DOMContentLoaded', () => {
const gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
});
I can easily send 'test' to the console. That provides me with the ability to check that my onSelectionChanged() is working; however, I really need to pass the output from onSelectionChanged() as an array. I need to pass that and use that in an embedded script within my HTML. This is so I can filter the data in my leaflet layers and features.
my html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Read in the geojson-->
<script src='assets/spatialdata.json'></script>
<script src="https://unpkg.com/ag-grid-community#27.0.1/dist/ag-grid-community.min.js"></script>
<script src="myownscript.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="bstrap/js/bootstrap.min.js"></script>
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css">
<link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-theme-alpine.css">
</head>
<body>
<script >
var sat_data = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox/satellite-streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: 'my.api.key'
});
var bounds = new L.LatLngBounds(new L.LatLng(41.008,-106.710), new L.LatLng(41.813,-104.861));
var baseMaps = {
"Satellite":sat_data
};
var map = L.map('map', {
center: [41.210, -105.360],
zoom: 11,
layers:[osm,sat_data],
noWrap:true,
maxBounds:bounds,
maxBoundsViscosit:1.0
});
L.control.layers(baseMaps).addTo(map);
var promise = $.getJSON("/assets/vedauwoo.geojson");
promise.then(function(data){
var allData = L.geoJson(data,{
onEachFeature: function(feature,layer){
layer.bindPopup('<h4> Area Name: '+feature.properties.Name+'</h4><p>Grades: '+feature.properties.Grade+'</p>');
}
});
var others = L.geoJson(data, {
onEachFeature: function(feature,layer){
layer.bindPopup('<h4> Area Name: '+feature.properties.Name+'</h4><p>Grades: '+feature.properties.Grade+'</p>');
},
filter: function(feature,layer){
}
});
var layerGroup = L.layerGroup().addTo(map);
allData.addTo(layerGroup)
$("#others").click(function() {
var dataToSubset = grabFilteredData();
var subset_data = L.geoJson(data, {
onEachFeature: function(feature,layer){
layer.bindPopup('<h4> Area Name: '+feature.properties.Name+'</h4><p>Grades: '+feature.properties.Grade+'</p>');
},
filter: function(feature,layer){
return dataToSubset.includes(feature.properties.SpatialID);
}
});
//Works in a hacky way by sending the ID over
layerGroup.removeLayer(allData)
layerGroup.addLayer(subset_data)
window.map_id = subset_data._leaflet_id;
});
$("#allData").click(function() {
layerGroup.removeLayer(map_id)
layerGroup.addLayer(allData)
});
</script>
</body>
</html>
I have tried extensive searching. For some reason, the majority of use cases for gridOptions.api.getSelectedRows() or forEachNodeAfterFilter end with an example of using console.log(). I need to actually pass that information along instead of just outputting to the console. I am not sure if this is a misunderstanding on my part for how JS works, or if it is expected behavior from ag-grid, but it doesn't seem possible.
This doesn't seem to work as the console.log() in the .js file doesn't work, and in the script in the HTML it can not find test.
I am primarily a statistician/python programmer, so this a new foray for me. It is likely I am missing a bigger picture thing and if so, I would appreciate alternatives to my current approach.
So once onSelectionChanged is called with the filtered rows - what script do you need to pass it to?
I assume you want to link the table with the leaflet map. If so, you need to
obtain a reference to the map object (see Leaflet docs)
create a GeoJSON layer based on the filtered Geometries and add it to the map.
If the filtering in the table and thus the leaflet layer data update happens multiple times, you need to remove the existing layer and add a new one, as far as I know. Check this post.

Uncaught TypeError: Cannot read property 'properties' of undefined in Leaflet smap-responsive

I am building a map with multiple geojsons in Leaflet and it has worked well on a normal size computer screen. It doesn't however work on smaller screens or Apple products and so I am attemting to move my code over to Smap-responsive https://github.com/getsmap/smap-responsive .
I have added a geojson following the given example and styled it based upon attributes, it looks how I want it to and the pop ups work how I want them to. The problem comes when I try to add a second geojson. When I click points on the first layer it works as it should but when I turn off that layer and turn on the second layer the popups don’t work on the second layer. If I refresh the page and try the second layer first, those popups work but then they don’t work on the first layer. The error i get is:
“Uncaught TypeError: Cannot read property 'properties' of undefined”
Here is the code:
var config = {
// These params are default and can be overridden by calling the map with e.g. http://mymap?center=13.1,55.6&zoom=17
params: {
// The map's centering from start. Coordinates should be in WGS 84 and given like [easting, northing] i.e. [longitude, latitude]
center: [14.0, 55.52],
// The initial zoom of the map, In this example I zoom out slightly if the screen is smaller than given number of pixels
zoom: $(window).width() < 600 ? 11 : 11
},
// Optional configuration object for the Leaflet map object. You can use all options specified here: http://leafletjs.com/reference.html#map-class
// mapConfig: {
// maxBounds: [ // Optional. Limit panning of the map. Given as [[north, west], [south, east]]
// [55.71628170645908, 12.6507568359375],
// [55.42589636057864, 13.34564208984375]
// ],
// minZoom: 11, // Optional. Limit how much you can zoom out. 0 is maximum zoomed out.
// maxZoom: 18 // Optional. Limit how much you can zoom in. 18 is usually the maximum zoom.
// },
smapOptions: {
// The text of the <title>-tag
title: "webbkartan",
// The favicon to be used
favIcon: "//assets-cdn.github.com/favicon.ico"
},
// -- Baselayers (background layers) --
bl: [
// -- An openstreetmap layer. Note that all layer types used as overlays can also be used as baselayers, and vice versa (see more layers below). --
{
init: "L.TileLayer",
url: '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
options: {
layerId: "osm",
displayName: "OSM",
attribution: '<span>© OpenStreetMap contributors</span> | <span>Tiles Courtesy of MapQuest <img src="//developer.mapquest.com/content/osm/mq_logo.png"></span>',
maxZoom: 18
}
}
],
// -- Overlays --
ol: [
{
init: "L.GeoJSON.WFS",
url: document.URL.search(/dev.html?/) > 0 ? "examples/data/recipient.geojson" : "../examples/data/recipient.geojson",
options: {
displayName: "Totalkväve halt",
category: ["Status"],
layerId: "kvave",
attribution: "",
inputCrs: "EPSG:4326",
uniqueKey: "Nr",
selectable: true,
reverseAxis: false,
reverseAxisBbox: true,
geomType: "POINT",
legend:"examples/data/legend/kvave_legend.jpg",
popup:
'<h4>Punkt ${Nr} </h4>'+
'<br><img src="examples/data/diagram/' + '${Ar_kvav}' + '"/ width=400>'+
'<img src="examples/data/diagram/' + '${Man_kvav}' + '"/ width=400>'+
'<p><font size=2>'+ '${Plats}'+
'<br><b> Frekvens: </b>${frekvens_g}/år'+
'<br><b> Senast provtagning: </b> ${sist_anv}'+
'<br><b> Nuvarande status: </b> ${Status_fos} status'+
'<br><b> Senaste uppdaterad: </b> ${uppdaterad}</p>',
style:function(feature){
switch (feature.properties.Status_kva){
case "Extremt hög halt" : return {color: '#FF000D'};
case "Mycket hög halt": return {color: '#FFBB00'};
case null: return {color: '#8C8C89'};
};
}
}
},
{
init: "L.GeoJSON.WFS",
url: document.URL.search(/dev.html?/) > 0 ? "examples/data/recipient.geojson" : "../examples/data/recipient.geojson",
options: {
displayName: "Totalfosfor status",
category: ["Status"],
layerId: "fosfor",
attribution: "",
inputCrs: "EPSG:4326",
uniqueKey: "OBJECTID",
selectable: true,
reverseAxis: false,
reverseAxisBbox: true,
geomType: "POINT",
legend:"examples/data/legend/fos_legend.jpg",
popup:
'<h4>Punkt ${Nr} </h4>'+
'<br><img src="examples/data/diagram/' + '${Ar_fos}' + '"/ width=400>'+
'<img src="examples/data/diagram/' + '${Man_fos}' + '"/ width=400>'+
'<p><font size=2>'+ '${Plats}'+
'<br><b> Frekvens: </b>${frekvens_g}/år'+
'<br><b> Senast provtagning: </b> ${sist_anv}'+
'<br><b> Nuvarande status: </b> ${Status_fos} status'+
'<br><b> Senaste uppdaterad: </b> ${uppdaterad}</p>',
style:function(feature){
switch (feature.properties.Status_fos){
case "Hög" : return {color:'#02A0F5', fillColor: '#02A0F5', fillOpacity:1};
case "God" : return {color:'#29D637', fillColor: '#29D637', fillOpacity:1};
case "Otillfredsställande" : return {color: '#F5AA07', fillColor: '#F5AA07', fillOpacity:1};
case "Dålig": return {color:'#FC0000', fillColor: '#FC0000', fillOpacity:1};
case null: return {color:'#8C8C89', fillColor: '#8C8C89',fillOpacity:1 };
};
}
}
},
],
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Plugins are Leaflet controls. The options of a control
// given here, will override the options in the control.
// Thereby, you can manage everything the control lets
// you manage from this config file – without having to
// edit the plugin itself.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
plugins: [
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Scale is Leaflet's in-built scale bar control. See options: http://leafletjs.com/reference.html#control-scale
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Scale",
options: {
imperial: false
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// LayerSwitcher is a responsive layer menu for both overlays and baselayers.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.LayerSwitcher",
options: {
toggleSubLayersOnClick: false, // If true, all layers below this header will be turned on when expanding it.
unfoldOnClick: true, // If true, clicking anywhere on a header will unfold it. If false, user has to click on the icon next the header text.
unfoldAll: false, // If true, all subheaders will be unfolded when unfolding a header.
olFirst: false, // If true, the overlays panel is shown at the top
pxDesktop: 992, // Breakpoint for switching between mobile and desktop switcher
btnHide: true, // Show a hide button at the top header
catIconClass: "fa fa-chevron-right" // Icon class for foldable headers
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Zoombar creates a custom zoombar with [+] and [-] buttons.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Zoombar",
options: {}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Geolocate shows the users position. Based on the HTML5 geolocation API.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Geolocate",
options: {
position: 'bottomright', // Button's position
locateOptions: {
maxZoom: 17, // Maximum auto-zoom after finding location
enableHighAccuracy: true // true: Will turn on GPS if installed (better accuracy but uses more battery)
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// SelectVector is needed to make WMS layers selectable
// using getfeatureinfo requests.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.SelectWMS",
options: {
wmsVersion: "1.3.0", // The WMS version to use in the getfeatureinfo request
info_format: "text/plain", // The fallback info format to fetch from the WMS service. Overridden by layer's info_format in layer's selectOptions.
maxFeatures: 20, // Max features to fetch on click
buffer: 12, // Buffer around click (a larger number makes it easier to click on lines and points)
useProxy: false // If you want call the URL with a prepended proxy URL (defined in ws above)
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// SelectVector is needed in order to make vector (e.g. WFS) layers selectable.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.SelectVector",
options: {
// The select style.
selectStyle: {
weight: 5,
color: '#00FFFF',
fillColor: '#00FFFF',
opacity: 1,
fillOpacity: .5
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Search connects to a autocomplete and geolocate service and places a marker
// at the geolocated location.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Search",
options: {
_lang: {
// Watermark/placeholder for text entry. Language dependent.
"en": {search: "Search address or place"}, // english
"sv": {search: "Sök adress eller plats"} // swedish
},
gui: true, // If false, entry is not shown but the plugin can still take the POI URL parameter
whitespace: "%20", // How to encode whitespace.
wsOrgProj: "EPSG:3008", // The projection of the returned coordinates from the web service
useProxy: false, // If you want call the URL with a prepended proxy URL (defined in ws above)
wsAcUrl: "//kartor.malmo.se/api/v1/addresses/autocomplete/", // Required. Autocomplete service.
wsLocateUrl: "//kartor.malmo.se/api/v1/addresses/geolocate/", // Required. Geolocate service.
acOptions: { // typeahead options (Bootstrap's autocomplete library)
items: 100 // Number of options to display on autocomplete
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Print creates a downloadable image server-side. Requires Geoserver and the plugin "Mapfish print".
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// {
// init: "L.Control.Print",
// options: {
// printUrl: "//kartor.malmo.se/print-servlet/leaflet_print/", // The print service URL
// position: "topright" // Button's position
// }
// },
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// ShareLink adds a button which, on click, will create a
// URL which recreates the map, more or less how it looked like.
// It is up to other plugins to add and receive URL parameters by
// listening to the events:
// - Create params: "smap.core.createparams"
// - Apply params: "smap.core.beforeapplyparams" or "smap.core.applyparams"
// For instance:
//
// smap.event.on("smap.core.createparams", function(e, paramsObject) {
// paramsObject.myparameter = 3;
// });
// smap.event.on("smap.core.applyparams", function(e, paramsObject) {
// alert(paramsObject.myparameter);
// });
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.ShareLink",
options: {
position: "topright",
root: location.protocol + "//malmo.se/karta?" // location.protocol + "//kartor.malmo.se/init/?appid=stadsatlas-v1&" // Link to malmo.se instead of directly to map
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// RedirectClick opens a new browser tab when the user clicks on the map.
// The easting ${x} and northing ${y} is sent along to the url. See example below.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init : "L.Control.RedirectClick", // Pictometry
options: {
position: "topright", // Button's position
url: "http://kartor.malmo.se/urbex/index.htm?p=true&xy=${x};${y}", // Malmö pictometry
btnClass: "fa fa-plane", // Button's icon class
cursor: "crosshair" // Cursor shown in map before click
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Info simply creates a toggleable Bootstrap modal which you can fill with any info below.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Info",
options: {
addToMenu: false, // Create toggle button or not
position: "topright", // Button's position (requires addToMenu == true)
autoActivate: false, // Open from start
// Here follows the content of the modal – language dependent!
_lang: {
"en": {
titleInfo: "<h4>A header</h4>",
bodyContent:
'<p>Some content</p>'
},
"sv": {
titleInfo: "<h4>En rubrik</h4>",
bodyContent:
'<p>Lite innehåll</p>'
}
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// MeasureDraw is a combined measure and drawing tool. The created
// markers, lines or polygons can be shared with others
// (geometries and attributes sent along as a URL parameter).
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.MeasureDraw",
options: {
position: "topright", // Button's position
saveMode: "url", // So far url is the only option
layerName: "measurelayer", // The internal layerId for the draw layer
stylePolygon: { // Draw style for polygons
color: '#0077e2',
weight: 3
},
stylePolyline: { // Draw style for polylines
color: '#0077e2',
weight: 9
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// ToolHandler takes care of making all buttons inside the top-right div responsive.
// When the screen width is smaller than the defined breakpoint, the buttons are contained
// within a Bootstrap popover which can be toggled by a single button.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.ToolHandler",
options: {
showPopoverTitle: false // Show title (header) in the popover
}
}
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Add2HomeScreen creates a popover on iOS devices supporting
// "Add To Homescreen", which advices the user to add the website
// to the homescreen, making it look almost like a native app.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// {
// init: "L.Control.Add2HomeScreen",
// options: {}
// }
]
};
The error points to "feature.properties." in the function that sets the colors of the first layer I turn on and it comes when I click to get a pop up on the second layer I have turned on. I haven't had this problem when using Leaflet without smap-resonsive.
I have tried moving the function out to an external js. file, defining the functions with "var something =". I have tried calling the colors direct from an attribute also but all give the same error.
I am new to Leaflet and Javascript, any help appreciated!
The error was caused by bug which meant that only the uppermost layer was selectable. Described here:
https://github.com/getsmap/smap-responsive/issues/198
Thanks to Johan Lahti for a quick reposonse in solving the problem!

Best method to label polygon in leaflet?

I am labeling 6 polygons in a GeoJson file. I am using the circleMarker on the each polygon centroid then calling .bindLabel, but I get this error: "circleMarker.bindLabel is not a function". Leaflet.label.js is called.
The map.
Code for GeoJSON:
var districts = L.geoJson(null, {
style: function (feature) {
return {
weight: 1,
opacity: 1,
color: 'blueviolet',
fillColor: 'plum',
fillOpacity: 0.5
};
},
onEachFeature: function (feature, layer) {
layer.on('mouseover', function () {
this.setStyle({
'fillColor': '#0000ff'
});
});
layer.on('mouseout', function () {
this.setStyle({
'fillColor': 'plum'
});
});
layer.on('click', function () {
window.location = feature.properties.URL;
});
var circleMarker = L.circleMarker(layer.getBounds().getCenter());
// e.g. using Leaflet.label plugin
circleMarker.bindLabel(feature.properties['NAME'], { noHide: true })
.circleMarker.addTo(map);
}
});
$.getJSON("data/districts.geojson", function (data) {
districts.addData(data);
});
You're calling a circleMarker method on your circleMarker object instance. That will never work. L.CircleMarker doesn't have a circleMarker method. This won't work:
circleMarker.bindLabel(feature.properties['NAME'], { noHide: true }).circleMarker.addTo(map);
This will:
circleMarker.bindLabel(feature.properties['NAME'], { noHide: true }).addTo(map);
And this will too:
circleMarker.bindLabel(feature.properties['NAME'], { noHide: true });
circleMarker.addTo(map);
But if you want to add a label without using L.CircleMarker you can simply do:
onEachFeature: function (feature, layer) {
layer.bindLabel(feature.properties['NAME'], { 'noHide': true });
}
You're also loading your scripts in the incorrect order:
<script src="assets/leaflet-label/leaflet.label.js"></script>
<script src="assets/leaflet-0.7.2/leaflet.js"></script>
Leaflet.label wants to extend classes from Leaflet, but it can't because Leaflet itself isn't loaded yet. So yes, you've loaded Leaflet.label, just not at the correct time. You could see this in your console, because Leaflet.label should throw an error when it doesn't find Leaflet. The correct way:
<script src="assets/leaflet-0.7.2/leaflet.js"></script>
<script src="assets/leaflet-label/leaflet.label.js"></script>

Polygon labels with Leaflet

Using leaflet 7.3 and polygon data in GeoJSON, how can I add labels from field: NAME?
Here is example of current GeoJSON polygon data. I would like to enable fixed labels in center of polygon, overlap OK.
var districts = L.geoJson(null, {
style: function (feature) {
return {
color: "green",
fill: true,
opacity: 0.8
};
},
onEachFeature(feature, layer) {
layer.on('mouseover', function () {
this.setStyle({
'fillColor': '#0000ff'
});
});
layer.on('mouseout', function () {
this.setStyle({
'fillColor': '#ff0000'
});
});
layer.on('click', function () {
window.location = feature.properties.URL;
});
}
});
$.getJSON("data/districts.geojson", function (data) {
districts.addData(data);
});
In onEachFeature callback, you can get the center of the L.Polygon created by GeoJSON layer and bind a label to it.
var polygonCenter = layer.getBounds().getCenter();
// e.g. using Leaflet.label plugin
L.marker(polygonCenter)
.bindLabel(feature.properties['NAME'], { noHide: true })
.addTo(map);
Here is an example: http://jsfiddle.net/FranceImage/ro54bqbz/ using Leaflet.label

reactive chart with chart.js in meteor

i am using chart.js to generate charts in a meteor app.
Here is my code
function drawChart(){
var data = [
{
value: Policies.find({'purchased_cover.trip_type': 'Single Trip'}).count(),
color:"#F38630"
},
{
value :Policies.find({'purchased_cover.trip_type': 'Annual Multi-Trip'}).count(),
color : "#E0E4CC"
},
{
value : Policies.find({'purchased_cover.trip_type': 'Backpacker'}).count(),
color : "#69D2E7"
},
{
value :Policies.find({'purchased_cover.trip_type': 'Golf Annual'}).count(),
color : "green"
},
{
value :Policies.find({'purchased_cover.trip_type': 'Golf'}).count(),
color : "red"
},
{
value :Policies.find({'purchased_cover.trip_type': 'Winter Sports Annual'}).count(),
color : "yellow"
}
]
var ctx = $("#pieChart").get(0).getContext("2d");
var myPieChart = new Chart(ctx);
new Chart(ctx).Pie(data);
}
Template.charts.rendered = function(){
drawChart();
};
i have few helpers to display the count in html templates and it works fine whenever the counts changes but the chart is not changing until i reload the page..i want the chart to be reactive to the changes in the collection.
You can use Tracker.autorun to rerun drawChart whenever reactive data sources it depends on change:
if (Meteor.isClient) {
function drawChart() {
...
}
Tracker.autorun(drawChart());
}

Categories