airship
airship copied to clipboard
Bridge setup does not work for feature-dependent expression values
What is happening?
When adding a Legend through the Bridge, Airship creates a baseStyle
object with default values for each style property from the viz. This is not 100% accurate, cause it's getting a single value for each property. When the property is an expression that depends on a feature, this doesn't work.
https://github.com/CartoDB/airship/blob/1b52c881f758828baaa23f8faa39d5544d47dfdc/packages/bridge/src/vl/legends/index.ts#L28-L40
What should happen?
From my perspective, the best solution is to use the getLegendData
for each style property. This will imply some changes in the widget data, but it's the correct way to proceed.
Steps to Reproduce
Use this html example:
<!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>DEMO</title>
<script src="https://libs.cartocdn.com/airship-components/v2.1.1/airship.js"></script>
<script src="https://libs.cartocdn.com/airship-bridge/v2.1.1/asbridge.js"></script>
<script src="http://libs.cartocdn.com/carto-vl/v1.4.1/carto-vl.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.js"></script>
<link rel="stylesheet" href="https://libs.cartocdn.com/airship-style/v2.1.1/airship.css">
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.css" rel="stylesheet" />
<style>
html, body {
margin: 0;
}
#map {
position: absolute;
width: 100%;
height: 100%;
}
.as-panel {
flex-direction: column;
}
as-legend {
width: 100%;
}
#widget {
font-size: 2em;
margin-top: 20px;
}
</style>
</head>
<body class="as-app-body as-app">
<div class="as-content">
<main class="as-main">
<div class="as-map-area">
<div id="map"></div>
<div class="as-map-panels">
<div class="as-panel as-panel--top as-panel--left" id="legends">
<as-legend
id="spend-data-legend"
heading="Spend Data"
description="Color intensity defined by Spend Data">
<as-legend-color-continuous-polygon id="spend-data" slot="legends" />
</as-legend>
</div>
</div>
</div>
</main>
<aside class="as-sidebar as-sidebar--right">
<section class="as-box">
<as-widget-header>
<h2 class="as-widget-header__header">Spend Data</h2>
</as-widget-header>
<p class="as-body" id="widget"></p>
</section>
<section class="as-box">
<as-histogram-widget
show-clear
id="histogramWidget"
heading="spend-data"
>
</as-histogram-widget>
</section>
<section class="as-box">
<as-category-widget
show-clear
id="categoryWidget"
heading="Type"
></as-category-widget>
</section>
</aside>
</div>
<script>
const map = new mapboxgl.Map({
container: 'map',
style: carto.basemaps.darkmatter,
center: [0, 40],
zoom: 1
});
map.addControl(new mapboxgl.NavigationControl());
carto.setDefaultAuth({
username: 'cartovl',
apiKey: 'default_public'
});
const source = new carto.source.SQL(`
SELECT * FROM spend_data
`);
const viz = new carto.Viz(`
color: opacity(ramp(clusterAVG($amount), sunset),0.9)
width: clusterCount()
`);
const layer = new carto.Layer('spend_data', source, viz);
layer.addTo(map, 'watername_ocean');
AsBridge.VL.Legends.rampLegend('#spend-data',
layer,
'color'
);
</script>
</body>
</html>
Thank you @elenatorro!