Flatten viz.json layers
See original GitHub issueBackground
viz.json files contain information about a visualization created by the CARTO Builder. deep-insight.js/cartodb.js use these files to render beautiful dashboards and maps 😃
In previous versions of the editor (before The Builder was born) there are/were two different flavours of viz.json files:
- viz.json for public maps.
- viz.json for maps that are password protected or have any private dataset.
Let’s see a couple of examples of viz.json files for the same map (4 layers: 1 basemap, 1 CartoDB layer, 1 torque layer and the layer with labels) with different privacy settings (showing only the part related to layers
):
1. viz.json format for public maps:
{
...
"layers": [
{
"options": {
"default": "true",
"url": "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"name": "Positron",
"className": "positron_rainbow_labels",
"attribution": "© <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors © <a href=\"https://carto.com/attributions\">CARTO</a>",
"labels": {
"url": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png"
},
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
"type": "Tiled"
},
"infowindow": null,
"tooltip": null,
"id": "9b9a0f4e-b486-4281-abcf-7fde4e26408d",
"order": 0,
"type": "tiled"
},
{
"type": "layergroup",
"options": {
"user_name": "pabloalonso",
"maps_api_template": "https://{user}.carto.com:443",
"sql_api_template": "https://{user}.carto.com:443",
"filter": "mapnik",
"layer_definition": {
"stat_tag": "67478336-48e4-11e6-ad50-0ecd1babdde5",
"version": "3.0.0",
"layers": [
{
"id": "7713296c-ccb7-4047-a736-5fb272d9f8ac",
"type": "CartoDB",
"infowindow": { ... },
"tooltip": { ... },
"legend": null,
"order": 1,
"visible": true,
"options": {
"layer_name": "airbnb_madrid_oct_2015_listings_with_closest_metro",
"cartocss": "// points\n [mapnik-geometry-type=point] {\n marker-fill: #FF6600;\n marker-opacity: 1;\n marker-width: 12;\n marker-line-color: white;\n marker-line-width: 3;\n marker-line-opacity: 0.9;\n marker-placement: point;\n marker-type: ellipse;marker-allow-overlap: true;\n }\n\n //lines\n [mapnik-geometry-type=linestring] {\n line-color: #FF6600; \n line-width: 2; \n line-opacity: 0.7;\n }\n\n //polygons\n [mapnik-geometry-type=polygon] {\n polygon-fill:#FF6600;\n polygon-opacity: 0.7;\n line-opacity:1;\n line-color: #FFFFFF;\n }",
"cartocss_version": "2.1.1",
"interactivity": "cartodb_id",
"source": "c1"
}
}
]
},
"attribution": ""
}
},
{
"id": "71b75edb-8140-4640-a266-4a13bc84d994",
"type": "torque",
"order": 2,
"legend": null,
"options": {
"stat_tag": "67478336-48e4-11e6-ad50-0ecd1babdde5",
"maps_api_template": "https://{user}.carto.com:443",
"sql_api_template": "https://{user}.carto.com:443",
"visible": true,
"table_name": "airbnb_madrid_oct_2015_listings_with_closest_metro"
},
"cartocss": "Map {\n -torque-frame-count: 256;\n -torque-animation-duration: 30;\n -torque-time-attribute: \"cartodb_id\";\n -torque-aggregation-function: \"count(1)\";\n -torque-resolution: 2;\n -torque-data-aggregation: linear;\n}#layer {\n marker-width: 7;\n marker-fill: #FFB927;\n marker-fill-opacity: 0.9;\n marker-allow-overlap: true;\n marker-line-width: 1.5;\n marker-line-color: #ffda8d;\n marker-line-opacity: 1;\n}\n#layer[frame-offset=1] {\nmarker-width: 9;\nmarker-fill-opacity: 0.5;\n}\n#layer[frame-offset=2] {\nmarker-width: 11;\nmarker-fill-opacity: 0.25;\n}",
"cartocss_version": "2.1.1",
"sql": "SELECT * FROM airbnb_madrid_oct_2015_listings_with_closest_metro",
"source": "a0"
},
{
"options": {
"default": "true",
"url": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"attribution": "© <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors © <a href=\"https://carto.com/attributions\">CARTO</a>",
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"type": "Tiled",
"name": "Positron Labels"
},
"infowindow": null,
"tooltip": null,
"id": "e2e7eac2-f9a0-4f3b-b97c-a377c812c3d6",
"order": 3,
"type": "tiled"
}
],
"analyses": [
{
"id": "c1",
"type": "buffer",
"params": {
"source": {
"id": "c0",
"type": "source",
"params": {
"query": "SELECT * FROM airbnb_madrid_oct_2015_listings_with_closest_metro LIMIT 10"
},
"options": {
"table_name": "airbnb_madrid_oct_2015_listings_with_closest_metro"
}
},
"radius": 1000,
"dissolved": false
},
"options": {
"distance": "kilometers"
}
},
{
"id": "a0",
"type": "source",
"params": {
"query": "SELECT * FROM twitter_t3chfest_reduced"
},
"options": {
"table_name": "twitter_t3chfest_reduced"
}
}
],
...
}
2. viz.json format for protected maps/maps with private datasets:
{
...
"layers": [
{
"options": {
"default": "true",
"url": "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"name": "Positron",
"className": "positron_rainbow_labels",
"attribution": "© <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors © <a href=\"https://carto.com/attributions\">CARTO</a>",
"labels": {
"url": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png"
},
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
"type": "Tiled"
},
"infowindow": null,
"tooltip": null,
"id": "9b9a0f4e-b486-4281-abcf-7fde4e26408d",
"order": 0,
"type": "tiled"
},
{
"type": "namedmap",
"order": 1,
"options": {
"type": "namedmap",
"user_name": "pabloalonso",
"maps_api_template": "https://{user}.carto.com:443",
"sql_api_template": "https://{user}.carto.com:443",
"filter": "mapnik",
"named_map": {
"name": "tpl_67478336_48e4_11e6_ad50_0ecd1babdde5",
"stat_tag": "67478336-48e4-11e6-ad50-0ecd1babdde5",
"params": {
"layer0": 1
},
"layers": [
{
"id": "7713296c-ccb7-4047-a736-5fb272d9f8ac",
"layer_name": "airbnb_madrid_oct_2015_listings_with_closest_metro",
"interactivity": "cartodb_id",
"visible": true,
"options": {
"source": "c1"
},
"infowindow": { ... },
"tooltip": { ... }
}
]
},
"attribution": ""
}
},
{
"id": "71b75edb-8140-4640-a266-4a13bc84d994",
"type": "torque",
"order": 2,
"legend": null,
"options": {
"stat_tag": "67478336-48e4-11e6-ad50-0ecd1babdde5",
"maps_api_template": "https://{user}.carto.com:443",
"sql_api_template": "https://{user}.carto.com:443",
"visible": true,
"table_name": "airbnb_madrid_oct_2015_listings_with_closest_metro",
"named_map": {
"name": "tpl_67478336_48e4_11e6_ad50_0ecd1babdde5",
"layer_index": 1,
"params": {
"layer0": 1
}
}
},
"cartocss": "Map {\n -torque-frame-count: 256;\n -torque-animation-duration: 30;\n -torque-time-attribute: \"cartodb_id\";\n -torque-aggregation-function: \"count(1)\";\n -torque-resolution: 2;\n -torque-data-aggregation: linear;\n}#layer {\n marker-width: 7;\n marker-fill: #FFB927;\n marker-fill-opacity: 0.9;\n marker-allow-overlap: true;\n marker-line-width: 1.5;\n marker-line-color: #ffda8d;\n marker-line-opacity: 1;\n}\n#layer[frame-offset=1] {\nmarker-width: 9;\nmarker-fill-opacity: 0.5;\n}\n#layer[frame-offset=2] {\nmarker-width: 11;\nmarker-fill-opacity: 0.25;\n}",
"cartocss_version": "2.1.1",
"sql": "SELECT * FROM airbnb_madrid_oct_2015_listings_with_closest_metro",
"source": "a0"
},
{
"options": {
"default": "true",
"url": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"subdomains": "abcd",
"minZoom": "0",
"maxZoom": "18",
"attribution": "© <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors © <a href=\"https://carto.com/attributions\">CARTO</a>",
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
"type": "Tiled",
"name": "Positron Labels"
},
"infowindow": null,
"tooltip": null,
"id": "e2e7eac2-f9a0-4f3b-b97c-a377c812c3d6",
"order": 3,
"type": "tiled"
}
],
"analyses": [
{
"id": "c1",
"type": "buffer",
"params": {
"source": {
"id": "c0",
"type": "source",
"options": {
"table_name": "airbnb_madrid_oct_2015_listings_with_closest_metro"
}
},
"radius": 1000,
"dissolved": false
},
"options": {
"distance": "kilometers"
}
},
{
"id": "a0",
"type": "source",
"options": {
"table_name": "twitter_t3chfest_reduced"
}
}
],
...
}
The information that was used to instantiate the map in both cases, was extracted to a new section in the viz.json, so it can be safely removed from the layergroup
/namedmap
layer itself:
"datasource": {
"user_name": "chuck",
"maps_api_template": "https://{user}.carto.com:443",
"stat_tag": "67478336-48e4-11e6-ad50-0ecd1babdde5",
"template_name": "tpl_67478336_48e4_11e6_ad50_0ecd1babdde5"
},
CartoDB.js looks for datasource.template_name
to determine if the map should be instantiated via an anonymous or named map.
In 1. CartoDB
layers are grouped into a layergroup
layer. As we can see, each (sub) layer within this layer has a CartoDB
type and exposes some information that is somehow related to the schema of the associated dataset (eg: sql, cartocss, infowindow and tooltip field names, etc). eg:
{
"id": "7713296c-ccb7-4047-a736-5fb272d9f8ac",
"type": "CartoDB",
"infowindow": {
"template_name": "none", // TODO: This could be removed from viz.json
"fields": [],
"maxHeight": 180,
"template": "",
"alternative_names": {},
"width": 226,
"headerColor": { // TODO: This could be removed from viz.json
"color": {
"fixed": "#35AAE5",
"opacity": 1
}
}
},
"tooltip": {
"fields": [],
"template_name": "none",
"template": "",
"template_type": "mustache"
},
"legend": null,
"order": 1,
"visible": true,
"options": {
"layer_name": "airbnb_madrid_oct_2015_listings_with_closest_metro",
"cartocss": "...",
"cartocss_version": "2.1.1",
"interactivity": "cartodb_id",
"source": "c1"
}
}
Also, in 1. some analyses
items include a query
param with the SQL for that node.
In 2. There’s a namedmap
layer whose (sub)layers don’t have a type and don’t include any SQL or CartoCSS options. eg:
{
"id": "7713296c-ccb7-4047-a736-5fb272d9f8ac",
"layer_name": "airbnb_madrid_oct_2015_listings_with_closest_metro",
"interactivity": "cartodb_id",
"visible": true,
"options": {
"source": "c1"
},
"infowindow": {
"template_name": "infowindow_light",
"fields": [
{
"name": "require_guest_phone_verification",
"title": true,
"position": null
},
{
"name": "require_guest_profile_picture",
"title": true,
"position": null
},
{
"name": "instant_bookable",
"title": true,
"position": null
}
],
"maxHeight": 180,
"template": "<div class=\"CDB-infowindow CDB-infowindow--light js-infowindow\">...</div>\n",
"alternative_names": {},
"width": 226,
"headerColor": {
"color": {
"fixed": "#35AAE5",
"opacity": 1
}
},
"template_type": "mustache"
},
"tooltip": {
"fields": [
{
"name": "require_guest_phone_verification",
"title": true,
"position": null
},
{
"name": "require_guest_profile_picture",
"title": true,
"position": null
},
{
"name": "instant_bookable",
"title": true,
"position": null
}
],
"template_name": "tooltip_dark",
"template": "<div class=\"CDB-Tooltip CDB-Tooltip--isDark\">...</div>\n",
"template_type": "mustache"
}
}
Queries are removed from analyses in the viz.json in 2.
Goals / scope
The goal of this issue is to remove the concept of layergroup
and namedmap
layers from the viz.json. Instead of grouping CartoDB
layers into one, all layers should be rendered at the same level.
Proposed changes
There’ll still be two different viz.json “flavours”:
- The one used by the builder, where data (layers and analyses) is unfiltered.
- The one used by embeds/public maps, where data (layers and analyses) is “filtered” (no sql, cartocss).
Layers that lived inside of layergroup
and namedmap
layers, will now be “first class citizens”, and have the following format:
{
"id": "7713296c-ccb7-4047-a736-5fb272d9f8ac",
"type": "CartoDB",
"visible": true,
"options": {
"source": "c1", //
"sql": "SELECT foo FROM bar;", // (*)
"cartocss": ... // (*)
"cartocss_version": "2.1.1" (*)
"layer_name": "something",
"attribution": "© Some custom attribution"
},
"infowindow": { ... },
"tooltip": { ... }
}
(*) Only present if type
of viz.json is unfiltered
…
Notice that each “CartoDB” layer should include any custom attribution present in the dataset.
cc: @javisantana @rochoa @xavijam @CartoDB/frontend @CartoDB/backend. I’d love your input/feedback/ideas about this! Thx
Issue Analytics
- State:
- Created 7 years ago
- Comments:13 (13 by maintainers)
Top GitHub Comments
I’d say yes cause they are not being used by CartoDB.js v4.
.name
has been moved to thedatasource
section.I’m sorry I won’t be of much help but probably more hassle. I can tell as a newcomer what are the main things it’s hard for me to get (but probably that’s an offtopic, for another PR)
why do we have tooltip, and infowindow at a higher level, and why not inside the options? why do we have those options in the first place? why there’s a kind/type you refer earlier (we deal with this differently in many places of the codes, with transformations and such)
sorry if I should rise these concerns elsewhere, but I’m hitting them again and again, first with the infowindows, now with the layers (as layer in the map, and user layer).