Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add color_category and color_bins helpers #692

Merged
merged 22 commits into from
May 23, 2019
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions cartoframes/assets/templates/viz/basic.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@
<div class="as-map-area">
<div id="map"></div>
<div class="as-map-panels">
<div class="as-panel as-panel--right as-panel--top">
<div class="as-panel__element" id="legends" style="display: none;">
</div>
<div class="as-panel as-panel--left as-panel--top">
{% if has_legends %}
{% include 'viz/legends.html.j2' %}
{% endif %}
</div> <!-- as-panel -->
</div> <!-- as-map-panels -->
</div> <!-- as-map-area -->
Expand Down
35 changes: 35 additions & 0 deletions cartoframes/assets/templates/viz/legends.html.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{% macro legend(legend_data, id) -%}
{% set type = legend_data.type %}
{% if type == 'basic' %}
<as-basic-legend id="{{id}}" slot="legends"></as-basic-legend>
{% elif type == 'gradient' %}
<as-color-gradient-legend id="{{id}}" slot="legends"></as-color-gradient-legend>
{% elif type == 'color_steps' %}
<as-color-steps-legend id="{{id}}" slot="legends"></as-color-steps-legend>
{% else %}
<div>
<p class="as-body as-color--error">Unknown legend type {{ type }}</p>
</div>
{% endif %}
{%- endmacro %}

<div class="as-panel__element" id="legends">
{% if default_legend != none %}
<as-legends id="basicLegendContainer" heading="Map Legend">
<as-basic-legend id="basicLegend">
</as-basic-legend>
</as-legends>
{% endif %}

{% for source in sources %}
{% if source.legend %}
<as-legends
heading="{{source.legend.heading}}"
description="{{source.legend.description}}"
source="{{source.legend.source}}"
>
{{ legend(source.legend, 'source%d_legend' % loop.index0) }}
</as-legends>
{% endif %}
{% endfor %}
</div>
26 changes: 26 additions & 0 deletions cartoframes/assets/templates/viz/legends.js.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
function createDefaultLegend(layers) {
const defaultLegendContainer = document.querySelector('#basicLegendContainer');
defaultLegendContainer.style.display = 'none';

AsBridge.VL.Legends.layersLegend(
'#basicLegend',
layers,
{
onLoad: () => defaultLegendContainer.style.display = 'unset'
}
)
}

function createLegend(layer, legendData, layerIndex) {
const element = document.querySelector(`#source${layerIndex}_legend`);

if (legendData.ramp) {
AsBridge.VL.Legends.rampLegend(
element,
layer,
legendData.ramp
);
} else {
// TODO: we don't have a bridge for this case, should this even be a case?
}
}
15 changes: 15 additions & 0 deletions cartoframes/assets/templates/viz/map.js.j2
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{% if has_legends %}
{% include 'viz/legends.js.j2' %}
{% endif %}
{% include 'error/parser.js.j2' %}
{% include 'utils/base64.js.j2' %}

Expand Down Expand Up @@ -39,12 +42,16 @@ function onReady() {
map.flyTo({{ camera|clear_none|tojson }});
{% endif %}

const layers = [];

sources.forEach((elem, idx) => {
const factory = new SourceFactory();
const source = factory.createSource(elem);
const viz = new carto.Viz(elem['viz']);
const layer = new carto.Layer(`layer${idx}`, source, viz);

layers.push(layer);

try {
layer._updateLayer.catch(displayError);
} catch (err) {
Expand Down Expand Up @@ -73,6 +80,10 @@ function onReady() {
}
}

if (elem.legend) {
createLegend(layer, elem.legend, idx);
}

function setPopupsClick(tempPopup, interactivity, attrs) {
interactivity.on('featureClick', (event) => {
updatePopup(tempPopup, event, attrs)
Expand Down Expand Up @@ -139,6 +150,10 @@ function onReady() {
}
}
});

{% if default_legend %}
createDefaultLegend(layers);
{% endif %}
}

function setReady () {
Expand Down
8 changes: 4 additions & 4 deletions cartoframes/viz/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
AIRSHIP_BRIDGE_SCRIPT = '/packages/bridge/dist/asbridge.js'
AIRSHIP_STYLE = '/packages/styles/dist/airship.css'
AIRSHIP_ICONS_STYLE = '/packages/icons/dist/icons.css'
AIRSHIP_COMPONENTS_PATH = 'https://libs.cartocdn.com/airship-components/v2.0/airship.js'
AIRSHIP_BRIDGE_PATH = 'https://libs.cartocdn.com/airship-bridge/v2.0/asbridge.js'
AIRSHIP_STYLES_PATH = 'https://libs.cartocdn.com/airship-style/v2.0/airship.css'
AIRSHIP_ICONS_PATH = 'https://libs.cartocdn.com/airship-icons/v2.0/icons.css'
AIRSHIP_COMPONENTS_PATH = 'https://libs.cartocdn.com/airship-components/cartoframes/airship.js'
AIRSHIP_BRIDGE_PATH = 'https://libs.cartocdn.com/airship-bridge/cartoframes/asbridge.js'
AIRSHIP_STYLES_PATH = 'https://libs.cartocdn.com/airship-style/cartoframes/airship.css'
AIRSHIP_ICONS_PATH = 'https://libs.cartocdn.com/airship-icons/cartoframes/icons.css'

CREDENTIALS = {
'username': 'cartoframes',
Expand Down
16 changes: 16 additions & 0 deletions cartoframes/viz/helpers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from __future__ import absolute_import

from .color_category_layer import color_category_layer
from .color_bins_layer import color_bins_layer


def inspect(helper):
import inspect
lines = inspect.getsource(helper)
print(lines)


__all__ = [
'color_category_layer',
'color_bins_layer'
]
32 changes: 32 additions & 0 deletions cartoframes/viz/helpers/color_bins_layer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import absolute_import

from ..layer import Layer


def color_bins_layer(source, value, bins=5, palette='purpor', title=''):
return Layer(
source,
style={
'point': {
'color': 'ramp(globalQuantiles(${0},{1}),reverse({2}))'.format(value, bins, palette)
},
'line': {
'color': 'ramp(globalQuantiles(${0},{1}),reverse({2}))'.format(value, bins, palette)
},
'polygon': {
'color': 'opacity(ramp(globalQuantiles(${0},{1}),reverse({2})),0.9)'.format(value, bins, palette)
}
},
popup={
'hover': {
'label': title or value,
'value': '$' + value
}
},
legend={
'type': 'basic',
'ramp': 'color',
'heading': title or value,
'description': ''
}
)
32 changes: 32 additions & 0 deletions cartoframes/viz/helpers/color_category_layer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import absolute_import

from ..layer import Layer


def color_category_layer(source, value, top=11, palette='bold', title=''):
return Layer(
source,
style={
'point': {
'color': 'ramp(top(${0}, {1}), {2})'.format(value, top, palette)
},
'line': {
'color': 'ramp(top(${0}, {1}), {2})'.format(value, top, palette)
},
'polygon': {
'color': 'opacity(ramp(top(${0}, {1}), {2}),0.9)'.format(value, top, palette)
}
},
popup={
'hover': {
'label': title or value,
'value': '$' + value
}
},
legend={
'type': 'basic',
'ramp': 'color',
'heading': title or value,
'description': ''
}
)
18 changes: 15 additions & 3 deletions cartoframes/viz/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ def __init__(self,
size=None,
viewport=None,
template=None,
default_legend=None,
**kwargs):

self.layers = _init_layers(layers)
Expand All @@ -153,12 +154,18 @@ def __init__(self,
self._airship_path = kwargs.get('_airship_path', None)
self._htmlMap = HTMLMap()

if default_legend is None and all(layer.legend is None for layer in self.layers):
self.default_legend = True
else:
self.default_legend = default_legend

self._htmlMap.set_content(
size=self.size,
sources=self.sources,
bounds=self.bounds,
viewport=self.viewport,
basemap=self.basemap,
default_legend=self.default_legend,
_carto_vl_path=self._carto_vl_path,
_airship_path=self._airship_path)

Expand All @@ -179,7 +186,7 @@ def _get_bounds(bounds, layers):

def _init_layers(layers):
if layers is None:
return None
return []
if not isinstance(layers, collections.Iterable):
return [layers]
else:
Expand Down Expand Up @@ -380,14 +387,15 @@ def __init__(self):

def set_content(
self, size, sources, bounds, viewport=None, basemap=None,
default_legend=None,
_carto_vl_path=defaults.CARTO_VL_PATH, _airship_path=None):

self.html = self._parse_html_content(
size, sources, bounds, viewport, basemap,
size, sources, bounds, viewport, basemap, default_legend,
_carto_vl_path, _airship_path)

def _parse_html_content(
self, size, sources, bounds, viewport, basemap=None,
self, size, sources, bounds, viewport, basemap=None, default_legend=None,
_carto_vl_path=defaults.CARTO_VL_PATH, _airship_path=None):

token = ''
Expand Down Expand Up @@ -441,6 +449,8 @@ def _parse_html_content(
'pitch': viewport.get('pitch')
}

has_legends = any(source['legend'] is not None for source in sources) or default_legend

return self._template.render(
width=size[0] if size is not None else None,
height=size[1] if size is not None else None,
Expand All @@ -450,6 +460,8 @@ def _parse_html_content(
mapboxtoken=token,
bounds=bounds,
camera=camera,
has_legends=has_legends,
default_legend=default_legend,
carto_vl_path=_carto_vl_path,
airship_components_path=airship_components_path,
airship_bridge_path=airship_bridge_path,
Expand Down
12 changes: 10 additions & 2 deletions cartoframes/viz/popup.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,17 @@ def _init_popup(self, data):
if isinstance(data, dict):
# TODO: error control
if 'click' in data:
self._click = data.get('click', [])
click_data = data.get('click', [])
if isinstance(click_data, list):
self._click = click_data
else:
self._click = [click_data]
if 'hover' in data:
self._hover = data.get('hover', [])
hover_data = data.get('hover', [])
if isinstance(hover_data, list):
self._hover = hover_data
else:
self._hover = [hover_data]
else:
raise ValueError('Wrong popup input')

Expand Down
2 changes: 1 addition & 1 deletion examples/debug/API/basemaps.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"outputs": [],
"source": [
"from cartoframes.auth import Context, set_default_context\n",
"from cartoframes.viz import Map, Layer, basemaps\n",
"from cartoframes.viz import Map, Layer, basemapsc\n",
"\n",
"# Context\n",
"context = Context(\n",
Expand Down
Loading