Initial commit

This commit is contained in:
zhongjin
2020-06-13 18:34:34 +08:00
commit 52aaa9f15d
655 changed files with 96796 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
<html>
<head>
<title>Refactoria</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../dist/public/carto.js"></script>
<style>
* {
box-sizing: border-box;
}
body, *{ margin: 0; padding: 0; }
#map {
position: absolute;
height: 400px;
width: 50%;
top: 100px;
z-index: 0;
}
</style>
</head>
<body>
<span>Popups should position correctly even if page is scrolled</span>
<div id="map"></div>
<div style="height: 1200px; width: 3000px;"></div>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const populatedPlacesSource = new carto.source.Dataset(`
ne_10m_populated_places_simple
`);
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle, {
featureOverColumns: ['name', 'pop_max', 'pop_min']
});
client.addLayer(populatedPlacesLayer);
client.getLeafletLayer().addTo(map);
const popup = L.popup({ closeButton: false });
function openPopup(featureEvent) {
let content = '<div class="widget">';
if (featureEvent.data.name) {
content += `<h2 class="h2">${featureEvent.data.name}</h2>`;
}
if (featureEvent.data.pop_max || featureEvent.data.pop_min) {
content += `<ul>`;
if (featureEvent.data.pop_max) {
content += `<li><h3>Max:</h3><p class="open-sans">${featureEvent.data.pop_max}</p></li>`;
}
if (featureEvent.data.pop_min) {
content += `<li><h3>Min:</h3><p class="open-sans">${featureEvent.data.pop_min}</p></li>`;
}
content += `</ul>`;
}
content += `</div>`;
popup.setContent(content);
popup.setLatLng(featureEvent.latLng);
if (!popup.isOpen()) {
popup.openOn(map);
}
}
function closePopup(featureEvent) {
popup.removeFrom(map);
}
function setPopupsClick() {
populatedPlacesLayer.off('featureOver');
populatedPlacesLayer.off('featureOut');
populatedPlacesLayer.on('featureClicked', openPopup);
}
setPopupsClick();
</script>
</body>
</html>
@@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width">
<!-- Include Carto.js -->
<script src="../../dist/public/carto.js"></script>
<!-- Include Leaflet -->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places,visualization,drawing"></script>
</head>
<body>
<button onclick="LAYERS.loadLayer('europe')">Activar capa</button>
<button onclick="LAYERS.removeLayer('europe')">Desactivar capa</button>
<div id="map" style="width: 100%;height: 96vh;"></div>
<script>
const MAP = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: { lat: 0, lng: 0 }
});
var LAYERS = {
populatedPlaces: {
loaded: false,
client: new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
}),
source: new carto.source.Dataset('ne_10m_populated_places_simple'),
cartoCSS: new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`),
},
europe: {
loaded: false,
client: new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
}),
source: new carto.source.Dataset('ne_adm0_europe'),
cartoCSS: new carto.style.CartoCSS(`
#layer {
polygon-fill: #826DBA;
polygon-opacity: 0.8;
::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 0.8;
}
}
`),
},
loadLayer: function (layerName) {
const dataset = LAYERS[layerName];
const layer = new carto.layer.Layer(dataset.source, dataset.cartoCSS, {});
window.layers = window.layers || {};
window.layers[layerName] = layer;
dataset.client.addLayer(layer)
if (!dataset.loaded) {
MAP.overlayMapTypes.push(dataset.client.getGoogleMapsMapType(MAP));
dataset.loaded = true;
}
},
removeLayer: function (layerName) {
const dataset = LAYERS[layerName];
const layer = dataset.client.getLayers()[0];
dataset.client.removeLayer(layer);
}
};
LAYERS.loadLayer('europe');
LAYERS.loadLayer('populatedPlaces');
</script>
</body>
</html>
+268
View File
@@ -0,0 +1,268 @@
{
"main": {
"file": {
"leaflet": "public/layers/change-order-leaflet.html",
"gmaps": "public/layers/change-order-gmaps.html"
}
},
"categories": [
{
"title": "Basics",
"samples": [
{
"title": "Add a layer",
"desc": "Add one CARTO layer to your map",
"file": {
"leaflet": "public/layers/single-layer-leaflet.html",
"gmaps": "public/layers/single-layer-gmaps.html"
}
},
{
"title": "Add more layers",
"desc": "Add multiple CARTO layers to your map",
"file": {
"leaflet": "public/layers/multilayer-leaflet.html",
"gmaps": "public/layers/multilayer-gmaps.html"
}
},
{
"title": "Change the source",
"desc": "Update the source of your layers",
"file": {
"leaflet": "public/layers/change-source-leaflet.html",
"gmaps": "public/layers/change-source-gmaps.html"
}
},
{
"title": "Change the style",
"desc": "Update the style of your layers",
"file": {
"leaflet": "public/layers/change-style-leaflet.html",
"gmaps": "public/layers/change-style-gmaps.html"
}
},
{
"title": "Move the layers",
"desc": "Update the order of your layers",
"file": {
"leaflet": "public/layers/change-order-leaflet.html",
"gmaps": "public/layers/change-order-gmaps.html"
}
},
{
"title": "Server tile aggregation",
"desc": "Apply smart backend aggregation",
"file": {
"leaflet": "public/layers/layer-with-aggregation-leaflet.html",
"gmaps": "public/layers/layer-with-aggregation-gmaps.html"
}
},
{
"title": "Server tile aggregation with cluster of points",
"desc": "Apply smart backend aggregation to create a cluster of points",
"file": {
"leaflet": "public/layers/layer-with-aggregation-cluster-leaflet.html",
"gmaps": "public/layers/layer-with-aggregation-cluster-gmaps.html"
}
}
]
},
{
"title": "Interactivity",
"samples": [
{
"title": "Detect feature click",
"desc": "Interact with the features on the click event",
"file": {
"leaflet": "public/layers/feature-click-leaflet.html",
"gmaps": "public/layers/feature-click-gmaps.html"
}
},
{
"title": "Detect feature over/out",
"desc": "Interact with the features on the over/out events",
"file": {
"leaflet": "public/layers/feature-over-out-leaflet.html",
"gmaps": "public/layers/feature-over-out-gmaps.html"
}
},
{
"title": "Change the feature columns",
"desc": "Change the columns returned in the feature event",
"file": {
"leaflet": "public/layers/change-feature-columns-leaflet.html",
"gmaps": "public/layers/change-feature-columns-gmaps.html"
}
}
]
},
{
"title": "Widgets",
"samples": [
{
"title": "Formula widget",
"desc": "Create a widget with the formula dataview",
"file": "public/dataviews/formula.html"
},
{
"title": "Category widget",
"desc": "Create a widget with the category dataview",
"file": "public/dataviews/category.html"
},
{
"title": "Histogram widget",
"desc": "Create a widget with the histogram dataview",
"file": "public/dataviews/histogram.html"
},
{
"title": "Time Series widget",
"desc": "Create a widget with the time series dataview",
"file": "public/dataviews/time-series.html"
},
{
"title": "Bounding Box filter",
"desc": "Apply a map bounding box filter to the widgets",
"file": {
"leaflet": "public/filters/bounding-box-leaflet.html",
"gmaps": "public/filters/bounding-box-gmaps.html"
}
},
{
"title": "Circle filter",
"desc": "Apply a circle filter to the widgets",
"file": "public/filters/circle-filter.html"
},
{
"title": "Polygon filter",
"desc": "Apply a polygon filter to the widgets",
"file": "public/filters/polygon-filter.html"
},
{
"title": "Status and error handling",
"desc": "Manage the status and erros in dataviews",
"file": "public/dataviews/error-handling.html"
}
]
},
{
"title": "Filters",
"samples": [
{
"title": "Category Filter",
"desc": "Create a Category filter with checkbox selectors",
"file": "public/filters/category-filter.html"
},
{
"title": "Range Filter",
"desc": "Create a Range filter with a range slider",
"file": "public/filters/range-filter.html"
},
{
"title": "AND Filter",
"desc": "Apply an AND filter to combine multiple filters",
"file": "public/filters/and-filter.html"
},
{
"title": "Complex Filter",
"desc": "Apply several combined filters to a dataset",
"file": "public/filters/complex-filter.html"
}
]
},
{
"title": "Misc",
"samples": [
{
"title": "Guide",
"desc": "Full reference guide example",
"file": {
"leaflet": "public/misc/guide-leaflet.html",
"gmaps": "public/misc/guide-gmaps.html"
}
},
{
"title": "Pop-Ups",
"desc": "Create pop-up information windows and interact with your map",
"file": {
"leaflet": "public/misc/popups-leaflet.html",
"gmaps": "public/misc/popups-gmaps.html"
}
},
{
"title": "Pop-Ups with embed videos",
"desc": "Create pop-up information windows with embed videos.",
"file": {
"leaflet": "public/misc/popups-video-leaflet.html",
"gmaps": "public/misc/popups-video-gmaps.html"
}
},
{
"title": "Legends",
"desc": "Create dynamic legends",
"file": {
"leaflet": "public/misc/legends-leaflet.html",
"gmaps": "public/misc/legends-gmaps.html"
}
},
{
"title": "Most/less populated places",
"desc": "Filter the 20 most/less populated places in the world",
"file": {
"leaflet": "public/misc/populated-places-leaflet.html",
"gmaps": "public/misc/populated-places-gmaps.html"
}
},
{
"title": "Edit SQL & CartoCSS",
"desc": "Edit manually the SQL query and the CartoCSS style",
"file": {
"leaflet": "public/misc/edit-sql-cartocss-leaflet.html",
"gmaps": "public/misc/edit-sql-cartocss-gmaps.html"
}
},
{
"title": "Error handling",
"desc": "Handle common errors in maps",
"file": {
"leaflet": "public/misc/error-handling-leaflet.html",
"gmaps": "public/misc/error-handling-gmaps.html"
}
},
{
"title": "Hexagon aggregation",
"desc": "Aggregate point data into hexagon grid",
"file": {
"leaflet": "public/misc/hexagon-aggregation-leaflet.html",
"gmaps": "public/misc/hexagon-aggregation-gmaps.html"
}
},
{
"title": "Filter data using drawing tools",
"desc": "Filter data based on a drawn circle",
"file": {
"leaflet": "public/misc/filter-data-map-leaflet.html",
"gmaps": "public/misc/filter-data-map-gmaps.html"
}
},
{
"title": "Dropdown menu with data from CARTO dataset",
"desc": "Look for data within your dataset using dropdown menu.",
"file": {
"leaflet": "public/misc/custom-search-dataset-leaflet.html",
"gmaps": "public/misc/custom-search-dataset-gmaps.html"
}
},
{
"title": "Storymap using CARTO.js and Storymap.js",
"desc": "Create a storytelling map using Storymap.js",
"file": "public/misc/storymap-leaflet.html"
},
{
"title": "Pie Chart Widget using CARTO.js and Vega-Lite",
"desc": "Create a map with a pie chart using Vega Lite and CARTO.js category dataviews.",
"file": "public/misc/piechart-vega.html"
}
]
}
]
}
+44
View File
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Examples | CARTO</title>
<link type="text/css" rel="stylesheet" href="../../docs/v4/styles/jsdoc-default.css">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<h1 class="page-title">Examples</h1>
<div id="container" style="margin-left:48px;"></div>
<h4 style="margin-left:30px">CDN:<a href="../dist/public/carto.js"> ../dist/public/carto.js</a></h4>
<script>
$(function () {
$.getJSON('./examples.json').done(function(data) {
renderCategories(data.categories);
});
function renderCategories(categories) {
var $container = $('#container');
categories.forEach(function (category) {
const $category = $(`<h2>${category.title}</h2>`);
const $samples = $(`<ul></ul>`);
if (category.samples) {
category.samples.forEach(function (sample) {
let link = ''
if (typeof sample.file === 'string') {
link = `(<a href="${sample.file}">Link</a>)`;
} else {
link = `(<a href="${sample.file.leaflet}">Leaflet</a> | <a href="${sample.file.gmaps}">Google Maps</a>)`;
}
const $sample = $(`<li><h3>${sample.title} <span style="font-size:0.8em;">${link}</span></h3></li>`);
$samples.append($sample);
});
}
$container.append($category);
$container.append($samples);
});
}
});
</script>
</body>
</html>
+351
View File
@@ -0,0 +1,351 @@
<!DOCTYPE html>
<html>
<head>
<title>Basemap selector | CARTO</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="shortcut icon" href="http://cartodb.com/assets/favicon.ico" />
<link rel="stylesheet" href="../../dist/internal/themes/css/cartodb.css" />
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<style>
html {
font-family: 'Open Sans';
}
html,
body,
#map {
height: 100%;
padding: 0;
margin: 0;
}
#basemapSelector {
background: white;
right: 30px;
top: 30px;
padding: 10px;
position: absolute;
}
#basemapSelector h1 {
font-size: 1.6em;
line-height: 120%;
}
#basemapSelector h2 {
font-size: 1.2em;
line-height: 120%;
}
#basemapSelector ul {
margin: 10px 0;
}
</style>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="map"></div>
<div id="basemapSelector">
<h1>Basemap selector</h1>
<h2>CartoDB</h2>
<ul>
<li>
<a href="#" class="js-basemap" data-basemap-id="cartodb-positron" data-provider="leaflet">Positron</a>
</li>
<li>
<a href="#" class="js-basemap" data-basemap-id="cartodb-dark-matter" data-provider="leaflet">Dark Matter</a>
</li>
</ul>
<h2>Google Maps</h2>
<ul>
<li>
<a href="#" class="js-basemap" data-basemap-id="gmaps-roadmap" data-provider="googlemaps">Roadmap</a>
</li>
<li>
<a href="#" class="js-basemap" data-basemap-id="gmaps-satellite" data-provider="googlemaps">Satellite</a>
</li>
</ul>
</div>
<!-- include google maps library -->
<script type="text/javascript" src="http://www.maps.google.com/maps/api/js?key=AIzaSyCk5gRspKeHNJ0sS6iZotUsQvlAkXsieFg&v=3.32"></script>
<!-- include cartodb.js library -->
<script src="../../dist/internal/cartodb.uncompressed.js"></script>
<script>
var BASEMAPS = {
'cartodb-positron': {
'urlTemplate': 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png',
'attribution': '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
},
'cartodb-dark-matter': {
'urlTemplate': 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png',
'attribution': '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
},
'gmaps-roadmap': {
'baseType': 'roadmap',
'style': '[]'
},
'gmaps-satellite': {
'baseType': 'satellite',
'style': '[]'
}
};
var currentProvider = 'leaflet';
var cartoDBMap;
function replaceBasemap(newProvider, basemapId) {
var basemapAttrs = BASEMAPS[basemapId];
if (!cartoDBMap) throw new Error('map not initialised yet');
if (!basemapAttrs) throw new Error('unknown basemap');
// Remove the current baselayer
cartoDBMap.removeLayerAt(0);
var changingProvider = currentProvider !== newProvider;
var createLayerMethod;
if (newProvider === 'googlemaps') {
createLayerMethod = cartoDBMap.createGMapsBaseLayer;
} else { // leaflet
createLayerMethod = cartoDBMap.createTileLayer;
}
createLayerMethod.call(cartoDBMap, basemapAttrs, {
at: 0,
silent: changingProvider
});
if (changingProvider) {
cartoDBMap.set('provider', newProvider);
currentProvider = newProvider;
}
}
$('.js-basemap').click(function (e) {
e.preventDefault();
replaceBasemap($(this).data('provider'), $(this).data('basemap-id'));
});
function main() {
var vizjson = {
"id": "2b13c956-e7c1-11e2-806b-5404a6a683d5",
"version": "0.1.0",
"title": "european_countries_e 0",
"likes": 0,
"description": null,
"scrollwheel": true,
"legends": true,
"url": null,
"map_provider": "leaflet",
"center": "[52.5897007687178, 52.734375]",
"zoom": 4,
"updated_at": "2015-03-13T11:24:37+00:00",
"datasource": {
"user_name": "documentation",
"maps_api_template": "http://{user}.cartodb.com:80",
"force_cors": true, // This is sometimes set in the editor,
"stat_tag": "84ec6844-4b4b-11e5-9c1d-080027880ca6"
},
"layers": [
{
"options": {
"id": "0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order": 0,
"visible": true,
"type": "Tiled",
"name": "Positron",
"className": "default positron_rainbow",
"baseType": "positron_rainbow",
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
"read_only": true,
"minZoom": "0",
"maxZoom": "18",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"subdomains": "abcd",
"category": "CartoDB"
},
"infowindow": null,
"tooltip": null,
"id": "0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order": 0,
"type": "tiled"
},
{
"id": "923b7812-2d56-41c6-ac15-3ce430db090f",
"type": "CartoDB",
"infowindow": {
"fields": [
{
"name": "name",
"title": true,
"position": 4
}
],
"template": '' +
'<div class="CDB-infowindow CDB-infowindow--custom js-infowindow" style="max-width: 200px;">' +
'<div class="CDB-infowindow-close js-close"></div>' +
'<div class="CDB-infowindow-container">' +
'<div class="CDB-infowindow-header CDB-infowindow-headerBg CDB-infowindow-headerBg--dark">' +
'<div class="CDB-infowindow-list">' +
'<div class="CDB-infowindow-listItem">' +
'<h4 class="CDB-infowindow-title">{{ name }}</h4>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="CDB-hook CDB-hook--white">' +
'<div class="CDB-hook-inner">' +
'</div>' +
'</div>' +
'</div>' +
'</div>',
"alternative_names": {},
"width": 226,
"maxHeight": 180
},
"tooltip": {
"fields": [
{
"name": "name",
"title": true,
"position": 1
}
],
"template_name": "tooltip_light",
"template": ' ' +
'<div class="CDB-Tooltip CDB-Tooltip--isDark js-content">' +
'<ul class="CDB-Tooltip-list">' +
'{{#fields}}' +
'<li class="CDB-Tooltip-listItem">' +
'<h3 class="CDB-Tooltip-listTitle">NAME</h3>' +
'<h4 class="CDB-Tooltip-listText">{{value}}</h4>' +
'</li>' +
'{{/fields}}' +
'</ul>' +
'</div>',
"alternative_names": {},
"maxHeight": 180
},
"legend": {
"type": "choropleth",
"show_title": false,
"title": "",
"template": "",
"items": [
{
"name": "Left label",
"visible": true,
"value": "5592.00",
"type": "text"
},
{
"name": "Right label",
"visible": true,
"value": "1638094.00",
"type": "text"
},
{
"name": "Color",
"visible": true,
"value": "#FFFFB2",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FED976",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FEB24C",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FD8D3C",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FC4E2A",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#E31A1C",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#B10026",
"type": "color"
}
]
},
"order": 1,
"visible": true,
"options": {
"sql": "select * from european_countries_e",
"layer_name": "european_countries_e",
"cartocss": "/** choropleth visualization */\n\n#european_countries_e{\n polygon-fill: #FFFFB2;\n polygon-opacity: 0.8;\n line-color: #FFF;\n line-width: 1;\n line-opacity: 0.5;\n}\n#european_countries_e [ area <= 1638094] {\n polygon-fill: #B10026;\n}\n#european_countries_e [ area <= 55010] {\n polygon-fill: #E31A1C;\n}\n#european_countries_e [ area <= 34895] {\n polygon-fill: #FC4E2A;\n}\n#european_countries_e [ area <= 12890] {\n polygon-fill: #FD8D3C;\n}\n#european_countries_e [ area <= 10025] {\n polygon-fill: #FEB24C;\n}\n#european_countries_e [ area <= 9150] {\n polygon-fill: #FED976;\n}\n#european_countries_e [ area <= 5592] {\n polygon-fill: #FFFFB2;\n}",
"cartocss_version": "2.1.1",
"table_name": "\"\"."
}
}
],
"overlays": [
{
"type": "loader",
"options": {
"display": true,
"x": 20,
"y": 150
}
},
{
"type": "search",
"options": {
"display": true
}
},
{
"type": "zoom",
"options": {
"x": 20,
"y": 20,
"display": true
}
}
],
"prev": null,
"next": null,
"transition_options": {}
};
cartodb.createVis('map', vizjson, {})
.done(function (vis, layers) {
cartoDBMap = vis.map;
})
.error(function (err) {
console.log(err);
});
}
window.onload = main;
</script>
</body>
</html>
@@ -0,0 +1,596 @@
<!DOCTYPE html>
<html>
<head>
<title>Geometry Editor | CARTO</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="shortcut icon" href="http://cartodb.com/assets/favicon.ico" />
<link rel="stylesheet" href="../../dist/internal/themes/css/cartodb.css" />
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<style>
html,
body {
height: 100%;
padding: 0;
margin: 0;
}
body {
font-family: 'Open Sans';
display: flex;
flex-direction: row;
}
.sidebar-title {
line-height: 2em;
padding: 0 10px;
text-transform: uppercase;
}
.sidebar-title-dark {
background: black;
color: white;
}
#sidebar {
width: 300px;
height: 100%;
display: flex;
flex-direction: column;
}
#map {
height: 100%;
flex: 1;
position: relative;
}
#controls {
padding: 10px;
}
#controls button {
font-size: 14px;
color: blue;
text-decoration: underline;
display: block;
margin-bottom: 10px;
}
#controls button.is-enabled {
color: red;
text-decoration: none;
}
#geojsonViewer {
flex: 1;
padding: 10px;
background: black;
}
#geojsonViewer textarea {
background: black;
font-family: "Lucida Console", Monaco, monospace;
font-size: 12px;
border: none;
color: #CDCDCD;
width: 100%;
height: 100%;
outline: none;
}
h1 {
font-size: 2em;
line-height: 1em;
margin: 10px;
}
</style>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
</head>
<body>
<div id="sidebar">
<h1>Geometry Editor</h1>
<p class="sidebar-title">Tools</p>
<div id="controls">
<button class="js-drawing-control js-draw-point">Draw Point</button>
<button class="js-drawing-control js-draw-line">Draw Polyline</button>
<button class="js-drawing-control js-draw-polygon">Draw Polygon</button>
<br/>
<button class="js-drawing-control js-edit-geometry-point">Edit Point</button>
<button class="js-drawing-control js-edit-geometry-polyline">Edit Polyline</button>
<button class="js-drawing-control js-edit-geometry-polygon">Edit Polygon</button>
<br/>
<button class="js-drawing-control js-edit-geometry-multi-point">Edit MultiPoint</button>
<button class="js-drawing-control js-edit-geometry-multi-polyline">Edit MultiPolyline</button>
<button class="js-drawing-control js-edit-geometry-multi-polygon">Edit MultiPolygon</button>
<br/>
<button class="js-drawing-control js-edit-features">Click & Edit</button>
</div>
<p class="sidebar-title sidebar-title-dark">GeoJSON</p>
<div id="geojsonViewer">
<textarea class="js-geojson-textarea" readonly></textarea>
</div>
</div>
<div id="map"></div>
<!-- include google maps library -->
<script type="text/javascript" src="http://www.maps.google.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- include cartodb.js library -->
<script src="../../dist/internal/cartodb.uncompressed.js"></script>
<script>
var vizjson = {
"id": "2b13c956-e7c1-11e2-806b-5404a6a683d5",
"version": "0.1.0",
"title": "european_countries_e 0",
"likes": 0,
"description": null,
"scrollwheel": true,
"legends": true,
"url": null,
"map_provider": "leaflet",
"center": "[52.5897007687178, 52.734375]",
"zoom": 4,
"updated_at": "2015-03-13T11:24:37+00:00",
"datasource": {
"user_name": "documentation",
"maps_api_template": "http://{user}.cartodb.com:80",
"force_cors": true, // This is sometimes set in the editor,
"stat_tag": "84ec6844-4b4b-11e5-9c1d-080027880ca6"
},
"layers": [
{
"options": {
"id": "0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order": 0,
"visible": true,
"type": "Tiled",
"name": "Positron",
"className": "default positron_rainbow",
"baseType": "positron_rainbow",
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
"read_only": true,
"minZoom": "0",
"maxZoom": "18",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"subdomains": "abcd",
"category": "CartoDB"
},
"infowindow": null,
"tooltip": null,
"id": "0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order": 0,
"type": "tiled"
},
{
"id": "923b7812-2d56-41c6-ac15-3ce430db090f",
"type": "CartoDB",
"infowindow": {
"fields": [
{
"name": "name",
"title": true,
"position": 4
}
],
"template": '' +
'<div class="CDB-infowindow CDB-infowindow--custom js-infowindow" style="max-width: 200px;">' +
'<div class="CDB-infowindow-close js-close"></div>' +
'<div class="CDB-infowindow-container">' +
'<div class="CDB-infowindow-header CDB-infowindow-headerBg CDB-infowindow-headerBg--dark">' +
'<div class="CDB-infowindow-list">' +
'<div class="CDB-infowindow-listItem">' +
'<h4 class="CDB-infowindow-title">{{ name }}</h4>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="CDB-hook CDB-hook--white">' +
'<div class="CDB-hook-inner">' +
'</div>' +
'</div>' +
'</div>' +
'</div>',
"alternative_names": {},
"width": 226,
"maxHeight": 180
},
"tooltip": {
"fields": [
{
"name": "name",
"title": true,
"position": 1
}
],
"template_name": "tooltip_light",
"template": ' ' +
'<div class="CDB-Tooltip CDB-Tooltip--isDark js-content">' +
'<ul class="CDB-Tooltip-list">' +
'{{#fields}}' +
'<li class="CDB-Tooltip-listItem">' +
'<h3 class="CDB-Tooltip-listTitle">NAME</h3>' +
'<h4 class="CDB-Tooltip-listText">{{value}}</h4>' +
'</li>' +
'{{/fields}}' +
'</ul>' +
'</div>',
"alternative_names": {},
"maxHeight": 180
},
"legend": {
"type": "choropleth",
"show_title": false,
"title": "",
"template": "",
"items": [
{
"name": "Left label",
"visible": true,
"value": "5592.00",
"type": "text"
},
{
"name": "Right label",
"visible": true,
"value": "1638094.00",
"type": "text"
},
{
"name": "Color",
"visible": true,
"value": "#FFFFB2",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FED976",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FEB24C",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FD8D3C",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FC4E2A",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#E31A1C",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#B10026",
"type": "color"
}
]
},
"order": 1,
"visible": true,
"options": {
"sql": "select * from european_countries_e",
"layer_name": "european_countries_e",
"cartocss": "/** choropleth visualization */\n\n#european_countries_e{\n polygon-fill: #FFFFB2;\n polygon-opacity: 0.8;\n line-color: #FFF;\n line-width: 1;\n line-opacity: 0.5;\n}\n#european_countries_e [ area <= 1638094] {\n polygon-fill: #B10026;\n}\n#european_countries_e [ area <= 55010] {\n polygon-fill: #E31A1C;\n}\n#european_countries_e [ area <= 34895] {\n polygon-fill: #FC4E2A;\n}\n#european_countries_e [ area <= 12890] {\n polygon-fill: #FD8D3C;\n}\n#european_countries_e [ area <= 10025] {\n polygon-fill: #FEB24C;\n}\n#european_countries_e [ area <= 9150] {\n polygon-fill: #FED976;\n}\n#european_countries_e [ area <= 5592] {\n polygon-fill: #FFFFB2;\n}",
"cartocss_version": "2.1.1",
"table_name": "\"\"."
}
}
],
"overlays": [
{
"type": "loader",
"options": {
"display": true,
"x": 20,
"y": 150
}
},
{
"type": "fullscreen",
"options": {
"x": 20,
"y": 140,
"display": true
}
},
{
"type": "search",
"options": {
"display": true
}
},
{
"type": "zoom",
"options": {
"x": 20,
"y": 20,
"display": true
}
}
],
"prev": null,
"next": null,
"transition_options": {}
};
var point = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
-3.779296875,
40.245991504199026
]
}
};
var polygon = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-8.96484375,
41.918628865183045
],
[
-7.84423828125,
43.74728909225908
],
[
-1.69189453125,
43.34914966389313
],
[
3.1091308593749996,
42.35042512243457
],
[
3.1640625,
41.828642001860544
],
[
-1.9555664062500002,
36.94111143010769
],
[
-5.55908203125,
36.00467348670187
],
[
-7.31689453125,
37.3002752813443
],
[
-6.39404296875,
41.74672584176937
],
[
-8.96484375,
41.918628865183045
]
]
]
}
};
var polyline = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
-2.021484375,
43.51668853502906
],
[
3.6035156249999996,
42.293564192170095
]
]
}
};
var multiPoint = {
"type": "MultiPoint",
"coordinates": [[100.0, 0.0], [101.0, 1.0]]
};
var multiPolyline = {
"type": "MultiLineString",
"coordinates": [
[[100.0, 0.0], [101.0, 1.0]],
[[102.0, 2.0], [103.0, 3.0]]
]
};
var multiPolygon = {
"type": "MultiPolygon",
"coordinates": [
[
[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]
],
[
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]
]
]
};
function displayGeoJSON(geometry) {
updateDisplayedGeoJSON(geometry);
geometry.on('change', updateDisplayedGeoJSON);
}
function updateDisplayedGeoJSON(geometry) {
if (geometry.isComplete()) {
$('.js-geojson-textarea').val(JSON.stringify(geometry.toGeoJSON(), null, 2));
}
}
function clearGeoJSON() {
$('.js-geojson-textarea').val('');
}
function drawPoint(vis) {
return drawGeometry(vis, vis.map.drawPoint());
}
function drawPolyline(vis) {
return drawGeometry(vis, vis.map.drawPolyline());
}
function drawPolygon(vis) {
return drawGeometry(vis, vis.map.drawPolygon());
}
function editGeometry(vis, geoJSON) {
var geometry = window.geometry = vis.map.editGeometry(geoJSON);
displayGeoJSON(geometry);
}
function enableClickToEdit(vis) {
vis.map.enableFeatureInteractivity();
vis.map.on('featureClick', fetchFeatureAndEditGeometry, this);
}
function disableClickToEdit(vis) {
vis.map.disableFeatureInteractivity();
vis.map.stopDrawingGeometry();
vis.map.off('featureClick', fetchFeatureAndEditGeometry, this);
}
function fetchFeatureAndEditGeometry(event) {
var featureID = event.feature.cartodb_id;
var tableName = 'european_countries_e';
var sql = new cartodb.SQL({
protocol: 'https',
user: 'documentation',
host: 'cartodb.com'
});
sql.execute("SELECT ST_AsGeoJSON(the_geom) AS geojson FROM {{tableName }} WHERE cartodb_id = {{id}}", { tableName: tableName, id: featureID })
.done(function (data) {
var geoJSON = JSON.parse(data.rows[0].geojson);
editGeometry(vis, geoJSON);
})
.error(function (errors) {
// errors contains a list of errors
console.log("errors:" + errors);
});
}
function drawGeometry(vis, geometry) {
window.geometry = geometry;
clearGeoJSON();
displayGeoJSON(geometry);
return geometry;
}
function enableControls(vis) {
$('.js-drawing-control').click(function () {
var clickedControl = this;
$('.js-drawing-control').each(function (index) {
var isEnabled = false;
if (clickedControl === this) {
isEnabled = !($(this).hasClass('is-enabled'));
}
$(this).toggleClass('is-enabled', isEnabled);
});
vis.map.stopDrawingGeometry();
vis.map.stopEditingGeometry();
});
document.querySelector('.js-draw-point').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
drawPoint(vis);
}
});
document.querySelector('.js-draw-line').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
drawPolyline(vis);
}
});
document.querySelector('.js-draw-polygon').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
drawPolygon(vis);
}
});
document.querySelector('.js-edit-geometry-point').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, point);
}
});
document.querySelector('.js-edit-geometry-polyline').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, polyline);
}
});
document.querySelector('.js-edit-geometry-polygon').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, polygon);
}
});
document.querySelector('.js-edit-geometry-multi-point').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, multiPoint);
}
});
document.querySelector('.js-edit-geometry-multi-polyline').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, multiPolyline);
}
});
document.querySelector('.js-edit-geometry-multi-polygon').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, multiPolygon);
}
});
document.querySelector('.js-edit-features').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
enableClickToEdit(vis);
} else {
disableClickToEdit(vis);
}
});
}
function main() {
cartodb.createVis('map', vizjson, {
legends: false,
gmaps_base_type: 'roadmap'
})
.done(function (vis, layers) {
enableControls(vis);
})
.error(function (err) {
console.log(err);
});
}
window.onload = main;
</script>
</body>
</html>
@@ -0,0 +1,607 @@
<!DOCTYPE html>
<html>
<head>
<title>Geometry Editor | CARTO</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<link rel="shortcut icon" href="http://cartodb.com/assets/favicon.ico" />
<link rel="stylesheet" href="../../dist/internal/themes/css/cartodb.css" />
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<style>
html, body {
height: 100%;
padding: 0;
margin: 0;
}
body {
font-family: 'Open Sans';
display: flex;
flex-direction: row;
}
.sidebar-title {
line-height: 2em;
padding: 0 10px;
text-transform: uppercase;
}
.sidebar-title-dark {
background: black;
color: white;
}
#sidebar {
width: 300px;
height: 100%;
display: flex;
flex-direction: column;
}
#map {
height: 100%;
flex: 1;
position: relative;
}
#controls {
padding: 10px;
}
#controls button {
font-size: 14px;
color: blue;
text-decoration: underline;
display: block;
margin-bottom: 10px;
}
#controls button.is-enabled {
color: red;
text-decoration: none;
}
#geojsonViewer {
flex:1;
padding: 10px;
background: black;
}
#geojsonViewer textarea {
background: black;
font-family: "Lucida Console", Monaco, monospace;
font-size: 12px;
border: none;
color: #CDCDCD;
width: 100%;
height: 100%;
outline: none;
}
h1 {
font-size: 2em;
line-height: 1em;
margin: 10px;
}
</style>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
</head>
<body>
<div id="sidebar">
<h1>Geometry Editor</h1>
<p class="sidebar-title">Tools</p>
<div id="controls">
<button class="js-drawing-control js-draw-point">Draw Point</button>
<button class="js-drawing-control js-draw-line">Draw Polyline</button>
<button class="js-drawing-control js-draw-polygon">Draw Polygon</button>
<br/>
<button class="js-drawing-control js-edit-geometry-point">Edit Point</button>
<button class="js-drawing-control js-edit-geometry-polyline">Edit Polyline</button>
<button class="js-drawing-control js-edit-geometry-polygon">Edit Polygon</button>
<br/>
<button class="js-drawing-control js-edit-geometry-multi-point">Edit MultiPoint</button>
<button class="js-drawing-control js-edit-geometry-multi-polyline">Edit MultiPolyline</button>
<button class="js-drawing-control js-edit-geometry-multi-polygon">Edit MultiPolygon</button>
<br/>
<button class="js-drawing-control js-edit-features">Click & Edit</button>
</div>
<p class="sidebar-title sidebar-title-dark">GeoJSON</p>
<div id="geojsonViewer">
<textarea class="js-geojson-textarea" readonly></textarea>
</div>
</div>
<div id="map"></div>
<!-- include cartodb.js library -->
<script src="../../dist/internal/cartodb.uncompressed.js"></script>
<script>
var vizjson = {
"id":"2b13c956-e7c1-11e2-806b-5404a6a683d5",
"version":"0.1.0",
"title":"european_countries_e 0",
"likes":0,
"description":null,
"scrollwheel":true,
"legends":true,
"url":null,
"map_provider":"leaflet",
"center":"[52.5897007687178, 52.734375]",
"zoom":4,
"updated_at":"2015-03-13T11:24:37+00:00",
"datasource": {
"user_name": "documentation",
"maps_api_template": "http://{user}.cartodb.com:80",
"force_cors": true, // This is sometimes set in the editor,
"stat_tag": "84ec6844-4b4b-11e5-9c1d-080027880ca6"
},
"layers":[
{
"options":{
"id":"0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order":0,
"visible":true,
"type":"Tiled",
"name":"Positron",
"className":"default positron_rainbow",
"baseType":"positron_rainbow",
"urlTemplate":"http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
"read_only":true,
"minZoom":"0",
"maxZoom":"18",
"attribution":"&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"subdomains":"abcd",
"category":"CartoDB"
},
"infowindow":null,
"tooltip":null,
"id":"0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order":0,
"type":"tiled"
},
{
"id":"923b7812-2d56-41c6-ac15-3ce430db090f",
"type":"CartoDB",
"infowindow":{
"fields":[
{
"name":"name",
"title":true,
"position":4
}
],
"template": '' +
'<div class="CDB-infowindow CDB-infowindow--custom js-infowindow" style="max-width: 200px;">' +
'<div class="CDB-infowindow-close js-close"></div>' +
'<div class="CDB-infowindow-container">' +
'<div class="CDB-infowindow-header CDB-infowindow-headerBg CDB-infowindow-headerBg--dark">' +
'<div class="CDB-infowindow-list">' +
'<div class="CDB-infowindow-listItem">' +
'<h4 class="CDB-infowindow-title">{{ name }}</h4>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="CDB-hook CDB-hook--white">' +
'<div class="CDB-hook-inner">' +
'</div>' +
'</div>' +
'</div>' +
'</div>',
"alternative_names":{},
"width":226,
"maxHeight":180
},
"tooltip":{
"fields": [
{
"name": "name",
"title": true,
"position": 1
}
],
"template_name":"tooltip_light",
"template": ' '+
'<div class="CDB-Tooltip CDB-Tooltip--isDark js-content">'+
'<ul class="CDB-Tooltip-list">'+
'{{#fields}}'+
'<li class="CDB-Tooltip-listItem">'+
'<h3 class="CDB-Tooltip-listTitle">NAME</h3>'+
'<h4 class="CDB-Tooltip-listText">{{value}}</h4>'+
'</li>'+
'{{/fields}}'+
'</ul>'+
'</div>',
"alternative_names":{},
"maxHeight":180
},
"legend":{
"type":"choropleth",
"show_title":false,
"title":"",
"template":"",
"items":[
{
"name":"Left label",
"visible":true,
"value":"5592.00",
"type":"text"
},
{
"name":"Right label",
"visible":true,
"value":"1638094.00",
"type":"text"
},
{
"name":"Color",
"visible":true,
"value":"#FFFFB2",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#FED976",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#FEB24C",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#FD8D3C",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#FC4E2A",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#E31A1C",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#B10026",
"type":"color"
}
]
},
"order":1,
"visible":true,
"options":{
"sql":"select * from european_countries_e",
"layer_name":"european_countries_e",
"cartocss":"/** choropleth visualization */\n\n#european_countries_e{\n polygon-fill: #FFFFB2;\n polygon-opacity: 0.8;\n line-color: #FFF;\n line-width: 1;\n line-opacity: 0.5;\n}\n#european_countries_e [ area <= 1638094] {\n polygon-fill: #B10026;\n}\n#european_countries_e [ area <= 55010] {\n polygon-fill: #E31A1C;\n}\n#european_countries_e [ area <= 34895] {\n polygon-fill: #FC4E2A;\n}\n#european_countries_e [ area <= 12890] {\n polygon-fill: #FD8D3C;\n}\n#european_countries_e [ area <= 10025] {\n polygon-fill: #FEB24C;\n}\n#european_countries_e [ area <= 9150] {\n polygon-fill: #FED976;\n}\n#european_countries_e [ area <= 5592] {\n polygon-fill: #FFFFB2;\n}",
"cartocss_version":"2.1.1",
"table_name":"\"\"."
}
},
{
"options": {
"visible": true,
"type": "Tiled",
"default": "true",
"url": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"name": "Positron Labels",
"id": "bc054932-1ae8-4d4a-96d6-d49ce4247a59",
"className": "httpsbasemapscartocdncomlight_only_labelszxypng",
"order": 3
},
"infowindow": null,
"tooltip": null,
"id": "bc054932-1ae8-4d4a-96d6-d49ce4247a59",
"order": 3,
"type": "tiled"
}
],
"overlays":[
{
"type":"loader",
"options":{
"display":true,
"x":20,
"y":150
}
},
{
"type":"fullscreen",
"options":{
"x":20,
"y":140,
"display":true
}
},
{
"type":"search",
"options":{
"display":true
}
},
{
"type":"zoom",
"options":{
"x":20,
"y":20,
"display":true
}
}
],
"prev":null,
"next":null,
"transition_options":{}
};
var point = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
-3.779296875,
40.245991504199026
]
}
};
var polygon = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-8.96484375,
41.918628865183045
],
[
-7.84423828125,
43.74728909225908
],
[
-1.69189453125,
43.34914966389313
],
[
3.1091308593749996,
42.35042512243457
],
[
3.1640625,
41.828642001860544
],
[
-1.9555664062500002,
36.94111143010769
],
[
-5.55908203125,
36.00467348670187
],
[
-7.31689453125,
37.3002752813443
],
[
-6.39404296875,
41.74672584176937
],
[
-8.96484375,
41.918628865183045
]
]
]
}
};
var polyline = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
-2.021484375,
43.51668853502906
],
[
3.6035156249999996,
42.293564192170095
]
]
}
};
var multiPoint = {
"type": "MultiPoint",
"coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
};
var multiPolyline = {
"type": "MultiLineString",
"coordinates": [
[ [100.0, 0.0], [101.0, 1.0] ],
[ [102.0, 2.0], [103.0, 3.0] ]
]
};
var multiPolygon = {
"type": "MultiPolygon",
"coordinates": [
[
[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]
],
[
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]
]
]
};
function displayGeoJSON (geometry) {
updateDisplayedGeoJSON(geometry);
geometry.on('change', updateDisplayedGeoJSON);
}
function updateDisplayedGeoJSON (geometry) {
if (geometry.isComplete()) {
$('.js-geojson-textarea').val(JSON.stringify(geometry.toGeoJSON(), null, 2));
}
}
function clearGeoJSON () {
$('.js-geojson-textarea').val('');
}
function drawPoint (vis) {
return drawGeometry(vis, vis.map.drawPoint());
}
function drawPolyline (vis) {
return drawGeometry(vis, vis.map.drawPolyline());
}
function drawPolygon (vis) {
return drawGeometry(vis, vis.map.drawPolygon());
}
function editGeometry (vis, geoJSON) {
var geometry = window.geometry = vis.map.editGeometry(geoJSON);
displayGeoJSON(geometry);
}
function enableClickToEdit (vis) {
vis.map.enableFeatureInteractivity();
vis.map.on('featureClick', fetchFeatureAndEditGeometry, this);
}
function disableClickToEdit (vis) {
vis.map.disableFeatureInteractivity();
vis.map.stopDrawingGeometry();
vis.map.off('featureClick', fetchFeatureAndEditGeometry, this);
}
function fetchFeatureAndEditGeometry (event) {
var featureID = event.feature.cartodb_id;
var tableName = 'european_countries_e';
var sql = new cartodb.SQL({
protocol: 'https',
user: 'documentation',
host: 'cartodb.com'
});
sql.execute("SELECT ST_AsGeoJSON(the_geom) AS geojson FROM {{tableName }} WHERE cartodb_id = {{id}}", { tableName: tableName, id: featureID })
.done(function(data) {
var geoJSON = JSON.parse(data.rows[0].geojson);
editGeometry(vis, geoJSON);
})
.error(function(errors) {
// errors contains a list of errors
console.log("errors:" + errors);
});
}
function drawGeometry (vis, geometry) {
window.geometry = geometry;
clearGeoJSON();
displayGeoJSON(geometry);
return geometry;
}
function enableControls (vis) {
$('.js-drawing-control').click(function () {
var clickedControl = this;
$('.js-drawing-control').each(function (index) {
var isEnabled = false;
if (clickedControl === this) {
isEnabled = !($(this).hasClass('is-enabled'));
}
$(this).toggleClass('is-enabled', isEnabled);
});
vis.map.stopDrawingGeometry();
vis.map.stopEditingGeometry();
});
document.querySelector('.js-draw-point').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
drawPoint(vis);
}
});
document.querySelector('.js-draw-line').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
drawPolyline(vis);
}
});
document.querySelector('.js-draw-polygon').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
drawPolygon(vis);
}
});
document.querySelector('.js-edit-geometry-point').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, point);
}
});
document.querySelector('.js-edit-geometry-polyline').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, polyline);
}
});
document.querySelector('.js-edit-geometry-polygon').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, polygon);
}
});
document.querySelector('.js-edit-geometry-multi-point').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, multiPoint);
}
});
document.querySelector('.js-edit-geometry-multi-polyline').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, multiPolyline);
}
});
document.querySelector('.js-edit-geometry-multi-polygon').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
editGeometry(vis, multiPolygon);
}
});
document.querySelector('.js-edit-features').addEventListener('click', function () {
if ($(this).hasClass('is-enabled')) {
enableClickToEdit(vis);
} else {
disableClickToEdit(vis);
}
});
}
function main () {
cartodb.createVis('map', vizjson, {
legends: false
})
.done(function (vis, layers) {
enableControls(vis);
})
.error(function (err) {
console.log(err);
});
}
window.onload = main;
</script>
</body>
</html>
+269
View File
@@ -0,0 +1,269 @@
<!DOCTYPE html>
<html>
<head>
<title>Easy example | CARTO</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<link rel="shortcut icon" href="http://cartodb.com/assets/favicon.ico" />
<link rel="stylesheet" href="../../dist/internal/themes/css/cartodb.css" />
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<style>
html, body, #map {
height: 100%;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<!-- include cartodb.js library -->
<script src="../../dist/internal/cartodb.uncompressed.js"></script>
<script>
function main() {
var vizjson = {
"id":"2b13c956-e7c1-11e2-806b-5404a6a683d5",
"version":"0.1.0",
"title":"european_countries_e 0",
"likes":0,
"description":null,
"scrollwheel":true,
"legends":true,
"url":null,
"map_provider":"leaflet",
"center":"[52.5897007687178, 52.734375]",
"zoom":4,
"updated_at":"2015-03-13T11:24:37+00:00",
"datasource": {
"user_name": "documentation",
"maps_api_template": "http://{user}.cartodb.com:80",
"force_cors": true, // This is sometimes set in the editor,
"stat_tag": "84ec6844-4b4b-11e5-9c1d-080027880ca6"
},
"layers":[
{
"options":{
"id":"0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order":0,
"visible":true,
"type":"Tiled",
"name":"Positron",
"className":"default positron_rainbow",
"baseType":"positron_rainbow",
"urlTemplate":"http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
"read_only":true,
"minZoom":"0",
"maxZoom":"18",
"attribution":"&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"subdomains":"abcd",
"category":"CartoDB"
},
"infowindow":null,
"tooltip":null,
"id":"0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order":0,
"type":"tiled"
},
{
"id":"923b7812-2d56-41c6-ac15-3ce430db090f",
"type":"CartoDB",
"infowindow":{
"fields":[
{
"name":"name",
"title":true,
"position":4
}
],
"template": '' +
'<div class="CDB-infowindow CDB-infowindow--custom js-infowindow" style="max-width: 200px;">' +
'<div class="CDB-infowindow-close js-close"></div>' +
'<div class="CDB-infowindow-container">' +
'<div class="CDB-infowindow-header CDB-infowindow-headerBg CDB-infowindow-headerBg--dark">' +
'<div class="CDB-infowindow-list">' +
'<div class="CDB-infowindow-listItem">' +
'<h4 class="CDB-infowindow-title">{{ name }}</h4>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="CDB-hook CDB-hook--white">' +
'<div class="CDB-hook-inner">' +
'</div>' +
'</div>' +
'</div>' +
'</div>',
"alternative_names":{},
"width":226,
"maxHeight":180
},
"tooltip":{
"fields": [
{
"name": "name",
"title": true,
"position": 1
}
],
"template_name":"tooltip_light",
"template": ' '+
'<div class="CDB-Tooltip CDB-Tooltip--isDark js-content">'+
'<ul class="CDB-Tooltip-list">'+
'{{#fields}}'+
'<li class="CDB-Tooltip-listItem">'+
'<h3 class="CDB-Tooltip-listTitle">NAME</h3>'+
'<h4 class="CDB-Tooltip-listText">{{value}}</h4>'+
'</li>'+
'{{/fields}}'+
'</ul>'+
'</div>',
"alternative_names":{},
"maxHeight":180
},
"legend":{
"type":"choropleth",
"show_title":false,
"title":"",
"template":"",
"items":[
{
"name":"Left label",
"visible":true,
"value":"5592.00",
"type":"text"
},
{
"name":"Right label",
"visible":true,
"value":"1638094.00",
"type":"text"
},
{
"name":"Color",
"visible":true,
"value":"#FFFFB2",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#FED976",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#FEB24C",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#FD8D3C",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#FC4E2A",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#E31A1C",
"type":"color"
},
{
"name":"Color",
"visible":true,
"value":"#B10026",
"type":"color"
}
]
},
"order":1,
"visible":true,
"options":{
"sql":"select * from european_countries_e",
"layer_name":"european_countries_e",
"cartocss":"/** choropleth visualization */\n\n#european_countries_e{\n polygon-fill: #FFFFB2;\n polygon-opacity: 0.8;\n line-color: #FFF;\n line-width: 1;\n line-opacity: 0.5;\n}\n#european_countries_e [ area <= 1638094] {\n polygon-fill: #B10026;\n}\n#european_countries_e [ area <= 55010] {\n polygon-fill: #E31A1C;\n}\n#european_countries_e [ area <= 34895] {\n polygon-fill: #FC4E2A;\n}\n#european_countries_e [ area <= 12890] {\n polygon-fill: #FD8D3C;\n}\n#european_countries_e [ area <= 10025] {\n polygon-fill: #FEB24C;\n}\n#european_countries_e [ area <= 9150] {\n polygon-fill: #FED976;\n}\n#european_countries_e [ area <= 5592] {\n polygon-fill: #FFFFB2;\n}",
"cartocss_version":"2.1.1",
"table_name":"\"\"."
}
},
{
"options": {
"visible": true,
"type": "Tiled",
"default": "true",
"url": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"name": "Positron Labels",
"id": "bc054932-1ae8-4d4a-96d6-d49ce4247a59",
"className": "httpsbasemapscartocdncomlight_only_labelszxypng",
"order": 3
},
"infowindow": null,
"tooltip": null,
"id": "bc054932-1ae8-4d4a-96d6-d49ce4247a59",
"order": 3,
"type": "tiled"
}
],
"overlays":[
{
"type":"loader",
"options":{
"display":true,
"x":20,
"y":150
}
},
{
"type":"fullscreen",
"options":{
"x":20,
"y":140,
"display":true
}
},
{
"type":"search",
"options":{
"display":true
}
},
{
"type":"zoom",
"options":{
"x":20,
"y":20,
"display":true
}
}
],
"prev":null,
"next":null,
"transition_options":{}
};
cartodb.createVis('map', vizjson, {})
.done(function(vis, layers) {
})
.error(function(err) {
console.log(err);
});
}
window.onload = main;
</script>
</body>
</html>
+77
View File
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Base example | CARTO</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<link rel="shortcut icon" href="http://cartodb.com/assets/favicon.ico" />
<!--Include carto styles -->
<link rel="stylesheet" href="../../dist/internal/themes/css/cartodb.css" />
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<!-- Include cartodb.js Library -->
<script src="../../dist/internal/cartodb.uncompressed.js"></script>
<!-- Custom Map styles -->
<style>
html,
body,
#map {
font-family: "Open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
height: 100%;
padding: 0;
margin: 0;
background: #162945;
position: relative;
}
</style>
<style>
nav {
padding: 15px;
display: flex;
flex-direction: row;
background: white;
color: #162945;
border-bottom: 1px solid #eee;
font-size: 13px;
}
input {
background: none;
border: none;
}
button {
color: #FFF;
padding: 5px 10px;
background-color: #1785FB;
border-radius: 3px;
}
.CDB-OverlayContainer {
z-index: 999;
}
</style>
<script>
window.mapboxApiKey = 'pk.eyJ1IjoiY2FydG8tdGVhbSIsImEiOiJjamNseTl3ZzQwZnFkMndudnIydnJoMXZxIn0.HycQBkaaV7ZwLkHm5hEmfg';
function loadVizJson(name) {
let url = 'viz/' + name;
fetch(url)
.then(data => data.json())
.then(vizjson => {
cartodb.createVis('map', vizjson)
.done(console.log)
.error(console.error);
});
}
</script>
</head>
<body onload="loadVizJson('003.json')">
<div id="map"></div>
</body>
</html>
+203
View File
@@ -0,0 +1,203 @@
{
"id": "2b13c956-e7c1-11e2-806b-5404a6a683d5",
"version": "0.1.0",
"title": "european_countries_e 0",
"likes": 0,
"description": null,
"scrollwheel": true,
"legends": true,
"url": null,
"map_provider": "leaflet",
"center": "[52.5897007687178, 52.734375]",
"zoom": 4,
"updated_at": "2015-03-13T11:24:37+00:00",
"datasource": {
"user_name": "documentation",
"maps_api_template": "http://{user}.cartodb.com:80",
"force_cors": true,
"stat_tag": "84ec6844-4b4b-11e5-9c1d-080027880ca6"
},
"layers": [
{
"options": {
"id": "0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order": 0,
"visible": true,
"type": "Tiled",
"name": "Positron",
"className": "default positron_rainbow",
"baseType": "positron_rainbow",
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
"read_only": true,
"minZoom": "0",
"maxZoom": "18",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"subdomains": "abcd",
"category": "CartoDB"
},
"infowindow": null,
"tooltip": null,
"id": "0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order": 0,
"type": "tiled"
},
{
"id": "923b7812-2d56-41c6-ac15-3ce430db090f",
"type": "CartoDB",
"infowindow": {
"fields": [
{
"name": "name",
"title": true,
"position": 4
}
],
"template": "<div> {{ name }} </div>",
"alternative_names": {},
"width": 226,
"maxHeight": 180
},
"tooltip": {
"fields": [
{
"name": "name",
"title": true,
"position": 1
}
],
"template_name": "tooltip_light",
"template": "<div> TEMPLATE_1 </div>",
"alternative_names": {},
"maxHeight": 180
},
"legend": {
"type": "choropleth",
"show_title": false,
"title": "",
"template": "",
"items": [
{
"name": "Left label",
"visible": true,
"value": "5592.00",
"type": "text"
},
{
"name": "Right label",
"visible": true,
"value": "1638094.00",
"type": "text"
},
{
"name": "Color",
"visible": true,
"value": "#FFFFB2",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FED976",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FEB24C",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FD8D3C",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#FC4E2A",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#E31A1C",
"type": "color"
},
{
"name": "Color",
"visible": true,
"value": "#B10026",
"type": "color"
}
]
},
"order": 1,
"visible": true,
"options": {
"sql": "select * from european_countries_e",
"layer_name": "european_countries_e",
"cartocss": "/** choropleth visualization */\n\n#european_countries_e{\n polygon-fill: #FFFFB2;\n polygon-opacity: 0.8;\n line-color: #FFF;\n line-width: 1;\n line-opacity: 0.5;\n}\n#european_countries_e [ area <= 1638094] {\n polygon-fill: #B10026;\n}\n#european_countries_e [ area <= 55010] {\n polygon-fill: #E31A1C;\n}\n#european_countries_e [ area <= 34895] {\n polygon-fill: #FC4E2A;\n}\n#european_countries_e [ area <= 12890] {\n polygon-fill: #FD8D3C;\n}\n#european_countries_e [ area <= 10025] {\n polygon-fill: #FEB24C;\n}\n#european_countries_e [ area <= 9150] {\n polygon-fill: #FED976;\n}\n#european_countries_e [ area <= 5592] {\n polygon-fill: #FFFFB2;\n}",
"cartocss_version": "2.1.1",
"table_name": "\"\"."
}
},
{
"options": {
"visible": true,
"type": "Tiled",
"default": "true",
"url": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"name": "Positron Labels",
"id": "bc054932-1ae8-4d4a-96d6-d49ce4247a59",
"className": "httpsbasemapscartocdncomlight_only_labelszxypng",
"order": 3
},
"infowindow": null,
"tooltip": null,
"id": "bc054932-1ae8-4d4a-96d6-d49ce4247a59",
"order": 3,
"type": "tiled"
}
],
"overlays": [
{
"type": "loader",
"options": {
"display": true,
"x": 20,
"y": 150
}
},
{
"type": "fullscreen",
"options": {
"x": 20,
"y": 140,
"display": true
}
},
{
"type": "search",
"options": {
"display": true
}
},
{
"type": "zoom",
"options": {
"x": 20,
"y": 20,
"display": true
}
}
],
"prev": null,
"next": null,
"transition_options": {}
}
+170
View File
@@ -0,0 +1,170 @@
{
"bounds": [
[
-73.8273,
-179
],
[
83.261,
179
]
],
"center": "[41, -3]",
"datasource": {
"user_name": "cartojs-test",
"maps_api_template": "https://{user}.carto.com:443",
"stat_tag": "3626e3ca-1e40-4e5c-95f8-f83b54131ddc"
},
"description": "<p>Basic test displaying points in red.</p>\n",
"options": {
"dashboard_menu": true,
"layer_selector": false,
"legends": true,
"scrollwheel": true
},
"id": "3626e3ca-1e40-4e5c-95f8-f83b54131ddc",
"layers": [
{
"id": "e7bbdf2c-8e66-49f3-b7b8-793e3a4fd6ea",
"type": "tiled",
"options": {
"default": "true",
"url": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"name": "Voyager",
"className": "voyager_labels",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"labels": {
"url": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_only_labels/{z}/{x}/{y}.png"
},
"urlTemplate": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_nolabels/{z}/{x}/{y}.png"
}
},
{
"id": "b39d9e30-1a03-48d2-8734-4e700632f800",
"legends": [],
"type": "CartoDB",
"infowindow": {
"template_name": "none",
"fields": [],
"maxHeight": 180,
"template": "",
"alternative_names": {},
"width": 226,
"headerColor": {
"color": {
"fixed": "#35AAE5",
"opacity": 1
}
}
},
"tooltip": {
"fields": [],
"template_name": "none",
"template": "",
"template_type": "mustache"
},
"visible": true,
"options": {
"layer_name": "ne_10m_populated_places_simple",
"cartocss": "#layer {\n marker-width: 10;\n marker-fill: #ff0900;\n marker-fill-opacity: 1;\n marker-allow-overlap: true;\n marker-line-width: 1;\n marker-line-color: #FFFFFF;\n marker-line-opacity: 1;\n}",
"cartocss_version": "2.1.1",
"attribution": "",
"source": "a0"
}
},
{
"id": "7a5e026f-d014-43a7-b0c3-403eaabc889d",
"type": "tiled",
"options": {
"default": "true",
"url": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_only_labels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"urlTemplate": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_only_labels/{z}/{x}/{y}.png",
"type": "Tiled",
"name": "Voyager Labels"
}
}
],
"likes": 0,
"map_provider": "leaflet",
"overlays": [
{
"type": "share",
"order": 2,
"options": {
"display": true,
"x": 20,
"y": 20
},
"template": ""
},
{
"type": "search",
"order": 3,
"options": {
"display": true,
"x": 60,
"y": 20
},
"template": ""
},
{
"type": "zoom",
"order": 6,
"options": {
"display": true,
"x": 20,
"y": 20
},
"template": "<a href=\"#zoom_in\" class=\"zoom_in\">+</a> <a href=\"#zoom_out\" class=\"zoom_out\">-</a>"
},
{
"type": "loader",
"order": 8,
"options": {
"display": true,
"x": 20,
"y": 150
},
"template": "<div class=\"loader\" original-title=\"\"></div>"
},
{
"type": "logo",
"order": 9,
"options": {
"display": true,
"x": 10,
"y": 40
},
"template": ""
}
],
"title": "001-Test",
"updated_at": "2017-10-24T11:29:21+00:00",
"user": {
"fullname": "cartojs-test",
"avatar_url": "//cartodb-libs.global.ssl.fastly.net/cartodbui/assets/unversioned/images/avatars/avatar_planet_orange.png",
"profile_url": "https://cartojs-test.carto.com"
},
"version": "3.0.0",
"widgets": [],
"zoom": 7,
"analyses": [
{
"id": "a0",
"type": "source",
"params": {
"query": "SELECT * FROM ne_10m_populated_places_simple"
},
"options": {
"table_name": "ne_10m_populated_places_simple"
}
}
]
}
+262
View File
@@ -0,0 +1,262 @@
{
"bounds": [
[
-73.8273,
-179
],
[
83.261,
179
]
],
"center": "[41, -3]",
"datasource": {
"user_name": "cartojs-test",
"maps_api_template": "https://{user}.carto.com:443",
"stat_tag": "b8c116e4-37af-4eee-83d6-79d4c33201e4"
},
"description": "<p>Map to test the different generated legends.</p>\n\n<p>Points to test:</p>\n\n<ul>\n<li>Category legend</li>\n<li>Choropleth legend</li>\n<li>Bubble legend</li>\n</ul>\n\n<p>(Choropleth and bubble share the same layer)</p>\n",
"options": {
"dashboard_menu": true,
"layer_selector": false,
"legends": true,
"scrollwheel": true
},
"id": "b8c116e4-37af-4eee-83d6-79d4c33201e4",
"layers": [
{
"id": "0176d48c-09b1-4bf2-9493-546b93e4df88",
"type": "tiled",
"options": {
"default": "true",
"url": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"name": "Voyager",
"className": "voyager_labels",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"labels": {
"url": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_only_labels/{z}/{x}/{y}.png"
},
"urlTemplate": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
"type": "Tiled"
}
},
{
"id": "7c115d5b-6c1e-4390-890f-52d9c12f6cb2",
"legends": [
{
"conf": {
"columns": []
},
"created_at": "2017-10-24T11:52:52+00:00",
"definition": {},
"id": "61c56598-c76e-4b11-952e-7412452e6e29",
"layer_id": "7c115d5b-6c1e-4390-890f-52d9c12f6cb2",
"post_html": "",
"pre_html": "",
"title": "pop_max",
"type": "choropleth",
"updated_at": "2017-10-24T12:02:06+00:00"
},
{
"conf": {
"columns": []
},
"created_at": "2017-10-24T12:01:27+00:00",
"definition": {
"color": "#fef6b5",
"top_label": "",
"bottom_label": ""
},
"id": "6210c946-9ee5-4d8a-ba99-25a8d7c5bc65",
"layer_id": "7c115d5b-6c1e-4390-890f-52d9c12f6cb2",
"post_html": "",
"pre_html": "",
"title": "pop_max",
"type": "bubble",
"updated_at": "2017-10-24T12:02:06+00:00"
}
],
"type": "CartoDB",
"infowindow": {
"template_name": "none",
"maxHeight": 180,
"template": "",
"alternative_names": {},
"fields": null,
"width": 226,
"headerColor": {
"color": {
"fixed": "#35AAE5",
"opacity": 1
}
}
},
"tooltip": {
"template_name": "none",
"template": ""
},
"visible": true,
"options": {
"layer_name": "Layer1",
"cartocss": "#layer {\n marker-width: ramp([pop_max], range(2, 11), quantiles(5));\n marker-fill: ramp([pop_max], (#fef6b5, #ffd08e, #ffa679, #f67b77, #e15383), quantiles);\n marker-fill-opacity: 1;\n marker-allow-overlap: true;\n marker-line-width: 1;\n marker-line-color: #FFFFFF;\n marker-line-opacity: 1;\n}",
"cartocss_version": "2.1.1",
"attribution": "",
"source": "c0"
}
},
{
"id": "97bf19b9-fee0-49fd-ad44-8f4026da6888",
"legends": [
{
"conf": {
"columns": [
"title"
]
},
"created_at": "2017-10-24T11:52:00+00:00",
"definition": {},
"id": "07cc33c9-63c3-4bc6-9c9a-6b3c46ebbda1",
"layer_id": "97bf19b9-fee0-49fd-ad44-8f4026da6888",
"post_html": "",
"pre_html": "",
"title": "Category Legend",
"type": "category",
"updated_at": "2017-10-24T11:59:25+00:00"
}
],
"type": "CartoDB",
"infowindow": {
"template_name": "none",
"maxHeight": 180,
"template": "",
"alternative_names": {},
"fields": null,
"width": 226,
"headerColor": {
"color": {
"fixed": "#35AAE5",
"opacity": 1
}
}
},
"tooltip": {
"template_name": "none",
"template": ""
},
"visible": true,
"options": {
"layer_name": "layer0",
"cartocss": "#layer {\n marker-width: 7;\n marker-fill: ramp([featurecla], (#5F4690, #1D6996, #38A6A5, #0F8554, #73AF48, #EDAD08, #E17C05, #CC503E), (\"Populated place\", \"Admin-1 capital\", \"Admin-0 capital\", \"Admin-1 region capital\", \"Scientific station\", \"Admin-0 region capital\", \"Admin-0 capital alt\", \"Historic place\"), \"=\");\n marker-fill-opacity: 1;\n marker-allow-overlap: true;\n marker-line-width: 0;\n marker-line-color: #FFFFFF;\n marker-line-opacity: 1;\n}",
"cartocss_version": "2.1.1",
"attribution": "",
"source": "b0"
}
},
{
"id": "2669e10c-d1bf-4ed5-8f8e-6518a1afb234",
"type": "tiled",
"options": {
"default": "true",
"url": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_only_labels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"urlTemplate": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager_only_labels/{z}/{x}/{y}.png",
"type": "Tiled",
"name": "Voyager Labels"
}
}
],
"likes": 0,
"map_provider": "leaflet",
"overlays": [
{
"type": "share",
"order": 2,
"options": {
"display": true,
"x": 20,
"y": 20
},
"template": ""
},
{
"type": "search",
"order": 3,
"options": {
"display": true,
"x": 60,
"y": 20
},
"template": ""
},
{
"type": "zoom",
"order": 6,
"options": {
"display": true,
"x": 20,
"y": 20
},
"template": "<a href=\"#zoom_in\" class=\"zoom_in\">+</a> <a href=\"#zoom_out\" class=\"zoom_out\">-</a>"
},
{
"type": "loader",
"order": 8,
"options": {
"display": true,
"x": 20,
"y": 150
},
"template": "<div class=\"loader\" original-title=\"\"></div>"
},
{
"type": "logo",
"order": 9,
"options": {
"display": true,
"x": 10,
"y": 40
},
"template": ""
}
],
"title": "002-Test",
"updated_at": "2017-10-24T12:05:16+00:00",
"user": {
"fullname": "cartojs-test",
"avatar_url": "//cartodb-libs.global.ssl.fastly.net/cartodbui/assets/unversioned/images/avatars/avatar_planet_orange.png",
"profile_url": "https://cartojs-test.carto.com"
},
"version": "3.0.0",
"widgets": [],
"zoom": 7,
"analyses": [
{
"id": "c0",
"type": "source",
"params": {
"query": "SELECT * FROM ne_10m_populated_places_simple"
},
"options": {
"table_name": "ne_10m_populated_places_simple",
"simple_geom": "point"
}
},
{
"id": "b0",
"type": "source",
"params": {
"query": "SELECT * FROM ne_10m_populated_places_simple"
},
"options": {
"table_name": "ne_10m_populated_places_simple",
"simple_geom": "point"
}
}
]
}
+53
View File
@@ -0,0 +1,53 @@
{
"id": "2b13c956-e7c1-11e2-806b-5404a6a683d5",
"version": "0.1.0",
"title": "european_countries_e 0",
"likes": 0,
"description": null,
"scrollwheel": true,
"legends": true,
"url": null,
"map_provider": "leaflet",
"center": "[52.5897007687178, 52.734375]",
"zoom": 4,
"updated_at": "2015-03-13T11:24:37+00:00",
"datasource": {
"user_name": "documentation",
"maps_api_template": "http://{user}.cartodb.com:80",
"force_cors": true,
"stat_tag": "84ec6844-4b4b-11e5-9c1d-080027880ca6"
},
"layers": [
{
"options": {
"id": "0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order": 0,
"visible": true,
"type": "Tiled",
"name": "Positron",
"className": "default positron_rainbow",
"baseType": "positron_rainbow",
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
"read_only": true,
"minZoom": "0",
"maxZoom": "18",
"attribution": "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
"subdomains": "abcd",
"category": "CartoDB"
},
"infowindow": null,
"tooltip": null,
"id": "0a3d9104-99c6-482b-9f8c-7c6134bddcdc",
"order": 0,
"type": "tiled"
}
],
"overlays": [
{
"type": "search",
"options": {
"display": true
}
}
]
}
+89
View File
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Base example | CARTO</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<link rel="shortcut icon" href="http://cartodb.com/assets/favicon.ico" />
<!--Include carto styles -->
<link rel="stylesheet" href="../../dist/internal/themes/css/cartodb.css" />
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<!-- Include cartodb.js Library -->
<script src="../../dist/internal/cartodb.uncompressed.js"></script>
<!-- Custom Map styles -->
<style>
html,
body,
#map {
font-family: "Open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
height: 100%;
padding: 0;
margin: 0;
background: #162945;
position: relative;
}
</style>
<style>
#map {
height: calc(100% - 55px);
}
nav {
padding: 15px;
display: flex;
flex-direction: row;
background: white;
color: #162945;
border-bottom: 1px solid #eee;
font-size: 13px;
}
input {
background: none;
border: none;
}
button {
color: #FFF;
padding: 5px 10px;
background-color: #1785FB;
border-radius: 3px;
}
.CDB-OverlayContainer{
z-index: 999;
}
</style>
<script>
function loadVizJson(name) {
let url = 'viz/' + name;
fetch(url)
.then(data => data.json())
.then(vizjson => {
cartodb.createVis('map', vizjson)
.done(console.log)
.error(console.error);
});
}
</script>
</head>
<body>
<nav>
<input list="examples" type="text" name="url" onchange="loadVizJson(document.querySelector('input').value)">
<datalist id="examples">
<option value="000.json" />
<option value="001.json" />
<option value="002.json" />
<option value="003.json" />
</datalist>
<button onclick="loadVizJson(document.querySelector('input').value)" type="button">LOAD VIZ</button>
</nav>
<div id="map"></div>
</body>
</html>
+99
View File
@@ -0,0 +1,99 @@
<!DOCTYPE html>
<html>
<head>
<title>Category widget | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body class="bg-gray">
<div class="dataview">
<ul>
<li>
<h2 class="h2">Column</h2>
<input id="column" type="text" value="adm0name" class="input_text open-sans"></input>
</li>
<li>
<h2 class="h2">Limit</h2>
<input id="limit" type="number" value="10" class="input_text open-sans"></input>
</li>
<li>
<h2 class="h2">Operation</h2>
<select id="operation" class="select open-sans">
<option value="sum">SUM</option>
<option value="count">COUNT</option>
<option value="avg">AVG</option>
<option value="max">MAX</option>
<option value="min">MIN</option>
</select>
</li>
<li>
<h2 class="h2">Operation column</h2>
<input id="operationColumn" type="text" value="pop_max" class="input_text open-sans"></input>
</li>
</ul>
<button onclick="applyDataviewChanges()" class="button open-sans">Apply</button>
<pre class="code" id="data"></pre>
</div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Category widget</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create a widget with the category dataview.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Change form values.</p>
</section>
<div id="controls">
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const categoryDataview = new carto.dataview.Category(source, 'adm0name', {
limit: 10,
operation: carto.operation.SUM,
operationColumn: 'pop_max'
});
categoryDataview.on('dataChanged', data => {
document.getElementById('data').innerHTML = JSON.stringify(data, null, 4);
});
categoryDataview.on('error', error => {
alert(error.message);
});
client.addDataview(categoryDataview);
function applyDataviewChanges() {
const column = document.getElementById('column').value;
const limit = document.getElementById('limit').value;
const operation = document.getElementById('operation').value;
const operationColumn = document.getElementById('operationColumn').value;
categoryDataview.setColumn(column);
categoryDataview.setLimit(parseInt(limit));
categoryDataview.setOperation(operation);
categoryDataview.setOperationColumn(operationColumn);
}
</script>
</body>
</html>
@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html>
<head>
<title>Widgets error handling | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body class="bg-gray">
<div class="dataview">
<ul>
<li>
<h2 class="h2">Column</h2>
<input id="column" type="text" value="pop_max" class="input_text open-sans"></input>
</li>
<li>
<h2 class="h2">Operation</h2>
<select id="operation" class="select">
<option value="count">COUNT</option>
<option value="sum">SUM</option>
<option value="avg">AVG</option>
<option value="max">MAX</option>
<option value="min">MIN</option>
</select>
</li>
</ul>
<button onclick="applyDataviewChanges()" class="button open-sans text-blue"><b>Apply</b></button>
<button onclick="provokeError()" class="button button-error open-sans text-red"><b>Provoke error</b></button>
<pre class="code" id="data"></pre>
</div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Status and error handling</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Manage the status and erros in dataviews.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Apply submits the form. Provoke error sends a wrong column.</p>
</section>
<div id="controls">
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset(`
ne_10m_populated_places_simple
`);
const formulaDataview = new carto.dataview.Formula(source, 'pop_max', {
operation: carto.operation.COUNT
});
let data;
formulaDataview.on('dataChanged', newData => {
data = JSON.stringify(newData, null, 4);
setText(data);
});
formulaDataview.on('error', error => {
setText(error.message);
});
formulaDataview.on('statusChanged', status => {
if (status === carto.dataview.status.LOADING) {
setText('Loading...');
} else if (status === carto.dataview.status.LOADED && data) {
setText(data);
}
});
client.addDataview(formulaDataview);
function applyDataviewChanges() {
const column = document.getElementById('column').value;
const operation = document.getElementById('operation').value;
formulaDataview.setColumn(column);
formulaDataview.setOperation(operation);
}
function provokeError () {
formulaDataview.setColumn('wrongcolumn');
}
function setText (text) {
document.getElementById('data').innerHTML = text;
}
</script>
</body>
</html>
+86
View File
@@ -0,0 +1,86 @@
<!DOCTYPE html>
<html>
<head>
<title>Formula widget | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body class="bg-gray">
<div class="dataview">
<ul>
<li>
<h2 class="h2">Column</h2>
<input id="column" type="text" value="pop_max" class="input_text open-sans"></input>
</li>
<li>
<h2 class="h2">Operation</h2>
<select id="operation" class="select open-sans">
<option value="count">COUNT</option>
<option value="sum">SUM</option>
<option value="avg">AVG</option>
<option value="max">MAX</option>
<option value="min">MIN</option>
</select>
</li>
</ul>
<button onclick="applyDataviewChanges()" class="button open-sans">Apply</button>
<pre class="code" id="data"></pre>
</div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Formula widget</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create a widget with the formula dataview.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Change column or operation on the form.</p>
<p class="open-sans">Example columns: rank_max, pop_max, pop_min.</p>
</section>
<div id="controls">
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const formulaDataview = new carto.dataview.Formula(source, 'pop_max', {
operation: carto.operation.COUNT
});
formulaDataview.on('dataChanged', data => {
document.getElementById('data').innerHTML = JSON.stringify(data, null, 4);
});
formulaDataview.on('error', error => {
alert(error.message);
});
client.addDataview(formulaDataview);
function applyDataviewChanges() {
const column = document.getElementById('column').value;
const operation = document.getElementById('operation').value;
formulaDataview.setColumn(column);
formulaDataview.setOperation(operation);
}
</script>
</body>
</html>
+99
View File
@@ -0,0 +1,99 @@
<!DOCTYPE html>
<html>
<head>
<title>Histogram widget | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body class="bg-gray">
<div class="dataview">
<ul>
<li>
<h2 class="h2">Column</h2>
<input id="column" type="text" value="price" class="input_text open-sans"></input>
</li>
<li>
<h2 class="h2">Bins</h2>
<input id="bins" type="number" value="5" class="input_text open-sans"></input>
</li>
<li>
<h2 class="h2">Start</h2>
<input id="start" type="number" class="input_text open-sans"></input>
</li>
<li>
<h2 class="h2">End</h2>
<input id="end" type="number" class="input_text open-sans"></input>
</li>
</ul>
<button onclick="applyDataviewChanges()" class="button open-sans">Apply</button>
<pre class="code" id="data"></pre>
</div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Histogram widget</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create a widget with the histogram dataview.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Change column or bins on the form.</p>
<p class="open-sans">Start and end values must be used together.</p>
<p class="open-sans">Example columns: price, minimum_nights, availability_365.</p>
</section>
<div id="controls">
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.SQL('SELECT * FROM airbnb_listings WHERE price < 150');
const histogramDataview = new carto.dataview.Histogram(source, 'price', {
bins: 5
});
histogramDataview.on('dataChanged', data => {
document.getElementById('data').innerHTML = JSON.stringify(data, null, 4);
});
histogramDataview.on('error', error => {
alert(error.message);
});
client.addDataview(histogramDataview);
function applyDataviewChanges() {
const column = document.getElementById('column').value;
const bins = parseInt(document.getElementById('bins').value);
const startValue = parseFloat(document.getElementById('start').value);
const endValue = parseFloat(document.getElementById('end').value);
const start = Number.isFinite(startValue) ? startValue : null;
const end = Number.isFinite(endValue) ? endValue : null;
try {
histogramDataview.setColumn(column);
histogramDataview.setStartEnd(start, end);
histogramDataview.setBins(bins);
} catch(error) {
alert(error.message);
}
}
</script>
</body>
</html>
@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<title>Time Series widget | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body class="bg-gray">
<div class="dataview">
<ul>
<li>
<h2 class="h2">Column</h2>
<input id="column" type="text" value="date" class="input_text open-sans"></input>
</li>
<li>
<h2 class="h2">Aggregation</h2>
<select id="aggregation" class="select">
<option value="auto">Auto</option>
<option value="millennium">Millennium</option>
<option value="century">Century</option>
<option value="decade">Decade</option>
<option value="year">Year</option>
<option value="quarter">Quarter</option>
<option value="month">Month</option>
<option value="week">Week</option>
<option value="day">Day</option>
<option value="hour">Hour</option>
<option value="minute">Minute</option>
</select>
</li>
<li>
<h2 class="h2">Offset</h2>
<input id="offset" type="number" value="1" class="input_text open-sans"></input>
</li>
</ul>
<button class="button open-sans" onclick="applyDataviewChanges()">Apply</button>
<pre class="code" id="data"></pre>
</div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Time Series widget</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create a widget with the time series dataview.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Select different aggregations on the form.</p>
</section>
<div id="controls">
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('railroad_data');
const timeseriesDataview = new carto.dataview.TimeSeries(source, 'date', {
aggregation: carto.dataview.timeAggregation.AUTO,
offset: 1
});
timeseriesDataview.on('dataChanged', data => {
document.getElementById('data').innerHTML = JSON.stringify(data, null, 4);
});
timeseriesDataview.on('error', error => {
alert(error.message);
});
client.addDataview(timeseriesDataview);
function applyDataviewChanges() {
const column = document.getElementById('column').value;
const aggregation = document.getElementById('aggregation').value;
const offset = document.getElementById('offset').value;
timeseriesDataview.setColumn(column);
timeseriesDataview.setAggregation(aggregation);
timeseriesDataview.setOffset(parseInt(offset));
}
</script>
</body>
</html>
+153
View File
@@ -0,0 +1,153 @@
<!DOCTYPE html>
<html>
<head>
<title>AND Filter | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>AND Filter</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Apply an AND filter to exclude listings that are not within the selected room types and have a higher price than the one we set.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Change the selected price range and the selected room types to filter the listings.</p>
</section>
<div id="controls">
<div id="info">
<h3>Room Types</h3>
</div>
<ul>
<li>
<input type="checkbox" name="roomTypes[]" id="entire" value="Entire home/apt" checked>
<label for="entire">Entire home/apt</label>
</li>
<li>
<input type="checkbox" name="roomTypes[]" id="private" value="Private room" checked>
<label for="private">Private Room</label>
</li>
<li>
<input type="checkbox" name="roomTypes[]" id="shared" value="Shared room" checked>
<label for="shared">Shared Room</label>
</li>
</ul>
<div id="info">
<h3>Price</h3>
</div>
<div class="widget">
<p class="open-sans">Showing listings below and equal to <span class="js-price-placeholder">40€</span></p>
</div>
<input type="range" name="price" class="slider" min="1" max="60" value="40" step="1" min-with-suffix="1€" max-with-suffix="60€">
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([40.42252398976147, -3.659729361534119], 12);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const inputRange = document.querySelector('#controls input[type=range]');
inputRange.style.setProperty('--value', (inputRange.value - inputRange.min) / 0.59);
const pricePlaceholder = document.querySelector('#controls .js-price-placeholder');
const roomTypesCheckboxes = document.querySelectorAll('#controls input[type=checkbox]');
function getSelectedRoomTypes () {
const values = [];
roomTypesCheckboxes.forEach(input => input.checked ? values.push(input.value): null);
return values;
}
function applyPriceFilters (e) {
const maximumPrice = parseInt(e.target.value);
pricePlaceholder.innerText = maximumPrice + "€";
priceFilter.setFilters({ lte: maximumPrice });
// or
// priceFilter.set('lte', maximumPrice);
}
function applyRoomFilters () {
roomTypeFilter.setFilters({ in: getSelectedRoomTypes() });
// or
// roomTypeFilter.set('in', getSelectedRoomTypes());
}
function registerListeners () {
inputRange.addEventListener('input', e => {
inputRange.style.setProperty('--value', (inputRange.value - inputRange.min) / 0.59);
});
inputRange.addEventListener('change', e => {
applyPriceFilters(e)
});
roomTypesCheckboxes.forEach(
input => input.addEventListener('click', () => applyRoomFilters())
);
}
const roomTypeFilter = new carto.filter.Category('room_type', { in: getSelectedRoomTypes() });
const priceFilter = new carto.filter.Range('price', { lte: 40 });
const source = new carto.source.SQL('SELECT * FROM airbnb_listings');
// You can apply both filters in two different ways
// 1. Adding both filters to the source
source.addFilters([ priceFilter, roomTypeFilter ]);
// 2. Creating an AND filter to join the two filters and adding it to the source
// const roomAndPriceFilter = new carto.filter.AND([ priceFilter, roomTypeFilter ]);
// source.addFilter(roomAndPriceFilter)
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
marker-fill: ramp([price], (#ffc6c4, #ee919b, #cc607d, #9e3963, #672044), quantiles);
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
registerListeners();
</script>
</body>
</html>
@@ -0,0 +1,115 @@
<!DOCTYPE html>
<html>
<head>
<title>Bounding Box filter | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Bounding Box filter</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Apply a map bounding box filter to dataviews.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Move the map</p>
</section>
<div class="widget category"></div>
<div class="widget formula"></div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
zoomControl: true,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {
featureOverColumns: ['name', 'pop_max']
});
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
const categoryDataview = new carto.dataview.Category(source, 'adm0name', {
limit: 4,
operation: carto.operation.SUM,
operationColumn: 'pop_max'
});
categoryDataview.on('dataChanged', renderWidgetCategory);
client.addDataview(categoryDataview);
const formulaDataview = new carto.dataview.Formula(source, 'pop_max', {
operation: carto.operation.COUNT,
});
formulaDataview.on('dataChanged', renderWidgetFormula);
client.addDataview(formulaDataview);
const bboxFilter = new carto.filter.BoundingBoxGoogleMaps(map);
categoryDataview.addFilter(bboxFilter);
formulaDataview.addFilter(bboxFilter);
function renderWidgetCategory(data) {
const categories = data.categories.map(category => `
<li>
<h3>${category.name}</h3>
<p class="open-sans">${parseInt(category.value)} <small>inhabitants</small></p>
</li>
`).join('');
const content = `<ul>${categories}</ul>`;
document.querySelector('.widget.category').innerHTML = content;
}
function renderWidgetFormula(data) {
const content = `<h2 class="h2">${data.result} <small>cities</small></h2>`;
document.querySelector('.widget.formula').innerHTML = content;
}
</script>
</body>
</html>
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<title>Bounding Box filter | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Bounding Box filter</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Apply a map bounding box filter to dataviews.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Move the map</p>
</section>
<div class="widget category"></div>
<div class="widget formula"></div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {
featureOverColumns: ['name', 'pop_max']
});
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
const categoryDataview = new carto.dataview.Category(source, 'adm0name', {
limit: 4,
operation: carto.operation.SUM,
operationColumn: 'pop_max'
});
categoryDataview.on('dataChanged', renderWidgetCategory);
client.addDataview(categoryDataview);
const formulaDataview = new carto.dataview.Formula(source, 'pop_max', {
operation: carto.operation.COUNT,
});
formulaDataview.on('dataChanged', renderWidgetFormula);
client.addDataview(formulaDataview);
const bboxFilter = new carto.filter.BoundingBoxLeaflet(map);
categoryDataview.addFilter(bboxFilter);
formulaDataview.addFilter(bboxFilter);
function renderWidgetCategory(data) {
const categories = data.categories.map(category => `
<li>
<h3>${category.name}</h3>
<p class="open-sans">${parseInt(category.value)} <small>inhabitants</small></p>
</li>
`).join('');
const content = `<ul>${categories}</ul>`;
document.querySelector('.widget.category').innerHTML = content;
}
function renderWidgetFormula(data) {
const content = `<h2 class="h2">${data.result} <small>cities</small></h2>`;
document.querySelector('.widget.formula').innerHTML = content;
}
</script>
</body>
</html>
@@ -0,0 +1,113 @@
<!DOCTYPE html>
<html>
<head>
<title>Category Filter | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Category Filter</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Apply a category filter to the listings shown in the visualization.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Change the selected room types to filter the listings.</p>
</section>
<div id="controls">
<div id="info">
<h3>Room Types</h3>
</div>
<ul>
<li>
<input type="checkbox" name="roomTypes[]" id="entire" value="Entire home/apt" checked>
<label for="entire">Entire home/apt</label>
</li>
<li>
<input type="checkbox" name="roomTypes[]" id="private" value="Private room" checked>
<label for="private">Private Room</label>
</li>
<li>
<input type="checkbox" name="roomTypes[]" id="shared" value="Shared room" checked>
<label for="shared">Shared Room</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
function getSelectedRoomTypes () {
const inputControls = document.querySelectorAll('#controls input');
const values = [];
inputControls.forEach(input => input.checked ? values.push(input.value): null);
return values;
}
function applyFilters () {
roomTypeFilter.setFilters({ in: getSelectedRoomTypes() });
// or
// roomTypeFilter.set('in', getSelectedRoomTypes());
}
function registerListeners () {
document.querySelectorAll('#controls input').forEach(
input => input.addEventListener('click', () => applyFilters())
);
}
const map = L.map('map').setView([40.42252398976147, -3.659729361534119], 12);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const roomTypeFilter = new carto.filter.Category('room_type', { in: getSelectedRoomTypes() });
const source = new carto.source.SQL('SELECT * FROM airbnb_listings');
source.addFilter(roomTypeFilter);
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
marker-fill: ramp([room_type], (#88CCEE, #CC6677, #DDCC77), ("Entire home/apt", "Private room", "Shared room"), "=");
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
registerListeners();
</script>
</body>
</html>
+334
View File
@@ -0,0 +1,334 @@
<!DOCTYPE html>
<html>
<head>
<title> Filter data on map with Circle | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" rel="stylesheet">
<!-- Include Leaflet Draw plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.css" />
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
<!-- Include Chart.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<style>
.dataview {
margin-bottom: 0px;
color: gray;
padding-bottom: 3px;
border-bottom: 1px #ddd solid;
}
#railroadWidget {
max-width: 90%;
}
</style>
</head>
<body>
<!-- map element -->
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box" style="max-height:90vh; overflow: auto;">
<header>
<h1>Circle Filter</h1>
<p class="open-sans"><em>Draw a circle to get filtered results</em></p>
</header>
<br />
<div>
<p class="open-sans dataview">Formula dataview</p>
<div class="widget formula">
<!-- To be updated with Formula & Circle filter -->
</div>
<p class="open-sans dataview">Category dataview</p>
<div class="widget category">
<!-- To be updated with Category & Circle filter -->
</div>
<p class="open-sans dataview">Histogram dataview</p>
<div class="widget histogram">
<!-- To be updated with Histogram & Circle filter -->
</div>
</div>
<div>
<p class="open-sans dataview">TimeSeries dataview</p>
<div>
<!-- To be updated with TimeSeries & Circle filter -->
<canvas id="railroadWidget"></canvas>
</div>
</div>
</div>
</aside>
<script>
// basic objects
let map;
let client;
let citiesSource;
let railRoadSource;
let categoryDataview;
let formulaDataview;
let histogramDataview;
let timeSeriesDataview;
let railroadWidget;
let circleFilter;
let drawnItems;
// create basic map and client configuration
function createBasicMap() {
map = L.map('map').setView([40, -80], 7);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
// set CARTO client
client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
}
// create a cities layer & source
function prepareCitiesLayer() {
citiesSource = new carto.source.SQL(`
SELECT * FROM ne_10m_populated_places_simple
`);
const style = new carto.style.CartoCSS(`
#layer {
marker-fill: red;
}
`);
const layer = new carto.layer.Layer(citiesSource, style);
client.addLayer(layer);
}
// functions to display filtered dataview results on the panel
// 1. cities --> category
function renderWidgetCategory(data) {
const categories = data.categories.map(category => `
<li>
<h3>${category.name}</h3>
<p class="open-sans">${parseInt(category.value)} <small>inhabitants</small></p>
</li>
`).join('');
const content = `<ul>${categories}</ul>`;
document.querySelector('.widget.category').innerHTML = content;
}
// 2. cities --> formula
function renderWidgetFormula(data) {
const content = `<h2 class="h2">${data.result} <small>cities</small></h2>`;
document.querySelector('.widget.formula').innerHTML = content;
}
// 3. cities --> histogram
function renderWidgetHistogram(data) {
let histogram = '<ul class="open-sans">';
data.bins.forEach(bin => {
const line = '<li>' + bin.start + ' to ' + bin.end + ' interval has ' + bin.freq +
' cities</li>';
if (bin.freq > 0) {
histogram += line;
}
});
histogram += "</ul>";
document.querySelector('.widget.histogram').innerHTML = histogram;
}
// 4. raiload --> timeseries
function initializeWidgetTimeSeries() {
const widgetElement = document.getElementById("railroadWidget");
railroadWidget = new Chart(widgetElement.getContext('2d'), {
type: 'bar',
data: {
datasets: [{
label: 'Railroad accidents',
data: [],
borderWidth: 1,
backgroundColor: 'rgba(0, 255, 0, 0.5)'
}]
},
options: {
responsive: true,
scales: {
xAxes: [{
ticks: {
display: false
}
}]
}
}
});
widgetElement.style.display = 'none';
}
function renderWidgetTimeSeries(data) {
const widget = document.getElementById("railroadWidget");
if (data.totalAmount === 0){
widget.style.display = 'none';
}else{
widget.style.display = 'block';
}
railroadWidget.data.labels = data.bins.map(function (x) {
let dt = new Date(x.start);
return dt.getFullYear() + "/" + (dt.getMonth() + 1) + "/" + dt.getDate();
});
railroadWidget.data.datasets.forEach((dataset) => {
dataset.data = data.bins.map(x => x.freq);
});
railroadWidget.update();
};
// create 3 dataviews on cities (Category, Formula & Histogram).
function createDataviewsOnCities() {
// Category dataview
categoryDataview = new carto.dataview.Category(citiesSource, 'adm1name', {
limit: 4,
operation: carto.operation.SUM,
operationColumn: 'pop_max'
});
categoryDataview.on('dataChanged', renderWidgetCategory);
client.addDataview(categoryDataview);
// Formula dataview
formulaDataview = new carto.dataview.Formula(citiesSource, 'pop_max', {
operation: carto.operation.COUNT,
});
formulaDataview.on('dataChanged', renderWidgetFormula);
client.addDataview(formulaDataview);
// Histogram dataview
histogramDataview = new carto.dataview.Histogram(citiesSource, 'pop_max', {
bins: 10
});
histogramDataview.on('dataChanged', renderWidgetHistogram);
client.addDataview(histogramDataview);
}
// create a railroad data layer & source
function prepareRailroadLayer() {
railRoadSource = new carto.source.Dataset('railroad_data');
const railroadLayer = new carto.layer.Layer(railRoadSource,
new carto.style.CartoCSS(`
#layer {
marker-width: 5;
marker-fill: #00FF00;
marker-line-color: gray;
marker-line-width: 0.3;
}
`)
);
client.addLayer(railroadLayer);
}
// create 1 dataview on railroad data (TimeSeries)
function createDataviewOnRailroad() {
timeSeriesDataview = new carto.dataview.TimeSeries(railRoadSource, 'date', {
aggregation: carto.dataview.timeAggregation.AUTO,
offset: 1
});
timeSeriesDataview.on('dataChanged', renderWidgetTimeSeries);
client.addDataview(timeSeriesDataview);
}
// create the circle filter and add it to the dataviews
function createAndBindCircleFilter() {
circleFilter = new carto.filter.Circle();
circleFilter.setCircle({
lat: 0,
lng: 0,
radius: 0
});
categoryDataview.addFilter(circleFilter);
formulaDataview.addFilter(circleFilter);
histogramDataview.addFilter(circleFilter);
timeSeriesDataview.addFilter(circleFilter);
}
function prepareCircleDrawing() {
// layer to draw circles
drawnItems = L.featureGroup().addTo(map);
// Control to draw a Circle and use it as the spatial filter
let drawControl = new L.Control.Draw({
draw: {
polygon: false,
polyline: false,
line: false,
marker: false,
rectangle: false,
circle: {
shapeOptions: {
color: 'red',
weight: 0.1,
opacity: 0.5
}
},
circlemarker: false,
},
edit: false
});
map.addControl(drawControl);
// Get radius and center & apply to Circle filter
map.on(L.Draw.Event.CREATED, function (e, d) {
let drawnCircle = e.layer;
drawnItems.clearLayers();
drawnItems.addLayer(drawnCircle);
// get circle data
let radius = drawnCircle.getRadius();
let centerLat = drawnCircle.getLatLng().lat;
let centerLng = drawnCircle.getLatLng().lng;
const circleData = {
lat: centerLat,
lng: centerLng,
radius: radius
};
console.log(circleData);
circleFilter.setCircle(circleData); // updated filter !
});
}
// Run the example
createBasicMap();
prepareCitiesLayer();
prepareRailroadLayer();
client.getLeafletLayer().addTo(map);
createDataviewsOnCities();
createDataviewOnRailroad();
initializeWidgetTimeSeries();
createAndBindCircleFilter();
prepareCircleDrawing();
</script>
</body>
</html>
@@ -0,0 +1,90 @@
<!DOCTYPE html>
<html>
<head>
<title>Complex Filter Example | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Complex Example</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">This map has applied a filters combination that show listings meeting these conditions:</p>
<ul>
<li class="open-sans">Between 30€ and 40€.</li>
<li class="open-sans">Centro neighbourhood.</li>
<li class="open-sans">Entire home/apartment listings OR listings that have been reviewed after May 2015.</li>
</ul>
<p class="description open-sans">If you want to know more, please go to <a href="https://cartojs-test.carto.com/tables/airbnb_listings/public">Airbnb Listings dataset</a>.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Go to the source code below, and see how filters are applied.</p>
</section>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([40.4175117794419, -3.6971674673259263], 15);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('airbnb_listings');
// or
// const source = new carto.source.SQL('SELECT * FROM airbnb_listings');
const entireHomeFilter = new carto.filter.Category('room_type', { eq: 'Entire home/apt' });
const neighbourhoodFilter = new carto.filter.Category('neighbourhood_group', { in: ['Centro'] });
const reviewsInLastYearFilter = new carto.filter.Range('last_review', { gte: new Date('2015-05-01T00:00:00.000Z') });
const priceFilter = new carto.filter.Range('price', { between: { min: 30, max: 40 } });
const filtersCombination = new carto.filter.AND([
neighbourhoodFilter,
priceFilter,
new carto.filter.OR([ entireHomeFilter, reviewsInLastYearFilter ])
]);
source.addFilter(filtersCombination);
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
</script>
</body>
</html>
@@ -0,0 +1,139 @@
<!DOCTYPE html>
<html>
<head>
<title>Custom Bounding Box filter | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.12/leaflet.draw-src.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.12/leaflet.draw-src.css" />
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Custom Bounding Box filter</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Apply a custom bounding box filter to dataviews.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Click on the <em>Draw a rectangle</em> button and draw a rectangle</p>
</section>
<div class="widget category"></div>
<div class="widget formula"></div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 20;
marker-fill: #FF583E;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {
featureOverColumns: ['name', 'pop_max']
});
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
const categoryDataview = new carto.dataview.Category(source, 'adm0name', {
limit: 4,
operation: carto.operation.SUM,
operationColumn: 'pop_max'
});
categoryDataview.on('dataChanged', renderWidgetCategory);
client.addDataview(categoryDataview);
const formulaDataview = new carto.dataview.Formula(source, 'pop_max', {
operation: carto.operation.COUNT,
});
formulaDataview.on('dataChanged', renderWidgetFormula);
client.addDataview(formulaDataview);
const bboxFilter = new carto.filter.BoundingBox(map);
categoryDataview.addFilter(bboxFilter);
formulaDataview.addFilter(bboxFilter);
// Setup drawing rectangles to configure custom bounding boxes
let rectangle = null;
const drawnItems = L.featureGroup().addTo(map);
map.addControl(new L.Control.Draw({
draw: {
polyline: false,
polygon: false,
marker: false,
circle: false,
circlemarker: false
}
}));
const el = document.getElementsByClassName('leaflet-draw-draw-rectangle');
el[0].addEventListener('click', () => {
drawnItems.removeLayer(rectangle);
bboxFilter.resetBounds();
});
map.on(L.Draw.Event.CREATED, event => {
rectangle = event.layer;
drawnItems.addLayer(rectangle);
const latLngs = rectangle.getLatLngs();
const bounds = {
west: latLngs[0][1].lng,
south: latLngs[0][3].lat,
east: latLngs[0][3].lng,
north: latLngs[0][1].lat
}
bboxFilter.setBounds(bounds);
});
function renderWidgetCategory(data) {
const categories = data.categories.map(category => `
<li>
<h3>${category.name}</h3>
<p class="open-sans">${parseInt(category.value)} <small>inhabitants</small></p>
</li>
`).join('');
const content = `<ul>${categories}</ul>`;
document.querySelector('.widget.category').innerHTML = content;
}
function renderWidgetFormula(data) {
const content = `<h2 class="h2">${data.result} <small>cities</small></h2>`;
document.querySelector('.widget.formula').innerHTML = content;
}
</script>
</body>
</html>
+332
View File
@@ -0,0 +1,332 @@
<!DOCTYPE html>
<html>
<head>
<title> Filter data on map with Polygon | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" rel="stylesheet">
<!-- Include Leaflet Draw plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.css" />
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
<!-- Include Chart.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<style>
.dataview {
margin-bottom: 0px;
color: gray;
padding-bottom: 3px;
border-bottom: 1px #ddd solid;
}
#railroadWidget {
max-width: 90%;
}
</style>
</head>
<body>
<!-- map element -->
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box" style="max-height:90vh; overflow: auto;">
<header>
<h1>Polygon Filter</h1>
<p class="open-sans"><em>Draw a polygon to get filtered results</em></p>
</header>
<br />
<div>
<p class="open-sans dataview">Formula dataview</p>
<div class="widget formula">
<!-- To be updated with Formula & Circle filter -->
</div>
<p class="open-sans dataview">Category dataview</p>
<div class="widget category">
<!-- To be updated with Category & Circle filter -->
</div>
<p class="open-sans dataview">Histogram dataview</p>
<div class="widget histogram">
<!-- To be updated with Histogram & Circle filter -->
</div>
</div>
<div>
<p class="open-sans dataview">TimeSeries dataview</p>
<div>
<!-- To be updated with TimeSeries & Circle filter -->
<canvas id="railroadWidget"></canvas>
</div>
</div>
</div>
</aside>
<script>
// basic objects
let map;
let client;
let citiesSource;
let railRoadSource;
let categoryDataview;
let formulaDataview;
let histogramDataview;
let timeSeriesDataview;
let railroadWidget;
let polygonFilter;
let drawnItems;
// create basic map and client configuration
function createBasicMap() {
map = L.map('map').setView([40, -80], 7);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
// set CARTO client
client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
}
// create a cities layer & source
function prepareCitiesLayer() {
citiesSource = new carto.source.SQL(`
SELECT * FROM ne_10m_populated_places_simple
`);
const style = new carto.style.CartoCSS(`
#layer {
marker-fill: red;
}
`);
const layer = new carto.layer.Layer(citiesSource, style);
client.addLayer(layer);
}
// functions to display filtered dataview results on the panel
// 1. cities --> category
function renderWidgetCategory(data) {
const categories = data.categories.map(category => `
<li>
<h3>${category.name}</h3>
<p class="open-sans">${parseInt(category.value)} <small>inhabitants</small></p>
</li>
`).join('');
const content = `<ul>${categories}</ul>`;
document.querySelector('.widget.category').innerHTML = content;
}
// 2. cities --> formula
function renderWidgetFormula(data) {
const content = `<h2 class="h2">${data.result} <small>cities</small></h2>`;
document.querySelector('.widget.formula').innerHTML = content;
}
// 3. cities --> histogram
function renderWidgetHistogram(data) {
let histogram = '<ul class="open-sans">';
data.bins.forEach(bin => {
const line = '<li>' + bin.start + ' to ' + bin.end + ' interval has ' + bin.freq +
' cities</li>';
if (bin.freq > 0) {
histogram += line;
}
});
histogram += "</ul>";
document.querySelector('.widget.histogram').innerHTML = histogram;
}
// 4. raiload --> timeseries
function initializeWidgetTimeSeries() {
const widgetElement = document.getElementById("railroadWidget");
railroadWidget = new Chart(widgetElement.getContext('2d'), {
type: 'bar',
data: {
datasets: [{
label: 'Railroad accidents',
data: [],
borderWidth: 1,
backgroundColor: 'rgba(0, 255, 0, 0.5)'
}]
},
options: {
responsive: true,
scales: {
xAxes: [{
ticks: {
display: false
}
}]
}
}
});
widgetElement.style.display = 'none';
}
function renderWidgetTimeSeries(data) {
const widget = document.getElementById("railroadWidget");
if (data.totalAmount === 0){
widget.style.display = 'none';
}else{
widget.style.display = 'block';
}
railroadWidget.data.labels = data.bins.map(function (x) {
let dt = new Date(x.start);
return dt.getFullYear() + "/" + (dt.getMonth() + 1) + "/" + dt.getDate();
});
railroadWidget.data.datasets.forEach((dataset) => {
dataset.data = data.bins.map(x => x.freq);
});
railroadWidget.update();
};
// create 3 dataviews on cities (Category, Formula & Histogram).
function createDataviewsOnCities() {
// Category dataview
categoryDataview = new carto.dataview.Category(citiesSource, 'adm1name', {
limit: 4,
operation: carto.operation.SUM,
operationColumn: 'pop_max'
});
categoryDataview.on('dataChanged', renderWidgetCategory);
client.addDataview(categoryDataview);
// Formula dataview
formulaDataview = new carto.dataview.Formula(citiesSource, 'pop_max', {
operation: carto.operation.COUNT,
});
formulaDataview.on('dataChanged', renderWidgetFormula);
client.addDataview(formulaDataview);
// Example to deal with dataview errors
formulaDataview.on('error', cartoError => {
console.error(cartoError.message);
})
// Histogram dataview
histogramDataview = new carto.dataview.Histogram(citiesSource, 'pop_max', {
bins: 10
});
histogramDataview.on('dataChanged', renderWidgetHistogram);
client.addDataview(histogramDataview);
}
// create a railroad data layer & source
function prepareRailroadLayer() {
railRoadSource = new carto.source.Dataset('railroad_data');
const railroadLayer = new carto.layer.Layer(railRoadSource,
new carto.style.CartoCSS(`
#layer {
marker-width: 5;
marker-fill: #00FF00;
marker-line-color: gray;
marker-line-width: 0.3;
}
`)
);
client.addLayer(railroadLayer);
}
// create 1 dataview on railroad data (TimeSeries)
function createDataviewOnRailroad() {
timeSeriesDataview = new carto.dataview.TimeSeries(railRoadSource, 'date', {
aggregation: carto.dataview.timeAggregation.AUTO,
offset: 1
});
timeSeriesDataview.on('dataChanged', renderWidgetTimeSeries);
client.addDataview(timeSeriesDataview);
}
// create the polygon filter and add it to the dataviews
function createAndBindPolygonFilter() {
polygonFilter = new carto.filter.Polygon();
polygonFilter.setPolygon({
type: 'Polygon',
coordinates: []
});
categoryDataview.addFilter(polygonFilter);
formulaDataview.addFilter(polygonFilter);
histogramDataview.addFilter(polygonFilter);
timeSeriesDataview.addFilter(polygonFilter);
}
function preparePolygonDrawing() {
// layer to draw polygons
drawnItems = L.featureGroup().addTo(map);
// Control to draw a Polygon and use it as the spatial filter
let drawControl = new L.Control.Draw({
draw: {
polygon: {
allowIntersection: false,
showArea: true,
shapeOptions: {
color: '#bada55'
}
},
polyline: false,
line: false,
marker: false,
rectangle: false,
circle: false,
circlemarker: false,
},
edit: false
});
map.addControl(drawControl);
// Get radius and center & apply to Polygon filter
map.on(L.Draw.Event.CREATED, function (e, d) {
let drawnPolygon = e.layer;
drawnItems.clearLayers();
drawnItems.addLayer(drawnPolygon);
// get polygon data
let polygonData = drawnPolygon.toGeoJSON()['geometry'];
console.log(polygonData);
polygonFilter.setPolygon(polygonData); // updated filter !
});
}
// Run the example
createBasicMap();
prepareCitiesLayer();
prepareRailroadLayer();
client.getLeafletLayer().addTo(map);
createDataviewsOnCities();
createDataviewOnRailroad();
initializeWidgetTimeSeries();
createAndBindPolygonFilter();
preparePolygonDrawing();
</script>
</body>
</html>
+105
View File
@@ -0,0 +1,105 @@
<!DOCTYPE html>
<html>
<head>
<title>Range Filter | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Range Filter</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Change the price filter to filter the listings shown in the visualization by price.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Change the selected price range to filter the listings.</p>
</section>
<div id="controls">
<div id="info">
<h3>Price</h3>
</div>
<div class="widget">
<p class="open-sans">Showing listings below and equal to <span class="js-price-placeholder">40€</span></p>
</div>
<input type="range" name="price" class="slider" min="1" max="60" value="40" step="1" min-with-suffix="1€" max-with-suffix="60€">
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const inputRange = document.querySelector('#controls input[type=range]');
inputRange.style.setProperty('--value', (inputRange.value - inputRange.min) / 0.59);
const pricePlaceholder = document.querySelector('#controls .js-price-placeholder');
function applyFilters (e) {
const maximumPrice = parseInt(e.target.value);
priceFilter.setFilters({ lte: maximumPrice });
pricePlaceholder.innerText = maximumPrice + "€";
}
function registerListeners () {
inputRange.addEventListener('input', e => {
inputRange.style.setProperty('--value', (inputRange.value - inputRange.min) / 0.59);
});
inputRange.addEventListener('change', e => {
applyFilters(e)
});
}
const map = L.map('map').setView([40.42252398976147, -3.659729361534119], 12);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const priceFilter = new carto.filter.Range('price', { lte: 40 });
const source = new carto.source.SQL('SELECT * FROM airbnb_listings');
source.addFilter(priceFilter);
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
marker-fill: ramp([price], (#ffc6c4, #ee919b, #cc607d, #9e3963, #672044), quantiles);
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
registerListeners();
</script>
</body>
</html>
@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html>
<head>
<title>Change feature columns | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Change the feature columns</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Change the columns returned in the feature event.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Click on the markers</p>
</section>
<div id="controls">
<ul class="actions">
<li>
<input id="red" type="radio" name="style" onclick="setMoreData()">
<label for="red">More data</label>
</li>
<li>
<input id="green" type="radio" name="style" onclick="setLessData()" checked>
<label for="green">Less data</label>
</li>
</ul>
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {
featureClickColumns: ['name']
});
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
layer.on('featureClicked', featureEvent => {
let content = '';
if (featureEvent.data.name) {
content += `<h3>${featureEvent.data.name.toUpperCase()}</h3>`;
}
if (featureEvent.data.pop_max) {
content += `<p class="open-sans">${featureEvent.data.pop_max} <span>max inhabitants</span></p>`;
}
if (featureEvent.data.pop_min) {
content += `<p class="open-sans">${featureEvent.data.pop_min} <span>min inhabitants</span></p>`;
}
document.getElementById('info').innerHTML = content;
});
function setMoreData() {
layer.setFeatureClickColumns(['name', 'pop_max', 'pop_min']);
document.getElementById('info').innerHTML = '';
}
function setLessData() {
layer.setFeatureClickColumns(['name']);
document.getElementById('info').innerHTML = '';
}
</script>
</body>
</html>
@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html>
<head>
<title>Change feature columns | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Change the feature columns</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Change the columns returned in the feature event.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Click on the markers</p>
</section>
<div id="controls">
<ul class="actions">
<li>
<input id="red" type="radio" name="style" onclick="setMoreData()">
<label for="red">More data</label>
</li>
<li>
<input id="green" type="radio" name="style" onclick="setLessData()" checked>
<label for="green">Less data</label>
</li>
</ul>
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {
featureClickColumns: ['name']
});
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
layer.on('featureClicked', featureEvent => {
let content = '';
if (featureEvent.data.name) {
content += `<h3>${featureEvent.data.name.toUpperCase()}</h3>`;
}
if (featureEvent.data.pop_max) {
content += `<p class="open-sans"><span>${featureEvent.data.pop_max}</span> max inhabitants</p>`;
}
if (featureEvent.data.pop_min) {
content += `<p class="open-sans"><span>${featureEvent.data.pop_min}</span> min inhabitants</p>`;
}
document.getElementById('info').innerHTML = content;
});
function setMoreData() {
layer.setFeatureClickColumns(['name', 'pop_max', 'pop_min']);
document.getElementById('info').innerHTML = '';
}
function setLessData() {
layer.setFeatureClickColumns(['name']);
document.getElementById('info').innerHTML = '';
}
</script>
</body>
</html>
@@ -0,0 +1,113 @@
<!DOCTYPE html>
<html>
<head>
<title>Change order | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Move the layers</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Update the order of your layers.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Click to move countries layer to&nbsp;front/back</p>
</section>
<div id="controls">
<ul>
<li onclick="bringToBack()">
<input type="radio" name="style" id="bringToBack">
<label for="bringToBack">Bring to back</label>
</li>
<li onclick="bringToFront()">
<input type="radio" name="style" checked id="bringToFront">
<label for="bringToFront">Bring to front</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const spainCitiesSource = new carto.source.Dataset('ne_10m_populated_places_simple');
const spainCitiesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const spainCitiesLayer = new carto.layer.Layer(spainCitiesSource, spainCitiesStyle);
const europeCountriesSource = new carto.source.Dataset('ne_adm0_europe');
const europeCountriesStyle = new carto.style.CartoCSS(`
#layer {
polygon-fill: #826DBA;
polygon-opacity: 0.8;
::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 0.8;
}
}
`);
const europeCountriesLayer = new carto.layer.Layer(europeCountriesSource, europeCountriesStyle);
client.addLayers([europeCountriesLayer, spainCitiesLayer]);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
function bringToBack() {
spainCitiesLayer.bringToBack();
// or
// spainCitiesLayer.setOrder(0);
// or
// client.moveLayer(spainCitiesLayer, 0);
}
function bringToFront() {
spainCitiesLayer.bringToFront();
// or
// spainCitiesLayer.setOrder(1);
// or
// client.moveLayer(spainCitiesLayer, 1);
}
</script>
</body>
</html>
@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<title>Change order | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Move the layers</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Update the order of your layers.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Click to move countries layer to&nbsp;front/back</p>
</section>
<div id="controls">
<ul>
<li onclick="bringToBack()">
<input type="radio" name="style" id="bringToBack">
<label for="bringToBack">Bring to back</label>
</li>
<li onclick="bringToFront()">
<input type="radio" name="style" checked id="bringToFront">
<label for="bringToFront">Bring to front</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const spainCitiesSource = new carto.source.Dataset('ne_10m_populated_places_simple');
const spainCitiesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const spainCitiesLayer = new carto.layer.Layer(spainCitiesSource, spainCitiesStyle);
const europeCountriesSource = new carto.source.Dataset('ne_adm0_europe');
const europeCountriesStyle = new carto.style.CartoCSS(`
#layer {
polygon-fill: #826DBA;
polygon-opacity: 0.8;
::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 0.8;
}
}
`);
const europeCountriesLayer = new carto.layer.Layer(europeCountriesSource, europeCountriesStyle);
client.addLayers([europeCountriesLayer, spainCitiesLayer]);
client.getLeafletLayer().addTo(map);
function bringToBack() {
spainCitiesLayer.bringToBack();
// or
// spainCitiesLayer.setOrder(0);
// or
// client.moveLayer(spainCitiesLayer, 0);
}
function bringToFront() {
spainCitiesLayer.bringToFront();
// or
// spainCitiesLayer.setOrder(1);
// or
// client.moveLayer(spainCitiesLayer, 1);
}
</script>
</body>
</html>
@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html>
<head>
<title>Change source | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Change the source</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Update the source of your layers.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Select different sources</p>
</section>
<div id="controls">
<ul>
<li onclick="setAllCities()">
<input type="radio" name="source" checked id="all">
<label for="all">All cities</label>
</li>
<li onclick="setEuropeanCities()">
<input type="radio" name="source" id="europe">
<label for="europe">European cities</label>
</li>
<li onclick="setSpanishCities()">
<input type="radio" name="source" id="spain">
<label for="spain">Spanish cities</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.SQL('SELECT * FROM ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
function setAllCities() {
source.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
`);
}
function setEuropeanCities() {
source.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
`);
}
function setSpanishCities() {
source.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name = \'Spain\'
`);
}
</script>
</body>
</html>
@@ -0,0 +1,100 @@
<!DOCTYPE html>
<html>
<head>
<title>Change source | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Change the source</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Update the source of your layers.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Select different sources</p>
</section>
<div id="controls">
<ul>
<li onclick="setAllCities()">
<input type="radio" name="source" checked id="all">
<label for="all">All cities</label>
</li>
<li onclick="setEuropeanCities()">
<input type="radio" name="source" id="europe">
<label for="europe">European cities</label>
</li>
<li onclick="setSpanishCities()">
<input type="radio" name="source" id="spain">
<label for="spain">Spanish cities</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.SQL('SELECT * FROM ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
function setAllCities() {
source.setQuery('SELECT * FROM ne_10m_populated_places_simple');
}
function setEuropeanCities() {
source.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
`);
}
function setSpanishCities() {
source.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name = \'Spain\'
`);
}
</script>
</body>
</html>
@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html>
<head>
<title>Change style | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Change the style</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Update the style of your layers.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Select different styles</p>
</section>
<div id="controls">
<ul>
<li onclick="setRed()">
<input type="radio" name="style" checked id="red">
<label for="red">Size 7px - Red</label>
</li>
<li onclick="setGreen()">
<input type="radio" name="style" id="green">
<label for="green">Size 9px - Green</label>
</li>
<li onclick="setBlue()">
<input type="radio" name="style" id="blue">
<label for="blue">Size 11px - Blue</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
function setRed() {
style.setContent(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
}
function setGreen() {
style.setContent(`
#layer {
marker-width: 7;
marker-fill: #9BC63B;
marker-line-color: #FFFFFF;
}
`);
}
function setBlue() {
style.setContent(`
#layer {
marker-width: 9;
marker-fill: #1785FB;
marker-line-color: #FFFFFF;
}
`);
}
</script>
</body>
</html>
@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html>
<head>
<title>Change style | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Change the style</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Update the style of your layers.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Select different styles</p>
</section>
<div id="controls">
<ul>
<li onclick="setRed()">
<input type="radio" name="style" checked id="red">
<label for="red">Size 7px - Red</label>
</li>
<li onclick="setGreen()">
<input type="radio" name="style" id="green">
<label for="green">Size 9px - Green</label>
</li>
<li onclick="setBlue()">
<input type="radio" name="style" id="blue">
<label for="blue">Size 11px - Blue</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
function setRed() {
style.setContent(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
}
function setGreen() {
style.setContent(`
#layer {
marker-width: 9;
marker-fill: #9BC63B;
marker-line-color: #FFFFFF;
}
`);
}
function setBlue() {
style.setContent(`
#layer {
marker-width: 11;
marker-fill: #1785FB;
marker-line-color: #FFFFFF;
}
`);
}
</script>
</body>
</html>
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<title>Feature click | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Detect feature click</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Interact with the features on the click event.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Click on the markers</p>
</section>
<div id="controls">
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {
featureClickColumns: ['name', 'pop_max']
});
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
layer.on('featureClicked', featureEvent => {
const content = `
<h3>${featureEvent.data.name.toUpperCase()}</h3>
<p class="open-sans">${featureEvent.data.pop_max} <small>max inhabitants</small></p>
`;
document.getElementById('info').innerHTML = content;
});
</script>
</body>
</html>
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html>
<head>
<title>Feature click | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Detect feature click</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Interact with the features on the click event.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Click on the markers</p>
</section>
<div id="controls">
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {
featureClickColumns: ['name', 'pop_max']
});
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
layer.on('featureClicked', featureEvent => {
const content = `
<h3>${featureEvent.data.name.toUpperCase()}</h3>
<p class="open-sans">${featureEvent.data.pop_max} <small>max inhabitants</small></p>
`;
document.getElementById('info').innerHTML = content;
});
</script>
</body>
</html>
@@ -0,0 +1,111 @@
<!DOCTYPE html>
<html>
<head>
<title>Feature over/out | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Detect feature over/out</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Interact with the features on the over/out event.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Move the mouse over the markers</p>
</section>
<div id="controls">
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 10;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {
featureOverColumns: ['name', 'pop_max']
});
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
layer.on('featureOver', featureEvent => {
const content = `
<h3>${featureEvent.data.name.toUpperCase()}</h3>
<p class="open-sans">${featureEvent.data.pop_max} <small>max inhabitants</small></p>
`;
document.getElementById('info').innerHTML = content;
featureVisible = true;
});
layer.on('featureOut', featureEvent => {
hideInfo();
});
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
const hideInfo = debounce(function () {
document.getElementById('info').innerHTML = '';
}, 500);
</script>
</body>
</html>
@@ -0,0 +1,102 @@
<!DOCTYPE html>
<html>
<head>
<title>Feature over/out | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Detect feature over/out</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Interact with the features on the over/out event.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Move the mouse over the markers</p>
</section>
<div id="controls">
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 10;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {
featureOverColumns: ['name', 'pop_max']
});
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
layer.on('featureOver', featureEvent => {
const content = `
<h3>${featureEvent.data.name.toUpperCase()}</h3>
<p class="open-sans">${featureEvent.data.pop_max} <small>max inhabitants</small></p>
`;
document.getElementById('info').innerHTML = content;
featureVisible = true;
});
layer.on('featureOut', featureEvent => {
hideInfo();
});
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
const hideInfo = debounce(function () {
document.getElementById('info').innerHTML = '';
}, 500);
</script>
</body>
</html>
@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<title>Layer with aggregation cluster | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Server tile aggregation cluster</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">This map has smart backend aggregation cluster applied. See source code for details.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 38.479395, lng: -102.480469 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
// Define source using value 1 as count to count the number
// of points within the aggregation that will be created
const source = new carto.source.SQL(`
SELECT *, 1 as count
FROM stormevents_locations_2014
`);
// Aggregation option summing al values of field count
const aggregation = new carto.layer.Aggregation({
threshold: 1,
resolution: 32,
placement: carto.layer.Aggregation.placement.SAMPLE,
columns: {
total_agg: {
aggregateFunction: carto.layer.Aggregation.operation.SUM,
aggregatedColumn: "count"
}
}
});
const style = new carto.style.CartoCSS(`
#layer {
marker-fill: red;
marker-width: ramp([total_agg], 6,25 , quantiles);
}
#layer::labels {
text-name: [total_agg];
text-face-name: 'DejaVu Sans Book';
text-size: 10;
text-fill: #FFFFFF;
text-label-position-tolerance: 0;
text-halo-radius: 1;
text-halo-fill: #6F808D;
text-allow-overlap: true;
text-placement: point;
text-placement-type: dummy;
}
`);
const layer = new carto.layer.Layer(source, style, { aggregation });
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
</script>
</body>
</html>
@@ -0,0 +1,90 @@
<!DOCTYPE html>
<html>
<head>
<title>Layer with aggregation cluster | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Server tile aggregation cluster</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">This map has smart backend aggregation cluster applied. See source code for details.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([38.479395, -102.480469], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
// Define source using value 1 as count to count the number
// of points within the aggregation that will be created
const source = new carto.source.SQL(`
SELECT *, 1 as count
FROM stormevents_locations_2014
`);
// Aggregation option summing al values of field count
const aggregation = new carto.layer.Aggregation({
threshold: 1,
resolution: 32,
placement: carto.layer.Aggregation.placement.SAMPLE,
columns: {
total_agg: {
aggregateFunction: carto.layer.Aggregation.operation.SUM,
aggregatedColumn: "count"
}
}
});
const style = new carto.style.CartoCSS(`
#layer {
marker-fill: red;
marker-width: ramp([total_agg], 6,25 , quantiles);
}
#layer::labels {
text-name: [total_agg];
text-face-name: 'DejaVu Sans Book';
text-size: 10;
text-fill: #FFFFFF;
text-label-position-tolerance: 0;
text-halo-radius: 1;
text-halo-fill: #6F808D;
text-allow-overlap: true;
text-placement: point;
text-placement-type: dummy;
}
`);
const layer = new carto.layer.Layer(source, style, { aggregation });
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
</script>
</body>
</html>
@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>
<head>
<title>Layer with aggregation | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Server tile aggregation</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">This map has smart backend aggregation applied. See source code for details.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: ramp([population], (#ecda9a, #f7945d, #ee4d5a), jenks());
marker-line-color: #FFFFFF;
}
`);
// Aggregation option
const aggregation = new carto.layer.Aggregation({
threshold: 1,
resolution: 4,
placement: carto.layer.Aggregation.placement.SAMPLE,
columns: {
population: {
aggregateFunction: carto.layer.Aggregation.operation.SUM,
aggregatedColumn: 'pop_max'
}
}
});
const layer = new carto.layer.Layer(source, style, { aggregation });
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
</script>
</body>
</html>
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<title>Layer with aggregation | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Server tile aggregation</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">This map has smart backend aggregation applied. See source code for details.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: ramp([population], (#ecda9a, #f7945d, #ee4d5a), jenks());
marker-line-color: #FFFFFF;
}
`);
// Aggregation option
const aggregation = new carto.layer.Aggregation({
threshold: 1,
resolution: 4,
placement: carto.layer.Aggregation.placement.SAMPLE,
columns: {
population: {
aggregateFunction: carto.layer.Aggregation.operation.SUM,
aggregatedColumn: 'pop_max'
}
}
});
const layer = new carto.layer.Layer(source, style, { aggregation });
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
</script>
</body>
</html>
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title>Layer with zoom options | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, { minzoom: 3, maxzoom: 3 });
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
</script>
</body>
</html>
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<title>Layer with zoom options | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<script>
const map = L.map('map').setView([30, 0], 3);
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style, {minzoom: 3, maxzoom: 3});
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
</script>
</body>
</html>
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<head>
<title>Multilayer | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Add more layers</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Add multiple CARTO layers to your map.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 40, lng: 0 },
zoom: 5,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const spainCitiesSource = new carto.source.SQL(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name = \'Spain\'
`);
const spainCitiesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const spainCitiesLayer = new carto.layer.Layer(spainCitiesSource, spainCitiesStyle);
const europeCountriesSource = new carto.source.Dataset('ne_adm0_europe');
const europeCountriesStyle = new carto.style.CartoCSS(`
#layer {
polygon-fill: #826DBA;
polygon-opacity: 0.8;
::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 0.8;
}
}
`);
const europeCountriesLayer = new carto.layer.Layer(europeCountriesSource, europeCountriesStyle);
client.addLayers([europeCountriesLayer, spainCitiesLayer]);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
</script>
</body>
</html>
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<title>Multilayer | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Add more layers</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Add multiple CARTO layers to your map.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([40, 0], 5);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const spainCitiesSource = new carto.source.SQL(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name = \'Spain\'
`);
const spainCitiesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const spainCitiesLayer = new carto.layer.Layer(spainCitiesSource, spainCitiesStyle);
const europeCountriesSource = new carto.source.Dataset('ne_adm0_europe');
const europeCountriesStyle = new carto.style.CartoCSS(`
#layer {
polygon-fill: #826DBA;
polygon-opacity: 0.8;
::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 0.8;
}
}
`);
const europeCountriesLayer = new carto.layer.Layer(europeCountriesSource, europeCountriesStyle);
client.addLayers([europeCountriesLayer, spainCitiesLayer]);
client.getLeafletLayer().addTo(map);
</script>
</body>
</html>
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<title>Single layer | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Add a layer</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Add one CARTO layer to your map.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
</script>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<title>Single layer | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="https://fonts.googleapis.com/css?family=Montserrat:600" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map">
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Add a layer</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Add one CARTO layer to your map.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.Dataset('ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
</script>
</body>
</html>
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>App | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
</head>
<body>
<!-- TODO: add your code here -->
</body>
</html>
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>App | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
</head>
<body>
<!-- TODO: add your code here -->
</body>
</html>
@@ -0,0 +1,178 @@
<!DOCTYPE html>
<html>
<head>
<title>Custom search dataset | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
<style>
#selectDrop {
background-color: #d2eaef;
opacity: 0.8;
position: absolute;
top: 50px;
left: 50px;
width: auto;
height: auto;
padding: 10px;
display: block;
z-index: 9000;
}
#selectDrop input {
width: 200px;
}
div#results {
background: #FFF;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="searchbox">
<select id="selectDrop">
<option selected value="">Please Select</option>
</select>
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Look for data within your dataset</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Look for data within your dataset using dropdown menu.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
let input;
// set map with initial zoom and coodinates view
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 40, lng: 2 },
zoom: 4,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
// populate dropdown menu
populateDrowpDown()
// set CARTO client
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.SQL(`
SELECT * FROM ne_adm0_europe
`);
// define CartoCSS code to style data on map
const style = new carto.style.CartoCSS(`
#ne_adm0_europe {
polygon-fill: #3E7BB6;
polygon-opacity: 0.7;
line-color: #FFF;
line-width: 0.5;
line-opacity: 1;
}
#layer::labels {
text-name: [admin];
text-face-name: 'DejaVu Sans Book';
text-size: 10;
text-fill: #FFFFFF;
text-label-position-tolerance: 0;
text-halo-radius: 1;
text-halo-fill: #6F808D;
text-dy: -10;
text-allow-overlap: true;
text-placement: point;
text-placement-type: dummy;
}
`);
// create CARTO layer from source and style variables
const Cartolayer = new carto.layer.Layer(source, style);
// add CARTO layer to the client
client.addLayer(Cartolayer);
// get tile from client and add them to the map object
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
// function to get list of country names to populate dropdown menu
function populateDrowpDown(){
return fetch(
`https://cartojs-test.carto.com/api/v2/sql?format=geojson&q=SELECT the_geom, admin FROM ne_adm0_europe ORDER BY admin ASC`
).then((resp) => resp.json())
.then((response) => {
return response['features'].map(function(feature){
option = document.createElement("option")
option.setAttribute("value", feature.properties.admin)
option.textContent = feature.properties.admin
document.getElementById("selectDrop").appendChild(option);
});
}).catch((error) => {
console.log(error)
})
}
// when select option from downdown menu, change bounding box of map
// to geometry of the selected country
document.getElementById('selectDrop').addEventListener("change", function (e) {
input = e.currentTarget.selectedOptions[0].attributes[0].value;
// calculate the xmax, ymax, xmin, ymin coordinates of the bounding box
// of the country polygon of the CARTO dataset
return fetch(
`https://cartojs-test.carto.com/api/v2/sql?format=geojson&q=
WITH bbox as (
SELECT ST_Envelope(the_geom) as the_geom
FROM ne_adm0_europe
WHERE admin Ilike '${input}'
)
SELECT the_geom, ST_Xmax(the_geom) as xmax,
ST_Ymax(the_geom) as ymax,
ST_Xmin(the_geom) as xmin,
ST_Ymin(the_geom) as ymin
FROM bbox
`)
.then((resp) => resp.json())
.then((response) => {
// get coordinates
coordinates = response['features'][0].properties
// set LatLng objects from coordinates from CARTO
let sw = new google.maps.LatLng(coordinates.ymin, coordinates.xmin);
let ne = new google.maps.LatLng(coordinates.ymax, coordinates.xmax);
// instantiate Google bounds
bounds = new google.maps.LatLngBounds(sw, ne)
// set bounds of map to the geometry from CARTO
map.fitBounds(bounds);
})
});
</script>
</body>
</html>
@@ -0,0 +1,147 @@
<!DOCTYPE html>
<html>
<head>
<title>Custom search dataset | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
<style>
#selectDrop {
background-color: #d2eaef;
opacity: 0.8;
position: absolute;
top: 10px;
left: 50px;
width: auto;
height: auto;
padding: 10px;
display: block;
z-index: 9000;
}
#selectDrop input {
width: 200px;
}
div#results {
background: #FFF;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="searchbox">
<select id="selectDrop">
<option selected value="">Please Select</option>
</select>
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Look for data within your dataset</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Look for data within your dataset using dropdown menu.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
// set map with initial zoom and coodinates view
const map = L.map('map').setView([40, 2], 4);
let input;
// disable scroll wheel zoom
map.scrollWheelZoom.disable();
// populate dropdown menu
populateDrowpDown()
// add basemaps to map
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
// set CARTO client
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.SQL(`
SELECT * FROM ne_adm0_europe
`);
// define CartoCSS code to style data on map
const style = new carto.style.CartoCSS(`
#ne_adm0_europe {
polygon-fill: #3E7BB6;
polygon-opacity: 0.7;
line-color: #FFF;
line-width: 0.5;
line-opacity: 1;
}
#layer::labels {
text-name: [admin];
text-face-name: 'DejaVu Sans Book';
text-size: 10;
text-fill: #FFFFFF;
text-label-position-tolerance: 0;
text-halo-radius: 1;
text-halo-fill: #6F808D;
text-dy: -10;
text-allow-overlap: true;
text-placement: point;
text-placement-type: dummy;
}
`);
// create CARTO layer from source and style variables
const Cartolayer = new carto.layer.Layer(source, style);
// add CARTO layer to the client
client.addLayer(Cartolayer);
// get tile from client and add them to the map object
client.getLeafletLayer().addTo(map);
// function to get list of country names to populate dropdown menu
function populateDrowpDown(){
return fetch(
`https://cartojs-test.carto.com/api/v2/sql?format=geojson&q=SELECT the_geom, admin FROM ne_adm0_europe ORDER BY admin ASC`
).then((resp) => resp.json())
.then((response) => {
return response['features'].map(function(feature){
option = document.createElement("option")
option.setAttribute("value", feature.properties.admin)
option.textContent = feature.properties.admin
document.getElementById("selectDrop").appendChild(option);
});
}).catch((error) => {
console.log(error)
})
}
// when select option from downdown menu, change bounding box of map
// to geometry of the selected country
document.getElementById('selectDrop').addEventListener("change", function (e) {
input = e.currentTarget.selectedOptions[0].attributes[0].value;
return fetch(`https://cartojs-test.carto.com/api/v2/sql?format=geojson&q=SELECT * FROM ne_adm0_europe where admin Ilike '${input}'`)
.then((resp) => resp.json())
.then((response) => {
geojsonLayer = L.geoJson(response)
map.fitBounds(geojsonLayer.getBounds());
})
});
</script>
</body>
</html>
@@ -0,0 +1,119 @@
<!DOCTYPE html>
<html>
<head>
<title>Edit SQL & CartoCSS | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Edit SQL & CartoCSS</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Edit manually the SQL query and the CartoCSS style.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">This example only uses one style and one layer whose content is changed.</p>
<p class="open-sans">Since the style and source objects are the same they won't trigger events. You need to use the promise to handle
errors.</p>
</section>
</section>
<footer class="js-footer"></footer>
</div>
<div class="box widget">
<h2 class="h2">SQL</h2>
<textarea id="sql" rows="3">SELECT * FROM ne_10m_populated_places_simple</textarea>
<button class="button" onclick="updateSource()">UPDATE SQL</button>
</div>
<div class="box widget">
<h2 class="h2">CartoCSS</h2>
<textarea id="cartocss" rows="3">
#layer {
marker-fill: red;
}
</textarea>
<button class="button-update button" onclick="updateStyle()">UPDATE STYLE</button>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const populatedPlacesSource = new carto.source.SQL(getValue('#sql'));
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-fill-opacity: 0.9;
marker-line-width: 0.5;
marker-line-color: #FFFFFF;
}
`);
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
client.addLayer(populatedPlacesLayer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
function updateSource() {
reset('#sql');
populatedPlacesSource.setQuery(getValue('#sql'))
.catch(cartoError => {
error('#sql', cartoError);
});
}
function updateStyle() {
reset('#cartocss')
populatedPlacesStyle.setContent(getValue('#cartocss'))
.catch(cartoError => {
error('#cartocss', cartoError);
});
}
function getValue(id) {
return document.querySelector(id).value
}
function reset(id) {
document.querySelector(id).style.background = 'white';
}
function error(id, cartoError) {
document.querySelector(id).style.border = '1px solid #E57373';
alert(cartoError.message);
}
</script>
</body>
</html>
@@ -0,0 +1,111 @@
<!DOCTYPE html>
<html>
<head>
<title>Edit SQL CARTOCSS | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Edit SQL & CartoCSS</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Edit manually the SQL query and the CartoCSS style.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">This example only uses one style and one layer whose content is changed.</p>
<p class="open-sans">Since the style and source objects are the same they won't trigger events. You need to use the promise to handle errors.</p>
</section>
</section>
<footer class="js-footer"></footer>
</div>
<div class="box widget">
<h2 class="h2">SQL</h2>
<textarea id="sql" rows="3">SELECT * FROM ne_10m_populated_places_simple</textarea>
<button class="button" onclick="updateSource()">UPDATE SQL</button>
</div>
<div class="box widget">
<h2 class="h2">CartoCSS</h2>
<textarea id="cartocss" rows="3">
#layer {
marker-fill: red;
}
</textarea>
<button class="button-update button" onclick="updateStyle()">UPDATE STYLE</button>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const populatedPlacesSource = new carto.source.SQL(getValue('#sql'));
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-fill-opacity: 0.9;
marker-line-width: 0.5;
marker-line-color: #FFFFFF;
}
`);
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
client.addLayer(populatedPlacesLayer);
client.getLeafletLayer().addTo(map);
function updateSource() {
reset('#sql');
populatedPlacesSource.setQuery(getValue('#sql'))
.catch(cartoError => {
error('#sql', cartoError);
});
}
function updateStyle() {
reset('#cartocss')
populatedPlacesStyle.setContent(getValue('#cartocss'))
.catch(cartoError => {
error('#cartocss', cartoError);
});
}
function getValue(id) {
return document.querySelector(id).value
}
function reset(id) {
document.querySelector(id).style.border = 'default';
}
function error(id, cartoError) {
document.querySelector(id).style.border = '1px solid #E57373';
alert(cartoError.message);
}
</script>
</body>
</html>
@@ -0,0 +1,201 @@
<!DOCTYPE html>
<html>
<head>
<title>Error handling | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Error handling</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Handle common errors in maps.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">In this example we handle the client error while calling the `addLayer` funciton.</p>
<p class="open-sans">See `refreshLayer` function in the source code for an example on how to handle Promise errors.</p>
</section>
<div id="controls">
<div id="info">
<p class="mt-16 open-sans"></p>
</div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
<div class="box widget">
<h2 class="h2">DATASET</h2>
<textarea id="dataset-value" rows=2></textarea>
<button id="dataset-button" class="button" onclick="updateDataset()">SET WRONG DATASET</button>
</div>
<div class="box widget">
<h2 class="h2">STYLE</h2>
<textarea id="style-value" rows="3"></textarea>
<button id="style-button" class="button" onclick="updateStyle()">UPDATE STYLE</button>
</div>
</aside>
<script>
// Setting up a Google Maps Map
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 50, lng: 15 },
zoom: 4,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
// State
const state = {
isDatasetValid: true,
isStyleValid: true,
errorMessage: '',
updating: false
};
// Datasets
const validDataset = 'ne_10m_populated_places_simple';
const wrongDataset = 'wrong_dataset';
// Style
const validStyle = '#layer { marker-fill: red; }';
const wrongStyle = '#layer { marker-fill: wrong-color; }';
let source = new carto.source.Dataset(validDataset);
let style = new carto.style.CartoCSS(validStyle);
let layer = new carto.layer.Layer(source, style);
// Adding the layers to the map
client.addLayer(layer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
updateUI();
function refreshLayer(layer) {
client.addLayer(layer)
.then(function () {
state.errorMessage = '';
state.updating = false;
updateUI();
})
.catch(function (error) {
state.errorMessage = error.message;
state.updating = false;
updateUI();
});
}
function updateDataset() {
client.removeLayer(layer);
state.isDatasetValid = !state.isDatasetValid;
state.updating = true;
const dataset = state.isDatasetValid
? validDataset
: wrongDataset;
updateUI();
source = new carto.source.Dataset(dataset);
layer = new carto.layer.Layer(source, style);
refreshLayer(layer);
}
function updateStyle() {
client.removeLayer(layer);
state.isStyleValid = !state.isStyleValid;
state.updating = true;
const styleContent = state.isStyleValid
? validStyle
: wrongStyle;
updateUI();
style = new carto.style.CartoCSS(styleContent);
layer = new carto.layer.Layer(source, style);
refreshLayer(layer);
}
function updateUI() {
const datasetValueEl = document.getElementById('dataset-value');
const styleValueEl = document.getElementById('style-value');
const datasetButtonEl = document.getElementById('dataset-button');
const styleButtonEl = document.getElementById('style-button');
const panelEl = document.querySelector('#info p');
datasetValueEl.value = state.isDatasetValid
? validDataset
: wrongDataset;
styleValueEl.value = state.isStyleValid
? validStyle
: wrongStyle;
datasetButtonEl.textContent = state.isDatasetValid
? 'Set wrong dataset'
: 'Revert to a valid dataset';
styleButtonEl.textContent = state.isStyleValid
? 'Set wrong style'
: 'Revert to a valid style';
panelEl.textContent = state.updating
? 'Updating...'
: state.errorMessage
? state.errorMessage
: 'Everything OK';
if (state.updating) {
panelEl.classList.remove('bg-red');
panelEl.classList.remove('bg-white');
panelEl.classList.add('bg-orange');
panelEl.classList.add('p-8');
panelEl.classList.add('text-white');
} else if (state.errorMessage) {
panelEl.classList.add('bg-red');
panelEl.classList.remove('bg-white');
panelEl.classList.remove('bg-orange');
panelEl.classList.add('p-8');
panelEl.classList.add('text-white');
} else {
panelEl.classList.add('bg-white');
panelEl.classList.remove('bg-red');
panelEl.classList.remove('bg-orange');
panelEl.classList.remove('p-8');
panelEl.classList.remove('text-white');
}
}
</script>
</body>
</html>
@@ -0,0 +1,190 @@
<!DOCTYPE html>
<html>
<head>
<title>Error handling | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Error handling</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Handle common errors in maps.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">In this example we handle the client error while calling the `addLayer` funciton.</p>
<p class="open-sans">See `refreshLayer` function in the source code for an example on how to handle Promise errors.</p>
</section>
<div id="controls">
<div id="info"><p class="mt-16 open-sans"></p></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
<div class="box widget">
<h2 class="h2">DATASET</h2>
<textarea id="dataset-value" rows=2></textarea>
<button id="dataset-button" class="button" onclick="updateDataset()">SET WRONG DATASET</button>
</div>
<div class="box widget">
<h2 class="h2">STYLE</h2>
<textarea id="style-value" rows="3"></textarea>
<button id="style-button" class="button" onclick="updateStyle()">UPDATE STYLE</button>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
// State
const state = {
isDatasetValid: true,
isStyleValid: true,
errorMessage: '',
updating: false
};
// Datasets
const validDataset = 'ne_10m_populated_places_simple';
const wrongDataset = 'wrong_dataset';
// Style
const validStyle = '#layer { marker-fill: red; }';
const wrongStyle = '#layer { marker-fill: wrong-color; }';
let source = new carto.source.Dataset(validDataset);
let style = new carto.style.CartoCSS(validStyle);
let layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
updateUI();
function refreshLayer (layer) {
client.addLayer(layer)
.then(function () {
state.errorMessage = '';
state.updating = false;
updateUI();
})
.catch(function (error) {
state.errorMessage = error.message;
state.updating = false;
updateUI();
});
}
function updateDataset() {
client.removeLayer(layer);
state.isDatasetValid = !state.isDatasetValid;
state.updating = true;
const dataset = state.isDatasetValid
? validDataset
: wrongDataset;
updateUI();
source = new carto.source.Dataset(dataset);
layer = new carto.layer.Layer(source, style);
refreshLayer(layer);
}
function updateStyle() {
client.removeLayer(layer);
state.isStyleValid = !state.isStyleValid;
state.updating = true;
const styleContent = state.isStyleValid
? validStyle
: wrongStyle;
updateUI();
style = new carto.style.CartoCSS(styleContent);
layer = new carto.layer.Layer(source, style);
refreshLayer(layer);
}
function updateUI () {
const datasetValueEl = document.getElementById('dataset-value');
const styleValueEl = document.getElementById('style-value');
const datasetButtonEl = document.getElementById('dataset-button');
const styleButtonEl = document.getElementById('style-button');
const panelEl = document.querySelector('#info p');
datasetValueEl.value = state.isDatasetValid
? validDataset
: wrongDataset;
styleValueEl.value = state.isStyleValid
? validStyle
: wrongStyle;
datasetButtonEl.textContent = state.isDatasetValid
? 'Set wrong dataset'
: 'Revert to a valid dataset';
styleButtonEl.textContent = state.isStyleValid
? 'Set wrong style'
: 'Revert to a valid style';
panelEl.textContent = state.updating
? 'Updating...'
: state.errorMessage
? state.errorMessage
: 'Everything OK';
if (state.updating) {
panelEl.classList.remove('bg-red');
panelEl.classList.remove('bg-white');
panelEl.classList.add('bg-orange');
panelEl.classList.add('p-8');
panelEl.classList.add('text-white');
} else if (state.errorMessage) {
panelEl.classList.add('bg-red');
panelEl.classList.remove('bg-white');
panelEl.classList.remove('bg-orange');
panelEl.classList.add('p-8');
panelEl.classList.add('text-white');
} else {
panelEl.classList.add('bg-white');
panelEl.classList.remove('bg-red');
panelEl.classList.remove('bg-orange');
panelEl.classList.remove('p-8');
panelEl.classList.remove('text-white');
}
}
</script>
</body>
</html>
@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html>
<head>
<title> Filter data on map | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&libraries=drawing&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Filter data based on drawn circle</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Filter data based on drawn circle.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
// set map with initial zoom and coodinates view
// and disabling scroll wheel zoom
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 40, lng: -80 },
zoom: 5,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
var drawingManager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['circle']
},
circleOptions: {
fillColor: 'green',
fillOpacity: 0.5,
strokeWeight: 0.1,
clickable: false,
editable: false,
zIndex: 1
}
});
drawingManager.setMap(map);
// set CARTO client
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
// set SQL query to create the grid of hexagons
const source = new carto.source.SQL(`
SELECT * FROM ne_10m_populated_places_simple
`);
// define styles of layer.
const style = new carto.style.CartoCSS(`
#layer {
marker-fill: red;
}
`);
// set the CARTO layer using the source and style defines previously
const layer = new carto.layer.Layer(source, style);
// add CARTO layer to the client
client.addLayer(layer);
// retrieve tiles from CARTO to the map
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
// get radius and center of drawn circle and change source of the CARTO layer
google.maps.event.addListener(drawingManager, 'circlecomplete', function (circle) {
let radius = circle.getRadius();
let centerLat = circle.getCenter().lat();
let centerLng = circle.getCenter().lng();
circleCountPointsIntersect(radius, centerLat, centerLng)
});
// function to change the source of the CARTO layer based on radius and
// center of the circle
function circleCountPointsIntersect(radius, lat,lng){
source.setQuery(`
SELECT cartodb_id, the_geom, the_geom_webmercator
FROM ne_10m_populated_places_simple
WHERE ST_intersects(
the_geom,
ST_Buffer(
ST_SetSRID(ST_Point(${lng},${lat}),4326)::geography,
${radius})::geometry
)
`);
};
</script>
</body>
</html>
@@ -0,0 +1,125 @@
<!DOCTYPE html>
<html>
<head>
<title> Filter data on map | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include Leaflet Draw plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.css" />
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<!-- map element -->
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Filter data based on drawn circle</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Filter data based on drawn circle.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
// set map with initial zoom and coodinates view
const map = L.map('map').setView([40, -80], 7);
// disable scroll wheel zoom
map.scrollWheelZoom.disable();
// add basemaps to map
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
// set CARTO client
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
// set SQL query to create the grid of hexagons
const source = new carto.source.SQL(`
SELECT * FROM ne_10m_populated_places_simple
`);
// define styles of layer.
const style = new carto.style.CartoCSS(`
#layer {
marker-fill: red;
}
`);
// set the CARTO layer using the source and style defines previously
const layer = new carto.layer.Layer(source, style);
// add CARTO layer to the client
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
let drawControl = new L.Control.Draw({
draw: {
polygon: false,
polyline: false,
line: false,
marker: false,
rectangle: false,
circle: {
shapeOptions: {
color: 'green',
weight: 0.1,
opacity: 0.5
}
},
circlemarker: false,
},
edit: false
});
// initialise the draw controls
map.addControl(drawControl);
// get radius and center of drawn circle and change source of the CARTO layer
map.on(L.Draw.Event.CREATED, function (e) {
let layer = e.layer;
map.addLayer(layer);
let radius = layer.getRadius();
let centerLat = layer.getLatLng().lat;
let centerLng = layer.getLatLng().lng;
circleCountPointsIntersect(radius, centerLat, centerLng)
});
// function to change the source of the CARTO layer based on radius and
// center of the circle
function circleCountPointsIntersect(radius, lat,lng){
source.setQuery(`
SELECT cartodb_id, the_geom, the_geom_webmercator
FROM ne_10m_populated_places_simple
WHERE ST_intersects(
the_geom,
ST_Buffer(
ST_SetSRID(ST_Point(${lng},${lat}),4326)::geography,
${radius})::geometry
)
`);
};
</script>
</body>
</html>
+218
View File
@@ -0,0 +1,218 @@
<!DOCTYPE html>
<html>
<head>
<title>Guide | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Guide</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Full reference guide example.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Select a country</p>
</section>
<div id="controls">
<h2 class="h2">European countries</h2>
<select class="js-countries">
<option value="">All</option>
</select>
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
<div class="box widget">
<h2 class="h2">Average population</h2>
<p class="result open-sans">
<span class="js-average-population">xxx</span>
<small>inhabitants</small>
</p>
</div>
</aside>
<script>
// 1. Setting up a Google Maps Map
// 1.1 Creating the Google Maps Map
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 50, lng: 15 },
zoom: 4,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// 1.2 Hide countries borders
map.set('styles', [{
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
// 2 Defining a carto.Client
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
// 3. Displaying countries and cities on the map
// 3.1 Defining the layers
// European Countries layer
const europeanCountriesDataset = new carto.source.Dataset('ne_adm0_europe');
const europeanCountriesStyle = new carto.style.CartoCSS(`
#layer {
polygon-fill: #826DBA;
polygon-opacity: 0.5;
::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 0.5;
}
}
`);
const europeanCountries = new carto.layer.Layer(europeanCountriesDataset, europeanCountriesStyle);
// Europe cities layer
const populatedPlacesSource = new carto.source.SQL(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
`);
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-fill-opacity: 0.9;
marker-line-width: 0.5;
marker-line-color: #FFFFFF;
marker-line-opacity: 1;
marker-type: ellipse;
marker-allow-overlap: false;
}
`);
const populatedPlaces = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle, {
featureOverColumns: ['name']
});
// 3.2 Adding the layers to the client
client.addLayers([europeanCountries, populatedPlaces]);
// 3.3. Adding the layers to the map
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
// 4. Setting up tooltips
// 4.1 Showing the tooltip when user mouses over a city
const infowindow = new google.maps.InfoWindow();
populatedPlaces.on('featureOver', featureEvent => {
infowindow.setPosition(featureEvent.latLng);
if (!infowindow.map) {
infowindow.setContent(featureEvent.data.name);
infowindow.open(map);
}
});
// 4.2 Hiding the tooltip
populatedPlaces.on('featureOut', featureEvent => {
infowindow.close();
});
// 5 Creating a formula widget
// 5.1 Defining a formula dataview
const averagePopulation = new carto.dataview.Formula(populatedPlacesSource, 'pop_max', {
operation: carto.operation.AVG
});
// 5.2 Listening to data changes on the dataview
averagePopulation.on('dataChanged', data => {
refreshAveragePopulationWidget(data.result);
});
function refreshAveragePopulationWidget(avgPopulation) {
const widgetDom = document.querySelector('.box.widget');
const averagePopulationDom = widgetDom.querySelector('.js-average-population');
averagePopulationDom.innerText = Math.floor(avgPopulation);
}
// 5.3 Adding the dataview to the client
client.addDataview(averagePopulation);
// 6 Creating a country selector widget
// 6.1 Defining a category dataview
const countriesDataview = new carto.dataview.Category(europeanCountriesDataset, 'admin', {
limit: 100
});
// 6.2 Listening to data changes on the dataview
countriesDataview.on('dataChanged', data => {
const countryNames = data.categories.map(category => category.name).sort();
refreshCountriesWidget(countryNames);
});
function refreshCountriesWidget(adminNames) {
const asideElement = document.querySelector('aside.toolbox');
const countriesDom = asideElement.querySelector('.js-countries');
countriesDom.onchange = event => {
const admin = event.target.value;
highlightCountry(admin);
filterPopulatedPlacesByCountry(admin);
};
// Fill in the list of countries
adminNames.forEach(admin => {
const option = document.createElement('option');
option.innerHTML = admin;
option.value = admin;
countriesDom.appendChild(option);
});
}
function highlightCountry(admin) {
let cartoCSS = `
#layer {
polygon-fill: #826DBA;
polygon-opacity: 0.5;
::outline {
line-color: #FFFFFF;
line-width: 1;
line-opacity: 0.5;
}
}
`;
if (admin) {
cartoCSS = `
${cartoCSS}
#layer[admin!='${admin}'] {
polygon-fill: #e5e5e5;
}
`;
}
europeanCountriesStyle.setContent(cartoCSS);
}
function filterPopulatedPlacesByCountry(admin) {
const query = admin
? `SELECT * FROM ne_10m_populated_places_simple WHERE adm0name='${admin}'`
: 'SELECT * FROM ne_10m_populated_places_simple WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)';
populatedPlacesSource.setQuery(query);
}
// 6.3 Adding the dataview to the client
client.addDataview(countriesDataview);
</script>
</body>
</html>
+217
View File
@@ -0,0 +1,217 @@
<!DOCTYPE html>
<html>
<head>
<title>Guide | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Guide</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Full reference guide example.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Select a country</p>
</section>
<div id="controls">
<h2 class="h2">European countries</h2>
<select class="js-countries">
<option value="">All</option>
</select>
<div id="info"></div>
</div>
</section>
<footer class="js-footer"></footer>
</div>
<div class="box widget">
<h2 class="h2">Average population</h2>
<p class="result open-sans"><span class="js-average-population">xxx</span> <small>inhabitants</small></p>
</div>
</aside>
<script>
// 1. Setting up the Leaflet Map
// 1.1 Creating the Leaflet Map
const map = L.map('map').setView([50, 15], 4);
map.scrollWheelZoom.disable();
// 1.2 Adding basemap and labels layers
// Adding Voyager Basemap
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
// Adding Voyager Labels
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}.png', {
maxZoom: 18,
zIndex: 10
}).addTo(map);
// 2 Defining a carto.Client
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
// 3. Displaying countries and cities on the map
// 3.1 Defining the layers
// European Countries layer
const europeanCountriesDataset = new carto.source.Dataset('ne_adm0_europe');
const europeanCountriesStyle = new carto.style.CartoCSS(`
#layer {
polygon-fill: #826DBA;
polygon-opacity: 0.5;
::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 0.5;
}
}
`);
const europeanCountries = new carto.layer.Layer(europeanCountriesDataset, europeanCountriesStyle);
// Europe cities layer
const populatedPlacesSource = new carto.source.SQL(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
`);
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-fill-opacity: 0.9;
marker-line-width: 0.5;
marker-line-color: #FFFFFF;
marker-line-opacity: 1;
marker-type: ellipse;
marker-allow-overlap: false;
}
`);
const populatedPlaces = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle, {
featureOverColumns: ['name']
});
// 3.2 Adding the layers to the client
client.addLayers([europeanCountries, populatedPlaces]);
// 3.3. Adding the layers to the map
client.getLeafletLayer().addTo(map);
// 4. Setting up tooltips
// 4.1 Showing the tooltip when user mouses over a city
const popup = L.popup({ closeButton: false });
populatedPlaces.on('featureOver', featureEvent => {
popup.setLatLng(featureEvent.latLng);
if (!popup.isOpen()) {
popup.setContent(featureEvent.data.name);
popup.openOn(map);
}
});
// 4.2 Hiding the tooltip
populatedPlaces.on('featureOut', featureEvent => {
popup.removeFrom(map);
});
// 5 Creating a formula widget
// 5.1 Defining a formula dataview
const averagePopulation = new carto.dataview.Formula(populatedPlacesSource, 'pop_max', {
operation: carto.operation.AVG
});
// 5.2 Listening to data changes on the dataview
averagePopulation.on('dataChanged', data => {
refreshAveragePopulationWidget(data.result);
});
function refreshAveragePopulationWidget(avgPopulation) {
const widgetDom = document.querySelector('.box.widget');
const averagePopulationDom = widgetDom.querySelector('.js-average-population');
averagePopulationDom.innerText = Math.floor(avgPopulation);
}
// 5.3 Adding the dataview to the client
client.addDataview(averagePopulation);
// 6 Creating a country selector widget
// 6.1 Defining a category dataview
const countriesDataview = new carto.dataview.Category(europeanCountriesDataset, 'admin', {
limit: 100
});
// 6.2 Listening to data changes on the dataview
countriesDataview.on('dataChanged', data => {
const countryNames = data.categories.map(category => category.name).sort();
refreshCountriesWidget(countryNames);
});
function refreshCountriesWidget(adminNames) {
const asideElement = document.querySelector('aside.toolbox');
const countriesDom = asideElement.querySelector('.js-countries');
countriesDom.onchange = event => {
const admin = event.target.value;
highlightCountry(admin);
filterPopulatedPlacesByCountry(admin);
};
// Fill in the list of countries
adminNames.forEach(admin => {
const option = document.createElement('option');
option.innerHTML = admin;
option.value = admin;
countriesDom.appendChild(option);
});
}
function highlightCountry(admin) {
let cartoCSS = `
#layer {
polygon-fill: #826DBA;
polygon-opacity: 0.5;
::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 0.5;
}
}
`;
if (admin) {
cartoCSS = `
${cartoCSS}
#layer[admin!='${admin}'] {
polygon-fill: #e5e5e5;
}
`;
}
europeanCountriesStyle.setContent(cartoCSS);
}
function filterPopulatedPlacesByCountry(admin) {
const query = admin
? `SELECT * FROM ne_10m_populated_places_simple WHERE adm0name='${admin}'`
: 'SELECT * FROM ne_10m_populated_places_simple WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)';
populatedPlacesSource.setQuery(query);
}
// 6.3 Adding the dataview to the client
client.addDataview(countriesDataview);
</script>
</body>
</html>
@@ -0,0 +1,133 @@
<!DOCTYPE html>
<html>
<head>
<title>Hexagon aggregation | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Create an hexagonal grid</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Aggregate your points in hexagons.</p>
</section>
<footer class="js-footer"></footer>
</div>
<!-- Set legend of the map -->
<div class="box legend">
<h2 class="h2">Number of points aggregated in hexagons</h2>
<ul class="category open-sans">
<li><div class="circle" style="background: #04817E "></div><p>1-2</p></li>
<li><div class="circle" style="background: #39AB7E "></div><p>>2</p></li>
<li><div class="circle" style="background: #8BD16D"></div><p>>9</p></li>
<li><div class="circle" style="background: #EDEF5D"></div><p>>30</p></li>
</ul>
</div>
</aside>
<script>
// set map with initial zoom and coodinates view
// and disabling scroll wheel zoom
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 40, lng: -80 },
zoom: 7,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
// set CARTO client
const client = new carto.Client({
apiKey: 'default_public',
username: 'public'
});
// set SQL query to create the grid of hexagons
/*
To create the grid of hexagons we must use a SQL query that generates that grid for a specific
zoom level. We will use the zoom level 9 to create a grid of hexagons that will have a side size
of 12 pixel units.
We use the CARTO function CDB_HexagonGrid(geometry, side measure) to create the hexagon grid
where "geometry" is defined by the PostGIS function ST_Expand: "ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12)"
and "side measure" is defined by "CDB_XYZ_Resolution(9) * 12)", where the function
CDB_XYZ_Resolution(zoom level) returns the pixel resolution of tiles at a given zoom level.
The geometry defined in "ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12)" returns the geometry of
the bounding box that is defined by mapnik's !bbox! token and that is expanded in all directions a
distance of CDB_XYZ_Resolution(9) * 12 units
*/
const source = new carto.source.SQL(`
-- Create hexagon grid
WITH hgrid AS (
SELECT CDB_HexagonGrid(
ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12),
CDB_XYZ_Resolution(9) * 12) as cell
)
-- select the data from the "virtual table" hgrid, which has been created
-- using the "WITH" statement of PostgreSQL,
-- that intesects with the dataset of points "stormevents_locations_2014"
SELECT hgrid.cell as the_geom_webmercator,
count(1) as agg_value,
row_number() over () as cartodb_id
FROM hgrid, (SELECT * FROM stormevents_locations_2014) i
WHERE ST_Intersects(i.the_geom_webmercator, hgrid.cell)
GROUP BY hgrid.cell
`);
// define styles of layer. We will style the color of the geometry based on the value
// of the column "agg_value" of the SQL query.
const style = new carto.style.CartoCSS(`
#layer {
[agg_value > 0] {
polygon-fill: #04817E;
}
[agg_value > 2] {
polygon-fill: #39AB7E;
}
[agg_value > 9] {
polygon-fill: #8BD16D;
}
[agg_value > 30] {
polygon-fill: #EDEF5D;
}
}
#layer::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 1;
}
`);
// set the CARTO layer using the source and style defines previously
const layer = new carto.layer.Layer(source, style);
// add CARTO layer to the client
client.addLayer(layer);
// retrieve tiles from CARTO to the map
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
</script>
</body>
</html>
@@ -0,0 +1,127 @@
<!DOCTYPE html>
<html>
<head>
<title>Hexagon aggregation | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Create an hexagonal grid</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Aggregate your points in hexagons.</p>
</section>
<footer class="js-footer"></footer>
</div>
<!-- Set legend of the map -->
<div class="box legend">
<h2 class="h2">Number of points aggregated in hexagons</h2>
<ul class="category open-sans">
<li><div class="circle" style="background: #04817E "></div><p>1-2</p></li>
<li><div class="circle" style="background: #39AB7E "></div><p>>2</p></li>
<li><div class="circle" style="background: #8BD16D"></div><p>>9</p></li>
<li><div class="circle" style="background: #EDEF5D"></div><p>>30</p></li>
</ul>
</div>
</aside>
<script>
// set map with initial zoom and coodinates view
const map = L.map('map').setView([40, -80], 7);
// disable scroll wheel zoom
map.scrollWheelZoom.disable();
// add basemaps to map
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
// set CARTO client
const client = new carto.Client({
apiKey: 'default_public',
username: 'public'
});
// set SQL query to create the grid of hexagons
/*
To create the grid of hexagons we must use a SQL query that generates that grid for a specific
zoom level. We will use the zoom level 9 to create a grid of hexagons that will have a side size
of 12 pixel units.
We use the CARTO function CDB_HexagonGrid(geometry, side measure) to create the hexagon grid
where "geometry" is defined by the PostGIS function ST_Expand: "ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12)"
and "side measure" is defined by "CDB_XYZ_Resolution(9) * 12)", where the function
CDB_XYZ_Resolution(zoom level) returns the pixel resolution of tiles at a given zoom level.
The geometry defined in "ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12)" returns the geometry of
the bounding box that is defined by mapnik's !bbox! token and that is expanded in all directions a
distance of CDB_XYZ_Resolution(9) * 12 units
*/
const source = new carto.source.SQL(`
-- Create hexagon grid
WITH hgrid AS (
SELECT CDB_HexagonGrid(
ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12),
CDB_XYZ_Resolution(9) * 12) as cell
)
-- select the data from the "virtual table" hgrid, which has been created
-- using the "WITH" statement of PostgreSQL,
-- that intesects with the dataset of points "stormevents_locations_2014"
SELECT hgrid.cell as the_geom_webmercator,
count(1) as agg_value,
row_number() over () as cartodb_id
FROM hgrid, (SELECT * FROM stormevents_locations_2014) i
WHERE ST_Intersects(i.the_geom_webmercator, hgrid.cell)
GROUP BY hgrid.cell
`);
// define styles of layer. We will style the color of the geometry based on the value
// of the column "agg_value" of the SQL query.
const style = new carto.style.CartoCSS(`
#layer {
[agg_value > 0] {
polygon-fill: #04817E;
}
[agg_value > 2] {
polygon-fill: #39AB7E;
}
[agg_value > 9] {
polygon-fill: #8BD16D;
}
[agg_value > 30] {
polygon-fill: #EDEF5D;
}
}
#layer::outline {
line-width: 1;
line-color: #FFFFFF;
line-opacity: 1;
}
`);
// set the CARTO layer using the source and style defines previously
const layer = new carto.layer.Layer(source, style);
// add CARTO layer to the client
client.addLayer(layer);
// retrieve tiles from CARTO to the map
client.getLeafletLayer().addTo(map);
</script>
</body>
</html>
+193
View File
@@ -0,0 +1,193 @@
<!DOCTYPE html>
<html>
<head>
<title>Legends | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Legends</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create dynamic legends.</p>
<div class="separator"></div>
<div id="controls">
<ul>
<li onclick="setAllCities()">
<input type="radio" name="data" checked id="all">
<label for="all">ALL cities</label>
</li>
<li onclick="setEuropeanCities()">
<input type="radio" name="data" id="europe">
<label for="europe">European cities</label>
</li>
<li onclick="setSpanishCities()">
<input type="radio" name="data" id="spain">
<label for="spain">Spanish cities</label>
</li>
</ul>
<div class="separator"></div>
<ul>
<li onchange="invertColors()">
<input type="checkbox" name="data" id="invertColors">
<label for="invertColors">Invert colors</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
<div class="box legend">
<h2 class="h2">World cities</h2>
<ul class="category open-sans">
<li id="capital"></li>
<li id="normal"></li>
</ul>
<h2 class="h2">Inhabitants</h2>
<ul id="legend-population">
<li class="size open-sans">
<div id="min"></div>
<div id="max"></div>
</li>
<li class="avg open-sans"></li>
</ul>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const populatedPlacesSource = new carto.source.SQL('SELECT * FROM ne_10m_populated_places_simple');
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: ramp([pop_max], range(2, 12), quantiles(5));
marker-fill: ramp([adm0cap], (#EE4D5A, #68B69E), (0, 1), "=", category);
marker-fill-opacity: 0.6;
marker-allow-overlap: true;
marker-line-width: 1;
marker-line-color: #000;
marker-line-opacity: 0.2;
}
`);
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
client.addLayer(populatedPlacesLayer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
populatedPlacesLayer.on('metadataChanged', function (event) {
event.styles.forEach(function (styleMetadata) {
switch (styleMetadata.getProperty()) {
case 'marker-width':
renderLegendSize(styleMetadata);
break;
case 'marker-fill':
renderLegendCapital(styleMetadata);
break;
}
});
});
function renderLegendSize(metadata) {
document.getElementById('min').innerHTML = `
<div class="circle circle-outline" style="width:8px; height:8px;"></div> <p>${metadata.getMin()}</p>
`;
document.getElementById('max').innerHTML = `
<div class="circle circle-outline" style="width:24px; height:24px;"></div> <p>${metadata.getMax()}</p>
`;
document.querySelector('.legend .avg').innerHTML = `
<p><b>Average: </b> ${metadata.getAverage().toFixed(2)}</p>
`;
}
function renderLegendCapital(metadata) {
const categories = metadata.getCategories();
for (category of categories) {
switch (category.name) {
case 0:
document.getElementById('normal').innerHTML = `
<div class="circle" style="background:${category.value}"></div> Normal
`;
break;
case 1:
document.getElementById('capital').innerHTML = `
<div class="circle" style="background:${category.value}"></div> Capital
`;
break;
}
}
}
function setAllCities() {
populatedPlacesSource.setQuery('SELECT * FROM ne_10m_populated_places_simple');
}
function setEuropeanCities() {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
`);
}
function setSpanishCities() {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name = \'Spain\'
`);
}
function invertColors() {
const invert = document.getElementById('invertColors').checked;
const colors = invert ? '(#68B69E, #EE4D5A)' : '(#EE4D5A, #68B69E)';
const content = `
#layer {
marker-width: ramp([pop_max], range(2, 12), quantiles(5));
marker-fill: ramp([adm0cap], ${colors}, (0, 1), "=", category);
marker-fill-opacity: 0.6;
marker-allow-overlap: true;
marker-line-width: 1;
marker-line-color: #000;
marker-line-opacity: 0.2;
}
`;
populatedPlacesStyle.setContent(content);
}
</script>
</body>
</html>
+185
View File
@@ -0,0 +1,185 @@
<!DOCTYPE html>
<html>
<head>
<title>Legends | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Legends</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create dynamic legends.</p>
<div class="separator"></div>
<div id="controls">
<ul>
<li onclick="setAllCities()">
<input type="radio" name="data" checked id="all">
<label for="all">ALL cities</label>
</li>
<li onclick="setEuropeanCities()">
<input type="radio" name="data" id="europe">
<label for="europe">European cities</label>
</li>
<li onclick="setSpanishCities()">
<input type="radio" name="data" id="spain">
<label for="spain">Spanish cities</label>
</li>
</ul>
<div class="separator"></div>
<ul>
<li onchange="invertColors()">
<input type="checkbox" name="data" id="invertColors">
<label for="invertColors">Invert colors</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
<div class="box legend">
<h2 class="h2">World cities</h2>
<ul class="category open-sans">
<li id="capital"></li>
<li id="normal"></li>
</ul>
<h2 class="h2">Inhabitants</h2>
<ul id="legend-population">
<li class="size open-sans">
<div id="min"></div>
<div id="max"></div>
</li>
<li class="avg open-sans"></li>
</ul>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const populatedPlacesSource = new carto.source.SQL('SELECT * FROM ne_10m_populated_places_simple');
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: ramp([pop_max], range(2, 12), quantiles(5));
marker-fill: ramp([adm0cap], (#EE4D5A, #68B69E), (0, 1), "=", category);
marker-fill-opacity: 0.6;
marker-allow-overlap: true;
marker-line-width: 1;
marker-line-color: #000;
marker-line-opacity: 0.2;
}
`);
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
client.addLayer(populatedPlacesLayer);
client.getLeafletLayer().addTo(map);
populatedPlacesLayer.on('metadataChanged', function(event) {
event.styles.forEach(function (styleMetadata) {
switch(styleMetadata.getProperty()) {
case 'marker-width':
renderLegendSize(styleMetadata);
break;
case 'marker-fill':
renderLegendCapital(styleMetadata);
break;
}
});
});
function renderLegendSize(metadata) {
document.getElementById('min').innerHTML = `
<div class="circle circle-outline" style="width:8px; height:8px;"></div> <p>${metadata.getMin()}</p>
`;
document.getElementById('max').innerHTML = `
<div class="circle circle-outline" style="width:24px; height:24px;"></div> <p>${metadata.getMax()}</p>
`;
document.querySelector('.legend .avg').innerHTML = `
<p><b>Average: </b> ${metadata.getAverage().toFixed(2)}</p>
`;
}
function renderLegendCapital(metadata) {
const categories = metadata.getCategories();
for (category of categories) {
switch (category.name) {
case 0:
document.getElementById('normal').innerHTML = `
<div class="circle" style="background:${category.value}"></div> Normal
`;
break;
case 1:
document.getElementById('capital').innerHTML = `
<div class="circle" style="background:${category.value}"></div> Capital
`;
break;
}
}
}
function setAllCities() {
populatedPlacesSource.setQuery('SELECT * FROM ne_10m_populated_places_simple');
}
function setEuropeanCities() {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
`);
}
function setSpanishCities() {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
WHERE adm0name = \'Spain\'
`);
}
function invertColors() {
const invert = document.getElementById('invertColors').checked;
const colors = invert ? '(#68B69E, #EE4D5A)' : '(#EE4D5A, #68B69E)';
const content = `
#layer {
marker-width: ramp([pop_max], range(2, 12), quantiles(5));
marker-fill: ramp([adm0cap], ${colors}, (0, 1), "=", category);
marker-fill-opacity: 0.6;
marker-allow-overlap: true;
marker-line-width: 1;
marker-line-color: #000;
marker-line-opacity: 0.2;
}
`;
populatedPlacesStyle.setContent(content);
}
</script>
</body>
</html>
+219
View File
@@ -0,0 +1,219 @@
<!DOCTYPE html>
<html>
<head>
<title>CARTO.js + Category Dataviews + Vega Pie Chart</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="https://libs.cartocdn.com/carto.js/v4.1.11/carto.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Montserrat:600" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<!-- Custom Style -->
<link href="https://carto.com/developers/carto-js/examples/maps/public/style.css" rel="stylesheet">
<!-- Vega -->
<script src="https://cdn.jsdelivr.net/npm/vega@3"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite@2"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed@3"></script>
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Pie Chart Example</h1>
</header>
<section>
<p class="description open-sans">Done with Vega Lite</p>
<br>
<div id="piechart"></div>
<div style="margin-top: 12px;" id="legend"></div>
</section>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.SQL('SELECT * FROM ne_10m_populated_places_simple');
const style = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: ramp([adm0name], cartocolor(Vivid), category(10));
marker-line-color: #FFFFFF;
}
`);
const layer = new carto.layer.Layer(source, style);
client.addLayer(layer);
client.getLeafletLayer().addTo(map);
const categoryDataview = new carto.dataview.Category(source, 'adm0name', {
limit: 12,
operation: carto.operation.COUNT
});
categoryDataview.on('dataChanged', data => {
const categories = data.categories;
drawPieChart(categories, '#piechart');
});
categoryDataview.on('error', error => {
alert(error.message);
});
client.addDataview(categoryDataview);
const bboxFilter = new carto.filter.BoundingBoxLeaflet(map);
categoryDataview.addFilter(bboxFilter);
const legend = document.getElementById("legend");
function renderCategoryLegend(metadata){
metadata.styles.forEach(function (styleMetadata) {
if (styleMetadata.getProperty() == 'marker-fill') {
let metaCategories = styleMetadata.getCategories();
for (category of metaCategories){
const li = document.createElement('li');
li.style.color = `${category.value}`
li.innerHTML = `<span style="color: black;">${category.name}</span>`;
legend.append(li);
}
}
});
}
layer.on('metadataChanged', renderCategoryLegend);
function drawPieChart(cats, id) {
const vegaSpecPie = {
"$schema": "https://vega.github.io/schema/vega/v3.3.1.json",
"width": 200,
"height": 200,
"autosize": "none",
"signals": [{
"name": "startAngle",
"value": 0
},
{
"name": "endAngle",
"value": 6.29
},
{
"name": "padAngle",
"value": 0.05
},
{
"name": "innerRadius",
"value": 40
},
{
"name": "sort",
"value": false
},
],
"data": [{
"name": "categories",
"values": cats,
"transform": [{
"type": "pie",
"field": "value",
"startAngle": {
"signal": "startAngle"
},
"endAngle": {
"signal": "endAngle"
},
"sort": {
"signal": "sort"
}
}]
}],
"scales": [{
"name": "vivid",
"type": "ordinal",
"domain": {
"data": "categories",
"field": "name"
},
"range": ['#E58606','#5D69B1','#52BCA3','#99C945','#CC61B0','#24796C','#DAA51B','#2F8AC4','#764E9F','#ED645A','#CC3A8E','#A5AA99']
}],
"marks": [{
"type": "arc",
"from": {
"data": "categories"
},
"encode": {
"enter": {
"fill": {
"scale": "vivid",
"field": "name"
},
"x": {
"signal": "width / 2"
},
"y": {
"signal": "height / 2"
}
},
"update": {
"startAngle": {
"field": "startAngle"
},
"endAngle": {
"field": "endAngle"
},
"padAngle": {
"signal": "padAngle"
},
"innerRadius": {
"signal": "innerRadius"
},
"outerRadius": {
"signal": "width / 2"
},
"fillOpacity": {
"value": 1
}
},
"hover": {
"fillOpacity": {
"value": 0.8
}
}
}
}]
};
vegaEmbed(id, vegaSpecPie, {
actions: false
});
}
</script>
</body>
</html>
@@ -0,0 +1,140 @@
<!DOCTYPE html>
<html>
<head>
<title>Populated places | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Most/less populated places</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Filter the 20 most/less populated places in the world.</p>
<div class="separator"></div>
<div id="controls">
<ul class="actions">
<li onclick="setAll()">
<input type="radio" name="style" value="01" id="all" checked="">
<label for="all">ALL Places
<label>
</li>
<li onclick="setMostPopulated(20)">
<input type="radio" name="style" value="02" id="most">
<label for="most">Most populated places</label>
</li>
<li onclick="setLessPopulated(20)">
<input type="radio" name="style" value="03" id="less">
<label for="less">Less populated places</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const populatedPlacesSource = new carto.source.SQL(`
SELECT *
FROM ne_10m_populated_places_simple
`);
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-fill: #EE4D5A;
marker-width: 7;
marker-line-color: #FFFFFF;
}
`);
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
client.addLayer(populatedPlacesLayer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
function setAll() {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
`);
populatedPlacesStyle.setContent(`
#layer {
marker-fill: #EE4D5A;
marker-width: 7;
marker-line-color: #FFFFFF;
}
`);
}
function setMostPopulated(limit) {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
ORDER BY pop_max DESC LIMIT ${limit}
`);
populatedPlacesStyle.setContent(`
#layer {
marker-fill: #68B69E;
marker-width: 12;
marker-line-color: #FFFFFF;
text-name: [name];
text-face-name: 'Open Sans Regular';
text-size: 12;
text-dy: -10;
}
`);
}
function setLessPopulated(limit) {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
ORDER BY pop_max ASC LIMIT ${limit}
`);
populatedPlacesStyle.setContent(`
#layer {
marker-fill: #F15743;
marker-width: 12;
marker-line-color: #FFFFFF;
text-name: [name];
text-face-name: 'Open Sans Regular';
text-size: 12;
text-dy: -10;
}
`);
}
</script>
</body>
</html>
@@ -0,0 +1,132 @@
<!DOCTYPE html>
<html>
<head>
<title>Populated places | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Most/less populated places</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Filter the 20 most/less populated places in the world.</p>
<div class="separator"></div>
<div id="controls">
<ul class="actions">
<li onclick="setAll()">
<input type="radio" name="style" value="01" id="all" checked="">
<label for="all">ALL Places<label>
</li>
<li onclick="setMostPopulated(20)">
<input type="radio" name="style" value="02" id="most">
<label for="most">Most populated places</label>
</li>
<li onclick="setLessPopulated(20)">
<input type="radio" name="style" value="03" id="less">
<label for="less">Less populated places</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const populatedPlacesSource = new carto.source.SQL(`
SELECT *
FROM ne_10m_populated_places_simple
`);
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-fill: #EE4D5A;
marker-width: 7;
marker-line-color: #FFFFFF;
}
`);
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
client.addLayer(populatedPlacesLayer);
client.getLeafletLayer().addTo(map);
function setAll() {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
`);
populatedPlacesStyle.setContent(`
#layer {
marker-fill: #EE4D5A;
marker-width: 7;
marker-line-color: #FFFFFF;
}
`);
}
function setMostPopulated(limit) {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
ORDER BY pop_max DESC LIMIT ${limit}
`);
populatedPlacesStyle.setContent(`
#layer {
marker-fill: #68B69E;
marker-width: 12;
marker-line-color: #FFFFFF;
text-name: [name];
text-face-name: 'Open Sans Regular';
text-size: 12;
text-dy: -10;
}
`);
}
function setLessPopulated(limit) {
populatedPlacesSource.setQuery(`
SELECT *
FROM ne_10m_populated_places_simple
ORDER BY pop_max ASC LIMIT ${limit}
`);
populatedPlacesStyle.setContent(`
#layer {
marker-fill: #F15743;
marker-width: 12;
marker-line-color: #FFFFFF;
text-name: [name];
text-face-name: 'Open Sans Regular';
text-size: 12;
text-dy: -10;
}
`);
}
</script>
</body>
</html>
+134
View File
@@ -0,0 +1,134 @@
<!DOCTYPE html>
<html>
<head>
<title>Pop-ups | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Pop-Ups</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create pop-up information windows and interact with your map.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Select your preferred kind of pop-ups</p>
</section>
<div id="controls">
<ul class="actions">
<li onclick="setPopupsClick()">
<input type="radio" name="style" value="01" id="popup">
<label for="popup">Pop-ups on click</label>
</li>
<li onclick="setPopupsHover()">
<input type="radio" name="style" value="01" id="hover">
<label for="hover">Pop-ups on hover</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 30, lng: 0 },
zoom: 3,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const populatedPlacesSource = new carto.source.Dataset('ne_10m_populated_places_simple');
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle, {
featureOverColumns: ['name', 'pop_max', 'pop_min']
});
client.addLayer(populatedPlacesLayer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
const infowindow = new google.maps.InfoWindow();
function openPopup(featureEvent) {
let content = '<div class="widget">';
if (featureEvent.data.name) {
content += `<h2 class="h2">${featureEvent.data.name}</h2>`;
}
if (featureEvent.data.pop_max || featureEvent.data.pop_min) {
content += `<ul>`;
if (featureEvent.data.pop_max) {
content += `<li><h3>Max:</h3><p class="open-sans">${featureEvent.data.pop_max}</p></li>`;
}
if (featureEvent.data.pop_min) {
content += `<li><h3>Min:</h3><p class="open-sans">${featureEvent.data.pop_min}</p></li>`;
}
content += `</ul>`;
}
content += `</div>`;
infowindow.setContent(content);
infowindow.setPosition(featureEvent.latLng);
if (!infowindow.map) {
infowindow.open(map);
}
}
function closePopup(featureEvent) {
infowindow.close();
}
function setPopupsClick() {
populatedPlacesLayer.off('featureOver');
populatedPlacesLayer.off('featureOut');
populatedPlacesLayer.on('featureClicked', openPopup);
}
function setPopupsHover() {
populatedPlacesLayer.off('featureClicked');
populatedPlacesLayer.on('featureOver', openPopup);
populatedPlacesLayer.on('featureOut', closePopup);
}
</script>
</body>
</html>
+129
View File
@@ -0,0 +1,129 @@
<!DOCTYPE html>
<html>
<head>
<title>Pop-ups | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Pop-Ups</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create pop-up information windows and interact with your map.</p>
<div class="separator"></div>
<section class="usage">
<header>USAGE</header>
<p class="open-sans">Select your preferred kind of pop-ups</p>
</section>
<div id="controls">
<ul class="actions">
<li onclick="setPopupsClick()">
<input type="radio" name="style" value="01" id="popup">
<label for="popup">Pop-ups on click</label>
</li>
<li onclick="setPopupsHover()">
<input type="radio" name="style" value="01" id="hover">
<label for="hover">Pop-ups on hover</label>
</li>
</ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([30, 0], 3);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const populatedPlacesSource = new carto.source.Dataset(`
ne_10m_populated_places_simple
`);
const populatedPlacesStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle, {
featureOverColumns: ['name', 'pop_max', 'pop_min']
});
client.addLayer(populatedPlacesLayer);
client.getLeafletLayer().addTo(map);
const popup = L.popup({ closeButton: false });
function openPopup(featureEvent) {
let content = '<div class="widget">';
if (featureEvent.data.name) {
content += `<h2 class="h2">${featureEvent.data.name}</h2>`;
}
if (featureEvent.data.pop_max || featureEvent.data.pop_min) {
content += `<ul>`;
if (featureEvent.data.pop_max) {
content += `<li><h3>Max:</h3><p class="open-sans">${featureEvent.data.pop_max}</p></li>`;
}
if (featureEvent.data.pop_min) {
content += `<li><h3>Min:</h3><p class="open-sans">${featureEvent.data.pop_min}</p></li>`;
}
content += `</ul>`;
}
content += `</div>`;
popup.setContent(content);
popup.setLatLng(featureEvent.latLng);
if (!popup.isOpen()) {
popup.openOn(map);
}
}
function closePopup(featureEvent) {
popup.removeFrom(map);
}
function setPopupsClick() {
populatedPlacesLayer.off('featureOver');
populatedPlacesLayer.off('featureOut');
populatedPlacesLayer.on('featureClicked', openPopup);
}
function setPopupsHover() {
populatedPlacesLayer.off('featureClicked');
populatedPlacesLayer.on('featureOver', openPopup);
populatedPlacesLayer.on('featureOut', closePopup);
}
</script>
</body>
</html>
@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html>
<head>
<title>Pop-ups with embed video | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<!-- Include Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Pop-Ups with embed video</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create pop-up information windows with embed videos.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 0, lng: 0 },
zoom: 5,
fullscreenControl: false,
gestureHandling: 'cooperative'
});
// Hide the map labels and geometry strokes
map.set('styles', [{
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}, {
elementType: 'geometry.stroke',
stylers: [{ visibility: 'off' }]
}]);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const cartoSource = new carto.source.Dataset(`
example_video
`);
const cartoStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 20;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const cartoLayer = new carto.layer.Layer(cartoSource, cartoStyle, {
featureClickColumns: ['youtube_url']
});
client.addLayer(cartoLayer);
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
const infowindow = new google.maps.InfoWindow();
function openPopup(featureEvent) {
let content = '<div class="widget">';
if (featureEvent.data.youtube_url) {
content += `<iframe width="240" src= ${featureEvent.data.youtube_url} frameborder="0" allowfullscreen></iframe>`
}
content += `</div>`;
infowindow.setContent(content);
infowindow.setPosition(featureEvent.latLng);
if (!infowindow.map) {
infowindow.open(map);
}
}
function closePopup(featureEvent) {
infowindow.close();
}
cartoLayer.on('featureClicked', openPopup);
</script>
</body>
</html>
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<title>Pop-ups with embed video | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<link href="../style.css" rel="stylesheet">
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Pop-Ups with embed video</h1>
<button class="github-logo js-source-link"></button>
</header>
<section>
<p class="description open-sans">Create pop-up information windows with embed videos.</p>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const map = L.map('map').setView([0, 0], 5);
map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const cartoSource = new carto.source.Dataset(`
example_video
`);
const cartoStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 20;
marker-fill: #EE4D5A;
marker-line-color: #FFFFFF;
}
`);
const cartoLayer = new carto.layer.Layer(cartoSource, cartoStyle, {
featureClickColumns: ['youtube_url']
});
client.addLayer(cartoLayer);
client.getLeafletLayer().addTo(map);
const popup = L.popup({ closeButton: false });
function openPopup(featureEvent) {
let content = '<div class="widget">';
if (featureEvent.data.youtube_url) {
content += `<iframe width="240" src= ${featureEvent.data.youtube_url} frameborder="0" allowfullscreen></iframe>`
}
content += `</div>`;
popup.setContent(content);
popup.setLatLng(featureEvent.latLng);
if (!popup.isOpen()) {
popup.openOn(map);
}
}
function closePopUp(featureEvent) {
// remove popup from map object
popup.removeFrom(map)
}
cartoLayer.on('featureClicked', openPopup);
</script>
</body>
</html>
+194
View File
@@ -0,0 +1,194 @@
<!DOCTYPE html>
<html>
<head>
<title>Storytelling map using Storymap.js | CARTO</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="../../../dist/public/carto.js"></script>
<!--jquery-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!--boostrap-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!--leaflet.ajax for asynchronously adding geojson data-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>
<!--story map plugin-->
<script src="https://cdn.rawgit.com/jakobzhao/storymap/master/dist/storymap.2.3.js"></script>
<link href="../style.css" rel="stylesheet">
<!--add required stylesheets-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<!--animation-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!--Google Font-->
<link href="https://fonts.googleapis.com/css?family=Cairo" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/jakobzhao/storymap/master/dist/storymap.2.3.css">
</head>
<body>
<div id="map"></div>
<div id="storymap" class="container-fluid">
<div class="row">
<div class="col-sm-6 col-md-8 storymap-map"></div>
<div class="col-sm-6 col-md-4 storymap-story">
<section data-scene="scene1">
<h1>Spain, France and Portugal</h1>
</section>
<section data-scene="scene2">
<h1>Spain</h1>
<p>
<a href="https://en.wikipedia.org/wiki/Spain">Source Wikipedia</a>
</p>
<p>
Spain (Spanish: España [esˈpaɲa] (About this sound listen)), officially the Kingdom of Spain (Spanish: Reino de España),[a][b]
is a sovereign state located on the Iberian Peninsula in southwestern Europe, with two large archipelagoes,
the Balearic Islands in the Mediterranean Sea and the Canary Islands off the North African Atlantic
coast, two cities, Ceuta and Melilla, in the North African mainland and several small islands in
the Alboran Sea near the Moroccan coast. The country's mainland is bordered to the south and east
by the Mediterranean Sea except for a small land boundary with Gibraltar; to the north and northeast
by France, Andorra, and the Bay of Biscay; and to the west and northwest by Portugal and the Atlantic
Ocean. It is the only European country to have a border with an African country (Morocco)[h] and
its African territory accounts for nearly 5% of its population, mostly in the Canary Islands but
also in Ceuta and Melilla.
</p>
</section>
<section data-scene="scene3">
<h1>France</h1>
<p>
<a href="https://en.wikipedia.org/wiki/France">Source Wikipedia</a>
</p>
<p>
France (French IPA: [fʁɑ̃s]), officially the French Republic (French: République française [ʁepyblik fʁɑ̃sɛz]), is a country
whose territory consists of metropolitan France in western Europe, as well as several overseas regions
and territories.[XIII] The metropolitan area of France extends from the Mediterranean Sea to the
English Channel and the North Sea, and from the Rhine to the Atlantic Ocean. The overseas territories
include French Guiana in South America and several islands in the Atlantic, Pacific and Indian oceans.
The country's 18 integral regions (5 of which are situated overseas) span a combined area of 643,801
square kilometres (248,573 sq mi) which, as of October 2017, has a population of 67.15 million people.[10]
France is a unitary semi-presidential republic with its capital in Paris, the country's largest city
and main cultural and commercial centre. Other major urban centres include Marseille, Lyon, Lille,
Nice, Toulouse and Bordeaux.
</p>
</section>
<section data-scene="scene4">
<h1>Portugal</h1>
<p>
<a href="https://en.wikipedia.org/wiki/Portugal">Source Wikipedia</a>
</p>
<p>
Portugal (Portuguese: [puɾtuˈɣaɫ]), officially the Portuguese Republic (Portuguese: República Portuguesa [ʁɛ'puβlikɐ puɾtu'ɣezɐ]),[note
1] is a sovereign state located on the Iberian Peninsula in southwestern Europe. It is the westernmost
country of mainland Europe, being bordered to the west and south by the Atlantic Ocean and to the
north and east by Spain. Its territory also includes the Atlantic archipelagos of the Azores and
Madeira, both autonomous regions with their own regional governments. At 1.7 million km2, its Exclusive
Economic Zone is the 3rd largest in the European Union and the 11th largest in the world.
</p>
</section>
</div>
</div>
</div>
<!-- Description -->
<aside class="toolbox">
<div class="box">
<header>
<h1>Storytelling map</h1>
<button class="github-logo js-source-link"></button>
</header>
<div>
<p class="description open-sans">Storytelling map using Storymap.js and CARTO.js.</p>
</div>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
// set map with initial zoom and coodinates view
const map = L.map('map').setView([40, 2], 4);
// define scenes
let scenes = {
scene1: { lat: 30, lng: 0, zoom: 3, layers: ['basemap'], name: "1" },
scene2: { lat: 40.40002626, lng: -3.68335169, zoom: 5, layers: ['basemap','cartoLayer'], name: "2" },
scene3: { lat: 47.08372683, lng: 2.39999792, zoom: 5, layers: ['basemap','cartoLayer'], name: "3" },
scene4: { lat: 38.52995953, lng: -8.90001001, zoom: 7, layers: ['basemap','cartoLayer'], name: "4" }
};
// disable scroll wheel zoom
map.scrollWheelZoom.disable();
// add basemaps to map
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
// set CARTO client
const client = new carto.Client({
apiKey: 'default_public',
username: 'cartojs-test'
});
const source = new carto.source.SQL(`
SELECT * FROM ne_10m_populated_places_simple
WHERE adm0name IN ('Spain', 'Portugal', 'France')
`);
// define CartoCSS code to style data on map
const style = new carto.style.CartoCSS(`
#layer[adm0name = "Spain"]{
marker-fill: #fbb4ae;
marker-allow-overlap: true;
}
#layer[adm0name = "Portugal"]{
marker-fill: #ccebc5;
marker-allow-overlap: true;
}
#layer[adm0name = "France"]{
marker-fill: #b3cde3;
marker-allow-overlap: true;
}
`);
// create CARTO layer from source and style variables
const Cartolayer = new carto.layer.Layer(source, style);
// add CARTO layer to the client
client.addLayer(Cartolayer);
// define layers that will be used on the map
var layers = {
cartoLayer: {
layer: client.getLeafletLayer()
},
basemap: {
layer: L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png')
}
};
// initializaze storymap
$('#storymap').storymap({
scenes: scenes,
layers: layers,
baselayer: layers.basemap,
legend: true,
loader: true,
flyto: false,
scalebar: true,
scrolldown: true,
progressline: true,
navwidget: true,
createMap: function () {
let map = L.map($(".storymap-map")[0], { zoomControl: false }).setView([30, 0], 3);
// add basemap
this.baselayer.layer.addTo(map);
// add carto layer
layers.cartoLayer.layer.addTo(map)
return map;
}
});
</script>
</body>
</html>
+487
View File
@@ -0,0 +1,487 @@
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
height: 100%;
width: 100%;
z-index: 0;
}
aside.toolbox {
position: absolute;
top: 24px;
right: 24px;
min-width: 300px;
max-width: 300px;
z-index: 2;
}
/* UTILITIES */
.mt-16 {
margin-top: 16px !important;
}
.p-8 {
padding: 8px !important;
}
.bg-white {
background: #FFFFFF;
}
.bg-red {
background: #EE4D5A;
}
.bg-orange {
background: #EF9E4E;
}
.bg-gray {
background: #F9F9F9;
}
.text-white {
color: #FFFFFF !important;
}
.text-red {
color: #F15743;
}
.h2 {
color: #2E3C43;
line-height: 32px;
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
font-size: 20px;
font-weight: 600;
}
.open-sans {
color: #747D82;
font-size: 12px;
line-height: 16px;
font-family: 'Open Sans', Arial, Helvetica, sans-serif;
font-weight: 400;
}
.button {
border: 1px solid #1785FB;
color: #1785FB;
border-radius: 4px;
cursor: pointer;
text-transform: uppercase;
font-weight: 600;
outline: none;
background: transparent;
}
.button-error {
border: 1px solid #F15743;
color: #F15743;
border-radius: 4px;
cursor: pointer;
text-transform: uppercase;
font-weight: 600;
outline: none;
background: transparent;
}
/* STYLES */
.github-logo {
position: absolute;
top: 20px;
right: 16px;
width: 24px;
height: 24px;
border: 0;
padding: 0;
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5TaGFwZTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZGVmcz48L2RlZnM+ICAgIDxnIGlkPSJEb2NzIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4gICAgICAgIDxnIGlkPSJEb2N1bWVudGF0aW9uLS0tQVBJLS0tRXhhbXBsZXMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMzc2LjAwMDAwMCwgLTExNi4wMDAwMDApIiBmaWxsPSIjQkFCRUMwIiBmaWxsLXJ1bGU9Im5vbnplcm8iPiAgICAgICAgICAgIDxnIGlkPSJGbG9hdC0yIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMTE1LjAwMDAwMCwgOTYuMDAwMDAwKSI+ICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yNzIuOTk4OTU3LDIwIEMyNjYuMzcyODcsMjAgMjYxLDI1LjUwNzIyMjIgMjYxLDMyLjMwMjQ1ODMgQzI2MSwzNy43MzkwNzUxIDI2NC40MzcyMTcsNDIuMzQ5ODIyNSAyNjkuMjA2OTU3LDQzLjk3ODAyNjIgQzI2OS44MDU5MTMsNDQuMDg5MjgzMiAyNjkuOTk1ODI2LDQzLjcyNTU1ODMgMjY5Ljk5NTgyNiw0My4zOTkyNzU3IEMyNjkuOTk1ODI2LDQzLjEwNjE1NjMgMjcwLjAwMjA4Nyw0Mi4yODk5MTQ5IDI2OS45OTU4MjYsNDEuMjYyOTI3MSBDMjY2LjY1ODc4Myw0Mi4wMDUzNTM3IDI2NS45NjY5NTcsMzkuNjQyMjExOSAyNjUuOTY2OTU3LDM5LjY0MjIxMTkgQzI2NS40MjIyNjEsMzguMjIwNDc1NyAyNjQuNjM2NTIyLDM3Ljg0Mjg0MzcgMjY0LjYzNjUyMiwzNy44NDI4NDM3IEMyNjMuNTQ2MDg3LDM3LjA3OTAyMTUgMjY0LjcxNzkxMywzNy4wOTUwNjgyIDI2NC43MTc5MTMsMzcuMDk1MDY4MiBDMjY1LjkyMTA0MywzNy4xODA2NTA1IDI2Ni41NTY1MjIsMzguMzYxNjg2NSAyNjYuNTU2NTIyLDM4LjM2MTY4NjUgQzI2Ny42MjcxMyw0MC4yNDIzNTc5IDI2OS4zNjQ1MjIsMzkuNjk4OTEwMiAyNzAuMDQ4LDM5LjM4NDM5NTIgQzI3MC4xNTc1NjUsMzguNTkwNjE5MiAyNzAuNDY3NDc4LDM4LjA0NjEwMTcgMjcwLjgxMDc4MywzNy43NDEyMTQ3IEMyNjguMTQ1NzM5LDM3LjQyODgzOTIgMjY1LjM0NTA0MywzNi4zNzUxMDY5IDI2NS4zNDUwNDMsMzEuNjU4NDUxNCBDMjY1LjM0NTA0MywzMC4zMTU4Nzg3IDI2NS44MTI1MjIsMjkuMjE4Mjg1NSAyNjYuNTgwNTIyLDI4LjM1NzExMzQgQzI2Ni40NTYzNDgsMjguMDQ3OTQ3MyAyNjYuMDQzMTMsMjYuNzk2MzA1OSAyNjYuNjk2MzQ4LDI1LjEwMjg0NTggQzI2Ni42OTYzNDgsMjUuMTAyODQ1OCAyNjcuNzA1MzkxLDI0Ljc3MTIxNDMgMjY5Ljk5NTgyNiwyNi4zNjUxODUgQzI3MC45NTM3MzksMjYuMDkxMzIxNSAyNzEuOTgwNTIyLDI1Ljk1NTQ1OTYgMjczLjAwMTA0MywyNS45NTAxMTA3IEMyNzQuMDIwNTIyLDI1Ljk1NTQ1OTYgMjc1LjA0NjI2MSwyNi4wOTEzMjE1IDI3Ni4wMDYyNjEsMjYuMzY1MTg1IEMyNzguMjk2Njk2LDI0Ljc3MzM1MzggMjc5LjMwMjYwOSwyNS4xMDI4NDU4IDI3OS4zMDI2MDksMjUuMTAyODQ1OCBDMjc5Ljk1Njg3LDI2Ljc5NjMwNTkgMjc5LjU0NDY5NiwyOC4wNDkwMTcxIDI3OS40MjE1NjUsMjguMzU4MTgzMiBDMjgwLjE4OTU2NSwyOS4yMTkzNTUzIDI4MC42NTYsMzAuMzE2OTQ4NSAyODAuNjU2LDMxLjY1OTUyMTIgQzI4MC42NTYsMzYuMzg3OTQ0MyAyNzcuODUxMTMsMzcuNDI2Njk5NyAyNzUuMTc2Njk2LDM3LjcyOTQ0NzEgQzI3NS42MDY2MDksMzguMTExMzU4MiAyNzUuOTk3OTEzLDM4Ljg0OTUwNTcgMjc1Ljk5NzkxMywzOS45OTczNzg2IEMyNzUuOTk3OTEzLDQxLjUzNTcyMDcgMjc1Ljk5NzkxMyw0Mi45OTkxNzg0IDI3NS45OTc5MTMsNDMuNDAzNTU0OCBDMjc1Ljk5NzkxMyw0My43MzMwNDY4IDI3Ni4xOTIsNDQuMDk1NzAxOSAyNzYuODAxMzkxLDQzLjk3Njk1NjQgQzI4MS41NjU5MTMsNDIuMzQ2NjEzMiAyODUsMzcuNzM2OTM1NiAyODUsMzIuMzAyNDU4MyBDMjg1LDI1LjUwNzIyMjIgMjc5LjYyODE3NCwyMCAyNzIuOTk4OTU3LDIwIFoiIGlkPSJTaGFwZSI+PC9wYXRoPiAgICAgICAgICAgIDwvZz4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==);
background-color: transparent;
cursor: pointer;
}
.box {
background: #FFFFFF;
z-index: 2;
border-radius: 4px;
padding: 16px;
margin: 0 0 24px;
box-shadow: 0 0px 16px rgba(0, 0, 0, 0.24);
}
.box header h1 {
display: inline-block;
color: #2E3C43;
line-height: 32px;
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
font-size: 20px;
font-weight: 600;
margin: 0;
width: calc(100% - 24px);
}
.box section .separator {
min-height: 1px;
background-color: rgba(46, 60, 67, 0.08);
margin: 16px 0;
}
.box section .usage {
position: relative;
background-color: #F9F9F9;
padding: 16px;
border-left: #979797 solid 1px;
}
.box section .usage:after {
content: '';
position: absolute;
top: 0;
right: 0;
border-width: 0 20px 20px 0;
border-style: solid;
border-color: #979797 #fff;
}
.box section .usage header {
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
font-size: 12px;
font-weight: 600;
margin: 0 0 12px;
}
.box section .usage p{
margin: 0 0 16px;
}
.box section .usage p:last-child{
margin: 0;
}
.box section .description {
margin-bottom: 0;
}
/* BOX CONTROLS */
#controls ul {
padding: 0;
margin-bottom: 0;
}
#controls li {
list-style-type: none;
margin: 0 0 8px 0;
display: flex;
vertical-align: middle;
}
#controls li input {
margin: 0 8px 0 0;
}
#controls li input[type=checkbox] {
margin: 2px 8px 0 0;
}
#controls li label {
font: 12px/16px 'Open Sans';
cursor: pointer;
}
#controls li:last-child {
margin-bottom: 0;
}
#controls li:hover {
cursor: pointer;
}
#controls h2 {
margin: 16px 0 8px;
}
#controls #info h3 {
color: #2E3C43;
line-height: 32px;
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
font-size: 20px;
font-weight: 600;
margin: 16px 0 8px;
}
#controls #info p {
margin: 0;
}
/* WIDGETS */
.widget h2, .legend h2 {
margin: 0 0 8px;
}
.widget h3, .legend h3 {
color: #2E3C43;
line-height: 24px;
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
font-size: 16px;
font-weight: 600;
margin: 0 0 8px;
}
.widget p {
margin: 0 0 16px;
}
.widget ul {
padding: 0;
}
.widget li {
list-style-type: none;
}
.widget .category {
color: #2E3C43;
line-height: 16px;
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
font-size: 16px;
font-weight: 600;
margin: 0;
}
.widget textarea {
width: 100%;
resize: none;
padding: 7px 8px 6px;
border: 1px solid #DDD;
border-radius: 4px;
margin-bottom: 8px;
}
.widget button {
padding: 4px 12px;
}
.widget button:hover {
background: rgba(23,133,251,.08);
}
/* LEGENDS */
.legend ul {
list-style-type: none;
margin-bottom: 24px;
padding: 0;
}
.legend ul:last-child {
margin: 0;
padding: 0;
border: 0;
}
.legend .circle {
width: 8px;
height: 8px;
border-radius: 50%;
margin-right: 8px;
}
.legend .circle-outline {
background: #F9F9F9;
border: 1px solid rgba(0,0,0,0.10);
}
.legend .category {
font: 600;
}
.legend .category li {
margin-bottom: 6px;
display: flex;
align-items: center;
text-transform: uppercase;
}
.legend .category li:last-child {
margin-bottom: 0;
}
.legend .size {
display: flex;
align-items: center;
}
.legend .size > div {
margin-right: 32px;
display: flex;
align-items: center;
}
.legend .size > div:last-child {
margin-right: 0;
}
.legend .size p {
margin: 0;
text-transform: uppercase;
}
.legend .avg{
margin-top: 12px;
}
.legend .avg p strong {
font-weight: 600;
}
/* DATAVIEWS */
.dataview ul {
display: flex;
list-style-type: none;
flex-wrap: wrap;
width: calc(100% - 376px);
padding: 0;
margin: 0 0 0 40px;
}
.dataview li {
margin: 0 20px 20px 0;
}
.dataview .input_text {
min-height: 32px;
padding: 7px 8px;
border: 1px solid #DDD;
border-radius: 4px;
}
.dataview .input_text:hover,
.dataview .select:hover {
border: 1px solid #1785FB;
}
.dataview .select {
-webkit-appearance: none;
appearance: none;
min-height: 32px;
padding: 7px 8px;
border: 1px solid #DDD;
border-radius: 4px;
background: #fff;
min-width: 150px;
}
.dataview .button {
padding: 8px 20px;
margin: 0 0 0 40px;
cursor: pointer;
}
.code {
margin: 40px;
font-size: 14px;
color: #747D82;
}
/* TABS */
.maptabs {
display: flex;
list-style: none;
padding-left: 0;
margin-bottom: 0;
}
.maptabs li.maptab {
flex-grow: 1;
display: flex;
justify-content: center;
}
.maptabs .maptab a {
font: 12px 'Montserrat', 'Helvetica Neue', Helvetica, Arial,
sans-serif;
font-weight: 600;
text-decoration: none;
padding: 12px;
border: 1px solid rgba(22, 39, 69, 0.2);
color: #00B9BF;
transition: all .2s;
flex-grow: 1;
display: flex;
justify-content: center;
}
.maptabs .maptab.is-active a {
background: #2E3C43;
color: #ffffff;
border: 1px solid #2E3C43;
border-right: 0;
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.15);
}
.maptabs .maptab a:hover {
background: #00B9BF;
border-color: #00B9BF;
color: #ffffff;
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.15);
}
.maptabs .maptab.is-active a:hover {
background: #2E3C43;
color: #ffffff;
border: 1px solid #2E3C43;
}
.maptabs .maptab:first-child a {
border-radius: 4px 0 0 4px;
}
.maptabs .maptab:last-child a {
border-radius: 0 4px 4px 0;
border-right: 1px solid rgba(22, 39, 69, 0.2);
}
/* RANGE SLIDER */
input[type="range"] {
position: relative;
display: inline-block;
width: 100%;
height: 10px;
background-color: rgb(23, 133, 251);
border-radius: 10px;
outline: none;
cursor: pointer;
margin: 0 0 22px;
-webkit-appearance: none;
}
input[type=range]::before,
input[type=range]::after {
color: #747D82;
position: absolute;
top: 20px;
}
input[type=range]::before {
content: attr(min-with-suffix);
left: 0;
}
input[type=range]::after {
content: attr(max-with-suffix);
right: 0;
}
input[type="range"]::-webkit-slider-runnable-track,
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
}
input[type="range"]::-webkit-slider-thumb {
width: 15px;
height: 15px;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
box-shadow: 0 5px 15px 0 rgba(20, 75, 102, 0.15);
margin-top: -2px;
}
input[type="range"]::-moz-range-thumb {
width: 15px;
height: 15px;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
box-shadow: 0 5px 15px 0 rgba(20, 75, 102, 0.15);
margin-top: -2px;
}
input[type="range"]::-ms-thumb {
width: 15px;
height: 15px;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
box-shadow: 0 5px 15px 0 rgba(20, 75, 102, 0.15);
margin-top: -2px;
}
input[type="range"]::-webkit-slider-runnable-track {
height: 10px;
width: 100%;
background: linear-gradient(to right, transparent calc(var(--value) * 1%), rgb(226, 230, 227) 0);
border-radius: 10px;
}
input[type="range"]::-moz-range-track {
height: 10px;
background: linear-gradient(to right, transparent calc(var(--value) * 1%), rgb(226, 230, 227) 0);
border-radius: 10px;
}
input[type="range"]::-ms-track {
background-color: rgb(23, 133, 251);
height: 10px;
}
input[type="range"]::-ms-fill-lower {
background-color: rgb(226, 230, 227);
}
input[type="range"]::-ms-fill-upper {
background-color: rgb(23, 133, 251);;
}