{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "import pydeck as pdk\n",
    "pn.extension('deckgl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Deck.gl](https://deck.gl/#/) is a very powerful WebGL-powered framework for visual exploratory data analysis of large datasets. The `DeckGL` *pane* renders JSON Deck.gl JSON specification as well as `PyDeck` plots inside a panel. If data is encoded in the deck.gl layers the pane will extract the data and send it across the websocket in a binary format speeding up rendering.\n",
    "\n",
    "The [`PyDeck`](https://deckgl.readthedocs.io/en/latest/) *package* provides Python bindings. Please follow the [installation instructions](https://github.com/uber/deck.gl/blob/master/bindings/pydeck/README.md) closely to get it working in this Jupyter Notebook.\n",
    "\n",
    "#### Parameters:\n",
    "\n",
    "For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n",
    "\n",
    "* **``mapbox_api_key``** (string): The MapBox API key if not supplied by a PyDeck object.\n",
    "* **``object``** (object, dict or string): The deck.GL JSON or PyDeck object being displayed\n",
    "* **``tooltips``** (boolean, default=True): Whether to enable tooltips\n",
    "\n",
    "In addition to parameters which control how the object is displayed the DeckGL pane also exposes a number of parameters which receive updates from the plot:\n",
    "\n",
    "* **``click_state``** (dict): Contains the last click event on the DeckGL plot.\n",
    "* **``hover_state``** (dict): Contains information about the current hover location on the DeckGL plot.\n",
    "* **``view_state``** (dict): Contains information about the current view port of the DeckGL plot.\n",
    "\n",
    "____"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In order to use Deck.gl you need a MAP BOX Key which you can acquire for free for limited use at [mapbox.com](https://account.mapbox.com/access-tokens/).\n",
    "\n",
    "Now we can define a JSON spec and pass it to the DeckGL pane along with the Mapbox key:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "MAPBOX_KEY = \"pk.eyJ1IjoicGFuZWxvcmciLCJhIjoiY2s1enA3ejhyMWhmZjNobjM1NXhtbWRrMyJ9.B_frQsAVepGIe-HiOJeqvQ\"\n",
    "\n",
    "json_spec = {\n",
    "    \"initialViewState\": {\n",
    "        \"bearing\": -27.36,\n",
    "        \"latitude\": 52.2323,\n",
    "        \"longitude\": -1.415,\n",
    "        \"maxZoom\": 15,\n",
    "        \"minZoom\": 5,\n",
    "        \"pitch\": 40.5,\n",
    "        \"zoom\": 6\n",
    "    },\n",
    "    \"layers\": [{\n",
    "        \"@@type\": \"HexagonLayer\",\n",
    "        \"autoHighlight\": True,\n",
    "        \"coverage\": 1,\n",
    "        \"data\": \"https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv\",\n",
    "        \"elevationRange\": [0, 3000],\n",
    "        \"elevationScale\": 50,\n",
    "        \"extruded\": True,\n",
    "        \"getPosition\": \"@@=[lng, lat]\",\n",
    "        \"id\": \"8a553b25-ef3a-489c-bbe2-e102d18a3211\", \"pickable\": True\n",
    "    }],\n",
    "    \"mapStyle\": \"mapbox://styles/mapbox/dark-v9\",\n",
    "    \"views\": [{\"@@type\": \"MapView\", \"controller\": True}]\n",
    "}\n",
    "\n",
    "deck_gl = pn.pane.DeckGL(json_spec, mapbox_api_key=MAPBOX_KEY, sizing_mode='stretch_width', height=600)\n",
    "\n",
    "deck_gl"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Like other panes the DeckGL object can be replaced or updated. In this example we will change the `colorRange` of the HexagonLayer and then trigger an update:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "COLOR_RANGE = [\n",
    "      [1, 152, 189],\n",
    "      [73, 227, 206],\n",
    "      [216, 254, 181],\n",
    "      [254, 237, 177],\n",
    "      [254, 173, 84],\n",
    "      [209, 55, 78]\n",
    "]\n",
    "\n",
    "json_spec['layers'][0]['colorRange'] = COLOR_RANGE\n",
    "\n",
    "deck_gl.param.trigger('object')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively the `DeckGL` pane can also be given a PyDeck object to render:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pydeck\n",
    "\n",
    "DATA_URL = \"https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/geojson/vancouver-blocks.json\"\n",
    "\n",
    "LAND_COVER = [[[-123.0, 49.196], [-123.0, 49.324], [-123.306, 49.324], [-123.306, 49.196]]]\n",
    "\n",
    "INITIAL_VIEW_STATE = pydeck.ViewState(\n",
    "  latitude=49.254,\n",
    "  longitude=-123.13,\n",
    "  zoom=11,\n",
    "  max_zoom=16,\n",
    "  pitch=45,\n",
    "  bearing=0\n",
    ")\n",
    "\n",
    "polygon = pydeck.Layer(\n",
    "    'PolygonLayer',\n",
    "    LAND_COVER,\n",
    "    stroked=False,\n",
    "    # processes the data as a flat longitude-latitude pair\n",
    "    get_polygon='-',\n",
    "    get_fill_color=[0, 0, 0, 20]\n",
    ")\n",
    "\n",
    "geojson = pydeck.Layer(\n",
    "    'GeoJsonLayer',\n",
    "    DATA_URL,\n",
    "    opacity=0.8,\n",
    "    stroked=False,\n",
    "    filled=True,\n",
    "    extruded=True,\n",
    "    wireframe=True,\n",
    "    get_elevation='properties.valuePerSqm / 20',\n",
    "    get_fill_color='[255, 255, properties.growth * 255]',\n",
    "    get_line_color=[255, 255, 255],\n",
    "    pickable=True\n",
    ")\n",
    "\n",
    "r = pydeck.Deck(\n",
    "    mapbox_key=MAPBOX_KEY,\n",
    "    layers=[polygon, geojson],\n",
    "    initial_view_state=INITIAL_VIEW_STATE\n",
    ")\n",
    "\n",
    "pn.pane.DeckGL(r, sizing_mode='stretch_width', height=600)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Controls\n",
    "\n",
    "The `DeckGL` pane exposes a number of options which can be changed from both Python and Javascript. Try out the effect of these parameters interactively:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
